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" ] },
1438 emit => 'bswap%M %S0',
1446 # bswap16, use xchg here
1449 irn_flags => [ "rematerializable" ],
1450 reg_req => { in => [ "eax ebx ecx edx" ],
1451 out => [ "in_r1" ] },
1452 emit => 'xchg %<S0, %>S0',
1464 reg_req => { in => [ "none" ], out => [ "none" ] },
1473 # Undefined Instruction on ALL x86 CPU's
1477 reg_req => { in => [ "none" ], out => [ "none" ] },
1489 irn_flags => [ "rematerializable" ],
1491 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1492 ins => [ "port", "value", "mem" ],
1493 emit => 'out%M %^S0, %#S1',
1497 modified_flags => $status_flags
1504 irn_flags => [ "rematerializable" ],
1506 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1507 ins => [ "port", "mem" ],
1508 outs => [ "res", "M" ],
1509 emit => 'in%M %#D0, %^S0',
1513 modified_flags => $status_flags
1517 # Intel style prefetching
1520 op_flags => [ "uses_memory" ],
1521 state => "exc_pinned",
1522 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1523 ins => [ "base", "index", "mem" ],
1526 emit => "prefetcht0 %AM",
1531 op_flags => [ "uses_memory" ],
1532 state => "exc_pinned",
1533 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1534 ins => [ "base", "index", "mem" ],
1537 emit => "prefetcht1 %AM",
1542 op_flags => [ "uses_memory" ],
1543 state => "exc_pinned",
1544 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1545 ins => [ "base", "index", "mem" ],
1548 emit => "prefetcht2 %AM",
1553 op_flags => [ "uses_memory" ],
1554 state => "exc_pinned",
1555 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1556 ins => [ "base", "index", "mem" ],
1559 emit => "prefetchnta %AM",
1564 # 3DNow! prefetch instructions
1567 op_flags => [ "uses_memory" ],
1568 state => "exc_pinned",
1569 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1570 ins => [ "base", "index", "mem" ],
1573 emit => "prefetch %AM",
1578 op_flags => [ "uses_memory" ],
1579 state => "exc_pinned",
1580 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1581 ins => [ "base", "index", "mem" ],
1584 emit => "prefetchw %AM",
1590 irn_flags => [ "rematerializable" ],
1591 reg_req => { out => [ "xmm" ] },
1592 emit => 'xorp%FX %D0, %D0',
1599 op_flags => [ "constlike" ],
1600 irn_flags => [ "rematerializable" ],
1601 reg_req => { out => [ "xmm" ] },
1608 irn_flags => [ "rematerializable" ],
1609 reg_req => { out => [ "xmm" ] },
1610 emit => 'pxor %D0, %D0',
1616 # produces all 1 bits
1618 irn_flags => [ "rematerializable" ],
1619 reg_req => { out => [ "xmm" ] },
1620 emit => 'pcmpeqb %D0, %D0',
1626 # integer shift left, dword
1628 irn_flags => [ "rematerializable" ],
1629 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1630 emit => 'pslld %#S1, %D0',
1636 # integer shift left, qword
1638 irn_flags => [ "rematerializable" ],
1639 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1640 emit => 'psllq %#S1, %D0',
1646 # integer shift right, dword
1648 irn_flags => [ "rematerializable" ],
1649 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1650 emit => 'psrld %#S1, %D0',
1656 # mov from integer to SSE register
1658 irn_flags => [ "rematerializable" ],
1659 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1660 emit => 'movd %S0, %D0',
1667 irn_flags => [ "rematerializable" ],
1668 state => "exc_pinned",
1669 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1670 out => [ "in_r4 in_r5", "flags", "none" ] },
1671 ins => [ "base", "index", "mem", "left", "right" ],
1672 outs => [ "res", "flags", "M" ],
1673 am => "source,binary",
1674 emit => 'adds%FX %B',
1681 irn_flags => [ "rematerializable" ],
1682 state => "exc_pinned",
1683 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1684 out => [ "in_r4 in_r5", "flags", "none" ] },
1685 ins => [ "base", "index", "mem", "left", "right" ],
1686 outs => [ "res", "flags", "M" ],
1687 am => "source,binary",
1688 emit => 'muls%FX %B',
1695 irn_flags => [ "rematerializable" ],
1696 state => "exc_pinned",
1697 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1698 out => [ "in_r4 in_r5", "flags", "none" ] },
1699 ins => [ "base", "index", "mem", "left", "right" ],
1700 outs => [ "res", "flags", "M" ],
1701 am => "source,binary",
1702 emit => 'maxs%FX %B',
1709 irn_flags => [ "rematerializable" ],
1710 state => "exc_pinned",
1711 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1712 out => [ "in_r4 in_r5", "flags", "none" ] },
1713 ins => [ "base", "index", "mem", "left", "right" ],
1714 outs => [ "res", "flags", "M" ],
1715 am => "source,binary",
1716 emit => 'mins%FX %B',
1723 irn_flags => [ "rematerializable" ],
1724 state => "exc_pinned",
1725 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1726 out => [ "in_r4 in_r5", "flags", "none" ] },
1727 ins => [ "base", "index", "mem", "left", "right" ],
1728 outs => [ "res", "flags", "M" ],
1729 am => "source,binary",
1730 emit => 'andp%FX %B',
1737 irn_flags => [ "rematerializable" ],
1738 state => "exc_pinned",
1739 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1740 out => [ "in_r4 in_r5", "flags", "none" ] },
1741 ins => [ "base", "index", "mem", "left", "right" ],
1742 outs => [ "res", "flags", "M" ],
1743 am => "source,binary",
1744 emit => 'orp%FX %B',
1751 irn_flags => [ "rematerializable" ],
1752 state => "exc_pinned",
1753 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1754 out => [ "in_r4 in_r5", "flags", "none" ] },
1755 ins => [ "base", "index", "mem", "left", "right" ],
1756 outs => [ "res", "flags", "M" ],
1757 am => "source,binary",
1758 emit => 'xorp%FX %B',
1765 irn_flags => [ "rematerializable" ],
1766 state => "exc_pinned",
1767 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1768 out => [ "in_r4 !in_r5", "flags", "none" ] },
1769 ins => [ "base", "index", "mem", "left", "right" ],
1770 outs => [ "res", "flags", "M" ],
1771 am => "source,binary",
1772 emit => 'andnp%FX %B',
1779 irn_flags => [ "rematerializable" ],
1780 state => "exc_pinned",
1781 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1782 out => [ "in_r4", "flags", "none" ] },
1783 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1784 outs => [ "res", "flags", "M" ],
1785 am => "source,binary",
1786 emit => 'subs%FX %B',
1793 irn_flags => [ "rematerializable" ],
1794 state => "exc_pinned",
1795 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1796 out => [ "in_r4 !in_r5", "flags", "none" ] },
1797 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1798 outs => [ "res", "flags", "M" ],
1799 am => "source,binary",
1800 emit => 'divs%FX %B',
1806 irn_flags => [ "rematerializable" ],
1807 state => "exc_pinned",
1808 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1809 out => [ "eflags" ] },
1810 ins => [ "base", "index", "mem", "left", "right" ],
1811 outs => [ "flags" ],
1812 am => "source,binary",
1813 attr => "bool ins_permuted",
1814 init_attr => "attr->data.ins_permuted = ins_permuted;",
1815 emit => 'ucomis%FX %B',
1818 mode => $mode_flags,
1819 modified_flags => 1,
1823 op_flags => [ "uses_memory", "fragile" ],
1824 state => "exc_pinned",
1825 reg_req => { in => [ "gp", "gp", "none" ],
1826 out => [ "xmm", "none", "none", "none", "none" ] },
1827 ins => [ "base", "index", "mem" ],
1828 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1829 emit => 'movs%FX %AM, %D0',
1830 attr => "ir_mode *load_mode",
1831 init_attr => "attr->ls_mode = load_mode;",
1837 op_flags => [ "uses_memory", "fragile" ],
1838 state => "exc_pinned",
1839 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1840 out => [ "none", "none", "none" ] },
1841 ins => [ "base", "index", "mem", "val" ],
1842 outs => [ "M", "X_regular", "X_except" ],
1843 emit => 'movs%FX %S3, %AM',
1849 op_flags => [ "uses_memory", "fragile" ],
1850 state => "exc_pinned",
1851 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1852 out => [ "none", "none", "none" ] },
1853 ins => [ "base", "index", "mem", "val" ],
1854 outs => [ "M", "X_regular", "X_except" ],
1855 emit => 'movs%FX %S3, %AM',
1861 state => "exc_pinned",
1862 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1863 ins => [ "base", "index", "mem", "val" ],
1864 am => "source,unary",
1865 emit => 'cvtsi2ss %AS3, %D0',
1872 state => "exc_pinned",
1873 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1874 ins => [ "base", "index", "mem", "val" ],
1875 am => "source,unary",
1876 emit => 'cvtsi2sd %AS3, %D0',
1884 ins => [ "val_high", "val_low" ],
1886 dump_func => "NULL",
1891 outs => [ "res_high", "res_low" ],
1893 dump_func => "NULL",
1897 op_flags => [ "uses_memory", "fragile" ],
1899 reg_req => { in => [ "edi", "esi", "ecx", "none" ],
1900 out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1901 ins => [ "dest", "source", "count", "mem" ],
1902 outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1903 attr_type => "ia32_copyb_attr_t",
1904 attr => "unsigned size",
1907 # we don't care about this flag, so no need to mark this node
1908 # modified_flags => [ "DF" ]
1912 op_flags => [ "uses_memory", "fragile" ],
1914 reg_req => { in => [ "edi", "esi", "none" ],
1915 out => [ "edi", "esi", "none", "none", "none" ] },
1916 ins => [ "dest", "source", "mem" ],
1917 outs => [ "dest", "source", "M", "X_regular", "X_except" ],
1918 attr_type => "ia32_copyb_attr_t",
1919 attr => "unsigned size",
1922 # we don't care about this flag, so no need to mark this node
1923 # modified_flags => [ "DF" ]
1927 state => "exc_pinned",
1928 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1938 op_flags => [ "uses_memory", "fragile" ],
1939 state => "exc_pinned",
1940 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1941 out => [ "gp", "none", "none", "none", "none" ] },
1942 ins => [ "base", "index", "mem", "val" ],
1943 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1944 emit => "mov%#Ml %#AS3, %D0",
1945 am => "source,unary",
1948 attr => "ir_mode *smaller_mode",
1949 init_attr => "attr->ls_mode = smaller_mode;",
1954 op_flags => [ "uses_memory", "fragile" ],
1955 state => "exc_pinned",
1956 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1957 out => [ "gp", "none", "none", "none", "none" ] },
1958 ins => [ "base", "index", "mem", "val" ],
1959 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1960 emit => "mov%#Ml %#AS3, %D0",
1961 am => "source,unary",
1964 attr => "ir_mode *smaller_mode",
1965 init_attr => "attr->ls_mode = smaller_mode;",
1970 state => "exc_pinned",
1971 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1972 ins => [ "base", "index", "mem", "val" ],
1973 am => "source,unary",
1980 state => "exc_pinned",
1981 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1982 ins => [ "base", "index", "mem", "val" ],
1983 am => "source,unary",
1990 state => "exc_pinned",
1991 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1992 ins => [ "base", "index", "mem", "val" ],
1993 am => "source,unary",
1999 # rematerialisation disabled for all float nodes for now, because the fpcw
2000 # handler runs before spilling and we might end up with wrong fpcw then
2003 # irn_flags => [ "rematerializable" ],
2004 state => "exc_pinned",
2005 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2006 out => [ "vfp", "none", "none" ] },
2007 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2008 outs => [ "res", "dummy", "M" ],
2009 am => "source,binary",
2013 attr_type => "ia32_x87_attr_t",
2017 # irn_flags => [ "rematerializable" ],
2018 state => "exc_pinned",
2019 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2020 out => [ "vfp", "none", "none" ] },
2021 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2022 outs => [ "res", "dummy", "M" ],
2023 am => "source,binary",
2027 attr_type => "ia32_x87_attr_t",
2031 # irn_flags => [ "rematerializable" ],
2032 state => "exc_pinned",
2033 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2034 out => [ "vfp", "none", "none" ] },
2035 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2036 outs => [ "res", "dummy", "M" ],
2037 am => "source,binary",
2041 attr_type => "ia32_x87_attr_t",
2045 state => "exc_pinned",
2046 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2047 out => [ "vfp", "none", "none" ] },
2048 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2049 outs => [ "res", "dummy", "M" ],
2050 am => "source,binary",
2053 attr_type => "ia32_x87_attr_t",
2057 reg_req => { in => [ "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
2058 ins => [ "left", "right", "fpcw" ],
2062 attr_type => "ia32_x87_attr_t",
2066 irn_flags => [ "rematerializable" ],
2067 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2072 attr_type => "ia32_x87_attr_t",
2076 irn_flags => [ "rematerializable" ],
2077 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2082 attr_type => "ia32_x87_attr_t",
2086 irn_flags => [ "rematerializable" ],
2087 op_flags => [ "uses_memory", "fragile" ],
2088 state => "exc_pinned",
2089 reg_req => { in => [ "gp", "gp", "none" ],
2090 out => [ "vfp", "none", "none", "none", "none" ] },
2091 ins => [ "base", "index", "mem" ],
2092 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
2093 attr => "ir_mode *load_mode",
2094 init_attr => "attr->attr.ls_mode = load_mode;",
2097 attr_type => "ia32_x87_attr_t",
2101 irn_flags => [ "rematerializable" ],
2102 op_flags => [ "uses_memory", "fragile" ],
2103 state => "exc_pinned",
2104 reg_req => { in => [ "gp", "gp", "none", "vfp" ],
2105 out => [ "none", "none", "none" ] },
2106 ins => [ "base", "index", "mem", "val" ],
2107 outs => [ "M", "X_regular", "X_except" ],
2108 attr => "ir_mode *store_mode",
2109 init_attr => "attr->attr.ls_mode = store_mode;",
2112 attr_type => "ia32_x87_attr_t",
2116 state => "exc_pinned",
2117 reg_req => { in => [ "gp", "gp", "none" ],
2118 out => [ "vfp", "none", "none" ] },
2119 outs => [ "res", "unused", "M" ],
2120 ins => [ "base", "index", "mem" ],
2123 attr_type => "ia32_x87_attr_t",
2127 op_flags => [ "uses_memory", "fragile" ],
2128 state => "exc_pinned",
2129 reg_req => { in => [ "gp", "gp", "none", "vfp", "fpcw" ],
2130 out => [ "none", "none", "none", "none" ] },
2131 ins => [ "base", "index", "mem", "val", "fpcw" ],
2132 outs => [ "dummy", "M", "X_regular", "X_except" ],
2135 attr_type => "ia32_x87_attr_t",
2138 # SSE3 fisttp instruction
2140 op_flags => [ "uses_memory", "fragile" ],
2141 state => "exc_pinned",
2142 reg_req => { in => [ "gp", "gp", "none", "vfp" ],
2143 out => [ "in_r4", "none", "none", "none" ]},
2144 ins => [ "base", "index", "mem", "val" ],
2145 outs => [ "res", "M", "X_regular", "X_except" ],
2148 attr_type => "ia32_x87_attr_t",
2152 irn_flags => [ "rematerializable" ],
2153 reg_req => { out => [ "vfp" ] },
2158 attr_type => "ia32_x87_attr_t",
2162 irn_flags => [ "rematerializable" ],
2163 reg_req => { out => [ "vfp" ] },
2168 attr_type => "ia32_x87_attr_t",
2172 irn_flags => [ "rematerializable" ],
2173 reg_req => { out => [ "vfp" ] },
2178 attr_type => "ia32_x87_attr_t",
2182 irn_flags => [ "rematerializable" ],
2183 reg_req => { out => [ "vfp" ] },
2188 attr_type => "ia32_x87_attr_t",
2192 irn_flags => [ "rematerializable" ],
2193 reg_req => { out => [ "vfp" ] },
2198 attr_type => "ia32_x87_attr_t",
2202 irn_flags => [ "rematerializable" ],
2203 reg_req => { out => [ "vfp" ] },
2208 attr_type => "ia32_x87_attr_t",
2212 irn_flags => [ "rematerializable" ],
2213 reg_req => { out => [ "vfp" ] },
2218 attr_type => "ia32_x87_attr_t",
2222 # we can't allow to rematerialize this node so we don't
2223 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2224 # irn_flags => [ "rematerializable" ],
2225 reg_req => { in => [ "vfp", "vfp" ], out => [ "eax" ] },
2226 ins => [ "left", "right" ],
2227 outs => [ "flags" ],
2228 attr => "bool ins_permuted",
2229 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2232 attr_type => "ia32_x87_attr_t",
2237 irn_flags => [ "rematerializable" ],
2238 reg_req => { in => [ "vfp", "vfp" ], out => [ "eflags" ] },
2239 ins => [ "left", "right" ],
2240 outs => [ "flags" ],
2241 attr => "bool ins_permuted",
2242 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2245 attr_type => "ia32_x87_attr_t",
2250 # irn_flags => [ "rematerializable" ],
2251 reg_req => { in => [ "vfp" ], out => [ "eax" ] },
2253 outs => [ "flags" ],
2254 attr => "bool ins_permuted",
2255 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2258 attr_type => "ia32_x87_attr_t",
2263 irn_flags => [ "rematerializable" ],
2264 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2266 outs => [ "flags" ],
2270 mode => $mode_flags,
2274 state => "exc_pinned",
2275 emit => 'fadd%FM %AF',
2277 attr_type => "ia32_x87_attr_t",
2282 state => "exc_pinned",
2283 emit => 'faddp%FM %AF',
2285 attr_type => "ia32_x87_attr_t",
2290 state => "exc_pinned",
2291 emit => 'fmul%FM %AF',
2293 attr_type => "ia32_x87_attr_t",
2298 state => "exc_pinned",
2299 emit => 'fmulp%FM %AF',,
2301 attr_type => "ia32_x87_attr_t",
2306 state => "exc_pinned",
2307 emit => 'fsub%FM %AF',
2309 attr_type => "ia32_x87_attr_t",
2313 # Note: gas is strangely buggy: fdivrp and fdivp as well as fsubrp and fsubp
2314 # are swapped, we work this around in the emitter...
2317 state => "exc_pinned",
2318 # see note about gas bugs
2319 emit => 'fsubrp%FM %AF',
2321 attr_type => "ia32_x87_attr_t",
2326 state => "exc_pinned",
2327 irn_flags => [ "rematerializable" ],
2328 emit => 'fsubr%FM %AF',
2330 attr_type => "ia32_x87_attr_t",
2335 state => "exc_pinned",
2336 irn_flags => [ "rematerializable" ],
2337 # see note about gas bugs before fsubp
2338 emit => 'fsubp%FM %AF',
2340 attr_type => "ia32_x87_attr_t",
2347 attr_type => "ia32_x87_attr_t",
2351 # this node is just here, to keep the simulator running
2352 # we can omit this when a fprem simulation function exists
2357 attr_type => "ia32_x87_attr_t",
2362 state => "exc_pinned",
2363 emit => 'fdiv%FM %AF',
2365 attr_type => "ia32_x87_attr_t",
2370 state => "exc_pinned",
2371 # see note about gas bugs before fsubp
2372 emit => 'fdivrp%FM %AF',
2374 attr_type => "ia32_x87_attr_t",
2379 state => "exc_pinned",
2380 emit => 'fdivr%FM %AF',
2382 attr_type => "ia32_x87_attr_t",
2387 state => "exc_pinned",
2388 # see note about gas bugs before fsubp
2389 emit => 'fdivp%FM %AF',
2391 attr_type => "ia32_x87_attr_t",
2398 attr_type => "ia32_x87_attr_t",
2403 op_flags => [ "keep" ],
2404 irn_flags => [ "rematerializable" ],
2407 attr_type => "ia32_x87_attr_t",
2412 irn_flags => [ "rematerializable" ],
2413 state => "exc_pinned",
2414 emit => 'fld%FM %AM',
2415 attr_type => "ia32_x87_attr_t",
2421 irn_flags => [ "rematerializable" ],
2422 state => "exc_pinned",
2423 emit => 'fst%FM %AM',
2425 attr_type => "ia32_x87_attr_t",
2431 irn_flags => [ "rematerializable" ],
2432 state => "exc_pinned",
2433 emit => 'fstp%FM %AM',
2435 attr_type => "ia32_x87_attr_t",
2441 state => "exc_pinned",
2442 emit => 'fild%FM %AM',
2443 attr_type => "ia32_x87_attr_t",
2449 state => "exc_pinned",
2450 emit => 'fist%FM %AM',
2452 attr_type => "ia32_x87_attr_t",
2458 state => "exc_pinned",
2459 emit => 'fistp%FM %AM',
2461 attr_type => "ia32_x87_attr_t",
2466 # SSE3 fisttp instruction
2468 state => "exc_pinned",
2469 emit => 'fisttp%FM %AM',
2471 attr_type => "ia32_x87_attr_t",
2477 op_flags => [ "constlike", "keep" ],
2478 irn_flags => [ "rematerializable" ],
2479 reg_req => { out => [ "vfp" ] },
2481 attr_type => "ia32_x87_attr_t",
2486 op_flags => [ "constlike", "keep" ],
2487 irn_flags => [ "rematerializable" ],
2488 reg_req => { out => [ "vfp" ] },
2490 attr_type => "ia32_x87_attr_t",
2495 op_flags => [ "constlike", "keep" ],
2496 irn_flags => [ "rematerializable" ],
2497 reg_req => { out => [ "vfp" ] },
2499 attr_type => "ia32_x87_attr_t",
2504 op_flags => [ "constlike", "keep" ],
2505 irn_flags => [ "rematerializable" ],
2506 reg_req => { out => [ "vfp" ] },
2508 attr_type => "ia32_x87_attr_t",
2513 op_flags => [ "constlike", "keep" ],
2514 irn_flags => [ "rematerializable" ],
2515 reg_req => { out => [ "vfp" ] },
2517 attr_type => "ia32_x87_attr_t",
2522 op_flags => [ "constlike", "keep" ],
2523 irn_flags => [ "rematerializable" ],
2524 reg_req => { out => [ "vfp" ] },
2526 attr_type => "ia32_x87_attr_t",
2531 op_flags => [ "constlike", "keep" ],
2532 irn_flags => [ "rematerializable" ],
2533 reg_req => { out => [ "vfp" ] },
2535 attr_type => "ia32_x87_attr_t",
2540 # Note that it is NEVER allowed to do CSE on these nodes
2541 # Moreover, note the virtual register requierements!
2544 op_flags => [ "keep" ],
2545 reg_req => { out => [ "none" ] },
2546 cmp_attr => "return 1;",
2548 attr_type => "ia32_x87_attr_t",
2554 op_flags => [ "keep" ],
2555 reg_req => { out => [ "none" ] },
2556 cmp_attr => "return 1;",
2558 attr_type => "ia32_x87_attr_t",
2564 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2565 cmp_attr => "return 1;",
2567 attr_type => "ia32_x87_attr_t",
2572 op_flags => [ "keep" ],
2573 reg_req => { out => [ "none" ] },
2574 cmp_attr => "return 1;",
2576 attr_type => "ia32_x87_attr_t",
2582 op_flags => [ "keep" ],
2583 reg_req => { out => [ "none" ] },
2584 cmp_attr => "return 1;",
2585 emit => 'ffreep %F0',
2586 attr_type => "ia32_x87_attr_t",
2592 op_flags => [ "keep" ],
2593 reg_req => { out => [ "none" ] },
2594 cmp_attr => "return 1;",
2596 attr_type => "ia32_x87_attr_t",
2602 op_flags => [ "keep" ],
2603 reg_req => { out => [ "none" ] },
2604 cmp_attr => "return 1;",
2606 attr_type => "ia32_x87_attr_t",
2613 emit => "fucom %F1\n".
2615 attr_type => "ia32_x87_attr_t",
2621 emit => "fucomp %F1\n".
2623 attr_type => "ia32_x87_attr_t",
2629 emit => "fucompp\n".
2631 attr_type => "ia32_x87_attr_t",
2637 emit => 'fucomi %F1',
2638 attr_type => "ia32_x87_attr_t",
2644 emit => 'fucompi %F1',
2645 attr_type => "ia32_x87_attr_t",
2653 attr_type => "ia32_x87_attr_t",
2657 # Spilling and reloading of SSE registers, hardcoded, not generated #
2660 op_flags => [ "uses_memory", "fragile" ],
2661 state => "exc_pinned",
2662 reg_req => { in => [ "gp", "gp", "none" ],
2663 out => [ "xmm", "none", "none", "none" ] },
2664 emit => 'movdqu %D0, %AM',
2665 ins => [ "base", "index", "mem" ],
2666 outs => [ "res", "M", "X_regular", "X_except" ],
2672 op_flags => [ "uses_memory", "fragile" ],
2673 state => "exc_pinned",
2674 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
2675 out => [ "none", "none", "none" ] },
2676 ins => [ "base", "index", "mem", "val" ],
2677 outs => [ "M", "X_regular", "X_except" ],
2678 emit => 'movdqu %B',
2685 # Transform some attributes
2686 foreach my $op (keys(%nodes)) {
2687 my $node = $nodes{$op};
2688 my $op_attr_init = $node->{op_attr_init};
2690 if(defined($op_attr_init)) {
2691 $op_attr_init .= "\n\t";
2696 if(!defined($node->{latency})) {
2698 $node->{latency} = 0;
2700 die("Latency missing for op $op");
2703 $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2705 $node->{op_attr_init} = $op_attr_init;