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_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" ] },
1061 op_flags => [ "constlike", "dump_noblock" ],
1062 irn_flags => [ "not_scheduled" ],
1063 reg_req => { out => [ "fp_NOREG:I" ] },
1068 attr_type => "ia32_x87_attr_t",
1073 op_flags => [ "constlike", "dump_noblock" ],
1074 irn_flags => [ "not_scheduled" ],
1075 reg_req => { out => [ "xmm_NOREG:I" ] },
1084 op_flags => [ "constlike" ],
1085 irn_flags => [ "not_scheduled" ],
1086 reg_req => { out => [ "fpcw:I" ] },
1090 modified_flags => $fpcw_flags
1094 op_flags => [ "uses_memory" ],
1096 reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] },
1097 ins => [ "base", "index", "mem" ],
1099 emit => "fldcw %AM",
1102 modified_flags => $fpcw_flags
1106 op_flags => [ "uses_memory" ],
1108 reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1109 ins => [ "base", "index", "mem", "fpcw" ],
1111 emit => "fnstcw %AM",
1117 op_flags => [ "uses_memory" ],
1119 reg_req => { in => [ "fp_cw" ], out => [ "none" ] },
1127 # we should not rematrialize this node. It has very strict constraints.
1128 reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] },
1129 ins => [ "val", "clobbered" ],
1138 # Note that we add additional latency values depending on address mode, so a
1139 # lateny of 0 for load is correct
1142 op_flags => [ "uses_memory", "fragile" ],
1143 state => "exc_pinned",
1144 reg_req => { in => [ "gp", "gp", "none" ],
1145 out => [ "gp", "none", "none", "none", "none" ] },
1146 ins => [ "base", "index", "mem" ],
1147 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1149 emit => "mov%#Ml %AM, %D0",
1154 op_flags => [ "uses_memory", "fragile" ],
1155 state => "exc_pinned",
1156 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1157 out => [ "none", "none", "none" ] },
1158 ins => [ "base", "index", "mem", "val" ],
1159 outs => [ "M", "X_regular", "X_except" ],
1160 emit => 'mov%M %#S3, %AM',
1166 op_flags => [ "uses_memory", "fragile" ],
1167 state => "exc_pinned",
1168 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1169 out => ["none", "none", "none" ] },
1170 ins => [ "base", "index", "mem", "val" ],
1171 outs => [ "M", "X_regular", "X_except" ],
1172 emit => 'mov%M %#S3, %AM',
1178 irn_flags => [ "rematerializable" ],
1179 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1180 ins => [ "base", "index" ],
1181 emit => 'leal %AM, %D0',
1185 # lea doesn't modify the flags, but setting this seems advantageous since it
1186 # increases chances that the Lea is transformed back to an Add
1187 modified_flags => 1,
1191 state => "exc_pinned",
1192 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1193 ins => [ "base", "index", "mem", "val", "stack" ],
1194 emit => 'push%M %AS3',
1195 outs => [ "stack", "M" ],
1196 am => "source,unary",
1202 state => "exc_pinned",
1203 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1205 outs => [ "stack" ],
1206 emit => 'pushl %%eax',
1213 state => "exc_pinned",
1214 reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1215 ins => [ "mem", "stack" ],
1216 outs => [ "res", "M", "unused", "stack" ],
1217 emit => 'pop%M %D0',
1218 latency => 3, # Pop is more expensive than Push on Athlon
1223 state => "exc_pinned",
1224 reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1225 ins => [ "mem", "stack" ],
1226 outs => [ "res", "M", "unused", "stack" ],
1227 emit => 'pop%M %D0',
1228 latency => 3, # Pop is more expensive than Push on Athlon
1233 state => "exc_pinned",
1234 reg_req => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1237 emit => 'movl %S0, %D0',
1244 state => "exc_pinned",
1245 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1246 ins => [ "base", "index", "mem", "stack" ],
1247 outs => [ "unused0", "M", "unused1", "stack" ],
1248 emit => 'pop%M %AM',
1249 latency => 3, # Pop is more expensive than Push on Athlon
1254 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1256 outs => [ "frame", "stack", "M" ],
1262 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1264 outs => [ "frame", "stack" ],
1267 state => "exc_pinned",
1272 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1273 ins => [ "base", "index", "mem", "stack", "size" ],
1274 am => "source,binary",
1277 outs => [ "stack", "M" ],
1279 modified_flags => $status_flags
1284 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1285 ins => [ "base", "index", "mem", "stack", "size" ],
1286 am => "source,binary",
1287 emit => "subl %B\n".
1290 outs => [ "stack", "addr", "M" ],
1292 modified_flags => $status_flags
1296 op_flags => [ "keep" ],
1304 irn_flags => [ "rematerializable" ],
1305 reg_req => { out => [ "gp" ] },
1307 emit => "movl %%gs:0, %D0",
1313 # BT supports source address mode, but this is unused yet
1316 irn_flags => [ "rematerializable" ],
1317 state => "exc_pinned",
1318 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1319 ins => [ "left", "right" ],
1320 emit => 'bt%M %S1, %S0',
1323 mode => $mode_flags,
1324 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1328 irn_flags => [ "rematerializable" ],
1329 state => "exc_pinned",
1330 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1331 out => [ "gp", "flags", "none" ] },
1332 ins => [ "base", "index", "mem", "operand" ],
1333 outs => [ "res", "flags", "M" ],
1334 am => "source,binary",
1335 emit => 'bsf%M %AS3, %D0',
1339 modified_flags => $status_flags
1343 irn_flags => [ "rematerializable" ],
1344 state => "exc_pinned",
1345 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1346 out => [ "gp", "flags", "none" ] },
1347 ins => [ "base", "index", "mem", "operand" ],
1348 outs => [ "res", "flags", "M" ],
1349 am => "source,binary",
1350 emit => 'bsr%M %AS3, %D0',
1354 modified_flags => $status_flags
1358 # SSE4.2 or SSE4a popcnt instruction
1361 irn_flags => [ "rematerializable" ],
1362 state => "exc_pinned",
1363 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1364 out => [ "gp", "flags", "none" ] },
1365 ins => [ "base", "index", "mem", "operand" ],
1366 outs => [ "res", "flags", "M" ],
1367 am => "source,binary",
1368 emit => 'popcnt%M %AS3, %D0',
1372 modified_flags => $status_flags
1376 op_flags => [ "uses_memory", "fragile" ],
1377 state => "exc_pinned",
1379 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1380 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" ]
1382 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1383 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" ],
1384 emit => "call %*AS3",
1385 attr_type => "ia32_call_attr_t",
1386 attr => "unsigned pop, ir_type *call_tp",
1387 am => "source,unary",
1388 units => [ "BRANCH" ],
1389 latency => 4, # random number
1390 modified_flags => $status_flags
1394 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1396 # PS: try gcc __builtin_frame_address(100000) :-)
1399 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1400 ins => [ "frame", "cnt", "tmp" ],
1402 latency => 4, # random number
1403 attr_type => "ia32_climbframe_attr_t",
1404 attr => "unsigned count",
1413 irn_flags => [ "rematerializable" ],
1414 reg_req => { in => [ "gp" ],
1415 out => [ "in_r1" ] },
1417 emit => 'bswap%M %S0',
1425 # bswap16, use xchg here
1428 irn_flags => [ "rematerializable" ],
1429 reg_req => { in => [ "eax ebx ecx edx" ],
1430 out => [ "in_r1" ] },
1431 emit => 'xchg %<S0, %>S0',
1443 reg_req => { in => [ "none" ], out => [ "none" ] },
1452 # Undefined Instruction on ALL x86 CPU's
1456 reg_req => { in => [ "none" ], out => [ "none" ] },
1468 irn_flags => [ "rematerializable" ],
1470 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1471 ins => [ "port", "value", "mem" ],
1472 emit => 'out%M %^S0, %#S1',
1476 modified_flags => $status_flags
1483 irn_flags => [ "rematerializable" ],
1485 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1486 ins => [ "port", "mem" ],
1487 outs => [ "res", "M" ],
1488 emit => 'in%M %#D0, %^S0',
1492 modified_flags => $status_flags
1496 # Intel style prefetching
1499 op_flags => [ "uses_memory" ],
1500 state => "exc_pinned",
1501 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1502 ins => [ "base", "index", "mem" ],
1505 emit => "prefetcht0 %AM",
1510 op_flags => [ "uses_memory" ],
1511 state => "exc_pinned",
1512 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1513 ins => [ "base", "index", "mem" ],
1516 emit => "prefetcht1 %AM",
1521 op_flags => [ "uses_memory" ],
1522 state => "exc_pinned",
1523 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1524 ins => [ "base", "index", "mem" ],
1527 emit => "prefetcht2 %AM",
1532 op_flags => [ "uses_memory" ],
1533 state => "exc_pinned",
1534 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1535 ins => [ "base", "index", "mem" ],
1538 emit => "prefetchnta %AM",
1543 # 3DNow! prefetch instructions
1546 op_flags => [ "uses_memory" ],
1547 state => "exc_pinned",
1548 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1549 ins => [ "base", "index", "mem" ],
1552 emit => "prefetch %AM",
1557 op_flags => [ "uses_memory" ],
1558 state => "exc_pinned",
1559 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1560 ins => [ "base", "index", "mem" ],
1563 emit => "prefetchw %AM",
1569 irn_flags => [ "rematerializable" ],
1570 reg_req => { out => [ "xmm" ] },
1571 emit => 'xorp%FX %D0, %D0',
1578 op_flags => [ "constlike" ],
1579 irn_flags => [ "rematerializable" ],
1580 reg_req => { out => [ "xmm" ] },
1587 irn_flags => [ "rematerializable" ],
1588 reg_req => { out => [ "xmm" ] },
1589 emit => 'pxor %D0, %D0',
1595 # produces all 1 bits
1597 irn_flags => [ "rematerializable" ],
1598 reg_req => { out => [ "xmm" ] },
1599 emit => 'pcmpeqb %D0, %D0',
1605 # integer shift left, dword
1607 irn_flags => [ "rematerializable" ],
1608 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1609 emit => 'pslld %#S1, %D0',
1615 # integer shift left, qword
1617 irn_flags => [ "rematerializable" ],
1618 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1619 emit => 'psllq %#S1, %D0',
1625 # integer shift right, dword
1627 irn_flags => [ "rematerializable" ],
1628 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1629 emit => 'psrld %#S1, %D0',
1635 # mov from integer to SSE register
1637 irn_flags => [ "rematerializable" ],
1638 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1639 emit => 'movd %S0, %D0',
1646 irn_flags => [ "rematerializable" ],
1647 state => "exc_pinned",
1648 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1649 out => [ "in_r4 in_r5", "flags", "none" ] },
1650 ins => [ "base", "index", "mem", "left", "right" ],
1651 outs => [ "res", "flags", "M" ],
1652 am => "source,binary",
1653 emit => 'adds%FX %B',
1660 irn_flags => [ "rematerializable" ],
1661 state => "exc_pinned",
1662 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1663 out => [ "in_r4 in_r5", "flags", "none" ] },
1664 ins => [ "base", "index", "mem", "left", "right" ],
1665 outs => [ "res", "flags", "M" ],
1666 am => "source,binary",
1667 emit => 'muls%FX %B',
1674 irn_flags => [ "rematerializable" ],
1675 state => "exc_pinned",
1676 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1677 out => [ "in_r4 in_r5", "flags", "none" ] },
1678 ins => [ "base", "index", "mem", "left", "right" ],
1679 outs => [ "res", "flags", "M" ],
1680 am => "source,binary",
1681 emit => 'maxs%FX %B',
1688 irn_flags => [ "rematerializable" ],
1689 state => "exc_pinned",
1690 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1691 out => [ "in_r4 in_r5", "flags", "none" ] },
1692 ins => [ "base", "index", "mem", "left", "right" ],
1693 outs => [ "res", "flags", "M" ],
1694 am => "source,binary",
1695 emit => 'mins%FX %B',
1702 irn_flags => [ "rematerializable" ],
1703 state => "exc_pinned",
1704 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1705 out => [ "in_r4 in_r5", "flags", "none" ] },
1706 ins => [ "base", "index", "mem", "left", "right" ],
1707 outs => [ "res", "flags", "M" ],
1708 am => "source,binary",
1709 emit => 'andp%FX %B',
1716 irn_flags => [ "rematerializable" ],
1717 state => "exc_pinned",
1718 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1719 out => [ "in_r4 in_r5", "flags", "none" ] },
1720 ins => [ "base", "index", "mem", "left", "right" ],
1721 outs => [ "res", "flags", "M" ],
1722 am => "source,binary",
1723 emit => 'orp%FX %B',
1730 irn_flags => [ "rematerializable" ],
1731 state => "exc_pinned",
1732 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1733 out => [ "in_r4 in_r5", "flags", "none" ] },
1734 ins => [ "base", "index", "mem", "left", "right" ],
1735 outs => [ "res", "flags", "M" ],
1736 am => "source,binary",
1737 emit => 'xorp%FX %B',
1744 irn_flags => [ "rematerializable" ],
1745 state => "exc_pinned",
1746 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1747 out => [ "in_r4 !in_r5", "flags", "none" ] },
1748 ins => [ "base", "index", "mem", "left", "right" ],
1749 outs => [ "res", "flags", "M" ],
1750 am => "source,binary",
1751 emit => 'andnp%FX %B',
1758 irn_flags => [ "rematerializable" ],
1759 state => "exc_pinned",
1760 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1761 out => [ "in_r4", "flags", "none" ] },
1762 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1763 outs => [ "res", "flags", "M" ],
1764 am => "source,binary",
1765 emit => 'subs%FX %B',
1772 irn_flags => [ "rematerializable" ],
1773 state => "exc_pinned",
1774 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1775 out => [ "in_r4 !in_r5", "flags", "none" ] },
1776 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1777 outs => [ "res", "flags", "M" ],
1778 am => "source,binary",
1779 emit => 'divs%FX %B',
1785 irn_flags => [ "rematerializable" ],
1786 state => "exc_pinned",
1787 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1788 out => [ "eflags" ] },
1789 ins => [ "base", "index", "mem", "left", "right" ],
1790 outs => [ "flags" ],
1791 am => "source,binary",
1792 attr => "bool ins_permuted",
1793 init_attr => "attr->data.ins_permuted = ins_permuted;",
1794 emit => 'ucomis%FX %B',
1797 mode => $mode_flags,
1798 modified_flags => 1,
1802 op_flags => [ "uses_memory", "fragile" ],
1803 state => "exc_pinned",
1804 reg_req => { in => [ "gp", "gp", "none" ],
1805 out => [ "xmm", "none", "none", "none", "none" ] },
1806 ins => [ "base", "index", "mem" ],
1807 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1808 emit => 'movs%FX %AM, %D0',
1809 attr => "ir_mode *load_mode",
1810 init_attr => "attr->ls_mode = load_mode;",
1816 op_flags => [ "uses_memory", "fragile" ],
1817 state => "exc_pinned",
1818 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1819 out => [ "none", "none", "none" ] },
1820 ins => [ "base", "index", "mem", "val" ],
1821 outs => [ "M", "X_regular", "X_except" ],
1822 emit => 'movs%FX %S3, %AM',
1828 op_flags => [ "uses_memory", "fragile" ],
1829 state => "exc_pinned",
1830 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1831 out => [ "none", "none", "none" ] },
1832 ins => [ "base", "index", "mem", "val" ],
1833 outs => [ "M", "X_regular", "X_except" ],
1834 emit => 'movs%FX %S3, %AM',
1840 state => "exc_pinned",
1841 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1842 ins => [ "base", "index", "mem", "val" ],
1843 am => "source,unary",
1844 emit => 'cvtsi2ss %AS3, %D0',
1851 state => "exc_pinned",
1852 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1853 ins => [ "base", "index", "mem", "val" ],
1854 am => "source,unary",
1855 emit => 'cvtsi2sd %AS3, %D0',
1863 ins => [ "val_high", "val_low" ],
1865 dump_func => "NULL",
1870 outs => [ "res_high", "res_low" ],
1872 dump_func => "NULL",
1876 op_flags => [ "uses_memory", "fragile" ],
1878 reg_req => { in => [ "edi", "esi", "ecx", "none" ],
1879 out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1880 ins => [ "dest", "source", "count", "mem" ],
1881 outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1882 attr_type => "ia32_copyb_attr_t",
1883 attr => "unsigned size",
1886 # we don't care about this flag, so no need to mark this node
1887 # modified_flags => [ "DF" ]
1891 op_flags => [ "uses_memory", "fragile" ],
1893 reg_req => { in => [ "edi", "esi", "none" ],
1894 out => [ "edi", "esi", "none", "none", "none" ] },
1895 ins => [ "dest", "source", "mem" ],
1896 outs => [ "dest", "source", "M", "X_regular", "X_except" ],
1897 attr_type => "ia32_copyb_attr_t",
1898 attr => "unsigned size",
1901 # we don't care about this flag, so no need to mark this node
1902 # modified_flags => [ "DF" ]
1906 state => "exc_pinned",
1907 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1917 op_flags => [ "uses_memory", "fragile" ],
1918 state => "exc_pinned",
1919 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1920 out => [ "gp", "none", "none", "none", "none" ] },
1921 ins => [ "base", "index", "mem", "val" ],
1922 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1923 emit => "mov%#Ml %#AS3, %D0",
1924 am => "source,unary",
1927 attr => "ir_mode *smaller_mode",
1928 init_attr => "attr->ls_mode = smaller_mode;",
1933 op_flags => [ "uses_memory", "fragile" ],
1934 state => "exc_pinned",
1935 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1936 out => [ "gp", "none", "none", "none", "none" ] },
1937 ins => [ "base", "index", "mem", "val" ],
1938 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1939 emit => "mov%#Ml %#AS3, %D0",
1940 am => "source,unary",
1943 attr => "ir_mode *smaller_mode",
1944 init_attr => "attr->ls_mode = smaller_mode;",
1949 state => "exc_pinned",
1950 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1951 ins => [ "base", "index", "mem", "val" ],
1952 am => "source,unary",
1959 state => "exc_pinned",
1960 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1961 ins => [ "base", "index", "mem", "val" ],
1962 am => "source,unary",
1969 state => "exc_pinned",
1970 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1971 ins => [ "base", "index", "mem", "val" ],
1972 am => "source,unary",
1978 # rematerialisation disabled for all float nodes for now, because the fpcw
1979 # handler runs before spilling and we might end up with wrong fpcw then
1982 # irn_flags => [ "rematerializable" ],
1983 state => "exc_pinned",
1984 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1985 out => [ "fp", "none", "none" ] },
1986 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1987 outs => [ "res", "dummy", "M" ],
1988 emit => 'fadd%FP%FM %AF',
1989 am => "source,binary",
1993 attr_type => "ia32_x87_attr_t",
1997 # irn_flags => [ "rematerializable" ],
1998 state => "exc_pinned",
1999 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2000 out => [ "fp", "none", "none" ] },
2001 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2002 outs => [ "res", "dummy", "M" ],
2003 emit => 'fmul%FP%FM %AF',
2004 am => "source,binary",
2008 attr_type => "ia32_x87_attr_t",
2012 # irn_flags => [ "rematerializable" ],
2013 state => "exc_pinned",
2014 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2015 out => [ "fp", "none", "none" ] },
2016 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2017 outs => [ "res", "dummy", "M" ],
2018 emit => 'fsub%FR%FP%FM %AF',
2019 am => "source,binary",
2023 attr_type => "ia32_x87_attr_t",
2027 state => "exc_pinned",
2028 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2029 out => [ "fp", "none", "none" ] },
2030 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2031 outs => [ "res", "dummy", "M" ],
2032 emit => 'fdiv%FR%FP%FM %AF',
2033 am => "source,binary",
2036 attr_type => "ia32_x87_attr_t",
2040 reg_req => { in => [ "fp", "fp", "fpcw" ], out => [ "fp" ] },
2041 ins => [ "left", "right", "fpcw" ],
2046 attr_type => "ia32_x87_attr_t",
2050 irn_flags => [ "rematerializable" ],
2051 reg_req => { in => [ "fp"], out => [ "fp" ] },
2057 attr_type => "ia32_x87_attr_t",
2061 irn_flags => [ "rematerializable" ],
2062 reg_req => { in => [ "fp"], out => [ "fp" ] },
2068 attr_type => "ia32_x87_attr_t",
2072 irn_flags => [ "rematerializable" ],
2073 op_flags => [ "uses_memory", "fragile" ],
2074 state => "exc_pinned",
2075 reg_req => { in => [ "gp", "gp", "none" ],
2076 out => [ "fp", "none", "none", "none", "none" ] },
2077 ins => [ "base", "index", "mem" ],
2078 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
2079 emit => 'fld%FM %AM',
2080 attr => "ir_mode *load_mode",
2081 init_attr => "attr->attr.ls_mode = load_mode;",
2084 attr_type => "ia32_x87_attr_t",
2088 irn_flags => [ "rematerializable" ],
2089 op_flags => [ "uses_memory", "fragile" ],
2090 state => "exc_pinned",
2091 reg_req => { in => [ "gp", "gp", "none", "fp" ],
2092 out => [ "none", "none", "none" ] },
2093 ins => [ "base", "index", "mem", "val" ],
2094 outs => [ "M", "X_regular", "X_except" ],
2095 emit => 'fst%FP%FM %AM',
2096 attr => "ir_mode *store_mode",
2097 init_attr => "attr->attr.ls_mode = store_mode;",
2100 attr_type => "ia32_x87_attr_t",
2104 state => "exc_pinned",
2105 reg_req => { in => [ "gp", "gp", "none" ],
2106 out => [ "fp", "none", "none" ] },
2107 outs => [ "res", "unused", "M" ],
2108 ins => [ "base", "index", "mem" ],
2109 emit => 'fild%FM %AM',
2112 attr_type => "ia32_x87_attr_t",
2116 op_flags => [ "uses_memory", "fragile" ],
2117 state => "exc_pinned",
2118 reg_req => { in => [ "gp", "gp", "none", "fp", "fpcw" ],
2119 out => [ "none", "none", "none", "none" ] },
2120 ins => [ "base", "index", "mem", "val", "fpcw" ],
2121 outs => [ "dummy", "M", "X_regular", "X_except" ],
2122 emit => 'fist%FP%FM %AM',
2125 attr_type => "ia32_x87_attr_t",
2128 # SSE3 fisttp instruction
2130 op_flags => [ "uses_memory", "fragile" ],
2131 state => "exc_pinned",
2132 reg_req => { in => [ "gp", "gp", "none", "fp" ],
2133 out => [ "in_r4", "none", "none", "none" ]},
2134 ins => [ "base", "index", "mem", "val" ],
2135 outs => [ "res", "M", "X_regular", "X_except" ],
2136 emit => 'fisttp%FM %AM',
2139 attr_type => "ia32_x87_attr_t",
2143 irn_flags => [ "rematerializable" ],
2144 reg_req => { out => [ "fp" ] },
2150 attr_type => "ia32_x87_attr_t",
2154 irn_flags => [ "rematerializable" ],
2155 reg_req => { out => [ "fp" ] },
2161 attr_type => "ia32_x87_attr_t",
2165 irn_flags => [ "rematerializable" ],
2166 reg_req => { out => [ "fp" ] },
2172 attr_type => "ia32_x87_attr_t",
2176 irn_flags => [ "rematerializable" ],
2177 reg_req => { out => [ "fp" ] },
2183 attr_type => "ia32_x87_attr_t",
2187 irn_flags => [ "rematerializable" ],
2188 reg_req => { out => [ "fp" ] },
2194 attr_type => "ia32_x87_attr_t",
2198 irn_flags => [ "rematerializable" ],
2199 reg_req => { out => [ "fp" ] },
2205 attr_type => "ia32_x87_attr_t",
2209 irn_flags => [ "rematerializable" ],
2210 reg_req => { out => [ "fp" ] },
2216 attr_type => "ia32_x87_attr_t",
2220 # we can't allow to rematerialize this node so we don't
2221 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2222 # irn_flags => [ "rematerializable" ],
2223 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2224 ins => [ "left", "right" ],
2225 outs => [ "flags" ],
2226 emit => "fucom%FP %F0\n".
2228 attr => "bool ins_permuted",
2229 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2232 attr_type => "ia32_x87_attr_t",
2237 # we can't allow to rematerialize this node so we don't
2238 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2239 # irn_flags => [ "rematerializable" ],
2240 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2241 ins => [ "left", "right" ],
2242 outs => [ "flags" ],
2243 emit => "fucompp\n".
2245 attr => "bool ins_permuted",
2246 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2249 attr_type => "ia32_x87_attr_t",
2254 irn_flags => [ "rematerializable" ],
2255 reg_req => { in => [ "fp", "fp" ], out => [ "eflags" ] },
2256 ins => [ "left", "right" ],
2257 outs => [ "flags" ],
2258 emit => 'fucom%FPi %F0',
2259 attr => "bool ins_permuted",
2260 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2263 attr_type => "ia32_x87_attr_t",
2268 # irn_flags => [ "rematerializable" ],
2269 reg_req => { in => [ "fp" ], out => [ "eax" ] },
2271 outs => [ "flags" ],
2274 attr => "bool ins_permuted",
2275 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2278 attr_type => "ia32_x87_attr_t",
2283 irn_flags => [ "rematerializable" ],
2284 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2286 outs => [ "flags" ],
2290 mode => $mode_flags,
2294 # Note that it is NEVER allowed to do CSE on these nodes
2295 # Moreover, note the virtual register requierements!
2298 op_flags => [ "keep" ],
2299 reg_req => { out => [ "none" ] },
2300 cmp_attr => "return 1;",
2302 attr_type => "ia32_x87_attr_t",
2308 op_flags => [ "keep" ],
2309 reg_req => { out => [ "none" ] },
2310 cmp_attr => "return 1;",
2312 attr_type => "ia32_x87_attr_t",
2318 reg_req => { in => [ "fp"], out => [ "fp" ] },
2319 cmp_attr => "return 1;",
2321 attr_type => "ia32_x87_attr_t",
2326 op_flags => [ "keep" ],
2327 reg_req => { out => [ "none" ] },
2328 cmp_attr => "return 1;",
2330 attr_type => "ia32_x87_attr_t",
2336 op_flags => [ "keep" ],
2337 reg_req => { out => [ "none" ] },
2338 cmp_attr => "return 1;",
2339 emit => 'ffreep %F0',
2340 attr_type => "ia32_x87_attr_t",
2346 op_flags => [ "keep" ],
2347 reg_req => { out => [ "none" ] },
2348 cmp_attr => "return 1;",
2350 attr_type => "ia32_x87_attr_t",
2356 op_flags => [ "keep" ],
2357 reg_req => { out => [ "none" ] },
2358 cmp_attr => "return 1;",
2360 attr_type => "ia32_x87_attr_t",
2365 # Spilling and reloading of SSE registers, hardcoded, not generated #
2368 op_flags => [ "uses_memory", "fragile" ],
2369 state => "exc_pinned",
2370 reg_req => { in => [ "gp", "gp", "none" ],
2371 out => [ "xmm", "none", "none", "none" ] },
2372 emit => 'movdqu %D0, %AM',
2373 ins => [ "base", "index", "mem" ],
2374 outs => [ "res", "M", "X_regular", "X_except" ],
2380 op_flags => [ "uses_memory", "fragile" ],
2381 state => "exc_pinned",
2382 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
2383 out => [ "none", "none", "none" ] },
2384 ins => [ "base", "index", "mem", "val" ],
2385 outs => [ "M", "X_regular", "X_except" ],
2386 emit => 'movdqu %B',
2393 # Transform some attributes
2394 foreach my $op (keys(%nodes)) {
2395 my $node = $nodes{$op};
2396 my $op_attr_init = $node->{op_attr_init};
2398 if(defined($op_attr_init)) {
2399 $op_attr_init .= "\n\t";
2404 if(!defined($node->{latency})) {
2406 $node->{latency} = 0;
2408 die("Latency missing for op $op");
2411 $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2413 $node->{op_attr_init} = $op_attr_init;