1 # This is the specification for the ia32 assembler Firm-operations
7 $mode_fp87 = "ia32_mode_E";
9 $mode_flags = "mode_Iu";
10 $mode_fpcw = "ia32_mode_fpcw";
14 { name => "edx", dwarf => 2 },
15 { name => "ecx", dwarf => 1 },
16 { name => "eax", dwarf => 0 },
17 { name => "ebx", dwarf => 3 },
18 { name => "esi", dwarf => 6 },
19 { name => "edi", dwarf => 7 },
20 { name => "ebp", dwarf => 5 },
21 { name => "esp", dwarf => 4, type => "ignore" },
22 { name => "gp_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
26 { name => "mm0", dwarf => 29, type => "ignore" },
27 { name => "mm1", dwarf => 30, type => "ignore" },
28 { name => "mm2", dwarf => 31, type => "ignore" },
29 { name => "mm3", dwarf => 32, type => "ignore" },
30 { name => "mm4", dwarf => 33, type => "ignore" },
31 { name => "mm5", dwarf => 34, type => "ignore" },
32 { name => "mm6", dwarf => 35, type => "ignore" },
33 { name => "mm7", dwarf => 36, type => "ignore" },
34 { mode => $mode_mmx, flags => "manual_ra" }
37 { name => "xmm0", dwarf => 21 },
38 { name => "xmm1", dwarf => 22 },
39 { name => "xmm2", dwarf => 23 },
40 { name => "xmm3", dwarf => 24 },
41 { name => "xmm4", dwarf => 25 },
42 { name => "xmm5", dwarf => 26 },
43 { name => "xmm6", dwarf => 27 },
44 { name => "xmm7", dwarf => 28 },
45 { name => "xmm_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
49 { name => "st0", realname => "st", dwarf => 11 },
50 { name => "st1", realname => "st(1)", dwarf => 12 },
51 { name => "st2", realname => "st(2)", dwarf => 13 },
52 { name => "st3", realname => "st(3)", dwarf => 14 },
53 { name => "st4", realname => "st(4)", dwarf => 15 },
54 { name => "st5", realname => "st(5)", dwarf => 16 },
55 { name => "st6", realname => "st(6)", dwarf => 17 },
56 { name => "st7", realname => "st(7)", dwarf => 18 },
57 { name => "fp_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
58 { mode => $mode_fp87 }
60 fp_cw => [ # the floating point control word
61 { name => "fpcw", dwarf => 37, type => "ignore | state" },
62 { mode => $mode_fpcw, flags => "manual_ra | state" }
65 { name => "eflags", dwarf => 9 },
66 { mode => "mode_Iu", flags => "manual_ra" }
71 GP => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
72 SSE => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
73 VFP => [ 1, "VFP_VF0", "VFP_VF1", "VFP_VF2", "VFP_VF3", "VFP_VF4", "VFP_VF5", "VFP_VF6", "VFP_VF7" ],
74 BRANCH => [ 1, "BRANCH1", "BRANCH2" ],
79 bundels_per_cycle => 1
82 $default_op_attr_type = "ia32_op_attr_t";
83 $default_attr_type = "ia32_attr_t";
84 $default_copy_attr = "ia32_copy_attr";
86 sub ia32_custom_init_attr {
92 if(defined($node->{modified_flags})) {
93 $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n";
95 if(defined($node->{am})) {
97 if($am eq "source,unary") {
98 $res .= "\tset_ia32_am_support(res, ia32_am_unary);";
99 } elsif($am eq "source,binary") {
100 $res .= "\tset_ia32_am_support(res, ia32_am_binary);";
101 } elsif($am eq "none") {
104 die("Invalid address mode '$am' specified on op $name");
107 if($node->{state} ne "exc_pinned"
108 and $node->{state} ne "pinned") {
109 die("AM nodes must have pinned or AM pinned state ($name)");
115 $custom_init_attr_func = \&ia32_custom_init_attr;
119 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
120 "\tinit_ia32_x87_attributes(res);".
121 "\tinit_ia32_asm_attributes(res);",
123 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);",
125 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
126 "\tinit_ia32_call_attributes(res, pop, call_tp);",
127 ia32_condcode_attr_t =>
128 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
129 "\tinit_ia32_condcode_attributes(res, condition_code);",
130 ia32_switch_attr_t =>
131 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
132 "\tinit_ia32_switch_attributes(res, switch_table);",
134 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
135 "\tinit_ia32_copyb_attributes(res, size);",
136 ia32_immediate_attr_t =>
137 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
138 "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
140 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
141 "\tinit_ia32_x87_attributes(res);",
142 ia32_climbframe_attr_t =>
143 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
144 "\tinit_ia32_climbframe_attributes(res, count);",
148 ia32_asm_attr_t => "ia32_compare_asm_attr",
149 ia32_attr_t => "ia32_compare_nodes_attr",
150 ia32_call_attr_t => "ia32_compare_call_attr",
151 ia32_condcode_attr_t => "ia32_compare_condcode_attr",
152 ia32_copyb_attr_t => "ia32_compare_copyb_attr",
153 ia32_switch_attr_t => "ia32_compare_nodes_attr",
154 ia32_immediate_attr_t => "ia32_compare_immediate_attr",
155 ia32_x87_attr_t => "ia32_compare_x87_attr",
156 ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
162 $status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
163 $status_flags_wo_cf = [ "PF", "AF", "ZF", "SF", "OF" ];
164 $fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
165 "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
171 op_flags => [ "constlike" ],
172 irn_flags => [ "not_scheduled" ],
173 reg_req => { out => [ "gp_NOREG:I" ] },
174 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
175 attr_type => "ia32_immediate_attr_t",
176 hash_func => "ia32_hash_Immediate",
184 out_arity => "variable",
185 attr_type => "ia32_asm_attr_t",
186 attr => "ident *asm_text, const ia32_asm_reg_t *register_map",
187 init_attr => "attr->asm_text = asm_text;\n".
188 "\tattr->register_map = register_map;\n",
190 modified_flags => $status_flags,
193 # "allocates" a free register
195 op_flags => [ "constlike", "cse_neutral" ],
196 irn_flags => [ "rematerializable" ],
197 reg_req => { out => [ "gp" ] },
202 cmp_attr => "return 1;",
206 irn_flags => [ "rematerializable" ],
207 state => "exc_pinned",
208 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
209 out => [ "in_r4 in_r5", "flags", "none" ] },
210 ins => [ "base", "index", "mem", "left", "right" ],
211 outs => [ "res", "flags", "M" ],
213 am => "source,binary",
217 modified_flags => $status_flags
221 irn_flags => [ "rematerializable" ],
222 state => "exc_pinned",
223 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
224 ins => [ "base", "index", "mem", "val" ],
225 emit => "add%M %#S3, %AM",
229 modified_flags => $status_flags
233 irn_flags => [ "rematerializable" ],
234 state => "exc_pinned",
235 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
236 ins => [ "base", "index", "mem", "val" ],
237 emit => "add%M %#S3, %AM",
241 modified_flags => $status_flags
245 state => "exc_pinned",
246 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
247 out => [ "in_r4 in_r5", "flags", "none" ] },
248 ins => [ "base", "index", "mem", "left", "right", "eflags" ],
249 outs => [ "res", "flags", "M" ],
251 am => "source,binary",
255 modified_flags => $status_flags
259 ins => [ "left", "right" ],
265 ins => [ "left", "right", "eflags" ],
271 # we should not rematrialize this node. It produces 2 results and has
272 # very strict constraints
273 state => "exc_pinned",
274 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
275 out => [ "eax", "flags", "none", "edx" ] },
276 ins => [ "base", "index", "mem", "left", "right" ],
277 emit => 'mul%M %AS4',
278 outs => [ "res_low", "flags", "M", "res_high" ],
279 am => "source,binary",
282 modified_flags => $status_flags
286 ins => [ "left", "right" ],
287 outs => [ "res_low", "flags", "M", "res_high" ],
293 irn_flags => [ "rematerializable" ],
294 state => "exc_pinned",
295 # TODO: adjust out requirements for the 3 operand form
296 # (no need for should_be_same then)
297 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
298 out => [ "in_r4 in_r5", "flags", "none" ] },
299 ins => [ "base", "index", "mem", "left", "right" ],
300 outs => [ "res", "flags", "M" ],
301 am => "source,binary",
305 modified_flags => $status_flags
309 irn_flags => [ "rematerializable" ],
310 state => "exc_pinned",
311 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
312 out => [ "eax", "flags", "none", "edx" ] },
313 ins => [ "base", "index", "mem", "left", "right" ],
314 emit => 'imul%M %AS4',
315 outs => [ "res_low", "flags", "M", "res_high" ],
316 am => "source,binary",
319 modified_flags => $status_flags
323 ins => [ "left", "right" ],
324 outs => [ "res_low", "flags", "M", "res_high" ],
330 irn_flags => [ "rematerializable" ],
331 state => "exc_pinned",
332 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
333 out => [ "in_r4 in_r5", "flags", "none" ] },
334 ins => [ "base", "index", "mem", "left", "right" ],
335 outs => [ "res", "flags", "M" ],
336 am => "source,binary",
341 modified_flags => $status_flags
345 irn_flags => [ "rematerializable" ],
346 state => "exc_pinned",
347 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
348 ins => [ "base", "index", "mem", "val" ],
349 emit => 'and%M %#S3, %AM',
353 modified_flags => $status_flags
357 irn_flags => [ "rematerializable" ],
358 state => "exc_pinned",
359 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
360 ins => [ "base", "index", "mem", "val" ],
361 emit => 'and%M %#S3, %AM',
365 modified_flags => $status_flags
369 irn_flags => [ "rematerializable" ],
370 state => "exc_pinned",
371 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
372 out => [ "in_r4 in_r5", "flags", "none" ] },
373 ins => [ "base", "index", "mem", "left", "right" ],
374 outs => [ "res", "flags", "M" ],
375 am => "source,binary",
380 modified_flags => $status_flags
384 irn_flags => [ "rematerializable" ],
385 state => "exc_pinned",
386 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
387 ins => [ "base", "index", "mem", "val" ],
388 emit => 'or%M %#S3, %AM',
392 modified_flags => $status_flags
396 irn_flags => [ "rematerializable" ],
397 state => "exc_pinned",
398 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
399 ins => [ "base", "index", "mem", "val" ],
400 emit => 'or%M %#S3, %AM',
404 modified_flags => $status_flags
408 irn_flags => [ "rematerializable" ],
409 state => "exc_pinned",
410 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
411 out => [ "in_r4 in_r5", "flags", "none" ] },
412 ins => [ "base", "index", "mem", "left", "right" ],
413 outs => [ "res", "flags", "M" ],
414 am => "source,binary",
419 modified_flags => $status_flags
423 op_flags => [ "constlike" ],
424 irn_flags => [ "rematerializable" ],
425 reg_req => { out => [ "gp", "flags" ] },
426 outs => [ "res", "flags" ],
427 emit => "xor%M %D0, %D0",
431 modified_flags => $status_flags
435 irn_flags => [ "rematerializable" ],
436 state => "exc_pinned",
437 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
438 ins => [ "base", "index", "mem", "val" ],
439 emit => 'xor%M %#S3, %AM',
443 modified_flags => $status_flags
447 irn_flags => [ "rematerializable" ],
448 state => "exc_pinned",
449 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
450 ins => [ "base", "index", "mem", "val" ],
451 emit => 'xor%M %#S3, %AM',
455 modified_flags => $status_flags
459 irn_flags => [ "rematerializable" ],
460 state => "exc_pinned",
461 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
462 out => [ "in_r4", "flags", "none" ] },
463 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
464 outs => [ "res", "flags", "M" ],
465 am => "source,binary",
470 modified_flags => $status_flags
474 irn_flags => [ "rematerializable" ],
475 state => "exc_pinned",
476 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
477 ins => [ "base", "index", "mem", "subtrahend" ],
478 emit => 'sub%M %#S3, %AM',
482 modified_flags => $status_flags
486 irn_flags => [ "rematerializable" ],
487 state => "exc_pinned",
488 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
489 ins => [ "base", "index", "mem", "subtrahend" ],
490 emit => 'sub%M %#S3, %AM',
494 modified_flags => $status_flags
498 state => "exc_pinned",
499 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
500 out => [ "in_r4", "flags", "none" ] },
501 ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
502 outs => [ "res", "flags", "M" ],
503 am => "source,binary",
508 modified_flags => $status_flags
512 # Spiller currently fails when rematerializing flag consumers
513 # irn_flags => [ "rematerializable" ],
514 reg_req => { in => [ "flags" ], out => [ "gp", "flags" ] },
515 outs => [ "res", "flags" ],
516 emit => "sbb%M %D0, %D0",
520 modified_flags => $status_flags
524 ins => [ "minuend", "subtrahend" ],
530 ins => [ "minuend", "subtrahend", "eflags" ],
536 op_flags => [ "fragile", "uses_memory" ],
537 state => "exc_pinned",
538 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
539 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
540 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
541 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
542 am => "source,unary",
543 emit => "idiv%M %AS3",
546 modified_flags => $status_flags
550 op_flags => [ "fragile", "uses_memory" ],
551 state => "exc_pinned",
552 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
553 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
554 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
555 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
556 am => "source,unary",
557 emit => "div%M %AS3",
560 modified_flags => $status_flags
564 irn_flags => [ "rematerializable" ],
565 reg_req => { in => [ "gp", "ecx" ],
566 out => [ "in_r1 !in_r2", "flags" ] },
567 ins => [ "val", "count" ],
568 outs => [ "res", "flags" ],
569 emit => 'shl%M %<S1, %S0',
573 modified_flags => $status_flags
577 irn_flags => [ "rematerializable" ],
578 state => "exc_pinned",
579 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
580 ins => [ "base", "index", "mem", "count" ],
581 emit => 'shl%M %<S3, %AM',
585 modified_flags => $status_flags
589 irn_flags => [ "rematerializable" ],
590 reg_req => { in => [ "gp", "gp", "ecx" ],
591 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
592 ins => [ "val_high", "val_low", "count" ],
593 outs => [ "res", "flags" ],
594 emit => "shld%M %<S2, %S1, %D0",
598 modified_flags => $status_flags
602 irn_flags => [ "rematerializable" ],
603 reg_req => { in => [ "gp", "ecx" ],
604 out => [ "in_r1 !in_r2", "flags" ] },
605 ins => [ "val", "count" ],
606 outs => [ "res", "flags" ],
607 emit => 'shr%M %<S1, %S0',
611 modified_flags => $status_flags
615 irn_flags => [ "rematerializable" ],
616 state => "exc_pinned",
617 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
618 ins => [ "base", "index", "mem", "count" ],
619 emit => 'shr%M %<S3, %AM',
623 modified_flags => $status_flags
627 irn_flags => [ "rematerializable" ],
628 reg_req => { in => [ "gp", "gp", "ecx" ],
629 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
630 ins => [ "val_high", "val_low", "count" ],
631 outs => [ "res", "flags" ],
632 emit => "shrd%M %<S2, %S1, %D0",
636 modified_flags => $status_flags
640 irn_flags => [ "rematerializable" ],
641 reg_req => { in => [ "gp", "ecx" ],
642 out => [ "in_r1 !in_r2", "flags" ] },
643 ins => [ "val", "count" ],
644 outs => [ "res", "flags" ],
645 emit => 'sar%M %<S1, %S0',
649 modified_flags => $status_flags
653 irn_flags => [ "rematerializable" ],
654 state => "exc_pinned",
655 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
656 ins => [ "base", "index", "mem", "count" ],
657 emit => 'sar%M %<S3, %AM',
661 modified_flags => $status_flags
665 irn_flags => [ "rematerializable" ],
666 reg_req => { in => [ "gp", "ecx" ],
667 out => [ "in_r1 !in_r2", "flags" ] },
668 ins => [ "val", "count" ],
669 outs => [ "res", "flags" ],
670 emit => 'ror%M %<S1, %S0',
674 modified_flags => $status_flags
678 irn_flags => [ "rematerializable" ],
679 state => "exc_pinned",
680 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
681 ins => [ "base", "index", "mem", "count" ],
682 emit => 'ror%M %<S3, %AM',
686 modified_flags => $status_flags
690 irn_flags => [ "rematerializable" ],
691 reg_req => { in => [ "gp", "ecx" ],
692 out => [ "in_r1 !in_r2", "flags" ] },
693 ins => [ "val", "count" ],
694 outs => [ "res", "flags" ],
695 emit => 'rol%M %<S1, %D0',
699 modified_flags => $status_flags
703 irn_flags => [ "rematerializable" ],
704 state => "exc_pinned",
705 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
706 ins => [ "base", "index", "mem", "count" ],
707 emit => 'rol%M %<S3, %AM',
711 modified_flags => $status_flags
715 irn_flags => [ "rematerializable" ],
716 reg_req => { in => [ "gp" ],
717 out => [ "in_r1", "flags" ] },
720 outs => [ "res", "flags" ],
724 modified_flags => $status_flags
728 irn_flags => [ "rematerializable" ],
729 state => "exc_pinned",
730 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
731 ins => [ "base", "index", "mem" ],
736 modified_flags => $status_flags
740 irn_flags => [ "rematerializable" ],
741 reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
742 outs => [ "low_res", "high_res" ],
745 modified_flags => $status_flags
750 irn_flags => [ "rematerializable" ],
751 reg_req => { in => [ "gp" ],
752 out => [ "in_r1", "flags" ] },
754 outs => [ "res", "flags" ],
759 modified_flags => $status_flags_wo_cf
763 irn_flags => [ "rematerializable" ],
764 state => "exc_pinned",
765 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
766 ins => [ "base", "index", "mem" ],
771 modified_flags => $status_flags_wo_cf
775 irn_flags => [ "rematerializable" ],
776 reg_req => { in => [ "gp" ],
777 out => [ "in_r1", "flags" ] },
779 outs => [ "res", "flags" ],
784 modified_flags => $status_flags_wo_cf
788 irn_flags => [ "rematerializable" ],
789 state => "exc_pinned",
790 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
791 ins => [ "base", "index", "mem" ],
796 modified_flags => $status_flags_wo_cf
800 irn_flags => [ "rematerializable" ],
801 reg_req => { in => [ "gp" ],
802 out => [ "in_r1" ] },
813 irn_flags => [ "rematerializable" ],
814 state => "exc_pinned",
815 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
816 ins => [ "base", "index", "mem" ],
825 reg_req => { in => [ "flags" ], out => [ "flags" ] },
830 modified_flags => $status_flags
834 reg_req => { out => [ "flags" ] },
839 modified_flags => $status_flags
843 irn_flags => [ "rematerializable" ],
844 state => "exc_pinned",
845 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
846 out => [ "flags", "none", "none" ] },
847 ins => [ "base", "index", "mem", "left", "right" ],
848 outs => [ "eflags", "unused", "M" ],
849 am => "source,binary",
851 attr => "bool ins_permuted",
852 init_attr => "attr->data.ins_permuted = ins_permuted;",
856 modified_flags => $status_flags
860 irn_flags => [ "rematerializable" ],
861 state => "exc_pinned",
862 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
863 out => [ "flags", "none", "none" ] },
864 ins => [ "base", "index", "mem", "left", "right" ],
865 outs => [ "eflags", "unused", "M" ],
866 am => "source,binary",
868 attr => "bool ins_permuted",
869 init_attr => "attr->data.ins_permuted = ins_permuted;",
873 modified_flags => $status_flags
877 irn_flags => [ "rematerializable" ],
878 state => "exc_pinned",
879 reg_req => { in => [ "eax ebx ecx edx" ],
880 out => [ "in_r1", "flags" ] },
881 emit => 'xorb %>S0, %<S0',
883 outs => [ "res", "flags" ],
887 modified_flags => $status_flags,
891 irn_flags => [ "rematerializable" ],
892 state => "exc_pinned",
893 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] ,
894 out => [ "flags", "none", "none" ] },
895 ins => [ "base", "index", "mem", "left", "right" ],
896 outs => [ "eflags", "unused", "M" ],
897 am => "source,binary",
899 attr => "bool ins_permuted",
900 init_attr => "attr->data.ins_permuted = ins_permuted;",
904 modified_flags => $status_flags
908 irn_flags => [ "rematerializable" ],
909 state => "exc_pinned",
910 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
911 out => [ "flags", "none", "none" ] },
912 ins => [ "base", "index", "mem", "left", "right" ],
913 outs => [ "eflags", "unused", "M" ],
914 am => "source,binary",
916 attr => "bool ins_permuted",
917 init_attr => "attr->data.ins_permuted = ins_permuted;",
921 modified_flags => $status_flags
925 #irn_flags => [ "rematerializable" ],
926 reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
929 attr_type => "ia32_condcode_attr_t",
930 attr => "ia32_condition_code_t condition_code",
931 # The way we handle Setcc with float nodes (potentially) destroys the flags
932 # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
933 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
934 . "\tif (condition_code & ia32_cc_additional_float_cases) {\n"
935 . "\t\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"
936 . "\t\t/* attr->latency = 3; */\n"
944 #irn_flags => [ "rematerializable" ],
945 state => "exc_pinned",
946 reg_req => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
947 ins => [ "base", "index", "mem","eflags" ],
948 attr_type => "ia32_condcode_attr_t",
949 attr => "ia32_condition_code_t condition_code",
950 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
951 emit => 'set%P3 %AM',
958 #irn_flags => [ "rematerializable" ],
959 state => "exc_pinned",
960 # (note: leave the false,true order intact to make it compatible with other
962 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
963 out => [ "in_r4 in_r5", "flags", "none" ] },
964 ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
965 outs => [ "res", "flags", "M" ],
966 am => "source,binary",
967 attr_type => "ia32_condcode_attr_t",
968 attr => "ia32_condition_code_t condition_code",
976 op_flags => [ "cfopcode", "forking" ],
977 reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
979 outs => [ "false", "true" ],
980 attr_type => "ia32_condcode_attr_t",
981 attr => "ia32_condition_code_t condition_code",
983 units => [ "BRANCH" ],
988 op_flags => [ "cfopcode", "forking" ],
989 reg_req => { in => [ "gp", "gp" ] },
990 ins => [ "base", "index" ],
991 out_arity => "variable",
992 attr_type => "ia32_switch_attr_t",
993 attr => "const ir_switch_table *switch_table",
995 units => [ "BRANCH" ],
1000 irn_flags => [ "simple_jump" ],
1001 op_flags => [ "cfopcode" ],
1002 reg_req => { out => [ "none" ] },
1004 units => [ "BRANCH" ],
1010 op_flags => [ "cfopcode", "unknown_jump" ],
1011 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1012 out => [ "none", "flags", "none" ] },
1013 ins => [ "base", "index", "mem", "target" ],
1014 outs => [ "jmp", "flags", "M" ],
1015 am => "source,unary",
1016 emit => 'jmp %*AS3',
1018 units => [ "BRANCH" ],
1023 op_flags => [ "constlike" ],
1024 irn_flags => [ "rematerializable" ],
1025 reg_req => { out => [ "gp" ] },
1026 emit => "movl %I, %D0",
1028 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
1029 attr_type => "ia32_immediate_attr_t",
1035 op_flags => [ "constlike" ],
1036 irn_flags => [ "rematerializable" ],
1037 reg_req => { out => [ "gp" ] },
1044 op_flags => [ "constlike" ],
1045 reg_req => { out => [ "gp" ] },
1049 modified_flags => $status_flags,
1054 op_flags => [ "constlike", "dump_noblock" ],
1055 irn_flags => [ "not_scheduled" ],
1056 reg_req => { out => [ "gp_NOREG:I" ] },
1065 op_flags => [ "constlike", "dump_noblock" ],
1066 irn_flags => [ "not_scheduled" ],
1067 reg_req => { out => [ "fp_NOREG:I" ] },
1072 attr_type => "ia32_x87_attr_t",
1077 op_flags => [ "constlike", "dump_noblock" ],
1078 irn_flags => [ "not_scheduled" ],
1079 reg_req => { out => [ "xmm_NOREG:I" ] },
1088 op_flags => [ "constlike" ],
1089 irn_flags => [ "not_scheduled" ],
1090 reg_req => { out => [ "fpcw:I" ] },
1094 modified_flags => $fpcw_flags
1098 op_flags => [ "uses_memory" ],
1100 reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] },
1101 ins => [ "base", "index", "mem" ],
1103 emit => "fldcw %AM",
1106 modified_flags => $fpcw_flags
1110 op_flags => [ "uses_memory" ],
1112 reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1113 ins => [ "base", "index", "mem", "fpcw" ],
1115 emit => "fnstcw %AM",
1121 op_flags => [ "uses_memory" ],
1123 reg_req => { in => [ "fp_cw" ], out => [ "none" ] },
1131 # we should not rematrialize this node. It has very strict constraints.
1132 reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] },
1133 ins => [ "val", "clobbered" ],
1142 # Note that we add additional latency values depending on address mode, so a
1143 # lateny of 0 for load is correct
1146 op_flags => [ "uses_memory", "fragile" ],
1147 state => "exc_pinned",
1148 reg_req => { in => [ "gp", "gp", "none" ],
1149 out => [ "gp", "none", "none", "none", "none" ] },
1150 ins => [ "base", "index", "mem" ],
1151 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1153 emit => "mov%#Ml %AM, %D0",
1158 op_flags => [ "uses_memory", "fragile" ],
1159 state => "exc_pinned",
1160 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1161 out => [ "none", "none", "none" ] },
1162 ins => [ "base", "index", "mem", "val" ],
1163 outs => [ "M", "X_regular", "X_except" ],
1164 emit => 'mov%M %#S3, %AM',
1170 op_flags => [ "uses_memory", "fragile" ],
1171 state => "exc_pinned",
1172 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1173 out => ["none", "none", "none" ] },
1174 ins => [ "base", "index", "mem", "val" ],
1175 outs => [ "M", "X_regular", "X_except" ],
1176 emit => 'mov%M %#S3, %AM',
1182 irn_flags => [ "rematerializable" ],
1183 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1184 ins => [ "base", "index" ],
1185 emit => 'leal %AM, %D0',
1189 # lea doesn't modify the flags, but setting this seems advantageous since it
1190 # increases chances that the Lea is transformed back to an Add
1191 modified_flags => 1,
1195 state => "exc_pinned",
1196 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1197 ins => [ "base", "index", "mem", "val", "stack" ],
1198 emit => 'push%M %AS3',
1199 outs => [ "stack", "M" ],
1200 am => "source,unary",
1206 state => "exc_pinned",
1207 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1209 outs => [ "stack" ],
1210 emit => 'pushl %%eax',
1217 state => "exc_pinned",
1218 reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1219 ins => [ "mem", "stack" ],
1220 outs => [ "res", "M", "unused", "stack" ],
1221 emit => 'pop%M %D0',
1222 latency => 3, # Pop is more expensive than Push on Athlon
1227 state => "exc_pinned",
1228 reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1229 ins => [ "mem", "stack" ],
1230 outs => [ "res", "M", "unused", "stack" ],
1231 emit => 'pop%M %D0',
1232 latency => 3, # Pop is more expensive than Push on Athlon
1237 state => "exc_pinned",
1238 reg_req => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1241 emit => 'movl %S0, %D0',
1248 state => "exc_pinned",
1249 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1250 ins => [ "base", "index", "mem", "stack" ],
1251 outs => [ "unused0", "M", "unused1", "stack" ],
1252 emit => 'pop%M %AM',
1253 latency => 3, # Pop is more expensive than Push on Athlon
1258 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1260 outs => [ "frame", "stack", "M" ],
1266 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1268 outs => [ "frame", "stack" ],
1271 state => "exc_pinned",
1276 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1277 ins => [ "base", "index", "mem", "stack", "size" ],
1278 am => "source,binary",
1281 outs => [ "stack", "M" ],
1283 modified_flags => $status_flags
1288 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1289 ins => [ "base", "index", "mem", "stack", "size" ],
1290 am => "source,binary",
1291 emit => "subl %B\n".
1294 outs => [ "stack", "addr", "M" ],
1296 modified_flags => $status_flags
1300 op_flags => [ "keep" ],
1308 irn_flags => [ "rematerializable" ],
1309 reg_req => { out => [ "gp" ] },
1311 emit => "movl %%gs:0, %D0",
1317 # BT supports source address mode, but this is unused yet
1320 irn_flags => [ "rematerializable" ],
1321 state => "exc_pinned",
1322 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1323 ins => [ "left", "right" ],
1324 emit => 'bt%M %S1, %S0',
1327 mode => $mode_flags,
1328 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1332 irn_flags => [ "rematerializable" ],
1333 state => "exc_pinned",
1334 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1335 out => [ "gp", "flags", "none" ] },
1336 ins => [ "base", "index", "mem", "operand" ],
1337 outs => [ "res", "flags", "M" ],
1338 am => "source,binary",
1339 emit => 'bsf%M %AS3, %D0',
1343 modified_flags => $status_flags
1347 irn_flags => [ "rematerializable" ],
1348 state => "exc_pinned",
1349 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1350 out => [ "gp", "flags", "none" ] },
1351 ins => [ "base", "index", "mem", "operand" ],
1352 outs => [ "res", "flags", "M" ],
1353 am => "source,binary",
1354 emit => 'bsr%M %AS3, %D0',
1358 modified_flags => $status_flags
1362 # SSE4.2 or SSE4a popcnt instruction
1365 irn_flags => [ "rematerializable" ],
1366 state => "exc_pinned",
1367 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1368 out => [ "gp", "flags", "none" ] },
1369 ins => [ "base", "index", "mem", "operand" ],
1370 outs => [ "res", "flags", "M" ],
1371 am => "source,binary",
1372 emit => 'popcnt%M %AS3, %D0',
1376 modified_flags => $status_flags
1380 op_flags => [ "uses_memory", "fragile" ],
1381 state => "exc_pinned",
1383 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1384 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" ]
1386 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1387 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" ],
1388 emit => "call %*AS3",
1389 attr_type => "ia32_call_attr_t",
1390 attr => "unsigned pop, ir_type *call_tp",
1391 am => "source,unary",
1392 units => [ "BRANCH" ],
1393 latency => 4, # random number
1394 modified_flags => $status_flags
1398 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1400 # PS: try gcc __builtin_frame_address(100000) :-)
1403 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1404 ins => [ "frame", "cnt", "tmp" ],
1406 latency => 4, # random number
1407 attr_type => "ia32_climbframe_attr_t",
1408 attr => "unsigned count",
1417 irn_flags => [ "rematerializable" ],
1418 reg_req => { in => [ "gp" ],
1419 out => [ "in_r1" ] },
1421 emit => 'bswap%M %S0',
1429 # bswap16, use xchg here
1432 irn_flags => [ "rematerializable" ],
1433 reg_req => { in => [ "eax ebx ecx edx" ],
1434 out => [ "in_r1" ] },
1435 emit => 'xchg %<S0, %>S0',
1447 reg_req => { in => [ "none" ], out => [ "none" ] },
1456 # Undefined Instruction on ALL x86 CPU's
1460 reg_req => { in => [ "none" ], out => [ "none" ] },
1472 irn_flags => [ "rematerializable" ],
1474 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1475 ins => [ "port", "value", "mem" ],
1476 emit => 'out%M %^S0, %#S1',
1480 modified_flags => $status_flags
1487 irn_flags => [ "rematerializable" ],
1489 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1490 ins => [ "port", "mem" ],
1491 outs => [ "res", "M" ],
1492 emit => 'in%M %#D0, %^S0',
1496 modified_flags => $status_flags
1500 # Intel style prefetching
1503 op_flags => [ "uses_memory" ],
1504 state => "exc_pinned",
1505 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1506 ins => [ "base", "index", "mem" ],
1509 emit => "prefetcht0 %AM",
1514 op_flags => [ "uses_memory" ],
1515 state => "exc_pinned",
1516 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1517 ins => [ "base", "index", "mem" ],
1520 emit => "prefetcht1 %AM",
1525 op_flags => [ "uses_memory" ],
1526 state => "exc_pinned",
1527 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1528 ins => [ "base", "index", "mem" ],
1531 emit => "prefetcht2 %AM",
1536 op_flags => [ "uses_memory" ],
1537 state => "exc_pinned",
1538 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1539 ins => [ "base", "index", "mem" ],
1542 emit => "prefetchnta %AM",
1547 # 3DNow! prefetch instructions
1550 op_flags => [ "uses_memory" ],
1551 state => "exc_pinned",
1552 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1553 ins => [ "base", "index", "mem" ],
1556 emit => "prefetch %AM",
1561 op_flags => [ "uses_memory" ],
1562 state => "exc_pinned",
1563 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1564 ins => [ "base", "index", "mem" ],
1567 emit => "prefetchw %AM",
1573 irn_flags => [ "rematerializable" ],
1574 reg_req => { out => [ "xmm" ] },
1575 emit => 'xorp%FX %D0, %D0',
1582 op_flags => [ "constlike" ],
1583 irn_flags => [ "rematerializable" ],
1584 reg_req => { out => [ "xmm" ] },
1591 irn_flags => [ "rematerializable" ],
1592 reg_req => { out => [ "xmm" ] },
1593 emit => 'pxor %D0, %D0',
1599 # produces all 1 bits
1601 irn_flags => [ "rematerializable" ],
1602 reg_req => { out => [ "xmm" ] },
1603 emit => 'pcmpeqb %D0, %D0',
1609 # integer shift left, dword
1611 irn_flags => [ "rematerializable" ],
1612 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1613 emit => 'pslld %#S1, %D0',
1619 # integer shift left, qword
1621 irn_flags => [ "rematerializable" ],
1622 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1623 emit => 'psllq %#S1, %D0',
1629 # integer shift right, dword
1631 irn_flags => [ "rematerializable" ],
1632 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1633 emit => 'psrld %#S1, %D0',
1639 # mov from integer to SSE register
1641 irn_flags => [ "rematerializable" ],
1642 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1643 emit => 'movd %S0, %D0',
1650 irn_flags => [ "rematerializable" ],
1651 state => "exc_pinned",
1652 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1653 out => [ "in_r4 in_r5", "flags", "none" ] },
1654 ins => [ "base", "index", "mem", "left", "right" ],
1655 outs => [ "res", "flags", "M" ],
1656 am => "source,binary",
1657 emit => 'adds%FX %B',
1664 irn_flags => [ "rematerializable" ],
1665 state => "exc_pinned",
1666 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1667 out => [ "in_r4 in_r5", "flags", "none" ] },
1668 ins => [ "base", "index", "mem", "left", "right" ],
1669 outs => [ "res", "flags", "M" ],
1670 am => "source,binary",
1671 emit => 'muls%FX %B',
1678 irn_flags => [ "rematerializable" ],
1679 state => "exc_pinned",
1680 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1681 out => [ "in_r4 in_r5", "flags", "none" ] },
1682 ins => [ "base", "index", "mem", "left", "right" ],
1683 outs => [ "res", "flags", "M" ],
1684 am => "source,binary",
1685 emit => 'maxs%FX %B',
1692 irn_flags => [ "rematerializable" ],
1693 state => "exc_pinned",
1694 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1695 out => [ "in_r4 in_r5", "flags", "none" ] },
1696 ins => [ "base", "index", "mem", "left", "right" ],
1697 outs => [ "res", "flags", "M" ],
1698 am => "source,binary",
1699 emit => 'mins%FX %B',
1706 irn_flags => [ "rematerializable" ],
1707 state => "exc_pinned",
1708 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1709 out => [ "in_r4 in_r5", "flags", "none" ] },
1710 ins => [ "base", "index", "mem", "left", "right" ],
1711 outs => [ "res", "flags", "M" ],
1712 am => "source,binary",
1713 emit => 'andp%FX %B',
1720 irn_flags => [ "rematerializable" ],
1721 state => "exc_pinned",
1722 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1723 out => [ "in_r4 in_r5", "flags", "none" ] },
1724 ins => [ "base", "index", "mem", "left", "right" ],
1725 outs => [ "res", "flags", "M" ],
1726 am => "source,binary",
1727 emit => 'orp%FX %B',
1734 irn_flags => [ "rematerializable" ],
1735 state => "exc_pinned",
1736 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1737 out => [ "in_r4 in_r5", "flags", "none" ] },
1738 ins => [ "base", "index", "mem", "left", "right" ],
1739 outs => [ "res", "flags", "M" ],
1740 am => "source,binary",
1741 emit => 'xorp%FX %B',
1748 irn_flags => [ "rematerializable" ],
1749 state => "exc_pinned",
1750 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1751 out => [ "in_r4 !in_r5", "flags", "none" ] },
1752 ins => [ "base", "index", "mem", "left", "right" ],
1753 outs => [ "res", "flags", "M" ],
1754 am => "source,binary",
1755 emit => 'andnp%FX %B',
1762 irn_flags => [ "rematerializable" ],
1763 state => "exc_pinned",
1764 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1765 out => [ "in_r4", "flags", "none" ] },
1766 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1767 outs => [ "res", "flags", "M" ],
1768 am => "source,binary",
1769 emit => 'subs%FX %B',
1776 irn_flags => [ "rematerializable" ],
1777 state => "exc_pinned",
1778 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1779 out => [ "in_r4 !in_r5", "flags", "none" ] },
1780 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1781 outs => [ "res", "flags", "M" ],
1782 am => "source,binary",
1783 emit => 'divs%FX %B',
1789 irn_flags => [ "rematerializable" ],
1790 state => "exc_pinned",
1791 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1792 out => [ "eflags" ] },
1793 ins => [ "base", "index", "mem", "left", "right" ],
1794 outs => [ "flags" ],
1795 am => "source,binary",
1796 attr => "bool ins_permuted",
1797 init_attr => "attr->data.ins_permuted = ins_permuted;",
1798 emit => 'ucomis%FX %B',
1801 mode => $mode_flags,
1802 modified_flags => 1,
1806 op_flags => [ "uses_memory", "fragile" ],
1807 state => "exc_pinned",
1808 reg_req => { in => [ "gp", "gp", "none" ],
1809 out => [ "xmm", "none", "none", "none", "none" ] },
1810 ins => [ "base", "index", "mem" ],
1811 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1812 emit => 'movs%FX %AM, %D0',
1813 attr => "ir_mode *load_mode",
1814 init_attr => "attr->ls_mode = load_mode;",
1820 op_flags => [ "uses_memory", "fragile" ],
1821 state => "exc_pinned",
1822 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1823 out => [ "none", "none", "none" ] },
1824 ins => [ "base", "index", "mem", "val" ],
1825 outs => [ "M", "X_regular", "X_except" ],
1826 emit => 'movs%FX %S3, %AM',
1832 op_flags => [ "uses_memory", "fragile" ],
1833 state => "exc_pinned",
1834 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1835 out => [ "none", "none", "none" ] },
1836 ins => [ "base", "index", "mem", "val" ],
1837 outs => [ "M", "X_regular", "X_except" ],
1838 emit => 'movs%FX %S3, %AM',
1844 state => "exc_pinned",
1845 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1846 ins => [ "base", "index", "mem", "val" ],
1847 am => "source,unary",
1848 emit => 'cvtsi2ss %AS3, %D0',
1855 state => "exc_pinned",
1856 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1857 ins => [ "base", "index", "mem", "val" ],
1858 am => "source,unary",
1859 emit => 'cvtsi2sd %AS3, %D0',
1867 ins => [ "val_high", "val_low" ],
1869 dump_func => "NULL",
1874 outs => [ "res_high", "res_low" ],
1876 dump_func => "NULL",
1880 op_flags => [ "uses_memory", "fragile" ],
1882 reg_req => { in => [ "edi", "esi", "ecx", "none" ],
1883 out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1884 ins => [ "dest", "source", "count", "mem" ],
1885 outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1886 attr_type => "ia32_copyb_attr_t",
1887 attr => "unsigned size",
1890 # we don't care about this flag, so no need to mark this node
1891 # modified_flags => [ "DF" ]
1895 op_flags => [ "uses_memory", "fragile" ],
1897 reg_req => { in => [ "edi", "esi", "none" ],
1898 out => [ "edi", "esi", "none", "none", "none" ] },
1899 ins => [ "dest", "source", "mem" ],
1900 outs => [ "dest", "source", "M", "X_regular", "X_except" ],
1901 attr_type => "ia32_copyb_attr_t",
1902 attr => "unsigned size",
1905 # we don't care about this flag, so no need to mark this node
1906 # modified_flags => [ "DF" ]
1910 state => "exc_pinned",
1911 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1921 op_flags => [ "uses_memory", "fragile" ],
1922 state => "exc_pinned",
1923 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1924 out => [ "gp", "none", "none", "none", "none" ] },
1925 ins => [ "base", "index", "mem", "val" ],
1926 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1927 emit => "mov%#Ml %#AS3, %D0",
1928 am => "source,unary",
1931 attr => "ir_mode *smaller_mode",
1932 init_attr => "attr->ls_mode = smaller_mode;",
1937 op_flags => [ "uses_memory", "fragile" ],
1938 state => "exc_pinned",
1939 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1940 out => [ "gp", "none", "none", "none", "none" ] },
1941 ins => [ "base", "index", "mem", "val" ],
1942 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1943 emit => "mov%#Ml %#AS3, %D0",
1944 am => "source,unary",
1947 attr => "ir_mode *smaller_mode",
1948 init_attr => "attr->ls_mode = smaller_mode;",
1953 state => "exc_pinned",
1954 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1955 ins => [ "base", "index", "mem", "val" ],
1956 am => "source,unary",
1963 state => "exc_pinned",
1964 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1965 ins => [ "base", "index", "mem", "val" ],
1966 am => "source,unary",
1973 state => "exc_pinned",
1974 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1975 ins => [ "base", "index", "mem", "val" ],
1976 am => "source,unary",
1982 # rematerialisation disabled for all float nodes for now, because the fpcw
1983 # handler runs before spilling and we might end up with wrong fpcw then
1986 # irn_flags => [ "rematerializable" ],
1987 state => "exc_pinned",
1988 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1989 out => [ "fp", "none", "none" ] },
1990 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1991 outs => [ "res", "dummy", "M" ],
1992 emit => 'fadd%FP%FM %AF',
1993 am => "source,binary",
1997 attr_type => "ia32_x87_attr_t",
2001 # irn_flags => [ "rematerializable" ],
2002 state => "exc_pinned",
2003 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2004 out => [ "fp", "none", "none" ] },
2005 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2006 outs => [ "res", "dummy", "M" ],
2007 emit => 'fmul%FP%FM %AF',
2008 am => "source,binary",
2012 attr_type => "ia32_x87_attr_t",
2016 # irn_flags => [ "rematerializable" ],
2017 state => "exc_pinned",
2018 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2019 out => [ "fp", "none", "none" ] },
2020 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2021 outs => [ "res", "dummy", "M" ],
2022 emit => 'fsub%FR%FP%FM %AF',
2023 am => "source,binary",
2027 attr_type => "ia32_x87_attr_t",
2031 state => "exc_pinned",
2032 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
2033 out => [ "fp", "none", "none" ] },
2034 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2035 outs => [ "res", "dummy", "M" ],
2036 emit => 'fdiv%FR%FP%FM %AF',
2037 am => "source,binary",
2040 attr_type => "ia32_x87_attr_t",
2044 reg_req => { in => [ "fp", "fp", "fpcw" ], out => [ "fp" ] },
2045 ins => [ "left", "right", "fpcw" ],
2050 attr_type => "ia32_x87_attr_t",
2054 irn_flags => [ "rematerializable" ],
2055 reg_req => { in => [ "fp"], out => [ "fp" ] },
2061 attr_type => "ia32_x87_attr_t",
2065 irn_flags => [ "rematerializable" ],
2066 reg_req => { in => [ "fp"], out => [ "fp" ] },
2072 attr_type => "ia32_x87_attr_t",
2076 irn_flags => [ "rematerializable" ],
2077 op_flags => [ "uses_memory", "fragile" ],
2078 state => "exc_pinned",
2079 reg_req => { in => [ "gp", "gp", "none" ],
2080 out => [ "fp", "none", "none", "none", "none" ] },
2081 ins => [ "base", "index", "mem" ],
2082 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
2083 emit => 'fld%FM %AM',
2084 attr => "ir_mode *load_mode",
2085 init_attr => "attr->attr.ls_mode = load_mode;",
2088 attr_type => "ia32_x87_attr_t",
2092 irn_flags => [ "rematerializable" ],
2093 op_flags => [ "uses_memory", "fragile" ],
2094 state => "exc_pinned",
2095 reg_req => { in => [ "gp", "gp", "none", "fp" ],
2096 out => [ "none", "none", "none" ] },
2097 ins => [ "base", "index", "mem", "val" ],
2098 outs => [ "M", "X_regular", "X_except" ],
2099 emit => 'fst%FP%FM %AM',
2100 attr => "ir_mode *store_mode",
2101 init_attr => "attr->attr.ls_mode = store_mode;",
2104 attr_type => "ia32_x87_attr_t",
2108 state => "exc_pinned",
2109 reg_req => { in => [ "gp", "gp", "none" ],
2110 out => [ "fp", "none", "none" ] },
2111 outs => [ "res", "unused", "M" ],
2112 ins => [ "base", "index", "mem" ],
2113 emit => 'fild%FM %AM',
2116 attr_type => "ia32_x87_attr_t",
2120 op_flags => [ "uses_memory", "fragile" ],
2121 state => "exc_pinned",
2122 reg_req => { in => [ "gp", "gp", "none", "fp", "fpcw" ],
2123 out => [ "none", "none", "none", "none" ] },
2124 ins => [ "base", "index", "mem", "val", "fpcw" ],
2125 outs => [ "dummy", "M", "X_regular", "X_except" ],
2126 emit => 'fist%FP%FM %AM',
2129 attr_type => "ia32_x87_attr_t",
2132 # SSE3 fisttp instruction
2134 op_flags => [ "uses_memory", "fragile" ],
2135 state => "exc_pinned",
2136 reg_req => { in => [ "gp", "gp", "none", "fp" ],
2137 out => [ "in_r4", "none", "none", "none" ]},
2138 ins => [ "base", "index", "mem", "val" ],
2139 outs => [ "res", "M", "X_regular", "X_except" ],
2140 emit => 'fisttp%FM %AM',
2143 attr_type => "ia32_x87_attr_t",
2147 irn_flags => [ "rematerializable" ],
2148 reg_req => { out => [ "fp" ] },
2154 attr_type => "ia32_x87_attr_t",
2158 irn_flags => [ "rematerializable" ],
2159 reg_req => { out => [ "fp" ] },
2165 attr_type => "ia32_x87_attr_t",
2169 irn_flags => [ "rematerializable" ],
2170 reg_req => { out => [ "fp" ] },
2176 attr_type => "ia32_x87_attr_t",
2180 irn_flags => [ "rematerializable" ],
2181 reg_req => { out => [ "fp" ] },
2187 attr_type => "ia32_x87_attr_t",
2191 irn_flags => [ "rematerializable" ],
2192 reg_req => { out => [ "fp" ] },
2198 attr_type => "ia32_x87_attr_t",
2202 irn_flags => [ "rematerializable" ],
2203 reg_req => { out => [ "fp" ] },
2209 attr_type => "ia32_x87_attr_t",
2213 irn_flags => [ "rematerializable" ],
2214 reg_req => { out => [ "fp" ] },
2220 attr_type => "ia32_x87_attr_t",
2224 # we can't allow to rematerialize this node so we don't
2225 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2226 # irn_flags => [ "rematerializable" ],
2227 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2228 ins => [ "left", "right" ],
2229 outs => [ "flags" ],
2230 emit => "fucom%FP %F0\n".
2232 attr => "bool ins_permuted",
2233 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2236 attr_type => "ia32_x87_attr_t",
2241 # we can't allow to rematerialize this node so we don't
2242 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2243 # irn_flags => [ "rematerializable" ],
2244 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2245 ins => [ "left", "right" ],
2246 outs => [ "flags" ],
2247 emit => "fucompp\n".
2249 attr => "bool ins_permuted",
2250 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2253 attr_type => "ia32_x87_attr_t",
2258 irn_flags => [ "rematerializable" ],
2259 reg_req => { in => [ "fp", "fp" ], out => [ "eflags" ] },
2260 ins => [ "left", "right" ],
2261 outs => [ "flags" ],
2262 emit => 'fucom%FPi %F0',
2263 attr => "bool ins_permuted",
2264 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2267 attr_type => "ia32_x87_attr_t",
2272 # irn_flags => [ "rematerializable" ],
2273 reg_req => { in => [ "fp" ], out => [ "eax" ] },
2275 outs => [ "flags" ],
2278 attr => "bool ins_permuted",
2279 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2282 attr_type => "ia32_x87_attr_t",
2287 irn_flags => [ "rematerializable" ],
2288 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2290 outs => [ "flags" ],
2294 mode => $mode_flags,
2298 # Note that it is NEVER allowed to do CSE on these nodes
2299 # Moreover, note the virtual register requierements!
2302 op_flags => [ "keep" ],
2303 reg_req => { out => [ "none" ] },
2304 cmp_attr => "return 1;",
2306 attr_type => "ia32_x87_attr_t",
2312 op_flags => [ "keep" ],
2313 reg_req => { out => [ "none" ] },
2314 cmp_attr => "return 1;",
2316 attr_type => "ia32_x87_attr_t",
2322 reg_req => { in => [ "fp"], out => [ "fp" ] },
2323 cmp_attr => "return 1;",
2325 attr_type => "ia32_x87_attr_t",
2330 op_flags => [ "keep" ],
2331 reg_req => { out => [ "none" ] },
2332 cmp_attr => "return 1;",
2334 attr_type => "ia32_x87_attr_t",
2340 op_flags => [ "keep" ],
2341 reg_req => { out => [ "none" ] },
2342 cmp_attr => "return 1;",
2343 emit => 'ffreep %F0',
2344 attr_type => "ia32_x87_attr_t",
2350 op_flags => [ "keep" ],
2351 reg_req => { out => [ "none" ] },
2352 cmp_attr => "return 1;",
2354 attr_type => "ia32_x87_attr_t",
2360 op_flags => [ "keep" ],
2361 reg_req => { out => [ "none" ] },
2362 cmp_attr => "return 1;",
2364 attr_type => "ia32_x87_attr_t",
2369 # Spilling and reloading of SSE registers, hardcoded, not generated #
2372 op_flags => [ "uses_memory", "fragile" ],
2373 state => "exc_pinned",
2374 reg_req => { in => [ "gp", "gp", "none" ],
2375 out => [ "xmm", "none", "none", "none" ] },
2376 emit => 'movdqu %D0, %AM',
2377 ins => [ "base", "index", "mem" ],
2378 outs => [ "res", "M", "X_regular", "X_except" ],
2384 op_flags => [ "uses_memory", "fragile" ],
2385 state => "exc_pinned",
2386 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
2387 out => [ "none", "none", "none" ] },
2388 ins => [ "base", "index", "mem", "val" ],
2389 outs => [ "M", "X_regular", "X_except" ],
2390 emit => 'movdqu %B',
2397 # Transform some attributes
2398 foreach my $op (keys(%nodes)) {
2399 my $node = $nodes{$op};
2400 my $op_attr_init = $node->{op_attr_init};
2402 if(defined($op_attr_init)) {
2403 $op_attr_init .= "\n\t";
2408 if(!defined($node->{latency})) {
2410 $node->{latency} = 0;
2412 die("Latency missing for op $op");
2415 $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2417 $node->{op_attr_init} = $op_attr_init;