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 => "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_asm_attributes(res);",
122 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);",
124 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
125 "\tinit_ia32_call_attributes(res, pop, call_tp);",
126 ia32_condcode_attr_t =>
127 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
128 "\tinit_ia32_condcode_attributes(res, condition_code);",
129 ia32_switch_attr_t =>
130 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
131 "\tinit_ia32_switch_attributes(res, switch_table);",
133 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
134 "\tinit_ia32_copyb_attributes(res, size);",
135 ia32_immediate_attr_t =>
136 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
137 "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
139 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
140 "\tinit_ia32_x87_attributes(res);",
141 ia32_climbframe_attr_t =>
142 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
143 "\tinit_ia32_climbframe_attributes(res, count);",
147 ia32_asm_attr_t => "ia32_compare_asm_attr",
148 ia32_attr_t => "ia32_compare_nodes_attr",
149 ia32_call_attr_t => "ia32_compare_call_attr",
150 ia32_condcode_attr_t => "ia32_compare_condcode_attr",
151 ia32_copyb_attr_t => "ia32_compare_copyb_attr",
152 ia32_switch_attr_t => "ia32_compare_nodes_attr",
153 ia32_immediate_attr_t => "ia32_compare_immediate_attr",
154 ia32_x87_attr_t => "ia32_compare_x87_attr",
155 ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
158 $status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
159 $status_flags_wo_cf = [ "PF", "AF", "ZF", "SF", "OF" ];
160 $fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
161 "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
167 op_flags => [ "constlike" ],
168 irn_flags => [ "not_scheduled" ],
169 reg_req => { out => [ "gp_NOREG:I" ] },
170 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
171 attr_type => "ia32_immediate_attr_t",
172 hash_func => "ia32_hash_Immediate",
180 out_arity => "variable",
181 attr_type => "ia32_asm_attr_t",
182 attr => "ident *asm_text, const ia32_asm_reg_t *register_map",
183 init_attr => "attr->asm_text = asm_text;\n".
184 "\tattr->register_map = register_map;\n",
186 modified_flags => $status_flags,
189 # "allocates" a free register
191 op_flags => [ "constlike", "cse_neutral" ],
192 irn_flags => [ "rematerializable" ],
193 reg_req => { out => [ "gp" ] },
198 cmp_attr => "return 1;",
202 irn_flags => [ "rematerializable" ],
203 state => "exc_pinned",
204 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
205 out => [ "in_r4 in_r5", "flags", "none" ] },
206 ins => [ "base", "index", "mem", "left", "right" ],
207 outs => [ "res", "flags", "M" ],
209 am => "source,binary",
213 modified_flags => $status_flags
217 irn_flags => [ "rematerializable" ],
218 state => "exc_pinned",
219 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
220 ins => [ "base", "index", "mem", "val" ],
221 emit => "add%M %#S3, %AM",
225 modified_flags => $status_flags
229 irn_flags => [ "rematerializable" ],
230 state => "exc_pinned",
231 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
232 ins => [ "base", "index", "mem", "val" ],
233 emit => "add%M %#S3, %AM",
237 modified_flags => $status_flags
241 state => "exc_pinned",
242 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
243 out => [ "in_r4 in_r5", "flags", "none" ] },
244 ins => [ "base", "index", "mem", "left", "right", "eflags" ],
245 outs => [ "res", "flags", "M" ],
247 am => "source,binary",
251 modified_flags => $status_flags
255 ins => [ "left", "right" ],
261 ins => [ "left", "right", "eflags" ],
267 # we should not rematrialize this node. It produces 2 results and has
268 # very strict constraints
269 state => "exc_pinned",
270 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
271 out => [ "eax", "flags", "none", "edx" ] },
272 ins => [ "base", "index", "mem", "left", "right" ],
273 emit => 'mul%M %AS4',
274 outs => [ "res_low", "flags", "M", "res_high" ],
275 am => "source,binary",
278 modified_flags => $status_flags
282 ins => [ "left", "right" ],
283 outs => [ "res_low", "flags", "M", "res_high" ],
289 irn_flags => [ "rematerializable" ],
290 state => "exc_pinned",
291 # TODO: adjust out requirements for the 3 operand form
292 # (no need for should_be_same then)
293 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
294 out => [ "in_r4 in_r5", "flags", "none" ] },
295 ins => [ "base", "index", "mem", "left", "right" ],
296 outs => [ "res", "flags", "M" ],
297 am => "source,binary",
301 modified_flags => $status_flags
305 irn_flags => [ "rematerializable" ],
306 state => "exc_pinned",
307 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
308 out => [ "eax", "flags", "none", "edx" ] },
309 ins => [ "base", "index", "mem", "left", "right" ],
310 emit => 'imul%M %AS4',
311 outs => [ "res_low", "flags", "M", "res_high" ],
312 am => "source,binary",
315 modified_flags => $status_flags
319 ins => [ "left", "right" ],
320 outs => [ "res_low", "flags", "M", "res_high" ],
326 irn_flags => [ "rematerializable" ],
327 state => "exc_pinned",
328 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
329 out => [ "in_r4 in_r5", "flags", "none" ] },
330 ins => [ "base", "index", "mem", "left", "right" ],
331 outs => [ "res", "flags", "M" ],
332 am => "source,binary",
337 modified_flags => $status_flags
341 irn_flags => [ "rematerializable" ],
342 state => "exc_pinned",
343 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
344 ins => [ "base", "index", "mem", "val" ],
345 emit => 'and%M %#S3, %AM',
349 modified_flags => $status_flags
353 irn_flags => [ "rematerializable" ],
354 state => "exc_pinned",
355 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
356 ins => [ "base", "index", "mem", "val" ],
357 emit => 'and%M %#S3, %AM',
361 modified_flags => $status_flags
365 irn_flags => [ "rematerializable" ],
366 state => "exc_pinned",
367 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
368 out => [ "in_r4 in_r5", "flags", "none" ] },
369 ins => [ "base", "index", "mem", "left", "right" ],
370 outs => [ "res", "flags", "M" ],
371 am => "source,binary",
376 modified_flags => $status_flags
380 irn_flags => [ "rematerializable" ],
381 state => "exc_pinned",
382 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
383 ins => [ "base", "index", "mem", "val" ],
384 emit => 'or%M %#S3, %AM',
388 modified_flags => $status_flags
392 irn_flags => [ "rematerializable" ],
393 state => "exc_pinned",
394 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
395 ins => [ "base", "index", "mem", "val" ],
396 emit => 'or%M %#S3, %AM',
400 modified_flags => $status_flags
404 irn_flags => [ "rematerializable" ],
405 state => "exc_pinned",
406 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
407 out => [ "in_r4 in_r5", "flags", "none" ] },
408 ins => [ "base", "index", "mem", "left", "right" ],
409 outs => [ "res", "flags", "M" ],
410 am => "source,binary",
415 modified_flags => $status_flags
419 op_flags => [ "constlike" ],
420 irn_flags => [ "rematerializable" ],
421 reg_req => { out => [ "gp", "flags" ] },
422 outs => [ "res", "flags" ],
423 emit => "xor%M %D0, %D0",
427 modified_flags => $status_flags
431 irn_flags => [ "rematerializable" ],
432 state => "exc_pinned",
433 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
434 ins => [ "base", "index", "mem", "val" ],
435 emit => 'xor%M %#S3, %AM',
439 modified_flags => $status_flags
443 irn_flags => [ "rematerializable" ],
444 state => "exc_pinned",
445 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
446 ins => [ "base", "index", "mem", "val" ],
447 emit => 'xor%M %#S3, %AM',
451 modified_flags => $status_flags
455 irn_flags => [ "rematerializable" ],
456 state => "exc_pinned",
457 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
458 out => [ "in_r4", "flags", "none" ] },
459 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
460 outs => [ "res", "flags", "M" ],
461 am => "source,binary",
466 modified_flags => $status_flags
470 irn_flags => [ "rematerializable" ],
471 state => "exc_pinned",
472 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
473 ins => [ "base", "index", "mem", "subtrahend" ],
474 emit => 'sub%M %#S3, %AM',
478 modified_flags => $status_flags
482 irn_flags => [ "rematerializable" ],
483 state => "exc_pinned",
484 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
485 ins => [ "base", "index", "mem", "subtrahend" ],
486 emit => 'sub%M %#S3, %AM',
490 modified_flags => $status_flags
494 state => "exc_pinned",
495 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
496 out => [ "in_r4", "flags", "none" ] },
497 ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
498 outs => [ "res", "flags", "M" ],
499 am => "source,binary",
504 modified_flags => $status_flags
508 # Spiller currently fails when rematerializing flag consumers
509 # irn_flags => [ "rematerializable" ],
510 reg_req => { in => [ "flags" ], out => [ "gp", "flags" ] },
511 outs => [ "res", "flags" ],
512 emit => "sbb%M %D0, %D0",
516 modified_flags => $status_flags
520 ins => [ "minuend", "subtrahend" ],
526 ins => [ "minuend", "subtrahend", "eflags" ],
532 op_flags => [ "fragile", "uses_memory" ],
533 state => "exc_pinned",
534 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
535 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
536 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
537 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
538 am => "source,unary",
539 emit => "idiv%M %AS3",
542 modified_flags => $status_flags
546 op_flags => [ "fragile", "uses_memory" ],
547 state => "exc_pinned",
548 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
549 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
550 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
551 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
552 am => "source,unary",
553 emit => "div%M %AS3",
556 modified_flags => $status_flags
560 irn_flags => [ "rematerializable" ],
561 reg_req => { in => [ "gp", "ecx" ],
562 out => [ "in_r1 !in_r2", "flags" ] },
563 ins => [ "val", "count" ],
564 outs => [ "res", "flags" ],
565 emit => 'shl%M %<S1, %S0',
569 modified_flags => $status_flags
573 irn_flags => [ "rematerializable" ],
574 state => "exc_pinned",
575 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
576 ins => [ "base", "index", "mem", "count" ],
577 emit => 'shl%M %<S3, %AM',
581 modified_flags => $status_flags
585 irn_flags => [ "rematerializable" ],
586 reg_req => { in => [ "gp", "gp", "ecx" ],
587 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
588 ins => [ "val_high", "val_low", "count" ],
589 outs => [ "res", "flags" ],
590 emit => "shld%M %<S2, %S1, %D0",
594 modified_flags => $status_flags
598 irn_flags => [ "rematerializable" ],
599 reg_req => { in => [ "gp", "ecx" ],
600 out => [ "in_r1 !in_r2", "flags" ] },
601 ins => [ "val", "count" ],
602 outs => [ "res", "flags" ],
603 emit => 'shr%M %<S1, %S0',
607 modified_flags => $status_flags
611 irn_flags => [ "rematerializable" ],
612 state => "exc_pinned",
613 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
614 ins => [ "base", "index", "mem", "count" ],
615 emit => 'shr%M %<S3, %AM',
619 modified_flags => $status_flags
623 irn_flags => [ "rematerializable" ],
624 reg_req => { in => [ "gp", "gp", "ecx" ],
625 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
626 ins => [ "val_high", "val_low", "count" ],
627 outs => [ "res", "flags" ],
628 emit => "shrd%M %<S2, %S1, %D0",
632 modified_flags => $status_flags
636 irn_flags => [ "rematerializable" ],
637 reg_req => { in => [ "gp", "ecx" ],
638 out => [ "in_r1 !in_r2", "flags" ] },
639 ins => [ "val", "count" ],
640 outs => [ "res", "flags" ],
641 emit => 'sar%M %<S1, %S0',
645 modified_flags => $status_flags
649 irn_flags => [ "rematerializable" ],
650 state => "exc_pinned",
651 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
652 ins => [ "base", "index", "mem", "count" ],
653 emit => 'sar%M %<S3, %AM',
657 modified_flags => $status_flags
661 irn_flags => [ "rematerializable" ],
662 reg_req => { in => [ "gp", "ecx" ],
663 out => [ "in_r1 !in_r2", "flags" ] },
664 ins => [ "val", "count" ],
665 outs => [ "res", "flags" ],
666 emit => 'ror%M %<S1, %S0',
670 modified_flags => $status_flags
674 irn_flags => [ "rematerializable" ],
675 state => "exc_pinned",
676 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
677 ins => [ "base", "index", "mem", "count" ],
678 emit => 'ror%M %<S3, %AM',
682 modified_flags => $status_flags
686 irn_flags => [ "rematerializable" ],
687 reg_req => { in => [ "gp", "ecx" ],
688 out => [ "in_r1 !in_r2", "flags" ] },
689 ins => [ "val", "count" ],
690 outs => [ "res", "flags" ],
691 emit => 'rol%M %<S1, %D0',
695 modified_flags => $status_flags
699 irn_flags => [ "rematerializable" ],
700 state => "exc_pinned",
701 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
702 ins => [ "base", "index", "mem", "count" ],
703 emit => 'rol%M %<S3, %AM',
707 modified_flags => $status_flags
711 irn_flags => [ "rematerializable" ],
712 reg_req => { in => [ "gp" ],
713 out => [ "in_r1", "flags" ] },
716 outs => [ "res", "flags" ],
720 modified_flags => $status_flags
724 irn_flags => [ "rematerializable" ],
725 state => "exc_pinned",
726 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
727 ins => [ "base", "index", "mem" ],
732 modified_flags => $status_flags
736 irn_flags => [ "rematerializable" ],
737 reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
738 outs => [ "low_res", "high_res" ],
741 modified_flags => $status_flags
746 irn_flags => [ "rematerializable" ],
747 reg_req => { in => [ "gp" ],
748 out => [ "in_r1", "flags" ] },
750 outs => [ "res", "flags" ],
755 modified_flags => $status_flags_wo_cf
759 irn_flags => [ "rematerializable" ],
760 state => "exc_pinned",
761 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
762 ins => [ "base", "index", "mem" ],
767 modified_flags => $status_flags_wo_cf
771 irn_flags => [ "rematerializable" ],
772 reg_req => { in => [ "gp" ],
773 out => [ "in_r1", "flags" ] },
775 outs => [ "res", "flags" ],
780 modified_flags => $status_flags_wo_cf
784 irn_flags => [ "rematerializable" ],
785 state => "exc_pinned",
786 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
787 ins => [ "base", "index", "mem" ],
792 modified_flags => $status_flags_wo_cf
796 irn_flags => [ "rematerializable" ],
797 reg_req => { in => [ "gp" ],
798 out => [ "in_r1" ] },
809 irn_flags => [ "rematerializable" ],
810 state => "exc_pinned",
811 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
812 ins => [ "base", "index", "mem" ],
821 reg_req => { in => [ "flags" ], out => [ "flags" ] },
826 modified_flags => $status_flags
830 reg_req => { out => [ "flags" ] },
835 modified_flags => $status_flags
839 irn_flags => [ "rematerializable" ],
840 state => "exc_pinned",
841 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
842 out => [ "flags", "none", "none" ] },
843 ins => [ "base", "index", "mem", "left", "right" ],
844 outs => [ "eflags", "unused", "M" ],
845 am => "source,binary",
847 attr => "bool ins_permuted",
848 init_attr => "attr->data.ins_permuted = ins_permuted;",
852 modified_flags => $status_flags
856 irn_flags => [ "rematerializable" ],
857 state => "exc_pinned",
858 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
859 out => [ "flags", "none", "none" ] },
860 ins => [ "base", "index", "mem", "left", "right" ],
861 outs => [ "eflags", "unused", "M" ],
862 am => "source,binary",
864 attr => "bool ins_permuted",
865 init_attr => "attr->data.ins_permuted = ins_permuted;",
869 modified_flags => $status_flags
873 irn_flags => [ "rematerializable" ],
874 state => "exc_pinned",
875 reg_req => { in => [ "eax ebx ecx edx" ],
876 out => [ "in_r1", "flags" ] },
877 emit => 'xorb %>S0, %<S0',
879 outs => [ "res", "flags" ],
883 modified_flags => $status_flags,
887 irn_flags => [ "rematerializable" ],
888 state => "exc_pinned",
889 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] ,
890 out => [ "flags", "none", "none" ] },
891 ins => [ "base", "index", "mem", "left", "right" ],
892 outs => [ "eflags", "unused", "M" ],
893 am => "source,binary",
895 attr => "bool ins_permuted",
896 init_attr => "attr->data.ins_permuted = ins_permuted;",
900 modified_flags => $status_flags
904 irn_flags => [ "rematerializable" ],
905 state => "exc_pinned",
906 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
907 out => [ "flags", "none", "none" ] },
908 ins => [ "base", "index", "mem", "left", "right" ],
909 outs => [ "eflags", "unused", "M" ],
910 am => "source,binary",
912 attr => "bool ins_permuted",
913 init_attr => "attr->data.ins_permuted = ins_permuted;",
917 modified_flags => $status_flags
921 #irn_flags => [ "rematerializable" ],
922 reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
925 attr_type => "ia32_condcode_attr_t",
926 attr => "ia32_condition_code_t condition_code",
927 # The way we handle Setcc with float nodes (potentially) destroys the flags
928 # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
929 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
930 . "\tif (condition_code & ia32_cc_additional_float_cases) {\n"
931 . "\t\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"
932 . "\t\t/* attr->latency = 3; */\n"
940 #irn_flags => [ "rematerializable" ],
941 state => "exc_pinned",
942 reg_req => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
943 ins => [ "base", "index", "mem","eflags" ],
944 attr_type => "ia32_condcode_attr_t",
945 attr => "ia32_condition_code_t condition_code",
946 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
947 emit => 'set%P3 %AM',
954 #irn_flags => [ "rematerializable" ],
955 state => "exc_pinned",
956 # (note: leave the false,true order intact to make it compatible with other
958 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
959 out => [ "in_r4 in_r5", "flags", "none" ] },
960 ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
961 outs => [ "res", "flags", "M" ],
962 am => "source,binary",
963 attr_type => "ia32_condcode_attr_t",
964 attr => "ia32_condition_code_t condition_code",
972 op_flags => [ "cfopcode", "forking" ],
973 reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
975 outs => [ "false", "true" ],
976 attr_type => "ia32_condcode_attr_t",
977 attr => "ia32_condition_code_t condition_code",
979 units => [ "BRANCH" ],
984 op_flags => [ "cfopcode", "forking" ],
985 reg_req => { in => [ "gp", "gp" ] },
986 ins => [ "base", "index" ],
987 out_arity => "variable",
988 attr_type => "ia32_switch_attr_t",
989 attr => "const ir_switch_table *switch_table",
991 units => [ "BRANCH" ],
996 irn_flags => [ "simple_jump" ],
997 op_flags => [ "cfopcode" ],
998 reg_req => { out => [ "none" ] },
1000 units => [ "BRANCH" ],
1006 op_flags => [ "cfopcode", "unknown_jump" ],
1007 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1008 out => [ "none", "flags", "none" ] },
1009 ins => [ "base", "index", "mem", "target" ],
1010 outs => [ "jmp", "flags", "M" ],
1011 am => "source,unary",
1012 emit => 'jmp %*AS3',
1014 units => [ "BRANCH" ],
1019 op_flags => [ "constlike" ],
1020 irn_flags => [ "rematerializable" ],
1021 reg_req => { out => [ "gp" ] },
1022 emit => "movl %I, %D0",
1024 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
1025 attr_type => "ia32_immediate_attr_t",
1031 op_flags => [ "constlike" ],
1032 irn_flags => [ "rematerializable" ],
1033 reg_req => { out => [ "gp" ] },
1040 op_flags => [ "constlike" ],
1041 reg_req => { out => [ "gp" ] },
1045 modified_flags => $status_flags,
1050 op_flags => [ "constlike", "dump_noblock" ],
1051 irn_flags => [ "not_scheduled" ],
1052 reg_req => { out => [ "gp_NOREG:I" ] },
1060 op_flags => [ "constlike", "dump_noblock" ],
1061 irn_flags => [ "not_scheduled" ],
1062 reg_req => { out => [ "fp_NOREG:I" ] },
1066 attr_type => "ia32_x87_attr_t",
1071 op_flags => [ "constlike", "dump_noblock" ],
1072 irn_flags => [ "not_scheduled" ],
1073 reg_req => { out => [ "xmm_NOREG:I" ] },
1081 op_flags => [ "constlike" ],
1082 irn_flags => [ "not_scheduled" ],
1083 reg_req => { out => [ "fpcw" ] },
1087 modified_flags => $fpcw_flags
1091 op_flags => [ "uses_memory" ],
1093 reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw" ] },
1094 ins => [ "base", "index", "mem" ],
1096 emit => "fldcw %AM",
1099 modified_flags => $fpcw_flags
1103 op_flags => [ "uses_memory" ],
1105 reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1106 ins => [ "base", "index", "mem", "fpcw" ],
1108 emit => "fnstcw %AM",
1114 op_flags => [ "uses_memory" ],
1116 reg_req => { in => [ "fp_cw" ], out => [ "none" ] },
1124 # we should not rematrialize this node. It has very strict constraints.
1125 reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] },
1126 ins => [ "val", "clobbered" ],
1135 # Note that we add additional latency values depending on address mode, so a
1136 # lateny of 0 for load is correct
1139 op_flags => [ "uses_memory", "fragile" ],
1140 state => "exc_pinned",
1141 reg_req => { in => [ "gp", "gp", "none" ],
1142 out => [ "gp", "none", "none", "none", "none" ] },
1143 ins => [ "base", "index", "mem" ],
1144 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1146 emit => "mov%#Ml %AM, %D0",
1151 op_flags => [ "uses_memory", "fragile" ],
1152 state => "exc_pinned",
1153 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1154 out => [ "none", "none", "none" ] },
1155 ins => [ "base", "index", "mem", "val" ],
1156 outs => [ "M", "X_regular", "X_except" ],
1157 emit => 'mov%M %#S3, %AM',
1163 op_flags => [ "uses_memory", "fragile" ],
1164 state => "exc_pinned",
1165 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1166 out => ["none", "none", "none" ] },
1167 ins => [ "base", "index", "mem", "val" ],
1168 outs => [ "M", "X_regular", "X_except" ],
1169 emit => 'mov%M %#S3, %AM',
1175 irn_flags => [ "rematerializable" ],
1176 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1177 ins => [ "base", "index" ],
1178 emit => 'leal %AM, %D0',
1182 # lea doesn't modify the flags, but setting this seems advantageous since it
1183 # increases chances that the Lea is transformed back to an Add
1184 modified_flags => 1,
1188 state => "exc_pinned",
1189 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1190 ins => [ "base", "index", "mem", "val", "stack" ],
1191 emit => 'push%M %AS3',
1192 outs => [ "stack", "M" ],
1193 am => "source,unary",
1199 state => "exc_pinned",
1200 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1202 outs => [ "stack" ],
1203 emit => 'pushl %%eax',
1210 state => "exc_pinned",
1211 reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1212 ins => [ "mem", "stack" ],
1213 outs => [ "res", "M", "unused", "stack" ],
1214 emit => 'pop%M %D0',
1215 latency => 3, # Pop is more expensive than Push on Athlon
1220 state => "exc_pinned",
1221 reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1222 ins => [ "mem", "stack" ],
1223 outs => [ "res", "M", "unused", "stack" ],
1224 emit => 'pop%M %D0',
1225 latency => 3, # Pop is more expensive than Push on Athlon
1230 state => "exc_pinned",
1231 reg_req => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1234 emit => 'movl %S0, %D0',
1241 state => "exc_pinned",
1242 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1243 ins => [ "base", "index", "mem", "stack" ],
1244 outs => [ "unused0", "M", "unused1", "stack" ],
1245 emit => 'pop%M %AM',
1246 latency => 3, # Pop is more expensive than Push on Athlon
1251 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1253 outs => [ "frame", "stack", "M" ],
1259 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1261 outs => [ "frame", "stack" ],
1264 state => "exc_pinned",
1269 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1270 ins => [ "base", "index", "mem", "stack", "size" ],
1271 am => "source,binary",
1274 outs => [ "stack", "M" ],
1276 modified_flags => $status_flags
1281 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1282 ins => [ "base", "index", "mem", "stack", "size" ],
1283 am => "source,binary",
1284 emit => "subl %B\n".
1287 outs => [ "stack", "addr", "M" ],
1289 modified_flags => $status_flags
1293 op_flags => [ "keep" ],
1301 irn_flags => [ "rematerializable" ],
1302 reg_req => { out => [ "gp" ] },
1304 emit => "movl %%gs:0, %D0",
1310 # BT supports source address mode, but this is unused yet
1313 irn_flags => [ "rematerializable" ],
1314 state => "exc_pinned",
1315 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1316 ins => [ "left", "right" ],
1317 emit => 'bt%M %S1, %S0',
1320 mode => $mode_flags,
1321 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1325 irn_flags => [ "rematerializable" ],
1326 state => "exc_pinned",
1327 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1328 out => [ "gp", "flags", "none" ] },
1329 ins => [ "base", "index", "mem", "operand" ],
1330 outs => [ "res", "flags", "M" ],
1331 am => "source,binary",
1332 emit => 'bsf%M %AS3, %D0',
1336 modified_flags => $status_flags
1340 irn_flags => [ "rematerializable" ],
1341 state => "exc_pinned",
1342 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1343 out => [ "gp", "flags", "none" ] },
1344 ins => [ "base", "index", "mem", "operand" ],
1345 outs => [ "res", "flags", "M" ],
1346 am => "source,binary",
1347 emit => 'bsr%M %AS3, %D0',
1351 modified_flags => $status_flags
1355 # SSE4.2 or SSE4a popcnt instruction
1358 irn_flags => [ "rematerializable" ],
1359 state => "exc_pinned",
1360 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1361 out => [ "gp", "flags", "none" ] },
1362 ins => [ "base", "index", "mem", "operand" ],
1363 outs => [ "res", "flags", "M" ],
1364 am => "source,binary",
1365 emit => 'popcnt%M %AS3, %D0',
1369 modified_flags => $status_flags
1373 op_flags => [ "uses_memory", "fragile" ],
1374 state => "exc_pinned",
1376 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1377 out => [ "esp:I|S", "fpcw", "none", "eax", "ecx", "edx", "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "none", "none" ]
1379 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1380 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" ],
1381 emit => "call %*AS3",
1382 attr_type => "ia32_call_attr_t",
1383 attr => "unsigned pop, ir_type *call_tp",
1384 am => "source,unary",
1385 units => [ "BRANCH" ],
1386 latency => 4, # random number
1387 modified_flags => $status_flags
1391 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1393 # PS: try gcc __builtin_frame_address(100000) :-)
1396 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1397 ins => [ "frame", "cnt", "tmp" ],
1399 latency => 4, # random number
1400 attr_type => "ia32_climbframe_attr_t",
1401 attr => "unsigned count",
1410 irn_flags => [ "rematerializable" ],
1411 reg_req => { in => [ "gp" ],
1412 out => [ "in_r1" ] },
1414 emit => 'bswap%M %S0',
1422 # bswap16, use xchg here
1425 irn_flags => [ "rematerializable" ],
1426 reg_req => { in => [ "eax ebx ecx edx" ],
1427 out => [ "in_r1" ] },
1428 emit => 'xchg %<S0, %>S0',
1440 reg_req => { in => [ "none" ], out => [ "none" ] },
1449 # Undefined Instruction on ALL x86 CPU's
1453 reg_req => { in => [ "none" ], out => [ "none" ] },
1465 irn_flags => [ "rematerializable" ],
1467 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1468 ins => [ "port", "value", "mem" ],
1469 emit => 'out%M %^S0, %#S1',
1473 modified_flags => $status_flags
1480 irn_flags => [ "rematerializable" ],
1482 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1483 ins => [ "port", "mem" ],
1484 outs => [ "res", "M" ],
1485 emit => 'in%M %#D0, %^S0',
1489 modified_flags => $status_flags
1493 # Intel style prefetching
1496 op_flags => [ "uses_memory" ],
1497 state => "exc_pinned",
1498 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1499 ins => [ "base", "index", "mem" ],
1502 emit => "prefetcht0 %AM",
1507 op_flags => [ "uses_memory" ],
1508 state => "exc_pinned",
1509 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1510 ins => [ "base", "index", "mem" ],
1513 emit => "prefetcht1 %AM",
1518 op_flags => [ "uses_memory" ],
1519 state => "exc_pinned",
1520 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1521 ins => [ "base", "index", "mem" ],
1524 emit => "prefetcht2 %AM",
1529 op_flags => [ "uses_memory" ],
1530 state => "exc_pinned",
1531 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1532 ins => [ "base", "index", "mem" ],
1535 emit => "prefetchnta %AM",
1540 # 3DNow! prefetch instructions
1543 op_flags => [ "uses_memory" ],
1544 state => "exc_pinned",
1545 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1546 ins => [ "base", "index", "mem" ],
1549 emit => "prefetch %AM",
1554 op_flags => [ "uses_memory" ],
1555 state => "exc_pinned",
1556 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1557 ins => [ "base", "index", "mem" ],
1560 emit => "prefetchw %AM",
1566 irn_flags => [ "rematerializable" ],
1567 reg_req => { out => [ "xmm" ] },
1568 emit => 'xorp%FX %D0, %D0',
1575 op_flags => [ "constlike" ],
1576 irn_flags => [ "rematerializable" ],
1577 reg_req => { out => [ "xmm" ] },
1584 irn_flags => [ "rematerializable" ],
1585 reg_req => { out => [ "xmm" ] },
1586 emit => 'pxor %D0, %D0',
1592 # produces all 1 bits
1594 irn_flags => [ "rematerializable" ],
1595 reg_req => { out => [ "xmm" ] },
1596 emit => 'pcmpeqb %D0, %D0',
1602 # integer shift left, dword
1604 irn_flags => [ "rematerializable" ],
1605 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1606 emit => 'pslld %#S1, %D0',
1612 # integer shift left, qword
1614 irn_flags => [ "rematerializable" ],
1615 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1616 emit => 'psllq %#S1, %D0',
1622 # integer shift right, dword
1624 irn_flags => [ "rematerializable" ],
1625 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1626 emit => 'psrld %#S1, %D0',
1632 # mov from integer to SSE register
1634 irn_flags => [ "rematerializable" ],
1635 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1636 emit => 'movd %S0, %D0',
1643 irn_flags => [ "rematerializable" ],
1644 state => "exc_pinned",
1645 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1646 out => [ "in_r4 in_r5", "flags", "none" ] },
1647 ins => [ "base", "index", "mem", "left", "right" ],
1648 outs => [ "res", "flags", "M" ],
1649 am => "source,binary",
1650 emit => 'adds%FX %B',
1657 irn_flags => [ "rematerializable" ],
1658 state => "exc_pinned",
1659 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1660 out => [ "in_r4 in_r5", "flags", "none" ] },
1661 ins => [ "base", "index", "mem", "left", "right" ],
1662 outs => [ "res", "flags", "M" ],
1663 am => "source,binary",
1664 emit => 'muls%FX %B',
1671 irn_flags => [ "rematerializable" ],
1672 state => "exc_pinned",
1673 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1674 out => [ "in_r4 in_r5", "flags", "none" ] },
1675 ins => [ "base", "index", "mem", "left", "right" ],
1676 outs => [ "res", "flags", "M" ],
1677 am => "source,binary",
1678 emit => 'maxs%FX %B',
1685 irn_flags => [ "rematerializable" ],
1686 state => "exc_pinned",
1687 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1688 out => [ "in_r4 in_r5", "flags", "none" ] },
1689 ins => [ "base", "index", "mem", "left", "right" ],
1690 outs => [ "res", "flags", "M" ],
1691 am => "source,binary",
1692 emit => 'mins%FX %B',
1699 irn_flags => [ "rematerializable" ],
1700 state => "exc_pinned",
1701 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1702 out => [ "in_r4 in_r5", "flags", "none" ] },
1703 ins => [ "base", "index", "mem", "left", "right" ],
1704 outs => [ "res", "flags", "M" ],
1705 am => "source,binary",
1706 emit => 'andp%FX %B',
1713 irn_flags => [ "rematerializable" ],
1714 state => "exc_pinned",
1715 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1716 out => [ "in_r4 in_r5", "flags", "none" ] },
1717 ins => [ "base", "index", "mem", "left", "right" ],
1718 outs => [ "res", "flags", "M" ],
1719 am => "source,binary",
1720 emit => 'orp%FX %B',
1727 irn_flags => [ "rematerializable" ],
1728 state => "exc_pinned",
1729 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1730 out => [ "in_r4 in_r5", "flags", "none" ] },
1731 ins => [ "base", "index", "mem", "left", "right" ],
1732 outs => [ "res", "flags", "M" ],
1733 am => "source,binary",
1734 emit => 'xorp%FX %B',
1741 irn_flags => [ "rematerializable" ],
1742 state => "exc_pinned",
1743 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1744 out => [ "in_r4 !in_r5", "flags", "none" ] },
1745 ins => [ "base", "index", "mem", "left", "right" ],
1746 outs => [ "res", "flags", "M" ],
1747 am => "source,binary",
1748 emit => 'andnp%FX %B',
1755 irn_flags => [ "rematerializable" ],
1756 state => "exc_pinned",
1757 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1758 out => [ "in_r4", "flags", "none" ] },
1759 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1760 outs => [ "res", "flags", "M" ],
1761 am => "source,binary",
1762 emit => 'subs%FX %B',
1769 irn_flags => [ "rematerializable" ],
1770 state => "exc_pinned",
1771 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1772 out => [ "in_r4 !in_r5", "flags", "none" ] },
1773 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1774 outs => [ "res", "flags", "M" ],
1775 am => "source,binary",
1776 emit => 'divs%FX %B',
1782 irn_flags => [ "rematerializable" ],
1783 state => "exc_pinned",
1784 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1785 out => [ "eflags" ] },
1786 ins => [ "base", "index", "mem", "left", "right" ],
1787 outs => [ "flags" ],
1788 am => "source,binary",
1789 attr => "bool ins_permuted",
1790 init_attr => "attr->data.ins_permuted = ins_permuted;",
1791 emit => 'ucomis%FX %B',
1794 mode => $mode_flags,
1795 modified_flags => 1,
1799 op_flags => [ "uses_memory", "fragile" ],
1800 state => "exc_pinned",
1801 reg_req => { in => [ "gp", "gp", "none" ],
1802 out => [ "xmm", "none", "none", "none", "none" ] },
1803 ins => [ "base", "index", "mem" ],
1804 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1805 emit => 'movs%FX %AM, %D0',
1806 attr => "ir_mode *load_mode",
1807 init_attr => "attr->ls_mode = load_mode;",
1813 op_flags => [ "uses_memory", "fragile" ],
1814 state => "exc_pinned",
1815 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1816 out => [ "none", "none", "none" ] },
1817 ins => [ "base", "index", "mem", "val" ],
1818 outs => [ "M", "X_regular", "X_except" ],
1819 emit => 'movs%FX %S3, %AM',
1825 op_flags => [ "uses_memory", "fragile" ],
1826 state => "exc_pinned",
1827 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1828 out => [ "none", "none", "none" ] },
1829 ins => [ "base", "index", "mem", "val" ],
1830 outs => [ "M", "X_regular", "X_except" ],
1831 emit => 'movs%FX %S3, %AM',
1837 state => "exc_pinned",
1838 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1839 ins => [ "base", "index", "mem", "val" ],
1840 am => "source,unary",
1841 emit => 'cvtsi2ss %AS3, %D0',
1848 state => "exc_pinned",
1849 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1850 ins => [ "base", "index", "mem", "val" ],
1851 am => "source,unary",
1852 emit => 'cvtsi2sd %AS3, %D0',
1860 ins => [ "val_high", "val_low" ],
1862 dump_func => "NULL",
1867 outs => [ "res_high", "res_low" ],
1869 dump_func => "NULL",
1873 op_flags => [ "uses_memory", "fragile" ],
1875 reg_req => { in => [ "edi", "esi", "ecx", "none" ],
1876 out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1877 ins => [ "dest", "source", "count", "mem" ],
1878 outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1879 attr_type => "ia32_copyb_attr_t",
1880 attr => "unsigned size",
1883 # we don't care about this flag, so no need to mark this node
1884 # modified_flags => [ "DF" ]
1888 op_flags => [ "uses_memory", "fragile" ],
1890 reg_req => { in => [ "edi", "esi", "none" ],
1891 out => [ "edi", "esi", "none", "none", "none" ] },
1892 ins => [ "dest", "source", "mem" ],
1893 outs => [ "dest", "source", "M", "X_regular", "X_except" ],
1894 attr_type => "ia32_copyb_attr_t",
1895 attr => "unsigned size",
1898 # we don't care about this flag, so no need to mark this node
1899 # modified_flags => [ "DF" ]
1903 state => "exc_pinned",
1904 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1914 op_flags => [ "uses_memory", "fragile" ],
1915 state => "exc_pinned",
1916 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1917 out => [ "gp", "none", "none", "none", "none" ] },
1918 ins => [ "base", "index", "mem", "val" ],
1919 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1920 emit => "mov%#Ml %#AS3, %D0",
1921 am => "source,unary",
1924 attr => "ir_mode *smaller_mode",
1925 init_attr => "attr->ls_mode = smaller_mode;",
1930 op_flags => [ "uses_memory", "fragile" ],
1931 state => "exc_pinned",
1932 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1933 out => [ "gp", "none", "none", "none", "none" ] },
1934 ins => [ "base", "index", "mem", "val" ],
1935 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1936 emit => "mov%#Ml %#AS3, %D0",
1937 am => "source,unary",
1940 attr => "ir_mode *smaller_mode",
1941 init_attr => "attr->ls_mode = smaller_mode;",
1946 state => "exc_pinned",
1947 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1948 ins => [ "base", "index", "mem", "val" ],
1949 am => "source,unary",
1956 state => "exc_pinned",
1957 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1958 ins => [ "base", "index", "mem", "val" ],
1959 am => "source,unary",
1966 state => "exc_pinned",
1967 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1968 ins => [ "base", "index", "mem", "val" ],
1969 am => "source,unary",
1975 # rematerialisation disabled for all float nodes for now, because the fpcw
1976 # handler runs before spilling and we might end up with wrong fpcw then
1979 # irn_flags => [ "rematerializable" ],
1980 state => "exc_pinned",
1981 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1982 out => [ "fp", "none", "none" ] },
1983 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1984 outs => [ "res", "dummy", "M" ],
1985 emit => 'fadd%FP%FM %AF',
1986 am => "source,binary",
1990 attr_type => "ia32_x87_attr_t",
1994 # irn_flags => [ "rematerializable" ],
1995 state => "exc_pinned",
1996 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1997 out => [ "fp", "none", "none" ] },
1998 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1999 outs => [ "res", "dummy", "M" ],
2000 emit => 'fmul%FP%FM %AF',
2001 am => "source,binary",
2005 attr_type => "ia32_x87_attr_t",
2009 # irn_flags => [ "rematerializable" ],
2010 state => "exc_pinned",
2011 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2012 out => [ "fp", "none", "none" ] },
2013 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2014 outs => [ "res", "dummy", "M" ],
2015 emit => 'fsub%FR%FP%FM %AF',
2016 am => "source,binary",
2020 attr_type => "ia32_x87_attr_t",
2024 state => "exc_pinned",
2025 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2026 out => [ "fp", "none", "none" ] },
2027 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2028 outs => [ "res", "dummy", "M" ],
2029 emit => 'fdiv%FR%FP%FM %AF',
2030 am => "source,binary",
2033 attr_type => "ia32_x87_attr_t",
2037 reg_req => { in => [ "fp", "fp", "fpcw" ], out => [ "fp" ] },
2038 ins => [ "left", "right", "fpcw" ],
2043 attr_type => "ia32_x87_attr_t",
2047 irn_flags => [ "rematerializable" ],
2048 reg_req => { in => [ "fp"], out => [ "fp" ] },
2054 attr_type => "ia32_x87_attr_t",
2058 irn_flags => [ "rematerializable" ],
2059 reg_req => { in => [ "fp"], out => [ "fp" ] },
2065 attr_type => "ia32_x87_attr_t",
2069 irn_flags => [ "rematerializable" ],
2070 op_flags => [ "uses_memory", "fragile" ],
2071 state => "exc_pinned",
2072 reg_req => { in => [ "gp", "gp", "none" ],
2073 out => [ "fp", "none", "none", "none", "none" ] },
2074 ins => [ "base", "index", "mem" ],
2075 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
2076 emit => 'fld%FM %AM',
2077 attr => "ir_mode *load_mode",
2078 init_attr => "attr->attr.ls_mode = load_mode;",
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", "fp" ],
2089 out => [ "none", "none", "none" ] },
2090 ins => [ "base", "index", "mem", "val" ],
2091 outs => [ "M", "X_regular", "X_except" ],
2092 emit => 'fst%FP%FM %AM',
2093 attr => "ir_mode *store_mode",
2094 init_attr => "attr->attr.ls_mode = store_mode;",
2097 attr_type => "ia32_x87_attr_t",
2101 state => "exc_pinned",
2102 reg_req => { in => [ "gp", "gp", "none" ],
2103 out => [ "fp", "none", "none" ] },
2104 outs => [ "res", "unused", "M" ],
2105 ins => [ "base", "index", "mem" ],
2106 emit => 'fild%FM %AM',
2109 attr_type => "ia32_x87_attr_t",
2113 op_flags => [ "uses_memory", "fragile" ],
2114 state => "exc_pinned",
2115 reg_req => { in => [ "gp", "gp", "none", "fp", "fpcw" ],
2116 out => [ "none", "none", "none", "none" ] },
2117 ins => [ "base", "index", "mem", "val", "fpcw" ],
2118 outs => [ "dummy", "M", "X_regular", "X_except" ],
2119 emit => 'fist%FP%FM %AM',
2122 attr_type => "ia32_x87_attr_t",
2125 # SSE3 fisttp instruction
2127 op_flags => [ "uses_memory", "fragile" ],
2128 state => "exc_pinned",
2129 reg_req => { in => [ "gp", "gp", "none", "fp" ],
2130 out => [ "in_r4", "none", "none", "none" ]},
2131 ins => [ "base", "index", "mem", "val" ],
2132 outs => [ "res", "M", "X_regular", "X_except" ],
2133 emit => 'fisttp%FM %AM',
2136 attr_type => "ia32_x87_attr_t",
2140 irn_flags => [ "rematerializable" ],
2141 reg_req => { out => [ "fp" ] },
2147 attr_type => "ia32_x87_attr_t",
2151 irn_flags => [ "rematerializable" ],
2152 reg_req => { out => [ "fp" ] },
2158 attr_type => "ia32_x87_attr_t",
2162 irn_flags => [ "rematerializable" ],
2163 reg_req => { out => [ "fp" ] },
2169 attr_type => "ia32_x87_attr_t",
2173 irn_flags => [ "rematerializable" ],
2174 reg_req => { out => [ "fp" ] },
2180 attr_type => "ia32_x87_attr_t",
2184 irn_flags => [ "rematerializable" ],
2185 reg_req => { out => [ "fp" ] },
2191 attr_type => "ia32_x87_attr_t",
2195 irn_flags => [ "rematerializable" ],
2196 reg_req => { out => [ "fp" ] },
2202 attr_type => "ia32_x87_attr_t",
2206 irn_flags => [ "rematerializable" ],
2207 reg_req => { out => [ "fp" ] },
2213 attr_type => "ia32_x87_attr_t",
2217 # we can't allow to rematerialize this node so we don't
2218 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2219 # irn_flags => [ "rematerializable" ],
2220 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2221 ins => [ "left", "right" ],
2222 outs => [ "flags" ],
2223 emit => "fucom%FP %F0\n".
2225 attr => "bool ins_permuted",
2226 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2229 attr_type => "ia32_x87_attr_t",
2234 # we can't allow to rematerialize this node so we don't
2235 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2236 # irn_flags => [ "rematerializable" ],
2237 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2238 ins => [ "left", "right" ],
2239 outs => [ "flags" ],
2240 emit => "fucompp\n".
2242 attr => "bool ins_permuted",
2243 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2246 attr_type => "ia32_x87_attr_t",
2251 irn_flags => [ "rematerializable" ],
2252 reg_req => { in => [ "fp", "fp" ], out => [ "eflags" ] },
2253 ins => [ "left", "right" ],
2254 outs => [ "flags" ],
2255 emit => 'fucom%FPi %F0',
2256 attr => "bool ins_permuted",
2257 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2260 attr_type => "ia32_x87_attr_t",
2265 # irn_flags => [ "rematerializable" ],
2266 reg_req => { in => [ "fp" ], out => [ "eax" ] },
2268 outs => [ "flags" ],
2271 attr => "bool ins_permuted",
2272 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2275 attr_type => "ia32_x87_attr_t",
2280 irn_flags => [ "rematerializable" ],
2281 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2283 outs => [ "flags" ],
2287 mode => $mode_flags,
2291 # Note that it is NEVER allowed to do CSE on these nodes
2292 # Moreover, note the virtual register requierements!
2295 op_flags => [ "keep" ],
2296 reg_req => { out => [ "none" ] },
2297 cmp_attr => "return 1;",
2299 attr_type => "ia32_x87_attr_t",
2305 op_flags => [ "keep" ],
2306 reg_req => { out => [ "none" ] },
2307 cmp_attr => "return 1;",
2309 attr_type => "ia32_x87_attr_t",
2315 reg_req => { in => [ "fp"], out => [ "fp" ] },
2316 cmp_attr => "return 1;",
2318 attr_type => "ia32_x87_attr_t",
2323 op_flags => [ "keep" ],
2324 reg_req => { out => [ "none" ] },
2325 cmp_attr => "return 1;",
2327 attr_type => "ia32_x87_attr_t",
2333 op_flags => [ "keep" ],
2334 reg_req => { out => [ "none" ] },
2335 cmp_attr => "return 1;",
2336 emit => 'ffreep %F0',
2337 attr_type => "ia32_x87_attr_t",
2343 op_flags => [ "keep" ],
2344 reg_req => { out => [ "none" ] },
2345 cmp_attr => "return 1;",
2347 attr_type => "ia32_x87_attr_t",
2353 op_flags => [ "keep" ],
2354 reg_req => { out => [ "none" ] },
2355 cmp_attr => "return 1;",
2357 attr_type => "ia32_x87_attr_t",
2362 # Spilling and reloading of SSE registers, hardcoded, not generated #
2365 op_flags => [ "uses_memory", "fragile" ],
2366 state => "exc_pinned",
2367 reg_req => { in => [ "gp", "gp", "none" ],
2368 out => [ "xmm", "none", "none", "none" ] },
2369 emit => 'movdqu %D0, %AM',
2370 ins => [ "base", "index", "mem" ],
2371 outs => [ "res", "M", "X_regular", "X_except" ],
2377 op_flags => [ "uses_memory", "fragile" ],
2378 state => "exc_pinned",
2379 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
2380 out => [ "none", "none", "none" ] },
2381 ins => [ "base", "index", "mem", "val" ],
2382 outs => [ "M", "X_regular", "X_except" ],
2383 emit => 'movdqu %B',
2390 # Transform some attributes
2391 foreach my $op (keys(%nodes)) {
2392 my $node = $nodes{$op};
2393 my $op_attr_init = $node->{op_attr_init};
2395 if(defined($op_attr_init)) {
2396 $op_attr_init .= "\n\t";
2401 if(!defined($node->{latency})) {
2403 $node->{latency} = 0;
2405 die("Latency missing for op $op");
2408 $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2410 $node->{op_attr_init} = $op_attr_init;