Store have no memory proj
[libfirm] / ir / be / arm / arm_spec.pl
1 # Creation: 2006/02/13
2 # $Id$
3 # This is a template specification for the Firm-Backend
4
5 # the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
6
7 $arch = "arm";
8 $new_emit_syntax = 1;
9
10 # the number of additional opcodes you want to register
11 #$additional_opcodes = 0;
12
13 # The node description is done as a perl hash initializer with the
14 # following structure:
15 #
16 # %nodes = (
17 #
18 # <op-name> => {
19 #   op_flags  => "N|L|C|X|I|F|Y|H|c|K",
20 #   irn_flags => "R|N|I|S"
21 #   arity     => "0|1|2|3 ... |variable|dynamic|any",
22 #   state     => "floats|pinned|mem_pinned|exc_pinned",
23 #   args      => [
24 #                    { type => "type 1", name => "name 1" },
25 #                    { type => "type 2", name => "name 2" },
26 #                    ...
27 #                  ],
28 #   comment   => "any comment for constructor",
29 #   reg_req   => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] },
30 #   cmp_attr  => "c source code for comparing node attributes",
31 #   emit      => "emit code with templates",
32 #   attr      => "attitional attribute arguments for constructor"
33 #   init_attr => "emit attribute initialization template"
34 #   rd_constructor => "c source code which constructs an ir_node"
35 #   latency   => "latency of this operation (can be float)"
36 #   attr_type => "name of the attribute struct",
37 # },
38 #
39 # ... # (all nodes you need to describe)
40 #
41 # ); # close the %nodes initializer
42
43 # op_flags: flags for the operation, OPTIONAL (default is "N")
44 # the op_flags correspond to the firm irop_flags:
45 #   N   irop_flag_none
46 #   L   irop_flag_labeled
47 #   C   irop_flag_commutative
48 #   X   irop_flag_cfopcode
49 #   I   irop_flag_ip_cfopcode
50 #   F   irop_flag_fragile
51 #   Y   irop_flag_forking
52 #   H   irop_flag_highlevel
53 #   c   irop_flag_constlike
54 #   K   irop_flag_keep
55 #
56 # irn_flags: special node flags, OPTIONAL (default is 0)
57 # following irn_flags are supported:
58 #   R   rematerializeable
59 #   N   not spillable
60 #   I   ignore for register allocation
61 #   S   modifies stack pointer
62 #
63 # state: state of the operation, OPTIONAL (default is "floats")
64 #
65 # arity: arity of the operation, MUST NOT BE OMITTED
66 #
67 # args:  the OPTIONAL arguments of the node constructor (debug, irg and block
68 #        are always the first 3 arguments and are always autmatically
69 #        created)
70 #        If this key is missing the following arguments will be created:
71 #        for i = 1 .. arity: ir_node *op_i
72 #        ir_mode *mode
73 #
74 # outs:  if a node defines more than one output, the names of the projections
75 #        nodes having outs having automatically the mode mode_T
76 #        One can also annotate some flags for each out, additional to irn_flags.
77 #        They are separated from name with a colon ':', and concatenated by pipe '|'
78 #        Only I and S are available at the moment (same meaning as in irn_flags).
79 #        example: [ "frame:I", "stack:I|S", "M" ]
80 #
81 # comment: OPTIONAL comment for the node constructor
82 #
83 # rd_constructor: for every operation there will be a
84 #      new_rd_<arch>_<op-name> function with the arguments from above
85 #      which creates the ir_node corresponding to the defined operation
86 #      you can either put the complete source code of this function here
87 #
88 #      This key is OPTIONAL. If omitted, the following constructor will
89 #      be created:
90 #      if (!op_<arch>_<op-name>) assert(0);
91 #      for i = 1 to arity
92 #         set in[i] = op_i
93 #      done
94 #      res = new_ir_node(db, irg, block, op_<arch>_<op-name>, mode, arity, in)
95 #      return res
96 #
97 # NOTE: rd_constructor and args are only optional if and only if arity is 0,1,2 or 3
98 #
99 # latency: the latency of the operation, default is 1
100 #
101
102 # register types:
103 #   0 - no special type
104 #   1 - caller save (register must be saved by the caller of a function)
105 #   2 - callee save (register must be saved by the called function)
106 #   4 - ignore (do not assign this register)
107 #   8 - emitter can choose an arbitrary register of this class
108 #  16 - the register is a virtual one
109 #  32 - register represents a state
110 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
111 %reg_classes = (
112   gp => [
113                          { "name" => "r0", "type" => 1 },
114                          { "name" => "r1", "type" => 1 },
115                          { "name" => "r2", "type" => 1 },
116                          { "name" => "r3", "type" => 1 },
117                          { "name" => "r4", "type" => 2 },
118                          { "name" => "r5", "type" => 2 },
119                          { "name" => "r6", "type" => 2 },
120                          { "name" => "r7", "type" => 2 },
121                          { "name" => "r8", "type" => 2 },
122                          { "name" => "r9", "type" => 2 },
123                          { "name" => "r10", "type" => 2 },
124                          { "name" => "r11", "type" => 2 },
125                          { "name" => "r12", "type" => 6 }, # reserved for linker
126                          { "name" => "sp", "type" => 6 }, # this is our stack pointer
127                          { "name" => "lr", "type" => 3 }, # this is our return address
128                          { "name" => "pc", "type" => 6 }, # this is our program counter
129                          { "mode" => "mode_Iu" }
130                        ],
131   fpa  => [
132                          { "name" => "f0", "type" => 1 },
133                          { "name" => "f1", "type" => 1 },
134                          { "name" => "f2", "type" => 1 },
135                          { "name" => "f3", "type" => 1 },
136                          { "name" => "f4", "type" => 1 },
137                          { "name" => "f5", "type" => 1 },
138                          { "name" => "f6", "type" => 1 },
139                          { "name" => "f7", "type" => 1 },
140                          { "mode" => "mode_E" }
141                        ]
142 ); # %reg_classes
143
144 %emit_templates = (
145     M  => "${arch}_emit_mode(env, node);",
146     X  => "${arch}_emit_shift(env, node);",
147     S0 => "${arch}_emit_source_register(env, node, 0);",
148     S1 => "${arch}_emit_source_register(env, node, 1);",
149     S2 => "${arch}_emit_source_register(env, node, 2);",
150     S3 => "${arch}_emit_source_register(env, node, 3);",
151     S4 => "${arch}_emit_source_register(env, node, 4);",
152     D0 => "${arch}_emit_dest_register(env, node, 0);",
153     D1 => "${arch}_emit_dest_register(env, node, 1);",
154     D2 => "${arch}_emit_dest_register(env, node, 2);",
155         C  => "${arch}_emit_immediate(env, node);",
156         O  => "${arch}_emit_offset(env, mode);",
157 );
158
159 #--------------------------------------------------#
160 #                        _                         #
161 #                       (_)                        #
162 #  _ __   _____      __  _ _ __    ___  _ __  ___  #
163 # | '_ \ / _ \ \ /\ / / | | '__|  / _ \| '_ \/ __| #
164 # | | | |  __/\ V  V /  | | |    | (_) | |_) \__ \ #
165 # |_| |_|\___| \_/\_/   |_|_|     \___/| .__/|___/ #
166 #                                      | |         #
167 #                                      |_|         #
168 #--------------------------------------------------#
169
170 $default_attr_type = "arm_attr_t";
171
172 %init_attr = (
173         arm_attr_t           => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);",
174         arm_SymConst_attr_t  => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);",
175         arm_CondJmp_attr_t   => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);",
176         arm_SwitchJmp_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);",
177 );
178
179 %compare_attr = (
180         arm_attr_t           => "cmp_attr_arm",
181         arm_SymConst_attr_t  => "cmp_attr_arm_SymConst",
182         arm_CondJmp_attr_t   => "cmp_attr_arm_CondJmp",
183         arm_SwitchJmp_attr_t => "cmp_attr_arm_SwitchJmp",
184 );
185
186 %nodes = (
187
188 #-----------------------------------------------------------------#
189 #  _       _                                         _            #
190 # (_)     | |                                       | |           #
191 #  _ _ __ | |_ ___  __ _  ___ _ __   _ __   ___   __| | ___  ___  #
192 # | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| #
193 # | | | | | ||  __/ (_| |  __/ |    | | | | (_) | (_| |  __/\__ \ #
194 # |_|_| |_|\__\___|\__, |\___|_|    |_| |_|\___/ \__,_|\___||___/ #
195 #                   __/ |                                         #
196 #                  |___/                                          #
197 #-----------------------------------------------------------------#
198
199 # commutative operations
200
201 Add => {
202   op_flags  => "C",
203   irn_flags => "R",
204   comment   => "construct Add: Add(a, b) = Add(b, a) = a + b",
205   attr      => "arm_shift_modifier mod, tarval *shf",
206   init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
207   cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
208   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
209   emit      => '. add %D0, %S0, %S1%X'
210 },
211
212 Add_i => {
213   irn_flags => "R",
214   comment   => "construct Add: Add(a, const) = Add(const, a) = a + const",
215   attr      => "tarval *tv",
216   init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
217   cmp_attr  => 'return attr_a->value != attr_b->value;',
218   reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
219   emit      => '. add %D0, %S0, %C'
220 },
221
222 Mul => {
223   #op_flags  => "C",
224   irn_flags => "R",
225   comment   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
226   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "!in_r1" ] },
227   emit      =>'. mul %D0, %S0, %S1'
228 },
229
230 Smull => {
231   #op_flags  => "C",
232   irn_flags => "R",
233   comment   => "construct signed 64bit Mul: Mul(a, b) = Mul(b, a) = a * b",
234   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] },
235   emit      =>'. smull %D0, %D1, %S0, %S1',
236   outs      => [ "low", "high" ],
237 },
238
239 Umull => {
240   #op_flags  => "C",
241   irn_flags => "R",
242   comment   => "construct unsigned 64bit Mul: Mul(a, b) = Mul(b, a) = a * b",
243   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] },
244   emit      =>'. umull %D0, %D1, %S0, %S1',
245   outs      => [ "low", "high" ],
246 },
247
248 Mla => {
249   #op_flags  => "C",
250   irn_flags => "R",
251   comment   => "construct Mla: Mla(a, b, c) = a * b + c",
252   reg_req   => { "in" => [ "gp", "gp", "gp" ], "out" => [ "!in_r1" ] },
253   emit      =>'. mla %D0, %S0, %S1, %S2'
254 },
255
256 And => {
257   op_flags  => "C",
258   irn_flags => "R",
259   comment   => "construct And: And(a, b) = And(b, a) = a AND b",
260   attr      => "arm_shift_modifier mod, tarval *shf",
261   init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
262   cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
263   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
264   emit      => '. and %D0, %S0, %S1%X'
265 },
266
267 And_i => {
268   irn_flags => "R",
269   comment   => "construct And: And(a, const) = And(const, a) = a AND const",
270   attr      => "tarval *tv",
271   init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
272   reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
273   emit      => '. and %D0, %S0, %C',
274   cmp_attr  => 'return attr_a->value != attr_b->value;'
275 },
276
277 Or => {
278   op_flags  => "C",
279   irn_flags => "R",
280   comment   => "construct Or: Or(a, b) = Or(b, a) = a OR b",
281   attr      => "arm_shift_modifier mod, tarval *shf",
282   init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
283   cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
284   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
285   emit      => '. orr %D0, %S0, %S1%X'
286 },
287
288 Or_i => {
289   irn_flags => "R",
290   comment   => "construct Or: Or(a, const) = Or(const, a) = a OR const",
291   attr      => "tarval *tv",
292   init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
293   reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
294   cmp_attr  => 'return attr_a->value != attr_b->value;',
295   emit      => '. orr %D0, %S0, %C'
296 },
297
298 Eor => {
299   op_flags  => "C",
300   irn_flags => "R",
301   comment   => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
302   attr      => "arm_shift_modifier mod, tarval *shf",
303   init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
304   cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
305   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
306   emit      => '. eor %D0, %S0, %S1%X'
307 },
308
309 Eor_i => {
310   irn_flags => "R",
311   comment   => "construct Eor: Eor(a, const) = Eor(const, a) = a EOR const",
312   attr      => "tarval *tv",
313   init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
314   reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
315   cmp_attr  => 'return attr_a->value != attr_b->value;',
316   emit      => '. eor %D0, %S0, %C'
317 },
318
319 # not commutative operations
320
321 Bic => {
322   irn_flags => "R",
323   comment   => "construct Bic: Bic(a, b) = a AND ~b",
324   attr      => "arm_shift_modifier mod, tarval *shf",
325   init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
326   cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
327   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
328   emit      => '. bic %D0, %S0, %S1%X'
329 },
330
331 Bic_i => {
332   irn_flags => "R",
333   comment   => "construct Bic: Bic(a, const) = a AND ~const",
334   attr      => "tarval *tv",
335   init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
336   reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
337   emit      => '. bic %D0, %S0, %C',
338   cmp_attr  => 'return attr_a->value != attr_b->value;'
339 },
340
341 Sub => {
342   irn_flags => "R",
343   comment   => "construct Sub: Sub(a, b) = a - b",
344   attr      => "arm_shift_modifier mod, tarval *shf",
345   init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
346   cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
347   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
348   emit      => '. sub %D0, %S0, %S1%X'
349 },
350
351 Sub_i => {
352   irn_flags => "R",
353   comment   => "construct Sub: Sub(a, const) = a - const",
354   attr      => "tarval *tv",
355   init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
356   cmp_attr  => 'return attr_a->value != attr_b->value;',
357   reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
358   emit      => '. sub %D0, %S0, %C',
359 },
360
361 Rsb => {
362   irn_flags => "R",
363   comment   => "construct Rsb: Rsb(a, b) = b - a",
364   attr      => "arm_shift_modifier mod, tarval *shf",
365   init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
366   cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
367   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
368   emit      => '. rsb %D0, %S0, %S1%X'
369 },
370
371 Rsb_i => {
372   irn_flags => "R",
373   comment   => "construct Rsb: Rsb(a, const) = const - a",
374   attr      => "tarval *tv",
375   init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
376   reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
377   emit      => '. rsb %D0, %S0, %C',
378   cmp_attr  => 'return attr_a->value != attr_b->value;'
379 },
380
381 Shl => {
382   irn_flags => "R",
383   comment   => "construct Shl: Shl(a, b) = a << b",
384   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
385   emit      => '. mov %D0, %S0, lsl %S1'
386 },
387
388 Shr => {
389   irn_flags => "R",
390   comment   => "construct Shr: Shr(a, b) = a >> b",
391   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
392   emit      => '. mov %D0, %S0, lsr %S1'
393 },
394
395 Shrs => {
396   irn_flags => "R",
397   comment   => "construct Shrs: Shrs(a, b) = a >> b",
398   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
399   emit      => '. mov %D0, %S0, asr %S1'
400 },
401
402 #RotR => {
403 #  irn_flags => "R",
404 #  comment   => "construct RotR: RotR(a, b) = a ROTR b",
405 #  reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
406 #  emit      => '. mov %D0, %S0, ror %S1 /* RotR(%S0, %S1) -> %D0, (%A1, %A2) */'
407 ##  emit      => '. ror %S0, %S1, %D0'
408 #},
409
410 #RotL => {
411 #  irn_flags => "R",
412 #  comment   => "construct RotL: RotL(a, b) = a ROTL b",
413 #  reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
414 #  emit      => '. rol %S0, %S1, %D0'
415 #},
416
417 #RotL_i => {
418 #  irn_flags => "R",
419 #  comment   => "construct RotL: RotL(a, const) = a ROTL const",
420 #  reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
421 #  emit      => '. rol %S0, %C, %D0'
422 #},
423
424 Mov => {
425   irn_flags => "R",
426   comment   => "construct Mov: a = b",
427   attr      => "arm_shift_modifier mod, tarval *shf",
428   init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
429   cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
430   reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
431   emit      => '. mov %D0, %S0%X'
432 },
433
434 Mov_i => {
435   irn_flags => "R",
436   comment   => "represents an integer constant",
437   attr      => "tarval *tv",
438   init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
439   reg_req   => { "out" => [ "gp" ] },
440   emit      => '. mov %D0, %C',
441   cmp_attr  => 'return attr_a->value != attr_b->value;'
442 },
443
444 Mvn => {
445   irn_flags => "R",
446   comment   => "construct Not: Not(a) = !a",
447   attr      => "arm_shift_modifier mod, tarval *shf",
448   init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;',
449   cmp_attr  => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);',
450   reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
451   emit      => '. mvn %D0, %S0%X'
452 },
453
454 Mvn_i => {
455   irn_flags => "R",
456   comment   => "represents a negated integer constant",
457   attr      => "tarval *tv",
458   init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;',
459   cmp_attr  => 'return attr_a->value != attr_b->value;',
460   reg_req   => { "out" => [ "gp" ] },
461   emit      => '. mvn %D0, %C',
462 },
463
464 Abs => {
465   irn_flags => "R",
466   comment   => "construct Abs: Abs(a) = |a|",
467   reg_req   => { "in" => [ "gp" ], "out" => [ "gp" ] },
468   emit      =>
469 '. movs %S0, %S0, #0
470 . rsbmi %D0, %S0, #0'
471 },
472
473 # other operations
474
475 #
476 # this node produces ALWAYS an empty (tempary) gp reg and cannot be CSE'd
477 #
478 EmptyReg => {
479   op_flags  => "c",
480   irn_flags => "R",
481   comment   => "allocate an empty register for calculations",
482   reg_req   => { "out" => [ "gp" ] },
483   emit      => '. /* %D0 now available for calculations */',
484   cmp_attr  => 'return 1;'
485 },
486
487 Copy => {
488   comment  => "implements a register copy",
489   reg_req  => { "in" => [ "gp" ], "out" => [ "gp" ] },
490 },
491
492 CopyB => {
493   op_flags => "F|H",
494   state    => "pinned",
495   comment  => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)",
496   attr      => "tarval *tv",
497   init_attr => 'attr->value = tv;',
498   reg_req  => { "in" => [ "!sp", "!sp", "gp", "gp", "gp", "none" ], "out" => [ "none" ] },
499   outs     => [ "M" ],
500 },
501
502 SymConst => {
503   op_flags  => "c",
504   irn_flags => "R",
505   comment   => "represents a symbolic constant",
506   attr      => "ident *id",
507   init_attr => "\tset_arm_symconst_id(res, id);",
508   reg_req   => { "out" => [ "gp" ] },
509   attr_type   => "arm_SymConst_attr_t",
510 },
511
512 CondJmp => {
513   op_flags  => "L|X|Y",
514   comment   => "construct conditional jump: CMP A, B && JMPxx LABEL",
515   mode      => "mode_T",
516   attr      => "int proj_num",
517   init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
518   reg_req   => { "in" => [ "gp", "gp" ], "out" => [ "none", "none"] },
519   attr_type => "arm_CondJmp_attr_t",
520 },
521
522 SwitchJmp => {
523   op_flags  => "L|X|Y",
524   comment   => "construct switch",
525   mode      => "mode_T",
526   attr      => "int n_projs, long def_proj_num",
527   init_attr => "\tset_arm_SwitchJmp_n_projs(res, n_projs);\n".
528                  "\tset_arm_SwitchJmp_default_proj_num(res, def_proj_num);",
529   reg_req   => { "in" => [ "gp" ], "out" => [ "none" ] },
530   attr_type => "arm_SwitchJmp_attr_t",
531 },
532
533 # Load / Store
534
535 Load => {
536   op_flags  => "L|F",
537   irn_flags => "R",
538   state     => "exc_pinned",
539   comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
540   reg_req   => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
541   emit      => '. ldr %D0, [%S0, #0]',
542   outs      => [ "res", "M" ],
543 },
544
545 Loadb => {
546   op_flags  => "L|F",
547   irn_flags => "R",
548   state     => "exc_pinned",
549   comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
550   reg_req   => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
551   emit      => '. ldrb %D0, [%S0, #0]',
552   outs      => [ "res", "M" ],
553 },
554
555 Loadbs => {
556   op_flags  => "L|F",
557   irn_flags => "R",
558   state     => "exc_pinned",
559   comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
560   reg_req   => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
561   emit      => '. ldrsb %D0, [%S0, #0]',
562   outs      => [ "res", "M" ],
563 },
564
565 Loadh => {
566   op_flags  => "L|F",
567   irn_flags => "R",
568   state     => "exc_pinned",
569   comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
570   reg_req   => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
571   emit      => '. ldrh %D0, [%S0, #0]',
572   outs      => [ "res", "M" ],
573 },
574
575 Loadhs => {
576   op_flags  => "L|F",
577   irn_flags => "R",
578   state     => "exc_pinned",
579   comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
580   reg_req   => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
581   emit      => '. ldrsh %D0, [%S0, #0]',
582   outs      => [ "res", "M" ],
583 },
584
585 Storeb => {
586   op_flags  => "L|F",
587   irn_flags => "R",
588   state     => "exc_pinned",
589   comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
590   reg_req   => { "in" => [ "gp", "gp", "none" ], "out" => [ "none" ] },
591   emit      => '. strb %S1, [%S0, #0]',
592   mode      => "mode_M",
593 },
594
595 Storeh => {
596   op_flags  => "L|F",
597   irn_flags => "R",
598   state     => "exc_pinned",
599   comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
600   reg_req   => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] },
601   emit      => '. strh %S1, [%S0, #0]',
602   mode      => "mode_M",
603 },
604
605 Store => {
606   op_flags  => "L|F",
607   irn_flags => "R",
608   state     => "exc_pinned",
609   comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
610   reg_req   => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] },
611   emit      => '. str %S1, [%S0, #0]',
612   mode      => "mode_M",
613 },
614
615 StoreStackM4Inc => {
616   op_flags  => "L|F",
617   irn_flags => "R",
618   state     => "exc_pinned",
619   comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
620   reg_req   => { "in" => [ "sp", "gp", "gp", "gp", "gp", "none" ], "out" => [ "gp", "none" ] },
621   emit      => '. stmfd %S0!, {%S1, %S2, %S3, %S4}',
622   outs      => [ "ptr", "M" ],
623 },
624
625 LoadStackM3 => {
626   op_flags  => "L|F",
627   irn_flags => "R",
628   state     => "exc_pinned",
629   comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
630   reg_req   => { "in" => [ "sp", "none" ], "out" => [ "gp", "gp", "gp", "none" ] },
631   emit      => '. ldmfd %S0, {%D0, %D1, %D2}',
632   outs      => [ "res0", "res1", "res2", "M" ],
633 },
634
635
636 #---------------------------------------------------#
637 #    __                               _             #
638 #   / _|                             | |            #
639 #  | |_ _ __   __ _   _ __   ___   __| | ___  ___   #
640 #  |  _| '_ \ / _` | | '_ \ / _ \ / _` |/ _ \/ __|  #
641 #  | | | |_) | (_| | | | | | (_) | (_| |  __/\__ \  #
642 #  |_| | .__/ \__,_| |_| |_|\___/ \__,_|\___||___/  #
643 #      | |                                          #
644 #      |_|                                          #
645 #---------------------------------------------------#
646
647 # commutative operations
648
649 fpaAdd => {
650   op_flags  => "C",
651   irn_flags => "R",
652   comment   => "construct FPA Add: Add(a, b) = Add(b, a) = a + b",
653   reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
654   emit      => '. adf%M %D0, %S0, %S1',
655 },
656
657 fpaMul => {
658   op_flags  => "C",
659   comment   => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b",
660   reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
661   emit      =>'. muf%M %D0, %S0, %S1',
662 },
663
664 fpaFMul => {
665   op_flags  => "C",
666   comment   => "construct FPA Fast Mul: Mul(a, b) = Mul(b, a) = a * b",
667   reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
668   emit      =>'. fml%M %D0, %S0, %S1',
669 },
670
671 fpaMax => {
672   op_flags  => "C",
673   irn_flags => "R",
674   comment   => "construct FPA Max: Max(a, b) = Max(b, a) = a > b ? a : b",
675   reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
676   emit      =>'. fmax %S0, %S1, %D0',
677 },
678
679 fpaMin => {
680   op_flags  => "C",
681   irn_flags => "R",
682   comment   => "construct FPA Min: Min(a, b) = Min(b, a) = a < b ? a : b",
683   reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
684   emit      =>'. fmin %S0, %S1, %D0',
685 },
686
687 # not commutative operations
688
689 fpaSub => {
690   irn_flags => "R",
691   comment   => "construct FPA Sub: Sub(a, b) = a - b",
692   reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
693   emit      => '. suf%M %D0, %S0, %S1'
694 },
695
696 fpaRsb => {
697   irn_flags => "R",
698   comment   => "construct FPA reverse Sub: Sub(a, b) = b - a",
699   reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
700   emit      => '. rsf%M %D0, %S0, %S1'
701 },
702
703 fpaDiv => {
704   comment   => "construct FPA Div: Div(a, b) = a / b",
705   attr      => "ir_mode *op_mode",
706   init_attr => "attr->op_mode = op_mode;",
707   reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] },
708   emit      =>'. dvf%M %D0, %S0, %S1',
709   outs      => [ "res", "M" ],
710 },
711
712 fpaRdv => {
713   comment   => "construct FPA reverse Div: Div(a, b) = b / a",
714   attr      => "ir_mode *op_mode",
715   init_attr => "attr->op_mode = op_mode;",
716   reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] },
717   emit      =>'. rdf%M %D0, %S0, %S1',
718   outs      => [ "res", "M" ],
719 },
720
721 fpaFDiv => {
722   comment   => "construct FPA Fast Div: Div(a, b) = a / b",
723   attr      => "ir_mode *op_mode",
724   init_attr => "attr->op_mode = op_mode;",
725   reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] },
726   emit      =>'. fdv%M %D0, %S0, %S1',
727   outs      => [ "res", "M" ],
728 },
729
730 fpaFRdv => {
731   comment   => "construct FPA Fast reverse Div: Div(a, b) = b / a",
732   attr      => "ir_mode *op_mode",
733   init_attr => "attr->op_mode = op_mode;",
734   reg_req   => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] },
735   emit      =>'. frd%M %D0, %S0, %S1',
736   outs      => [ "res", "M" ],
737 },
738
739 fpaMov => {
740   irn_flags => "R",
741   comment   => "construct FPA Move: b = a",
742   reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
743   emit      => '. mvf%M %S0, %D0',
744 },
745
746 fpaMnv => {
747   irn_flags => "R",
748   comment   => "construct FPA Move Negated: b = -a",
749   reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
750   emit      => '. mnf%M %S0, %D0',
751 },
752
753 fpaAbs => {
754   irn_flags => "R",
755   comment   => "construct FPA Absolute value: fAbsd(a) = |a|",
756   reg_req   => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
757   emit      => '. abs%M %D0, %S0',
758 },
759
760 # other operations
761
762 fpaFlt => {
763   irn_flags => "R",
764   comment   => "construct a FPA integer->float conversion",
765   reg_req   => { "in" => ["gp"], "out" => [ "fpa" ] },
766   emit      => '. flt%M %D0, %S0',
767 },
768
769 fpaFix => {
770   irn_flags => "R",
771   comment   => "construct a FPA float->integer conversion",
772   reg_req   => { "in" => ["fpa"], "out" => [ "gp" ] },
773   emit      => '. fix %D0, %S0',
774 },
775
776 # Load / Store
777
778 fpaLdf => {
779   op_flags  => "L|F",
780   irn_flags => "R",
781   state     => "exc_pinned",
782   comment   => "construct FPA Load: Load(ptr, mem) = LD ptr",
783   attr      => "ir_mode *op_mode",
784   init_attr => "attr->op_mode = op_mode;",
785   reg_req   => { "in" => [ "gp", "none" ], "out" => [ "fpa", "none" ] },
786   emit      => '. ldf%M %D0, [%S0, #0]',
787   outs      => [ "res", "M" ],
788 },
789
790 fpaStf => {
791   op_flags  => "L|F",
792   irn_flags => "R",
793   state     => "exc_pinned",
794   comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
795   attr      => "ir_mode *op_mode",
796   init_attr => "attr->op_mode = op_mode;",
797   reg_req   => { "in" => [ "gp", "fpa", "none" ], "out" => [ "none" ] },
798   emit      => '. stf%M [%S1, #0], %S0',
799   outs      => [ "M" ],
800 },
801
802 fpaDbl2GP => {
803   op_flags  => "L|F",
804   irn_flags => "R",
805   comment   => "construct fp double to 2 gp register transfer",
806   reg_req   => { "in" => [ "fpa", "none" ], "out" => [ "gp", "gp", "none" ] },
807   outs      => [ "low", "high", "M" ],
808 },
809
810 AddSP => {
811   irn_flags => "I",
812   comment   => "construct Add to stack pointer",
813   reg_req   => { in => [ "sp", "gp", "none" ], out => [ "in_r1", "none" ] },
814   emit      => '. add %D0, %S0, %S1',
815   outs      => [ "stack:S", "M" ],
816 },
817
818 SubSP => {
819   irn_flags => "I",
820   comment   => "construct Sub from stack pointer",
821   reg_req   => { in => [ "sp", "gp", "none" ], out => [ "in_r1", "none" ] },
822   emit      => '. sub %D0, %S0, %S1',
823   outs      => [ "stack:S", "M" ],
824 },
825
826 LdTls => {
827   irn_flags => "R",
828   comment   => "load the TLS address",
829   reg_req   => { out => [ "gp" ] },
830 },
831
832
833 #
834 # floating point constants
835 #
836 fpaConst => {
837   op_flags  => "c",
838   irn_flags => "R",
839   comment   => "construct a floating point constant",
840   attr      => "tarval *tv",
841   init_attr => "attr->value = tv;",
842   mode      => "get_tarval_mode(tv)",
843   reg_req   => { "out" => [ "fpa" ] },
844 }
845
846 #---------------------------------------------------#
847 #          __                         _             #
848 #         / _|                       | |            #
849 #  __   _| |_ _ __    _ __   ___   __| | ___  ___   #
850 #  \ \ / /  _| '_ \  | '_ \ / _ \ / _` |/ _ \/ __|  #
851 #   \ V /| | | |_) | | | | | (_) | (_| |  __/\__ \  #
852 #    \_/ |_| | .__/  |_| |_|\___/ \__,_|\___||___/  #
853 #            | |                                    #
854 #            |_|                                    #
855 #---------------------------------------------------#
856
857 ); # end of %nodes