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 ins => [ "base", "index", "mem", "target" ],
1031 am => "source,unary",
1032 emit => 'jmp %*AS3',
1034 units => [ "BRANCH" ],
1036 init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements
1040 op_flags => [ "constlike" ],
1041 irn_flags => [ "rematerializable" ],
1042 reg_req => { out => [ "gp" ] },
1043 emit => "movl %I, %D0",
1045 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
1046 attr_type => "ia32_immediate_attr_t",
1052 op_flags => [ "constlike" ],
1053 irn_flags => [ "rematerializable" ],
1054 reg_req => { out => [ "gp" ] },
1061 op_flags => [ "constlike" ],
1062 reg_req => { out => [ "gp" ] },
1066 modified_flags => $status_flags,
1071 op_flags => [ "constlike", "dump_noblock" ],
1072 irn_flags => [ "not_scheduled" ],
1073 reg_req => { out => [ "gp_NOREG:I" ] },
1082 op_flags => [ "constlike", "dump_noblock" ],
1083 irn_flags => [ "not_scheduled" ],
1084 reg_req => { out => [ "vfp_NOREG:I" ] },
1089 attr_type => "ia32_x87_attr_t",
1094 op_flags => [ "constlike", "dump_noblock" ],
1095 irn_flags => [ "not_scheduled" ],
1096 reg_req => { out => [ "xmm_NOREG:I" ] },
1105 op_flags => [ "constlike" ],
1106 irn_flags => [ "not_scheduled" ],
1107 reg_req => { out => [ "fpcw:I" ] },
1111 modified_flags => $fpcw_flags
1115 op_flags => [ "uses_memory" ],
1117 reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] },
1118 ins => [ "base", "index", "mem" ],
1120 emit => "fldcw %AM",
1123 modified_flags => $fpcw_flags
1127 op_flags => [ "uses_memory" ],
1129 reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1130 ins => [ "base", "index", "mem", "fpcw" ],
1132 emit => "fnstcw %AM",
1138 op_flags => [ "uses_memory" ],
1140 reg_req => { in => [ "fp_cw" ], out => [ "none" ] },
1148 # we should not rematrialize this node. It has very strict constraints.
1149 reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] },
1150 ins => [ "val", "clobbered" ],
1159 # Note that we add additional latency values depending on address mode, so a
1160 # lateny of 0 for load is correct
1163 op_flags => [ "uses_memory", "fragile" ],
1164 state => "exc_pinned",
1165 reg_req => { in => [ "gp", "gp", "none" ],
1166 out => [ "gp", "none", "none", "none", "none" ] },
1167 ins => [ "base", "index", "mem" ],
1168 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1170 emit => "mov%#Ml %AM, %D0",
1175 op_flags => [ "uses_memory", "fragile" ],
1176 state => "exc_pinned",
1177 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1178 out => [ "none", "none", "none" ] },
1179 ins => [ "base", "index", "mem", "val" ],
1180 outs => [ "M", "X_regular", "X_except" ],
1181 emit => 'mov%M %#S3, %AM',
1187 op_flags => [ "uses_memory", "fragile" ],
1188 state => "exc_pinned",
1189 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1190 out => ["none", "none", "none" ] },
1191 ins => [ "base", "index", "mem", "val" ],
1192 outs => [ "M", "X_regular", "X_except" ],
1193 emit => 'mov%M %#S3, %AM',
1199 irn_flags => [ "rematerializable" ],
1200 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1201 ins => [ "base", "index" ],
1202 emit => 'leal %AM, %D0',
1206 # lea doesn't modify the flags, but setting this seems advantageous since it
1207 # increases chances that the Lea is transformed back to an Add
1208 modified_flags => 1,
1212 state => "exc_pinned",
1213 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1214 ins => [ "base", "index", "mem", "val", "stack" ],
1215 emit => 'push%M %AS3',
1216 outs => [ "stack", "M" ],
1217 am => "source,unary",
1223 state => "exc_pinned",
1224 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1226 outs => [ "stack" ],
1227 emit => 'pushl %%eax',
1234 state => "exc_pinned",
1235 reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1236 ins => [ "mem", "stack" ],
1237 outs => [ "res", "M", "unused", "stack" ],
1238 emit => 'pop%M %D0',
1239 latency => 3, # Pop is more expensive than Push on Athlon
1244 state => "exc_pinned",
1245 reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1246 ins => [ "mem", "stack" ],
1247 outs => [ "res", "M", "unused", "stack" ],
1248 emit => 'pop%M %D0',
1249 latency => 3, # Pop is more expensive than Push on Athlon
1254 state => "exc_pinned",
1255 reg_req => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1258 emit => 'movl %S0, %D0',
1265 state => "exc_pinned",
1266 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1267 ins => [ "base", "index", "mem", "stack" ],
1268 outs => [ "unused0", "M", "unused1", "stack" ],
1269 emit => 'pop%M %AM',
1270 latency => 3, # Pop is more expensive than Push on Athlon
1275 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1277 outs => [ "frame", "stack", "M" ],
1283 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1285 outs => [ "frame", "stack" ],
1288 state => "exc_pinned",
1293 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1294 ins => [ "base", "index", "mem", "stack", "size" ],
1295 am => "source,binary",
1298 outs => [ "stack", "M" ],
1300 modified_flags => $status_flags
1305 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1306 ins => [ "base", "index", "mem", "stack", "size" ],
1307 am => "source,binary",
1308 emit => "subl %B\n".
1311 outs => [ "stack", "addr", "M" ],
1313 modified_flags => $status_flags
1317 op_flags => [ "keep" ],
1325 irn_flags => [ "rematerializable" ],
1326 reg_req => { out => [ "gp" ] },
1328 emit => "movl %%gs:0, %D0",
1334 # BT supports source address mode, but this is unused yet
1337 irn_flags => [ "rematerializable" ],
1338 state => "exc_pinned",
1339 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1340 ins => [ "left", "right" ],
1341 emit => 'bt%M %S1, %S0',
1344 mode => $mode_flags,
1345 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1349 irn_flags => [ "rematerializable" ],
1350 state => "exc_pinned",
1351 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1352 out => [ "gp", "flags", "none" ] },
1353 ins => [ "base", "index", "mem", "operand" ],
1354 outs => [ "res", "flags", "M" ],
1355 am => "source,binary",
1356 emit => 'bsf%M %AS3, %D0',
1360 modified_flags => $status_flags
1364 irn_flags => [ "rematerializable" ],
1365 state => "exc_pinned",
1366 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1367 out => [ "gp", "flags", "none" ] },
1368 ins => [ "base", "index", "mem", "operand" ],
1369 outs => [ "res", "flags", "M" ],
1370 am => "source,binary",
1371 emit => 'bsr%M %AS3, %D0',
1375 modified_flags => $status_flags
1379 # SSE4.2 or SSE4a popcnt instruction
1382 irn_flags => [ "rematerializable" ],
1383 state => "exc_pinned",
1384 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1385 out => [ "gp", "flags", "none" ] },
1386 ins => [ "base", "index", "mem", "operand" ],
1387 outs => [ "res", "flags", "M" ],
1388 am => "source,binary",
1389 emit => 'popcnt%M %AS3, %D0',
1393 modified_flags => $status_flags
1397 op_flags => [ "uses_memory", "fragile" ],
1398 state => "exc_pinned",
1400 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1401 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" ]
1403 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1404 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" ],
1405 emit => "call %*AS3",
1406 attr_type => "ia32_call_attr_t",
1407 attr => "unsigned pop, ir_type *call_tp",
1408 am => "source,unary",
1409 units => [ "BRANCH" ],
1410 latency => 4, # random number
1411 modified_flags => $status_flags
1415 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1417 # PS: try gcc __builtin_frame_address(100000) :-)
1420 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1421 ins => [ "frame", "cnt", "tmp" ],
1423 latency => 4, # random number
1424 attr_type => "ia32_climbframe_attr_t",
1425 attr => "unsigned count",
1434 irn_flags => [ "rematerializable" ],
1435 reg_req => { in => [ "gp" ],
1436 out => [ "in_r1" ] },
1437 emit => 'bswap%M %S0',
1445 # bswap16, use xchg here
1448 irn_flags => [ "rematerializable" ],
1449 reg_req => { in => [ "eax ebx ecx edx" ],
1450 out => [ "in_r1" ] },
1451 emit => 'xchg %<S0, %>S0',
1463 reg_req => { in => [ "none" ], out => [ "none" ] },
1472 # Undefined Instruction on ALL x86 CPU's
1476 reg_req => { in => [ "none" ], out => [ "none" ] },
1488 irn_flags => [ "rematerializable" ],
1490 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1491 ins => [ "port", "value", "mem" ],
1492 emit => 'out%M %^S0, %#S1',
1496 modified_flags => $status_flags
1503 irn_flags => [ "rematerializable" ],
1505 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1506 ins => [ "port", "mem" ],
1507 outs => [ "res", "M" ],
1508 emit => 'in%M %#D0, %^S0',
1512 modified_flags => $status_flags
1516 # Intel style prefetching
1519 op_flags => [ "uses_memory" ],
1520 state => "exc_pinned",
1521 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1522 ins => [ "base", "index", "mem" ],
1525 emit => "prefetcht0 %AM",
1530 op_flags => [ "uses_memory" ],
1531 state => "exc_pinned",
1532 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1533 ins => [ "base", "index", "mem" ],
1536 emit => "prefetcht1 %AM",
1541 op_flags => [ "uses_memory" ],
1542 state => "exc_pinned",
1543 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1544 ins => [ "base", "index", "mem" ],
1547 emit => "prefetcht2 %AM",
1552 op_flags => [ "uses_memory" ],
1553 state => "exc_pinned",
1554 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1555 ins => [ "base", "index", "mem" ],
1558 emit => "prefetchnta %AM",
1563 # 3DNow! prefetch instructions
1566 op_flags => [ "uses_memory" ],
1567 state => "exc_pinned",
1568 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1569 ins => [ "base", "index", "mem" ],
1572 emit => "prefetch %AM",
1577 op_flags => [ "uses_memory" ],
1578 state => "exc_pinned",
1579 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1580 ins => [ "base", "index", "mem" ],
1583 emit => "prefetchw %AM",
1589 irn_flags => [ "rematerializable" ],
1590 reg_req => { out => [ "xmm" ] },
1591 emit => 'xorp%FX %D0, %D0',
1598 op_flags => [ "constlike" ],
1599 irn_flags => [ "rematerializable" ],
1600 reg_req => { out => [ "xmm" ] },
1607 irn_flags => [ "rematerializable" ],
1608 reg_req => { out => [ "xmm" ] },
1609 emit => 'pxor %D0, %D0',
1615 # produces all 1 bits
1617 irn_flags => [ "rematerializable" ],
1618 reg_req => { out => [ "xmm" ] },
1619 emit => 'pcmpeqb %D0, %D0',
1625 # integer shift left, dword
1627 irn_flags => [ "rematerializable" ],
1628 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1629 emit => 'pslld %#S1, %D0',
1635 # integer shift left, qword
1637 irn_flags => [ "rematerializable" ],
1638 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1639 emit => 'psllq %#S1, %D0',
1645 # integer shift right, dword
1647 irn_flags => [ "rematerializable" ],
1648 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1649 emit => 'psrld %#S1, %D0',
1655 # mov from integer to SSE register
1657 irn_flags => [ "rematerializable" ],
1658 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1659 emit => 'movd %S0, %D0',
1666 irn_flags => [ "rematerializable" ],
1667 state => "exc_pinned",
1668 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1669 out => [ "in_r4 in_r5", "flags", "none" ] },
1670 ins => [ "base", "index", "mem", "left", "right" ],
1671 outs => [ "res", "flags", "M" ],
1672 am => "source,binary",
1673 emit => 'adds%FX %B',
1680 irn_flags => [ "rematerializable" ],
1681 state => "exc_pinned",
1682 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1683 out => [ "in_r4 in_r5", "flags", "none" ] },
1684 ins => [ "base", "index", "mem", "left", "right" ],
1685 outs => [ "res", "flags", "M" ],
1686 am => "source,binary",
1687 emit => 'muls%FX %B',
1694 irn_flags => [ "rematerializable" ],
1695 state => "exc_pinned",
1696 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1697 out => [ "in_r4 in_r5", "flags", "none" ] },
1698 ins => [ "base", "index", "mem", "left", "right" ],
1699 outs => [ "res", "flags", "M" ],
1700 am => "source,binary",
1701 emit => 'maxs%FX %B',
1708 irn_flags => [ "rematerializable" ],
1709 state => "exc_pinned",
1710 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1711 out => [ "in_r4 in_r5", "flags", "none" ] },
1712 ins => [ "base", "index", "mem", "left", "right" ],
1713 outs => [ "res", "flags", "M" ],
1714 am => "source,binary",
1715 emit => 'mins%FX %B',
1722 irn_flags => [ "rematerializable" ],
1723 state => "exc_pinned",
1724 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1725 out => [ "in_r4 in_r5", "flags", "none" ] },
1726 ins => [ "base", "index", "mem", "left", "right" ],
1727 outs => [ "res", "flags", "M" ],
1728 am => "source,binary",
1729 emit => 'andp%FX %B',
1736 irn_flags => [ "rematerializable" ],
1737 state => "exc_pinned",
1738 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1739 out => [ "in_r4 in_r5", "flags", "none" ] },
1740 ins => [ "base", "index", "mem", "left", "right" ],
1741 outs => [ "res", "flags", "M" ],
1742 am => "source,binary",
1743 emit => 'orp%FX %B',
1750 irn_flags => [ "rematerializable" ],
1751 state => "exc_pinned",
1752 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1753 out => [ "in_r4 in_r5", "flags", "none" ] },
1754 ins => [ "base", "index", "mem", "left", "right" ],
1755 outs => [ "res", "flags", "M" ],
1756 am => "source,binary",
1757 emit => 'xorp%FX %B',
1764 irn_flags => [ "rematerializable" ],
1765 state => "exc_pinned",
1766 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1767 out => [ "in_r4 !in_r5", "flags", "none" ] },
1768 ins => [ "base", "index", "mem", "left", "right" ],
1769 outs => [ "res", "flags", "M" ],
1770 am => "source,binary",
1771 emit => 'andnp%FX %B',
1778 irn_flags => [ "rematerializable" ],
1779 state => "exc_pinned",
1780 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1781 out => [ "in_r4", "flags", "none" ] },
1782 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1783 outs => [ "res", "flags", "M" ],
1784 am => "source,binary",
1785 emit => 'subs%FX %B',
1792 irn_flags => [ "rematerializable" ],
1793 state => "exc_pinned",
1794 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1795 out => [ "in_r4 !in_r5", "flags", "none" ] },
1796 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1797 outs => [ "res", "flags", "M" ],
1798 am => "source,binary",
1799 emit => 'divs%FX %B',
1805 irn_flags => [ "rematerializable" ],
1806 state => "exc_pinned",
1807 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1808 out => [ "eflags" ] },
1809 ins => [ "base", "index", "mem", "left", "right" ],
1810 outs => [ "flags" ],
1811 am => "source,binary",
1812 attr => "bool ins_permuted",
1813 init_attr => "attr->data.ins_permuted = ins_permuted;",
1814 emit => 'ucomis%FX %B',
1817 mode => $mode_flags,
1818 modified_flags => 1,
1822 op_flags => [ "uses_memory", "fragile" ],
1823 state => "exc_pinned",
1824 reg_req => { in => [ "gp", "gp", "none" ],
1825 out => [ "xmm", "none", "none", "none", "none" ] },
1826 ins => [ "base", "index", "mem" ],
1827 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1828 emit => 'movs%FX %AM, %D0',
1829 attr => "ir_mode *load_mode",
1830 init_attr => "attr->ls_mode = load_mode;",
1836 op_flags => [ "uses_memory", "fragile" ],
1837 state => "exc_pinned",
1838 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1839 out => [ "none", "none", "none" ] },
1840 ins => [ "base", "index", "mem", "val" ],
1841 outs => [ "M", "X_regular", "X_except" ],
1842 emit => 'movs%FX %S3, %AM',
1848 op_flags => [ "uses_memory", "fragile" ],
1849 state => "exc_pinned",
1850 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1851 out => [ "none", "none", "none" ] },
1852 ins => [ "base", "index", "mem", "val" ],
1853 outs => [ "M", "X_regular", "X_except" ],
1854 emit => 'movs%FX %S3, %AM',
1860 state => "exc_pinned",
1861 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1862 ins => [ "base", "index", "mem", "val" ],
1863 am => "source,unary",
1864 emit => 'cvtsi2ss %AS3, %D0',
1871 state => "exc_pinned",
1872 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1873 ins => [ "base", "index", "mem", "val" ],
1874 am => "source,unary",
1875 emit => 'cvtsi2sd %AS3, %D0',
1883 ins => [ "val_high", "val_low" ],
1885 dump_func => "NULL",
1890 outs => [ "res_high", "res_low" ],
1892 dump_func => "NULL",
1896 op_flags => [ "uses_memory", "fragile" ],
1898 reg_req => { in => [ "edi", "esi", "ecx", "none" ],
1899 out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1900 ins => [ "dest", "source", "count", "mem" ],
1901 outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1902 attr_type => "ia32_copyb_attr_t",
1903 attr => "unsigned size",
1906 # we don't care about this flag, so no need to mark this node
1907 # modified_flags => [ "DF" ]
1911 op_flags => [ "uses_memory", "fragile" ],
1913 reg_req => { in => [ "edi", "esi", "none" ],
1914 out => [ "edi", "esi", "none", "none", "none" ] },
1915 ins => [ "dest", "source", "mem" ],
1916 outs => [ "dest", "source", "M", "X_regular", "X_except" ],
1917 attr_type => "ia32_copyb_attr_t",
1918 attr => "unsigned size",
1921 # we don't care about this flag, so no need to mark this node
1922 # modified_flags => [ "DF" ]
1926 state => "exc_pinned",
1927 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1937 op_flags => [ "uses_memory", "fragile" ],
1938 state => "exc_pinned",
1939 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1940 out => [ "gp", "none", "none", "none", "none" ] },
1941 ins => [ "base", "index", "mem", "val" ],
1942 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1943 emit => "mov%#Ml %#AS3, %D0",
1944 am => "source,unary",
1947 attr => "ir_mode *smaller_mode",
1948 init_attr => "attr->ls_mode = smaller_mode;",
1953 op_flags => [ "uses_memory", "fragile" ],
1954 state => "exc_pinned",
1955 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1956 out => [ "gp", "none", "none", "none", "none" ] },
1957 ins => [ "base", "index", "mem", "val" ],
1958 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1959 emit => "mov%#Ml %#AS3, %D0",
1960 am => "source,unary",
1963 attr => "ir_mode *smaller_mode",
1964 init_attr => "attr->ls_mode = smaller_mode;",
1969 state => "exc_pinned",
1970 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1971 ins => [ "base", "index", "mem", "val" ],
1972 am => "source,unary",
1979 state => "exc_pinned",
1980 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1981 ins => [ "base", "index", "mem", "val" ],
1982 am => "source,unary",
1989 state => "exc_pinned",
1990 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1991 ins => [ "base", "index", "mem", "val" ],
1992 am => "source,unary",
1998 # rematerialisation disabled for all float nodes for now, because the fpcw
1999 # handler runs before spilling and we might end up with wrong fpcw then
2002 # irn_flags => [ "rematerializable" ],
2003 state => "exc_pinned",
2004 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2005 out => [ "vfp", "none", "none" ] },
2006 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2007 outs => [ "res", "dummy", "M" ],
2008 am => "source,binary",
2012 attr_type => "ia32_x87_attr_t",
2016 # irn_flags => [ "rematerializable" ],
2017 state => "exc_pinned",
2018 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2019 out => [ "vfp", "none", "none" ] },
2020 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2021 outs => [ "res", "dummy", "M" ],
2022 am => "source,binary",
2026 attr_type => "ia32_x87_attr_t",
2030 # irn_flags => [ "rematerializable" ],
2031 state => "exc_pinned",
2032 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2033 out => [ "vfp", "none", "none" ] },
2034 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2035 outs => [ "res", "dummy", "M" ],
2036 am => "source,binary",
2040 attr_type => "ia32_x87_attr_t",
2044 state => "exc_pinned",
2045 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2046 out => [ "vfp", "none", "none" ] },
2047 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2048 outs => [ "res", "dummy", "M" ],
2049 am => "source,binary",
2052 attr_type => "ia32_x87_attr_t",
2056 reg_req => { in => [ "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
2057 ins => [ "left", "right", "fpcw" ],
2061 attr_type => "ia32_x87_attr_t",
2065 irn_flags => [ "rematerializable" ],
2066 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2071 attr_type => "ia32_x87_attr_t",
2075 irn_flags => [ "rematerializable" ],
2076 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2081 attr_type => "ia32_x87_attr_t",
2085 irn_flags => [ "rematerializable" ],
2086 op_flags => [ "uses_memory", "fragile" ],
2087 state => "exc_pinned",
2088 reg_req => { in => [ "gp", "gp", "none" ],
2089 out => [ "vfp", "none", "none", "none", "none" ] },
2090 ins => [ "base", "index", "mem" ],
2091 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
2092 attr => "ir_mode *load_mode",
2093 init_attr => "attr->attr.ls_mode = load_mode;",
2096 attr_type => "ia32_x87_attr_t",
2100 irn_flags => [ "rematerializable" ],
2101 op_flags => [ "uses_memory", "fragile" ],
2102 state => "exc_pinned",
2103 reg_req => { in => [ "gp", "gp", "none", "vfp" ],
2104 out => [ "none", "none", "none" ] },
2105 ins => [ "base", "index", "mem", "val" ],
2106 outs => [ "M", "X_regular", "X_except" ],
2107 attr => "ir_mode *store_mode",
2108 init_attr => "attr->attr.ls_mode = store_mode;",
2111 attr_type => "ia32_x87_attr_t",
2115 state => "exc_pinned",
2116 reg_req => { in => [ "gp", "gp", "none" ],
2117 out => [ "vfp", "none", "none" ] },
2118 outs => [ "res", "unused", "M" ],
2119 ins => [ "base", "index", "mem" ],
2122 attr_type => "ia32_x87_attr_t",
2126 op_flags => [ "uses_memory", "fragile" ],
2127 state => "exc_pinned",
2128 reg_req => { in => [ "gp", "gp", "none", "vfp", "fpcw" ],
2129 out => [ "none", "none", "none", "none" ] },
2130 ins => [ "base", "index", "mem", "val", "fpcw" ],
2131 outs => [ "dummy", "M", "X_regular", "X_except" ],
2134 attr_type => "ia32_x87_attr_t",
2137 # SSE3 fisttp instruction
2139 op_flags => [ "uses_memory", "fragile" ],
2140 state => "exc_pinned",
2141 reg_req => { in => [ "gp", "gp", "none", "vfp" ],
2142 out => [ "in_r4", "none", "none", "none" ]},
2143 ins => [ "base", "index", "mem", "val" ],
2144 outs => [ "res", "M", "X_regular", "X_except" ],
2147 attr_type => "ia32_x87_attr_t",
2151 irn_flags => [ "rematerializable" ],
2152 reg_req => { out => [ "vfp" ] },
2157 attr_type => "ia32_x87_attr_t",
2161 irn_flags => [ "rematerializable" ],
2162 reg_req => { out => [ "vfp" ] },
2167 attr_type => "ia32_x87_attr_t",
2171 irn_flags => [ "rematerializable" ],
2172 reg_req => { out => [ "vfp" ] },
2177 attr_type => "ia32_x87_attr_t",
2181 irn_flags => [ "rematerializable" ],
2182 reg_req => { out => [ "vfp" ] },
2187 attr_type => "ia32_x87_attr_t",
2191 irn_flags => [ "rematerializable" ],
2192 reg_req => { out => [ "vfp" ] },
2197 attr_type => "ia32_x87_attr_t",
2201 irn_flags => [ "rematerializable" ],
2202 reg_req => { out => [ "vfp" ] },
2207 attr_type => "ia32_x87_attr_t",
2211 irn_flags => [ "rematerializable" ],
2212 reg_req => { out => [ "vfp" ] },
2217 attr_type => "ia32_x87_attr_t",
2221 # we can't allow to rematerialize this node so we don't
2222 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2223 # irn_flags => [ "rematerializable" ],
2224 reg_req => { in => [ "vfp", "vfp" ], out => [ "eax" ] },
2225 ins => [ "left", "right" ],
2226 outs => [ "flags" ],
2227 attr => "bool ins_permuted",
2228 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2231 attr_type => "ia32_x87_attr_t",
2236 irn_flags => [ "rematerializable" ],
2237 reg_req => { in => [ "vfp", "vfp" ], out => [ "eflags" ] },
2238 ins => [ "left", "right" ],
2239 outs => [ "flags" ],
2240 attr => "bool ins_permuted",
2241 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2244 attr_type => "ia32_x87_attr_t",
2249 # irn_flags => [ "rematerializable" ],
2250 reg_req => { in => [ "vfp" ], out => [ "eax" ] },
2252 outs => [ "flags" ],
2253 attr => "bool ins_permuted",
2254 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2257 attr_type => "ia32_x87_attr_t",
2262 irn_flags => [ "rematerializable" ],
2263 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2265 outs => [ "flags" ],
2269 mode => $mode_flags,
2273 state => "exc_pinned",
2274 emit => 'fadd%FM %AF',
2276 attr_type => "ia32_x87_attr_t",
2281 state => "exc_pinned",
2282 emit => 'faddp%FM %AF',
2284 attr_type => "ia32_x87_attr_t",
2289 state => "exc_pinned",
2290 emit => 'fmul%FM %AF',
2292 attr_type => "ia32_x87_attr_t",
2297 state => "exc_pinned",
2298 emit => 'fmulp%FM %AF',,
2300 attr_type => "ia32_x87_attr_t",
2305 state => "exc_pinned",
2306 emit => 'fsub%FM %AF',
2308 attr_type => "ia32_x87_attr_t",
2312 # Note: gas is strangely buggy: fdivrp and fdivp as well as fsubrp and fsubp
2313 # are swapped, we work this around in the emitter...
2316 state => "exc_pinned",
2317 # see note about gas bugs
2318 emit => 'fsubrp%FM %AF',
2320 attr_type => "ia32_x87_attr_t",
2325 state => "exc_pinned",
2326 irn_flags => [ "rematerializable" ],
2327 emit => 'fsubr%FM %AF',
2329 attr_type => "ia32_x87_attr_t",
2334 state => "exc_pinned",
2335 irn_flags => [ "rematerializable" ],
2336 # see note about gas bugs before fsubp
2337 emit => 'fsubp%FM %AF',
2339 attr_type => "ia32_x87_attr_t",
2346 attr_type => "ia32_x87_attr_t",
2350 # this node is just here, to keep the simulator running
2351 # we can omit this when a fprem simulation function exists
2356 attr_type => "ia32_x87_attr_t",
2361 state => "exc_pinned",
2362 emit => 'fdiv%FM %AF',
2364 attr_type => "ia32_x87_attr_t",
2369 state => "exc_pinned",
2370 # see note about gas bugs before fsubp
2371 emit => 'fdivrp%FM %AF',
2373 attr_type => "ia32_x87_attr_t",
2378 state => "exc_pinned",
2379 emit => 'fdivr%FM %AF',
2381 attr_type => "ia32_x87_attr_t",
2386 state => "exc_pinned",
2387 # see note about gas bugs before fsubp
2388 emit => 'fdivp%FM %AF',
2390 attr_type => "ia32_x87_attr_t",
2397 attr_type => "ia32_x87_attr_t",
2402 op_flags => [ "keep" ],
2403 irn_flags => [ "rematerializable" ],
2406 attr_type => "ia32_x87_attr_t",
2411 irn_flags => [ "rematerializable" ],
2412 state => "exc_pinned",
2413 emit => 'fld%FM %AM',
2414 attr_type => "ia32_x87_attr_t",
2420 irn_flags => [ "rematerializable" ],
2421 state => "exc_pinned",
2422 emit => 'fst%FM %AM',
2424 attr_type => "ia32_x87_attr_t",
2430 irn_flags => [ "rematerializable" ],
2431 state => "exc_pinned",
2432 emit => 'fstp%FM %AM',
2434 attr_type => "ia32_x87_attr_t",
2440 state => "exc_pinned",
2441 emit => 'fild%FM %AM',
2442 attr_type => "ia32_x87_attr_t",
2448 state => "exc_pinned",
2449 emit => 'fist%FM %AM',
2451 attr_type => "ia32_x87_attr_t",
2457 state => "exc_pinned",
2458 emit => 'fistp%FM %AM',
2460 attr_type => "ia32_x87_attr_t",
2465 # SSE3 fisttp instruction
2467 state => "exc_pinned",
2468 emit => 'fisttp%FM %AM',
2470 attr_type => "ia32_x87_attr_t",
2476 op_flags => [ "constlike", "keep" ],
2477 irn_flags => [ "rematerializable" ],
2478 reg_req => { out => [ "vfp" ] },
2480 attr_type => "ia32_x87_attr_t",
2485 op_flags => [ "constlike", "keep" ],
2486 irn_flags => [ "rematerializable" ],
2487 reg_req => { out => [ "vfp" ] },
2489 attr_type => "ia32_x87_attr_t",
2494 op_flags => [ "constlike", "keep" ],
2495 irn_flags => [ "rematerializable" ],
2496 reg_req => { out => [ "vfp" ] },
2498 attr_type => "ia32_x87_attr_t",
2503 op_flags => [ "constlike", "keep" ],
2504 irn_flags => [ "rematerializable" ],
2505 reg_req => { out => [ "vfp" ] },
2507 attr_type => "ia32_x87_attr_t",
2512 op_flags => [ "constlike", "keep" ],
2513 irn_flags => [ "rematerializable" ],
2514 reg_req => { out => [ "vfp" ] },
2516 attr_type => "ia32_x87_attr_t",
2521 op_flags => [ "constlike", "keep" ],
2522 irn_flags => [ "rematerializable" ],
2523 reg_req => { out => [ "vfp" ] },
2525 attr_type => "ia32_x87_attr_t",
2530 op_flags => [ "constlike", "keep" ],
2531 irn_flags => [ "rematerializable" ],
2532 reg_req => { out => [ "vfp" ] },
2534 attr_type => "ia32_x87_attr_t",
2539 # Note that it is NEVER allowed to do CSE on these nodes
2540 # Moreover, note the virtual register requierements!
2543 op_flags => [ "keep" ],
2544 reg_req => { out => [ "none" ] },
2545 cmp_attr => "return 1;",
2547 attr_type => "ia32_x87_attr_t",
2553 op_flags => [ "keep" ],
2554 reg_req => { out => [ "none" ] },
2555 cmp_attr => "return 1;",
2557 attr_type => "ia32_x87_attr_t",
2563 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2564 cmp_attr => "return 1;",
2566 attr_type => "ia32_x87_attr_t",
2571 op_flags => [ "keep" ],
2572 reg_req => { out => [ "none" ] },
2573 cmp_attr => "return 1;",
2575 attr_type => "ia32_x87_attr_t",
2581 op_flags => [ "keep" ],
2582 reg_req => { out => [ "none" ] },
2583 cmp_attr => "return 1;",
2584 emit => 'ffreep %F0',
2585 attr_type => "ia32_x87_attr_t",
2591 op_flags => [ "keep" ],
2592 reg_req => { out => [ "none" ] },
2593 cmp_attr => "return 1;",
2595 attr_type => "ia32_x87_attr_t",
2601 op_flags => [ "keep" ],
2602 reg_req => { out => [ "none" ] },
2603 cmp_attr => "return 1;",
2605 attr_type => "ia32_x87_attr_t",
2612 emit => "fucom %F1\n".
2614 attr_type => "ia32_x87_attr_t",
2620 emit => "fucomp %F1\n".
2622 attr_type => "ia32_x87_attr_t",
2628 emit => "fucompp\n".
2630 attr_type => "ia32_x87_attr_t",
2636 emit => 'fucomi %F1',
2637 attr_type => "ia32_x87_attr_t",
2643 emit => 'fucompi %F1',
2644 attr_type => "ia32_x87_attr_t",
2652 attr_type => "ia32_x87_attr_t",
2656 # Spilling and reloading of SSE registers, hardcoded, not generated #
2659 op_flags => [ "uses_memory", "fragile" ],
2660 state => "exc_pinned",
2661 reg_req => { in => [ "gp", "gp", "none" ],
2662 out => [ "xmm", "none", "none", "none" ] },
2663 emit => 'movdqu %D0, %AM',
2664 ins => [ "base", "index", "mem" ],
2665 outs => [ "res", "M", "X_regular", "X_except" ],
2671 op_flags => [ "uses_memory", "fragile" ],
2672 state => "exc_pinned",
2673 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
2674 out => [ "none", "none", "none" ] },
2675 ins => [ "base", "index", "mem", "val" ],
2676 outs => [ "M", "X_regular", "X_except" ],
2677 emit => 'movdqu %B',
2684 # Transform some attributes
2685 foreach my $op (keys(%nodes)) {
2686 my $node = $nodes{$op};
2687 my $op_attr_init = $node->{op_attr_init};
2689 if(defined($op_attr_init)) {
2690 $op_attr_init .= "\n\t";
2695 if(!defined($node->{latency})) {
2697 $node->{latency} = 0;
2699 die("Latency missing for op $op");
2702 $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2704 $node->{op_attr_init} = $op_attr_init;