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",
997 reg_req => { in => [ "gp", "gp", "none", "gp" ],
998 out => [ "none", "none", "none" ] },
999 ins => [ "base", "index", "mem", "val" ],
1000 outs => [ "M", "X_regular", "X_except" ],
1001 emit => 'mov%M %#S3, %AM',
1006 op_flags => [ "uses_memory", "fragile" ],
1007 state => "exc_pinned",
1008 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1009 out => ["none", "none", "none" ] },
1010 ins => [ "base", "index", "mem", "val" ],
1011 outs => [ "M", "X_regular", "X_except" ],
1012 emit => 'mov%M %#S3, %AM',
1017 irn_flags => [ "rematerializable" ],
1018 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1019 ins => [ "base", "index" ],
1020 emit => 'leal %AM, %D0',
1023 # lea doesn't modify the flags, but setting this seems advantageous since it
1024 # increases chances that the Lea is transformed back to an Add
1025 modified_flags => 1,
1029 state => "exc_pinned",
1030 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1031 ins => [ "base", "index", "mem", "val", "stack" ],
1032 emit => 'push%M %AS3',
1033 outs => [ "stack", "M" ],
1034 am => "source,unary",
1039 state => "exc_pinned",
1040 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1042 outs => [ "stack" ],
1043 emit => 'pushl %%eax',
1049 state => "exc_pinned",
1050 reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1051 ins => [ "mem", "stack" ],
1052 outs => [ "res", "M", "unused", "stack" ],
1053 emit => 'pop%M %D0',
1054 latency => 3, # Pop is more expensive than Push on Athlon
1058 state => "exc_pinned",
1059 reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1060 ins => [ "mem", "stack" ],
1061 outs => [ "res", "M", "unused", "stack" ],
1062 emit => 'pop%M %D0',
1063 latency => 3, # Pop is more expensive than Push on Athlon
1067 state => "exc_pinned",
1068 reg_req => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1071 emit => 'movl %S0, %D0',
1077 state => "exc_pinned",
1078 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1079 ins => [ "base", "index", "mem", "stack" ],
1080 outs => [ "unused0", "M", "unused1", "stack" ],
1081 emit => 'pop%M %AM',
1082 latency => 3, # Pop is more expensive than Push on Athlon
1086 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1088 outs => [ "frame", "stack", "M" ],
1093 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1095 outs => [ "frame", "stack" ],
1097 state => "exc_pinned",
1102 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1103 ins => [ "base", "index", "mem", "stack", "size" ],
1104 am => "source,binary",
1107 outs => [ "stack", "M" ],
1108 modified_flags => $status_flags
1113 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1114 ins => [ "base", "index", "mem", "stack", "size" ],
1115 am => "source,binary",
1116 emit => "subl %B\n".
1119 outs => [ "stack", "addr", "M" ],
1120 modified_flags => $status_flags
1124 op_flags => [ "keep" ],
1132 irn_flags => [ "rematerializable" ],
1133 reg_req => { out => [ "gp" ] },
1134 emit => "movl %%gs:0, %D0",
1140 # BT supports source address mode, but this is unused yet
1143 irn_flags => [ "rematerializable" ],
1144 state => "exc_pinned",
1145 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1146 ins => [ "left", "right" ],
1147 emit => 'bt%M %S1, %S0',
1149 mode => $mode_flags,
1150 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1154 irn_flags => [ "rematerializable" ],
1155 state => "exc_pinned",
1156 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1157 out => [ "gp", "flags", "none" ] },
1158 ins => [ "base", "index", "mem", "operand" ],
1159 outs => [ "res", "flags", "M" ],
1160 am => "source,binary",
1161 emit => 'bsf%M %AS3, %D0',
1164 modified_flags => $status_flags
1168 irn_flags => [ "rematerializable" ],
1169 state => "exc_pinned",
1170 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1171 out => [ "gp", "flags", "none" ] },
1172 ins => [ "base", "index", "mem", "operand" ],
1173 outs => [ "res", "flags", "M" ],
1174 am => "source,binary",
1175 emit => 'bsr%M %AS3, %D0',
1178 modified_flags => $status_flags
1182 # SSE4.2 or SSE4a popcnt instruction
1185 irn_flags => [ "rematerializable" ],
1186 state => "exc_pinned",
1187 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1188 out => [ "gp", "flags", "none" ] },
1189 ins => [ "base", "index", "mem", "operand" ],
1190 outs => [ "res", "flags", "M" ],
1191 am => "source,binary",
1192 emit => 'popcnt%M %AS3, %D0',
1195 modified_flags => $status_flags
1199 op_flags => [ "uses_memory", "fragile" ],
1200 state => "exc_pinned",
1202 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1203 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" ]
1205 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1206 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" ],
1207 emit => "call %*AS3",
1208 attr_type => "ia32_call_attr_t",
1209 attr => "unsigned pop, ir_type *call_tp",
1210 am => "source,unary",
1211 latency => 4, # random number
1212 modified_flags => $status_flags
1216 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1218 # PS: try gcc __builtin_frame_address(100000) :-)
1221 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1222 ins => [ "frame", "cnt", "tmp" ],
1224 latency => 4, # random number
1225 attr_type => "ia32_climbframe_attr_t",
1226 attr => "unsigned count",
1234 irn_flags => [ "rematerializable" ],
1235 reg_req => { in => [ "gp" ],
1236 out => [ "in_r1" ] },
1238 emit => 'bswap%M %S0',
1245 # bswap16, use xchg here
1248 irn_flags => [ "rematerializable" ],
1249 reg_req => { in => [ "eax ebx ecx edx" ],
1250 out => [ "in_r1" ] },
1251 emit => 'xchg %<S0, %>S0',
1262 reg_req => { in => [ "none" ], out => [ "none" ] },
1270 # Undefined Instruction on ALL x86 CPU's
1274 reg_req => { in => [ "none" ], out => [ "none" ] },
1285 irn_flags => [ "rematerializable" ],
1287 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1288 ins => [ "port", "value", "mem" ],
1289 emit => 'out%M %^S0, %#S1',
1292 modified_flags => $status_flags
1299 irn_flags => [ "rematerializable" ],
1301 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1302 ins => [ "port", "mem" ],
1303 outs => [ "res", "M" ],
1304 emit => 'in%M %#D0, %^S0',
1307 modified_flags => $status_flags
1311 # Intel style prefetching
1314 op_flags => [ "uses_memory" ],
1315 state => "exc_pinned",
1316 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1317 ins => [ "base", "index", "mem" ],
1320 emit => "prefetcht0 %AM",
1324 op_flags => [ "uses_memory" ],
1325 state => "exc_pinned",
1326 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1327 ins => [ "base", "index", "mem" ],
1330 emit => "prefetcht1 %AM",
1334 op_flags => [ "uses_memory" ],
1335 state => "exc_pinned",
1336 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1337 ins => [ "base", "index", "mem" ],
1340 emit => "prefetcht2 %AM",
1344 op_flags => [ "uses_memory" ],
1345 state => "exc_pinned",
1346 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1347 ins => [ "base", "index", "mem" ],
1350 emit => "prefetchnta %AM",
1354 # 3DNow! prefetch instructions
1357 op_flags => [ "uses_memory" ],
1358 state => "exc_pinned",
1359 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1360 ins => [ "base", "index", "mem" ],
1363 emit => "prefetch %AM",
1367 op_flags => [ "uses_memory" ],
1368 state => "exc_pinned",
1369 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1370 ins => [ "base", "index", "mem" ],
1373 emit => "prefetchw %AM",
1378 irn_flags => [ "rematerializable" ],
1379 reg_req => { out => [ "xmm" ] },
1380 emit => 'xorp%FX %D0, %D0',
1386 op_flags => [ "constlike" ],
1387 irn_flags => [ "rematerializable" ],
1388 reg_req => { out => [ "xmm" ] },
1395 irn_flags => [ "rematerializable" ],
1396 reg_req => { out => [ "xmm" ] },
1397 emit => 'pxor %D0, %D0',
1402 # produces all 1 bits
1404 irn_flags => [ "rematerializable" ],
1405 reg_req => { out => [ "xmm" ] },
1406 emit => 'pcmpeqb %D0, %D0',
1411 # integer shift left, dword
1413 irn_flags => [ "rematerializable" ],
1414 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1415 emit => 'pslld %#S1, %D0',
1420 # integer shift left, qword
1422 irn_flags => [ "rematerializable" ],
1423 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1424 emit => 'psllq %#S1, %D0',
1429 # integer shift right, dword
1431 irn_flags => [ "rematerializable" ],
1432 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1433 emit => 'psrld %#S1, %D0',
1438 # mov from integer to SSE register
1440 irn_flags => [ "rematerializable" ],
1441 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1442 emit => 'movd %S0, %D0',
1448 irn_flags => [ "rematerializable" ],
1449 state => "exc_pinned",
1450 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1451 out => [ "in_r4 in_r5", "flags", "none" ] },
1452 ins => [ "base", "index", "mem", "left", "right" ],
1453 outs => [ "res", "flags", "M" ],
1454 am => "source,binary",
1455 emit => 'adds%FX %B',
1461 irn_flags => [ "rematerializable" ],
1462 state => "exc_pinned",
1463 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1464 out => [ "in_r4 in_r5", "flags", "none" ] },
1465 ins => [ "base", "index", "mem", "left", "right" ],
1466 outs => [ "res", "flags", "M" ],
1467 am => "source,binary",
1468 emit => 'muls%FX %B',
1474 irn_flags => [ "rematerializable" ],
1475 state => "exc_pinned",
1476 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1477 out => [ "in_r4 in_r5", "flags", "none" ] },
1478 ins => [ "base", "index", "mem", "left", "right" ],
1479 outs => [ "res", "flags", "M" ],
1480 am => "source,binary",
1481 emit => 'maxs%FX %B',
1487 irn_flags => [ "rematerializable" ],
1488 state => "exc_pinned",
1489 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1490 out => [ "in_r4 in_r5", "flags", "none" ] },
1491 ins => [ "base", "index", "mem", "left", "right" ],
1492 outs => [ "res", "flags", "M" ],
1493 am => "source,binary",
1494 emit => 'mins%FX %B',
1500 irn_flags => [ "rematerializable" ],
1501 state => "exc_pinned",
1502 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1503 out => [ "in_r4 in_r5", "flags", "none" ] },
1504 ins => [ "base", "index", "mem", "left", "right" ],
1505 outs => [ "res", "flags", "M" ],
1506 am => "source,binary",
1507 emit => 'andp%FX %B',
1513 irn_flags => [ "rematerializable" ],
1514 state => "exc_pinned",
1515 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1516 out => [ "in_r4 in_r5", "flags", "none" ] },
1517 ins => [ "base", "index", "mem", "left", "right" ],
1518 outs => [ "res", "flags", "M" ],
1519 am => "source,binary",
1520 emit => 'orp%FX %B',
1526 irn_flags => [ "rematerializable" ],
1527 state => "exc_pinned",
1528 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1529 out => [ "in_r4 in_r5", "flags", "none" ] },
1530 ins => [ "base", "index", "mem", "left", "right" ],
1531 outs => [ "res", "flags", "M" ],
1532 am => "source,binary",
1533 emit => 'xorp%FX %B',
1539 irn_flags => [ "rematerializable" ],
1540 state => "exc_pinned",
1541 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1542 out => [ "in_r4 !in_r5", "flags", "none" ] },
1543 ins => [ "base", "index", "mem", "left", "right" ],
1544 outs => [ "res", "flags", "M" ],
1545 am => "source,binary",
1546 emit => 'andnp%FX %B',
1552 irn_flags => [ "rematerializable" ],
1553 state => "exc_pinned",
1554 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1555 out => [ "in_r4", "flags", "none" ] },
1556 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1557 outs => [ "res", "flags", "M" ],
1558 am => "source,binary",
1559 emit => 'subs%FX %B',
1565 irn_flags => [ "rematerializable" ],
1566 state => "exc_pinned",
1567 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1568 out => [ "in_r4 !in_r5", "flags", "none" ] },
1569 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1570 outs => [ "res", "flags", "M" ],
1571 am => "source,binary",
1572 emit => 'divs%FX %B',
1577 irn_flags => [ "rematerializable" ],
1578 state => "exc_pinned",
1579 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1580 out => [ "eflags" ] },
1581 ins => [ "base", "index", "mem", "left", "right" ],
1582 outs => [ "flags" ],
1583 am => "source,binary",
1584 attr => "bool ins_permuted",
1585 init_attr => "attr->data.ins_permuted = ins_permuted;",
1586 emit => 'ucomis%FX %B',
1588 mode => $mode_flags,
1589 modified_flags => 1,
1593 op_flags => [ "uses_memory", "fragile" ],
1594 state => "exc_pinned",
1595 reg_req => { in => [ "gp", "gp", "none" ],
1596 out => [ "xmm", "none", "none", "none", "none" ] },
1597 ins => [ "base", "index", "mem" ],
1598 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1599 emit => 'movs%FX %AM, %D0',
1600 attr => "ir_mode *load_mode",
1601 init_attr => "attr->ls_mode = load_mode;",
1606 op_flags => [ "uses_memory", "fragile" ],
1607 state => "exc_pinned",
1608 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1609 out => [ "none", "none", "none" ] },
1610 ins => [ "base", "index", "mem", "val" ],
1611 outs => [ "M", "X_regular", "X_except" ],
1612 emit => 'movs%FX %S3, %AM',
1617 op_flags => [ "uses_memory", "fragile" ],
1618 state => "exc_pinned",
1619 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1620 out => [ "none", "none", "none" ] },
1621 ins => [ "base", "index", "mem", "val" ],
1622 outs => [ "M", "X_regular", "X_except" ],
1623 emit => 'movs%FX %S3, %AM',
1628 state => "exc_pinned",
1629 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1630 ins => [ "base", "index", "mem", "val" ],
1631 am => "source,unary",
1632 emit => 'cvtsi2ss %AS3, %D0',
1638 state => "exc_pinned",
1639 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1640 ins => [ "base", "index", "mem", "val" ],
1641 am => "source,unary",
1642 emit => 'cvtsi2sd %AS3, %D0',
1649 ins => [ "val_high", "val_low" ],
1651 dump_func => "NULL",
1656 outs => [ "res_high", "res_low" ],
1658 dump_func => "NULL",
1662 op_flags => [ "uses_memory", "fragile" ],
1664 reg_req => { in => [ "edi", "esi", "ecx", "none" ],
1665 out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1666 ins => [ "dest", "source", "count", "mem" ],
1667 outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1668 attr_type => "ia32_copyb_attr_t",
1669 attr => "unsigned size",
1671 # we don't care about this flag, so no need to mark this node
1672 # modified_flags => [ "DF" ]
1676 op_flags => [ "uses_memory", "fragile" ],
1678 reg_req => { in => [ "edi", "esi", "none" ],
1679 out => [ "edi", "esi", "none", "none", "none" ] },
1680 ins => [ "dest", "source", "mem" ],
1681 outs => [ "dest", "source", "M", "X_regular", "X_except" ],
1682 attr_type => "ia32_copyb_attr_t",
1683 attr => "unsigned size",
1685 # we don't care about this flag, so no need to mark this node
1686 # modified_flags => [ "DF" ]
1690 state => "exc_pinned",
1691 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1700 op_flags => [ "uses_memory", "fragile" ],
1701 state => "exc_pinned",
1704 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1705 out => [ "gp", "none", "none", "none", "none" ] }
1708 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1709 out => [ "gp", "none", "none", "none", "none" ] }
1712 ins => [ "base", "index", "mem", "val" ],
1713 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1714 emit => "mov%#Ml %#AS3, %D0",
1715 am => "source,unary",
1717 attr => "ir_mode *smaller_mode",
1718 init_attr => "attr->ls_mode = smaller_mode;",
1723 state => "exc_pinned",
1724 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1725 ins => [ "base", "index", "mem", "val" ],
1726 am => "source,unary",
1732 state => "exc_pinned",
1733 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1734 ins => [ "base", "index", "mem", "val" ],
1735 am => "source,unary",
1741 state => "exc_pinned",
1742 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1743 ins => [ "base", "index", "mem", "val" ],
1744 am => "source,unary",
1749 # rematerialisation disabled for all float nodes for now, because the fpcw
1750 # handler runs before spilling and we might end up with wrong fpcw then
1753 # irn_flags => [ "rematerializable" ],
1754 state => "exc_pinned",
1755 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1756 out => [ "fp", "none", "none" ] },
1757 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1758 outs => [ "res", "dummy", "M" ],
1759 emit => 'fadd%FP%FM %AF',
1760 am => "source,binary",
1763 attr_type => "ia32_x87_attr_t",
1767 # irn_flags => [ "rematerializable" ],
1768 state => "exc_pinned",
1769 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1770 out => [ "fp", "none", "none" ] },
1771 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1772 outs => [ "res", "dummy", "M" ],
1773 emit => 'fmul%FP%FM %AF',
1774 am => "source,binary",
1777 attr_type => "ia32_x87_attr_t",
1781 # irn_flags => [ "rematerializable" ],
1782 state => "exc_pinned",
1783 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1784 out => [ "fp", "none", "none" ] },
1785 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
1786 outs => [ "res", "dummy", "M" ],
1787 emit => 'fsub%FR%FP%FM %AF',
1788 am => "source,binary",
1791 attr_type => "ia32_x87_attr_t",
1795 state => "exc_pinned",
1796 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1797 out => [ "fp", "none", "none" ] },
1798 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
1799 outs => [ "res", "dummy", "M" ],
1800 emit => 'fdiv%FR%FP%FM %AF',
1801 am => "source,binary",
1803 attr_type => "ia32_x87_attr_t",
1807 reg_req => { in => [ "fp", "fp", "fpcw" ], out => [ "fp" ] },
1808 ins => [ "left", "right", "fpcw" ],
1812 attr_type => "ia32_x87_attr_t",
1816 irn_flags => [ "rematerializable" ],
1817 reg_req => { in => [ "fp"], out => [ "fp" ] },
1822 attr_type => "ia32_x87_attr_t",
1826 irn_flags => [ "rematerializable" ],
1827 reg_req => { in => [ "fp"], out => [ "fp" ] },
1832 attr_type => "ia32_x87_attr_t",
1836 irn_flags => [ "rematerializable" ],
1837 op_flags => [ "uses_memory", "fragile" ],
1838 state => "exc_pinned",
1839 reg_req => { in => [ "gp", "gp", "none" ],
1840 out => [ "fp", "none", "none", "none", "none" ] },
1841 ins => [ "base", "index", "mem" ],
1842 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1843 emit => 'fld%FM %AM',
1844 attr => "ir_mode *load_mode",
1845 init_attr => "attr->attr.ls_mode = load_mode;",
1847 attr_type => "ia32_x87_attr_t",
1851 irn_flags => [ "rematerializable" ],
1852 op_flags => [ "uses_memory", "fragile" ],
1853 state => "exc_pinned",
1854 reg_req => { in => [ "gp", "gp", "none", "fp" ],
1855 out => [ "none", "none", "none" ] },
1856 ins => [ "base", "index", "mem", "val" ],
1857 outs => [ "M", "X_regular", "X_except" ],
1858 emit => 'fst%FP%FM %AM',
1859 attr => "ir_mode *store_mode",
1860 init_attr => "attr->attr.ls_mode = store_mode;",
1862 attr_type => "ia32_x87_attr_t",
1866 state => "exc_pinned",
1867 reg_req => { in => [ "gp", "gp", "none" ],
1868 out => [ "fp", "none", "none" ] },
1869 outs => [ "res", "unused", "M" ],
1870 ins => [ "base", "index", "mem" ],
1871 emit => 'fild%FM %AM',
1873 attr_type => "ia32_x87_attr_t",
1877 op_flags => [ "uses_memory", "fragile" ],
1878 state => "exc_pinned",
1879 reg_req => { in => [ "gp", "gp", "none", "fp", "fpcw" ],
1880 out => [ "none", "none", "none", "none" ] },
1881 ins => [ "base", "index", "mem", "val", "fpcw" ],
1882 outs => [ "dummy", "M", "X_regular", "X_except" ],
1883 emit => 'fist%FP%FM %AM',
1885 attr_type => "ia32_x87_attr_t",
1888 # SSE3 fisttp instruction
1890 op_flags => [ "uses_memory", "fragile" ],
1891 state => "exc_pinned",
1892 reg_req => { in => [ "gp", "gp", "none", "fp" ],
1893 out => [ "in_r4", "none", "none", "none" ]},
1894 ins => [ "base", "index", "mem", "val" ],
1895 outs => [ "res", "M", "X_regular", "X_except" ],
1896 emit => 'fisttp%FM %AM',
1898 attr_type => "ia32_x87_attr_t",
1902 irn_flags => [ "rematerializable" ],
1903 reg_req => { out => [ "fp" ] },
1908 attr_type => "ia32_x87_attr_t",
1912 irn_flags => [ "rematerializable" ],
1913 reg_req => { out => [ "fp" ] },
1918 attr_type => "ia32_x87_attr_t",
1922 irn_flags => [ "rematerializable" ],
1923 reg_req => { out => [ "fp" ] },
1928 attr_type => "ia32_x87_attr_t",
1932 irn_flags => [ "rematerializable" ],
1933 reg_req => { out => [ "fp" ] },
1938 attr_type => "ia32_x87_attr_t",
1942 irn_flags => [ "rematerializable" ],
1943 reg_req => { out => [ "fp" ] },
1948 attr_type => "ia32_x87_attr_t",
1952 irn_flags => [ "rematerializable" ],
1953 reg_req => { out => [ "fp" ] },
1958 attr_type => "ia32_x87_attr_t",
1962 irn_flags => [ "rematerializable" ],
1963 reg_req => { out => [ "fp" ] },
1968 attr_type => "ia32_x87_attr_t",
1972 # we can't allow to rematerialize this node so we don't
1973 # accidently produce Phi(Fucom, Fucom(ins_permuted))
1974 # irn_flags => [ "rematerializable" ],
1975 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
1976 ins => [ "left", "right" ],
1977 outs => [ "flags" ],
1978 emit => "fucom%FP %F0\n".
1980 attr => "bool ins_permuted",
1981 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
1983 attr_type => "ia32_x87_attr_t",
1988 # we can't allow to rematerialize this node so we don't
1989 # accidently produce Phi(Fucom, Fucom(ins_permuted))
1990 # irn_flags => [ "rematerializable" ],
1991 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
1992 ins => [ "left", "right" ],
1993 outs => [ "flags" ],
1994 emit => "fucompp\n".
1996 attr => "bool ins_permuted",
1997 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
1999 attr_type => "ia32_x87_attr_t",
2004 irn_flags => [ "rematerializable" ],
2005 reg_req => { in => [ "fp", "fp" ], out => [ "eflags" ] },
2006 ins => [ "left", "right" ],
2007 outs => [ "flags" ],
2008 emit => 'fucom%FPi %F0',
2009 attr => "bool ins_permuted",
2010 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2012 attr_type => "ia32_x87_attr_t",
2017 # irn_flags => [ "rematerializable" ],
2018 reg_req => { in => [ "fp" ], out => [ "eax" ] },
2020 outs => [ "flags" ],
2023 attr => "bool ins_permuted",
2024 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2026 attr_type => "ia32_x87_attr_t",
2031 irn_flags => [ "rematerializable" ],
2032 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2034 outs => [ "flags" ],
2037 mode => $mode_flags,
2041 # Note that it is NEVER allowed to do CSE on these nodes
2042 # Moreover, note the virtual register requierements!
2045 op_flags => [ "keep" ],
2046 reg_req => { out => [ "none" ] },
2047 cmp_attr => "return 1;",
2049 attr_type => "ia32_x87_attr_t",
2055 op_flags => [ "keep" ],
2056 reg_req => { out => [ "none" ] },
2057 cmp_attr => "return 1;",
2059 attr_type => "ia32_x87_attr_t",
2065 reg_req => { in => [ "fp"], out => [ "fp" ] },
2066 cmp_attr => "return 1;",
2068 attr_type => "ia32_x87_attr_t",
2073 op_flags => [ "keep" ],
2074 reg_req => { out => [ "none" ] },
2075 cmp_attr => "return 1;",
2077 attr_type => "ia32_x87_attr_t",
2083 op_flags => [ "keep" ],
2084 reg_req => { out => [ "none" ] },
2085 cmp_attr => "return 1;",
2086 emit => 'ffreep %F0',
2087 attr_type => "ia32_x87_attr_t",
2093 op_flags => [ "keep" ],
2094 reg_req => { out => [ "none" ] },
2095 cmp_attr => "return 1;",
2097 attr_type => "ia32_x87_attr_t",
2103 op_flags => [ "keep" ],
2104 reg_req => { out => [ "none" ] },
2105 cmp_attr => "return 1;",
2107 attr_type => "ia32_x87_attr_t",
2112 # Spilling and reloading of SSE registers, hardcoded, not generated #
2115 op_flags => [ "uses_memory", "fragile" ],
2116 state => "exc_pinned",
2117 reg_req => { in => [ "gp", "gp", "none" ],
2118 out => [ "xmm", "none", "none", "none" ] },
2119 emit => 'movdqu %D0, %AM',
2120 ins => [ "base", "index", "mem" ],
2121 outs => [ "res", "M", "X_regular", "X_except" ],
2126 op_flags => [ "uses_memory", "fragile" ],
2127 state => "exc_pinned",
2128 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
2129 out => [ "none", "none", "none" ] },
2130 ins => [ "base", "index", "mem", "val" ],
2131 outs => [ "M", "X_regular", "X_except" ],
2132 emit => 'movdqu %B',
2138 # Transform some attributes
2139 foreach my $op (keys(%nodes)) {
2140 my $node = $nodes{$op};
2141 my $op_attr_init = $node->{op_attr_init};
2143 if(defined($op_attr_init)) {
2144 $op_attr_init .= "\n\t";
2149 if(!defined($node->{latency})) {
2151 $node->{latency} = 0;
2153 die("Latency missing for op $op");
2156 $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2158 $node->{op_attr_init} = $op_attr_init;