1 # This is the specification for the ia32 assembler Firm-operations
7 $mode_fp87 = "ia32_mode_E";
9 $mode_flags = "mode_Iu";
10 $mode_fpcw = "ia32_mode_fpcw";
13 $normal = 0; # no special type
14 $ignore = 1; # ignore (do not assign this register)
15 $virtual = 2; # the register is a virtual one
16 $state = 4; # register represents a state
17 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
20 { name => "edx", dwarf => 2 },
21 { name => "ecx", dwarf => 1 },
22 { name => "eax", dwarf => 0 },
23 { name => "ebx", dwarf => 3 },
24 { name => "esi", dwarf => 6 },
25 { name => "edi", dwarf => 7 },
26 { name => "ebp", dwarf => 5 },
27 { name => "esp", dwarf => 4, type => $ignore },
28 { name => "gp_NOREG", type => $ignore | $virtual }, # we need a dummy register for NoReg nodes
32 { name => "mm0", dwarf => 29, type => $ignore },
33 { name => "mm1", dwarf => 30, type => $ignore },
34 { name => "mm2", dwarf => 31, type => $ignore },
35 { name => "mm3", dwarf => 32, type => $ignore },
36 { name => "mm4", dwarf => 33, type => $ignore },
37 { name => "mm5", dwarf => 34, type => $ignore },
38 { name => "mm6", dwarf => 35, type => $ignore },
39 { name => "mm7", dwarf => 36, type => $ignore },
40 { mode => $mode_mmx, flags => "manual_ra" }
43 { name => "xmm0", dwarf => 21 },
44 { name => "xmm1", dwarf => 22 },
45 { name => "xmm2", dwarf => 23 },
46 { name => "xmm3", dwarf => 24 },
47 { name => "xmm4", dwarf => 25 },
48 { name => "xmm5", dwarf => 26 },
49 { name => "xmm6", dwarf => 27 },
50 { name => "xmm7", dwarf => 28 },
51 { name => "xmm_NOREG", type => $ignore | $virtual }, # we need a dummy register for NoReg nodes
55 { name => "st0", realname => "st", dwarf => 11 },
56 { name => "st1", realname => "st(1)", dwarf => 12 },
57 { name => "st2", realname => "st(2)", dwarf => 13 },
58 { name => "st3", realname => "st(3)", dwarf => 14 },
59 { name => "st4", realname => "st(4)", dwarf => 15 },
60 { name => "st5", realname => "st(5)", dwarf => 16 },
61 { name => "st6", realname => "st(6)", dwarf => 17 },
62 { name => "st7", realname => "st(7)", dwarf => 18 },
63 { name => "fp_NOREG", type => $ignore | $virtual }, # we need a dummy register for NoReg nodes
64 { mode => $mode_fp87 }
66 fp_cw => [ # the floating point control word
67 { name => "fpcw", dwarf => 37, type => $ignore | $state },
68 { mode => $mode_fpcw, flags => "manual_ra|state" }
71 { name => "eflags", dwarf => 9, type => 0 },
72 { mode => "mode_Iu", flags => "manual_ra" }
77 GP => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
78 SSE => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
79 VFP => [ 1, "VFP_VF0", "VFP_VF1", "VFP_VF2", "VFP_VF3", "VFP_VF4", "VFP_VF5", "VFP_VF6", "VFP_VF7" ],
80 BRANCH => [ 1, "BRANCH1", "BRANCH2" ],
85 bundels_per_cycle => 1
88 $default_op_attr_type = "ia32_op_attr_t";
89 $default_attr_type = "ia32_attr_t";
90 $default_copy_attr = "ia32_copy_attr";
92 sub ia32_custom_init_attr {
98 if(defined($node->{modified_flags})) {
99 $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n";
101 if(defined($node->{am})) {
102 my $am = $node->{am};
103 if($am eq "source,unary") {
104 $res .= "\tset_ia32_am_support(res, ia32_am_unary);";
105 } elsif($am eq "source,binary") {
106 $res .= "\tset_ia32_am_support(res, ia32_am_binary);";
107 } elsif($am eq "none") {
110 die("Invalid address mode '$am' specified on op $name");
113 if($node->{state} ne "exc_pinned"
114 and $node->{state} ne "pinned") {
115 die("AM nodes must have pinned or AM pinned state ($name)");
121 $custom_init_attr_func = \&ia32_custom_init_attr;
125 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
126 "\tinit_ia32_x87_attributes(res);".
127 "\tinit_ia32_asm_attributes(res);",
129 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);",
131 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
132 "\tinit_ia32_call_attributes(res, pop, call_tp);",
133 ia32_condcode_attr_t =>
134 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
135 "\tinit_ia32_condcode_attributes(res, condition_code);",
136 ia32_switch_attr_t =>
137 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
138 "\tinit_ia32_switch_attributes(res, switch_table);",
140 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
141 "\tinit_ia32_copyb_attributes(res, size);",
142 ia32_immediate_attr_t =>
143 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
144 "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
146 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
147 "\tinit_ia32_x87_attributes(res);",
148 ia32_climbframe_attr_t =>
149 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
150 "\tinit_ia32_climbframe_attributes(res, count);",
154 ia32_asm_attr_t => "ia32_compare_asm_attr",
155 ia32_attr_t => "ia32_compare_nodes_attr",
156 ia32_call_attr_t => "ia32_compare_call_attr",
157 ia32_condcode_attr_t => "ia32_compare_condcode_attr",
158 ia32_copyb_attr_t => "ia32_compare_copyb_attr",
159 ia32_switch_attr_t => "ia32_compare_nodes_attr",
160 ia32_immediate_attr_t => "ia32_compare_immediate_attr",
161 ia32_x87_attr_t => "ia32_compare_x87_attr",
162 ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
168 $status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
169 $status_flags_wo_cf = [ "PF", "AF", "ZF", "SF", "OF" ];
170 $fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
171 "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
177 op_flags => [ "constlike" ],
178 irn_flags => [ "not_scheduled" ],
179 reg_req => { out => [ "gp_NOREG:I" ] },
180 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
181 attr_type => "ia32_immediate_attr_t",
182 hash_func => "ia32_hash_Immediate",
190 out_arity => "variable",
191 attr_type => "ia32_asm_attr_t",
192 attr => "ident *asm_text, const ia32_asm_reg_t *register_map",
193 init_attr => "attr->asm_text = asm_text;\n".
194 "\tattr->register_map = register_map;\n",
196 modified_flags => $status_flags,
199 # "allocates" a free register
201 op_flags => [ "constlike", "cse_neutral" ],
202 irn_flags => [ "rematerializable" ],
203 reg_req => { out => [ "gp" ] },
208 cmp_attr => "return 1;",
212 irn_flags => [ "rematerializable" ],
213 state => "exc_pinned",
214 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
215 out => [ "in_r4 in_r5", "flags", "none" ] },
216 ins => [ "base", "index", "mem", "left", "right" ],
217 outs => [ "res", "flags", "M" ],
219 am => "source,binary",
223 modified_flags => $status_flags
227 irn_flags => [ "rematerializable" ],
228 state => "exc_pinned",
229 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
230 ins => [ "base", "index", "mem", "val" ],
231 emit => "add%M %#S3, %AM",
235 modified_flags => $status_flags
239 irn_flags => [ "rematerializable" ],
240 state => "exc_pinned",
241 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
242 ins => [ "base", "index", "mem", "val" ],
243 emit => "add%M %#S3, %AM",
247 modified_flags => $status_flags
251 state => "exc_pinned",
252 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
253 out => [ "in_r4 in_r5", "flags", "none" ] },
254 ins => [ "base", "index", "mem", "left", "right", "eflags" ],
255 outs => [ "res", "flags", "M" ],
257 am => "source,binary",
261 modified_flags => $status_flags
265 ins => [ "left", "right" ],
271 ins => [ "left", "right", "eflags" ],
277 # we should not rematrialize this node. It produces 2 results and has
278 # very strict constraints
279 state => "exc_pinned",
280 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
281 out => [ "eax", "flags", "none", "edx" ] },
282 ins => [ "base", "index", "mem", "left", "right" ],
283 emit => 'mul%M %AS4',
284 outs => [ "res_low", "flags", "M", "res_high" ],
285 am => "source,binary",
288 modified_flags => $status_flags
292 ins => [ "left", "right" ],
293 outs => [ "res_low", "flags", "M", "res_high" ],
299 irn_flags => [ "rematerializable" ],
300 state => "exc_pinned",
301 # TODO: adjust out requirements for the 3 operand form
302 # (no need for should_be_same then)
303 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
304 out => [ "in_r4 in_r5", "flags", "none" ] },
305 ins => [ "base", "index", "mem", "left", "right" ],
306 outs => [ "res", "flags", "M" ],
307 am => "source,binary",
311 modified_flags => $status_flags
315 irn_flags => [ "rematerializable" ],
316 state => "exc_pinned",
317 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
318 out => [ "eax", "flags", "none", "edx" ] },
319 ins => [ "base", "index", "mem", "left", "right" ],
320 emit => 'imul%M %AS4',
321 outs => [ "res_low", "flags", "M", "res_high" ],
322 am => "source,binary",
325 modified_flags => $status_flags
329 ins => [ "left", "right" ],
330 outs => [ "res_low", "flags", "M", "res_high" ],
336 irn_flags => [ "rematerializable" ],
337 state => "exc_pinned",
338 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
339 out => [ "in_r4 in_r5", "flags", "none" ] },
340 ins => [ "base", "index", "mem", "left", "right" ],
341 outs => [ "res", "flags", "M" ],
342 am => "source,binary",
347 modified_flags => $status_flags
351 irn_flags => [ "rematerializable" ],
352 state => "exc_pinned",
353 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
354 ins => [ "base", "index", "mem", "val" ],
355 emit => 'and%M %#S3, %AM',
359 modified_flags => $status_flags
363 irn_flags => [ "rematerializable" ],
364 state => "exc_pinned",
365 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
366 ins => [ "base", "index", "mem", "val" ],
367 emit => 'and%M %#S3, %AM',
371 modified_flags => $status_flags
375 irn_flags => [ "rematerializable" ],
376 state => "exc_pinned",
377 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
378 out => [ "in_r4 in_r5", "flags", "none" ] },
379 ins => [ "base", "index", "mem", "left", "right" ],
380 outs => [ "res", "flags", "M" ],
381 am => "source,binary",
386 modified_flags => $status_flags
390 irn_flags => [ "rematerializable" ],
391 state => "exc_pinned",
392 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
393 ins => [ "base", "index", "mem", "val" ],
394 emit => 'or%M %#S3, %AM',
398 modified_flags => $status_flags
402 irn_flags => [ "rematerializable" ],
403 state => "exc_pinned",
404 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
405 ins => [ "base", "index", "mem", "val" ],
406 emit => 'or%M %#S3, %AM',
410 modified_flags => $status_flags
414 irn_flags => [ "rematerializable" ],
415 state => "exc_pinned",
416 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
417 out => [ "in_r4 in_r5", "flags", "none" ] },
418 ins => [ "base", "index", "mem", "left", "right" ],
419 outs => [ "res", "flags", "M" ],
420 am => "source,binary",
425 modified_flags => $status_flags
429 op_flags => [ "constlike" ],
430 irn_flags => [ "rematerializable" ],
431 reg_req => { out => [ "gp", "flags" ] },
432 outs => [ "res", "flags" ],
433 emit => "xor%M %D0, %D0",
437 modified_flags => $status_flags
441 irn_flags => [ "rematerializable" ],
442 state => "exc_pinned",
443 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
444 ins => [ "base", "index", "mem", "val" ],
445 emit => 'xor%M %#S3, %AM',
449 modified_flags => $status_flags
453 irn_flags => [ "rematerializable" ],
454 state => "exc_pinned",
455 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
456 ins => [ "base", "index", "mem", "val" ],
457 emit => 'xor%M %#S3, %AM',
461 modified_flags => $status_flags
465 irn_flags => [ "rematerializable" ],
466 state => "exc_pinned",
467 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
468 out => [ "in_r4", "flags", "none" ] },
469 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
470 outs => [ "res", "flags", "M" ],
471 am => "source,binary",
476 modified_flags => $status_flags
480 irn_flags => [ "rematerializable" ],
481 state => "exc_pinned",
482 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
483 ins => [ "base", "index", "mem", "subtrahend" ],
484 emit => 'sub%M %#S3, %AM',
488 modified_flags => $status_flags
492 irn_flags => [ "rematerializable" ],
493 state => "exc_pinned",
494 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
495 ins => [ "base", "index", "mem", "subtrahend" ],
496 emit => 'sub%M %#S3, %AM',
500 modified_flags => $status_flags
504 state => "exc_pinned",
505 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
506 out => [ "in_r4", "flags", "none" ] },
507 ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
508 outs => [ "res", "flags", "M" ],
509 am => "source,binary",
514 modified_flags => $status_flags
518 # Spiller currently fails when rematerializing flag consumers
519 # irn_flags => [ "rematerializable" ],
520 reg_req => { in => [ "flags" ], out => [ "gp", "flags" ] },
521 outs => [ "res", "flags" ],
522 emit => "sbb%M %D0, %D0",
526 modified_flags => $status_flags
530 ins => [ "minuend", "subtrahend" ],
536 ins => [ "minuend", "subtrahend", "eflags" ],
542 op_flags => [ "fragile", "uses_memory" ],
543 state => "exc_pinned",
544 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
545 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
546 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
547 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
548 am => "source,unary",
549 emit => "idiv%M %AS3",
552 modified_flags => $status_flags
556 op_flags => [ "fragile", "uses_memory" ],
557 state => "exc_pinned",
558 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
559 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
560 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
561 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
562 am => "source,unary",
563 emit => "div%M %AS3",
566 modified_flags => $status_flags
570 irn_flags => [ "rematerializable" ],
571 reg_req => { in => [ "gp", "ecx" ],
572 out => [ "in_r1 !in_r2", "flags" ] },
573 ins => [ "val", "count" ],
574 outs => [ "res", "flags" ],
575 emit => 'shl%M %<S1, %S0',
579 modified_flags => $status_flags
583 irn_flags => [ "rematerializable" ],
584 state => "exc_pinned",
585 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
586 ins => [ "base", "index", "mem", "count" ],
587 emit => 'shl%M %<S3, %AM',
591 modified_flags => $status_flags
595 irn_flags => [ "rematerializable" ],
596 reg_req => { in => [ "gp", "gp", "ecx" ],
597 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
598 ins => [ "val_high", "val_low", "count" ],
599 outs => [ "res", "flags" ],
600 emit => "shld%M %<S2, %S1, %D0",
604 modified_flags => $status_flags
608 irn_flags => [ "rematerializable" ],
609 reg_req => { in => [ "gp", "ecx" ],
610 out => [ "in_r1 !in_r2", "flags" ] },
611 ins => [ "val", "count" ],
612 outs => [ "res", "flags" ],
613 emit => 'shr%M %<S1, %S0',
617 modified_flags => $status_flags
621 irn_flags => [ "rematerializable" ],
622 state => "exc_pinned",
623 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
624 ins => [ "base", "index", "mem", "count" ],
625 emit => 'shr%M %<S3, %AM',
629 modified_flags => $status_flags
633 irn_flags => [ "rematerializable" ],
634 reg_req => { in => [ "gp", "gp", "ecx" ],
635 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
636 ins => [ "val_high", "val_low", "count" ],
637 outs => [ "res", "flags" ],
638 emit => "shrd%M %<S2, %S1, %D0",
642 modified_flags => $status_flags
646 irn_flags => [ "rematerializable" ],
647 reg_req => { in => [ "gp", "ecx" ],
648 out => [ "in_r1 !in_r2", "flags" ] },
649 ins => [ "val", "count" ],
650 outs => [ "res", "flags" ],
651 emit => 'sar%M %<S1, %S0',
655 modified_flags => $status_flags
659 irn_flags => [ "rematerializable" ],
660 state => "exc_pinned",
661 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
662 ins => [ "base", "index", "mem", "count" ],
663 emit => 'sar%M %<S3, %AM',
667 modified_flags => $status_flags
671 irn_flags => [ "rematerializable" ],
672 reg_req => { in => [ "gp", "ecx" ],
673 out => [ "in_r1 !in_r2", "flags" ] },
674 ins => [ "val", "count" ],
675 outs => [ "res", "flags" ],
676 emit => 'ror%M %<S1, %S0',
680 modified_flags => $status_flags
684 irn_flags => [ "rematerializable" ],
685 state => "exc_pinned",
686 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
687 ins => [ "base", "index", "mem", "count" ],
688 emit => 'ror%M %<S3, %AM',
692 modified_flags => $status_flags
696 irn_flags => [ "rematerializable" ],
697 reg_req => { in => [ "gp", "ecx" ],
698 out => [ "in_r1 !in_r2", "flags" ] },
699 ins => [ "val", "count" ],
700 outs => [ "res", "flags" ],
701 emit => 'rol%M %<S1, %D0',
705 modified_flags => $status_flags
709 irn_flags => [ "rematerializable" ],
710 state => "exc_pinned",
711 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
712 ins => [ "base", "index", "mem", "count" ],
713 emit => 'rol%M %<S3, %AM',
717 modified_flags => $status_flags
721 irn_flags => [ "rematerializable" ],
722 reg_req => { in => [ "gp" ],
723 out => [ "in_r1", "flags" ] },
726 outs => [ "res", "flags" ],
730 modified_flags => $status_flags
734 irn_flags => [ "rematerializable" ],
735 state => "exc_pinned",
736 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
737 ins => [ "base", "index", "mem" ],
742 modified_flags => $status_flags
746 irn_flags => [ "rematerializable" ],
747 reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
748 outs => [ "low_res", "high_res" ],
751 modified_flags => $status_flags
756 irn_flags => [ "rematerializable" ],
757 reg_req => { in => [ "gp" ],
758 out => [ "in_r1", "flags" ] },
760 outs => [ "res", "flags" ],
765 modified_flags => $status_flags_wo_cf
769 irn_flags => [ "rematerializable" ],
770 state => "exc_pinned",
771 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
772 ins => [ "base", "index", "mem" ],
777 modified_flags => $status_flags_wo_cf
781 irn_flags => [ "rematerializable" ],
782 reg_req => { in => [ "gp" ],
783 out => [ "in_r1", "flags" ] },
785 outs => [ "res", "flags" ],
790 modified_flags => $status_flags_wo_cf
794 irn_flags => [ "rematerializable" ],
795 state => "exc_pinned",
796 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
797 ins => [ "base", "index", "mem" ],
802 modified_flags => $status_flags_wo_cf
806 irn_flags => [ "rematerializable" ],
807 reg_req => { in => [ "gp" ],
808 out => [ "in_r1" ] },
819 irn_flags => [ "rematerializable" ],
820 state => "exc_pinned",
821 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
822 ins => [ "base", "index", "mem" ],
831 reg_req => { in => [ "flags" ], out => [ "flags" ] },
836 modified_flags => $status_flags
840 reg_req => { out => [ "flags" ] },
845 modified_flags => $status_flags
849 irn_flags => [ "rematerializable" ],
850 state => "exc_pinned",
851 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
852 out => [ "flags", "none", "none" ] },
853 ins => [ "base", "index", "mem", "left", "right" ],
854 outs => [ "eflags", "unused", "M" ],
855 am => "source,binary",
857 attr => "bool ins_permuted",
858 init_attr => "attr->data.ins_permuted = ins_permuted;",
862 modified_flags => $status_flags
866 irn_flags => [ "rematerializable" ],
867 state => "exc_pinned",
868 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
869 out => [ "flags", "none", "none" ] },
870 ins => [ "base", "index", "mem", "left", "right" ],
871 outs => [ "eflags", "unused", "M" ],
872 am => "source,binary",
874 attr => "bool ins_permuted",
875 init_attr => "attr->data.ins_permuted = ins_permuted;",
879 modified_flags => $status_flags
883 irn_flags => [ "rematerializable" ],
884 state => "exc_pinned",
885 reg_req => { in => [ "eax ebx ecx edx" ],
886 out => [ "in_r1", "flags" ] },
887 emit => 'xorb %>S0, %<S0',
889 outs => [ "res", "flags" ],
893 modified_flags => $status_flags,
897 irn_flags => [ "rematerializable" ],
898 state => "exc_pinned",
899 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] ,
900 out => [ "flags", "none", "none" ] },
901 ins => [ "base", "index", "mem", "left", "right" ],
902 outs => [ "eflags", "unused", "M" ],
903 am => "source,binary",
905 attr => "bool ins_permuted",
906 init_attr => "attr->data.ins_permuted = ins_permuted;",
910 modified_flags => $status_flags
914 irn_flags => [ "rematerializable" ],
915 state => "exc_pinned",
916 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
917 out => [ "flags", "none", "none" ] },
918 ins => [ "base", "index", "mem", "left", "right" ],
919 outs => [ "eflags", "unused", "M" ],
920 am => "source,binary",
922 attr => "bool ins_permuted",
923 init_attr => "attr->data.ins_permuted = ins_permuted;",
927 modified_flags => $status_flags
931 #irn_flags => [ "rematerializable" ],
932 reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
935 attr_type => "ia32_condcode_attr_t",
936 attr => "ia32_condition_code_t condition_code",
937 # The way we handle Setcc with float nodes (potentially) destroys the flags
938 # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
939 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
940 . "\tif (condition_code & ia32_cc_additional_float_cases) {\n"
941 . "\t\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"
942 . "\t\t/* attr->latency = 3; */\n"
950 #irn_flags => [ "rematerializable" ],
951 state => "exc_pinned",
952 reg_req => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
953 ins => [ "base", "index", "mem","eflags" ],
954 attr_type => "ia32_condcode_attr_t",
955 attr => "ia32_condition_code_t condition_code",
956 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
957 emit => 'set%P3 %AM',
964 #irn_flags => [ "rematerializable" ],
965 state => "exc_pinned",
966 # (note: leave the false,true order intact to make it compatible with other
968 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
969 out => [ "in_r4 in_r5", "flags", "none" ] },
970 ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
971 outs => [ "res", "flags", "M" ],
972 am => "source,binary",
973 attr_type => "ia32_condcode_attr_t",
974 attr => "ia32_condition_code_t condition_code",
982 op_flags => [ "cfopcode", "forking" ],
983 reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
985 outs => [ "false", "true" ],
986 attr_type => "ia32_condcode_attr_t",
987 attr => "ia32_condition_code_t condition_code",
989 units => [ "BRANCH" ],
994 op_flags => [ "cfopcode", "forking" ],
995 reg_req => { in => [ "gp", "gp" ] },
996 ins => [ "base", "index" ],
997 out_arity => "variable",
998 attr_type => "ia32_switch_attr_t",
999 attr => "const ir_switch_table *switch_table",
1001 units => [ "BRANCH" ],
1006 irn_flags => [ "simple_jump" ],
1007 op_flags => [ "cfopcode" ],
1008 reg_req => { out => [ "none" ] },
1010 units => [ "BRANCH" ],
1016 op_flags => [ "cfopcode", "unknown_jump" ],
1017 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1018 out => [ "none", "flags", "none" ] },
1019 ins => [ "base", "index", "mem", "target" ],
1020 outs => [ "jmp", "flags", "M" ],
1021 am => "source,unary",
1022 emit => 'jmp %*AS3',
1024 units => [ "BRANCH" ],
1029 op_flags => [ "constlike" ],
1030 irn_flags => [ "rematerializable" ],
1031 reg_req => { out => [ "gp" ] },
1032 emit => "movl %I, %D0",
1034 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
1035 attr_type => "ia32_immediate_attr_t",
1041 op_flags => [ "constlike" ],
1042 irn_flags => [ "rematerializable" ],
1043 reg_req => { out => [ "gp" ] },
1050 op_flags => [ "constlike" ],
1051 reg_req => { out => [ "gp" ] },
1055 modified_flags => $status_flags,
1060 op_flags => [ "constlike", "dump_noblock" ],
1061 irn_flags => [ "not_scheduled" ],
1062 reg_req => { out => [ "gp_NOREG:I" ] },
1071 op_flags => [ "constlike", "dump_noblock" ],
1072 irn_flags => [ "not_scheduled" ],
1073 reg_req => { out => [ "fp_NOREG:I" ] },
1078 attr_type => "ia32_x87_attr_t",
1083 op_flags => [ "constlike", "dump_noblock" ],
1084 irn_flags => [ "not_scheduled" ],
1085 reg_req => { out => [ "xmm_NOREG:I" ] },
1094 op_flags => [ "constlike" ],
1095 irn_flags => [ "not_scheduled" ],
1096 reg_req => { out => [ "fpcw:I" ] },
1100 modified_flags => $fpcw_flags
1104 op_flags => [ "uses_memory" ],
1106 reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] },
1107 ins => [ "base", "index", "mem" ],
1109 emit => "fldcw %AM",
1112 modified_flags => $fpcw_flags
1116 op_flags => [ "uses_memory" ],
1118 reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1119 ins => [ "base", "index", "mem", "fpcw" ],
1121 emit => "fnstcw %AM",
1127 op_flags => [ "uses_memory" ],
1129 reg_req => { in => [ "fp_cw" ], out => [ "none" ] },
1137 # we should not rematrialize this node. It has very strict constraints.
1138 reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] },
1139 ins => [ "val", "clobbered" ],
1148 # Note that we add additional latency values depending on address mode, so a
1149 # lateny of 0 for load is correct
1152 op_flags => [ "uses_memory", "fragile" ],
1153 state => "exc_pinned",
1154 reg_req => { in => [ "gp", "gp", "none" ],
1155 out => [ "gp", "none", "none", "none", "none" ] },
1156 ins => [ "base", "index", "mem" ],
1157 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1159 emit => "mov%#Ml %AM, %D0",
1164 op_flags => [ "uses_memory", "fragile" ],
1165 state => "exc_pinned",
1166 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1167 out => [ "none", "none", "none" ] },
1168 ins => [ "base", "index", "mem", "val" ],
1169 outs => [ "M", "X_regular", "X_except" ],
1170 emit => 'mov%M %#S3, %AM',
1176 op_flags => [ "uses_memory", "fragile" ],
1177 state => "exc_pinned",
1178 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1179 out => ["none", "none", "none" ] },
1180 ins => [ "base", "index", "mem", "val" ],
1181 outs => [ "M", "X_regular", "X_except" ],
1182 emit => 'mov%M %#S3, %AM',
1188 irn_flags => [ "rematerializable" ],
1189 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1190 ins => [ "base", "index" ],
1191 emit => 'leal %AM, %D0',
1195 # lea doesn't modify the flags, but setting this seems advantageous since it
1196 # increases chances that the Lea is transformed back to an Add
1197 modified_flags => 1,
1201 state => "exc_pinned",
1202 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1203 ins => [ "base", "index", "mem", "val", "stack" ],
1204 emit => 'push%M %AS3',
1205 outs => [ "stack", "M" ],
1206 am => "source,unary",
1212 state => "exc_pinned",
1213 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1215 outs => [ "stack" ],
1216 emit => 'pushl %%eax',
1223 state => "exc_pinned",
1224 reg_req => { in => [ "none", "esp" ], out => [ "gp", "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 => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1235 ins => [ "mem", "stack" ],
1236 outs => [ "res", "M", "unused", "stack" ],
1237 emit => 'pop%M %D0',
1238 latency => 3, # Pop is more expensive than Push on Athlon
1243 state => "exc_pinned",
1244 reg_req => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1247 emit => 'movl %S0, %D0',
1254 state => "exc_pinned",
1255 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1256 ins => [ "base", "index", "mem", "stack" ],
1257 outs => [ "unused0", "M", "unused1", "stack" ],
1258 emit => 'pop%M %AM',
1259 latency => 3, # Pop is more expensive than Push on Athlon
1264 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1266 outs => [ "frame", "stack", "M" ],
1272 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1274 outs => [ "frame", "stack" ],
1277 state => "exc_pinned",
1282 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1283 ins => [ "base", "index", "mem", "stack", "size" ],
1284 am => "source,binary",
1287 outs => [ "stack", "M" ],
1289 modified_flags => $status_flags
1294 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1295 ins => [ "base", "index", "mem", "stack", "size" ],
1296 am => "source,binary",
1297 emit => "subl %B\n".
1300 outs => [ "stack", "addr", "M" ],
1302 modified_flags => $status_flags
1306 op_flags => [ "keep" ],
1314 irn_flags => [ "rematerializable" ],
1315 reg_req => { out => [ "gp" ] },
1317 emit => "movl %%gs:0, %D0",
1323 # BT supports source address mode, but this is unused yet
1326 irn_flags => [ "rematerializable" ],
1327 state => "exc_pinned",
1328 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1329 ins => [ "left", "right" ],
1330 emit => 'bt%M %S1, %S0',
1333 mode => $mode_flags,
1334 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1338 irn_flags => [ "rematerializable" ],
1339 state => "exc_pinned",
1340 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1341 out => [ "gp", "flags", "none" ] },
1342 ins => [ "base", "index", "mem", "operand" ],
1343 outs => [ "res", "flags", "M" ],
1344 am => "source,binary",
1345 emit => 'bsf%M %AS3, %D0',
1349 modified_flags => $status_flags
1353 irn_flags => [ "rematerializable" ],
1354 state => "exc_pinned",
1355 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1356 out => [ "gp", "flags", "none" ] },
1357 ins => [ "base", "index", "mem", "operand" ],
1358 outs => [ "res", "flags", "M" ],
1359 am => "source,binary",
1360 emit => 'bsr%M %AS3, %D0',
1364 modified_flags => $status_flags
1368 # SSE4.2 or SSE4a popcnt instruction
1371 irn_flags => [ "rematerializable" ],
1372 state => "exc_pinned",
1373 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1374 out => [ "gp", "flags", "none" ] },
1375 ins => [ "base", "index", "mem", "operand" ],
1376 outs => [ "res", "flags", "M" ],
1377 am => "source,binary",
1378 emit => 'popcnt%M %AS3, %D0',
1382 modified_flags => $status_flags
1386 op_flags => [ "uses_memory", "fragile" ],
1387 state => "exc_pinned",
1389 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1390 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" ]
1392 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1393 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" ],
1394 emit => "call %*AS3",
1395 attr_type => "ia32_call_attr_t",
1396 attr => "unsigned pop, ir_type *call_tp",
1397 am => "source,unary",
1398 units => [ "BRANCH" ],
1399 latency => 4, # random number
1400 modified_flags => $status_flags
1404 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1406 # PS: try gcc __builtin_frame_address(100000) :-)
1409 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1410 ins => [ "frame", "cnt", "tmp" ],
1412 latency => 4, # random number
1413 attr_type => "ia32_climbframe_attr_t",
1414 attr => "unsigned count",
1423 irn_flags => [ "rematerializable" ],
1424 reg_req => { in => [ "gp" ],
1425 out => [ "in_r1" ] },
1427 emit => 'bswap%M %S0',
1435 # bswap16, use xchg here
1438 irn_flags => [ "rematerializable" ],
1439 reg_req => { in => [ "eax ebx ecx edx" ],
1440 out => [ "in_r1" ] },
1441 emit => 'xchg %<S0, %>S0',
1453 reg_req => { in => [ "none" ], out => [ "none" ] },
1462 # Undefined Instruction on ALL x86 CPU's
1466 reg_req => { in => [ "none" ], out => [ "none" ] },
1478 irn_flags => [ "rematerializable" ],
1480 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1481 ins => [ "port", "value", "mem" ],
1482 emit => 'out%M %^S0, %#S1',
1486 modified_flags => $status_flags
1493 irn_flags => [ "rematerializable" ],
1495 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1496 ins => [ "port", "mem" ],
1497 outs => [ "res", "M" ],
1498 emit => 'in%M %#D0, %^S0',
1502 modified_flags => $status_flags
1506 # Intel style prefetching
1509 op_flags => [ "uses_memory" ],
1510 state => "exc_pinned",
1511 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1512 ins => [ "base", "index", "mem" ],
1515 emit => "prefetcht0 %AM",
1520 op_flags => [ "uses_memory" ],
1521 state => "exc_pinned",
1522 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1523 ins => [ "base", "index", "mem" ],
1526 emit => "prefetcht1 %AM",
1531 op_flags => [ "uses_memory" ],
1532 state => "exc_pinned",
1533 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1534 ins => [ "base", "index", "mem" ],
1537 emit => "prefetcht2 %AM",
1542 op_flags => [ "uses_memory" ],
1543 state => "exc_pinned",
1544 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1545 ins => [ "base", "index", "mem" ],
1548 emit => "prefetchnta %AM",
1553 # 3DNow! prefetch instructions
1556 op_flags => [ "uses_memory" ],
1557 state => "exc_pinned",
1558 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1559 ins => [ "base", "index", "mem" ],
1562 emit => "prefetch %AM",
1567 op_flags => [ "uses_memory" ],
1568 state => "exc_pinned",
1569 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1570 ins => [ "base", "index", "mem" ],
1573 emit => "prefetchw %AM",
1579 irn_flags => [ "rematerializable" ],
1580 reg_req => { out => [ "xmm" ] },
1581 emit => 'xorp%FX %D0, %D0',
1588 op_flags => [ "constlike" ],
1589 irn_flags => [ "rematerializable" ],
1590 reg_req => { out => [ "xmm" ] },
1597 irn_flags => [ "rematerializable" ],
1598 reg_req => { out => [ "xmm" ] },
1599 emit => 'pxor %D0, %D0',
1605 # produces all 1 bits
1607 irn_flags => [ "rematerializable" ],
1608 reg_req => { out => [ "xmm" ] },
1609 emit => 'pcmpeqb %D0, %D0',
1615 # integer shift left, dword
1617 irn_flags => [ "rematerializable" ],
1618 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1619 emit => 'pslld %#S1, %D0',
1625 # integer shift left, qword
1627 irn_flags => [ "rematerializable" ],
1628 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1629 emit => 'psllq %#S1, %D0',
1635 # integer shift right, dword
1637 irn_flags => [ "rematerializable" ],
1638 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1639 emit => 'psrld %#S1, %D0',
1645 # mov from integer to SSE register
1647 irn_flags => [ "rematerializable" ],
1648 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1649 emit => 'movd %S0, %D0',
1656 irn_flags => [ "rematerializable" ],
1657 state => "exc_pinned",
1658 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1659 out => [ "in_r4 in_r5", "flags", "none" ] },
1660 ins => [ "base", "index", "mem", "left", "right" ],
1661 outs => [ "res", "flags", "M" ],
1662 am => "source,binary",
1663 emit => 'adds%FX %B',
1670 irn_flags => [ "rematerializable" ],
1671 state => "exc_pinned",
1672 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1673 out => [ "in_r4 in_r5", "flags", "none" ] },
1674 ins => [ "base", "index", "mem", "left", "right" ],
1675 outs => [ "res", "flags", "M" ],
1676 am => "source,binary",
1677 emit => 'muls%FX %B',
1684 irn_flags => [ "rematerializable" ],
1685 state => "exc_pinned",
1686 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1687 out => [ "in_r4 in_r5", "flags", "none" ] },
1688 ins => [ "base", "index", "mem", "left", "right" ],
1689 outs => [ "res", "flags", "M" ],
1690 am => "source,binary",
1691 emit => 'maxs%FX %B',
1698 irn_flags => [ "rematerializable" ],
1699 state => "exc_pinned",
1700 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1701 out => [ "in_r4 in_r5", "flags", "none" ] },
1702 ins => [ "base", "index", "mem", "left", "right" ],
1703 outs => [ "res", "flags", "M" ],
1704 am => "source,binary",
1705 emit => 'mins%FX %B',
1712 irn_flags => [ "rematerializable" ],
1713 state => "exc_pinned",
1714 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1715 out => [ "in_r4 in_r5", "flags", "none" ] },
1716 ins => [ "base", "index", "mem", "left", "right" ],
1717 outs => [ "res", "flags", "M" ],
1718 am => "source,binary",
1719 emit => 'andp%FX %B',
1726 irn_flags => [ "rematerializable" ],
1727 state => "exc_pinned",
1728 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1729 out => [ "in_r4 in_r5", "flags", "none" ] },
1730 ins => [ "base", "index", "mem", "left", "right" ],
1731 outs => [ "res", "flags", "M" ],
1732 am => "source,binary",
1733 emit => 'orp%FX %B',
1740 irn_flags => [ "rematerializable" ],
1741 state => "exc_pinned",
1742 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1743 out => [ "in_r4 in_r5", "flags", "none" ] },
1744 ins => [ "base", "index", "mem", "left", "right" ],
1745 outs => [ "res", "flags", "M" ],
1746 am => "source,binary",
1747 emit => 'xorp%FX %B',
1754 irn_flags => [ "rematerializable" ],
1755 state => "exc_pinned",
1756 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1757 out => [ "in_r4 !in_r5", "flags", "none" ] },
1758 ins => [ "base", "index", "mem", "left", "right" ],
1759 outs => [ "res", "flags", "M" ],
1760 am => "source,binary",
1761 emit => 'andnp%FX %B',
1768 irn_flags => [ "rematerializable" ],
1769 state => "exc_pinned",
1770 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1771 out => [ "in_r4", "flags", "none" ] },
1772 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1773 outs => [ "res", "flags", "M" ],
1774 am => "source,binary",
1775 emit => 'subs%FX %B',
1782 irn_flags => [ "rematerializable" ],
1783 state => "exc_pinned",
1784 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1785 out => [ "in_r4 !in_r5", "flags", "none" ] },
1786 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1787 outs => [ "res", "flags", "M" ],
1788 am => "source,binary",
1789 emit => 'divs%FX %B',
1795 irn_flags => [ "rematerializable" ],
1796 state => "exc_pinned",
1797 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1798 out => [ "eflags" ] },
1799 ins => [ "base", "index", "mem", "left", "right" ],
1800 outs => [ "flags" ],
1801 am => "source,binary",
1802 attr => "bool ins_permuted",
1803 init_attr => "attr->data.ins_permuted = ins_permuted;",
1804 emit => 'ucomis%FX %B',
1807 mode => $mode_flags,
1808 modified_flags => 1,
1812 op_flags => [ "uses_memory", "fragile" ],
1813 state => "exc_pinned",
1814 reg_req => { in => [ "gp", "gp", "none" ],
1815 out => [ "xmm", "none", "none", "none", "none" ] },
1816 ins => [ "base", "index", "mem" ],
1817 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1818 emit => 'movs%FX %AM, %D0',
1819 attr => "ir_mode *load_mode",
1820 init_attr => "attr->ls_mode = load_mode;",
1826 op_flags => [ "uses_memory", "fragile" ],
1827 state => "exc_pinned",
1828 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1829 out => [ "none", "none", "none" ] },
1830 ins => [ "base", "index", "mem", "val" ],
1831 outs => [ "M", "X_regular", "X_except" ],
1832 emit => 'movs%FX %S3, %AM',
1838 op_flags => [ "uses_memory", "fragile" ],
1839 state => "exc_pinned",
1840 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1841 out => [ "none", "none", "none" ] },
1842 ins => [ "base", "index", "mem", "val" ],
1843 outs => [ "M", "X_regular", "X_except" ],
1844 emit => 'movs%FX %S3, %AM',
1850 state => "exc_pinned",
1851 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1852 ins => [ "base", "index", "mem", "val" ],
1853 am => "source,unary",
1854 emit => 'cvtsi2ss %AS3, %D0',
1861 state => "exc_pinned",
1862 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1863 ins => [ "base", "index", "mem", "val" ],
1864 am => "source,unary",
1865 emit => 'cvtsi2sd %AS3, %D0',
1873 ins => [ "val_high", "val_low" ],
1875 dump_func => "NULL",
1880 outs => [ "res_high", "res_low" ],
1882 dump_func => "NULL",
1886 op_flags => [ "uses_memory", "fragile" ],
1888 reg_req => { in => [ "edi", "esi", "ecx", "none" ],
1889 out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1890 ins => [ "dest", "source", "count", "mem" ],
1891 outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1892 attr_type => "ia32_copyb_attr_t",
1893 attr => "unsigned size",
1896 # we don't care about this flag, so no need to mark this node
1897 # modified_flags => [ "DF" ]
1901 op_flags => [ "uses_memory", "fragile" ],
1903 reg_req => { in => [ "edi", "esi", "none" ],
1904 out => [ "edi", "esi", "none", "none", "none" ] },
1905 ins => [ "dest", "source", "mem" ],
1906 outs => [ "dest", "source", "M", "X_regular", "X_except" ],
1907 attr_type => "ia32_copyb_attr_t",
1908 attr => "unsigned size",
1911 # we don't care about this flag, so no need to mark this node
1912 # modified_flags => [ "DF" ]
1916 state => "exc_pinned",
1917 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1927 op_flags => [ "uses_memory", "fragile" ],
1928 state => "exc_pinned",
1929 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1930 out => [ "gp", "none", "none", "none", "none" ] },
1931 ins => [ "base", "index", "mem", "val" ],
1932 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1933 emit => "mov%#Ml %#AS3, %D0",
1934 am => "source,unary",
1937 attr => "ir_mode *smaller_mode",
1938 init_attr => "attr->ls_mode = smaller_mode;",
1943 op_flags => [ "uses_memory", "fragile" ],
1944 state => "exc_pinned",
1945 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1946 out => [ "gp", "none", "none", "none", "none" ] },
1947 ins => [ "base", "index", "mem", "val" ],
1948 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1949 emit => "mov%#Ml %#AS3, %D0",
1950 am => "source,unary",
1953 attr => "ir_mode *smaller_mode",
1954 init_attr => "attr->ls_mode = smaller_mode;",
1959 state => "exc_pinned",
1960 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1961 ins => [ "base", "index", "mem", "val" ],
1962 am => "source,unary",
1969 state => "exc_pinned",
1970 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1971 ins => [ "base", "index", "mem", "val" ],
1972 am => "source,unary",
1979 state => "exc_pinned",
1980 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1981 ins => [ "base", "index", "mem", "val" ],
1982 am => "source,unary",
1988 # rematerialisation disabled for all float nodes for now, because the fpcw
1989 # handler runs before spilling and we might end up with wrong fpcw then
1992 # irn_flags => [ "rematerializable" ],
1993 state => "exc_pinned",
1994 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1995 out => [ "fp", "none", "none" ] },
1996 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1997 outs => [ "res", "dummy", "M" ],
1998 emit => 'fadd%FP%FM %AF',
1999 am => "source,binary",
2003 attr_type => "ia32_x87_attr_t",
2007 # irn_flags => [ "rematerializable" ],
2008 state => "exc_pinned",
2009 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2010 out => [ "fp", "none", "none" ] },
2011 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2012 outs => [ "res", "dummy", "M" ],
2013 emit => 'fmul%FP%FM %AF',
2014 am => "source,binary",
2018 attr_type => "ia32_x87_attr_t",
2022 # irn_flags => [ "rematerializable" ],
2023 state => "exc_pinned",
2024 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2025 out => [ "fp", "none", "none" ] },
2026 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2027 outs => [ "res", "dummy", "M" ],
2028 emit => 'fsub%FR%FP%FM %AF',
2029 am => "source,binary",
2033 attr_type => "ia32_x87_attr_t",
2037 state => "exc_pinned",
2038 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2039 out => [ "fp", "none", "none" ] },
2040 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2041 outs => [ "res", "dummy", "M" ],
2042 emit => 'fdiv%FR%FP%FM %AF',
2043 am => "source,binary",
2046 attr_type => "ia32_x87_attr_t",
2050 reg_req => { in => [ "fp", "fp", "fpcw" ], out => [ "fp" ] },
2051 ins => [ "left", "right", "fpcw" ],
2056 attr_type => "ia32_x87_attr_t",
2060 irn_flags => [ "rematerializable" ],
2061 reg_req => { in => [ "fp"], out => [ "fp" ] },
2067 attr_type => "ia32_x87_attr_t",
2071 irn_flags => [ "rematerializable" ],
2072 reg_req => { in => [ "fp"], out => [ "fp" ] },
2078 attr_type => "ia32_x87_attr_t",
2082 irn_flags => [ "rematerializable" ],
2083 op_flags => [ "uses_memory", "fragile" ],
2084 state => "exc_pinned",
2085 reg_req => { in => [ "gp", "gp", "none" ],
2086 out => [ "fp", "none", "none", "none", "none" ] },
2087 ins => [ "base", "index", "mem" ],
2088 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
2089 emit => 'fld%FM %AM',
2090 attr => "ir_mode *load_mode",
2091 init_attr => "attr->attr.ls_mode = load_mode;",
2094 attr_type => "ia32_x87_attr_t",
2098 irn_flags => [ "rematerializable" ],
2099 op_flags => [ "uses_memory", "fragile" ],
2100 state => "exc_pinned",
2101 reg_req => { in => [ "gp", "gp", "none", "fp" ],
2102 out => [ "none", "none", "none" ] },
2103 ins => [ "base", "index", "mem", "val" ],
2104 outs => [ "M", "X_regular", "X_except" ],
2105 emit => 'fst%FP%FM %AM',
2106 attr => "ir_mode *store_mode",
2107 init_attr => "attr->attr.ls_mode = store_mode;",
2110 attr_type => "ia32_x87_attr_t",
2114 state => "exc_pinned",
2115 reg_req => { in => [ "gp", "gp", "none" ],
2116 out => [ "fp", "none", "none" ] },
2117 outs => [ "res", "unused", "M" ],
2118 ins => [ "base", "index", "mem" ],
2119 emit => 'fild%FM %AM',
2122 attr_type => "ia32_x87_attr_t",
2126 op_flags => [ "uses_memory", "fragile" ],
2127 state => "exc_pinned",
2128 reg_req => { in => [ "gp", "gp", "none", "fp", "fpcw" ],
2129 out => [ "none", "none", "none", "none" ] },
2130 ins => [ "base", "index", "mem", "val", "fpcw" ],
2131 outs => [ "dummy", "M", "X_regular", "X_except" ],
2132 emit => 'fist%FP%FM %AM',
2135 attr_type => "ia32_x87_attr_t",
2138 # SSE3 fisttp instruction
2140 op_flags => [ "uses_memory", "fragile" ],
2141 state => "exc_pinned",
2142 reg_req => { in => [ "gp", "gp", "none", "fp" ],
2143 out => [ "in_r4", "none", "none", "none" ]},
2144 ins => [ "base", "index", "mem", "val" ],
2145 outs => [ "res", "M", "X_regular", "X_except" ],
2146 emit => 'fisttp%FM %AM',
2149 attr_type => "ia32_x87_attr_t",
2153 irn_flags => [ "rematerializable" ],
2154 reg_req => { out => [ "fp" ] },
2160 attr_type => "ia32_x87_attr_t",
2164 irn_flags => [ "rematerializable" ],
2165 reg_req => { out => [ "fp" ] },
2171 attr_type => "ia32_x87_attr_t",
2175 irn_flags => [ "rematerializable" ],
2176 reg_req => { out => [ "fp" ] },
2182 attr_type => "ia32_x87_attr_t",
2186 irn_flags => [ "rematerializable" ],
2187 reg_req => { out => [ "fp" ] },
2193 attr_type => "ia32_x87_attr_t",
2197 irn_flags => [ "rematerializable" ],
2198 reg_req => { out => [ "fp" ] },
2204 attr_type => "ia32_x87_attr_t",
2208 irn_flags => [ "rematerializable" ],
2209 reg_req => { out => [ "fp" ] },
2215 attr_type => "ia32_x87_attr_t",
2219 irn_flags => [ "rematerializable" ],
2220 reg_req => { out => [ "fp" ] },
2226 attr_type => "ia32_x87_attr_t",
2230 # we can't allow to rematerialize this node so we don't
2231 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2232 # irn_flags => [ "rematerializable" ],
2233 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2234 ins => [ "left", "right" ],
2235 outs => [ "flags" ],
2236 emit => "fucom%FP %F0\n".
2238 attr => "bool ins_permuted",
2239 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2242 attr_type => "ia32_x87_attr_t",
2247 # we can't allow to rematerialize this node so we don't
2248 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2249 # irn_flags => [ "rematerializable" ],
2250 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2251 ins => [ "left", "right" ],
2252 outs => [ "flags" ],
2253 emit => "fucompp\n".
2255 attr => "bool ins_permuted",
2256 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2259 attr_type => "ia32_x87_attr_t",
2264 irn_flags => [ "rematerializable" ],
2265 reg_req => { in => [ "fp", "fp" ], out => [ "eflags" ] },
2266 ins => [ "left", "right" ],
2267 outs => [ "flags" ],
2268 emit => 'fucom%FPi %F0',
2269 attr => "bool ins_permuted",
2270 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2273 attr_type => "ia32_x87_attr_t",
2278 # irn_flags => [ "rematerializable" ],
2279 reg_req => { in => [ "fp" ], out => [ "eax" ] },
2281 outs => [ "flags" ],
2284 attr => "bool ins_permuted",
2285 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2288 attr_type => "ia32_x87_attr_t",
2293 irn_flags => [ "rematerializable" ],
2294 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2296 outs => [ "flags" ],
2300 mode => $mode_flags,
2304 # Note that it is NEVER allowed to do CSE on these nodes
2305 # Moreover, note the virtual register requierements!
2308 op_flags => [ "keep" ],
2309 reg_req => { out => [ "none" ] },
2310 cmp_attr => "return 1;",
2312 attr_type => "ia32_x87_attr_t",
2318 op_flags => [ "keep" ],
2319 reg_req => { out => [ "none" ] },
2320 cmp_attr => "return 1;",
2322 attr_type => "ia32_x87_attr_t",
2328 reg_req => { in => [ "fp"], out => [ "fp" ] },
2329 cmp_attr => "return 1;",
2331 attr_type => "ia32_x87_attr_t",
2336 op_flags => [ "keep" ],
2337 reg_req => { out => [ "none" ] },
2338 cmp_attr => "return 1;",
2340 attr_type => "ia32_x87_attr_t",
2346 op_flags => [ "keep" ],
2347 reg_req => { out => [ "none" ] },
2348 cmp_attr => "return 1;",
2349 emit => 'ffreep %F0',
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",
2366 op_flags => [ "keep" ],
2367 reg_req => { out => [ "none" ] },
2368 cmp_attr => "return 1;",
2370 attr_type => "ia32_x87_attr_t",
2375 # Spilling and reloading of SSE registers, hardcoded, not generated #
2378 op_flags => [ "uses_memory", "fragile" ],
2379 state => "exc_pinned",
2380 reg_req => { in => [ "gp", "gp", "none" ],
2381 out => [ "xmm", "none", "none", "none" ] },
2382 emit => 'movdqu %D0, %AM',
2383 ins => [ "base", "index", "mem" ],
2384 outs => [ "res", "M", "X_regular", "X_except" ],
2390 op_flags => [ "uses_memory", "fragile" ],
2391 state => "exc_pinned",
2392 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
2393 out => [ "none", "none", "none" ] },
2394 ins => [ "base", "index", "mem", "val" ],
2395 outs => [ "M", "X_regular", "X_except" ],
2396 emit => 'movdqu %B',
2403 # Transform some attributes
2404 foreach my $op (keys(%nodes)) {
2405 my $node = $nodes{$op};
2406 my $op_attr_init = $node->{op_attr_init};
2408 if(defined($op_attr_init)) {
2409 $op_attr_init .= "\n\t";
2414 if(!defined($node->{latency})) {
2416 $node->{latency} = 0;
2418 die("Latency missing for op $op");
2421 $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2423 $node->{op_attr_init} = $op_attr_init;