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";
14 { name => "edx", dwarf => 2 },
15 { name => "ecx", dwarf => 1 },
16 { name => "eax", dwarf => 0 },
17 { name => "ebx", dwarf => 3 },
18 { name => "esi", dwarf => 6 },
19 { name => "edi", dwarf => 7 },
20 { name => "ebp", dwarf => 5 },
21 { name => "esp", dwarf => 4, type => "ignore" },
22 { name => "gp_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
26 { name => "mm0", dwarf => 29, type => "ignore" },
27 { name => "mm1", dwarf => 30, type => "ignore" },
28 { name => "mm2", dwarf => 31, type => "ignore" },
29 { name => "mm3", dwarf => 32, type => "ignore" },
30 { name => "mm4", dwarf => 33, type => "ignore" },
31 { name => "mm5", dwarf => 34, type => "ignore" },
32 { name => "mm6", dwarf => 35, type => "ignore" },
33 { name => "mm7", dwarf => 36, type => "ignore" },
34 { mode => $mode_mmx, flags => "manual_ra" }
37 { name => "xmm0", dwarf => 21 },
38 { name => "xmm1", dwarf => 22 },
39 { name => "xmm2", dwarf => 23 },
40 { name => "xmm3", dwarf => 24 },
41 { name => "xmm4", dwarf => 25 },
42 { name => "xmm5", dwarf => 26 },
43 { name => "xmm6", dwarf => 27 },
44 { name => "xmm7", dwarf => 28 },
45 { name => "xmm_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
49 { name => "st0", realname => "st", dwarf => 11 },
50 { name => "st1", realname => "st(1)", dwarf => 12 },
51 { name => "st2", realname => "st(2)", dwarf => 13 },
52 { name => "st3", realname => "st(3)", dwarf => 14 },
53 { name => "st4", realname => "st(4)", dwarf => 15 },
54 { name => "st5", realname => "st(5)", dwarf => 16 },
55 { name => "st6", realname => "st(6)", dwarf => 17 },
56 { name => "st7", realname => "st(7)", dwarf => 18 },
57 { name => "fp_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
58 { mode => $mode_fp87 }
60 fp_cw => [ # the floating point control word
61 { name => "fpcw", dwarf => 37, type => "ignore | state" },
62 { mode => $mode_fpcw, flags => "manual_ra | state" }
65 { name => "eflags", dwarf => 9 },
66 { mode => "mode_Iu", flags => "manual_ra" }
71 GP => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
72 SSE => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
73 VFP => [ 1, "VFP_VF0", "VFP_VF1", "VFP_VF2", "VFP_VF3", "VFP_VF4", "VFP_VF5", "VFP_VF6", "VFP_VF7" ],
74 BRANCH => [ 1, "BRANCH1", "BRANCH2" ],
79 bundels_per_cycle => 1
82 $default_op_attr_type = "ia32_op_attr_t";
83 $default_attr_type = "ia32_attr_t";
84 $default_copy_attr = "ia32_copy_attr";
86 sub ia32_custom_init_attr {
92 if(defined($node->{modified_flags})) {
93 $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n";
95 if(defined($node->{am})) {
97 if($am eq "source,unary") {
98 $res .= "\tset_ia32_am_support(res, ia32_am_unary);";
99 } elsif($am eq "source,binary") {
100 $res .= "\tset_ia32_am_support(res, ia32_am_binary);";
101 } elsif($am eq "none") {
104 die("Invalid address mode '$am' specified on op $name");
107 if($node->{state} ne "exc_pinned"
108 and $node->{state} ne "pinned") {
109 die("AM nodes must have pinned or AM pinned state ($name)");
115 $custom_init_attr_func = \&ia32_custom_init_attr;
119 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
120 "\tinit_ia32_x87_attributes(res);".
121 "\tinit_ia32_asm_attributes(res);",
123 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);",
125 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
126 "\tinit_ia32_call_attributes(res, pop, call_tp);",
127 ia32_condcode_attr_t =>
128 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
129 "\tinit_ia32_condcode_attributes(res, condition_code);",
130 ia32_switch_attr_t =>
131 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
132 "\tinit_ia32_switch_attributes(res, switch_table);",
134 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
135 "\tinit_ia32_copyb_attributes(res, size);",
136 ia32_immediate_attr_t =>
137 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
138 "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
140 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
141 "\tinit_ia32_x87_attributes(res);",
142 ia32_climbframe_attr_t =>
143 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
144 "\tinit_ia32_climbframe_attributes(res, count);",
148 ia32_asm_attr_t => "ia32_compare_asm_attr",
149 ia32_attr_t => "ia32_compare_nodes_attr",
150 ia32_call_attr_t => "ia32_compare_call_attr",
151 ia32_condcode_attr_t => "ia32_compare_condcode_attr",
152 ia32_copyb_attr_t => "ia32_compare_copyb_attr",
153 ia32_switch_attr_t => "ia32_compare_nodes_attr",
154 ia32_immediate_attr_t => "ia32_compare_immediate_attr",
155 ia32_x87_attr_t => "ia32_compare_x87_attr",
156 ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
159 $status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
160 $status_flags_wo_cf = [ "PF", "AF", "ZF", "SF", "OF" ];
161 $fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
162 "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
168 op_flags => [ "constlike" ],
169 irn_flags => [ "not_scheduled" ],
170 reg_req => { out => [ "gp_NOREG:I" ] },
171 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
172 attr_type => "ia32_immediate_attr_t",
173 hash_func => "ia32_hash_Immediate",
181 out_arity => "variable",
182 attr_type => "ia32_asm_attr_t",
183 attr => "ident *asm_text, const ia32_asm_reg_t *register_map",
184 init_attr => "attr->asm_text = asm_text;\n".
185 "\tattr->register_map = register_map;\n",
187 modified_flags => $status_flags,
190 # "allocates" a free register
192 op_flags => [ "constlike", "cse_neutral" ],
193 irn_flags => [ "rematerializable" ],
194 reg_req => { out => [ "gp" ] },
199 cmp_attr => "return 1;",
203 irn_flags => [ "rematerializable" ],
204 state => "exc_pinned",
205 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
206 out => [ "in_r4 in_r5", "flags", "none" ] },
207 ins => [ "base", "index", "mem", "left", "right" ],
208 outs => [ "res", "flags", "M" ],
210 am => "source,binary",
214 modified_flags => $status_flags
218 irn_flags => [ "rematerializable" ],
219 state => "exc_pinned",
220 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
221 ins => [ "base", "index", "mem", "val" ],
222 emit => "add%M %#S3, %AM",
226 modified_flags => $status_flags
230 irn_flags => [ "rematerializable" ],
231 state => "exc_pinned",
232 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
233 ins => [ "base", "index", "mem", "val" ],
234 emit => "add%M %#S3, %AM",
238 modified_flags => $status_flags
242 state => "exc_pinned",
243 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
244 out => [ "in_r4 in_r5", "flags", "none" ] },
245 ins => [ "base", "index", "mem", "left", "right", "eflags" ],
246 outs => [ "res", "flags", "M" ],
248 am => "source,binary",
252 modified_flags => $status_flags
256 ins => [ "left", "right" ],
262 ins => [ "left", "right", "eflags" ],
268 # we should not rematrialize this node. It produces 2 results and has
269 # very strict constraints
270 state => "exc_pinned",
271 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
272 out => [ "eax", "flags", "none", "edx" ] },
273 ins => [ "base", "index", "mem", "left", "right" ],
274 emit => 'mul%M %AS4',
275 outs => [ "res_low", "flags", "M", "res_high" ],
276 am => "source,binary",
279 modified_flags => $status_flags
283 ins => [ "left", "right" ],
284 outs => [ "res_low", "flags", "M", "res_high" ],
290 irn_flags => [ "rematerializable" ],
291 state => "exc_pinned",
292 # TODO: adjust out requirements for the 3 operand form
293 # (no need for should_be_same then)
294 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
295 out => [ "in_r4 in_r5", "flags", "none" ] },
296 ins => [ "base", "index", "mem", "left", "right" ],
297 outs => [ "res", "flags", "M" ],
298 am => "source,binary",
302 modified_flags => $status_flags
306 irn_flags => [ "rematerializable" ],
307 state => "exc_pinned",
308 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
309 out => [ "eax", "flags", "none", "edx" ] },
310 ins => [ "base", "index", "mem", "left", "right" ],
311 emit => 'imul%M %AS4',
312 outs => [ "res_low", "flags", "M", "res_high" ],
313 am => "source,binary",
316 modified_flags => $status_flags
320 ins => [ "left", "right" ],
321 outs => [ "res_low", "flags", "M", "res_high" ],
327 irn_flags => [ "rematerializable" ],
328 state => "exc_pinned",
329 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
330 out => [ "in_r4 in_r5", "flags", "none" ] },
331 ins => [ "base", "index", "mem", "left", "right" ],
332 outs => [ "res", "flags", "M" ],
333 am => "source,binary",
338 modified_flags => $status_flags
342 irn_flags => [ "rematerializable" ],
343 state => "exc_pinned",
344 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
345 ins => [ "base", "index", "mem", "val" ],
346 emit => 'and%M %#S3, %AM',
350 modified_flags => $status_flags
354 irn_flags => [ "rematerializable" ],
355 state => "exc_pinned",
356 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
357 ins => [ "base", "index", "mem", "val" ],
358 emit => 'and%M %#S3, %AM',
362 modified_flags => $status_flags
366 irn_flags => [ "rematerializable" ],
367 state => "exc_pinned",
368 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
369 out => [ "in_r4 in_r5", "flags", "none" ] },
370 ins => [ "base", "index", "mem", "left", "right" ],
371 outs => [ "res", "flags", "M" ],
372 am => "source,binary",
377 modified_flags => $status_flags
381 irn_flags => [ "rematerializable" ],
382 state => "exc_pinned",
383 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
384 ins => [ "base", "index", "mem", "val" ],
385 emit => 'or%M %#S3, %AM',
389 modified_flags => $status_flags
393 irn_flags => [ "rematerializable" ],
394 state => "exc_pinned",
395 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
396 ins => [ "base", "index", "mem", "val" ],
397 emit => 'or%M %#S3, %AM',
401 modified_flags => $status_flags
405 irn_flags => [ "rematerializable" ],
406 state => "exc_pinned",
407 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
408 out => [ "in_r4 in_r5", "flags", "none" ] },
409 ins => [ "base", "index", "mem", "left", "right" ],
410 outs => [ "res", "flags", "M" ],
411 am => "source,binary",
416 modified_flags => $status_flags
420 op_flags => [ "constlike" ],
421 irn_flags => [ "rematerializable" ],
422 reg_req => { out => [ "gp", "flags" ] },
423 outs => [ "res", "flags" ],
424 emit => "xor%M %D0, %D0",
428 modified_flags => $status_flags
432 irn_flags => [ "rematerializable" ],
433 state => "exc_pinned",
434 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
435 ins => [ "base", "index", "mem", "val" ],
436 emit => 'xor%M %#S3, %AM',
440 modified_flags => $status_flags
444 irn_flags => [ "rematerializable" ],
445 state => "exc_pinned",
446 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
447 ins => [ "base", "index", "mem", "val" ],
448 emit => 'xor%M %#S3, %AM',
452 modified_flags => $status_flags
456 irn_flags => [ "rematerializable" ],
457 state => "exc_pinned",
458 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
459 out => [ "in_r4", "flags", "none" ] },
460 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
461 outs => [ "res", "flags", "M" ],
462 am => "source,binary",
467 modified_flags => $status_flags
471 irn_flags => [ "rematerializable" ],
472 state => "exc_pinned",
473 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
474 ins => [ "base", "index", "mem", "subtrahend" ],
475 emit => 'sub%M %#S3, %AM',
479 modified_flags => $status_flags
483 irn_flags => [ "rematerializable" ],
484 state => "exc_pinned",
485 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
486 ins => [ "base", "index", "mem", "subtrahend" ],
487 emit => 'sub%M %#S3, %AM',
491 modified_flags => $status_flags
495 state => "exc_pinned",
496 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
497 out => [ "in_r4", "flags", "none" ] },
498 ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
499 outs => [ "res", "flags", "M" ],
500 am => "source,binary",
505 modified_flags => $status_flags
509 # Spiller currently fails when rematerializing flag consumers
510 # irn_flags => [ "rematerializable" ],
511 reg_req => { in => [ "flags" ], out => [ "gp", "flags" ] },
512 outs => [ "res", "flags" ],
513 emit => "sbb%M %D0, %D0",
517 modified_flags => $status_flags
521 ins => [ "minuend", "subtrahend" ],
527 ins => [ "minuend", "subtrahend", "eflags" ],
533 op_flags => [ "fragile", "uses_memory" ],
534 state => "exc_pinned",
535 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
536 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
537 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
538 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
539 am => "source,unary",
540 emit => "idiv%M %AS3",
543 modified_flags => $status_flags
547 op_flags => [ "fragile", "uses_memory" ],
548 state => "exc_pinned",
549 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
550 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
551 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
552 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
553 am => "source,unary",
554 emit => "div%M %AS3",
557 modified_flags => $status_flags
561 irn_flags => [ "rematerializable" ],
562 reg_req => { in => [ "gp", "ecx" ],
563 out => [ "in_r1 !in_r2", "flags" ] },
564 ins => [ "val", "count" ],
565 outs => [ "res", "flags" ],
566 emit => 'shl%M %<S1, %S0',
570 modified_flags => $status_flags
574 irn_flags => [ "rematerializable" ],
575 state => "exc_pinned",
576 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
577 ins => [ "base", "index", "mem", "count" ],
578 emit => 'shl%M %<S3, %AM',
582 modified_flags => $status_flags
586 irn_flags => [ "rematerializable" ],
587 reg_req => { in => [ "gp", "gp", "ecx" ],
588 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
589 ins => [ "val_high", "val_low", "count" ],
590 outs => [ "res", "flags" ],
591 emit => "shld%M %<S2, %S1, %D0",
595 modified_flags => $status_flags
599 irn_flags => [ "rematerializable" ],
600 reg_req => { in => [ "gp", "ecx" ],
601 out => [ "in_r1 !in_r2", "flags" ] },
602 ins => [ "val", "count" ],
603 outs => [ "res", "flags" ],
604 emit => 'shr%M %<S1, %S0',
608 modified_flags => $status_flags
612 irn_flags => [ "rematerializable" ],
613 state => "exc_pinned",
614 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
615 ins => [ "base", "index", "mem", "count" ],
616 emit => 'shr%M %<S3, %AM',
620 modified_flags => $status_flags
624 irn_flags => [ "rematerializable" ],
625 reg_req => { in => [ "gp", "gp", "ecx" ],
626 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
627 ins => [ "val_high", "val_low", "count" ],
628 outs => [ "res", "flags" ],
629 emit => "shrd%M %<S2, %S1, %D0",
633 modified_flags => $status_flags
637 irn_flags => [ "rematerializable" ],
638 reg_req => { in => [ "gp", "ecx" ],
639 out => [ "in_r1 !in_r2", "flags" ] },
640 ins => [ "val", "count" ],
641 outs => [ "res", "flags" ],
642 emit => 'sar%M %<S1, %S0',
646 modified_flags => $status_flags
650 irn_flags => [ "rematerializable" ],
651 state => "exc_pinned",
652 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
653 ins => [ "base", "index", "mem", "count" ],
654 emit => 'sar%M %<S3, %AM',
658 modified_flags => $status_flags
662 irn_flags => [ "rematerializable" ],
663 reg_req => { in => [ "gp", "ecx" ],
664 out => [ "in_r1 !in_r2", "flags" ] },
665 ins => [ "val", "count" ],
666 outs => [ "res", "flags" ],
667 emit => 'ror%M %<S1, %S0',
671 modified_flags => $status_flags
675 irn_flags => [ "rematerializable" ],
676 state => "exc_pinned",
677 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
678 ins => [ "base", "index", "mem", "count" ],
679 emit => 'ror%M %<S3, %AM',
683 modified_flags => $status_flags
687 irn_flags => [ "rematerializable" ],
688 reg_req => { in => [ "gp", "ecx" ],
689 out => [ "in_r1 !in_r2", "flags" ] },
690 ins => [ "val", "count" ],
691 outs => [ "res", "flags" ],
692 emit => 'rol%M %<S1, %D0',
696 modified_flags => $status_flags
700 irn_flags => [ "rematerializable" ],
701 state => "exc_pinned",
702 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
703 ins => [ "base", "index", "mem", "count" ],
704 emit => 'rol%M %<S3, %AM',
708 modified_flags => $status_flags
712 irn_flags => [ "rematerializable" ],
713 reg_req => { in => [ "gp" ],
714 out => [ "in_r1", "flags" ] },
717 outs => [ "res", "flags" ],
721 modified_flags => $status_flags
725 irn_flags => [ "rematerializable" ],
726 state => "exc_pinned",
727 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
728 ins => [ "base", "index", "mem" ],
733 modified_flags => $status_flags
737 irn_flags => [ "rematerializable" ],
738 reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
739 outs => [ "low_res", "high_res" ],
742 modified_flags => $status_flags
747 irn_flags => [ "rematerializable" ],
748 reg_req => { in => [ "gp" ],
749 out => [ "in_r1", "flags" ] },
751 outs => [ "res", "flags" ],
756 modified_flags => $status_flags_wo_cf
760 irn_flags => [ "rematerializable" ],
761 state => "exc_pinned",
762 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
763 ins => [ "base", "index", "mem" ],
768 modified_flags => $status_flags_wo_cf
772 irn_flags => [ "rematerializable" ],
773 reg_req => { in => [ "gp" ],
774 out => [ "in_r1", "flags" ] },
776 outs => [ "res", "flags" ],
781 modified_flags => $status_flags_wo_cf
785 irn_flags => [ "rematerializable" ],
786 state => "exc_pinned",
787 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
788 ins => [ "base", "index", "mem" ],
793 modified_flags => $status_flags_wo_cf
797 irn_flags => [ "rematerializable" ],
798 reg_req => { in => [ "gp" ],
799 out => [ "in_r1" ] },
810 irn_flags => [ "rematerializable" ],
811 state => "exc_pinned",
812 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
813 ins => [ "base", "index", "mem" ],
822 reg_req => { in => [ "flags" ], out => [ "flags" ] },
827 modified_flags => $status_flags
831 reg_req => { out => [ "flags" ] },
836 modified_flags => $status_flags
840 irn_flags => [ "rematerializable" ],
841 state => "exc_pinned",
842 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
843 out => [ "flags", "none", "none" ] },
844 ins => [ "base", "index", "mem", "left", "right" ],
845 outs => [ "eflags", "unused", "M" ],
846 am => "source,binary",
848 attr => "bool ins_permuted",
849 init_attr => "attr->data.ins_permuted = ins_permuted;",
853 modified_flags => $status_flags
857 irn_flags => [ "rematerializable" ],
858 state => "exc_pinned",
859 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
860 out => [ "flags", "none", "none" ] },
861 ins => [ "base", "index", "mem", "left", "right" ],
862 outs => [ "eflags", "unused", "M" ],
863 am => "source,binary",
865 attr => "bool ins_permuted",
866 init_attr => "attr->data.ins_permuted = ins_permuted;",
870 modified_flags => $status_flags
874 irn_flags => [ "rematerializable" ],
875 state => "exc_pinned",
876 reg_req => { in => [ "eax ebx ecx edx" ],
877 out => [ "in_r1", "flags" ] },
878 emit => 'xorb %>S0, %<S0',
880 outs => [ "res", "flags" ],
884 modified_flags => $status_flags,
888 irn_flags => [ "rematerializable" ],
889 state => "exc_pinned",
890 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] ,
891 out => [ "flags", "none", "none" ] },
892 ins => [ "base", "index", "mem", "left", "right" ],
893 outs => [ "eflags", "unused", "M" ],
894 am => "source,binary",
896 attr => "bool ins_permuted",
897 init_attr => "attr->data.ins_permuted = ins_permuted;",
901 modified_flags => $status_flags
905 irn_flags => [ "rematerializable" ],
906 state => "exc_pinned",
907 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
908 out => [ "flags", "none", "none" ] },
909 ins => [ "base", "index", "mem", "left", "right" ],
910 outs => [ "eflags", "unused", "M" ],
911 am => "source,binary",
913 attr => "bool ins_permuted",
914 init_attr => "attr->data.ins_permuted = ins_permuted;",
918 modified_flags => $status_flags
922 #irn_flags => [ "rematerializable" ],
923 reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
926 attr_type => "ia32_condcode_attr_t",
927 attr => "ia32_condition_code_t condition_code",
928 # The way we handle Setcc with float nodes (potentially) destroys the flags
929 # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
930 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
931 . "\tif (condition_code & ia32_cc_additional_float_cases) {\n"
932 . "\t\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"
933 . "\t\t/* attr->latency = 3; */\n"
941 #irn_flags => [ "rematerializable" ],
942 state => "exc_pinned",
943 reg_req => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
944 ins => [ "base", "index", "mem","eflags" ],
945 attr_type => "ia32_condcode_attr_t",
946 attr => "ia32_condition_code_t condition_code",
947 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
948 emit => 'set%P3 %AM',
955 #irn_flags => [ "rematerializable" ],
956 state => "exc_pinned",
957 # (note: leave the false,true order intact to make it compatible with other
959 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
960 out => [ "in_r4 in_r5", "flags", "none" ] },
961 ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
962 outs => [ "res", "flags", "M" ],
963 am => "source,binary",
964 attr_type => "ia32_condcode_attr_t",
965 attr => "ia32_condition_code_t condition_code",
973 op_flags => [ "cfopcode", "forking" ],
974 reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
976 outs => [ "false", "true" ],
977 attr_type => "ia32_condcode_attr_t",
978 attr => "ia32_condition_code_t condition_code",
980 units => [ "BRANCH" ],
985 op_flags => [ "cfopcode", "forking" ],
986 reg_req => { in => [ "gp", "gp" ] },
987 ins => [ "base", "index" ],
988 out_arity => "variable",
989 attr_type => "ia32_switch_attr_t",
990 attr => "const ir_switch_table *switch_table",
992 units => [ "BRANCH" ],
997 irn_flags => [ "simple_jump" ],
998 op_flags => [ "cfopcode" ],
999 reg_req => { out => [ "none" ] },
1001 units => [ "BRANCH" ],
1007 op_flags => [ "cfopcode", "unknown_jump" ],
1008 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1009 out => [ "none", "flags", "none" ] },
1010 ins => [ "base", "index", "mem", "target" ],
1011 outs => [ "jmp", "flags", "M" ],
1012 am => "source,unary",
1013 emit => 'jmp %*AS3',
1015 units => [ "BRANCH" ],
1020 op_flags => [ "constlike" ],
1021 irn_flags => [ "rematerializable" ],
1022 reg_req => { out => [ "gp" ] },
1023 emit => "movl %I, %D0",
1025 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
1026 attr_type => "ia32_immediate_attr_t",
1032 op_flags => [ "constlike" ],
1033 irn_flags => [ "rematerializable" ],
1034 reg_req => { out => [ "gp" ] },
1041 op_flags => [ "constlike" ],
1042 reg_req => { out => [ "gp" ] },
1046 modified_flags => $status_flags,
1051 op_flags => [ "constlike", "dump_noblock" ],
1052 irn_flags => [ "not_scheduled" ],
1053 reg_req => { out => [ "gp_NOREG:I" ] },
1062 op_flags => [ "constlike", "dump_noblock" ],
1063 irn_flags => [ "not_scheduled" ],
1064 reg_req => { out => [ "fp_NOREG:I" ] },
1069 attr_type => "ia32_x87_attr_t",
1074 op_flags => [ "constlike", "dump_noblock" ],
1075 irn_flags => [ "not_scheduled" ],
1076 reg_req => { out => [ "xmm_NOREG:I" ] },
1085 op_flags => [ "constlike" ],
1086 irn_flags => [ "not_scheduled" ],
1087 reg_req => { out => [ "fpcw:I" ] },
1091 modified_flags => $fpcw_flags
1095 op_flags => [ "uses_memory" ],
1097 reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] },
1098 ins => [ "base", "index", "mem" ],
1100 emit => "fldcw %AM",
1103 modified_flags => $fpcw_flags
1107 op_flags => [ "uses_memory" ],
1109 reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1110 ins => [ "base", "index", "mem", "fpcw" ],
1112 emit => "fnstcw %AM",
1118 op_flags => [ "uses_memory" ],
1120 reg_req => { in => [ "fp_cw" ], out => [ "none" ] },
1128 # we should not rematrialize this node. It has very strict constraints.
1129 reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] },
1130 ins => [ "val", "clobbered" ],
1139 # Note that we add additional latency values depending on address mode, so a
1140 # lateny of 0 for load is correct
1143 op_flags => [ "uses_memory", "fragile" ],
1144 state => "exc_pinned",
1145 reg_req => { in => [ "gp", "gp", "none" ],
1146 out => [ "gp", "none", "none", "none", "none" ] },
1147 ins => [ "base", "index", "mem" ],
1148 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1150 emit => "mov%#Ml %AM, %D0",
1155 op_flags => [ "uses_memory", "fragile" ],
1156 state => "exc_pinned",
1157 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1158 out => [ "none", "none", "none" ] },
1159 ins => [ "base", "index", "mem", "val" ],
1160 outs => [ "M", "X_regular", "X_except" ],
1161 emit => 'mov%M %#S3, %AM',
1167 op_flags => [ "uses_memory", "fragile" ],
1168 state => "exc_pinned",
1169 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1170 out => ["none", "none", "none" ] },
1171 ins => [ "base", "index", "mem", "val" ],
1172 outs => [ "M", "X_regular", "X_except" ],
1173 emit => 'mov%M %#S3, %AM',
1179 irn_flags => [ "rematerializable" ],
1180 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1181 ins => [ "base", "index" ],
1182 emit => 'leal %AM, %D0',
1186 # lea doesn't modify the flags, but setting this seems advantageous since it
1187 # increases chances that the Lea is transformed back to an Add
1188 modified_flags => 1,
1192 state => "exc_pinned",
1193 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1194 ins => [ "base", "index", "mem", "val", "stack" ],
1195 emit => 'push%M %AS3',
1196 outs => [ "stack", "M" ],
1197 am => "source,unary",
1203 state => "exc_pinned",
1204 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1206 outs => [ "stack" ],
1207 emit => 'pushl %%eax',
1214 state => "exc_pinned",
1215 reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1216 ins => [ "mem", "stack" ],
1217 outs => [ "res", "M", "unused", "stack" ],
1218 emit => 'pop%M %D0',
1219 latency => 3, # Pop is more expensive than Push on Athlon
1224 state => "exc_pinned",
1225 reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1226 ins => [ "mem", "stack" ],
1227 outs => [ "res", "M", "unused", "stack" ],
1228 emit => 'pop%M %D0',
1229 latency => 3, # Pop is more expensive than Push on Athlon
1234 state => "exc_pinned",
1235 reg_req => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1238 emit => 'movl %S0, %D0',
1245 state => "exc_pinned",
1246 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1247 ins => [ "base", "index", "mem", "stack" ],
1248 outs => [ "unused0", "M", "unused1", "stack" ],
1249 emit => 'pop%M %AM',
1250 latency => 3, # Pop is more expensive than Push on Athlon
1255 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1257 outs => [ "frame", "stack", "M" ],
1263 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1265 outs => [ "frame", "stack" ],
1268 state => "exc_pinned",
1273 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1274 ins => [ "base", "index", "mem", "stack", "size" ],
1275 am => "source,binary",
1278 outs => [ "stack", "M" ],
1280 modified_flags => $status_flags
1285 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1286 ins => [ "base", "index", "mem", "stack", "size" ],
1287 am => "source,binary",
1288 emit => "subl %B\n".
1291 outs => [ "stack", "addr", "M" ],
1293 modified_flags => $status_flags
1297 op_flags => [ "keep" ],
1305 irn_flags => [ "rematerializable" ],
1306 reg_req => { out => [ "gp" ] },
1308 emit => "movl %%gs:0, %D0",
1314 # BT supports source address mode, but this is unused yet
1317 irn_flags => [ "rematerializable" ],
1318 state => "exc_pinned",
1319 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1320 ins => [ "left", "right" ],
1321 emit => 'bt%M %S1, %S0',
1324 mode => $mode_flags,
1325 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1329 irn_flags => [ "rematerializable" ],
1330 state => "exc_pinned",
1331 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1332 out => [ "gp", "flags", "none" ] },
1333 ins => [ "base", "index", "mem", "operand" ],
1334 outs => [ "res", "flags", "M" ],
1335 am => "source,binary",
1336 emit => 'bsf%M %AS3, %D0',
1340 modified_flags => $status_flags
1344 irn_flags => [ "rematerializable" ],
1345 state => "exc_pinned",
1346 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1347 out => [ "gp", "flags", "none" ] },
1348 ins => [ "base", "index", "mem", "operand" ],
1349 outs => [ "res", "flags", "M" ],
1350 am => "source,binary",
1351 emit => 'bsr%M %AS3, %D0',
1355 modified_flags => $status_flags
1359 # SSE4.2 or SSE4a popcnt instruction
1362 irn_flags => [ "rematerializable" ],
1363 state => "exc_pinned",
1364 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1365 out => [ "gp", "flags", "none" ] },
1366 ins => [ "base", "index", "mem", "operand" ],
1367 outs => [ "res", "flags", "M" ],
1368 am => "source,binary",
1369 emit => 'popcnt%M %AS3, %D0',
1373 modified_flags => $status_flags
1377 op_flags => [ "uses_memory", "fragile" ],
1378 state => "exc_pinned",
1380 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1381 out => [ "esp:I|S", "fpcw:I", "none", "eax", "ecx", "edx", "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "none", "none" ]
1383 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1384 outs => [ "stack", "fpcw", "M", "eax", "ecx", "edx", "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "X_regular", "X_except" ],
1385 emit => "call %*AS3",
1386 attr_type => "ia32_call_attr_t",
1387 attr => "unsigned pop, ir_type *call_tp",
1388 am => "source,unary",
1389 units => [ "BRANCH" ],
1390 latency => 4, # random number
1391 modified_flags => $status_flags
1395 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1397 # PS: try gcc __builtin_frame_address(100000) :-)
1400 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1401 ins => [ "frame", "cnt", "tmp" ],
1403 latency => 4, # random number
1404 attr_type => "ia32_climbframe_attr_t",
1405 attr => "unsigned count",
1414 irn_flags => [ "rematerializable" ],
1415 reg_req => { in => [ "gp" ],
1416 out => [ "in_r1" ] },
1418 emit => 'bswap%M %S0',
1426 # bswap16, use xchg here
1429 irn_flags => [ "rematerializable" ],
1430 reg_req => { in => [ "eax ebx ecx edx" ],
1431 out => [ "in_r1" ] },
1432 emit => 'xchg %<S0, %>S0',
1444 reg_req => { in => [ "none" ], out => [ "none" ] },
1453 # Undefined Instruction on ALL x86 CPU's
1457 reg_req => { in => [ "none" ], out => [ "none" ] },
1469 irn_flags => [ "rematerializable" ],
1471 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1472 ins => [ "port", "value", "mem" ],
1473 emit => 'out%M %^S0, %#S1',
1477 modified_flags => $status_flags
1484 irn_flags => [ "rematerializable" ],
1486 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1487 ins => [ "port", "mem" ],
1488 outs => [ "res", "M" ],
1489 emit => 'in%M %#D0, %^S0',
1493 modified_flags => $status_flags
1497 # Intel style prefetching
1500 op_flags => [ "uses_memory" ],
1501 state => "exc_pinned",
1502 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1503 ins => [ "base", "index", "mem" ],
1506 emit => "prefetcht0 %AM",
1511 op_flags => [ "uses_memory" ],
1512 state => "exc_pinned",
1513 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1514 ins => [ "base", "index", "mem" ],
1517 emit => "prefetcht1 %AM",
1522 op_flags => [ "uses_memory" ],
1523 state => "exc_pinned",
1524 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1525 ins => [ "base", "index", "mem" ],
1528 emit => "prefetcht2 %AM",
1533 op_flags => [ "uses_memory" ],
1534 state => "exc_pinned",
1535 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1536 ins => [ "base", "index", "mem" ],
1539 emit => "prefetchnta %AM",
1544 # 3DNow! prefetch instructions
1547 op_flags => [ "uses_memory" ],
1548 state => "exc_pinned",
1549 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1550 ins => [ "base", "index", "mem" ],
1553 emit => "prefetch %AM",
1558 op_flags => [ "uses_memory" ],
1559 state => "exc_pinned",
1560 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1561 ins => [ "base", "index", "mem" ],
1564 emit => "prefetchw %AM",
1570 irn_flags => [ "rematerializable" ],
1571 reg_req => { out => [ "xmm" ] },
1572 emit => 'xorp%FX %D0, %D0',
1579 op_flags => [ "constlike" ],
1580 irn_flags => [ "rematerializable" ],
1581 reg_req => { out => [ "xmm" ] },
1588 irn_flags => [ "rematerializable" ],
1589 reg_req => { out => [ "xmm" ] },
1590 emit => 'pxor %D0, %D0',
1596 # produces all 1 bits
1598 irn_flags => [ "rematerializable" ],
1599 reg_req => { out => [ "xmm" ] },
1600 emit => 'pcmpeqb %D0, %D0',
1606 # integer shift left, dword
1608 irn_flags => [ "rematerializable" ],
1609 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1610 emit => 'pslld %#S1, %D0',
1616 # integer shift left, qword
1618 irn_flags => [ "rematerializable" ],
1619 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1620 emit => 'psllq %#S1, %D0',
1626 # integer shift right, dword
1628 irn_flags => [ "rematerializable" ],
1629 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1630 emit => 'psrld %#S1, %D0',
1636 # mov from integer to SSE register
1638 irn_flags => [ "rematerializable" ],
1639 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1640 emit => 'movd %S0, %D0',
1647 irn_flags => [ "rematerializable" ],
1648 state => "exc_pinned",
1649 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1650 out => [ "in_r4 in_r5", "flags", "none" ] },
1651 ins => [ "base", "index", "mem", "left", "right" ],
1652 outs => [ "res", "flags", "M" ],
1653 am => "source,binary",
1654 emit => 'adds%FX %B',
1661 irn_flags => [ "rematerializable" ],
1662 state => "exc_pinned",
1663 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1664 out => [ "in_r4 in_r5", "flags", "none" ] },
1665 ins => [ "base", "index", "mem", "left", "right" ],
1666 outs => [ "res", "flags", "M" ],
1667 am => "source,binary",
1668 emit => 'muls%FX %B',
1675 irn_flags => [ "rematerializable" ],
1676 state => "exc_pinned",
1677 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1678 out => [ "in_r4 in_r5", "flags", "none" ] },
1679 ins => [ "base", "index", "mem", "left", "right" ],
1680 outs => [ "res", "flags", "M" ],
1681 am => "source,binary",
1682 emit => 'maxs%FX %B',
1689 irn_flags => [ "rematerializable" ],
1690 state => "exc_pinned",
1691 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1692 out => [ "in_r4 in_r5", "flags", "none" ] },
1693 ins => [ "base", "index", "mem", "left", "right" ],
1694 outs => [ "res", "flags", "M" ],
1695 am => "source,binary",
1696 emit => 'mins%FX %B',
1703 irn_flags => [ "rematerializable" ],
1704 state => "exc_pinned",
1705 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1706 out => [ "in_r4 in_r5", "flags", "none" ] },
1707 ins => [ "base", "index", "mem", "left", "right" ],
1708 outs => [ "res", "flags", "M" ],
1709 am => "source,binary",
1710 emit => 'andp%FX %B',
1717 irn_flags => [ "rematerializable" ],
1718 state => "exc_pinned",
1719 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1720 out => [ "in_r4 in_r5", "flags", "none" ] },
1721 ins => [ "base", "index", "mem", "left", "right" ],
1722 outs => [ "res", "flags", "M" ],
1723 am => "source,binary",
1724 emit => 'orp%FX %B',
1731 irn_flags => [ "rematerializable" ],
1732 state => "exc_pinned",
1733 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1734 out => [ "in_r4 in_r5", "flags", "none" ] },
1735 ins => [ "base", "index", "mem", "left", "right" ],
1736 outs => [ "res", "flags", "M" ],
1737 am => "source,binary",
1738 emit => 'xorp%FX %B',
1745 irn_flags => [ "rematerializable" ],
1746 state => "exc_pinned",
1747 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1748 out => [ "in_r4 !in_r5", "flags", "none" ] },
1749 ins => [ "base", "index", "mem", "left", "right" ],
1750 outs => [ "res", "flags", "M" ],
1751 am => "source,binary",
1752 emit => 'andnp%FX %B',
1759 irn_flags => [ "rematerializable" ],
1760 state => "exc_pinned",
1761 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1762 out => [ "in_r4", "flags", "none" ] },
1763 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1764 outs => [ "res", "flags", "M" ],
1765 am => "source,binary",
1766 emit => 'subs%FX %B',
1773 irn_flags => [ "rematerializable" ],
1774 state => "exc_pinned",
1775 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1776 out => [ "in_r4 !in_r5", "flags", "none" ] },
1777 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1778 outs => [ "res", "flags", "M" ],
1779 am => "source,binary",
1780 emit => 'divs%FX %B',
1786 irn_flags => [ "rematerializable" ],
1787 state => "exc_pinned",
1788 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1789 out => [ "eflags" ] },
1790 ins => [ "base", "index", "mem", "left", "right" ],
1791 outs => [ "flags" ],
1792 am => "source,binary",
1793 attr => "bool ins_permuted",
1794 init_attr => "attr->data.ins_permuted = ins_permuted;",
1795 emit => 'ucomis%FX %B',
1798 mode => $mode_flags,
1799 modified_flags => 1,
1803 op_flags => [ "uses_memory", "fragile" ],
1804 state => "exc_pinned",
1805 reg_req => { in => [ "gp", "gp", "none" ],
1806 out => [ "xmm", "none", "none", "none", "none" ] },
1807 ins => [ "base", "index", "mem" ],
1808 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1809 emit => 'movs%FX %AM, %D0',
1810 attr => "ir_mode *load_mode",
1811 init_attr => "attr->ls_mode = load_mode;",
1817 op_flags => [ "uses_memory", "fragile" ],
1818 state => "exc_pinned",
1819 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1820 out => [ "none", "none", "none" ] },
1821 ins => [ "base", "index", "mem", "val" ],
1822 outs => [ "M", "X_regular", "X_except" ],
1823 emit => 'movs%FX %S3, %AM',
1829 op_flags => [ "uses_memory", "fragile" ],
1830 state => "exc_pinned",
1831 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1832 out => [ "none", "none", "none" ] },
1833 ins => [ "base", "index", "mem", "val" ],
1834 outs => [ "M", "X_regular", "X_except" ],
1835 emit => 'movs%FX %S3, %AM',
1841 state => "exc_pinned",
1842 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1843 ins => [ "base", "index", "mem", "val" ],
1844 am => "source,unary",
1845 emit => 'cvtsi2ss %AS3, %D0',
1852 state => "exc_pinned",
1853 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1854 ins => [ "base", "index", "mem", "val" ],
1855 am => "source,unary",
1856 emit => 'cvtsi2sd %AS3, %D0',
1864 ins => [ "val_high", "val_low" ],
1866 dump_func => "NULL",
1871 outs => [ "res_high", "res_low" ],
1873 dump_func => "NULL",
1877 op_flags => [ "uses_memory", "fragile" ],
1879 reg_req => { in => [ "edi", "esi", "ecx", "none" ],
1880 out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1881 ins => [ "dest", "source", "count", "mem" ],
1882 outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1883 attr_type => "ia32_copyb_attr_t",
1884 attr => "unsigned size",
1887 # we don't care about this flag, so no need to mark this node
1888 # modified_flags => [ "DF" ]
1892 op_flags => [ "uses_memory", "fragile" ],
1894 reg_req => { in => [ "edi", "esi", "none" ],
1895 out => [ "edi", "esi", "none", "none", "none" ] },
1896 ins => [ "dest", "source", "mem" ],
1897 outs => [ "dest", "source", "M", "X_regular", "X_except" ],
1898 attr_type => "ia32_copyb_attr_t",
1899 attr => "unsigned size",
1902 # we don't care about this flag, so no need to mark this node
1903 # modified_flags => [ "DF" ]
1907 state => "exc_pinned",
1908 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1918 op_flags => [ "uses_memory", "fragile" ],
1919 state => "exc_pinned",
1920 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1921 out => [ "gp", "none", "none", "none", "none" ] },
1922 ins => [ "base", "index", "mem", "val" ],
1923 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1924 emit => "mov%#Ml %#AS3, %D0",
1925 am => "source,unary",
1928 attr => "ir_mode *smaller_mode",
1929 init_attr => "attr->ls_mode = smaller_mode;",
1934 op_flags => [ "uses_memory", "fragile" ],
1935 state => "exc_pinned",
1936 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1937 out => [ "gp", "none", "none", "none", "none" ] },
1938 ins => [ "base", "index", "mem", "val" ],
1939 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1940 emit => "mov%#Ml %#AS3, %D0",
1941 am => "source,unary",
1944 attr => "ir_mode *smaller_mode",
1945 init_attr => "attr->ls_mode = smaller_mode;",
1950 state => "exc_pinned",
1951 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1952 ins => [ "base", "index", "mem", "val" ],
1953 am => "source,unary",
1960 state => "exc_pinned",
1961 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1962 ins => [ "base", "index", "mem", "val" ],
1963 am => "source,unary",
1970 state => "exc_pinned",
1971 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1972 ins => [ "base", "index", "mem", "val" ],
1973 am => "source,unary",
1979 # rematerialisation disabled for all float nodes for now, because the fpcw
1980 # handler runs before spilling and we might end up with wrong fpcw then
1983 # irn_flags => [ "rematerializable" ],
1984 state => "exc_pinned",
1985 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1986 out => [ "fp", "none", "none" ] },
1987 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1988 outs => [ "res", "dummy", "M" ],
1989 emit => 'fadd%FP%FM %AF',
1990 am => "source,binary",
1994 attr_type => "ia32_x87_attr_t",
1998 # irn_flags => [ "rematerializable" ],
1999 state => "exc_pinned",
2000 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2001 out => [ "fp", "none", "none" ] },
2002 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2003 outs => [ "res", "dummy", "M" ],
2004 emit => 'fmul%FP%FM %AF',
2005 am => "source,binary",
2009 attr_type => "ia32_x87_attr_t",
2013 # irn_flags => [ "rematerializable" ],
2014 state => "exc_pinned",
2015 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2016 out => [ "fp", "none", "none" ] },
2017 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2018 outs => [ "res", "dummy", "M" ],
2019 emit => 'fsub%FR%FP%FM %AF',
2020 am => "source,binary",
2024 attr_type => "ia32_x87_attr_t",
2028 state => "exc_pinned",
2029 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2030 out => [ "fp", "none", "none" ] },
2031 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2032 outs => [ "res", "dummy", "M" ],
2033 emit => 'fdiv%FR%FP%FM %AF',
2034 am => "source,binary",
2037 attr_type => "ia32_x87_attr_t",
2041 reg_req => { in => [ "fp", "fp", "fpcw" ], out => [ "fp" ] },
2042 ins => [ "left", "right", "fpcw" ],
2047 attr_type => "ia32_x87_attr_t",
2051 irn_flags => [ "rematerializable" ],
2052 reg_req => { in => [ "fp"], out => [ "fp" ] },
2058 attr_type => "ia32_x87_attr_t",
2062 irn_flags => [ "rematerializable" ],
2063 reg_req => { in => [ "fp"], out => [ "fp" ] },
2069 attr_type => "ia32_x87_attr_t",
2073 irn_flags => [ "rematerializable" ],
2074 op_flags => [ "uses_memory", "fragile" ],
2075 state => "exc_pinned",
2076 reg_req => { in => [ "gp", "gp", "none" ],
2077 out => [ "fp", "none", "none", "none", "none" ] },
2078 ins => [ "base", "index", "mem" ],
2079 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
2080 emit => 'fld%FM %AM',
2081 attr => "ir_mode *load_mode",
2082 init_attr => "attr->attr.ls_mode = load_mode;",
2085 attr_type => "ia32_x87_attr_t",
2089 irn_flags => [ "rematerializable" ],
2090 op_flags => [ "uses_memory", "fragile" ],
2091 state => "exc_pinned",
2092 reg_req => { in => [ "gp", "gp", "none", "fp" ],
2093 out => [ "none", "none", "none" ] },
2094 ins => [ "base", "index", "mem", "val" ],
2095 outs => [ "M", "X_regular", "X_except" ],
2096 emit => 'fst%FP%FM %AM',
2097 attr => "ir_mode *store_mode",
2098 init_attr => "attr->attr.ls_mode = store_mode;",
2101 attr_type => "ia32_x87_attr_t",
2105 state => "exc_pinned",
2106 reg_req => { in => [ "gp", "gp", "none" ],
2107 out => [ "fp", "none", "none" ] },
2108 outs => [ "res", "unused", "M" ],
2109 ins => [ "base", "index", "mem" ],
2110 emit => 'fild%FM %AM',
2113 attr_type => "ia32_x87_attr_t",
2117 op_flags => [ "uses_memory", "fragile" ],
2118 state => "exc_pinned",
2119 reg_req => { in => [ "gp", "gp", "none", "fp", "fpcw" ],
2120 out => [ "none", "none", "none", "none" ] },
2121 ins => [ "base", "index", "mem", "val", "fpcw" ],
2122 outs => [ "dummy", "M", "X_regular", "X_except" ],
2123 emit => 'fist%FP%FM %AM',
2126 attr_type => "ia32_x87_attr_t",
2129 # SSE3 fisttp instruction
2131 op_flags => [ "uses_memory", "fragile" ],
2132 state => "exc_pinned",
2133 reg_req => { in => [ "gp", "gp", "none", "fp" ],
2134 out => [ "in_r4", "none", "none", "none" ]},
2135 ins => [ "base", "index", "mem", "val" ],
2136 outs => [ "res", "M", "X_regular", "X_except" ],
2137 emit => 'fisttp%FM %AM',
2140 attr_type => "ia32_x87_attr_t",
2144 irn_flags => [ "rematerializable" ],
2145 reg_req => { out => [ "fp" ] },
2151 attr_type => "ia32_x87_attr_t",
2155 irn_flags => [ "rematerializable" ],
2156 reg_req => { out => [ "fp" ] },
2162 attr_type => "ia32_x87_attr_t",
2166 irn_flags => [ "rematerializable" ],
2167 reg_req => { out => [ "fp" ] },
2173 attr_type => "ia32_x87_attr_t",
2177 irn_flags => [ "rematerializable" ],
2178 reg_req => { out => [ "fp" ] },
2184 attr_type => "ia32_x87_attr_t",
2188 irn_flags => [ "rematerializable" ],
2189 reg_req => { out => [ "fp" ] },
2195 attr_type => "ia32_x87_attr_t",
2199 irn_flags => [ "rematerializable" ],
2200 reg_req => { out => [ "fp" ] },
2206 attr_type => "ia32_x87_attr_t",
2210 irn_flags => [ "rematerializable" ],
2211 reg_req => { out => [ "fp" ] },
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 => [ "fp", "fp" ], out => [ "eax" ] },
2225 ins => [ "left", "right" ],
2226 outs => [ "flags" ],
2227 emit => "fucom%FP %F0\n".
2229 attr => "bool ins_permuted",
2230 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2233 attr_type => "ia32_x87_attr_t",
2238 # we can't allow to rematerialize this node so we don't
2239 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2240 # irn_flags => [ "rematerializable" ],
2241 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2242 ins => [ "left", "right" ],
2243 outs => [ "flags" ],
2244 emit => "fucompp\n".
2246 attr => "bool ins_permuted",
2247 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2250 attr_type => "ia32_x87_attr_t",
2255 irn_flags => [ "rematerializable" ],
2256 reg_req => { in => [ "fp", "fp" ], out => [ "eflags" ] },
2257 ins => [ "left", "right" ],
2258 outs => [ "flags" ],
2259 emit => 'fucom%FPi %F0',
2260 attr => "bool ins_permuted",
2261 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2264 attr_type => "ia32_x87_attr_t",
2269 # irn_flags => [ "rematerializable" ],
2270 reg_req => { in => [ "fp" ], out => [ "eax" ] },
2272 outs => [ "flags" ],
2275 attr => "bool ins_permuted",
2276 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2279 attr_type => "ia32_x87_attr_t",
2284 irn_flags => [ "rematerializable" ],
2285 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2287 outs => [ "flags" ],
2291 mode => $mode_flags,
2295 # Note that it is NEVER allowed to do CSE on these nodes
2296 # Moreover, note the virtual register requierements!
2299 op_flags => [ "keep" ],
2300 reg_req => { out => [ "none" ] },
2301 cmp_attr => "return 1;",
2303 attr_type => "ia32_x87_attr_t",
2309 op_flags => [ "keep" ],
2310 reg_req => { out => [ "none" ] },
2311 cmp_attr => "return 1;",
2313 attr_type => "ia32_x87_attr_t",
2319 reg_req => { in => [ "fp"], out => [ "fp" ] },
2320 cmp_attr => "return 1;",
2322 attr_type => "ia32_x87_attr_t",
2327 op_flags => [ "keep" ],
2328 reg_req => { out => [ "none" ] },
2329 cmp_attr => "return 1;",
2331 attr_type => "ia32_x87_attr_t",
2337 op_flags => [ "keep" ],
2338 reg_req => { out => [ "none" ] },
2339 cmp_attr => "return 1;",
2340 emit => 'ffreep %F0',
2341 attr_type => "ia32_x87_attr_t",
2347 op_flags => [ "keep" ],
2348 reg_req => { out => [ "none" ] },
2349 cmp_attr => "return 1;",
2351 attr_type => "ia32_x87_attr_t",
2357 op_flags => [ "keep" ],
2358 reg_req => { out => [ "none" ] },
2359 cmp_attr => "return 1;",
2361 attr_type => "ia32_x87_attr_t",
2366 # Spilling and reloading of SSE registers, hardcoded, not generated #
2369 op_flags => [ "uses_memory", "fragile" ],
2370 state => "exc_pinned",
2371 reg_req => { in => [ "gp", "gp", "none" ],
2372 out => [ "xmm", "none", "none", "none" ] },
2373 emit => 'movdqu %D0, %AM',
2374 ins => [ "base", "index", "mem" ],
2375 outs => [ "res", "M", "X_regular", "X_except" ],
2381 op_flags => [ "uses_memory", "fragile" ],
2382 state => "exc_pinned",
2383 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
2384 out => [ "none", "none", "none" ] },
2385 ins => [ "base", "index", "mem", "val" ],
2386 outs => [ "M", "X_regular", "X_except" ],
2387 emit => 'movdqu %B',
2394 # Transform some attributes
2395 foreach my $op (keys(%nodes)) {
2396 my $node = $nodes{$op};
2397 my $op_attr_init = $node->{op_attr_init};
2399 if(defined($op_attr_init)) {
2400 $op_attr_init .= "\n\t";
2405 if(!defined($node->{latency})) {
2407 $node->{latency} = 0;
2409 die("Latency missing for op $op");
2412 $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2414 $node->{op_attr_init} = $op_attr_init;