OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [arm/] [arm-ldmstm.ml] - Blame information for rev 711

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
(* Auto-generate ARM ldm/stm patterns
2
   Copyright (C) 2010 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
   .
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 "  \"(((operands[%d] == operands[0] && operands[%d] == operands[1])\n" (nregs * 2 + 2) (nregs * 2 + 3);
220
  Printf.printf "     || (operands[%d] == operands[0] && operands[%d] == operands[1]))\n" (nregs * 2 + 3) (nregs * 2 + 2);
221
  Printf.printf "    && peep2_reg_dead_p (%d, operands[0]) && peep2_reg_dead_p (%d, operands[1]))\"\n" (nregs + 1) (nregs + 1);
222
  begin
223
    if thumb then
224
      Printf.printf "  [(set (match_dup %d) (match_op_dup %d [(match_dup %d) (match_dup %d)]))]\n"
225
        (nregs * 2) (nregs * 2 + 1) (nregs * 2 + 2) (nregs * 2 + 3)
226
    else begin
227
      Printf.printf "  [(parallel\n";
228
      Printf.printf "    [(set (match_dup %d) (match_op_dup %d [(match_dup %d) (match_dup %d)]))\n"
229
        (nregs * 2) (nregs * 2 + 1) (nregs * 2 + 2) (nregs * 2 + 3);
230
      Printf.printf "     (clobber (reg:CC CC_REGNUM))])]\n"
231
    end
232
  end;
233
  Printf.printf "{\n  if (!gen_ldm_seq (operands, %d, true))\n    FAIL;\n" nregs;
234
  Printf.printf "})\n\n"
235
 
236
let write_ldm_peephole nregs =
237
  Printf.printf "(define_peephole2\n";
238
  write_peep_sets (write_ldm_peep_set "" nregs) 0 true nregs;
239
  Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
240
  Printf.printf "  if (gen_ldm_seq (operands, %d, false))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
241
 
242
let write_ldm_peephole_b nregs =
243
  if nregs > 2 then begin
244
    Printf.printf "(define_peephole2\n";
245
    write_ldm_peep_set "" nregs 0 true;
246
    Printf.printf "\n   (parallel\n";
247
    write_peep_sets (write_ldm_peep_set "  " nregs) 1 true (nregs - 1);
248
    Printf.printf "])]\n  \"\"\n  [(const_int 0)]\n{\n";
249
    Printf.printf "  if (gen_ldm_seq (operands, %d, false))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
250
  end
251
 
252
let write_stm_peephole nregs =
253
  Printf.printf "(define_peephole2\n";
254
  write_peep_sets (write_stm_peep_set "" nregs) 0 true nregs;
255
  Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
256
  Printf.printf "  if (gen_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
257
 
258
let write_stm_peephole_b nregs =
259
  if nregs > 2 then begin
260
    Printf.printf "(define_peephole2\n";
261
    write_stm_peep_set "" nregs 0 true;
262
    Printf.printf "\n   (parallel\n";
263
    write_peep_sets (write_stm_peep_set "" nregs) 1 true (nregs - 1);
264
    Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
265
    Printf.printf "  if (gen_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
266
  end
267
 
268
let write_const_stm_peephole_a nregs =
269
  Printf.printf "(define_peephole2\n";
270
  write_peep_sets (write_const_stm_peep_set nregs) 0 true nregs;
271
  Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
272
  Printf.printf "  if (gen_const_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
273
 
274
let write_const_stm_peephole_b nregs =
275
  Printf.printf "(define_peephole2\n";
276
  write_peep_sets (write_any_load "const_int_operand" nregs) 0 true nregs;
277
  Printf.printf "\n";
278
  write_peep_sets (write_const_store nregs) 0 false nregs;
279
  Printf.printf "]\n  \"\"\n  [(const_int 0)]\n{\n";
280
  Printf.printf "  if (gen_const_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n" nregs
281
 
282
let patterns () =
283
  let addrmodes = [ IA; IB; DA; DB ]  in
284
  let sizes = [ 4; 3; 2] in
285
  List.iter
286
    (fun n ->
287
      List.iter
288
        (fun addrmode ->
289
          write_ldm_pattern addrmode n false;
290
          write_ldm_pattern addrmode n true;
291
          write_stm_pattern addrmode n false;
292
          write_stm_pattern addrmode n true)
293
        addrmodes;
294
      write_ldm_peephole n;
295
      write_ldm_peephole_b n;
296
      write_const_stm_peephole_a n;
297
      write_const_stm_peephole_b n;
298
      write_stm_peephole n;)
299
    sizes;
300
  write_ldm_commutative_peephole false;
301
  write_ldm_commutative_peephole true
302
 
303
let print_lines = List.iter (fun s -> Format.printf "%s@\n" s)
304
 
305
(* Do it.  *)
306
 
307
let _ =
308
  print_lines [
309
"/* ARM ldm/stm instruction patterns.  This file was automatically generated";
310
"   using arm-ldmstm.ml.  Please do not edit manually.";
311
"";
312
"   Copyright (C) 2010 Free Software Foundation, Inc.";
313
"   Contributed by CodeSourcery.";
314
"";
315
"   This file is part of GCC.";
316
"";
317
"   GCC is free software; you can redistribute it and/or modify it";
318
"   under the terms of the GNU General Public License as published";
319
"   by the Free Software Foundation; either version 3, or (at your";
320
"   option) any later version.";
321
"";
322
"   GCC is distributed in the hope that it will be useful, but WITHOUT";
323
"   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY";
324
"   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public";
325
"   License for more details.";
326
"";
327
"   You should have received a copy of the GNU General Public License and";
328
"   a copy of the GCC Runtime Library Exception along with this program;";
329
"   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see";
330
"   .  */";
331
""];
332
  patterns ();

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.