1 # This is the specification for the ia32 assembler Firm-operations
7 $mode_fp87 = "ia32_mode_E";
9 $mode_flags = "mode_Iu";
10 $mode_fpcw = "ia32_mode_fpcw";
13 $normal = 0; # no special type
14 $ignore = 1; # ignore (do not assign this register)
15 $arbitrary = 2; # emitter can choose an arbitrary register of this class
16 $virtual = 4; # the register is a virtual one
17 $state = 8; # register represents a state
18 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
21 { name => "edx", dwarf => 2 },
22 { name => "ecx", dwarf => 1 },
23 { name => "eax", dwarf => 0 },
24 { name => "ebx", dwarf => 3 },
25 { name => "esi", dwarf => 6 },
26 { name => "edi", dwarf => 7 },
27 { name => "ebp", dwarf => 5 },
28 { name => "esp", dwarf => 4, type => $ignore },
29 { name => "gp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
33 { name => "mm0", dwarf => 29, type => $ignore },
34 { name => "mm1", dwarf => 30, type => $ignore },
35 { name => "mm2", dwarf => 31, type => $ignore },
36 { name => "mm3", dwarf => 32, type => $ignore },
37 { name => "mm4", dwarf => 33, type => $ignore },
38 { name => "mm5", dwarf => 34, type => $ignore },
39 { name => "mm6", dwarf => 35, type => $ignore },
40 { name => "mm7", dwarf => 36, type => $ignore },
41 { mode => $mode_mmx, flags => "manual_ra" }
44 { name => "xmm0", dwarf => 21 },
45 { name => "xmm1", dwarf => 22 },
46 { name => "xmm2", dwarf => 23 },
47 { name => "xmm3", dwarf => 24 },
48 { name => "xmm4", dwarf => 25 },
49 { name => "xmm5", dwarf => 26 },
50 { name => "xmm6", dwarf => 27 },
51 { name => "xmm7", dwarf => 28 },
52 { name => "xmm_NOREG", type => $ignore | $virtual }, # we need a dummy register for NoReg nodes
56 { name => "st0", realname => "st", dwarf => 11 },
57 { name => "st1", realname => "st(1)", dwarf => 12 },
58 { name => "st2", realname => "st(2)", dwarf => 13 },
59 { name => "st3", realname => "st(3)", dwarf => 14 },
60 { name => "st4", realname => "st(4)", dwarf => 15 },
61 { name => "st5", realname => "st(5)", dwarf => 16 },
62 { name => "st6", realname => "st(6)", dwarf => 17 },
63 { name => "st7", realname => "st(7)", dwarf => 18 },
64 { name => "fp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
65 { mode => $mode_fp87 }
67 fp_cw => [ # the floating point control word
68 { name => "fpcw", dwarf => 37, type => $ignore | $state },
69 { mode => $mode_fpcw, flags => "manual_ra|state" }
72 { name => "eflags", dwarf => 9, type => 0 },
73 { mode => "mode_Iu", flags => "manual_ra" }
78 GP => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
79 SSE => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
80 VFP => [ 1, "VFP_VF0", "VFP_VF1", "VFP_VF2", "VFP_VF3", "VFP_VF4", "VFP_VF5", "VFP_VF6", "VFP_VF7" ],
81 BRANCH => [ 1, "BRANCH1", "BRANCH2" ],
86 bundels_per_cycle => 1
89 $default_op_attr_type = "ia32_op_attr_t";
90 $default_attr_type = "ia32_attr_t";
91 $default_copy_attr = "ia32_copy_attr";
93 sub ia32_custom_init_attr {
99 if(defined($node->{modified_flags})) {
100 $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n";
102 if(defined($node->{am})) {
103 my $am = $node->{am};
104 if($am eq "source,unary") {
105 $res .= "\tset_ia32_am_support(res, ia32_am_unary);";
106 } elsif($am eq "source,binary") {
107 $res .= "\tset_ia32_am_support(res, ia32_am_binary);";
108 } elsif($am eq "none") {
111 die("Invalid address mode '$am' specified on op $name");
114 if($node->{state} ne "exc_pinned"
115 and $node->{state} ne "pinned") {
116 die("AM nodes must have pinned or AM pinned state ($name)");
122 $custom_init_attr_func = \&ia32_custom_init_attr;
126 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
127 "\tinit_ia32_x87_attributes(res);".
128 "\tinit_ia32_asm_attributes(res);",
130 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);",
132 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
133 "\tinit_ia32_call_attributes(res, pop, call_tp);",
134 ia32_condcode_attr_t =>
135 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
136 "\tinit_ia32_condcode_attributes(res, condition_code);",
137 ia32_switch_attr_t =>
138 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
139 "\tinit_ia32_switch_attributes(res, switch_table);",
141 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
142 "\tinit_ia32_copyb_attributes(res, size);",
143 ia32_immediate_attr_t =>
144 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
145 "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
147 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
148 "\tinit_ia32_x87_attributes(res);",
149 ia32_climbframe_attr_t =>
150 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
151 "\tinit_ia32_climbframe_attributes(res, count);",
155 ia32_asm_attr_t => "ia32_compare_asm_attr",
156 ia32_attr_t => "ia32_compare_nodes_attr",
157 ia32_call_attr_t => "ia32_compare_call_attr",
158 ia32_condcode_attr_t => "ia32_compare_condcode_attr",
159 ia32_copyb_attr_t => "ia32_compare_copyb_attr",
160 ia32_switch_attr_t => "ia32_compare_nodes_attr",
161 ia32_immediate_attr_t => "ia32_compare_immediate_attr",
162 ia32_x87_attr_t => "ia32_compare_x87_attr",
163 ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
169 $status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
170 $status_flags_wo_cf = [ "PF", "AF", "ZF", "SF", "OF" ];
171 $fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
172 "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
178 op_flags => [ "constlike" ],
179 irn_flags => [ "not_scheduled" ],
180 reg_req => { out => [ "gp_NOREG:I" ] },
181 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
182 attr_type => "ia32_immediate_attr_t",
183 hash_func => "ia32_hash_Immediate",
191 out_arity => "variable",
192 attr_type => "ia32_asm_attr_t",
193 attr => "ident *asm_text, const ia32_asm_reg_t *register_map",
194 init_attr => "attr->asm_text = asm_text;\n".
195 "\tattr->register_map = register_map;\n",
197 modified_flags => $status_flags,
200 # "allocates" a free register
202 op_flags => [ "constlike", "cse_neutral" ],
203 irn_flags => [ "rematerializable" ],
204 reg_req => { out => [ "gp" ] },
209 cmp_attr => "return 1;",
213 irn_flags => [ "rematerializable" ],
214 state => "exc_pinned",
215 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
216 out => [ "in_r4 in_r5", "flags", "none" ] },
217 ins => [ "base", "index", "mem", "left", "right" ],
218 outs => [ "res", "flags", "M" ],
220 am => "source,binary",
224 modified_flags => $status_flags
228 irn_flags => [ "rematerializable" ],
229 state => "exc_pinned",
230 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
231 ins => [ "base", "index", "mem", "val" ],
232 emit => "add%M %#S3, %AM",
236 modified_flags => $status_flags
240 irn_flags => [ "rematerializable" ],
241 state => "exc_pinned",
242 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
243 ins => [ "base", "index", "mem", "val" ],
244 emit => "add%M %#S3, %AM",
248 modified_flags => $status_flags
252 state => "exc_pinned",
253 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
254 out => [ "in_r4 in_r5", "flags", "none" ] },
255 ins => [ "base", "index", "mem", "left", "right", "eflags" ],
256 outs => [ "res", "flags", "M" ],
258 am => "source,binary",
262 modified_flags => $status_flags
266 ins => [ "left", "right" ],
272 ins => [ "left", "right", "eflags" ],
278 # we should not rematrialize this node. It produces 2 results and has
279 # very strict constraints
280 state => "exc_pinned",
281 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
282 out => [ "eax", "flags", "none", "edx" ] },
283 ins => [ "base", "index", "mem", "left", "right" ],
284 emit => 'mul%M %AS4',
285 outs => [ "res_low", "flags", "M", "res_high" ],
286 am => "source,binary",
289 modified_flags => $status_flags
293 ins => [ "left", "right" ],
294 outs => [ "res_low", "flags", "M", "res_high" ],
300 irn_flags => [ "rematerializable" ],
301 state => "exc_pinned",
302 # TODO: adjust out requirements for the 3 operand form
303 # (no need for should_be_same then)
304 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
305 out => [ "in_r4 in_r5", "flags", "none" ] },
306 ins => [ "base", "index", "mem", "left", "right" ],
307 outs => [ "res", "flags", "M" ],
308 am => "source,binary",
312 modified_flags => $status_flags
316 irn_flags => [ "rematerializable" ],
317 state => "exc_pinned",
318 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
319 out => [ "eax", "flags", "none", "edx" ] },
320 ins => [ "base", "index", "mem", "left", "right" ],
321 emit => 'imul%M %AS4',
322 outs => [ "res_low", "flags", "M", "res_high" ],
323 am => "source,binary",
326 modified_flags => $status_flags
330 ins => [ "left", "right" ],
331 outs => [ "res_low", "flags", "M", "res_high" ],
337 irn_flags => [ "rematerializable" ],
338 state => "exc_pinned",
339 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
340 out => [ "in_r4 in_r5", "flags", "none" ] },
341 ins => [ "base", "index", "mem", "left", "right" ],
342 outs => [ "res", "flags", "M" ],
343 am => "source,binary",
348 modified_flags => $status_flags
352 irn_flags => [ "rematerializable" ],
353 state => "exc_pinned",
354 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
355 ins => [ "base", "index", "mem", "val" ],
356 emit => 'and%M %#S3, %AM',
360 modified_flags => $status_flags
364 irn_flags => [ "rematerializable" ],
365 state => "exc_pinned",
366 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
367 ins => [ "base", "index", "mem", "val" ],
368 emit => 'and%M %#S3, %AM',
372 modified_flags => $status_flags
376 irn_flags => [ "rematerializable" ],
377 state => "exc_pinned",
378 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
379 out => [ "in_r4 in_r5", "flags", "none" ] },
380 ins => [ "base", "index", "mem", "left", "right" ],
381 outs => [ "res", "flags", "M" ],
382 am => "source,binary",
387 modified_flags => $status_flags
391 irn_flags => [ "rematerializable" ],
392 state => "exc_pinned",
393 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
394 ins => [ "base", "index", "mem", "val" ],
395 emit => 'or%M %#S3, %AM',
399 modified_flags => $status_flags
403 irn_flags => [ "rematerializable" ],
404 state => "exc_pinned",
405 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
406 ins => [ "base", "index", "mem", "val" ],
407 emit => 'or%M %#S3, %AM',
411 modified_flags => $status_flags
415 irn_flags => [ "rematerializable" ],
416 state => "exc_pinned",
417 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
418 out => [ "in_r4 in_r5", "flags", "none" ] },
419 ins => [ "base", "index", "mem", "left", "right" ],
420 outs => [ "res", "flags", "M" ],
421 am => "source,binary",
426 modified_flags => $status_flags
430 op_flags => [ "constlike" ],
431 irn_flags => [ "rematerializable" ],
432 reg_req => { out => [ "gp", "flags" ] },
433 outs => [ "res", "flags" ],
434 emit => "xor%M %D0, %D0",
438 modified_flags => $status_flags
442 irn_flags => [ "rematerializable" ],
443 state => "exc_pinned",
444 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
445 ins => [ "base", "index", "mem", "val" ],
446 emit => 'xor%M %#S3, %AM',
450 modified_flags => $status_flags
454 irn_flags => [ "rematerializable" ],
455 state => "exc_pinned",
456 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
457 ins => [ "base", "index", "mem", "val" ],
458 emit => 'xor%M %#S3, %AM',
462 modified_flags => $status_flags
466 irn_flags => [ "rematerializable" ],
467 state => "exc_pinned",
468 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
469 out => [ "in_r4", "flags", "none" ] },
470 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
471 outs => [ "res", "flags", "M" ],
472 am => "source,binary",
477 modified_flags => $status_flags
481 irn_flags => [ "rematerializable" ],
482 state => "exc_pinned",
483 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
484 ins => [ "base", "index", "mem", "subtrahend" ],
485 emit => 'sub%M %#S3, %AM',
489 modified_flags => $status_flags
493 irn_flags => [ "rematerializable" ],
494 state => "exc_pinned",
495 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
496 ins => [ "base", "index", "mem", "subtrahend" ],
497 emit => 'sub%M %#S3, %AM',
501 modified_flags => $status_flags
505 state => "exc_pinned",
506 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
507 out => [ "in_r4", "flags", "none" ] },
508 ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
509 outs => [ "res", "flags", "M" ],
510 am => "source,binary",
515 modified_flags => $status_flags
519 # Spiller currently fails when rematerializing flag consumers
520 # irn_flags => [ "rematerializable" ],
521 reg_req => { in => [ "flags" ], out => [ "gp", "flags" ] },
522 outs => [ "res", "flags" ],
523 emit => "sbb%M %D0, %D0",
527 modified_flags => $status_flags
531 ins => [ "minuend", "subtrahend" ],
537 ins => [ "minuend", "subtrahend", "eflags" ],
543 op_flags => [ "fragile", "uses_memory" ],
544 state => "exc_pinned",
545 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
546 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
547 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
548 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
549 am => "source,unary",
550 emit => "idiv%M %AS3",
553 modified_flags => $status_flags
557 op_flags => [ "fragile", "uses_memory" ],
558 state => "exc_pinned",
559 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
560 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
561 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
562 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
563 am => "source,unary",
564 emit => "div%M %AS3",
567 modified_flags => $status_flags
571 irn_flags => [ "rematerializable" ],
572 reg_req => { in => [ "gp", "ecx" ],
573 out => [ "in_r1 !in_r2", "flags" ] },
574 ins => [ "val", "count" ],
575 outs => [ "res", "flags" ],
576 emit => 'shl%M %<S1, %S0',
580 modified_flags => $status_flags
584 irn_flags => [ "rematerializable" ],
585 state => "exc_pinned",
586 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
587 ins => [ "base", "index", "mem", "count" ],
588 emit => 'shl%M %<S3, %AM',
592 modified_flags => $status_flags
596 irn_flags => [ "rematerializable" ],
597 reg_req => { in => [ "gp", "gp", "ecx" ],
598 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
599 ins => [ "val_high", "val_low", "count" ],
600 outs => [ "res", "flags" ],
601 emit => "shld%M %<S2, %S1, %D0",
605 modified_flags => $status_flags
609 irn_flags => [ "rematerializable" ],
610 reg_req => { in => [ "gp", "ecx" ],
611 out => [ "in_r1 !in_r2", "flags" ] },
612 ins => [ "val", "count" ],
613 outs => [ "res", "flags" ],
614 emit => 'shr%M %<S1, %S0',
618 modified_flags => $status_flags
622 irn_flags => [ "rematerializable" ],
623 state => "exc_pinned",
624 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
625 ins => [ "base", "index", "mem", "count" ],
626 emit => 'shr%M %<S3, %AM',
630 modified_flags => $status_flags
634 irn_flags => [ "rematerializable" ],
635 reg_req => { in => [ "gp", "gp", "ecx" ],
636 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
637 ins => [ "val_high", "val_low", "count" ],
638 outs => [ "res", "flags" ],
639 emit => "shrd%M %<S2, %S1, %D0",
643 modified_flags => $status_flags
647 irn_flags => [ "rematerializable" ],
648 reg_req => { in => [ "gp", "ecx" ],
649 out => [ "in_r1 !in_r2", "flags" ] },
650 ins => [ "val", "count" ],
651 outs => [ "res", "flags" ],
652 emit => 'sar%M %<S1, %S0',
656 modified_flags => $status_flags
660 irn_flags => [ "rematerializable" ],
661 state => "exc_pinned",
662 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
663 ins => [ "base", "index", "mem", "count" ],
664 emit => 'sar%M %<S3, %AM',
668 modified_flags => $status_flags
672 irn_flags => [ "rematerializable" ],
673 reg_req => { in => [ "gp", "ecx" ],
674 out => [ "in_r1 !in_r2", "flags" ] },
675 ins => [ "val", "count" ],
676 outs => [ "res", "flags" ],
677 emit => 'ror%M %<S1, %S0',
681 modified_flags => $status_flags
685 irn_flags => [ "rematerializable" ],
686 state => "exc_pinned",
687 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
688 ins => [ "base", "index", "mem", "count" ],
689 emit => 'ror%M %<S3, %AM',
693 modified_flags => $status_flags
697 irn_flags => [ "rematerializable" ],
698 reg_req => { in => [ "gp", "ecx" ],
699 out => [ "in_r1 !in_r2", "flags" ] },
700 ins => [ "val", "count" ],
701 outs => [ "res", "flags" ],
702 emit => 'rol%M %<S1, %D0',
706 modified_flags => $status_flags
710 irn_flags => [ "rematerializable" ],
711 state => "exc_pinned",
712 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
713 ins => [ "base", "index", "mem", "count" ],
714 emit => 'rol%M %<S3, %AM',
718 modified_flags => $status_flags
722 irn_flags => [ "rematerializable" ],
723 reg_req => { in => [ "gp" ],
724 out => [ "in_r1", "flags" ] },
727 outs => [ "res", "flags" ],
731 modified_flags => $status_flags
735 irn_flags => [ "rematerializable" ],
736 state => "exc_pinned",
737 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
738 ins => [ "base", "index", "mem" ],
743 modified_flags => $status_flags
747 irn_flags => [ "rematerializable" ],
748 reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
749 outs => [ "low_res", "high_res" ],
752 modified_flags => $status_flags
757 irn_flags => [ "rematerializable" ],
758 reg_req => { in => [ "gp" ],
759 out => [ "in_r1", "flags" ] },
761 outs => [ "res", "flags" ],
766 modified_flags => $status_flags_wo_cf
770 irn_flags => [ "rematerializable" ],
771 state => "exc_pinned",
772 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
773 ins => [ "base", "index", "mem" ],
778 modified_flags => $status_flags_wo_cf
782 irn_flags => [ "rematerializable" ],
783 reg_req => { in => [ "gp" ],
784 out => [ "in_r1", "flags" ] },
786 outs => [ "res", "flags" ],
791 modified_flags => $status_flags_wo_cf
795 irn_flags => [ "rematerializable" ],
796 state => "exc_pinned",
797 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
798 ins => [ "base", "index", "mem" ],
803 modified_flags => $status_flags_wo_cf
807 irn_flags => [ "rematerializable" ],
808 reg_req => { in => [ "gp" ],
809 out => [ "in_r1" ] },
820 irn_flags => [ "rematerializable" ],
821 state => "exc_pinned",
822 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
823 ins => [ "base", "index", "mem" ],
832 reg_req => { in => [ "flags" ], out => [ "flags" ] },
837 modified_flags => $status_flags
841 reg_req => { out => [ "flags" ] },
846 modified_flags => $status_flags
850 irn_flags => [ "rematerializable" ],
851 state => "exc_pinned",
852 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
853 out => [ "flags", "none", "none" ] },
854 ins => [ "base", "index", "mem", "left", "right" ],
855 outs => [ "eflags", "unused", "M" ],
856 am => "source,binary",
858 attr => "bool ins_permuted",
859 init_attr => "attr->data.ins_permuted = ins_permuted;",
863 modified_flags => $status_flags
867 irn_flags => [ "rematerializable" ],
868 state => "exc_pinned",
869 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
870 out => [ "flags", "none", "none" ] },
871 ins => [ "base", "index", "mem", "left", "right" ],
872 outs => [ "eflags", "unused", "M" ],
873 am => "source,binary",
875 attr => "bool ins_permuted",
876 init_attr => "attr->data.ins_permuted = ins_permuted;",
880 modified_flags => $status_flags
884 irn_flags => [ "rematerializable" ],
885 state => "exc_pinned",
886 reg_req => { in => [ "eax ebx ecx edx" ],
887 out => [ "in_r1", "flags" ] },
888 emit => 'xorb %>S0, %<S0',
890 outs => [ "res", "flags" ],
894 modified_flags => $status_flags,
898 irn_flags => [ "rematerializable" ],
899 state => "exc_pinned",
900 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] ,
901 out => [ "flags", "none", "none" ] },
902 ins => [ "base", "index", "mem", "left", "right" ],
903 outs => [ "eflags", "unused", "M" ],
904 am => "source,binary",
906 attr => "bool ins_permuted",
907 init_attr => "attr->data.ins_permuted = ins_permuted;",
911 modified_flags => $status_flags
915 irn_flags => [ "rematerializable" ],
916 state => "exc_pinned",
917 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
918 out => [ "flags", "none", "none" ] },
919 ins => [ "base", "index", "mem", "left", "right" ],
920 outs => [ "eflags", "unused", "M" ],
921 am => "source,binary",
923 attr => "bool ins_permuted",
924 init_attr => "attr->data.ins_permuted = ins_permuted;",
928 modified_flags => $status_flags
932 #irn_flags => [ "rematerializable" ],
933 reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
936 attr_type => "ia32_condcode_attr_t",
937 attr => "ia32_condition_code_t condition_code",
938 # The way we handle Setcc with float nodes (potentially) destroys the flags
939 # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
940 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
941 . "\tif (condition_code & ia32_cc_additional_float_cases) {\n"
942 . "\t\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"
943 . "\t\t/* attr->latency = 3; */\n"
951 #irn_flags => [ "rematerializable" ],
952 state => "exc_pinned",
953 reg_req => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
954 ins => [ "base", "index", "mem","eflags" ],
955 attr_type => "ia32_condcode_attr_t",
956 attr => "ia32_condition_code_t condition_code",
957 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
958 emit => 'set%P3 %AM',
965 #irn_flags => [ "rematerializable" ],
966 state => "exc_pinned",
967 # (note: leave the false,true order intact to make it compatible with other
969 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
970 out => [ "in_r4 in_r5", "flags", "none" ] },
971 ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
972 outs => [ "res", "flags", "M" ],
973 am => "source,binary",
974 attr_type => "ia32_condcode_attr_t",
975 attr => "ia32_condition_code_t condition_code",
983 op_flags => [ "cfopcode", "forking" ],
984 reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
986 outs => [ "false", "true" ],
987 attr_type => "ia32_condcode_attr_t",
988 attr => "ia32_condition_code_t condition_code",
990 units => [ "BRANCH" ],
995 op_flags => [ "cfopcode", "forking" ],
996 reg_req => { in => [ "gp", "gp" ] },
997 ins => [ "base", "index" ],
998 out_arity => "variable",
999 attr_type => "ia32_switch_attr_t",
1000 attr => "const ir_switch_table *switch_table",
1002 units => [ "BRANCH" ],
1007 irn_flags => [ "simple_jump" ],
1008 op_flags => [ "cfopcode" ],
1009 reg_req => { out => [ "none" ] },
1011 units => [ "BRANCH" ],
1017 op_flags => [ "cfopcode", "unknown_jump" ],
1018 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1019 out => [ "none", "flags", "none" ] },
1020 ins => [ "base", "index", "mem", "target" ],
1021 outs => [ "jmp", "flags", "M" ],
1022 am => "source,unary",
1023 emit => 'jmp %*AS3',
1025 units => [ "BRANCH" ],
1030 op_flags => [ "constlike" ],
1031 irn_flags => [ "rematerializable" ],
1032 reg_req => { out => [ "gp" ] },
1033 emit => "movl %I, %D0",
1035 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
1036 attr_type => "ia32_immediate_attr_t",
1042 op_flags => [ "constlike" ],
1043 irn_flags => [ "rematerializable" ],
1044 reg_req => { out => [ "gp" ] },
1051 op_flags => [ "constlike" ],
1052 reg_req => { out => [ "gp" ] },
1056 modified_flags => $status_flags,
1061 op_flags => [ "constlike", "dump_noblock" ],
1062 irn_flags => [ "not_scheduled" ],
1063 reg_req => { out => [ "gp_NOREG:I" ] },
1072 op_flags => [ "constlike", "dump_noblock" ],
1073 irn_flags => [ "not_scheduled" ],
1074 reg_req => { out => [ "fp_NOREG:I" ] },
1079 attr_type => "ia32_x87_attr_t",
1084 op_flags => [ "constlike", "dump_noblock" ],
1085 irn_flags => [ "not_scheduled" ],
1086 reg_req => { out => [ "xmm_NOREG:I" ] },
1095 op_flags => [ "constlike" ],
1096 irn_flags => [ "not_scheduled" ],
1097 reg_req => { out => [ "fpcw:I" ] },
1101 modified_flags => $fpcw_flags
1105 op_flags => [ "uses_memory" ],
1107 reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] },
1108 ins => [ "base", "index", "mem" ],
1110 emit => "fldcw %AM",
1113 modified_flags => $fpcw_flags
1117 op_flags => [ "uses_memory" ],
1119 reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1120 ins => [ "base", "index", "mem", "fpcw" ],
1122 emit => "fnstcw %AM",
1128 op_flags => [ "uses_memory" ],
1130 reg_req => { in => [ "fp_cw" ], out => [ "none" ] },
1138 # we should not rematrialize this node. It has very strict constraints.
1139 reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] },
1140 ins => [ "val", "clobbered" ],
1149 # Note that we add additional latency values depending on address mode, so a
1150 # lateny of 0 for load is correct
1153 op_flags => [ "uses_memory", "fragile" ],
1154 state => "exc_pinned",
1155 reg_req => { in => [ "gp", "gp", "none" ],
1156 out => [ "gp", "none", "none", "none", "none" ] },
1157 ins => [ "base", "index", "mem" ],
1158 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1160 emit => "mov%#Ml %AM, %D0",
1165 op_flags => [ "uses_memory", "fragile" ],
1166 state => "exc_pinned",
1167 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1168 out => [ "none", "none", "none" ] },
1169 ins => [ "base", "index", "mem", "val" ],
1170 outs => [ "M", "X_regular", "X_except" ],
1171 emit => 'mov%M %#S3, %AM',
1177 op_flags => [ "uses_memory", "fragile" ],
1178 state => "exc_pinned",
1179 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1180 out => ["none", "none", "none" ] },
1181 ins => [ "base", "index", "mem", "val" ],
1182 outs => [ "M", "X_regular", "X_except" ],
1183 emit => 'mov%M %#S3, %AM',
1189 irn_flags => [ "rematerializable" ],
1190 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1191 ins => [ "base", "index" ],
1192 emit => 'leal %AM, %D0',
1196 # lea doesn't modify the flags, but setting this seems advantageous since it
1197 # increases chances that the Lea is transformed back to an Add
1198 modified_flags => 1,
1202 state => "exc_pinned",
1203 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1204 ins => [ "base", "index", "mem", "val", "stack" ],
1205 emit => 'push%M %AS3',
1206 outs => [ "stack", "M" ],
1207 am => "source,unary",
1213 state => "exc_pinned",
1214 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1216 outs => [ "stack" ],
1217 emit => 'pushl %%eax',
1224 state => "exc_pinned",
1225 reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1226 ins => [ "mem", "stack" ],
1227 outs => [ "res", "M", "unused", "stack" ],
1228 emit => 'pop%M %D0',
1229 latency => 3, # Pop is more expensive than Push on Athlon
1234 state => "exc_pinned",
1235 reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1236 ins => [ "mem", "stack" ],
1237 outs => [ "res", "M", "unused", "stack" ],
1238 emit => 'pop%M %D0',
1239 latency => 3, # Pop is more expensive than Push on Athlon
1244 state => "exc_pinned",
1245 reg_req => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1248 emit => 'movl %S0, %D0',
1255 state => "exc_pinned",
1256 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1257 ins => [ "base", "index", "mem", "stack" ],
1258 outs => [ "unused0", "M", "unused1", "stack" ],
1259 emit => 'pop%M %AM',
1260 latency => 3, # Pop is more expensive than Push on Athlon
1265 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1267 outs => [ "frame", "stack", "M" ],
1273 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1275 outs => [ "frame", "stack" ],
1278 state => "exc_pinned",
1283 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1284 ins => [ "base", "index", "mem", "stack", "size" ],
1285 am => "source,binary",
1288 outs => [ "stack", "M" ],
1290 modified_flags => $status_flags
1295 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1296 ins => [ "base", "index", "mem", "stack", "size" ],
1297 am => "source,binary",
1298 emit => "subl %B\n".
1301 outs => [ "stack", "addr", "M" ],
1303 modified_flags => $status_flags
1307 op_flags => [ "keep" ],
1315 irn_flags => [ "rematerializable" ],
1316 reg_req => { out => [ "gp" ] },
1318 emit => "movl %%gs:0, %D0",
1324 # BT supports source address mode, but this is unused yet
1327 irn_flags => [ "rematerializable" ],
1328 state => "exc_pinned",
1329 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1330 ins => [ "left", "right" ],
1331 emit => 'bt%M %S1, %S0',
1334 mode => $mode_flags,
1335 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1339 irn_flags => [ "rematerializable" ],
1340 state => "exc_pinned",
1341 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1342 out => [ "gp", "flags", "none" ] },
1343 ins => [ "base", "index", "mem", "operand" ],
1344 outs => [ "res", "flags", "M" ],
1345 am => "source,binary",
1346 emit => 'bsf%M %AS3, %D0',
1350 modified_flags => $status_flags
1354 irn_flags => [ "rematerializable" ],
1355 state => "exc_pinned",
1356 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1357 out => [ "gp", "flags", "none" ] },
1358 ins => [ "base", "index", "mem", "operand" ],
1359 outs => [ "res", "flags", "M" ],
1360 am => "source,binary",
1361 emit => 'bsr%M %AS3, %D0',
1365 modified_flags => $status_flags
1369 # SSE4.2 or SSE4a popcnt instruction
1372 irn_flags => [ "rematerializable" ],
1373 state => "exc_pinned",
1374 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1375 out => [ "gp", "flags", "none" ] },
1376 ins => [ "base", "index", "mem", "operand" ],
1377 outs => [ "res", "flags", "M" ],
1378 am => "source,binary",
1379 emit => 'popcnt%M %AS3, %D0',
1383 modified_flags => $status_flags
1387 op_flags => [ "uses_memory", "fragile" ],
1388 state => "exc_pinned",
1390 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1391 out => [ "esp:I|S", "fpcw:I", "none", "eax", "ecx", "edx", "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "none", "none" ]
1393 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1394 outs => [ "stack", "fpcw", "M", "eax", "ecx", "edx", "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "X_regular", "X_except" ],
1395 emit => "call %*AS3",
1396 attr_type => "ia32_call_attr_t",
1397 attr => "unsigned pop, ir_type *call_tp",
1398 am => "source,unary",
1399 units => [ "BRANCH" ],
1400 latency => 4, # random number
1401 modified_flags => $status_flags
1405 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1407 # PS: try gcc __builtin_frame_address(100000) :-)
1410 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1411 ins => [ "frame", "cnt", "tmp" ],
1413 latency => 4, # random number
1414 attr_type => "ia32_climbframe_attr_t",
1415 attr => "unsigned count",
1424 irn_flags => [ "rematerializable" ],
1425 reg_req => { in => [ "gp" ],
1426 out => [ "in_r1" ] },
1428 emit => 'bswap%M %S0',
1436 # bswap16, use xchg here
1439 irn_flags => [ "rematerializable" ],
1440 reg_req => { in => [ "eax ebx ecx edx" ],
1441 out => [ "in_r1" ] },
1442 emit => 'xchg %<S0, %>S0',
1454 reg_req => { in => [ "none" ], out => [ "none" ] },
1463 # Undefined Instruction on ALL x86 CPU's
1467 reg_req => { in => [ "none" ], out => [ "none" ] },
1479 irn_flags => [ "rematerializable" ],
1481 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1482 ins => [ "port", "value", "mem" ],
1483 emit => 'out%M %^S0, %#S1',
1487 modified_flags => $status_flags
1494 irn_flags => [ "rematerializable" ],
1496 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1497 ins => [ "port", "mem" ],
1498 outs => [ "res", "M" ],
1499 emit => 'in%M %#D0, %^S0',
1503 modified_flags => $status_flags
1507 # Intel style prefetching
1510 op_flags => [ "uses_memory" ],
1511 state => "exc_pinned",
1512 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1513 ins => [ "base", "index", "mem" ],
1516 emit => "prefetcht0 %AM",
1521 op_flags => [ "uses_memory" ],
1522 state => "exc_pinned",
1523 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1524 ins => [ "base", "index", "mem" ],
1527 emit => "prefetcht1 %AM",
1532 op_flags => [ "uses_memory" ],
1533 state => "exc_pinned",
1534 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1535 ins => [ "base", "index", "mem" ],
1538 emit => "prefetcht2 %AM",
1543 op_flags => [ "uses_memory" ],
1544 state => "exc_pinned",
1545 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1546 ins => [ "base", "index", "mem" ],
1549 emit => "prefetchnta %AM",
1554 # 3DNow! prefetch instructions
1557 op_flags => [ "uses_memory" ],
1558 state => "exc_pinned",
1559 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1560 ins => [ "base", "index", "mem" ],
1563 emit => "prefetch %AM",
1568 op_flags => [ "uses_memory" ],
1569 state => "exc_pinned",
1570 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1571 ins => [ "base", "index", "mem" ],
1574 emit => "prefetchw %AM",
1580 irn_flags => [ "rematerializable" ],
1581 reg_req => { out => [ "xmm" ] },
1582 emit => 'xorp%FX %D0, %D0',
1589 op_flags => [ "constlike" ],
1590 irn_flags => [ "rematerializable" ],
1591 reg_req => { out => [ "xmm" ] },
1598 irn_flags => [ "rematerializable" ],
1599 reg_req => { out => [ "xmm" ] },
1600 emit => 'pxor %D0, %D0',
1606 # produces all 1 bits
1608 irn_flags => [ "rematerializable" ],
1609 reg_req => { out => [ "xmm" ] },
1610 emit => 'pcmpeqb %D0, %D0',
1616 # integer shift left, dword
1618 irn_flags => [ "rematerializable" ],
1619 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1620 emit => 'pslld %#S1, %D0',
1626 # integer shift left, qword
1628 irn_flags => [ "rematerializable" ],
1629 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1630 emit => 'psllq %#S1, %D0',
1636 # integer shift right, dword
1638 irn_flags => [ "rematerializable" ],
1639 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1640 emit => 'psrld %#S1, %D0',
1646 # mov from integer to SSE register
1648 irn_flags => [ "rematerializable" ],
1649 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1650 emit => 'movd %S0, %D0',
1657 irn_flags => [ "rematerializable" ],
1658 state => "exc_pinned",
1659 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1660 out => [ "in_r4 in_r5", "flags", "none" ] },
1661 ins => [ "base", "index", "mem", "left", "right" ],
1662 outs => [ "res", "flags", "M" ],
1663 am => "source,binary",
1664 emit => 'adds%FX %B',
1671 irn_flags => [ "rematerializable" ],
1672 state => "exc_pinned",
1673 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1674 out => [ "in_r4 in_r5", "flags", "none" ] },
1675 ins => [ "base", "index", "mem", "left", "right" ],
1676 outs => [ "res", "flags", "M" ],
1677 am => "source,binary",
1678 emit => 'muls%FX %B',
1685 irn_flags => [ "rematerializable" ],
1686 state => "exc_pinned",
1687 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1688 out => [ "in_r4 in_r5", "flags", "none" ] },
1689 ins => [ "base", "index", "mem", "left", "right" ],
1690 outs => [ "res", "flags", "M" ],
1691 am => "source,binary",
1692 emit => 'maxs%FX %B',
1699 irn_flags => [ "rematerializable" ],
1700 state => "exc_pinned",
1701 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1702 out => [ "in_r4 in_r5", "flags", "none" ] },
1703 ins => [ "base", "index", "mem", "left", "right" ],
1704 outs => [ "res", "flags", "M" ],
1705 am => "source,binary",
1706 emit => 'mins%FX %B',
1713 irn_flags => [ "rematerializable" ],
1714 state => "exc_pinned",
1715 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1716 out => [ "in_r4 in_r5", "flags", "none" ] },
1717 ins => [ "base", "index", "mem", "left", "right" ],
1718 outs => [ "res", "flags", "M" ],
1719 am => "source,binary",
1720 emit => 'andp%FX %B',
1727 irn_flags => [ "rematerializable" ],
1728 state => "exc_pinned",
1729 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1730 out => [ "in_r4 in_r5", "flags", "none" ] },
1731 ins => [ "base", "index", "mem", "left", "right" ],
1732 outs => [ "res", "flags", "M" ],
1733 am => "source,binary",
1734 emit => 'orp%FX %B',
1741 irn_flags => [ "rematerializable" ],
1742 state => "exc_pinned",
1743 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1744 out => [ "in_r4 in_r5", "flags", "none" ] },
1745 ins => [ "base", "index", "mem", "left", "right" ],
1746 outs => [ "res", "flags", "M" ],
1747 am => "source,binary",
1748 emit => 'xorp%FX %B',
1755 irn_flags => [ "rematerializable" ],
1756 state => "exc_pinned",
1757 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1758 out => [ "in_r4 !in_r5", "flags", "none" ] },
1759 ins => [ "base", "index", "mem", "left", "right" ],
1760 outs => [ "res", "flags", "M" ],
1761 am => "source,binary",
1762 emit => 'andnp%FX %B',
1769 irn_flags => [ "rematerializable" ],
1770 state => "exc_pinned",
1771 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1772 out => [ "in_r4", "flags", "none" ] },
1773 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1774 outs => [ "res", "flags", "M" ],
1775 am => "source,binary",
1776 emit => 'subs%FX %B',
1783 irn_flags => [ "rematerializable" ],
1784 state => "exc_pinned",
1785 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1786 out => [ "in_r4 !in_r5", "flags", "none" ] },
1787 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1788 outs => [ "res", "flags", "M" ],
1789 am => "source,binary",
1790 emit => 'divs%FX %B',
1796 irn_flags => [ "rematerializable" ],
1797 state => "exc_pinned",
1798 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1799 out => [ "eflags" ] },
1800 ins => [ "base", "index", "mem", "left", "right" ],
1801 outs => [ "flags" ],
1802 am => "source,binary",
1803 attr => "bool ins_permuted",
1804 init_attr => "attr->data.ins_permuted = ins_permuted;",
1805 emit => 'ucomis%FX %B',
1808 mode => $mode_flags,
1809 modified_flags => 1,
1813 op_flags => [ "uses_memory", "fragile" ],
1814 state => "exc_pinned",
1815 reg_req => { in => [ "gp", "gp", "none" ],
1816 out => [ "xmm", "none", "none", "none", "none" ] },
1817 ins => [ "base", "index", "mem" ],
1818 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1819 emit => 'movs%FX %AM, %D0',
1820 attr => "ir_mode *load_mode",
1821 init_attr => "attr->ls_mode = load_mode;",
1827 op_flags => [ "uses_memory", "fragile" ],
1828 state => "exc_pinned",
1829 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1830 out => [ "none", "none", "none" ] },
1831 ins => [ "base", "index", "mem", "val" ],
1832 outs => [ "M", "X_regular", "X_except" ],
1833 emit => 'movs%FX %S3, %AM',
1839 op_flags => [ "uses_memory", "fragile" ],
1840 state => "exc_pinned",
1841 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1842 out => [ "none", "none", "none" ] },
1843 ins => [ "base", "index", "mem", "val" ],
1844 outs => [ "M", "X_regular", "X_except" ],
1845 emit => 'movs%FX %S3, %AM',
1851 state => "exc_pinned",
1852 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1853 ins => [ "base", "index", "mem", "val" ],
1854 am => "source,unary",
1855 emit => 'cvtsi2ss %AS3, %D0',
1862 state => "exc_pinned",
1863 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1864 ins => [ "base", "index", "mem", "val" ],
1865 am => "source,unary",
1866 emit => 'cvtsi2sd %AS3, %D0',
1874 ins => [ "val_high", "val_low" ],
1876 dump_func => "NULL",
1881 outs => [ "res_high", "res_low" ],
1883 dump_func => "NULL",
1887 op_flags => [ "uses_memory", "fragile" ],
1889 reg_req => { in => [ "edi", "esi", "ecx", "none" ],
1890 out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1891 ins => [ "dest", "source", "count", "mem" ],
1892 outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1893 attr_type => "ia32_copyb_attr_t",
1894 attr => "unsigned size",
1897 # we don't care about this flag, so no need to mark this node
1898 # modified_flags => [ "DF" ]
1902 op_flags => [ "uses_memory", "fragile" ],
1904 reg_req => { in => [ "edi", "esi", "none" ],
1905 out => [ "edi", "esi", "none", "none", "none" ] },
1906 ins => [ "dest", "source", "mem" ],
1907 outs => [ "dest", "source", "M", "X_regular", "X_except" ],
1908 attr_type => "ia32_copyb_attr_t",
1909 attr => "unsigned size",
1912 # we don't care about this flag, so no need to mark this node
1913 # modified_flags => [ "DF" ]
1917 state => "exc_pinned",
1918 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1928 op_flags => [ "uses_memory", "fragile" ],
1929 state => "exc_pinned",
1930 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1931 out => [ "gp", "none", "none", "none", "none" ] },
1932 ins => [ "base", "index", "mem", "val" ],
1933 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1934 emit => "mov%#Ml %#AS3, %D0",
1935 am => "source,unary",
1938 attr => "ir_mode *smaller_mode",
1939 init_attr => "attr->ls_mode = smaller_mode;",
1944 op_flags => [ "uses_memory", "fragile" ],
1945 state => "exc_pinned",
1946 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1947 out => [ "gp", "none", "none", "none", "none" ] },
1948 ins => [ "base", "index", "mem", "val" ],
1949 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1950 emit => "mov%#Ml %#AS3, %D0",
1951 am => "source,unary",
1954 attr => "ir_mode *smaller_mode",
1955 init_attr => "attr->ls_mode = smaller_mode;",
1960 state => "exc_pinned",
1961 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1962 ins => [ "base", "index", "mem", "val" ],
1963 am => "source,unary",
1970 state => "exc_pinned",
1971 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1972 ins => [ "base", "index", "mem", "val" ],
1973 am => "source,unary",
1980 state => "exc_pinned",
1981 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1982 ins => [ "base", "index", "mem", "val" ],
1983 am => "source,unary",
1989 # rematerialisation disabled for all float nodes for now, because the fpcw
1990 # handler runs before spilling and we might end up with wrong fpcw then
1993 # irn_flags => [ "rematerializable" ],
1994 state => "exc_pinned",
1995 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1996 out => [ "fp", "none", "none" ] },
1997 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1998 outs => [ "res", "dummy", "M" ],
1999 emit => 'fadd%FP%FM %AF',
2000 am => "source,binary",
2004 attr_type => "ia32_x87_attr_t",
2008 # irn_flags => [ "rematerializable" ],
2009 state => "exc_pinned",
2010 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2011 out => [ "fp", "none", "none" ] },
2012 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2013 outs => [ "res", "dummy", "M" ],
2014 emit => 'fmul%FP%FM %AF',
2015 am => "source,binary",
2019 attr_type => "ia32_x87_attr_t",
2023 # irn_flags => [ "rematerializable" ],
2024 state => "exc_pinned",
2025 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2026 out => [ "fp", "none", "none" ] },
2027 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2028 outs => [ "res", "dummy", "M" ],
2029 emit => 'fsub%FR%FP%FM %AF',
2030 am => "source,binary",
2034 attr_type => "ia32_x87_attr_t",
2038 state => "exc_pinned",
2039 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2040 out => [ "fp", "none", "none" ] },
2041 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2042 outs => [ "res", "dummy", "M" ],
2043 emit => 'fdiv%FR%FP%FM %AF',
2044 am => "source,binary",
2047 attr_type => "ia32_x87_attr_t",
2051 reg_req => { in => [ "fp", "fp", "fpcw" ], out => [ "fp" ] },
2052 ins => [ "left", "right", "fpcw" ],
2057 attr_type => "ia32_x87_attr_t",
2061 irn_flags => [ "rematerializable" ],
2062 reg_req => { in => [ "fp"], out => [ "fp" ] },
2068 attr_type => "ia32_x87_attr_t",
2072 irn_flags => [ "rematerializable" ],
2073 reg_req => { in => [ "fp"], out => [ "fp" ] },
2079 attr_type => "ia32_x87_attr_t",
2083 irn_flags => [ "rematerializable" ],
2084 op_flags => [ "uses_memory", "fragile" ],
2085 state => "exc_pinned",
2086 reg_req => { in => [ "gp", "gp", "none" ],
2087 out => [ "fp", "none", "none", "none", "none" ] },
2088 ins => [ "base", "index", "mem" ],
2089 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
2090 emit => 'fld%FM %AM',
2091 attr => "ir_mode *load_mode",
2092 init_attr => "attr->attr.ls_mode = load_mode;",
2095 attr_type => "ia32_x87_attr_t",
2099 irn_flags => [ "rematerializable" ],
2100 op_flags => [ "uses_memory", "fragile" ],
2101 state => "exc_pinned",
2102 reg_req => { in => [ "gp", "gp", "none", "fp" ],
2103 out => [ "none", "none", "none" ] },
2104 ins => [ "base", "index", "mem", "val" ],
2105 outs => [ "M", "X_regular", "X_except" ],
2106 emit => 'fst%FP%FM %AM',
2107 attr => "ir_mode *store_mode",
2108 init_attr => "attr->attr.ls_mode = store_mode;",
2111 attr_type => "ia32_x87_attr_t",
2115 state => "exc_pinned",
2116 reg_req => { in => [ "gp", "gp", "none" ],
2117 out => [ "fp", "none", "none" ] },
2118 outs => [ "res", "unused", "M" ],
2119 ins => [ "base", "index", "mem" ],
2120 emit => 'fild%FM %AM',
2123 attr_type => "ia32_x87_attr_t",
2127 op_flags => [ "uses_memory", "fragile" ],
2128 state => "exc_pinned",
2129 reg_req => { in => [ "gp", "gp", "none", "fp", "fpcw" ],
2130 out => [ "none", "none", "none", "none" ] },
2131 ins => [ "base", "index", "mem", "val", "fpcw" ],
2132 outs => [ "dummy", "M", "X_regular", "X_except" ],
2133 emit => 'fist%FP%FM %AM',
2136 attr_type => "ia32_x87_attr_t",
2139 # SSE3 fisttp instruction
2141 op_flags => [ "uses_memory", "fragile" ],
2142 state => "exc_pinned",
2143 reg_req => { in => [ "gp", "gp", "none", "fp" ],
2144 out => [ "in_r4", "none", "none", "none" ]},
2145 ins => [ "base", "index", "mem", "val" ],
2146 outs => [ "res", "M", "X_regular", "X_except" ],
2147 emit => 'fisttp%FM %AM',
2150 attr_type => "ia32_x87_attr_t",
2154 irn_flags => [ "rematerializable" ],
2155 reg_req => { out => [ "fp" ] },
2161 attr_type => "ia32_x87_attr_t",
2165 irn_flags => [ "rematerializable" ],
2166 reg_req => { out => [ "fp" ] },
2172 attr_type => "ia32_x87_attr_t",
2176 irn_flags => [ "rematerializable" ],
2177 reg_req => { out => [ "fp" ] },
2183 attr_type => "ia32_x87_attr_t",
2187 irn_flags => [ "rematerializable" ],
2188 reg_req => { out => [ "fp" ] },
2194 attr_type => "ia32_x87_attr_t",
2198 irn_flags => [ "rematerializable" ],
2199 reg_req => { out => [ "fp" ] },
2205 attr_type => "ia32_x87_attr_t",
2209 irn_flags => [ "rematerializable" ],
2210 reg_req => { out => [ "fp" ] },
2216 attr_type => "ia32_x87_attr_t",
2220 irn_flags => [ "rematerializable" ],
2221 reg_req => { out => [ "fp" ] },
2227 attr_type => "ia32_x87_attr_t",
2231 # we can't allow to rematerialize this node so we don't
2232 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2233 # irn_flags => [ "rematerializable" ],
2234 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2235 ins => [ "left", "right" ],
2236 outs => [ "flags" ],
2237 emit => "fucom%FP %F0\n".
2239 attr => "bool ins_permuted",
2240 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2243 attr_type => "ia32_x87_attr_t",
2248 # we can't allow to rematerialize this node so we don't
2249 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2250 # irn_flags => [ "rematerializable" ],
2251 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2252 ins => [ "left", "right" ],
2253 outs => [ "flags" ],
2254 emit => "fucompp\n".
2256 attr => "bool ins_permuted",
2257 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2260 attr_type => "ia32_x87_attr_t",
2265 irn_flags => [ "rematerializable" ],
2266 reg_req => { in => [ "fp", "fp" ], out => [ "eflags" ] },
2267 ins => [ "left", "right" ],
2268 outs => [ "flags" ],
2269 emit => 'fucom%FPi %F0',
2270 attr => "bool ins_permuted",
2271 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2274 attr_type => "ia32_x87_attr_t",
2279 # irn_flags => [ "rematerializable" ],
2280 reg_req => { in => [ "fp" ], out => [ "eax" ] },
2282 outs => [ "flags" ],
2285 attr => "bool ins_permuted",
2286 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2289 attr_type => "ia32_x87_attr_t",
2294 irn_flags => [ "rematerializable" ],
2295 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2297 outs => [ "flags" ],
2301 mode => $mode_flags,
2305 # Note that it is NEVER allowed to do CSE on these nodes
2306 # Moreover, note the virtual register requierements!
2309 op_flags => [ "keep" ],
2310 reg_req => { out => [ "none" ] },
2311 cmp_attr => "return 1;",
2313 attr_type => "ia32_x87_attr_t",
2319 op_flags => [ "keep" ],
2320 reg_req => { out => [ "none" ] },
2321 cmp_attr => "return 1;",
2323 attr_type => "ia32_x87_attr_t",
2329 reg_req => { in => [ "fp"], out => [ "fp" ] },
2330 cmp_attr => "return 1;",
2332 attr_type => "ia32_x87_attr_t",
2337 op_flags => [ "keep" ],
2338 reg_req => { out => [ "none" ] },
2339 cmp_attr => "return 1;",
2341 attr_type => "ia32_x87_attr_t",
2347 op_flags => [ "keep" ],
2348 reg_req => { out => [ "none" ] },
2349 cmp_attr => "return 1;",
2350 emit => 'ffreep %F0',
2351 attr_type => "ia32_x87_attr_t",
2357 op_flags => [ "keep" ],
2358 reg_req => { out => [ "none" ] },
2359 cmp_attr => "return 1;",
2361 attr_type => "ia32_x87_attr_t",
2367 op_flags => [ "keep" ],
2368 reg_req => { out => [ "none" ] },
2369 cmp_attr => "return 1;",
2371 attr_type => "ia32_x87_attr_t",
2376 # Spilling and reloading of SSE registers, hardcoded, not generated #
2379 op_flags => [ "uses_memory", "fragile" ],
2380 state => "exc_pinned",
2381 reg_req => { in => [ "gp", "gp", "none" ],
2382 out => [ "xmm", "none", "none", "none" ] },
2383 emit => 'movdqu %D0, %AM',
2384 ins => [ "base", "index", "mem" ],
2385 outs => [ "res", "M", "X_regular", "X_except" ],
2391 op_flags => [ "uses_memory", "fragile" ],
2392 state => "exc_pinned",
2393 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
2394 out => [ "none", "none", "none" ] },
2395 ins => [ "base", "index", "mem", "val" ],
2396 outs => [ "M", "X_regular", "X_except" ],
2397 emit => 'movdqu %B',
2404 # Transform some attributes
2405 foreach my $op (keys(%nodes)) {
2406 my $node = $nodes{$op};
2407 my $op_attr_init = $node->{op_attr_init};
2409 if(defined($op_attr_init)) {
2410 $op_attr_init .= "\n\t";
2415 if(!defined($node->{latency})) {
2417 $node->{latency} = 0;
2419 die("Latency missing for op $op");
2422 $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2424 $node->{op_attr_init} = $op_attr_init;