remove unused files
[platform/upstream/gcc48.git] / gcc / config / arm / arm-ldmstm.ml
1 (* Auto-generate ARM ldm/stm patterns
2    Copyright (C) 2010-2013 Free Software Foundation, Inc.
3    Contributed by CodeSourcery.
4
5    This file is part of GCC.
6
7    GCC is free software; you can redistribute it and/or modify it under
8    the terms of the GNU General Public License as published by the Free
9    Software Foundation; either version 3, or (at your option) any later
10    version.
11
12    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13    WARRANTY; without even the implied warranty of MERCHANTABILITY or
14    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15    for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GCC; see the file COPYING3.  If not see
19    <http://www.gnu.org/licenses/>.
20
21    This is an O'Caml program.  The O'Caml compiler is available from:
22
23      http://caml.inria.fr/
24
25    Or from your favourite OS's friendly packaging system. Tested with version
26    3.09.2, though other versions will probably work too.
27
28    Run with:
29      ocaml arm-ldmstm.ml >/path/to/gcc/config/arm/ldmstm.md
30 *)
31
32 type amode = IA | IB | DA | DB
33
34 type optype = IN | OUT | INOUT
35
36 let rec string_of_addrmode addrmode =
37   match addrmode with
38     IA -> "ia" | IB -> "ib" | DA -> "da" | DB -> "db"
39
40 let rec initial_offset addrmode nregs =
41   match addrmode with
42     IA -> 0
43   | IB -> 4
44   | DA -> -4 * nregs + 4
45   | DB -> -4 * nregs
46
47 let rec final_offset addrmode nregs =
48   match addrmode with
49     IA -> nregs * 4
50   | IB -> nregs * 4
51   | DA -> -4 * nregs
52   | DB -> -4 * nregs
53
54 let constr thumb =
55   if thumb then "l" else "rk"
56
57 let inout_constr op_type =
58   match op_type with
59   OUT -> "=&"
60   | INOUT -> "+&"
61   | IN -> ""
62
63 let destreg nregs first op_type thumb =
64   if not first then
65     Printf.sprintf "(match_dup %d)" (nregs + 1)
66   else
67     Printf.sprintf ("(match_operand:SI %d \"s_register_operand\" \"%s%s\")")
68       (nregs + 1) (inout_constr op_type) (constr thumb)
69
70 let write_ldm_set thumb nregs offset opnr first =
71   let indent = "     " in
72   Printf.printf "%s" (if first then "    [" else indent);
73   Printf.printf "(set (match_operand:SI %d \"arm_hard_register_operand\" \"\")\n" opnr;
74   Printf.printf "%s     (mem:SI " indent;
75   begin if offset != 0 then Printf.printf "(plus:SI " end;
76   Printf.printf "%s" (destreg nregs first IN thumb);
77   begin if offset != 0 then Printf.printf "\n%s             (const_int %d))" indent offset end;
78   Printf.printf "))"
79
80 let write_stm_set thumb nregs offset opnr first =
81   let indent = "     " in
82   Printf.printf "%s" (if first then "    [" else indent);
83   Printf.printf "(set (mem:SI ";
84   begin if offset != 0 then Printf.printf "(plus:SI " end;
85   Printf.printf "%s" (destreg nregs first IN thumb);
86   begin if offset != 0 then Printf.printf " (const_int %d))" offset end;
87   Printf.printf ")\n%s     (match_operand:SI %d \"arm_hard_register_operand\" \"\"))" indent opnr 
88
89 let write_ldm_peep_set extra_indent nregs opnr first =
90   let indent = "   " ^ extra_indent in
91   Printf.printf "%s" (if first then extra_indent ^ "  [" else indent);
92   Printf.printf "(set (match_operand:SI %d \"s_register_operand\" \"\")\n" opnr;
93   Printf.printf "%s     (match_operand:SI %d \"memory_operand\" \"\"))" indent (nregs + opnr)
94
95 let write_stm_peep_set extra_indent nregs opnr first =
96   let indent = "   " ^ extra_indent in
97   Printf.printf "%s" (if first then extra_indent ^ "  [" else indent);
98   Printf.printf "(set (match_operand:SI %d \"memory_operand\" \"\")\n" (nregs + opnr);
99   Printf.printf "%s     (match_operand:SI %d \"s_register_operand\" \"\"))" indent opnr
100
101 let write_any_load optype nregs opnr first =
102   let indent = "   " in
103   Printf.printf "%s" (if first then "  [" else indent);
104   Printf.printf "(set (match_operand:SI %d \"s_register_operand\" \"\")\n" opnr;
105   Printf.printf "%s     (match_operand:SI %d \"%s\" \"\"))" indent (nregs * 2 + opnr) optype
106
107 let write_const_store nregs opnr first =
108   let indent = "   " in
109   Printf.printf "%s(set (match_operand:SI %d \"memory_operand\" \"\")\n" indent (nregs + opnr);
110   Printf.printf "%s     (match_dup %d))" indent opnr
111
112 let write_const_stm_peep_set nregs opnr first =
113   write_any_load "const_int_operand" nregs opnr first;
114   Printf.printf "\n";
115   write_const_store nregs opnr false
116
117   
118 let rec write_pat_sets func opnr offset first n_left =
119   func offset opnr first;
120   begin
121     if n_left > 1 then begin
122       Printf.printf "\n";
123       write_pat_sets func (opnr + 1) (offset + 4) false (n_left - 1);
124     end else
125       Printf.printf "]"
126   end
127
128 let rec write_peep_sets func opnr first n_left =
129   func opnr first;
130   begin
131     if n_left > 1 then begin
132       Printf.printf "\n";
133       write_peep_sets func (opnr + 1) false (n_left - 1);
134     end
135   end
136     
137 let can_thumb addrmode update is_store =
138   match addrmode, update, is_store with
139     (* Thumb1 mode only supports IA with update.  However, for LDMIA,
140        if the address register also appears in the list of loaded
141        registers, the loaded value is stored, hence the RTL pattern
142        to describe such an insn does not have an update.  We check
143        in the match_parallel predicate that the condition described
144        above is met.  *)
145     IA, _, false -> true
146   | IA, true, true -> true
147   | _ -> false
148
149 let target addrmode thumb =
150   match addrmode, thumb with
151     IA, true -> "TARGET_THUMB1"
152   | IA, false -> "TARGET_32BIT"
153   | DB, false -> "TARGET_32BIT"
154   | _, false -> "TARGET_ARM"
155
156 let write_pattern_1 name ls addrmode nregs write_set_fn update thumb =
157   let astr = string_of_addrmode addrmode in
158   Printf.printf "(define_insn \"*%s%s%d_%s%s\"\n"
159     (if thumb then "thumb_" else "") name nregs astr
160     (if update then "_update" else "");
161   Printf.printf "  [(match_parallel 0 \"%s_multiple_operation\"\n" ls;
162   begin
163     if update then begin
164       Printf.printf "    [(set %s\n          (plus:SI %s"
165         (destreg nregs true INOUT thumb) (destreg nregs false IN thumb);
166       Printf.printf " (const_int %d)))\n"
167         (final_offset addrmode nregs)
168     end
169   end;
170   write_pat_sets
171     (write_set_fn thumb nregs) 1
172     (initial_offset addrmode nregs)
173     (not update) nregs;
174   Printf.printf ")]\n  \"%s && XVECLEN (operands[0], 0) == %d\"\n"
175     (target addrmode thumb)
176     (if update then nregs + 1 else nregs);
177   Printf.printf "  \"%s%%(%s%%)\\t%%%d%s, {"
178     name astr (nregs + 1) (if update then "!" else "");
179   for n = 1 to nregs; do
180     Printf.printf "%%%d%s" n (if n < nregs then ", " else "")
181   done;
182   Printf.printf "}\"\n";
183   Printf.printf "  [(set_attr \"type\" \"%s%d\")" ls nregs;
184   begin if not thumb then
185     Printf.printf "\n   (set_attr \"predicable\" \"yes\")";
186   end;
187   Printf.printf "])\n\n"
188
189 let write_ldm_pattern addrmode nregs update =
190   write_pattern_1 "ldm" "load" addrmode nregs write_ldm_set update false;
191   begin if can_thumb addrmode update false then
192     write_pattern_1 "ldm" "load" addrmode nregs write_ldm_set update true;
193   end
194
195 let write_stm_pattern addrmode nregs update =
196   write_pattern_1 "stm" "store" addrmode nregs write_stm_set update false;
197   begin if can_thumb addrmode update true then
198     write_pattern_1 "stm" "store" addrmode nregs write_stm_set update true;
199   end
200
201 let write_ldm_commutative_peephole thumb =
202   let nregs = 2 in
203   Printf.printf "(define_peephole2\n";
204   write_peep_sets (write_ldm_peep_set "" nregs) 0 true nregs;
205   let indent = "   " in
206   if thumb then begin
207     Printf.printf "\n%s(set (match_operand:SI %d \"s_register_operand\" \"\")\n" indent (nregs * 2);
208     Printf.printf "%s     (match_operator:SI %d \"commutative_binary_operator\"\n" indent (nregs * 2 + 1);
209     Printf.printf "%s      [(match_operand:SI %d \"s_register_operand\" \"\")\n" indent (nregs * 2 + 2);
210     Printf.printf "%s       (match_operand:SI %d \"s_register_operand\" \"\")]))]\n" indent (nregs * 2 + 3)
211   end else begin
212     Printf.printf "\n%s(parallel\n" indent;
213     Printf.printf "%s  [(set (match_operand:SI %d \"s_register_operand\" \"\")\n" indent (nregs * 2);
214     Printf.printf "%s        (match_operator:SI %d \"commutative_binary_operator\"\n" indent (nregs * 2 + 1);
215     Printf.printf "%s         [(match_operand:SI %d \"s_register_operand\" \"\")\n" indent (nregs * 2 + 2);
216     Printf.printf "%s          (match_operand:SI %d \"s_register_operand\" \"\")]))\n" indent (nregs * 2 + 3);
217     Printf.printf "%s   (clobber (reg:CC CC_REGNUM))])]\n" indent
218   end;
219   Printf.printf "  \"((((REGNO (operands[%d]) == REGNO (operands[0]))\n" (nregs * 2 + 2);
220   Printf.printf "         && (REGNO (operands[%d]) == REGNO (operands[1])))\n"  (nregs * 2 + 3);
221   Printf.printf "      || ((REGNO (operands[%d]) == REGNO (operands[0]))\n" (nregs * 2 + 3);
222   Printf.printf "         && (REGNO (operands[%d]) == REGNO (operands[1]))))\n" (nregs * 2 + 2);
223   Printf.printf "    && (peep2_regno_dead_p (%d, REGNO (operands[0]))\n" (nregs + 1);
224   Printf.printf "      || (REGNO (operands[0]) == REGNO (operands[%d])))\n"  (nregs * 2);
225   Printf.printf "    && (peep2_regno_dead_p (%d, REGNO (operands[1]))\n" (nregs + 1);
226   Printf.printf "      || (REGNO (operands[1]) == REGNO (operands[%d]))))\"\n" (nregs * 2);
227   begin
228     if thumb then
229       Printf.printf "  [(set (match_dup %d) (match_op_dup %d [(match_dup %d) (match_dup %d)]))]\n"
230         (nregs * 2) (nregs * 2 + 1) (nregs * 2 + 2) (nregs * 2 + 3)
231     else begin
232       Printf.printf "  [(parallel\n";
233       Printf.printf "    [(set (match_dup %d) (match_op_dup %d [(match_dup %d) (match_dup %d)]))\n"
234         (nregs * 2) (nregs * 2 + 1) (nregs * 2 + 2) (nregs * 2 + 3);
235       Printf.printf "     (clobber (reg:CC CC_REGNUM))])]\n"
236     end
237   end;
238   Printf.printf "{\n  if (!gen_ldm_seq (operands, %d, true))\n    FAIL;\n" nregs;
239   Printf.printf "})\n\n"
240
241 let write_ldm_peephole nregs =
242   Printf.printf "(define_peephole2\n";
243   write_peep_sets (write_ldm_peep_set "" nregs) 0 true nregs;
244   Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
245   Printf.printf "  if (gen_ldm_seq (operands, %d, false))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
246
247 let write_ldm_peephole_b nregs =
248   if nregs > 2 then begin
249     Printf.printf "(define_peephole2\n";
250     write_ldm_peep_set "" nregs 0 true;
251     Printf.printf "\n   (parallel\n";
252     write_peep_sets (write_ldm_peep_set "  " nregs) 1 true (nregs - 1);
253     Printf.printf "])]\n  \"\"\n  [(const_int 0)]\n{\n";
254     Printf.printf "  if (gen_ldm_seq (operands, %d, false))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
255   end
256
257 let write_stm_peephole nregs =
258   Printf.printf "(define_peephole2\n";
259   write_peep_sets (write_stm_peep_set "" nregs) 0 true nregs;
260   Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
261   Printf.printf "  if (gen_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
262
263 let write_stm_peephole_b nregs =
264   if nregs > 2 then begin
265     Printf.printf "(define_peephole2\n";
266     write_stm_peep_set "" nregs 0 true;
267     Printf.printf "\n   (parallel\n";
268     write_peep_sets (write_stm_peep_set "" nregs) 1 true (nregs - 1);
269     Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
270     Printf.printf "  if (gen_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
271   end
272
273 let write_const_stm_peephole_a nregs =
274   Printf.printf "(define_peephole2\n";
275   write_peep_sets (write_const_stm_peep_set nregs) 0 true nregs;
276   Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
277   Printf.printf "  if (gen_const_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
278
279 let write_const_stm_peephole_b nregs =
280   Printf.printf "(define_peephole2\n";
281   write_peep_sets (write_any_load "const_int_operand" nregs) 0 true nregs;
282   Printf.printf "\n";
283   write_peep_sets (write_const_store nregs) 0 false nregs;
284   Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
285   Printf.printf "  if (gen_const_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
286
287 let patterns () =
288   let addrmodes = [ IA; IB; DA; DB ]  in
289   let sizes = [ 4; 3; 2] in
290   List.iter
291     (fun n ->
292       List.iter
293         (fun addrmode ->
294           write_ldm_pattern addrmode n false;
295           write_ldm_pattern addrmode n true;
296           write_stm_pattern addrmode n false;
297           write_stm_pattern addrmode n true)
298         addrmodes;
299       write_ldm_peephole n;
300       write_ldm_peephole_b n;
301       write_const_stm_peephole_a n;
302       write_const_stm_peephole_b n;
303       write_stm_peephole n;)
304     sizes;
305   write_ldm_commutative_peephole false;
306   write_ldm_commutative_peephole true
307
308 let print_lines = List.iter (fun s -> Format.printf "%s@\n" s)
309
310 (* Do it.  *)
311
312 let _ = 
313   print_lines [
314 "/* ARM ldm/stm instruction patterns.  This file was automatically generated";
315 "   using arm-ldmstm.ml.  Please do not edit manually.";
316 "";
317 "   Copyright (C) 2010-2013 Free Software Foundation, Inc.";
318 "   Contributed by CodeSourcery.";
319 "";
320 "   This file is part of GCC.";
321 "";
322 "   GCC is free software; you can redistribute it and/or modify it";
323 "   under the terms of the GNU General Public License as published";
324 "   by the Free Software Foundation; either version 3, or (at your";
325 "   option) any later version.";
326 "";
327 "   GCC is distributed in the hope that it will be useful, but WITHOUT";
328 "   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY";
329 "   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public";
330 "   License for more details.";
331 "";
332 "   You should have received a copy of the GNU General Public License and";
333 "   a copy of the GCC Runtime Library Exception along with this program;";
334 "   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see";
335 "   <http://www.gnu.org/licenses/>.  */";
336 ""];
337   patterns ();