1 # This is the specification for the ia32 assembler Firm-operations
7 $mode_fp87 = "ia32_mode_E";
9 $mode_flags = "mode_Iu";
10 $mode_fpcw = "ia32_mode_fpcw";
14 { name => "edx", dwarf => 2 },
15 { name => "ecx", dwarf => 1 },
16 { name => "eax", dwarf => 0 },
17 { name => "ebx", dwarf => 3 },
18 { name => "esi", dwarf => 6 },
19 { name => "edi", dwarf => 7 },
20 { name => "ebp", dwarf => 5 },
21 { name => "esp", dwarf => 4, type => "ignore" },
22 { name => "gp_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
26 { name => "mm0", dwarf => 29, type => "ignore" },
27 { name => "mm1", dwarf => 30, type => "ignore" },
28 { name => "mm2", dwarf => 31, type => "ignore" },
29 { name => "mm3", dwarf => 32, type => "ignore" },
30 { name => "mm4", dwarf => 33, type => "ignore" },
31 { name => "mm5", dwarf => 34, type => "ignore" },
32 { name => "mm6", dwarf => 35, type => "ignore" },
33 { name => "mm7", dwarf => 36, type => "ignore" },
34 { mode => $mode_mmx, flags => "manual_ra" }
37 { name => "xmm0", dwarf => 21 },
38 { name => "xmm1", dwarf => 22 },
39 { name => "xmm2", dwarf => 23 },
40 { name => "xmm3", dwarf => 24 },
41 { name => "xmm4", dwarf => 25 },
42 { name => "xmm5", dwarf => 26 },
43 { name => "xmm6", dwarf => 27 },
44 { name => "xmm7", dwarf => 28 },
45 { name => "xmm_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
49 { name => "st0", realname => "st", dwarf => 11 },
50 { name => "st1", realname => "st(1)", dwarf => 12 },
51 { name => "st2", realname => "st(2)", dwarf => 13 },
52 { name => "st3", realname => "st(3)", dwarf => 14 },
53 { name => "st4", realname => "st(4)", dwarf => 15 },
54 { name => "st5", realname => "st(5)", dwarf => 16 },
55 { name => "st6", realname => "st(6)", dwarf => 17 },
56 { name => "st7", realname => "st(7)", dwarf => 18 },
57 { name => "fp_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
58 { mode => $mode_fp87 }
60 fp_cw => [ # the floating point control word
61 { name => "fpcw", dwarf => 37, type => "state" },
62 { mode => $mode_fpcw, flags => "manual_ra | state" }
65 { name => "eflags", dwarf => 9 },
66 { mode => "mode_Iu", flags => "manual_ra" }
70 $default_attr_type = "ia32_attr_t";
71 $default_copy_attr = "ia32_copy_attr";
73 sub ia32_custom_init_attr {
79 if(defined($node->{modified_flags})) {
80 $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n";
82 if(defined($node->{am})) {
84 if($am eq "source,unary") {
85 $res .= "\tset_ia32_am_support(res, ia32_am_unary);";
86 } elsif($am eq "source,binary") {
87 $res .= "\tset_ia32_am_support(res, ia32_am_binary);";
88 } elsif($am eq "none") {
91 die("Invalid address mode '$am' specified on op $name");
94 if($node->{state} ne "exc_pinned"
95 and $node->{state} ne "pinned") {
96 die("AM nodes must have pinned or AM pinned state ($name)");
102 $custom_init_attr_func = \&ia32_custom_init_attr;
106 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
107 "\tinit_ia32_asm_attributes(res);",
109 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);",
111 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
112 "\tinit_ia32_call_attributes(res, pop, call_tp);",
113 ia32_condcode_attr_t =>
114 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
115 "\tinit_ia32_condcode_attributes(res, condition_code);",
116 ia32_switch_attr_t =>
117 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
118 "\tinit_ia32_switch_attributes(res, switch_table);",
120 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
121 "\tinit_ia32_copyb_attributes(res, size);",
122 ia32_immediate_attr_t =>
123 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
124 "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
126 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
127 "\tinit_ia32_x87_attributes(res);",
128 ia32_climbframe_attr_t =>
129 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
130 "\tinit_ia32_climbframe_attributes(res, count);",
134 ia32_asm_attr_t => "ia32_compare_asm_attr",
135 ia32_attr_t => "ia32_compare_nodes_attr",
136 ia32_call_attr_t => "ia32_compare_call_attr",
137 ia32_condcode_attr_t => "ia32_compare_condcode_attr",
138 ia32_copyb_attr_t => "ia32_compare_copyb_attr",
139 ia32_switch_attr_t => "ia32_compare_nodes_attr",
140 ia32_immediate_attr_t => "ia32_compare_immediate_attr",
141 ia32_x87_attr_t => "ia32_compare_x87_attr",
142 ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
145 $status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
146 $status_flags_wo_cf = [ "PF", "AF", "ZF", "SF", "OF" ];
147 $fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
148 "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
150 my %binop_flags_constructors = (
152 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
153 out => [ "flags", "none", "none" ] },
156 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ],
157 out => [ "flags", "none", "none" ] },
161 my %binop_mem_constructors = (
162 "" => { reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] } },
163 "8bit" => { reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] } },
170 op_flags => [ "constlike" ],
171 irn_flags => [ "not_scheduled" ],
172 reg_req => { out => [ "gp_NOREG:I" ] },
173 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
174 attr_type => "ia32_immediate_attr_t",
175 hash_func => "ia32_hash_Immediate",
183 out_arity => "variable",
184 attr_type => "ia32_asm_attr_t",
185 attr => "ident *asm_text, const ia32_asm_reg_t *register_map",
186 init_attr => "attr->asm_text = asm_text;\n".
187 "\tattr->register_map = register_map;\n",
189 modified_flags => $status_flags,
192 # "allocates" a free register
194 op_flags => [ "constlike", "cse_neutral" ],
195 irn_flags => [ "rematerializable" ],
196 reg_req => { out => [ "gp" ] },
200 cmp_attr => "return 1;",
204 irn_flags => [ "rematerializable" ],
205 state => "exc_pinned",
206 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
207 out => [ "in_r4 in_r5", "flags", "none" ] },
208 ins => [ "base", "index", "mem", "left", "right" ],
209 outs => [ "res", "flags", "M" ],
211 am => "source,binary",
214 modified_flags => $status_flags
218 irn_flags => [ "rematerializable" ],
219 state => "exc_pinned",
220 constructors => \%binop_mem_constructors,
221 ins => [ "base", "index", "mem", "val" ],
222 emit => "add%M %#S3, %AM",
225 modified_flags => $status_flags
229 state => "exc_pinned",
230 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
231 out => [ "in_r4 in_r5", "flags", "none" ] },
232 ins => [ "base", "index", "mem", "left", "right", "eflags" ],
233 outs => [ "res", "flags", "M" ],
235 am => "source,binary",
238 modified_flags => $status_flags
242 ins => [ "left", "right" ],
248 ins => [ "left", "right", "eflags" ],
254 # we should not rematrialize this node. It produces 2 results and has
255 # very strict constraints
256 state => "exc_pinned",
257 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
258 out => [ "eax", "flags", "none", "edx" ] },
259 ins => [ "base", "index", "mem", "left", "right" ],
260 emit => 'mul%M %AS4',
261 outs => [ "res_low", "flags", "M", "res_high" ],
262 am => "source,binary",
264 modified_flags => $status_flags
268 ins => [ "left", "right" ],
269 outs => [ "res_low", "flags", "M", "res_high" ],
275 irn_flags => [ "rematerializable" ],
276 state => "exc_pinned",
277 # TODO: adjust out requirements for the 3 operand form
278 # (no need for should_be_same then)
279 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
280 out => [ "in_r4 in_r5", "flags", "none" ] },
281 ins => [ "base", "index", "mem", "left", "right" ],
282 outs => [ "res", "flags", "M" ],
283 am => "source,binary",
286 modified_flags => $status_flags
290 irn_flags => [ "rematerializable" ],
291 state => "exc_pinned",
292 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
293 out => [ "eax", "flags", "none", "edx" ] },
294 ins => [ "base", "index", "mem", "left", "right" ],
295 emit => 'imul%M %AS4',
296 outs => [ "res_low", "flags", "M", "res_high" ],
297 am => "source,binary",
299 modified_flags => $status_flags
303 ins => [ "left", "right" ],
304 outs => [ "res_low", "flags", "M", "res_high" ],
310 irn_flags => [ "rematerializable" ],
311 state => "exc_pinned",
312 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
313 out => [ "in_r4 in_r5", "flags", "none" ] },
314 ins => [ "base", "index", "mem", "left", "right" ],
315 outs => [ "res", "flags", "M" ],
316 am => "source,binary",
320 modified_flags => $status_flags
324 irn_flags => [ "rematerializable" ],
325 state => "exc_pinned",
326 constructors => \%binop_mem_constructors,
327 ins => [ "base", "index", "mem", "val" ],
328 emit => 'and%M %#S3, %AM',
331 modified_flags => $status_flags
335 irn_flags => [ "rematerializable" ],
336 state => "exc_pinned",
337 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
338 out => [ "in_r4 in_r5", "flags", "none" ] },
339 ins => [ "base", "index", "mem", "left", "right" ],
340 outs => [ "res", "flags", "M" ],
341 am => "source,binary",
345 modified_flags => $status_flags
349 irn_flags => [ "rematerializable" ],
350 state => "exc_pinned",
351 constructors => \%binop_mem_constructors,
352 ins => [ "base", "index", "mem", "val" ],
353 emit => 'or%M %#S3, %AM',
356 modified_flags => $status_flags
360 irn_flags => [ "rematerializable" ],
361 state => "exc_pinned",
362 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
363 out => [ "in_r4 in_r5", "flags", "none" ] },
364 ins => [ "base", "index", "mem", "left", "right" ],
365 outs => [ "res", "flags", "M" ],
366 am => "source,binary",
370 modified_flags => $status_flags
374 op_flags => [ "constlike" ],
375 irn_flags => [ "rematerializable" ],
376 reg_req => { out => [ "gp", "flags" ] },
377 outs => [ "res", "flags" ],
378 emit => "xor%M %D0, %D0",
381 modified_flags => $status_flags
385 irn_flags => [ "rematerializable" ],
386 state => "exc_pinned",
387 constructors => \%binop_mem_constructors,
388 ins => [ "base", "index", "mem", "val" ],
389 emit => 'xor%M %#S3, %AM',
392 modified_flags => $status_flags
396 irn_flags => [ "rematerializable" ],
397 state => "exc_pinned",
398 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
399 out => [ "in_r4", "flags", "none" ] },
400 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
401 outs => [ "res", "flags", "M" ],
402 am => "source,binary",
406 modified_flags => $status_flags
410 irn_flags => [ "rematerializable" ],
411 state => "exc_pinned",
412 constructors => \%binop_mem_constructors,
413 ins => [ "base", "index", "mem", "subtrahend" ],
414 emit => 'sub%M %#S3, %AM',
417 modified_flags => $status_flags
421 state => "exc_pinned",
422 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
423 out => [ "in_r4", "flags", "none" ] },
424 ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
425 outs => [ "res", "flags", "M" ],
426 am => "source,binary",
430 modified_flags => $status_flags
434 # Spiller currently fails when rematerializing flag consumers
435 # irn_flags => [ "rematerializable" ],
436 reg_req => { in => [ "flags" ], out => [ "gp", "flags" ] },
437 outs => [ "res", "flags" ],
438 emit => "sbb%M %D0, %D0",
441 modified_flags => $status_flags
445 ins => [ "minuend", "subtrahend" ],
451 ins => [ "minuend", "subtrahend", "eflags" ],
457 op_flags => [ "fragile", "uses_memory" ],
458 state => "exc_pinned",
459 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
460 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
461 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
462 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
463 am => "source,unary",
464 emit => "idiv%M %AS3",
466 modified_flags => $status_flags
470 op_flags => [ "fragile", "uses_memory" ],
471 state => "exc_pinned",
472 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
473 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
474 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
475 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
476 am => "source,unary",
477 emit => "div%M %AS3",
479 modified_flags => $status_flags
483 irn_flags => [ "rematerializable" ],
484 reg_req => { in => [ "gp", "ecx" ],
485 out => [ "in_r1 !in_r2", "flags" ] },
486 ins => [ "val", "count" ],
487 outs => [ "res", "flags" ],
488 emit => 'shl%M %<S1, %S0',
491 modified_flags => $status_flags
495 irn_flags => [ "rematerializable" ],
496 state => "exc_pinned",
497 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
498 ins => [ "base", "index", "mem", "count" ],
499 emit => 'shl%M %<S3, %AM',
502 modified_flags => $status_flags
506 irn_flags => [ "rematerializable" ],
507 reg_req => { in => [ "gp", "gp", "ecx" ],
508 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
509 ins => [ "val_high", "val_low", "count" ],
510 outs => [ "res", "flags" ],
511 emit => "shld%M %<S2, %S1, %D0",
514 modified_flags => $status_flags
518 irn_flags => [ "rematerializable" ],
519 reg_req => { in => [ "gp", "ecx" ],
520 out => [ "in_r1 !in_r2", "flags" ] },
521 ins => [ "val", "count" ],
522 outs => [ "res", "flags" ],
523 emit => 'shr%M %<S1, %S0',
526 modified_flags => $status_flags
530 irn_flags => [ "rematerializable" ],
531 state => "exc_pinned",
532 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
533 ins => [ "base", "index", "mem", "count" ],
534 emit => 'shr%M %<S3, %AM',
537 modified_flags => $status_flags
541 irn_flags => [ "rematerializable" ],
542 reg_req => { in => [ "gp", "gp", "ecx" ],
543 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
544 ins => [ "val_high", "val_low", "count" ],
545 outs => [ "res", "flags" ],
546 emit => "shrd%M %<S2, %S1, %D0",
549 modified_flags => $status_flags
553 irn_flags => [ "rematerializable" ],
554 reg_req => { in => [ "gp", "ecx" ],
555 out => [ "in_r1 !in_r2", "flags" ] },
556 ins => [ "val", "count" ],
557 outs => [ "res", "flags" ],
558 emit => 'sar%M %<S1, %S0',
561 modified_flags => $status_flags
565 irn_flags => [ "rematerializable" ],
566 state => "exc_pinned",
567 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
568 ins => [ "base", "index", "mem", "count" ],
569 emit => 'sar%M %<S3, %AM',
572 modified_flags => $status_flags
576 irn_flags => [ "rematerializable" ],
577 reg_req => { in => [ "gp", "ecx" ],
578 out => [ "in_r1 !in_r2", "flags" ] },
579 ins => [ "val", "count" ],
580 outs => [ "res", "flags" ],
581 emit => 'ror%M %<S1, %S0',
584 modified_flags => $status_flags
588 irn_flags => [ "rematerializable" ],
589 state => "exc_pinned",
590 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
591 ins => [ "base", "index", "mem", "count" ],
592 emit => 'ror%M %<S3, %AM',
595 modified_flags => $status_flags
599 irn_flags => [ "rematerializable" ],
600 reg_req => { in => [ "gp", "ecx" ],
601 out => [ "in_r1 !in_r2", "flags" ] },
602 ins => [ "val", "count" ],
603 outs => [ "res", "flags" ],
604 emit => 'rol%M %<S1, %D0',
607 modified_flags => $status_flags
611 irn_flags => [ "rematerializable" ],
612 state => "exc_pinned",
613 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
614 ins => [ "base", "index", "mem", "count" ],
615 emit => 'rol%M %<S3, %AM',
618 modified_flags => $status_flags
622 irn_flags => [ "rematerializable" ],
623 reg_req => { in => [ "gp" ],
624 out => [ "in_r1", "flags" ] },
627 outs => [ "res", "flags" ],
630 modified_flags => $status_flags
634 irn_flags => [ "rematerializable" ],
635 state => "exc_pinned",
636 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
637 ins => [ "base", "index", "mem" ],
641 modified_flags => $status_flags
645 irn_flags => [ "rematerializable" ],
646 reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
647 outs => [ "low_res", "high_res" ],
649 modified_flags => $status_flags
654 irn_flags => [ "rematerializable" ],
655 reg_req => { in => [ "gp" ],
656 out => [ "in_r1", "flags" ] },
658 outs => [ "res", "flags" ],
662 modified_flags => $status_flags_wo_cf
666 irn_flags => [ "rematerializable" ],
667 state => "exc_pinned",
668 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
669 ins => [ "base", "index", "mem" ],
673 modified_flags => $status_flags_wo_cf
677 irn_flags => [ "rematerializable" ],
678 reg_req => { in => [ "gp" ],
679 out => [ "in_r1", "flags" ] },
681 outs => [ "res", "flags" ],
685 modified_flags => $status_flags_wo_cf
689 irn_flags => [ "rematerializable" ],
690 state => "exc_pinned",
691 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
692 ins => [ "base", "index", "mem" ],
696 modified_flags => $status_flags_wo_cf
700 irn_flags => [ "rematerializable" ],
701 reg_req => { in => [ "gp" ],
702 out => [ "in_r1" ] },
712 irn_flags => [ "rematerializable" ],
713 state => "exc_pinned",
714 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
715 ins => [ "base", "index", "mem" ],
723 reg_req => { in => [ "flags" ], out => [ "flags" ] },
727 modified_flags => $status_flags
731 reg_req => { out => [ "flags" ] },
735 modified_flags => $status_flags
739 irn_flags => [ "rematerializable" ],
740 state => "exc_pinned",
741 constructors => \%binop_flags_constructors,
742 ins => [ "base", "index", "mem", "left", "right" ],
743 outs => [ "eflags", "unused", "M" ],
744 am => "source,binary",
746 attr => "bool ins_permuted",
747 init_attr => "attr->data.ins_permuted = ins_permuted;",
750 modified_flags => $status_flags
754 irn_flags => [ "rematerializable" ],
755 state => "exc_pinned",
756 reg_req => { in => [ "eax ebx ecx edx" ],
757 out => [ "in_r1", "flags" ] },
758 emit => 'xorb %>S0, %<S0',
760 outs => [ "res", "flags" ],
763 modified_flags => $status_flags,
767 irn_flags => [ "rematerializable" ],
768 state => "exc_pinned",
769 constructors => \%binop_flags_constructors,
770 ins => [ "base", "index", "mem", "left", "right" ],
771 outs => [ "eflags", "unused", "M" ],
772 am => "source,binary",
774 attr => "bool ins_permuted",
775 init_attr => "attr->data.ins_permuted = ins_permuted;",
778 modified_flags => $status_flags
782 #irn_flags => [ "rematerializable" ],
783 reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
786 attr_type => "ia32_condcode_attr_t",
787 attr => "ia32_condition_code_t condition_code",
788 # The way we handle Setcc with float nodes (potentially) destroys the flags
789 # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
790 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
791 . "\tif (condition_code & ia32_cc_additional_float_cases) {\n"
792 . "\t\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"
793 . "\t\t/* attr->latency = 3; */\n"
800 #irn_flags => [ "rematerializable" ],
801 state => "exc_pinned",
802 reg_req => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
803 ins => [ "base", "index", "mem","eflags" ],
804 attr_type => "ia32_condcode_attr_t",
805 attr => "ia32_condition_code_t condition_code",
806 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
807 emit => 'set%P3 %AM',
813 #irn_flags => [ "rematerializable" ],
814 state => "exc_pinned",
815 # (note: leave the false,true order intact to make it compatible with other
817 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
818 out => [ "in_r4 in_r5", "flags", "none" ] },
819 ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
820 outs => [ "res", "flags", "M" ],
821 am => "source,binary",
822 attr_type => "ia32_condcode_attr_t",
823 attr => "ia32_condition_code_t condition_code",
830 op_flags => [ "cfopcode", "forking" ],
831 reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
833 outs => [ "false", "true" ],
834 attr_type => "ia32_condcode_attr_t",
835 attr => "ia32_condition_code_t condition_code",
841 op_flags => [ "cfopcode", "forking" ],
842 reg_req => { in => [ "gp", "gp" ] },
843 ins => [ "base", "index" ],
844 out_arity => "variable",
845 attr_type => "ia32_switch_attr_t",
846 attr => "const ir_switch_table *switch_table",
852 irn_flags => [ "simple_jump" ],
853 op_flags => [ "cfopcode" ],
854 reg_req => { out => [ "none" ] },
861 op_flags => [ "cfopcode", "unknown_jump" ],
862 reg_req => { in => [ "gp", "gp", "none", "gp" ],
863 out => [ "none", "flags", "none" ] },
864 ins => [ "base", "index", "mem", "target" ],
865 outs => [ "jmp", "flags", "M" ],
866 am => "source,unary",
873 op_flags => [ "constlike" ],
874 irn_flags => [ "rematerializable" ],
875 reg_req => { out => [ "gp" ] },
876 emit => "movl %I, %D0",
877 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
878 attr_type => "ia32_immediate_attr_t",
884 op_flags => [ "constlike" ],
885 irn_flags => [ "rematerializable" ],
886 reg_req => { out => [ "gp" ] },
893 op_flags => [ "constlike" ],
894 reg_req => { out => [ "gp" ] },
897 modified_flags => $status_flags,
902 op_flags => [ "constlike", "dump_noblock" ],
903 irn_flags => [ "not_scheduled" ],
904 reg_req => { out => [ "gp_NOREG:I" ] },
911 op_flags => [ "constlike", "dump_noblock" ],
912 irn_flags => [ "not_scheduled" ],
913 reg_req => { out => [ "fp_NOREG:I" ] },
916 attr_type => "ia32_x87_attr_t",
921 op_flags => [ "constlike", "dump_noblock" ],
922 irn_flags => [ "not_scheduled" ],
923 reg_req => { out => [ "xmm_NOREG:I" ] },
930 op_flags => [ "constlike" ],
931 irn_flags => [ "not_scheduled" ],
932 reg_req => { out => [ "fpcw" ] },
935 modified_flags => $fpcw_flags
939 op_flags => [ "uses_memory" ],
941 reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw" ] },
942 ins => [ "base", "index", "mem" ],
946 modified_flags => $fpcw_flags
950 op_flags => [ "uses_memory" ],
952 reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
953 ins => [ "base", "index", "mem", "fpcw" ],
955 emit => "fnstcw %AM",
960 op_flags => [ "uses_memory" ],
962 reg_req => { in => [ "fp_cw" ], out => [ "none" ] },
970 # we should not rematrialize this node. It has very strict constraints.
971 reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] },
972 ins => [ "val", "clobbered" ],
980 # Note that we add additional latency values depending on address mode, so a
981 # lateny of 0 for load is correct
984 op_flags => [ "uses_memory", "fragile" ],
985 state => "exc_pinned",
986 reg_req => { in => [ "gp", "gp", "none" ],
987 out => [ "gp", "none", "none", "none", "none" ] },
988 ins => [ "base", "index", "mem" ],
989 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
991 emit => "mov%#Ml %AM, %D0",
995 op_flags => [ "uses_memory", "fragile" ],
996 state => "exc_pinned",
999 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1000 out => [ "none", "none", "none" ] }
1003 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1004 out => [ "none", "none", "none" ] }
1007 ins => [ "base", "index", "mem", "val" ],
1008 outs => [ "M", "X_regular", "X_except" ],
1009 emit => 'mov%M %#S3, %AM',
1014 irn_flags => [ "rematerializable" ],
1015 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1016 ins => [ "base", "index" ],
1017 emit => 'leal %AM, %D0',
1020 # lea doesn't modify the flags, but setting this seems advantageous since it
1021 # increases chances that the Lea is transformed back to an Add
1022 modified_flags => 1,
1026 state => "exc_pinned",
1027 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1028 ins => [ "base", "index", "mem", "val", "stack" ],
1029 emit => 'push%M %AS3',
1030 outs => [ "stack", "M" ],
1031 am => "source,unary",
1036 state => "exc_pinned",
1037 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1039 outs => [ "stack" ],
1040 emit => 'pushl %%eax',
1046 state => "exc_pinned",
1047 reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1048 ins => [ "mem", "stack" ],
1049 outs => [ "res", "M", "unused", "stack" ],
1050 emit => 'pop%M %D0',
1051 latency => 3, # Pop is more expensive than Push on Athlon
1055 state => "exc_pinned",
1056 reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1057 ins => [ "mem", "stack" ],
1058 outs => [ "res", "M", "unused", "stack" ],
1059 emit => 'pop%M %D0',
1060 latency => 3, # Pop is more expensive than Push on Athlon
1064 state => "exc_pinned",
1065 reg_req => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1068 emit => 'movl %S0, %D0',
1074 state => "exc_pinned",
1075 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1076 ins => [ "base", "index", "mem", "stack" ],
1077 outs => [ "unused0", "M", "unused1", "stack" ],
1078 emit => 'pop%M %AM',
1079 latency => 3, # Pop is more expensive than Push on Athlon
1083 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1085 outs => [ "frame", "stack", "M" ],
1090 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1092 outs => [ "frame", "stack" ],
1094 state => "exc_pinned",
1099 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1100 ins => [ "base", "index", "mem", "stack", "size" ],
1101 am => "source,binary",
1104 outs => [ "stack", "M" ],
1105 modified_flags => $status_flags
1110 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1111 ins => [ "base", "index", "mem", "stack", "size" ],
1112 am => "source,binary",
1113 emit => "subl %B\n".
1116 outs => [ "stack", "addr", "M" ],
1117 modified_flags => $status_flags
1121 op_flags => [ "keep" ],
1129 irn_flags => [ "rematerializable" ],
1130 reg_req => { out => [ "gp" ] },
1131 emit => "movl %%gs:0, %D0",
1137 # BT supports source address mode, but this is unused yet
1140 irn_flags => [ "rematerializable" ],
1141 state => "exc_pinned",
1142 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1143 ins => [ "left", "right" ],
1144 emit => 'bt%M %S1, %S0',
1146 mode => $mode_flags,
1147 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1151 irn_flags => [ "rematerializable" ],
1152 state => "exc_pinned",
1153 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1154 out => [ "gp", "flags", "none" ] },
1155 ins => [ "base", "index", "mem", "operand" ],
1156 outs => [ "res", "flags", "M" ],
1157 am => "source,binary",
1158 emit => 'bsf%M %AS3, %D0',
1161 modified_flags => $status_flags
1165 irn_flags => [ "rematerializable" ],
1166 state => "exc_pinned",
1167 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1168 out => [ "gp", "flags", "none" ] },
1169 ins => [ "base", "index", "mem", "operand" ],
1170 outs => [ "res", "flags", "M" ],
1171 am => "source,binary",
1172 emit => 'bsr%M %AS3, %D0',
1175 modified_flags => $status_flags
1179 # SSE4.2 or SSE4a popcnt instruction
1182 irn_flags => [ "rematerializable" ],
1183 state => "exc_pinned",
1184 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1185 out => [ "gp", "flags", "none" ] },
1186 ins => [ "base", "index", "mem", "operand" ],
1187 outs => [ "res", "flags", "M" ],
1188 am => "source,binary",
1189 emit => 'popcnt%M %AS3, %D0',
1192 modified_flags => $status_flags
1196 op_flags => [ "uses_memory", "fragile" ],
1197 state => "exc_pinned",
1199 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1200 out => [ "esp:I|S", "fpcw", "none", "eax", "ecx", "edx", "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "none", "none" ]
1202 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1203 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" ],
1204 emit => "call %*AS3",
1205 attr_type => "ia32_call_attr_t",
1206 attr => "unsigned pop, ir_type *call_tp",
1207 am => "source,unary",
1208 latency => 4, # random number
1209 modified_flags => $status_flags
1213 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1215 # PS: try gcc __builtin_frame_address(100000) :-)
1218 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1219 ins => [ "frame", "cnt", "tmp" ],
1221 latency => 4, # random number
1222 attr_type => "ia32_climbframe_attr_t",
1223 attr => "unsigned count",
1231 irn_flags => [ "rematerializable" ],
1232 reg_req => { in => [ "gp" ],
1233 out => [ "in_r1" ] },
1235 emit => 'bswap%M %S0',
1242 # bswap16, use xchg here
1245 irn_flags => [ "rematerializable" ],
1246 reg_req => { in => [ "eax ebx ecx edx" ],
1247 out => [ "in_r1" ] },
1248 emit => 'xchg %<S0, %>S0',
1259 reg_req => { in => [ "none" ], out => [ "none" ] },
1267 # Undefined Instruction on ALL x86 CPU's
1271 reg_req => { in => [ "none" ], out => [ "none" ] },
1282 irn_flags => [ "rematerializable" ],
1284 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1285 ins => [ "port", "value", "mem" ],
1286 emit => 'out%M %^S0, %#S1',
1289 modified_flags => $status_flags
1296 irn_flags => [ "rematerializable" ],
1298 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1299 ins => [ "port", "mem" ],
1300 outs => [ "res", "M" ],
1301 emit => 'in%M %#D0, %^S0',
1304 modified_flags => $status_flags
1308 # Intel style prefetching
1311 op_flags => [ "uses_memory" ],
1312 state => "exc_pinned",
1313 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1314 ins => [ "base", "index", "mem" ],
1317 emit => "prefetcht0 %AM",
1321 op_flags => [ "uses_memory" ],
1322 state => "exc_pinned",
1323 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1324 ins => [ "base", "index", "mem" ],
1327 emit => "prefetcht1 %AM",
1331 op_flags => [ "uses_memory" ],
1332 state => "exc_pinned",
1333 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1334 ins => [ "base", "index", "mem" ],
1337 emit => "prefetcht2 %AM",
1341 op_flags => [ "uses_memory" ],
1342 state => "exc_pinned",
1343 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1344 ins => [ "base", "index", "mem" ],
1347 emit => "prefetchnta %AM",
1351 # 3DNow! prefetch instructions
1354 op_flags => [ "uses_memory" ],
1355 state => "exc_pinned",
1356 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1357 ins => [ "base", "index", "mem" ],
1360 emit => "prefetch %AM",
1364 op_flags => [ "uses_memory" ],
1365 state => "exc_pinned",
1366 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1367 ins => [ "base", "index", "mem" ],
1370 emit => "prefetchw %AM",
1375 irn_flags => [ "rematerializable" ],
1376 reg_req => { out => [ "xmm" ] },
1377 emit => 'xorp%FX %D0, %D0',
1383 op_flags => [ "constlike" ],
1384 irn_flags => [ "rematerializable" ],
1385 reg_req => { out => [ "xmm" ] },
1392 irn_flags => [ "rematerializable" ],
1393 reg_req => { out => [ "xmm" ] },
1394 emit => 'pxor %D0, %D0',
1399 # produces all 1 bits
1401 irn_flags => [ "rematerializable" ],
1402 reg_req => { out => [ "xmm" ] },
1403 emit => 'pcmpeqb %D0, %D0',
1408 # integer shift left, dword
1410 irn_flags => [ "rematerializable" ],
1411 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1412 emit => 'pslld %#S1, %D0',
1417 # integer shift left, qword
1419 irn_flags => [ "rematerializable" ],
1420 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1421 emit => 'psllq %#S1, %D0',
1426 # integer shift right, dword
1428 irn_flags => [ "rematerializable" ],
1429 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1430 emit => 'psrld %#S1, %D0',
1435 # mov from integer to SSE register
1437 irn_flags => [ "rematerializable" ],
1438 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1439 emit => 'movd %S0, %D0',
1445 irn_flags => [ "rematerializable" ],
1446 state => "exc_pinned",
1447 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1448 out => [ "in_r4 in_r5", "flags", "none" ] },
1449 ins => [ "base", "index", "mem", "left", "right" ],
1450 outs => [ "res", "flags", "M" ],
1451 am => "source,binary",
1452 emit => 'adds%FX %B',
1458 irn_flags => [ "rematerializable" ],
1459 state => "exc_pinned",
1460 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1461 out => [ "in_r4 in_r5", "flags", "none" ] },
1462 ins => [ "base", "index", "mem", "left", "right" ],
1463 outs => [ "res", "flags", "M" ],
1464 am => "source,binary",
1465 emit => 'muls%FX %B',
1471 irn_flags => [ "rematerializable" ],
1472 state => "exc_pinned",
1473 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1474 out => [ "in_r4 in_r5", "flags", "none" ] },
1475 ins => [ "base", "index", "mem", "left", "right" ],
1476 outs => [ "res", "flags", "M" ],
1477 am => "source,binary",
1478 emit => 'maxs%FX %B',
1484 irn_flags => [ "rematerializable" ],
1485 state => "exc_pinned",
1486 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1487 out => [ "in_r4 in_r5", "flags", "none" ] },
1488 ins => [ "base", "index", "mem", "left", "right" ],
1489 outs => [ "res", "flags", "M" ],
1490 am => "source,binary",
1491 emit => 'mins%FX %B',
1497 irn_flags => [ "rematerializable" ],
1498 state => "exc_pinned",
1499 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1500 out => [ "in_r4 in_r5", "flags", "none" ] },
1501 ins => [ "base", "index", "mem", "left", "right" ],
1502 outs => [ "res", "flags", "M" ],
1503 am => "source,binary",
1504 emit => 'andp%FX %B',
1510 irn_flags => [ "rematerializable" ],
1511 state => "exc_pinned",
1512 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1513 out => [ "in_r4 in_r5", "flags", "none" ] },
1514 ins => [ "base", "index", "mem", "left", "right" ],
1515 outs => [ "res", "flags", "M" ],
1516 am => "source,binary",
1517 emit => 'orp%FX %B',
1523 irn_flags => [ "rematerializable" ],
1524 state => "exc_pinned",
1525 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1526 out => [ "in_r4 in_r5", "flags", "none" ] },
1527 ins => [ "base", "index", "mem", "left", "right" ],
1528 outs => [ "res", "flags", "M" ],
1529 am => "source,binary",
1530 emit => 'xorp%FX %B',
1536 irn_flags => [ "rematerializable" ],
1537 state => "exc_pinned",
1538 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1539 out => [ "in_r4 !in_r5", "flags", "none" ] },
1540 ins => [ "base", "index", "mem", "left", "right" ],
1541 outs => [ "res", "flags", "M" ],
1542 am => "source,binary",
1543 emit => 'andnp%FX %B',
1549 irn_flags => [ "rematerializable" ],
1550 state => "exc_pinned",
1551 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1552 out => [ "in_r4", "flags", "none" ] },
1553 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1554 outs => [ "res", "flags", "M" ],
1555 am => "source,binary",
1556 emit => 'subs%FX %B',
1562 irn_flags => [ "rematerializable" ],
1563 state => "exc_pinned",
1564 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1565 out => [ "in_r4 !in_r5", "flags", "none" ] },
1566 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1567 outs => [ "res", "flags", "M" ],
1568 am => "source,binary",
1569 emit => 'divs%FX %B',
1574 irn_flags => [ "rematerializable" ],
1575 state => "exc_pinned",
1576 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1577 out => [ "eflags" ] },
1578 ins => [ "base", "index", "mem", "left", "right" ],
1579 outs => [ "flags" ],
1580 am => "source,binary",
1581 attr => "bool ins_permuted",
1582 init_attr => "attr->data.ins_permuted = ins_permuted;",
1583 emit => 'ucomis%FX %B',
1585 mode => $mode_flags,
1586 modified_flags => 1,
1590 op_flags => [ "uses_memory", "fragile" ],
1591 state => "exc_pinned",
1592 reg_req => { in => [ "gp", "gp", "none" ],
1593 out => [ "xmm", "none", "none", "none", "none" ] },
1594 ins => [ "base", "index", "mem" ],
1595 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1596 emit => 'movs%FX %AM, %D0',
1597 attr => "ir_mode *load_mode",
1598 init_attr => "attr->ls_mode = load_mode;",
1603 op_flags => [ "uses_memory", "fragile" ],
1604 state => "exc_pinned",
1605 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1606 out => [ "none", "none", "none" ] },
1607 ins => [ "base", "index", "mem", "val" ],
1608 outs => [ "M", "X_regular", "X_except" ],
1609 emit => 'movs%FX %S3, %AM',
1614 op_flags => [ "uses_memory", "fragile" ],
1615 state => "exc_pinned",
1616 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1617 out => [ "none", "none", "none" ] },
1618 ins => [ "base", "index", "mem", "val" ],
1619 outs => [ "M", "X_regular", "X_except" ],
1620 emit => 'movs%FX %S3, %AM',
1625 state => "exc_pinned",
1626 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1627 ins => [ "base", "index", "mem", "val" ],
1628 am => "source,unary",
1629 emit => 'cvtsi2ss %AS3, %D0',
1635 state => "exc_pinned",
1636 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1637 ins => [ "base", "index", "mem", "val" ],
1638 am => "source,unary",
1639 emit => 'cvtsi2sd %AS3, %D0',
1646 ins => [ "val_high", "val_low" ],
1648 dump_func => "NULL",
1653 outs => [ "res_high", "res_low" ],
1655 dump_func => "NULL",
1659 op_flags => [ "uses_memory", "fragile" ],
1661 reg_req => { in => [ "edi", "esi", "ecx", "none" ],
1662 out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1663 ins => [ "dest", "source", "count", "mem" ],
1664 outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1665 attr_type => "ia32_copyb_attr_t",
1666 attr => "unsigned size",
1668 # we don't care about this flag, so no need to mark this node
1669 # modified_flags => [ "DF" ]
1673 op_flags => [ "uses_memory", "fragile" ],
1675 reg_req => { in => [ "edi", "esi", "none" ],
1676 out => [ "edi", "esi", "none", "none", "none" ] },
1677 ins => [ "dest", "source", "mem" ],
1678 outs => [ "dest", "source", "M", "X_regular", "X_except" ],
1679 attr_type => "ia32_copyb_attr_t",
1680 attr => "unsigned size",
1682 # we don't care about this flag, so no need to mark this node
1683 # modified_flags => [ "DF" ]
1687 state => "exc_pinned",
1688 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1697 op_flags => [ "uses_memory", "fragile" ],
1698 state => "exc_pinned",
1701 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1702 out => [ "gp", "none", "none", "none", "none" ] }
1705 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1706 out => [ "gp", "none", "none", "none", "none" ] }
1709 ins => [ "base", "index", "mem", "val" ],
1710 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1711 emit => "mov%#Ml %#AS3, %D0",
1712 am => "source,unary",
1714 attr => "ir_mode *smaller_mode",
1715 init_attr => "attr->ls_mode = smaller_mode;",
1720 state => "exc_pinned",
1721 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1722 ins => [ "base", "index", "mem", "val" ],
1723 am => "source,unary",
1729 state => "exc_pinned",
1730 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1731 ins => [ "base", "index", "mem", "val" ],
1732 am => "source,unary",
1738 state => "exc_pinned",
1739 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1740 ins => [ "base", "index", "mem", "val" ],
1741 am => "source,unary",
1746 # rematerialisation disabled for all float nodes for now, because the fpcw
1747 # handler runs before spilling and we might end up with wrong fpcw then
1750 # irn_flags => [ "rematerializable" ],
1751 state => "exc_pinned",
1752 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1753 out => [ "fp", "none", "none" ] },
1754 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1755 outs => [ "res", "dummy", "M" ],
1756 emit => 'fadd%FP%FM %AF',
1757 am => "source,binary",
1760 attr_type => "ia32_x87_attr_t",
1764 # irn_flags => [ "rematerializable" ],
1765 state => "exc_pinned",
1766 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1767 out => [ "fp", "none", "none" ] },
1768 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1769 outs => [ "res", "dummy", "M" ],
1770 emit => 'fmul%FP%FM %AF',
1771 am => "source,binary",
1774 attr_type => "ia32_x87_attr_t",
1778 # irn_flags => [ "rematerializable" ],
1779 state => "exc_pinned",
1780 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1781 out => [ "fp", "none", "none" ] },
1782 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
1783 outs => [ "res", "dummy", "M" ],
1784 emit => 'fsub%FR%FP%FM %AF',
1785 am => "source,binary",
1788 attr_type => "ia32_x87_attr_t",
1792 state => "exc_pinned",
1793 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1794 out => [ "fp", "none", "none" ] },
1795 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
1796 outs => [ "res", "dummy", "M" ],
1797 emit => 'fdiv%FR%FP%FM %AF',
1798 am => "source,binary",
1800 attr_type => "ia32_x87_attr_t",
1804 reg_req => { in => [ "fp", "fp", "fpcw" ], out => [ "fp" ] },
1805 ins => [ "left", "right", "fpcw" ],
1809 attr_type => "ia32_x87_attr_t",
1813 irn_flags => [ "rematerializable" ],
1814 reg_req => { in => [ "fp"], out => [ "fp" ] },
1819 attr_type => "ia32_x87_attr_t",
1823 irn_flags => [ "rematerializable" ],
1824 reg_req => { in => [ "fp"], out => [ "fp" ] },
1829 attr_type => "ia32_x87_attr_t",
1833 irn_flags => [ "rematerializable" ],
1834 op_flags => [ "uses_memory", "fragile" ],
1835 state => "exc_pinned",
1836 reg_req => { in => [ "gp", "gp", "none" ],
1837 out => [ "fp", "none", "none", "none", "none" ] },
1838 ins => [ "base", "index", "mem" ],
1839 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1840 emit => 'fld%FM %AM',
1841 attr => "ir_mode *load_mode",
1842 init_attr => "attr->attr.ls_mode = load_mode;",
1844 attr_type => "ia32_x87_attr_t",
1848 irn_flags => [ "rematerializable" ],
1849 op_flags => [ "uses_memory", "fragile" ],
1850 state => "exc_pinned",
1851 reg_req => { in => [ "gp", "gp", "none", "fp" ],
1852 out => [ "none", "none", "none" ] },
1853 ins => [ "base", "index", "mem", "val" ],
1854 outs => [ "M", "X_regular", "X_except" ],
1855 emit => 'fst%FP%FM %AM',
1856 attr => "ir_mode *store_mode",
1857 init_attr => "attr->attr.ls_mode = store_mode;",
1859 attr_type => "ia32_x87_attr_t",
1863 state => "exc_pinned",
1864 reg_req => { in => [ "gp", "gp", "none" ],
1865 out => [ "fp", "none", "none" ] },
1866 outs => [ "res", "unused", "M" ],
1867 ins => [ "base", "index", "mem" ],
1868 emit => 'fild%FM %AM',
1870 attr_type => "ia32_x87_attr_t",
1874 op_flags => [ "uses_memory", "fragile" ],
1875 state => "exc_pinned",
1876 reg_req => { in => [ "gp", "gp", "none", "fp", "fpcw" ],
1877 out => [ "none", "none", "none", "none" ] },
1878 ins => [ "base", "index", "mem", "val", "fpcw" ],
1879 outs => [ "dummy", "M", "X_regular", "X_except" ],
1880 emit => 'fist%FP%FM %AM',
1882 attr_type => "ia32_x87_attr_t",
1885 # SSE3 fisttp instruction
1887 op_flags => [ "uses_memory", "fragile" ],
1888 state => "exc_pinned",
1889 reg_req => { in => [ "gp", "gp", "none", "fp" ],
1890 out => [ "in_r4", "none", "none", "none" ]},
1891 ins => [ "base", "index", "mem", "val" ],
1892 outs => [ "res", "M", "X_regular", "X_except" ],
1893 emit => 'fisttp%FM %AM',
1895 attr_type => "ia32_x87_attr_t",
1899 irn_flags => [ "rematerializable" ],
1900 reg_req => { out => [ "fp" ] },
1905 attr_type => "ia32_x87_attr_t",
1909 irn_flags => [ "rematerializable" ],
1910 reg_req => { out => [ "fp" ] },
1915 attr_type => "ia32_x87_attr_t",
1919 irn_flags => [ "rematerializable" ],
1920 reg_req => { out => [ "fp" ] },
1925 attr_type => "ia32_x87_attr_t",
1929 irn_flags => [ "rematerializable" ],
1930 reg_req => { out => [ "fp" ] },
1935 attr_type => "ia32_x87_attr_t",
1939 irn_flags => [ "rematerializable" ],
1940 reg_req => { out => [ "fp" ] },
1945 attr_type => "ia32_x87_attr_t",
1949 irn_flags => [ "rematerializable" ],
1950 reg_req => { out => [ "fp" ] },
1955 attr_type => "ia32_x87_attr_t",
1959 irn_flags => [ "rematerializable" ],
1960 reg_req => { out => [ "fp" ] },
1965 attr_type => "ia32_x87_attr_t",
1969 # we can't allow to rematerialize this node so we don't
1970 # accidently produce Phi(Fucom, Fucom(ins_permuted))
1971 # irn_flags => [ "rematerializable" ],
1972 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
1973 ins => [ "left", "right" ],
1974 outs => [ "flags" ],
1975 emit => "fucom%FP %F0\n".
1977 attr => "bool ins_permuted",
1978 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
1980 attr_type => "ia32_x87_attr_t",
1985 # we can't allow to rematerialize this node so we don't
1986 # accidently produce Phi(Fucom, Fucom(ins_permuted))
1987 # irn_flags => [ "rematerializable" ],
1988 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
1989 ins => [ "left", "right" ],
1990 outs => [ "flags" ],
1991 emit => "fucompp\n".
1993 attr => "bool ins_permuted",
1994 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
1996 attr_type => "ia32_x87_attr_t",
2001 irn_flags => [ "rematerializable" ],
2002 reg_req => { in => [ "fp", "fp" ], out => [ "eflags" ] },
2003 ins => [ "left", "right" ],
2004 outs => [ "flags" ],
2005 emit => 'fucom%FPi %F0',
2006 attr => "bool ins_permuted",
2007 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2009 attr_type => "ia32_x87_attr_t",
2014 # irn_flags => [ "rematerializable" ],
2015 reg_req => { in => [ "fp" ], out => [ "eax" ] },
2017 outs => [ "flags" ],
2020 attr => "bool ins_permuted",
2021 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2023 attr_type => "ia32_x87_attr_t",
2028 irn_flags => [ "rematerializable" ],
2029 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2031 outs => [ "flags" ],
2034 mode => $mode_flags,
2038 # Note that it is NEVER allowed to do CSE on these nodes
2039 # Moreover, note the virtual register requierements!
2042 op_flags => [ "keep" ],
2043 reg_req => { out => [ "none" ] },
2044 cmp_attr => "return 1;",
2046 attr_type => "ia32_x87_attr_t",
2052 op_flags => [ "keep" ],
2053 reg_req => { out => [ "none" ] },
2054 cmp_attr => "return 1;",
2056 attr_type => "ia32_x87_attr_t",
2062 reg_req => { in => [ "fp"], out => [ "fp" ] },
2063 cmp_attr => "return 1;",
2065 attr_type => "ia32_x87_attr_t",
2070 op_flags => [ "keep" ],
2071 reg_req => { out => [ "none" ] },
2072 cmp_attr => "return 1;",
2074 attr_type => "ia32_x87_attr_t",
2080 op_flags => [ "keep" ],
2081 reg_req => { out => [ "none" ] },
2082 cmp_attr => "return 1;",
2083 emit => 'ffreep %F0',
2084 attr_type => "ia32_x87_attr_t",
2090 op_flags => [ "keep" ],
2091 reg_req => { out => [ "none" ] },
2092 cmp_attr => "return 1;",
2094 attr_type => "ia32_x87_attr_t",
2100 op_flags => [ "keep" ],
2101 reg_req => { out => [ "none" ] },
2102 cmp_attr => "return 1;",
2104 attr_type => "ia32_x87_attr_t",
2109 # Spilling and reloading of SSE registers, hardcoded, not generated #
2112 op_flags => [ "uses_memory", "fragile" ],
2113 state => "exc_pinned",
2114 reg_req => { in => [ "gp", "gp", "none" ],
2115 out => [ "xmm", "none", "none", "none" ] },
2116 emit => 'movdqu %D0, %AM',
2117 ins => [ "base", "index", "mem" ],
2118 outs => [ "res", "M", "X_regular", "X_except" ],
2123 op_flags => [ "uses_memory", "fragile" ],
2124 state => "exc_pinned",
2125 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
2126 out => [ "none", "none", "none" ] },
2127 ins => [ "base", "index", "mem", "val" ],
2128 outs => [ "M", "X_regular", "X_except" ],
2129 emit => 'movdqu %B',
2135 # Transform some attributes
2136 foreach my $op (keys(%nodes)) {
2137 my $node = $nodes{$op};
2138 my $op_attr_init = $node->{op_attr_init};
2140 if(defined($op_attr_init)) {
2141 $op_attr_init .= "\n\t";
2146 if(!defined($node->{latency})) {
2148 $node->{latency} = 0;
2150 die("Latency missing for op $op");
2153 $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2155 $node->{op_attr_init} = $op_attr_init;