3 # This is a template specification for the Firm-Backend
5 # the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
9 # the number of additional opcodes you want to register
10 #$additional_opcodes = 0;
19 $normal = 0; # no special type
20 $caller_save = 1; # caller save (register must be saved by the caller of a function)
21 $callee_save = 2; # callee save (register must be saved by the called function)
22 $ignore = 4; # ignore (do not assign this register)
23 $arbitrary = 8; # emitter can choose an arbitrary register of this class
24 $virtual = 16; # the register is a virtual one
25 $state = 32; # register represents a state
26 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
29 { name => "r0", type => $caller_save },
30 { name => "r1", type => $caller_save },
31 { name => "r2", type => $caller_save },
32 { name => "r3", type => $caller_save },
33 { name => "r4", type => $callee_save },
34 { name => "r5", type => $callee_save },
35 { name => "r6", type => $callee_save },
36 { name => "r7", type => $callee_save },
37 { name => "r8", type => $callee_save },
38 { name => "r9", type => $callee_save },
39 { name => "r10", type => $callee_save },
40 { name => "r11", type => $callee_save },
41 { name => "r12", type => $ignore | $callee_save }, # reserved for linker
42 { name => "sp", type => $ignore | $callee_save }, # this is our stack pointer
43 { name => "lr", type => $callee_save | $caller_save }, # this is our return address
44 { name => "pc", type => $ignore | $callee_save }, # this is our program counter
45 { name => "gp_UKNWN", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for Unknown nodes
49 { name => "f0", type => $caller_save },
50 { name => "f1", type => $caller_save },
51 { name => "f2", type => $caller_save },
52 { name => "f3", type => $caller_save },
53 { name => "f4", type => $caller_save },
54 { name => "f5", type => $caller_save },
55 { name => "f6", type => $caller_save },
56 { name => "f7", type => $caller_save },
57 { name => "fpa_UKNWN", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for Unknown nodes
63 M => "${arch}_emit_mode(node);",
64 X => "${arch}_emit_shift(node);",
65 S0 => "${arch}_emit_source_register(node, 0);",
66 S1 => "${arch}_emit_source_register(node, 1);",
67 S2 => "${arch}_emit_source_register(node, 2);",
68 S3 => "${arch}_emit_source_register(node, 3);",
69 S4 => "${arch}_emit_source_register(node, 4);",
70 D0 => "${arch}_emit_dest_register(node, 0);",
71 D1 => "${arch}_emit_dest_register(node, 1);",
72 D2 => "${arch}_emit_dest_register(node, 2);",
73 C => "${arch}_emit_immediate(node);",
74 O => "${arch}_emit_offset(mode);",
77 #--------------------------------------------------#
80 # _ __ _____ __ _ _ __ ___ _ __ ___ #
81 # | '_ \ / _ \ \ /\ / / | | '__| / _ \| '_ \/ __| #
82 # | | | | __/\ V V / | | | | (_) | |_) \__ \ #
83 # |_| |_|\___| \_/\_/ |_|_| \___/| .__/|___/ #
86 #--------------------------------------------------#
88 $default_attr_type = "arm_attr_t";
89 $default_copy_attr = "arm_copy_attr";
92 arm_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);",
93 arm_SymConst_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);",
94 arm_CondJmp_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);",
95 arm_SwitchJmp_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);",
96 arm_fpaConst_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);",
97 arm_load_store_attr_t =>
98 "\tinit_arm_attributes(res, flags, in_reqs, exec_units, n_res);\n".
99 "\tinit_arm_load_store_attributes(res, entity, entity_sign, offset);",
103 arm_attr_t => "cmp_attr_arm",
104 arm_SymConst_attr_t => "cmp_attr_arm_SymConst",
105 arm_CondJmp_attr_t => "cmp_attr_arm_CondJmp",
106 arm_SwitchJmp_attr_t => "cmp_attr_arm_SwitchJmp",
107 arm_fpaConst_attr_t => "cmp_attr_arm_fpaConst",
108 arm_load_store_attr_t => "cmp_attr_arm_load_store",
114 # comment => "blup di dup",
116 # emit => ". [%S0]-10",
118 # attr => "tarval *tv",
119 # init_attr => "(void) attri;",
121 # # cmp => "return 1;"
127 # reg_req => { in => [ "gp" ] },
128 # attr => "tarval *tv",
129 # init_attr => "(void) tv;",
135 # reg_req => { in => [ "gp", "gp" ] },
145 reg_req => { out => [ "gp_UKNWN:I" ] },
153 reg_req => { out => [ "fpa_UKNWN:I" ] },
158 #-----------------------------------------------------------------#
161 # _ _ __ | |_ ___ __ _ ___ _ __ _ __ ___ __| | ___ ___ #
162 # | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| #
163 # | | | | | || __/ (_| | __/ | | | | | (_) | (_| | __/\__ \ #
164 # |_|_| |_|\__\___|\__, |\___|_| |_| |_|\___/ \__,_|\___||___/ #
167 #-----------------------------------------------------------------#
169 # commutative operations
174 comment => "construct Add: Add(a, b) = Add(b, a) = a + b",
175 attr => "arm_shift_modifier mod, long shf",
176 init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
177 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
178 emit => '. add %D0, %S0, %S1%X'
183 comment => "construct Add: Add(a, const) = Add(const, a) = a + const",
185 init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
186 reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
187 emit => '. add %D0, %S0, %C'
193 comment => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
194 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "!in_r1" ] },
195 emit =>'. mul %D0, %S0, %S1'
201 comment => "construct signed 64bit Mul: Mul(a, b) = Mul(b, a) = a * b",
202 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] },
203 emit =>'. smull %D0, %D1, %S0, %S1',
204 outs => [ "low", "high" ],
210 comment => "construct unsigned 64bit Mul: Mul(a, b) = Mul(b, a) = a * b",
211 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] },
212 emit =>'. umull %D0, %D1, %S0, %S1',
213 outs => [ "low", "high" ],
219 comment => "construct Mla: Mla(a, b, c) = a * b + c",
220 reg_req => { "in" => [ "gp", "gp", "gp" ], "out" => [ "!in_r1" ] },
221 emit =>'. mla %D0, %S0, %S1, %S2'
227 comment => "construct And: And(a, b) = And(b, a) = a AND b",
228 attr => "arm_shift_modifier mod, long shf",
229 init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
230 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
231 emit => '. and %D0, %S0, %S1%X'
236 comment => "construct And: And(a, const) = And(const, a) = a AND const",
238 init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
239 reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
240 emit => '. and %D0, %S0, %C',
246 comment => "construct Or: Or(a, b) = Or(b, a) = a OR b",
247 attr => "arm_shift_modifier mod, long shf",
248 init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
249 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
250 emit => '. orr %D0, %S0, %S1%X'
255 comment => "construct Or: Or(a, const) = Or(const, a) = a OR const",
257 init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
258 reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
259 emit => '. orr %D0, %S0, %C'
265 comment => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
266 attr => "arm_shift_modifier mod, long shf",
267 init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
268 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
269 emit => '. eor %D0, %S0, %S1%X'
274 comment => "construct Eor: Eor(a, const) = Eor(const, a) = a EOR const",
276 init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
277 reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
278 emit => '. eor %D0, %S0, %C'
281 # not commutative operations
285 comment => "construct Bic: Bic(a, b) = a AND ~b",
286 attr => "arm_shift_modifier mod, long shf",
287 init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
288 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
289 emit => '. bic %D0, %S0, %S1%X'
294 comment => "construct Bic: Bic(a, const) = a AND ~const",
296 init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
297 reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
298 emit => '. bic %D0, %S0, %C',
303 comment => "construct Sub: Sub(a, b) = a - b",
304 attr => "arm_shift_modifier mod, long shf",
305 init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
306 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
307 emit => '. sub %D0, %S0, %S1%X'
312 comment => "construct Sub: Sub(a, const) = a - const",
314 init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
315 reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
316 emit => '. sub %D0, %S0, %C',
321 comment => "construct Rsb: Rsb(a, b) = b - a",
322 attr => "arm_shift_modifier mod, long shf",
323 init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
324 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
325 emit => '. rsb %D0, %S0, %S1%X'
330 comment => "construct Rsb: Rsb(a, const) = const - a",
332 init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
333 reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
334 emit => '. rsb %D0, %S0, %C',
339 comment => "construct Shl: Shl(a, b) = a << b",
340 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
341 emit => '. mov %D0, %S0, lsl %S1'
346 comment => "construct Shr: Shr(a, b) = a >>u b",
347 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
348 emit => '. mov %D0, %S0, lsr %S1'
353 comment => "construct Shrs: Shrs(a, b) = a >>s b",
354 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
355 emit => '. mov %D0, %S0, asr %S1'
360 comment => "construct Ror: Ror(a, b) = a <<r>> b",
361 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
362 emit => '. mov %D0, %S0, ror %S1'
367 # comment => "construct RotL: RotL(a, b) = a ROTL b",
368 # reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
369 # emit => '. rol %S0, %S1, %D0'
374 # comment => "construct RotL: RotL(a, const) = a ROTL const",
375 # reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
376 # emit => '. rol %S0, %C, %D0'
381 comment => "construct Mov: a = b",
382 attr => "arm_shift_modifier mod, long shf",
383 init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
384 reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
385 emit => '. mov %D0, %S0%X'
390 comment => "represents an integer constant",
392 init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
393 reg_req => { "out" => [ "gp" ] },
394 emit => '. mov %D0, %C',
399 comment => "construct Not: Not(a) = !a",
400 attr => "arm_shift_modifier mod, long shf",
401 init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
402 reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
403 emit => '. mvn %D0, %S0%X'
408 comment => "represents a negated integer constant",
410 init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
411 reg_req => { "out" => [ "gp" ] },
412 emit => '. mvn %D0, %C',
417 comment => "construct Abs: Abs(a) = |a|",
418 reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
421 . rsbmi %D0, %S0, #0'
427 # this node produces ALWAYS an empty (tempary) gp reg and cannot be CSE'd
432 comment => "allocate an empty register for calculations",
433 reg_req => { "out" => [ "gp" ] },
434 emit => '. /* %D0 now available for calculations */',
435 cmp_attr => 'return 1;'
439 comment => "implements a register copy",
440 reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
446 comment => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)",
448 init_attr => 'attr->imm_value = imm;',
449 reg_req => { "in" => [ "!sp", "!sp", "gp", "gp", "gp", "none" ], "out" => [ "none" ] },
456 comment => "represents a symbolic constant",
458 init_attr => "\tset_arm_symconst_id(res, id);",
459 reg_req => { "out" => [ "gp" ] },
460 attr_type => "arm_SymConst_attr_t",
466 comment => "construct conditional branch: CMP A, B && JMPxx LABEL",
468 attr => "int proj_num",
469 init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
470 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "none", "none"] },
471 attr_type => "arm_CondJmp_attr_t",
477 comment => "construct conditional branch: TST A, B && JMPxx LABEL",
479 attr => "int proj_num",
480 init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
481 reg_req => { "in" => [ "gp", "gp" ], "out" => [ "none", "none"] },
482 attr_type => "arm_CondJmp_attr_t",
489 reg_req => { out => [ "none" ] },
496 comment => "construct switch",
498 attr => "int n_projs, long def_proj_num",
499 init_attr => "\tset_arm_SwitchJmp_n_projs(res, n_projs);\n".
500 "\tset_arm_SwitchJmp_default_proj_num(res, def_proj_num);",
501 reg_req => { "in" => [ "gp" ], "out" => [ "none" ] },
502 attr_type => "arm_SwitchJmp_attr_t",
509 state => "exc_pinned",
510 ins => [ "ptr", "mem" ],
511 outs => [ "res", "M" ],
512 reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
513 emit => '. ldr %D0, [%S0, #0]',
514 attr_type => "arm_load_store_attr_t",
515 attr => "ir_entity *entity, int entity_sign, long offset",
520 state => "exc_pinned",
521 ins => [ "ptr", "mem" ],
522 outs => [ "res", "M" ],
523 reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
524 emit => '. ldrb %D0, [%S0, #0]',
525 attr_type => "arm_load_store_attr_t",
526 attr => "ir_entity *entity, int entity_sign, long offset",
531 state => "exc_pinned",
532 ins => [ "ptr", "mem" ],
533 outs => [ "res", "M" ],
534 reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
535 emit => '. ldrsb %D0, [%S0, #0]',
536 attr_type => "arm_load_store_attr_t",
537 attr => "ir_entity *entity, int entity_sign, long offset",
542 state => "exc_pinned",
543 ins => [ "ptr", "mem" ],
544 outs => [ "res", "M" ],
545 reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
546 emit => '. ldrh %D0, [%S0, #0]',
547 attr_type => "arm_load_store_attr_t",
548 attr => "ir_entity *entity, int entity_sign, long offset",
553 state => "exc_pinned",
554 ins => [ "ptr", "mem" ],
555 outs => [ "res", "M" ],
556 reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] },
557 emit => '. ldrsh %D0, [%S0, #0]',
558 attr_type => "arm_load_store_attr_t",
559 attr => "ir_entity *entity, int entity_sign, long offset",
564 state => "exc_pinned",
565 ins => [ "ptr", "val", "mem" ],
567 reg_req => { "in" => [ "gp", "gp", "none" ], "out" => [ "none" ] },
568 emit => '. strb %S1, [%S0, #0]',
570 attr_type => "arm_load_store_attr_t",
571 attr => "ir_entity *entity, int entity_sign, long offset",
576 state => "exc_pinned",
577 ins => [ "ptr", "val", "mem" ],
579 reg_req => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] },
580 emit => '. strh %S1, [%S0, #0]',
582 attr_type => "arm_load_store_attr_t",
583 attr => "ir_entity *entity, int entity_sign, long offset",
588 state => "exc_pinned",
589 ins => [ "ptr", "val", "mem" ],
591 reg_req => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] },
592 emit => '. str %S1, [%S0, #0]',
594 attr_type => "arm_load_store_attr_t",
595 attr => "ir_entity *entity, int entity_sign, long offset",
601 state => "exc_pinned",
602 comment => "construct Store: Push 4 Registers = ST ptr,val",
603 reg_req => { "in" => [ "sp", "gp", "gp", "gp", "gp", "none" ], "out" => [ "sp:I|S", "none" ] },
604 emit => '. stmfd %S0!, {%S1, %S2, %S3, %S4}',
605 outs => [ "ptr", "M" ],
608 LoadStackM3Epilogue => {
611 state => "exc_pinned",
612 comment => "construct Load: Load(ptr, mem) = LD ptr -> reg",
613 reg_req => { "in" => [ "sp", "none" ], "out" => [ "r11:I", "sp:I|S", "pc:I", "none" ] },
614 emit => '. ldmfd %S0, {%D0, %D1, %D2}',
615 outs => [ "res0", "res1", "res2", "M" ],
619 #---------------------------------------------------#
622 # | |_ _ __ __ _ _ __ ___ __| | ___ ___ #
623 # | _| '_ \ / _` | | '_ \ / _ \ / _` |/ _ \/ __| #
624 # | | | |_) | (_| | | | | | (_) | (_| | __/\__ \ #
625 # |_| | .__/ \__,_| |_| |_|\___/ \__,_|\___||___/ #
628 #---------------------------------------------------#
630 # commutative operations
635 comment => "construct FPA Add: Add(a, b) = Add(b, a) = a + b",
636 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
637 emit => '. adf%M %D0, %S0, %S1',
642 comment => "construct FPA Add: Add(a, b) = Add(b, a) = a + b",
644 init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
645 reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
646 emit => '. adf%M %D0, %S0, %C',
652 comment => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b",
653 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
654 emit =>'. muf%M %D0, %S0, %S1',
659 comment => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b",
661 init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
662 reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
663 emit => '. muf%M %D0, %S0, %C',
669 comment => "construct FPA Fast Mul: Mul(a, b) = Mul(b, a) = a * b",
670 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
671 emit =>'. fml%M %D0, %S0, %S1',
677 comment => "construct FPA Max: Max(a, b) = Max(b, a) = a > b ? a : b",
678 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
679 emit =>'. fmax %S0, %S1, %D0',
685 comment => "construct FPA Min: Min(a, b) = Min(b, a) = a < b ? a : b",
686 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
687 emit =>'. fmin %S0, %S1, %D0',
690 # not commutative operations
694 comment => "construct FPA Sub: Sub(a, b) = a - b",
695 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
696 emit => '. suf%M %D0, %S0, %S1'
701 comment => "construct FPA Sub: Sub(a, b) = a - b",
703 init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
704 reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
705 emit => '. suf%M %D0, %S0, %C'
710 comment => "construct FPA reverse Sub: Sub(a, b) = b - a",
711 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] },
712 emit => '. rsf%M %D0, %S0, %S1'
717 comment => "construct FPA reverse Sub: Sub(a, b) = b - a",
719 init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
720 reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
721 emit => '. rsf%M %D0, %S0, %C'
725 comment => "construct FPA Div: Div(a, b) = a / b",
726 attr => "ir_mode *op_mode",
727 init_attr => "attr->op_mode = op_mode;",
728 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] },
729 emit =>'. dvf%M %D0, %S0, %S1',
730 outs => [ "res", "M" ],
734 comment => "construct FPA Div: Div(a, b) = a / b",
735 attr => "ir_mode *op_mode, long imm",
736 init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
737 reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] },
738 emit =>'. dvf%M %D0, %S0, %C',
739 outs => [ "res", "M" ],
743 comment => "construct FPA reverse Div: Div(a, b) = b / a",
744 attr => "ir_mode *op_mode",
745 init_attr => "attr->op_mode = op_mode;",
746 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] },
747 emit =>'. rdf%M %D0, %S0, %S1',
748 outs => [ "res", "M" ],
752 comment => "construct FPA reverse Div: Div(a, b) = b / a",
753 attr => "ir_mode *op_mode, long imm",
754 init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
755 reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] },
756 emit =>'. rdf%M %D0, %S0, %S1',
757 outs => [ "res", "M" ],
761 comment => "construct FPA Fast Div: Div(a, b) = a / b",
762 attr => "ir_mode *op_mode",
763 init_attr => "attr->op_mode = op_mode;",
764 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] },
765 emit =>'. fdv%M %D0, %S0, %S1',
766 outs => [ "res", "M" ],
770 comment => "construct FPA Fast Div: Div(a, b) = a / b",
771 attr => "ir_mode *op_mode, long imm",
772 init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
773 reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] },
774 emit =>'. fdv%M %D0, %S0, %C',
775 outs => [ "res", "M" ],
779 comment => "construct FPA Fast reverse Div: Div(a, b) = b / a",
780 attr => "ir_mode *op_mode",
781 init_attr => "attr->op_mode = op_mode;",
782 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] },
783 emit =>'. frd%M %D0, %S0, %S1',
784 outs => [ "res", "M" ],
788 comment => "construct FPA Fast reverse Div: Div(a, b) = b / a",
789 attr => "ir_mode *op_mode, long imm",
790 init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
791 reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] },
792 emit =>'. frd%M %D0, %S0, %C',
793 outs => [ "res", "M" ],
798 comment => "construct FPA Move: b = a",
799 reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
800 emit => '. mvf%M %S0, %D0',
805 comment => "represents a float constant",
807 init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
808 reg_req => { "out" => [ "fpa" ] },
809 emit => '. mvf%M %D0, %C',
814 comment => "construct FPA Move Negated: b = -a",
815 reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
816 emit => '. mnf%M %S0, %D0',
821 comment => "represents a float constant",
823 init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;',
824 reg_req => { "out" => [ "fpa" ] },
825 emit => '. mnf%M %D0, %C',
830 comment => "construct FPA Absolute value: fAbsd(a) = |a|",
831 reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] },
832 emit => '. abs%M %D0, %S0',
839 comment => "construct a FPA integer->float conversion",
840 reg_req => { "in" => ["gp"], "out" => [ "fpa" ] },
841 emit => '. flt%M %D0, %S0',
846 comment => "construct a FPA float->integer conversion",
847 reg_req => { "in" => ["fpa"], "out" => [ "gp" ] },
848 emit => '. fix %D0, %S0',
854 comment => "construct floating point Compare and Branch: CMF A, B && JMPxx LABEL",
856 attr => "int proj_num",
857 init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
858 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "none", "none"] },
859 attr_type => "arm_CondJmp_attr_t",
865 comment => "construct floating point Compare negative and Branch: CMF A, -B && JMPxx LABEL",
867 attr => "int proj_num",
868 init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
869 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "none", "none"] },
870 attr_type => "arm_CondJmp_attr_t",
876 comment => "construct floating point Compare and Branch: CMF A, -B && JMPxx LABEL",
878 attr => "int proj_num",
879 init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
880 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "none", "none"] },
881 attr_type => "arm_CondJmp_attr_t",
887 comment => "construct floating point Compare and Branch: CMF A, -B && JMPxx LABEL",
889 attr => "int proj_num",
890 init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);",
891 reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "none", "none"] },
892 attr_type => "arm_CondJmp_attr_t",
900 state => "exc_pinned",
901 comment => "construct FPA Load: Load(ptr, mem) = LD ptr",
902 attr => "ir_mode *op_mode",
903 init_attr => "attr->op_mode = op_mode;",
904 reg_req => { "in" => [ "gp", "none" ], "out" => [ "fpa", "none" ] },
905 emit => '. ldf%M %D0, [%S0]',
906 outs => [ "res", "M" ],
912 state => "exc_pinned",
913 comment => "construct Store: Store(ptr, val, mem) = ST ptr,val",
914 attr => "ir_mode *op_mode",
915 init_attr => "attr->op_mode = op_mode;",
916 reg_req => { "in" => [ "gp", "fpa", "none" ], "out" => [ "none" ] },
917 emit => '. stf%M %S1, [%S0]',
924 comment => "construct fp double to 2 gp register transfer",
925 reg_req => { "in" => [ "fpa", "none" ], "out" => [ "gp", "gp", "none" ] },
926 outs => [ "low", "high", "M" ],
930 comment => "construct Add to stack pointer",
931 reg_req => { in => [ "sp", "gp", "none" ], out => [ "sp:I|S", "none" ] },
932 emit => '. add %D0, %S0, %S1',
933 outs => [ "stack", "M" ],
937 comment => "construct Sub from stack pointer and copy to Register",
938 reg_req => { in => [ "sp", "gp", "none" ], out => [ "sp:I|S", "gp", "none" ] },
939 ins => [ "stack", "size", "mem" ],
940 emit => ". sub %D0, %S0, %S1\n".
942 outs => [ "stack", "addr", "M" ],
947 comment => "load the TLS address",
948 reg_req => { out => [ "gp" ] },
953 # floating point constants
958 comment => "construct a floating point constant",
959 attr => "tarval *tv",
960 init_attr => "attr->tv = tv;",
961 mode => "get_tarval_mode(tv)",
962 reg_req => { "out" => [ "fpa" ] },
963 attr_type => "arm_fpaConst_attr_t",
966 #---------------------------------------------------#
969 # __ _| |_ _ __ _ __ ___ __| | ___ ___ #
970 # \ \ / / _| '_ \ | '_ \ / _ \ / _` |/ _ \/ __| #
971 # \ V /| | | |_) | | | | | (_) | (_| | __/\__ \ #
972 # \_/ |_| | .__/ |_| |_|\___/ \__,_|\___||___/ #
975 #---------------------------------------------------#