Home | History | Annotate | Line # | Download | only in nios2
nios2-ldstwm.sml revision 1.1
      1  1.1  mrg (* Auto-generate Nios II R2 CDX ldwm/stwm/push.n/pop.n patterns
      2  1.1  mrg    Copyright (C) 2014-2016 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by Mentor Graphics.
      4  1.1  mrg 
      5  1.1  mrg    This file is part of GCC.
      6  1.1  mrg 
      7  1.1  mrg    GCC is free software; you can redistribute it and/or modify it under
      8  1.1  mrg    the terms of the GNU General Public License as published by the Free
      9  1.1  mrg    Software Foundation; either version 3, or (at your option) any later
     10  1.1  mrg    version.
     11  1.1  mrg 
     12  1.1  mrg    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     13  1.1  mrg    WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  1.1  mrg    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  1.1  mrg    for more details.
     16  1.1  mrg 
     17  1.1  mrg    You should have received a copy of the GNU General Public License
     18  1.1  mrg    along with GCC; see the file COPYING3.  If not see
     19  1.1  mrg    <http://www.gnu.org/licenses/>.
     20  1.1  mrg 
     21  1.1  mrg    This is a Standard ML program.  There are multiple Standard ML
     22  1.1  mrg    implementations widely available.  We recommend the MLton optimizing
     23  1.1  mrg    SML compiler, due to its ease of creating a standalone executable.
     24  1.1  mrg 
     25  1.1  mrg      http://www.mlton.org/
     26  1.1  mrg 
     27  1.1  mrg    Or from your favourite OS's friendly packaging system. Tested with
     28  1.1  mrg    MLton Release 20130715, though other versions will probably work too.
     29  1.1  mrg 
     30  1.1  mrg    Run with:
     31  1.1  mrg      mlton -output a.out /path/to/gcc/config/nios2/nios2-ldstwm.sml
     32  1.1  mrg      ./a.out >/path/to/gcc/config/nios2/ldstwm.md
     33  1.1  mrg *)
     34  1.1  mrg 
     35  1.1  mrg datatype ld_st = ld | st;    
     36  1.1  mrg datatype push_pop = push | pop;
     37  1.1  mrg datatype inc_dec = inc | dec;
     38  1.1  mrg 
     39  1.1  mrg fun for ls f = map f ls;
     40  1.1  mrg fun conds cond str = if cond then str else "";
     41  1.1  mrg fun ints n = if n>=0 then (Int.toString n) else ("-" ^ (Int.toString (~n)));
     42  1.1  mrg 
     43  1.1  mrg fun pushpop_pattern pptype n fp =
     44  1.1  mrg     let 
     45  1.1  mrg 	val sp_reg = "(reg:SI SP_REGNO)";
     46  1.1  mrg 	val ra_reg = "(reg:SI RA_REGNO)";
     47  1.1  mrg 	val fp_reg = "(reg:SI FP_REGNO)";
     48  1.1  mrg 
     49  1.1  mrg 	fun sets lhs rhs = "(set " ^ lhs ^
     50  1.1  mrg 			   (if pptype=push then " "
     51  1.1  mrg 			    else " ") ^ rhs ^ ")";
     52  1.1  mrg 	val sp_adj =
     53  1.1  mrg 	    "(set " ^ sp_reg ^ "\n          " ^
     54  1.1  mrg 	    "(plus:SI " ^ sp_reg ^
     55  1.1  mrg 	    " (match_operand 1 \"const_int_operand\" \"\")))";
     56  1.1  mrg 
     57  1.1  mrg 	fun reg i regi = "(reg:SI " ^ (ints regi) ^ ")";
     58  1.1  mrg 	fun mem i opndi =
     59  1.1  mrg 	    if pptype=push then
     60  1.1  mrg 		"(mem:SI (plus:SI (reg:SI SP_REGNO) (const_int " ^ (ints (~4*i)) ^ ")))"
     61  1.1  mrg 	    else
     62  1.1  mrg 		"(match_operand:SI " ^
     63  1.1  mrg 		(ints opndi) ^ " \"stack_memory_operand\" \"\")";
     64  1.1  mrg 
     65  1.1  mrg 	val start = 1 + (if fp then 2 else 1);
     66  1.1  mrg 	val lim = n + (if fp then 2 else 1);
     67  1.1  mrg 	fun set_elt i regi opndi =
     68  1.1  mrg 	    if pptype=push then (sets (mem i opndi) (reg i regi))
     69  1.1  mrg 	    else (sets (reg i regi) (mem i opndi));
     70  1.1  mrg 	fun get_elt_list (i, regi, opndi) =
     71  1.1  mrg 	    if i > lim then []
     72  1.1  mrg 	    else (set_elt i regi opndi) :: get_elt_list (i+1, regi-1, opndi+1);
     73  1.1  mrg 
     74  1.1  mrg 	val set_elements = get_elt_list (start, 16+n-1, start+1);
     75  1.1  mrg 
     76  1.1  mrg 	val ra_set = if pptype=push then sets (mem 1 2) ra_reg
     77  1.1  mrg 		     else sets ra_reg (mem 1 2);
     78  1.1  mrg 	val fp_set = (conds fp (if pptype=push then sets (mem 2 3) fp_reg
     79  1.1  mrg 				else sets fp_reg (mem 2 3)));
     80  1.1  mrg 	val ret = (conds (pptype=pop) "(return)");
     81  1.1  mrg 	val element_list =
     82  1.1  mrg 	    List.filter (fn x => x<>"")
     83  1.1  mrg 			([ret, sp_adj, ra_set, fp_set] @ set_elements);
     84  1.1  mrg 
     85  1.1  mrg 	fun reg_index i = 16 + n - i;
     86  1.1  mrg 	fun pop_opnds 0 spl = (conds fp ("fp" ^ spl)) ^ "ra"
     87  1.1  mrg 	  | pop_opnds n spl = "r" ^ (ints (reg_index n)) ^ spl ^ (pop_opnds (n-1) spl);
     88  1.1  mrg 	fun push_opnds 0 spl = "ra" ^ (conds fp (spl ^ "fp"))
     89  1.1  mrg 	  | push_opnds n spl = (push_opnds (n-1) spl) ^ spl ^ "r" ^ (ints (reg_index n));
     90  1.1  mrg 
     91  1.1  mrg 	val spadj_opnd = if pptype=push then 2 else (start+n);
     92  1.1  mrg 	val spadj = ints spadj_opnd;
     93  1.1  mrg 	val regsave_num = n + (if fp then 2 else 1);
     94  1.1  mrg 
     95  1.1  mrg 	val ppname = if pptype=push then "push" else "pop";
     96  1.1  mrg 	val name = if pptype=push then "push" ^ "_" ^ (push_opnds n "_")
     97  1.1  mrg 		   else "pop" ^ "_" ^ (pop_opnds n "_");
     98  1.1  mrg     in
     99  1.1  mrg 	"(define_insn \"*cdx_" ^ name ^ "\"\n" ^
    100  1.1  mrg 	"  [(match_parallel 0 \"" ^
    101  1.1  mrg 	(conds (pptype=pop) "pop_operation") ^ "\"\n" ^
    102  1.1  mrg 	"    [" ^ (String.concatWith ("\n     ") element_list) ^ "])]\n" ^
    103  1.1  mrg 	"   \"TARGET_HAS_CDX && XVECLEN (operands[0], 0) == " ^
    104  1.1  mrg 	(ints (length element_list)) ^
    105  1.1  mrg 	(conds (pptype=push)
    106  1.1  mrg 	       ("\n    && (-INTVAL (operands[1]) & 3) == 0\n" ^
    107  1.1  mrg 		"    && (-INTVAL (operands[1]) - " ^
    108  1.1  mrg 		(ints (4*regsave_num)) ^ ") <= 60")) ^
    109  1.1  mrg 	"\"\n" ^
    110  1.1  mrg 	(if pptype=pop then
    111  1.1  mrg 	     "{\n" ^
    112  1.1  mrg 	     "  rtx x = XEXP (operands[" ^ spadj ^ "], 0);\n" ^
    113  1.1  mrg 	     "  operands[" ^ spadj ^ "] = REG_P (x) ? const0_rtx : XEXP (x, 1);\n" ^
    114  1.1  mrg 	     "  return \"pop.n\\\\t{" ^ (pop_opnds n ", ") ^ "}, %" ^ spadj ^ "\";\n" ^
    115  1.1  mrg 	     "}\n"
    116  1.1  mrg 	 else
    117  1.1  mrg 	     "{\n" ^
    118  1.1  mrg 	     "  operands[" ^ spadj ^ "] = " ^
    119  1.1  mrg 	     "GEN_INT (-INTVAL (operands[1]) - " ^ (ints (4*regsave_num)) ^ ");\n" ^
    120  1.1  mrg 	     "  return \"push.n\\\\t{" ^ (push_opnds n ", ") ^ "}, %" ^ spadj ^ "\";\n" ^
    121  1.1  mrg 	     "}\n") ^
    122  1.1  mrg 	"  [(set_attr \"type\" \"" ^ ppname ^ "\")])\n\n"
    123  1.1  mrg     end;
    124  1.1  mrg 
    125  1.1  mrg fun ldstwm_pattern ldst n id wb pc =
    126  1.1  mrg     let
    127  1.1  mrg 	val ldstwm = (if ldst=ld then "ldwm" else "stwm");
    128  1.1  mrg 	val name = "*cdx_" ^ ldstwm ^ (Int.toString n) ^
    129  1.1  mrg 		   (if id=inc then "_inc" else "_dec") ^
    130  1.1  mrg 		   (conds wb "_wb") ^ (conds pc "_ret");
    131  1.1  mrg 	val base_reg_referenced_p = ref false;
    132  1.1  mrg 	val base_regno = ints (n+1);
    133  1.1  mrg 	fun plus_addr base offset =
    134  1.1  mrg 	    "(plus:SI " ^ base ^ " (const_int " ^ (ints offset) ^ "))";
    135  1.1  mrg 	fun base_reg () =
    136  1.1  mrg 	    if !base_reg_referenced_p then
    137  1.1  mrg 		"(match_dup " ^ base_regno ^ ")"
    138  1.1  mrg 	    else (base_reg_referenced_p := true;
    139  1.1  mrg 		  "(match_operand:SI " ^ base_regno ^
    140  1.1  mrg 		  " \"register_operand\" \"" ^ (conds wb "+&") ^ "r\")");
    141  1.1  mrg 	fun reg i = "(match_operand:SI " ^ (ints i) ^
    142  1.1  mrg 		    " \"nios2_hard_register_operand\" \"" ^
    143  1.1  mrg 		    (conds (ldst=ld) "") ^ "\")";
    144  1.1  mrg 
    145  1.1  mrg 	fun addr 1 = if id=inc then base_reg ()
    146  1.1  mrg 		     else plus_addr (base_reg ()) (~4)
    147  1.1  mrg 	  | addr i = let val offset = if id=inc then (i-1)*4 else (~i*4)
    148  1.1  mrg 		     in plus_addr (base_reg ()) offset end;
    149  1.1  mrg 
    150  1.1  mrg 	fun mem i = "(mem:SI " ^ (addr i) ^ ")";
    151  1.1  mrg 	fun lhs i = if ldst=ld then reg i else mem i;
    152  1.1  mrg 	fun rhs i = if ldst=st then reg i else mem i;
    153  1.1  mrg 	fun sets lhs rhs = "(set " ^ lhs ^ "\n          " ^ rhs ^ ")";
    154  1.1  mrg 	fun set_elements i =
    155  1.1  mrg 	    if i > n then []
    156  1.1  mrg 	    else (sets (lhs i) (rhs i)) :: (set_elements (i+1));
    157  1.1  mrg 
    158  1.1  mrg 	fun opnds 1 = "%1"
    159  1.1  mrg 	  | opnds n = opnds(n-1) ^ ", %" ^ (Int.toString n);
    160  1.1  mrg 
    161  1.1  mrg 	val asm_template = ldstwm ^ "\\\\t{" ^ (opnds n) ^ "}" ^
    162  1.1  mrg 			   (if id=inc
    163  1.1  mrg 			    then ", (%" ^ base_regno ^ ")++"
    164  1.1  mrg 			    else ", --(%" ^ base_regno ^ ")") ^
    165  1.1  mrg 			   (conds wb ", writeback") ^
    166  1.1  mrg 			   (conds pc ", ret");
    167  1.1  mrg 	val wbtmp =
    168  1.1  mrg 	    if wb then
    169  1.1  mrg 		(sets (base_reg ())
    170  1.1  mrg 		      (plus_addr (base_reg ())
    171  1.1  mrg 				 ((if id=inc then n else ~n)*4)))
    172  1.1  mrg 	    else "";
    173  1.1  mrg 	val pctmp = conds pc "(return)";
    174  1.1  mrg 	val set_list = List.filter (fn x => x<>"")
    175  1.1  mrg 				   ([pctmp, wbtmp] @ (set_elements 1));
    176  1.1  mrg     in
    177  1.1  mrg 	if ldst=st andalso pc then ""
    178  1.1  mrg 	else
    179  1.1  mrg 	    "(define_insn \"" ^ name ^ "\"\n" ^
    180  1.1  mrg 	    "  [(match_parallel 0 \"" ^ ldstwm ^  "_operation\"\n" ^
    181  1.1  mrg 	    "    [" ^ (String.concatWith ("\n     ") set_list) ^ "])]\n" ^
    182  1.1  mrg 	    "   \"TARGET_HAS_CDX && XVECLEN (operands[0], 0) == " ^
    183  1.1  mrg 	    (ints (length set_list)) ^ "\"\n" ^
    184  1.1  mrg 	    "   \"" ^ asm_template ^ "\"\n" ^
    185  1.1  mrg 	    "  [(set_attr \"type\" \"" ^ ldstwm ^ "\")])\n\n"
    186  1.1  mrg     end;
    187  1.1  mrg 
    188  1.1  mrg fun peephole_pattern ldst n scratch_p =
    189  1.1  mrg     let
    190  1.1  mrg 	fun sets lhs rhs = "(set " ^ lhs ^ "\n        " ^ rhs ^ ")";
    191  1.1  mrg 	fun single_set i indent =
    192  1.1  mrg 	    let val reg = "(match_operand:SI " ^ (ints i) ^
    193  1.1  mrg 			  " \"register_operand\" \"\")";
    194  1.1  mrg 		val mem = "(match_operand:SI " ^ (ints (i+n)) ^
    195  1.1  mrg 			  " \"memory_operand\" \"\")";
    196  1.1  mrg 	    in
    197  1.1  mrg 		if ldst=ld then sets reg mem
    198  1.1  mrg 		else sets mem reg
    199  1.1  mrg 	    end;
    200  1.1  mrg 
    201  1.1  mrg 	fun single_sets i =
    202  1.1  mrg 	    if i=n then []
    203  1.1  mrg 	    else (single_set i "   ") :: (single_sets (i+1));
    204  1.1  mrg 
    205  1.1  mrg 	val scratch = ints (2*n);
    206  1.1  mrg 	val peephole_elements =
    207  1.1  mrg 	    let val tmp = single_sets 0 in
    208  1.1  mrg 		if scratch_p
    209  1.1  mrg 		then (["(match_scratch:SI " ^ scratch ^ " \"r\")"] @
    210  1.1  mrg 		      tmp @
    211  1.1  mrg 		      ["(match_dup " ^ scratch ^ ")"])
    212  1.1  mrg 		else tmp
    213  1.1  mrg 	    end;
    214  1.1  mrg     in
    215  1.1  mrg 	"(define_peephole2\n" ^
    216  1.1  mrg 	"  [" ^ (String.concatWith ("\n   ") peephole_elements) ^ "]\n" ^
    217  1.1  mrg 	"  \"TARGET_HAS_CDX\"\n" ^
    218  1.1  mrg 	"  [(const_int 0)]\n" ^
    219  1.1  mrg 	"{\n" ^
    220  1.1  mrg 	"  if (gen_ldstwm_peep (" ^
    221  1.1  mrg 	(if ldst=st then "false" else "true") ^ ", " ^ (ints n) ^ ", " ^ 
    222  1.1  mrg 	(if scratch_p then ("operands[" ^ scratch ^ "]") else "NULL_RTX") ^
    223  1.1  mrg 	", operands))\n" ^
    224  1.1  mrg 	"    DONE;\n" ^
    225  1.1  mrg 	"  else\n" ^
    226  1.1  mrg 	"    FAIL;\n" ^
    227  1.1  mrg 	"})\n\n"
    228  1.1  mrg     end;
    229  1.1  mrg 
    230  1.1  mrg 
    231  1.1  mrg print
    232  1.1  mrg ("/* Nios II R2 CDX ldwm/stwm/push.h/pop.n instruction patterns.\n" ^
    233  1.1  mrg  "   This file was automatically generated using nios2-ldstwm.sml.\n" ^
    234  1.1  mrg  "   Please do not edit manually.\n" ^
    235  1.1  mrg  "\n" ^
    236  1.1  mrg  "   Copyright (C) 2014-2016 Free Software Foundation, Inc.\n" ^
    237  1.1  mrg  "   Contributed by Mentor Graphics.\n" ^
    238  1.1  mrg  "\n" ^
    239  1.1  mrg  "   This file is part of GCC.\n" ^
    240  1.1  mrg  "\n" ^
    241  1.1  mrg  "   GCC is free software; you can redistribute it and/or modify it\n" ^
    242  1.1  mrg  "   under the terms of the GNU General Public License as published\n" ^
    243  1.1  mrg  "   by the Free Software Foundation; either version 3, or (at your\n" ^
    244  1.1  mrg  "   option) any later version.\n" ^
    245  1.1  mrg  "\n" ^
    246  1.1  mrg  "   GCC is distributed in the hope that it will be useful, but WITHOUT\n" ^
    247  1.1  mrg  "   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n" ^
    248  1.1  mrg  "   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\n" ^
    249  1.1  mrg  "   License for more details.\n" ^
    250  1.1  mrg  "\n" ^
    251  1.1  mrg  "   You should have received a copy of the GNU General Public License and\n" ^
    252  1.1  mrg  "   a copy of the GCC Runtime Library Exception along with this program;\n" ^
    253  1.1  mrg  "   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n" ^
    254  1.1  mrg  "   <http://www.gnu.org/licenses/>.  */\n\n");
    255  1.1  mrg 
    256  1.1  mrg fun seq a b = if a=b then [b]
    257  1.1  mrg 	      else a :: (seq (if a<b then a+1 else a-1) b);
    258  1.1  mrg 
    259  1.1  mrg (* push/pop patterns *)
    260  1.1  mrg for (seq 0 8) (fn n =>
    261  1.1  mrg   for [push, pop] (fn p =>
    262  1.1  mrg     for [true, false] (fn fp =>
    263  1.1  mrg        print (pushpop_pattern p n fp))));
    264  1.1  mrg 
    265  1.1  mrg (* ldwm/stwm patterns *)
    266  1.1  mrg for [ld, st] (fn l =>
    267  1.1  mrg   for (seq 1 12) (fn n =>
    268  1.1  mrg     for [inc, dec] (fn id =>
    269  1.1  mrg       for [true, false] (fn wb =>
    270  1.1  mrg         for [true, false] (fn pc =>
    271  1.1  mrg           print (ldstwm_pattern l n id wb pc))))));
    272  1.1  mrg 
    273  1.1  mrg (* peephole patterns *)
    274  1.1  mrg for [ld, st] (fn l =>
    275  1.1  mrg   for (seq 12 2) (fn n =>
    276  1.1  mrg     print (peephole_pattern l n true)));
    277  1.1  mrg 
    278