Removed C99 features and fixed 2 wrong assertions.
[libfirm] / ir / be / arm / arm_spec.pl
1 # Creation: 2006/02/13
2 # $Id$
3
4 # the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
5
6 $arch = "arm";
7
8 #
9 # Modes
10 #
11 $mode_gp      = "mode_Iu";
12 $mode_flags   = "mode_Bu";
13 $mode_fpa     = "mode_E";
14
15 # register types:
16 $normal      =  0; # no special type
17 $caller_save =  1; # caller save (register must be saved by the caller of a function)
18 $callee_save =  2; # callee save (register must be saved by the called function)
19 $ignore      =  4; # ignore (do not assign this register)
20 $arbitrary   =  8; # emitter can choose an arbitrary register of this class
21 $virtual     = 16; # the register is a virtual one
22 $state       = 32; # register represents a state
23 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
24 %reg_classes = (
25         gp => [
26                 { name => "r0",  type => $caller_save },
27                 { name => "r1",  type => $caller_save },
28                 { name => "r2",  type => $caller_save },
29                 { name => "r3",  type => $caller_save },
30                 { name => "r4",  type => $callee_save },
31                 { name => "r5",  type => $callee_save },
32                 { name => "r6",  type => $callee_save },
33                 { name => "r7",  type => $callee_save },
34                 { name => "r8",  type => $callee_save },
35                 { name => "r9",  type => $callee_save },
36                 { name => "r10", type => $callee_save },
37                 { name => "r11", type => $callee_save },
38                 { name => "r12", type => $ignore }, # reserved for linker/immediate fixups
39                 { name => "sp",  type => $ignore }, # this is our stack pointer
40                 { name => "lr",  type => $callee_save | $caller_save }, # this is our return address
41                 { name => "pc",  type => $ignore }, # this is our program counter
42                 { mode => $mode_gp }
43         ],
44         fpa  => [
45                 { name => "f0", type => $caller_save },
46                 { name => "f1", type => $caller_save },
47                 { name => "f2", type => $caller_save },
48                 { name => "f3", type => $caller_save },
49                 { name => "f4", type => $caller_save },
50                 { name => "f5", type => $caller_save },
51                 { name => "f6", type => $caller_save },
52                 { name => "f7", type => $caller_save },
53                 { mode => $mode_fpa }
54         ],
55         flags => [
56                 { name => "fl", type => 0 },
57                 { mode => $mode_flags, flags => "manual_ra" }
58         ],
59 );
60
61 %emit_templates = (
62         M   => "${arch}_emit_mode(node);",
63         LM  => "${arch}_emit_load_mode(node);",
64         SM  => "${arch}_emit_store_mode(node);",
65         SO  => "${arch}_emit_shifter_operand(node);",
66         S0  => "${arch}_emit_source_register(node, 0);",
67         S1  => "${arch}_emit_source_register(node, 1);",
68         S2  => "${arch}_emit_source_register(node, 2);",
69         S3  => "${arch}_emit_source_register(node, 3);",
70         S4  => "${arch}_emit_source_register(node, 4);",
71         D0  => "${arch}_emit_dest_register(node, 0);",
72         D1  => "${arch}_emit_dest_register(node, 1);",
73         D2  => "${arch}_emit_dest_register(node, 2);",
74         O   => "${arch}_emit_offset(node);",
75 );
76
77 $default_attr_type = "arm_attr_t";
78 $default_copy_attr = "arm_copy_attr";
79
80 %init_attr = (
81         arm_attr_t           => "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);",
82         arm_SymConst_attr_t  =>
83                 "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);\n".
84                 "\tinit_arm_SymConst_attributes(res, entity);",
85         arm_CondJmp_attr_t   => "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);",
86         arm_SwitchJmp_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);",
87         arm_fpaConst_attr_t  => "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);",
88         arm_load_store_attr_t =>
89                 "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);\n".
90                 "\tinit_arm_load_store_attributes(res, ls_mode, entity, entity_sign, offset, is_frame_entity);",
91         arm_shifter_operand_t =>
92                 "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);\n",
93         arm_cmp_attr_t =>
94                 "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);\n",
95         arm_CopyB_attr_t =>
96                 "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);\n".
97                 "\tinit_arm_CopyB_attributes(res, size);",
98 );
99
100 %compare_attr = (
101         arm_attr_t            => "cmp_attr_arm",
102         arm_SymConst_attr_t   => "cmp_attr_arm_SymConst",
103         arm_CondJmp_attr_t    => "cmp_attr_arm_CondJmp",
104         arm_SwitchJmp_attr_t  => "cmp_attr_arm_SwitchJmp",
105         arm_fpaConst_attr_t   => "cmp_attr_arm_fpaConst",
106         arm_load_store_attr_t => "cmp_attr_arm_load_store",
107         arm_shifter_operand_t => "cmp_attr_arm_shifter_operand",
108         arm_CopyB_attr_t      => "cmp_attr_arm_CopyB",
109         arm_cmp_attr_t        => "cmp_attr_arm_cmp",
110 );
111
112 my %unop_shifter_operand_constructors = (
113         imm => {
114                 attr       => "unsigned char immediate_value, unsigned char immediate_rot",
115                 custominit => "init_arm_shifter_operand(res, immediate_value, ARM_SHF_IMM, immediate_rot);",
116                 reg_req    => { in => [], out => [ "gp" ] },
117         },
118         reg => {
119                 custominit => "init_arm_shifter_operand(res, 0, ARM_SHF_REG, 0);",
120                 reg_req    => { in => [ "gp" ], out => [ "gp" ] },
121         },
122         reg_shift_reg => {
123                 attr       => "arm_shift_modifier shift_modifier",
124                 custominit => "init_arm_shifter_operand(res, 0, shift_modifier, 0);",
125                 reg_req    => { in => [ "gp", "gp" ], out => [ "gp" ] },
126         },
127         reg_shift_imm => {
128                 attr       => "arm_shift_modifier shift_modifier, unsigned shift_immediate",
129                 custominit => "init_arm_shifter_operand(res, 0, shift_modifier, shift_immediate);",
130                 reg_req    => { in => [ "gp" ], out => [ "gp" ] },
131         },
132 );
133
134 my %binop_shifter_operand_constructors = (
135         imm => {
136                 attr       => "unsigned char immediate_value, unsigned char immediate_rot",
137                 custominit => "init_arm_shifter_operand(res, immediate_value, ARM_SHF_IMM, immediate_rot);",
138                 reg_req    => { in => [ "gp" ], out => [ "gp" ] },
139                 ins        => [ "left" ],
140         },
141         reg => {
142                 custominit => "init_arm_shifter_operand(res, 0, ARM_SHF_REG, 0);",
143                 reg_req    => { in => [ "gp", "gp" ], out => [ "gp" ] },
144                 ins        => [ "left", "right" ],
145         },
146         reg_shift_reg => {
147                 attr       => "arm_shift_modifier shift_modifier",
148                 custominit => "init_arm_shifter_operand(res, 0, shift_modifier, 0);",
149                 reg_req    => { in => [ "gp", "gp", "gp" ], out => [ "gp" ] },
150                 ins        => [ "left", "right", "shift" ],
151         },
152         reg_shift_imm => {
153                 attr       => "arm_shift_modifier shift_modifier, unsigned shift_immediate",
154                 custominit => "init_arm_shifter_operand(res, 0, shift_modifier, shift_immediate);",
155                 reg_req    => { in => [ "gp", "gp" ], out => [ "gp" ] },
156                 ins        => [ "left", "right" ],
157         },
158 );
159
160 my %cmp_shifter_operand_constructors = (
161         imm => {
162                 attr       => "unsigned char immediate_value, unsigned char immediate_rot, bool ins_permuted, bool is_unsigned",
163                 custominit =>
164                         "init_arm_shifter_operand(res, immediate_value, ARM_SHF_IMM, immediate_rot);\n".
165                         "\tinit_arm_cmp_attr(res, ins_permuted, is_unsigned);",
166                 reg_req    => { in => [ "gp" ], out => [ "flags" ] },
167                 ins        => [ "left" ],
168         },
169         reg => {
170                 attr       => "bool ins_permuted, bool is_unsigned",
171                 custominit =>
172                         "init_arm_shifter_operand(res, 0, ARM_SHF_REG, 0);\n".
173                         "\tinit_arm_cmp_attr(res, ins_permuted, is_unsigned);",
174                 reg_req    => { in => [ "gp", "gp" ], out => [ "flags" ] },
175                 ins        => [ "left", "right" ],
176         },
177         reg_shift_reg => {
178                 attr       => "arm_shift_modifier shift_modifier, bool ins_permuted, bool is_unsigned",
179                 custominit =>
180                         "init_arm_shifter_operand(res, 0, shift_modifier, 0);\n".
181                         "\tinit_arm_cmp_attr(res, ins_permuted, is_unsigned);",
182                 reg_req    => { in => [ "gp", "gp", "gp" ], out => [ "flags" ] },
183                 ins        => [ "left", "right", "shift" ],
184         },
185         reg_shift_imm => {
186                 attr       => "arm_shift_modifier shift_modifier, unsigned shift_immediate, bool ins_permuted, bool is_unsigned",
187                 custominit =>
188                         "init_arm_shifter_operand(res, 0, shift_modifier, shift_immediate);\n".
189                         "\tinit_arm_cmp_attr(res, ins_permuted, is_unsigned);",
190                 reg_req    => { in => [ "gp", "gp" ], out => [ "flags" ] },
191                 ins        => [ "left", "right" ],
192         },
193 );
194
195
196 %nodes = (
197
198 Add => {
199         irn_flags => "R",
200         emit      => '. add %D0, %S0, %SO',
201         mode      => $mode_gp,
202         attr_type => "arm_shifter_operand_t",
203         constructors => \%binop_shifter_operand_constructors,
204 },
205
206 Mul => {
207         irn_flags => "R",
208         reg_req   => { in => [ "gp", "gp" ], out => [ "!in_r1" ] },
209         emit      =>'. mul %D0, %S0, %S1',
210         mode      => $mode_gp,
211 },
212
213 Smull => {
214         irn_flags => "R",
215         reg_req   => { in => [ "gp", "gp" ], out => [ "gp", "gp" ] },
216         emit      =>'. smull %D0, %D1, %S0, %S1',
217         outs      => [ "low", "high" ],
218 },
219
220 Umull => {
221         irn_flags => "R",
222         reg_req   => { in => [ "gp", "gp" ], out => [ "gp", "gp" ] },
223         emit      =>'. umull %D0, %D1, %S0, %S1',
224         outs      => [ "low", "high" ],
225         mode      => $mode_gp,
226 },
227
228 Mla => {
229         irn_flags => "R",
230         reg_req   => { in => [ "gp", "gp", "gp" ], out => [ "!in_r1" ] },
231         emit      =>'. mla %D0, %S0, %S1, %S2',
232         mode      => $mode_gp,
233 },
234
235 And => {
236         irn_flags => "R",
237         emit      => '. and %D0, %S0, %SO',
238         mode      => $mode_gp,
239         attr_type => "arm_shifter_operand_t",
240         constructors => \%binop_shifter_operand_constructors,
241 },
242
243 Or => {
244         irn_flags => "R",
245         emit      => '. orr %D0, %S0, %SO',
246         mode      => $mode_gp,
247         attr_type => "arm_shifter_operand_t",
248         constructors => \%binop_shifter_operand_constructors,
249 },
250
251 Eor => {
252         irn_flags => "R",
253         emit      => '. eor %D0, %S0, %SO',
254         mode      => $mode_gp,
255         attr_type => "arm_shifter_operand_t",
256         constructors => \%binop_shifter_operand_constructors,
257 },
258
259 Bic => {
260         irn_flags => "R",
261         emit      => '. bic %D0, %S0, %SO',
262         mode      => $mode_gp,
263         attr_type => "arm_shifter_operand_t",
264         constructors => \%binop_shifter_operand_constructors,
265 },
266
267 Sub => {
268         irn_flags => "R",
269         emit      => '. sub %D0, %S0, %SO',
270         mode      => $mode_gp,
271         attr_type => "arm_shifter_operand_t",
272         constructors => \%binop_shifter_operand_constructors,
273 },
274
275 Rsb => {
276         irn_flags => "R",
277         emit      => '. rsb %D0, %S0, %SO',
278         mode      => $mode_gp,
279         attr_type => "arm_shifter_operand_t",
280         constructors => \%binop_shifter_operand_constructors,
281 },
282
283 Mov => {
284         irn_flags => "R",
285         arity     => "variable",
286         emit      => '. mov %D0, %SO',
287         mode      => $mode_gp,
288         attr_type => "arm_shifter_operand_t",
289         constructors => \%unop_shifter_operand_constructors,
290 },
291
292 Mvn => {
293         irn_flags => "R",
294         attr_type => "arm_shifter_operand_t",
295         arity     => "variable",
296         emit      => '. mvn %D0, %SO',
297         mode      => $mode_gp,
298         constructors => \%unop_shifter_operand_constructors,
299 },
300
301 # Deprecated - we should construct the movs and rsbmi directly...
302 Abs => {
303         irn_flags => "R",
304         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
305         emit      =>
306 '. movs %S0, %S0, #0
307 . rsbmi %D0, %S0, #0',
308         mode      => $mode_gp,
309 },
310
311 # this node produces ALWAYS an empty (tempary) gp reg and cannot be CSE'd
312 EmptyReg => {
313         op_flags  => "c",
314         irn_flags => "R",
315         reg_req   => { out => [ "gp" ] },
316         emit      => '. /* %D0 now available for calculations */',
317         cmp_attr  => 'return 1;',
318         mode      => $mode_gp,
319 },
320
321 CopyB => {
322         op_flags  => "F|H",
323         state     => "pinned",
324         attr      => "unsigned size",
325         attr_type => "arm_CopyB_attr_t",
326         reg_req   => { in => [ "!sp", "!sp", "gp", "gp", "gp", "none" ], out => [ "none" ] },
327         outs      => [ "M" ],
328 },
329
330 FrameAddr => {
331         op_flags  => "c",
332         irn_flags => "R",
333         attr      => "ir_entity *entity",
334         reg_req   => { in => [ "gp" ], out => [ "gp" ] },
335         ins       => [ "base" ],
336         attr_type => "arm_SymConst_attr_t",
337         mode      => $mode_gp,
338 },
339
340 SymConst => {
341         op_flags  => "c",
342         irn_flags => "R",
343         attr      => "ir_entity *entity",
344         reg_req   => { out => [ "gp" ] },
345         attr_type => "arm_SymConst_attr_t",
346         mode      => $mode_gp,
347 },
348
349 Cmp => {
350         irn_flags    => "R|F",
351         emit         => '. cmp %S0, %SO',
352         mode         => $mode_flags,
353         attr_type    => "arm_cmp_attr_t",
354         constructors => \%cmp_shifter_operand_constructors,
355 },
356
357 Tst => {
358         irn_flags    => "R|F",
359         emit         => '. tst %S0, %SO',
360         mode         => $mode_flags,
361         attr_type    => "arm_cmp_attr_t",
362         constructors => \%cmp_shifter_operand_constructors,
363 },
364
365 B => {
366         op_flags  => "L|X|Y",
367         state     => "pinned",
368         mode      => "mode_T",
369         reg_req   => { in => [ "flags" ], out => [ "none", "none" ] },
370         attr      => "int proj_num",
371         attr_type => "arm_CondJmp_attr_t",
372         init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
373 },
374
375 Jmp => {
376         state     => "pinned",
377         op_flags  => "X",
378         irn_flags => "J",
379         reg_req   => { out => [ "none" ] },
380         mode      => "mode_X",
381 },
382
383 SwitchJmp => {
384         op_flags  => "L|X|Y",
385         state     => "pinned",
386         mode      => "mode_T",
387         attr      => "int n_projs, long def_proj_num",
388         init_attr => "\tset_arm_SwitchJmp_n_projs(res, n_projs);\n".
389                      "\tset_arm_SwitchJmp_default_proj_num(res, def_proj_num);",
390         reg_req   => { in => [ "gp" ], out => [ "none" ] },
391         attr_type => "arm_SwitchJmp_attr_t",
392 },
393
394 Ldr => {
395         op_flags  => "L|F",
396         state     => "exc_pinned",
397         ins       => [ "ptr", "mem" ],
398         outs      => [ "res", "M" ],
399         reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
400         emit      => '. ldr%LM %D0, [%S0, #%O]',
401         attr_type => "arm_load_store_attr_t",
402         attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
403 },
404
405 Str => {
406         op_flags  => "L|F",
407         state     => "exc_pinned",
408         ins       => [ "ptr", "val", "mem" ],
409         outs      => [ "mem" ],
410         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
411         emit      => '. str%SM %S1, [%S0, #%O]',
412         mode      => "mode_M",
413         attr_type => "arm_load_store_attr_t",
414         attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
415 },
416
417 StoreStackM4Inc => {
418         op_flags  => "L|F",
419         irn_flags => "R",
420         state     => "exc_pinned",
421         reg_req   => { in => [ "sp", "gp", "gp", "gp", "gp", "none" ], out => [ "sp:I|S", "none" ] },
422         emit      => '. stmfd %S0!, {%S1, %S2, %S3, %S4}',
423         outs      => [ "ptr", "M" ],
424 },
425
426 LoadStackM3Epilogue => {
427         op_flags  => "L|F",
428         irn_flags => "R",
429         state     => "exc_pinned",
430         reg_req   => { in => [ "sp", "none" ], out => [ "r11:I", "sp:I|S", "pc:I", "none" ] },
431         emit      => '. ldmfd %S0, {%D0, %D1, %D2}',
432         outs      => [ "res0", "res1", "res2", "M" ],
433 },
434
435
436
437 fpaAdf => {
438         irn_flags => "R",
439         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa" ] },
440         emit      => '. adf%M %D0, %S0, %S1',
441 },
442
443 fpaMuf => {
444         irn_flags => "R",
445         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa" ] },
446         emit      =>'. muf%M %D0, %S0, %S1',
447 },
448
449 fpaFml => {
450         irn_flags => "R",
451         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa" ] },
452         emit      =>'. fml%M %D0, %S0, %S1',
453 },
454
455 fpaMax => {
456         irn_flags => "R",
457         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa" ] },
458         emit      =>'. fmax %S0, %S1, %D0',
459 },
460
461 fpaMin => {
462         irn_flags => "R",
463         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa" ] },
464         emit      =>'. fmin %S0, %S1, %D0',
465 },
466
467 fpaSuf => {
468         irn_flags => "R",
469         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa" ] },
470         emit      => '. suf%M %D0, %S0, %S1'
471 },
472
473 fpaRsf => {
474         irn_flags => "R",
475         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa" ] },
476         emit      => '. rsf%M %D0, %S0, %S1'
477 },
478
479 fpaDvf => {
480         attr      => "ir_mode *op_mode",
481         init_attr => "attr->op_mode = op_mode;",
482         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa", "none" ] },
483         emit      =>'. dvf%M %D0, %S0, %S1',
484         outs      => [ "res", "M" ],
485 },
486
487 fpaRdf => {
488         attr      => "ir_mode *op_mode",
489         init_attr => "attr->op_mode = op_mode;",
490         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa", "none" ] },
491         emit      =>'. rdf%M %D0, %S0, %S1',
492         outs      => [ "res", "M" ],
493 },
494
495 fpaFdv => {
496         attr      => "ir_mode *op_mode",
497         init_attr => "attr->op_mode = op_mode;",
498         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa", "none" ] },
499         emit      =>'. fdv%M %D0, %S0, %S1',
500         outs      => [ "res", "M" ],
501 },
502
503 fpaFrd => {
504         attr      => "ir_mode *op_mode",
505         init_attr => "attr->op_mode = op_mode;",
506         reg_req   => { in => [ "fpa", "fpa" ], out => [ "fpa", "none" ] },
507         emit      =>'. frd%M %D0, %S0, %S1',
508         outs      => [ "res", "M" ],
509 },
510
511 fpaMvf => {
512         irn_flags => "R",
513         reg_req   => { in => [ "fpa" ], out => [ "fpa" ] },
514         emit      => '. mvf%M %S0, %D0',
515 },
516
517 fpaMnf => {
518         irn_flags => "R",
519         reg_req   => { in => [ "fpa" ], out => [ "fpa" ] },
520         emit      => '. mnf%M %S0, %D0',
521 },
522
523 fpaAbs => {
524         irn_flags => "R",
525         reg_req   => { in => [ "fpa" ], out => [ "fpa" ] },
526         emit      => '. abs%M %D0, %S0',
527 },
528
529 fpaFlt => {
530         irn_flags => "R",
531         reg_req   => { in => ["gp"], out => [ "fpa" ] },
532         emit      => '. flt%M %D0, %S0',
533 },
534
535 fpaFix => {
536         irn_flags => "R",
537         reg_req   => { in => ["fpa"], out => [ "gp" ] },
538         emit      => '. fix %D0, %S0',
539 },
540
541 fpaCmfBra => {
542         op_flags  => "L|X|Y",
543         state     => "pinned",
544         mode      => "mode_T",
545         attr      => "int proj_num",
546         init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
547         reg_req   => { in => [ "fpa", "fpa" ], out => [ "none", "none"] },
548         attr_type => "arm_CondJmp_attr_t",
549 },
550
551 fpaCnfBra => {
552         op_flags  => "L|X|Y",
553         state     => "pinned",
554         mode      => "mode_T",
555         attr      => "int proj_num",
556         init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
557         reg_req   => { in => [ "fpa", "fpa" ], out => [ "none", "none"] },
558         attr_type => "arm_CondJmp_attr_t",
559 },
560
561 fpaCmfeBra => {
562         op_flags  => "L|X|Y",
563         state     => "pinned",
564         mode      => "mode_T",
565         attr      => "int proj_num",
566         init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
567         reg_req   => { in => [ "fpa", "fpa" ], out => [ "none", "none"] },
568         attr_type => "arm_CondJmp_attr_t",
569 },
570
571 fpaCnfeBra => {
572         op_flags  => "L|X|Y",
573         state     => "pinned",
574         mode      => "mode_T",
575         attr      => "int proj_num",
576         init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
577         reg_req   => { in => [ "fpa", "fpa" ], out => [ "none", "none"] },
578         attr_type => "arm_CondJmp_attr_t",
579 },
580
581 fpaLdf => {
582         op_flags  => "L|F",
583         irn_flags => "R",
584         state     => "exc_pinned",
585         attr      => "ir_mode *op_mode",
586         init_attr => "attr->op_mode = op_mode;",
587         reg_req   => { in => [ "gp", "none" ], out => [ "fpa", "none" ] },
588         emit      => '. ldf%M %D0, [%S0]',
589         outs      => [ "res", "M" ],
590 },
591
592 fpaStf => {
593         op_flags  => "L|F",
594         irn_flags => "R",
595         state     => "exc_pinned",
596         attr      => "ir_mode *op_mode",
597         init_attr => "attr->op_mode = op_mode;",
598         reg_req   => { in => [ "gp", "fpa", "none" ], out => [ "none" ] },
599         emit      => '. stf%M %S1, [%S0]',
600         mode      => "mode_M",
601 },
602
603 fpaDbl2GP => {
604         op_flags  => "L|F",
605         irn_flags => "R",
606         reg_req   => { in => [ "fpa", "none" ], out => [ "gp", "gp", "none" ] },
607         outs      => [ "low", "high", "M" ],
608 },
609
610 AddSP => {
611         reg_req   => { in => [ "sp", "gp", "none" ], out => [ "sp:I|S", "none" ] },
612         emit      => '. add %D0, %S0, %S1',
613         outs      => [ "stack", "M" ],
614 },
615
616 SubSPandCopy => {
617         reg_req   => { in => [ "sp", "gp", "none" ], out => [ "sp:I|S", "gp", "none" ] },
618         ins       => [ "stack", "size", "mem" ],
619         emit      => ". sub %D0, %S0, %S1\n".
620                      ". mov sp, %D1",
621         outs      => [ "stack", "addr", "M" ],
622 },
623
624 LdTls => {
625         irn_flags => "R",
626         reg_req   => { out => [ "gp" ] },
627 },
628
629
630 #
631 # floating point constants
632 #
633 fpaConst => {
634         op_flags  => "c",
635         irn_flags => "R",
636         attr      => "tarval *tv",
637         init_attr => "attr->tv = tv;",
638         mode      => "get_tarval_mode(tv)",
639         reg_req   => { out => [ "fpa" ] },
640         attr_type => "arm_fpaConst_attr_t",
641 }
642
643 ); # end of %nodes