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