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
64 { name => "vfp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
65 { mode => $mode_fp87 }
68 { name => "st0", realname => "st", dwarf => 11, type => $ignore },
69 { name => "st1", realname => "st(1)", dwarf => 12, type => $ignore },
70 { name => "st2", realname => "st(2)", dwarf => 13, type => $ignore },
71 { name => "st3", realname => "st(3)", dwarf => 14, type => $ignore },
72 { name => "st4", realname => "st(4)", dwarf => 15, type => $ignore },
73 { name => "st5", realname => "st(5)", dwarf => 16, type => $ignore },
74 { name => "st6", realname => "st(6)", dwarf => 17, type => $ignore },
75 { name => "st7", realname => "st(7)", dwarf => 18, type => $ignore },
76 { mode => $mode_fp87, flags => "manual_ra" }
78 fp_cw => [ # the floating point control word
79 { name => "fpcw", dwarf => 37, type => $ignore | $state },
80 { mode => $mode_fpcw, flags => "manual_ra|state" }
83 { name => "eflags", dwarf => 9, type => 0 },
84 { mode => "mode_Iu", flags => "manual_ra" }
89 GP => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
90 SSE => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
91 VFP => [ 1, "VFP_VF0", "VFP_VF1", "VFP_VF2", "VFP_VF3", "VFP_VF4", "VFP_VF5", "VFP_VF6", "VFP_VF7" ],
92 BRANCH => [ 1, "BRANCH1", "BRANCH2" ],
97 bundels_per_cycle => 1
100 $default_op_attr_type = "ia32_op_attr_t";
101 $default_attr_type = "ia32_attr_t";
102 $default_copy_attr = "ia32_copy_attr";
104 sub ia32_custom_init_attr {
110 if(defined($node->{modified_flags})) {
111 $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n";
113 if(defined($node->{am})) {
114 my $am = $node->{am};
115 if($am eq "source,unary") {
116 $res .= "\tset_ia32_am_support(res, ia32_am_unary);";
117 } elsif($am eq "source,binary") {
118 $res .= "\tset_ia32_am_support(res, ia32_am_binary);";
119 } elsif($am eq "none") {
122 die("Invalid address mode '$am' specified on op $name");
125 if($node->{state} ne "exc_pinned"
126 and $node->{state} ne "pinned") {
127 die("AM nodes must have pinned or AM pinned state ($name)");
133 $custom_init_attr_func = \&ia32_custom_init_attr;
137 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
138 "\tinit_ia32_x87_attributes(res);".
139 "\tinit_ia32_asm_attributes(res);",
141 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);",
143 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
144 "\tinit_ia32_call_attributes(res, pop, call_tp);",
145 ia32_condcode_attr_t =>
146 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
147 "\tinit_ia32_condcode_attributes(res, condition_code);",
148 ia32_switch_attr_t =>
149 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
150 "\tinit_ia32_switch_attributes(res, switch_table);",
152 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
153 "\tinit_ia32_copyb_attributes(res, size);",
154 ia32_immediate_attr_t =>
155 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
156 "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
158 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
159 "\tinit_ia32_x87_attributes(res);",
160 ia32_climbframe_attr_t =>
161 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
162 "\tinit_ia32_climbframe_attributes(res, count);",
166 ia32_asm_attr_t => "ia32_compare_asm_attr",
167 ia32_attr_t => "ia32_compare_nodes_attr",
168 ia32_call_attr_t => "ia32_compare_call_attr",
169 ia32_condcode_attr_t => "ia32_compare_condcode_attr",
170 ia32_copyb_attr_t => "ia32_compare_copyb_attr",
171 ia32_switch_attr_t => "ia32_compare_nodes_attr",
172 ia32_immediate_attr_t => "ia32_compare_immediate_attr",
173 ia32_x87_attr_t => "ia32_compare_x87_attr",
174 ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
180 $status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
181 $status_flags_wo_cf = [ "PF", "AF", "ZF", "SF", "OF" ];
182 $fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
183 "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
189 op_flags => [ "constlike" ],
190 irn_flags => [ "not_scheduled" ],
191 reg_req => { out => [ "gp_NOREG:I" ] },
192 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
193 attr_type => "ia32_immediate_attr_t",
194 hash_func => "ia32_hash_Immediate",
202 out_arity => "variable",
203 attr_type => "ia32_asm_attr_t",
204 attr => "ident *asm_text, const ia32_asm_reg_t *register_map",
205 init_attr => "attr->asm_text = asm_text;\n".
206 "\tattr->register_map = register_map;\n",
208 modified_flags => $status_flags,
211 # "allocates" a free register
213 op_flags => [ "constlike", "cse_neutral" ],
214 irn_flags => [ "rematerializable" ],
215 reg_req => { out => [ "gp" ] },
220 cmp_attr => "return 1;",
224 irn_flags => [ "rematerializable" ],
225 state => "exc_pinned",
226 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
227 out => [ "in_r4 in_r5", "flags", "none" ] },
228 ins => [ "base", "index", "mem", "left", "right" ],
229 outs => [ "res", "flags", "M" ],
231 am => "source,binary",
235 modified_flags => $status_flags
239 irn_flags => [ "rematerializable" ],
240 state => "exc_pinned",
241 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
242 ins => [ "base", "index", "mem", "val" ],
243 emit => "add%M %#S3, %AM",
247 modified_flags => $status_flags
251 irn_flags => [ "rematerializable" ],
252 state => "exc_pinned",
253 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
254 ins => [ "base", "index", "mem", "val" ],
255 emit => "add%M %#S3, %AM",
259 modified_flags => $status_flags
263 state => "exc_pinned",
264 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
265 out => [ "in_r4 in_r5", "flags", "none" ] },
266 ins => [ "base", "index", "mem", "left", "right", "eflags" ],
267 outs => [ "res", "flags", "M" ],
269 am => "source,binary",
273 modified_flags => $status_flags
277 ins => [ "left", "right" ],
283 ins => [ "left", "right", "eflags" ],
289 # we should not rematrialize this node. It produces 2 results and has
290 # very strict constraints
291 state => "exc_pinned",
292 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
293 out => [ "eax", "flags", "none", "edx" ] },
294 ins => [ "base", "index", "mem", "left", "right" ],
295 emit => 'mul%M %AS4',
296 outs => [ "res_low", "flags", "M", "res_high" ],
297 am => "source,binary",
300 modified_flags => $status_flags
304 ins => [ "left", "right" ],
305 outs => [ "res_low", "flags", "M", "res_high" ],
311 irn_flags => [ "rematerializable" ],
312 state => "exc_pinned",
313 # TODO: adjust out requirements for the 3 operand form
314 # (no need for should_be_same then)
315 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
316 out => [ "in_r4 in_r5", "flags", "none" ] },
317 ins => [ "base", "index", "mem", "left", "right" ],
318 outs => [ "res", "flags", "M" ],
319 am => "source,binary",
323 modified_flags => $status_flags
327 irn_flags => [ "rematerializable" ],
328 state => "exc_pinned",
329 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
330 out => [ "eax", "flags", "none", "edx" ] },
331 ins => [ "base", "index", "mem", "left", "right" ],
332 emit => 'imul%M %AS4',
333 outs => [ "res_low", "flags", "M", "res_high" ],
334 am => "source,binary",
337 modified_flags => $status_flags
341 ins => [ "left", "right" ],
342 outs => [ "res_low", "flags", "M", "res_high" ],
348 irn_flags => [ "rematerializable" ],
349 state => "exc_pinned",
350 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
351 out => [ "in_r4 in_r5", "flags", "none" ] },
352 ins => [ "base", "index", "mem", "left", "right" ],
353 outs => [ "res", "flags", "M" ],
354 am => "source,binary",
359 modified_flags => $status_flags
363 irn_flags => [ "rematerializable" ],
364 state => "exc_pinned",
365 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
366 ins => [ "base", "index", "mem", "val" ],
367 emit => 'and%M %#S3, %AM',
371 modified_flags => $status_flags
375 irn_flags => [ "rematerializable" ],
376 state => "exc_pinned",
377 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
378 ins => [ "base", "index", "mem", "val" ],
379 emit => 'and%M %#S3, %AM',
383 modified_flags => $status_flags
387 irn_flags => [ "rematerializable" ],
388 state => "exc_pinned",
389 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
390 out => [ "in_r4 in_r5", "flags", "none" ] },
391 ins => [ "base", "index", "mem", "left", "right" ],
392 outs => [ "res", "flags", "M" ],
393 am => "source,binary",
398 modified_flags => $status_flags
402 irn_flags => [ "rematerializable" ],
403 state => "exc_pinned",
404 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
405 ins => [ "base", "index", "mem", "val" ],
406 emit => 'or%M %#S3, %AM',
410 modified_flags => $status_flags
414 irn_flags => [ "rematerializable" ],
415 state => "exc_pinned",
416 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
417 ins => [ "base", "index", "mem", "val" ],
418 emit => 'or%M %#S3, %AM',
422 modified_flags => $status_flags
426 irn_flags => [ "rematerializable" ],
427 state => "exc_pinned",
428 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
429 out => [ "in_r4 in_r5", "flags", "none" ] },
430 ins => [ "base", "index", "mem", "left", "right" ],
431 outs => [ "res", "flags", "M" ],
432 am => "source,binary",
437 modified_flags => $status_flags
441 op_flags => [ "constlike" ],
442 irn_flags => [ "rematerializable" ],
443 reg_req => { out => [ "gp", "flags" ] },
444 outs => [ "res", "flags" ],
445 emit => "xor%M %D0, %D0",
449 modified_flags => $status_flags
453 irn_flags => [ "rematerializable" ],
454 state => "exc_pinned",
455 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
456 ins => [ "base", "index", "mem", "val" ],
457 emit => 'xor%M %#S3, %AM',
461 modified_flags => $status_flags
465 irn_flags => [ "rematerializable" ],
466 state => "exc_pinned",
467 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
468 ins => [ "base", "index", "mem", "val" ],
469 emit => 'xor%M %#S3, %AM',
473 modified_flags => $status_flags
477 irn_flags => [ "rematerializable" ],
478 state => "exc_pinned",
479 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
480 out => [ "in_r4", "flags", "none" ] },
481 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
482 outs => [ "res", "flags", "M" ],
483 am => "source,binary",
488 modified_flags => $status_flags
492 irn_flags => [ "rematerializable" ],
493 state => "exc_pinned",
494 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
495 ins => [ "base", "index", "mem", "subtrahend" ],
496 emit => 'sub%M %#S3, %AM',
500 modified_flags => $status_flags
504 irn_flags => [ "rematerializable" ],
505 state => "exc_pinned",
506 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
507 ins => [ "base", "index", "mem", "subtrahend" ],
508 emit => 'sub%M %#S3, %AM',
512 modified_flags => $status_flags
516 state => "exc_pinned",
517 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
518 out => [ "in_r4", "flags", "none" ] },
519 ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
520 outs => [ "res", "flags", "M" ],
521 am => "source,binary",
526 modified_flags => $status_flags
530 # Spiller currently fails when rematerializing flag consumers
531 # irn_flags => [ "rematerializable" ],
532 reg_req => { in => [ "flags" ], out => [ "gp", "flags" ] },
533 outs => [ "res", "flags" ],
534 emit => "sbb%M %D0, %D0",
538 modified_flags => $status_flags
542 ins => [ "minuend", "subtrahend" ],
548 ins => [ "minuend", "subtrahend", "eflags" ],
554 op_flags => [ "fragile", "uses_memory" ],
555 state => "exc_pinned",
556 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
557 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
558 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
559 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
560 am => "source,unary",
561 emit => "idiv%M %AS3",
564 modified_flags => $status_flags
568 op_flags => [ "fragile", "uses_memory" ],
569 state => "exc_pinned",
570 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
571 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
572 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
573 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
574 am => "source,unary",
575 emit => "div%M %AS3",
578 modified_flags => $status_flags
582 irn_flags => [ "rematerializable" ],
583 reg_req => { in => [ "gp", "ecx" ],
584 out => [ "in_r1 !in_r2", "flags" ] },
585 ins => [ "val", "count" ],
586 outs => [ "res", "flags" ],
587 emit => 'shl%M %<S1, %S0',
591 modified_flags => $status_flags
595 irn_flags => [ "rematerializable" ],
596 state => "exc_pinned",
597 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
598 ins => [ "base", "index", "mem", "count" ],
599 emit => 'shl%M %<S3, %AM',
603 modified_flags => $status_flags
607 irn_flags => [ "rematerializable" ],
608 reg_req => { in => [ "gp", "gp", "ecx" ],
609 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
610 ins => [ "val_high", "val_low", "count" ],
611 outs => [ "res", "flags" ],
612 emit => "shld%M %<S2, %S1, %D0",
616 modified_flags => $status_flags
620 irn_flags => [ "rematerializable" ],
621 reg_req => { in => [ "gp", "ecx" ],
622 out => [ "in_r1 !in_r2", "flags" ] },
623 ins => [ "val", "count" ],
624 outs => [ "res", "flags" ],
625 emit => 'shr%M %<S1, %S0',
629 modified_flags => $status_flags
633 irn_flags => [ "rematerializable" ],
634 state => "exc_pinned",
635 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
636 ins => [ "base", "index", "mem", "count" ],
637 emit => 'shr%M %<S3, %AM',
641 modified_flags => $status_flags
645 irn_flags => [ "rematerializable" ],
646 reg_req => { in => [ "gp", "gp", "ecx" ],
647 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
648 ins => [ "val_high", "val_low", "count" ],
649 outs => [ "res", "flags" ],
650 emit => "shrd%M %<S2, %S1, %D0",
654 modified_flags => $status_flags
658 irn_flags => [ "rematerializable" ],
659 reg_req => { in => [ "gp", "ecx" ],
660 out => [ "in_r1 !in_r2", "flags" ] },
661 ins => [ "val", "count" ],
662 outs => [ "res", "flags" ],
663 emit => 'sar%M %<S1, %S0',
667 modified_flags => $status_flags
671 irn_flags => [ "rematerializable" ],
672 state => "exc_pinned",
673 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
674 ins => [ "base", "index", "mem", "count" ],
675 emit => 'sar%M %<S3, %AM',
679 modified_flags => $status_flags
683 irn_flags => [ "rematerializable" ],
684 reg_req => { in => [ "gp", "ecx" ],
685 out => [ "in_r1 !in_r2", "flags" ] },
686 ins => [ "val", "count" ],
687 outs => [ "res", "flags" ],
688 emit => 'ror%M %<S1, %S0',
692 modified_flags => $status_flags
696 irn_flags => [ "rematerializable" ],
697 state => "exc_pinned",
698 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
699 ins => [ "base", "index", "mem", "count" ],
700 emit => 'ror%M %<S3, %AM',
704 modified_flags => $status_flags
708 irn_flags => [ "rematerializable" ],
709 reg_req => { in => [ "gp", "ecx" ],
710 out => [ "in_r1 !in_r2", "flags" ] },
711 ins => [ "val", "count" ],
712 outs => [ "res", "flags" ],
713 emit => 'rol%M %<S1, %D0',
717 modified_flags => $status_flags
721 irn_flags => [ "rematerializable" ],
722 state => "exc_pinned",
723 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
724 ins => [ "base", "index", "mem", "count" ],
725 emit => 'rol%M %<S3, %AM',
729 modified_flags => $status_flags
733 irn_flags => [ "rematerializable" ],
734 reg_req => { in => [ "gp" ],
735 out => [ "in_r1", "flags" ] },
738 outs => [ "res", "flags" ],
742 modified_flags => $status_flags
746 irn_flags => [ "rematerializable" ],
747 state => "exc_pinned",
748 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
749 ins => [ "base", "index", "mem" ],
754 modified_flags => $status_flags
758 irn_flags => [ "rematerializable" ],
759 reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
760 outs => [ "low_res", "high_res" ],
763 modified_flags => $status_flags
768 irn_flags => [ "rematerializable" ],
769 reg_req => { in => [ "gp" ],
770 out => [ "in_r1", "flags" ] },
772 outs => [ "res", "flags" ],
777 modified_flags => $status_flags_wo_cf
781 irn_flags => [ "rematerializable" ],
782 state => "exc_pinned",
783 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
784 ins => [ "base", "index", "mem" ],
789 modified_flags => $status_flags_wo_cf
793 irn_flags => [ "rematerializable" ],
794 reg_req => { in => [ "gp" ],
795 out => [ "in_r1", "flags" ] },
797 outs => [ "res", "flags" ],
802 modified_flags => $status_flags_wo_cf
806 irn_flags => [ "rematerializable" ],
807 state => "exc_pinned",
808 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
809 ins => [ "base", "index", "mem" ],
814 modified_flags => $status_flags_wo_cf
818 irn_flags => [ "rematerializable" ],
819 reg_req => { in => [ "gp" ],
820 out => [ "in_r1" ] },
831 irn_flags => [ "rematerializable" ],
832 state => "exc_pinned",
833 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
834 ins => [ "base", "index", "mem" ],
843 reg_req => { in => [ "flags" ], out => [ "flags" ] },
848 modified_flags => $status_flags
852 reg_req => { out => [ "flags" ] },
857 modified_flags => $status_flags
861 irn_flags => [ "rematerializable" ],
862 state => "exc_pinned",
863 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
864 out => [ "flags", "none", "none" ] },
865 ins => [ "base", "index", "mem", "left", "right" ],
866 outs => [ "eflags", "unused", "M" ],
867 am => "source,binary",
869 attr => "bool ins_permuted",
870 init_attr => "attr->data.ins_permuted = ins_permuted;",
874 modified_flags => $status_flags
878 irn_flags => [ "rematerializable" ],
879 state => "exc_pinned",
880 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
881 out => [ "flags", "none", "none" ] },
882 ins => [ "base", "index", "mem", "left", "right" ],
883 outs => [ "eflags", "unused", "M" ],
884 am => "source,binary",
886 attr => "bool ins_permuted",
887 init_attr => "attr->data.ins_permuted = ins_permuted;",
891 modified_flags => $status_flags
895 irn_flags => [ "rematerializable" ],
896 state => "exc_pinned",
897 reg_req => { in => [ "eax ebx ecx edx" ],
898 out => [ "in_r1", "flags" ] },
899 emit => 'xorb %>S0, %<S0',
901 outs => [ "res", "flags" ],
905 modified_flags => $status_flags,
909 irn_flags => [ "rematerializable" ],
910 state => "exc_pinned",
911 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] ,
912 out => [ "flags", "none", "none" ] },
913 ins => [ "base", "index", "mem", "left", "right" ],
914 outs => [ "eflags", "unused", "M" ],
915 am => "source,binary",
917 attr => "bool ins_permuted",
918 init_attr => "attr->data.ins_permuted = ins_permuted;",
922 modified_flags => $status_flags
926 irn_flags => [ "rematerializable" ],
927 state => "exc_pinned",
928 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
929 out => [ "flags", "none", "none" ] },
930 ins => [ "base", "index", "mem", "left", "right" ],
931 outs => [ "eflags", "unused", "M" ],
932 am => "source,binary",
934 attr => "bool ins_permuted",
935 init_attr => "attr->data.ins_permuted = ins_permuted;",
939 modified_flags => $status_flags
943 #irn_flags => [ "rematerializable" ],
944 reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
947 attr_type => "ia32_condcode_attr_t",
948 attr => "ia32_condition_code_t condition_code",
949 # The way we handle Setcc with float nodes (potentially) destroys the flags
950 # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
951 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
952 . "\tif (condition_code & ia32_cc_additional_float_cases) {\n"
953 . "\t\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"
954 . "\t\t/* attr->latency = 3; */\n"
962 #irn_flags => [ "rematerializable" ],
963 state => "exc_pinned",
964 reg_req => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
965 ins => [ "base", "index", "mem","eflags" ],
966 attr_type => "ia32_condcode_attr_t",
967 attr => "ia32_condition_code_t condition_code",
968 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
969 emit => 'set%P3 %AM',
976 #irn_flags => [ "rematerializable" ],
977 state => "exc_pinned",
978 # (note: leave the false,true order intact to make it compatible with other
980 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
981 out => [ "in_r4 in_r5", "flags", "none" ] },
982 ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
983 outs => [ "res", "flags", "M" ],
984 am => "source,binary",
985 attr_type => "ia32_condcode_attr_t",
986 attr => "ia32_condition_code_t condition_code",
994 op_flags => [ "cfopcode", "forking" ],
995 reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
997 outs => [ "false", "true" ],
998 attr_type => "ia32_condcode_attr_t",
999 attr => "ia32_condition_code_t condition_code",
1001 units => [ "BRANCH" ],
1006 op_flags => [ "cfopcode", "forking" ],
1007 reg_req => { in => [ "gp", "gp" ] },
1008 ins => [ "base", "index" ],
1009 out_arity => "variable",
1010 attr_type => "ia32_switch_attr_t",
1011 attr => "const ir_switch_table *switch_table",
1013 units => [ "BRANCH" ],
1018 irn_flags => [ "simple_jump" ],
1019 op_flags => [ "cfopcode" ],
1020 reg_req => { out => [ "none" ] },
1022 units => [ "BRANCH" ],
1028 op_flags => [ "cfopcode", "unknown_jump" ],
1029 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1030 out => [ "none", "flags", "none" ] },
1031 ins => [ "base", "index", "mem", "target" ],
1032 outs => [ "jmp", "flags", "M" ],
1033 am => "source,unary",
1034 emit => 'jmp %*AS3',
1036 units => [ "BRANCH" ],
1041 op_flags => [ "constlike" ],
1042 irn_flags => [ "rematerializable" ],
1043 reg_req => { out => [ "gp" ] },
1044 emit => "movl %I, %D0",
1046 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
1047 attr_type => "ia32_immediate_attr_t",
1053 op_flags => [ "constlike" ],
1054 irn_flags => [ "rematerializable" ],
1055 reg_req => { out => [ "gp" ] },
1062 op_flags => [ "constlike" ],
1063 reg_req => { out => [ "gp" ] },
1067 modified_flags => $status_flags,
1072 op_flags => [ "constlike", "dump_noblock" ],
1073 irn_flags => [ "not_scheduled" ],
1074 reg_req => { out => [ "gp_NOREG:I" ] },
1083 op_flags => [ "constlike", "dump_noblock" ],
1084 irn_flags => [ "not_scheduled" ],
1085 reg_req => { out => [ "vfp_NOREG:I" ] },
1090 attr_type => "ia32_x87_attr_t",
1095 op_flags => [ "constlike", "dump_noblock" ],
1096 irn_flags => [ "not_scheduled" ],
1097 reg_req => { out => [ "xmm_NOREG:I" ] },
1106 op_flags => [ "constlike" ],
1107 irn_flags => [ "not_scheduled" ],
1108 reg_req => { out => [ "fpcw:I" ] },
1112 modified_flags => $fpcw_flags
1116 op_flags => [ "uses_memory" ],
1118 reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] },
1119 ins => [ "base", "index", "mem" ],
1121 emit => "fldcw %AM",
1124 modified_flags => $fpcw_flags
1128 op_flags => [ "uses_memory" ],
1130 reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1131 ins => [ "base", "index", "mem", "fpcw" ],
1133 emit => "fnstcw %AM",
1139 op_flags => [ "uses_memory" ],
1141 reg_req => { in => [ "fp_cw" ], out => [ "none" ] },
1149 # we should not rematrialize this node. It has very strict constraints.
1150 reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] },
1151 ins => [ "val", "clobbered" ],
1160 # Note that we add additional latency values depending on address mode, so a
1161 # lateny of 0 for load is correct
1164 op_flags => [ "uses_memory", "fragile" ],
1165 state => "exc_pinned",
1166 reg_req => { in => [ "gp", "gp", "none" ],
1167 out => [ "gp", "none", "none", "none", "none" ] },
1168 ins => [ "base", "index", "mem" ],
1169 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1171 emit => "mov%#Ml %AM, %D0",
1176 op_flags => [ "uses_memory", "fragile" ],
1177 state => "exc_pinned",
1178 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1179 out => [ "none", "none", "none" ] },
1180 ins => [ "base", "index", "mem", "val" ],
1181 outs => [ "M", "X_regular", "X_except" ],
1182 emit => 'mov%M %#S3, %AM',
1188 op_flags => [ "uses_memory", "fragile" ],
1189 state => "exc_pinned",
1190 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1191 out => ["none", "none", "none" ] },
1192 ins => [ "base", "index", "mem", "val" ],
1193 outs => [ "M", "X_regular", "X_except" ],
1194 emit => 'mov%M %#S3, %AM',
1200 irn_flags => [ "rematerializable" ],
1201 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1202 ins => [ "base", "index" ],
1203 emit => 'leal %AM, %D0',
1207 # lea doesn't modify the flags, but setting this seems advantageous since it
1208 # increases chances that the Lea is transformed back to an Add
1209 modified_flags => 1,
1213 state => "exc_pinned",
1214 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1215 ins => [ "base", "index", "mem", "val", "stack" ],
1216 emit => 'push%M %AS3',
1217 outs => [ "stack", "M" ],
1218 am => "source,unary",
1224 state => "exc_pinned",
1225 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1227 outs => [ "stack" ],
1228 emit => 'pushl %%eax',
1235 state => "exc_pinned",
1236 reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1237 ins => [ "mem", "stack" ],
1238 outs => [ "res", "M", "unused", "stack" ],
1239 emit => 'pop%M %D0',
1240 latency => 3, # Pop is more expensive than Push on Athlon
1245 state => "exc_pinned",
1246 reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1247 ins => [ "mem", "stack" ],
1248 outs => [ "res", "M", "unused", "stack" ],
1249 emit => 'pop%M %D0',
1250 latency => 3, # Pop is more expensive than Push on Athlon
1255 state => "exc_pinned",
1256 reg_req => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1259 emit => 'movl %S0, %D0',
1266 state => "exc_pinned",
1267 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1268 ins => [ "base", "index", "mem", "stack" ],
1269 outs => [ "unused0", "M", "unused1", "stack" ],
1270 emit => 'pop%M %AM',
1271 latency => 3, # Pop is more expensive than Push on Athlon
1276 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1278 outs => [ "frame", "stack", "M" ],
1284 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1286 outs => [ "frame", "stack" ],
1289 state => "exc_pinned",
1294 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1295 ins => [ "base", "index", "mem", "stack", "size" ],
1296 am => "source,binary",
1299 outs => [ "stack", "M" ],
1301 modified_flags => $status_flags
1306 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1307 ins => [ "base", "index", "mem", "stack", "size" ],
1308 am => "source,binary",
1309 emit => "subl %B\n".
1312 outs => [ "stack", "addr", "M" ],
1314 modified_flags => $status_flags
1318 op_flags => [ "keep" ],
1326 irn_flags => [ "rematerializable" ],
1327 reg_req => { out => [ "gp" ] },
1329 emit => "movl %%gs:0, %D0",
1335 # BT supports source address mode, but this is unused yet
1338 irn_flags => [ "rematerializable" ],
1339 state => "exc_pinned",
1340 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1341 ins => [ "left", "right" ],
1342 emit => 'bt%M %S1, %S0',
1345 mode => $mode_flags,
1346 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1350 irn_flags => [ "rematerializable" ],
1351 state => "exc_pinned",
1352 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1353 out => [ "gp", "flags", "none" ] },
1354 ins => [ "base", "index", "mem", "operand" ],
1355 outs => [ "res", "flags", "M" ],
1356 am => "source,binary",
1357 emit => 'bsf%M %AS3, %D0',
1361 modified_flags => $status_flags
1365 irn_flags => [ "rematerializable" ],
1366 state => "exc_pinned",
1367 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1368 out => [ "gp", "flags", "none" ] },
1369 ins => [ "base", "index", "mem", "operand" ],
1370 outs => [ "res", "flags", "M" ],
1371 am => "source,binary",
1372 emit => 'bsr%M %AS3, %D0',
1376 modified_flags => $status_flags
1380 # SSE4.2 or SSE4a popcnt instruction
1383 irn_flags => [ "rematerializable" ],
1384 state => "exc_pinned",
1385 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1386 out => [ "gp", "flags", "none" ] },
1387 ins => [ "base", "index", "mem", "operand" ],
1388 outs => [ "res", "flags", "M" ],
1389 am => "source,binary",
1390 emit => 'popcnt%M %AS3, %D0',
1394 modified_flags => $status_flags
1398 op_flags => [ "uses_memory", "fragile" ],
1399 state => "exc_pinned",
1401 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1402 out => [ "esp:I|S", "fpcw:I", "none", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "none", "none" ]
1404 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1405 outs => [ "stack", "fpcw", "M", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "X_regular", "X_except" ],
1406 emit => "call %*AS3",
1407 attr_type => "ia32_call_attr_t",
1408 attr => "unsigned pop, ir_type *call_tp",
1409 am => "source,unary",
1410 units => [ "BRANCH" ],
1411 latency => 4, # random number
1412 modified_flags => $status_flags
1416 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1418 # PS: try gcc __builtin_frame_address(100000) :-)
1421 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1422 ins => [ "frame", "cnt", "tmp" ],
1424 latency => 4, # random number
1425 attr_type => "ia32_climbframe_attr_t",
1426 attr => "unsigned count",
1435 irn_flags => [ "rematerializable" ],
1436 reg_req => { in => [ "gp" ],
1437 out => [ "in_r1" ] },
1439 emit => 'bswap%M %S0',
1447 # bswap16, use xchg here
1450 irn_flags => [ "rematerializable" ],
1451 reg_req => { in => [ "eax ebx ecx edx" ],
1452 out => [ "in_r1" ] },
1453 emit => 'xchg %<S0, %>S0',
1465 reg_req => { in => [ "none" ], out => [ "none" ] },
1474 # Undefined Instruction on ALL x86 CPU's
1478 reg_req => { in => [ "none" ], out => [ "none" ] },
1490 irn_flags => [ "rematerializable" ],
1492 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1493 ins => [ "port", "value", "mem" ],
1494 emit => 'out%M %^S0, %#S1',
1498 modified_flags => $status_flags
1505 irn_flags => [ "rematerializable" ],
1507 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1508 ins => [ "port", "mem" ],
1509 outs => [ "res", "M" ],
1510 emit => 'in%M %#D0, %^S0',
1514 modified_flags => $status_flags
1518 # Intel style prefetching
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 => "prefetcht0 %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 => "prefetcht1 %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 => "prefetcht2 %AM",
1554 op_flags => [ "uses_memory" ],
1555 state => "exc_pinned",
1556 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1557 ins => [ "base", "index", "mem" ],
1560 emit => "prefetchnta %AM",
1565 # 3DNow! prefetch instructions
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 => "prefetch %AM",
1579 op_flags => [ "uses_memory" ],
1580 state => "exc_pinned",
1581 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1582 ins => [ "base", "index", "mem" ],
1585 emit => "prefetchw %AM",
1591 irn_flags => [ "rematerializable" ],
1592 reg_req => { out => [ "xmm" ] },
1593 emit => 'xorp%FX %D0, %D0',
1600 op_flags => [ "constlike" ],
1601 irn_flags => [ "rematerializable" ],
1602 reg_req => { out => [ "xmm" ] },
1609 irn_flags => [ "rematerializable" ],
1610 reg_req => { out => [ "xmm" ] },
1611 emit => 'pxor %D0, %D0',
1617 # produces all 1 bits
1619 irn_flags => [ "rematerializable" ],
1620 reg_req => { out => [ "xmm" ] },
1621 emit => 'pcmpeqb %D0, %D0',
1627 # integer shift left, dword
1629 irn_flags => [ "rematerializable" ],
1630 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1631 emit => 'pslld %#S1, %D0',
1637 # integer shift left, qword
1639 irn_flags => [ "rematerializable" ],
1640 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1641 emit => 'psllq %#S1, %D0',
1647 # integer shift right, dword
1649 irn_flags => [ "rematerializable" ],
1650 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1651 emit => 'psrld %#S1, %D0',
1657 # mov from integer to SSE register
1659 irn_flags => [ "rematerializable" ],
1660 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1661 emit => 'movd %S0, %D0',
1668 irn_flags => [ "rematerializable" ],
1669 state => "exc_pinned",
1670 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1671 out => [ "in_r4 in_r5", "flags", "none" ] },
1672 ins => [ "base", "index", "mem", "left", "right" ],
1673 outs => [ "res", "flags", "M" ],
1674 am => "source,binary",
1675 emit => 'adds%FX %B',
1682 irn_flags => [ "rematerializable" ],
1683 state => "exc_pinned",
1684 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1685 out => [ "in_r4 in_r5", "flags", "none" ] },
1686 ins => [ "base", "index", "mem", "left", "right" ],
1687 outs => [ "res", "flags", "M" ],
1688 am => "source,binary",
1689 emit => 'muls%FX %B',
1696 irn_flags => [ "rematerializable" ],
1697 state => "exc_pinned",
1698 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1699 out => [ "in_r4 in_r5", "flags", "none" ] },
1700 ins => [ "base", "index", "mem", "left", "right" ],
1701 outs => [ "res", "flags", "M" ],
1702 am => "source,binary",
1703 emit => 'maxs%FX %B',
1710 irn_flags => [ "rematerializable" ],
1711 state => "exc_pinned",
1712 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1713 out => [ "in_r4 in_r5", "flags", "none" ] },
1714 ins => [ "base", "index", "mem", "left", "right" ],
1715 outs => [ "res", "flags", "M" ],
1716 am => "source,binary",
1717 emit => 'mins%FX %B',
1724 irn_flags => [ "rematerializable" ],
1725 state => "exc_pinned",
1726 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1727 out => [ "in_r4 in_r5", "flags", "none" ] },
1728 ins => [ "base", "index", "mem", "left", "right" ],
1729 outs => [ "res", "flags", "M" ],
1730 am => "source,binary",
1731 emit => 'andp%FX %B',
1738 irn_flags => [ "rematerializable" ],
1739 state => "exc_pinned",
1740 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1741 out => [ "in_r4 in_r5", "flags", "none" ] },
1742 ins => [ "base", "index", "mem", "left", "right" ],
1743 outs => [ "res", "flags", "M" ],
1744 am => "source,binary",
1745 emit => 'orp%FX %B',
1752 irn_flags => [ "rematerializable" ],
1753 state => "exc_pinned",
1754 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1755 out => [ "in_r4 in_r5", "flags", "none" ] },
1756 ins => [ "base", "index", "mem", "left", "right" ],
1757 outs => [ "res", "flags", "M" ],
1758 am => "source,binary",
1759 emit => 'xorp%FX %B',
1766 irn_flags => [ "rematerializable" ],
1767 state => "exc_pinned",
1768 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1769 out => [ "in_r4 !in_r5", "flags", "none" ] },
1770 ins => [ "base", "index", "mem", "left", "right" ],
1771 outs => [ "res", "flags", "M" ],
1772 am => "source,binary",
1773 emit => 'andnp%FX %B',
1780 irn_flags => [ "rematerializable" ],
1781 state => "exc_pinned",
1782 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1783 out => [ "in_r4", "flags", "none" ] },
1784 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1785 outs => [ "res", "flags", "M" ],
1786 am => "source,binary",
1787 emit => 'subs%FX %B',
1794 irn_flags => [ "rematerializable" ],
1795 state => "exc_pinned",
1796 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1797 out => [ "in_r4 !in_r5", "flags", "none" ] },
1798 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1799 outs => [ "res", "flags", "M" ],
1800 am => "source,binary",
1801 emit => 'divs%FX %B',
1807 irn_flags => [ "rematerializable" ],
1808 state => "exc_pinned",
1809 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1810 out => [ "eflags" ] },
1811 ins => [ "base", "index", "mem", "left", "right" ],
1812 outs => [ "flags" ],
1813 am => "source,binary",
1814 attr => "bool ins_permuted",
1815 init_attr => "attr->data.ins_permuted = ins_permuted;",
1816 emit => 'ucomis%FX %B',
1819 mode => $mode_flags,
1820 modified_flags => 1,
1824 op_flags => [ "uses_memory", "fragile" ],
1825 state => "exc_pinned",
1826 reg_req => { in => [ "gp", "gp", "none" ],
1827 out => [ "xmm", "none", "none", "none", "none" ] },
1828 ins => [ "base", "index", "mem" ],
1829 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1830 emit => 'movs%FX %AM, %D0',
1831 attr => "ir_mode *load_mode",
1832 init_attr => "attr->ls_mode = load_mode;",
1838 op_flags => [ "uses_memory", "fragile" ],
1839 state => "exc_pinned",
1840 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1841 out => [ "none", "none", "none" ] },
1842 ins => [ "base", "index", "mem", "val" ],
1843 outs => [ "M", "X_regular", "X_except" ],
1844 emit => 'movs%FX %S3, %AM',
1850 op_flags => [ "uses_memory", "fragile" ],
1851 state => "exc_pinned",
1852 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1853 out => [ "none", "none", "none" ] },
1854 ins => [ "base", "index", "mem", "val" ],
1855 outs => [ "M", "X_regular", "X_except" ],
1856 emit => 'movs%FX %S3, %AM',
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 => 'cvtsi2ss %AS3, %D0',
1873 state => "exc_pinned",
1874 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1875 ins => [ "base", "index", "mem", "val" ],
1876 am => "source,unary",
1877 emit => 'cvtsi2sd %AS3, %D0',
1885 ins => [ "val_high", "val_low" ],
1887 dump_func => "NULL",
1892 outs => [ "res_high", "res_low" ],
1894 dump_func => "NULL",
1898 op_flags => [ "uses_memory", "fragile" ],
1900 reg_req => { in => [ "edi", "esi", "ecx", "none" ],
1901 out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1902 ins => [ "dest", "source", "count", "mem" ],
1903 outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1904 attr_type => "ia32_copyb_attr_t",
1905 attr => "unsigned size",
1908 # we don't care about this flag, so no need to mark this node
1909 # modified_flags => [ "DF" ]
1913 op_flags => [ "uses_memory", "fragile" ],
1915 reg_req => { in => [ "edi", "esi", "none" ],
1916 out => [ "edi", "esi", "none", "none", "none" ] },
1917 ins => [ "dest", "source", "mem" ],
1918 outs => [ "dest", "source", "M", "X_regular", "X_except" ],
1919 attr_type => "ia32_copyb_attr_t",
1920 attr => "unsigned size",
1923 # we don't care about this flag, so no need to mark this node
1924 # modified_flags => [ "DF" ]
1928 state => "exc_pinned",
1929 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1939 op_flags => [ "uses_memory", "fragile" ],
1940 state => "exc_pinned",
1941 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1942 out => [ "gp", "none", "none", "none", "none" ] },
1943 ins => [ "base", "index", "mem", "val" ],
1944 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1945 emit => "mov%#Ml %#AS3, %D0",
1946 am => "source,unary",
1949 attr => "ir_mode *smaller_mode",
1950 init_attr => "attr->ls_mode = smaller_mode;",
1955 op_flags => [ "uses_memory", "fragile" ],
1956 state => "exc_pinned",
1957 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1958 out => [ "gp", "none", "none", "none", "none" ] },
1959 ins => [ "base", "index", "mem", "val" ],
1960 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1961 emit => "mov%#Ml %#AS3, %D0",
1962 am => "source,unary",
1965 attr => "ir_mode *smaller_mode",
1966 init_attr => "attr->ls_mode = smaller_mode;",
1971 state => "exc_pinned",
1972 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1973 ins => [ "base", "index", "mem", "val" ],
1974 am => "source,unary",
1981 state => "exc_pinned",
1982 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1983 ins => [ "base", "index", "mem", "val" ],
1984 am => "source,unary",
1991 state => "exc_pinned",
1992 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1993 ins => [ "base", "index", "mem", "val" ],
1994 am => "source,unary",
2000 # rematerialisation disabled for all float nodes for now, because the fpcw
2001 # handler runs before spilling and we might end up with wrong fpcw then
2004 # irn_flags => [ "rematerializable" ],
2005 state => "exc_pinned",
2006 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2007 out => [ "vfp", "none", "none" ] },
2008 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2009 outs => [ "res", "dummy", "M" ],
2010 am => "source,binary",
2014 attr_type => "ia32_x87_attr_t",
2018 # irn_flags => [ "rematerializable" ],
2019 state => "exc_pinned",
2020 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2021 out => [ "vfp", "none", "none" ] },
2022 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2023 outs => [ "res", "dummy", "M" ],
2024 am => "source,binary",
2028 attr_type => "ia32_x87_attr_t",
2032 # irn_flags => [ "rematerializable" ],
2033 state => "exc_pinned",
2034 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2035 out => [ "vfp", "none", "none" ] },
2036 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2037 outs => [ "res", "dummy", "M" ],
2038 am => "source,binary",
2042 attr_type => "ia32_x87_attr_t",
2046 state => "exc_pinned",
2047 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2048 out => [ "vfp", "none", "none" ] },
2049 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2050 outs => [ "res", "dummy", "M" ],
2051 am => "source,binary",
2054 attr_type => "ia32_x87_attr_t",
2058 reg_req => { in => [ "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
2059 ins => [ "left", "right", "fpcw" ],
2063 attr_type => "ia32_x87_attr_t",
2067 irn_flags => [ "rematerializable" ],
2068 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2073 attr_type => "ia32_x87_attr_t",
2077 irn_flags => [ "rematerializable" ],
2078 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2083 attr_type => "ia32_x87_attr_t",
2087 irn_flags => [ "rematerializable" ],
2088 op_flags => [ "uses_memory", "fragile" ],
2089 state => "exc_pinned",
2090 reg_req => { in => [ "gp", "gp", "none" ],
2091 out => [ "vfp", "none", "none", "none", "none" ] },
2092 ins => [ "base", "index", "mem" ],
2093 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
2094 attr => "ir_mode *load_mode",
2095 init_attr => "attr->attr.ls_mode = load_mode;",
2098 attr_type => "ia32_x87_attr_t",
2102 irn_flags => [ "rematerializable" ],
2103 op_flags => [ "uses_memory", "fragile" ],
2104 state => "exc_pinned",
2105 reg_req => { in => [ "gp", "gp", "none", "vfp" ],
2106 out => [ "none", "none", "none" ] },
2107 ins => [ "base", "index", "mem", "val" ],
2108 outs => [ "M", "X_regular", "X_except" ],
2109 attr => "ir_mode *store_mode",
2110 init_attr => "attr->attr.ls_mode = store_mode;",
2113 attr_type => "ia32_x87_attr_t",
2117 state => "exc_pinned",
2118 reg_req => { in => [ "gp", "gp", "none" ],
2119 out => [ "vfp", "none", "none" ] },
2120 outs => [ "res", "unused", "M" ],
2121 ins => [ "base", "index", "mem" ],
2124 attr_type => "ia32_x87_attr_t",
2128 op_flags => [ "uses_memory", "fragile" ],
2129 state => "exc_pinned",
2130 reg_req => { in => [ "gp", "gp", "none", "vfp", "fpcw" ],
2131 out => [ "none", "none", "none", "none" ] },
2132 ins => [ "base", "index", "mem", "val", "fpcw" ],
2133 outs => [ "dummy", "M", "X_regular", "X_except" ],
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", "vfp" ],
2144 out => [ "in_r4", "none", "none", "none" ]},
2145 ins => [ "base", "index", "mem", "val" ],
2146 outs => [ "res", "M", "X_regular", "X_except" ],
2149 attr_type => "ia32_x87_attr_t",
2153 irn_flags => [ "rematerializable" ],
2154 reg_req => { out => [ "vfp" ] },
2159 attr_type => "ia32_x87_attr_t",
2163 irn_flags => [ "rematerializable" ],
2164 reg_req => { out => [ "vfp" ] },
2169 attr_type => "ia32_x87_attr_t",
2173 irn_flags => [ "rematerializable" ],
2174 reg_req => { out => [ "vfp" ] },
2179 attr_type => "ia32_x87_attr_t",
2183 irn_flags => [ "rematerializable" ],
2184 reg_req => { out => [ "vfp" ] },
2189 attr_type => "ia32_x87_attr_t",
2193 irn_flags => [ "rematerializable" ],
2194 reg_req => { out => [ "vfp" ] },
2199 attr_type => "ia32_x87_attr_t",
2203 irn_flags => [ "rematerializable" ],
2204 reg_req => { out => [ "vfp" ] },
2209 attr_type => "ia32_x87_attr_t",
2213 irn_flags => [ "rematerializable" ],
2214 reg_req => { out => [ "vfp" ] },
2219 attr_type => "ia32_x87_attr_t",
2223 # we can't allow to rematerialize this node so we don't
2224 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2225 # irn_flags => [ "rematerializable" ],
2226 reg_req => { in => [ "vfp", "vfp" ], out => [ "eax" ] },
2227 ins => [ "left", "right" ],
2228 outs => [ "flags" ],
2229 attr => "bool ins_permuted",
2230 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2233 attr_type => "ia32_x87_attr_t",
2238 irn_flags => [ "rematerializable" ],
2239 reg_req => { in => [ "vfp", "vfp" ], out => [ "eflags" ] },
2240 ins => [ "left", "right" ],
2241 outs => [ "flags" ],
2242 attr => "bool ins_permuted",
2243 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2246 attr_type => "ia32_x87_attr_t",
2251 # irn_flags => [ "rematerializable" ],
2252 reg_req => { in => [ "vfp" ], out => [ "eax" ] },
2254 outs => [ "flags" ],
2255 attr => "bool ins_permuted",
2256 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2259 attr_type => "ia32_x87_attr_t",
2264 irn_flags => [ "rematerializable" ],
2265 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2267 outs => [ "flags" ],
2271 mode => $mode_flags,
2275 state => "exc_pinned",
2276 emit => 'fadd%FP%FM %AF',
2278 attr_type => "ia32_x87_attr_t",
2283 state => "exc_pinned",
2284 emit => 'fmul%FP%FM %AF',
2286 attr_type => "ia32_x87_attr_t",
2291 state => "exc_pinned",
2292 emit => 'fsub%FR%FP%FM %AF',
2294 attr_type => "ia32_x87_attr_t",
2301 attr_type => "ia32_x87_attr_t",
2306 state => "exc_pinned",
2307 emit => 'fdiv%FR%FP%FM %AF',
2309 attr_type => "ia32_x87_attr_t",
2316 attr_type => "ia32_x87_attr_t",
2321 op_flags => [ "keep" ],
2322 irn_flags => [ "rematerializable" ],
2325 attr_type => "ia32_x87_attr_t",
2330 irn_flags => [ "rematerializable" ],
2331 state => "exc_pinned",
2332 emit => 'fld%FM %AM',
2333 attr_type => "ia32_x87_attr_t",
2339 irn_flags => [ "rematerializable" ],
2340 state => "exc_pinned",
2341 emit => 'fst%FP%FM %AM',
2343 attr_type => "ia32_x87_attr_t",
2349 state => "exc_pinned",
2350 emit => 'fild%FM %AM',
2351 attr_type => "ia32_x87_attr_t",
2357 state => "exc_pinned",
2358 emit => 'fist%FP%FM %AM',
2360 attr_type => "ia32_x87_attr_t",
2365 # SSE3 fisttp instruction
2367 state => "exc_pinned",
2368 emit => 'fisttp%FM %AM',
2370 attr_type => "ia32_x87_attr_t",
2376 op_flags => [ "constlike", "keep" ],
2377 irn_flags => [ "rematerializable" ],
2378 reg_req => { out => [ "vfp" ] },
2380 attr_type => "ia32_x87_attr_t",
2385 op_flags => [ "constlike", "keep" ],
2386 irn_flags => [ "rematerializable" ],
2387 reg_req => { out => [ "vfp" ] },
2389 attr_type => "ia32_x87_attr_t",
2394 op_flags => [ "constlike", "keep" ],
2395 irn_flags => [ "rematerializable" ],
2396 reg_req => { out => [ "vfp" ] },
2398 attr_type => "ia32_x87_attr_t",
2403 op_flags => [ "constlike", "keep" ],
2404 irn_flags => [ "rematerializable" ],
2405 reg_req => { out => [ "vfp" ] },
2407 attr_type => "ia32_x87_attr_t",
2412 op_flags => [ "constlike", "keep" ],
2413 irn_flags => [ "rematerializable" ],
2414 reg_req => { out => [ "vfp" ] },
2416 attr_type => "ia32_x87_attr_t",
2421 op_flags => [ "constlike", "keep" ],
2422 irn_flags => [ "rematerializable" ],
2423 reg_req => { out => [ "vfp" ] },
2425 attr_type => "ia32_x87_attr_t",
2430 op_flags => [ "constlike", "keep" ],
2431 irn_flags => [ "rematerializable" ],
2432 reg_req => { out => [ "vfp" ] },
2434 attr_type => "ia32_x87_attr_t",
2439 # Note that it is NEVER allowed to do CSE on these nodes
2440 # Moreover, note the virtual register requierements!
2443 op_flags => [ "keep" ],
2444 reg_req => { out => [ "none" ] },
2445 cmp_attr => "return 1;",
2447 attr_type => "ia32_x87_attr_t",
2453 op_flags => [ "keep" ],
2454 reg_req => { out => [ "none" ] },
2455 cmp_attr => "return 1;",
2457 attr_type => "ia32_x87_attr_t",
2463 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2464 cmp_attr => "return 1;",
2466 attr_type => "ia32_x87_attr_t",
2471 op_flags => [ "keep" ],
2472 reg_req => { out => [ "none" ] },
2473 cmp_attr => "return 1;",
2475 attr_type => "ia32_x87_attr_t",
2481 op_flags => [ "keep" ],
2482 reg_req => { out => [ "none" ] },
2483 cmp_attr => "return 1;",
2484 emit => 'ffreep %F0',
2485 attr_type => "ia32_x87_attr_t",
2491 op_flags => [ "keep" ],
2492 reg_req => { out => [ "none" ] },
2493 cmp_attr => "return 1;",
2495 attr_type => "ia32_x87_attr_t",
2501 op_flags => [ "keep" ],
2502 reg_req => { out => [ "none" ] },
2503 cmp_attr => "return 1;",
2505 attr_type => "ia32_x87_attr_t",
2512 emit => "fucom %F1\n".
2514 attr_type => "ia32_x87_attr_t",
2520 emit => "fucomp %F1\n".
2522 attr_type => "ia32_x87_attr_t",
2528 emit => "fucompp\n".
2530 attr_type => "ia32_x87_attr_t",
2536 emit => 'fucomi %F1',
2537 attr_type => "ia32_x87_attr_t",
2543 emit => 'fucompi %F1',
2544 attr_type => "ia32_x87_attr_t",
2552 attr_type => "ia32_x87_attr_t",
2556 # Spilling and reloading of SSE registers, hardcoded, not generated #
2559 op_flags => [ "uses_memory", "fragile" ],
2560 state => "exc_pinned",
2561 reg_req => { in => [ "gp", "gp", "none" ],
2562 out => [ "xmm", "none", "none", "none" ] },
2563 emit => 'movdqu %D0, %AM',
2564 ins => [ "base", "index", "mem" ],
2565 outs => [ "res", "M", "X_regular", "X_except" ],
2571 op_flags => [ "uses_memory", "fragile" ],
2572 state => "exc_pinned",
2573 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
2574 out => [ "none", "none", "none" ] },
2575 ins => [ "base", "index", "mem", "val" ],
2576 outs => [ "M", "X_regular", "X_except" ],
2577 emit => 'movdqu %B',
2584 # Transform some attributes
2585 foreach my $op (keys(%nodes)) {
2586 my $node = $nodes{$op};
2587 my $op_attr_init = $node->{op_attr_init};
2589 if(defined($op_attr_init)) {
2590 $op_attr_init .= "\n\t";
2595 if(!defined($node->{latency})) {
2597 $node->{latency} = 0;
2599 die("Latency missing for op $op");
2602 $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2604 $node->{op_attr_init} = $op_attr_init;