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" ];
154 op_flags => [ "constlike" ],
155 irn_flags => [ "not_scheduled" ],
156 reg_req => { out => [ "gp_NOREG:I" ] },
157 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
158 attr_type => "ia32_immediate_attr_t",
159 hash_func => "ia32_hash_Immediate",
167 out_arity => "variable",
168 attr_type => "ia32_asm_attr_t",
169 attr => "ident *asm_text, const ia32_asm_reg_t *register_map",
170 init_attr => "attr->asm_text = asm_text;\n".
171 "\tattr->register_map = register_map;\n",
173 modified_flags => $status_flags,
176 # "allocates" a free register
178 op_flags => [ "constlike", "cse_neutral" ],
179 irn_flags => [ "rematerializable" ],
180 reg_req => { out => [ "gp" ] },
184 cmp_attr => "return 1;",
188 irn_flags => [ "rematerializable" ],
189 state => "exc_pinned",
190 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
191 out => [ "in_r4 in_r5", "flags", "none" ] },
192 ins => [ "base", "index", "mem", "left", "right" ],
193 outs => [ "res", "flags", "M" ],
195 am => "source,binary",
198 modified_flags => $status_flags
202 irn_flags => [ "rematerializable" ],
203 state => "exc_pinned",
204 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
205 ins => [ "base", "index", "mem", "val" ],
206 emit => "add%M %#S3, %AM",
209 modified_flags => $status_flags
213 irn_flags => [ "rematerializable" ],
214 state => "exc_pinned",
215 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
216 ins => [ "base", "index", "mem", "val" ],
217 emit => "add%M %#S3, %AM",
220 modified_flags => $status_flags
224 state => "exc_pinned",
225 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
226 out => [ "in_r4 in_r5", "flags", "none" ] },
227 ins => [ "base", "index", "mem", "left", "right", "eflags" ],
228 outs => [ "res", "flags", "M" ],
230 am => "source,binary",
233 modified_flags => $status_flags
237 ins => [ "left", "right" ],
243 ins => [ "left", "right", "eflags" ],
249 # we should not rematrialize this node. It produces 2 results and has
250 # very strict constraints
251 state => "exc_pinned",
252 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
253 out => [ "eax", "flags", "none", "edx" ] },
254 ins => [ "base", "index", "mem", "left", "right" ],
255 emit => 'mul%M %AS4',
256 outs => [ "res_low", "flags", "M", "res_high" ],
257 am => "source,binary",
259 modified_flags => $status_flags
263 ins => [ "left", "right" ],
264 outs => [ "res_low", "flags", "M", "res_high" ],
270 irn_flags => [ "rematerializable" ],
271 state => "exc_pinned",
272 # TODO: adjust out requirements for the 3 operand form
273 # (no need for should_be_same then)
274 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
275 out => [ "in_r4 in_r5", "flags", "none" ] },
276 ins => [ "base", "index", "mem", "left", "right" ],
277 outs => [ "res", "flags", "M" ],
278 am => "source,binary",
281 modified_flags => $status_flags
285 irn_flags => [ "rematerializable" ],
286 state => "exc_pinned",
287 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
288 out => [ "eax", "flags", "none", "edx" ] },
289 ins => [ "base", "index", "mem", "left", "right" ],
290 emit => 'imul%M %AS4',
291 outs => [ "res_low", "flags", "M", "res_high" ],
292 am => "source,binary",
294 modified_flags => $status_flags
298 ins => [ "left", "right" ],
299 outs => [ "res_low", "flags", "M", "res_high" ],
305 irn_flags => [ "rematerializable" ],
306 state => "exc_pinned",
307 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
308 out => [ "in_r4 in_r5", "flags", "none" ] },
309 ins => [ "base", "index", "mem", "left", "right" ],
310 outs => [ "res", "flags", "M" ],
311 am => "source,binary",
315 modified_flags => $status_flags
319 irn_flags => [ "rematerializable" ],
320 state => "exc_pinned",
321 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
322 ins => [ "base", "index", "mem", "val" ],
323 emit => 'and%M %#S3, %AM',
326 modified_flags => $status_flags
330 irn_flags => [ "rematerializable" ],
331 state => "exc_pinned",
332 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
333 ins => [ "base", "index", "mem", "val" ],
334 emit => 'and%M %#S3, %AM',
337 modified_flags => $status_flags
341 irn_flags => [ "rematerializable" ],
342 state => "exc_pinned",
343 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
344 out => [ "in_r4 in_r5", "flags", "none" ] },
345 ins => [ "base", "index", "mem", "left", "right" ],
346 outs => [ "res", "flags", "M" ],
347 am => "source,binary",
351 modified_flags => $status_flags
355 irn_flags => [ "rematerializable" ],
356 state => "exc_pinned",
357 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
358 ins => [ "base", "index", "mem", "val" ],
359 emit => 'or%M %#S3, %AM',
362 modified_flags => $status_flags
366 irn_flags => [ "rematerializable" ],
367 state => "exc_pinned",
368 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
369 ins => [ "base", "index", "mem", "val" ],
370 emit => 'or%M %#S3, %AM',
373 modified_flags => $status_flags
377 irn_flags => [ "rematerializable" ],
378 state => "exc_pinned",
379 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
380 out => [ "in_r4 in_r5", "flags", "none" ] },
381 ins => [ "base", "index", "mem", "left", "right" ],
382 outs => [ "res", "flags", "M" ],
383 am => "source,binary",
387 modified_flags => $status_flags
391 op_flags => [ "constlike" ],
392 irn_flags => [ "rematerializable" ],
393 reg_req => { out => [ "gp", "flags" ] },
394 outs => [ "res", "flags" ],
395 emit => "xor%M %D0, %D0",
398 modified_flags => $status_flags
402 irn_flags => [ "rematerializable" ],
403 state => "exc_pinned",
404 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
405 ins => [ "base", "index", "mem", "val" ],
406 emit => 'xor%M %#S3, %AM',
409 modified_flags => $status_flags
413 irn_flags => [ "rematerializable" ],
414 state => "exc_pinned",
415 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
416 ins => [ "base", "index", "mem", "val" ],
417 emit => 'xor%M %#S3, %AM',
420 modified_flags => $status_flags
424 irn_flags => [ "rematerializable" ],
425 state => "exc_pinned",
426 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
427 out => [ "in_r4", "flags", "none" ] },
428 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
429 outs => [ "res", "flags", "M" ],
430 am => "source,binary",
434 modified_flags => $status_flags
438 irn_flags => [ "rematerializable" ],
439 state => "exc_pinned",
440 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
441 ins => [ "base", "index", "mem", "subtrahend" ],
442 emit => 'sub%M %#S3, %AM',
445 modified_flags => $status_flags
449 irn_flags => [ "rematerializable" ],
450 state => "exc_pinned",
451 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
452 ins => [ "base", "index", "mem", "subtrahend" ],
453 emit => 'sub%M %#S3, %AM',
456 modified_flags => $status_flags
460 state => "exc_pinned",
461 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
462 out => [ "in_r4", "flags", "none" ] },
463 ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
464 outs => [ "res", "flags", "M" ],
465 am => "source,binary",
469 modified_flags => $status_flags
473 # Spiller currently fails when rematerializing flag consumers
474 # irn_flags => [ "rematerializable" ],
475 reg_req => { in => [ "flags" ], out => [ "gp", "flags" ] },
476 outs => [ "res", "flags" ],
477 emit => "sbb%M %D0, %D0",
480 modified_flags => $status_flags
484 ins => [ "minuend", "subtrahend" ],
490 ins => [ "minuend", "subtrahend", "eflags" ],
496 op_flags => [ "fragile", "uses_memory" ],
497 state => "exc_pinned",
498 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
499 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
500 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
501 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
502 am => "source,unary",
503 emit => "idiv%M %AS3",
505 modified_flags => $status_flags
509 op_flags => [ "fragile", "uses_memory" ],
510 state => "exc_pinned",
511 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
512 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
513 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
514 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
515 am => "source,unary",
516 emit => "div%M %AS3",
518 modified_flags => $status_flags
522 irn_flags => [ "rematerializable" ],
523 reg_req => { in => [ "gp", "ecx" ],
524 out => [ "in_r1 !in_r2", "flags" ] },
525 ins => [ "val", "count" ],
526 outs => [ "res", "flags" ],
527 emit => 'shl%M %<S1, %S0',
530 modified_flags => $status_flags
534 irn_flags => [ "rematerializable" ],
535 state => "exc_pinned",
536 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
537 ins => [ "base", "index", "mem", "count" ],
538 emit => 'shl%M %<S3, %AM',
541 modified_flags => $status_flags
545 irn_flags => [ "rematerializable" ],
546 reg_req => { in => [ "gp", "gp", "ecx" ],
547 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
548 ins => [ "val_high", "val_low", "count" ],
549 outs => [ "res", "flags" ],
550 emit => "shld%M %<S2, %S1, %D0",
553 modified_flags => $status_flags
557 irn_flags => [ "rematerializable" ],
558 reg_req => { in => [ "gp", "ecx" ],
559 out => [ "in_r1 !in_r2", "flags" ] },
560 ins => [ "val", "count" ],
561 outs => [ "res", "flags" ],
562 emit => 'shr%M %<S1, %S0',
565 modified_flags => $status_flags
569 irn_flags => [ "rematerializable" ],
570 state => "exc_pinned",
571 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
572 ins => [ "base", "index", "mem", "count" ],
573 emit => 'shr%M %<S3, %AM',
576 modified_flags => $status_flags
580 irn_flags => [ "rematerializable" ],
581 reg_req => { in => [ "gp", "gp", "ecx" ],
582 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
583 ins => [ "val_high", "val_low", "count" ],
584 outs => [ "res", "flags" ],
585 emit => "shrd%M %<S2, %S1, %D0",
588 modified_flags => $status_flags
592 irn_flags => [ "rematerializable" ],
593 reg_req => { in => [ "gp", "ecx" ],
594 out => [ "in_r1 !in_r2", "flags" ] },
595 ins => [ "val", "count" ],
596 outs => [ "res", "flags" ],
597 emit => 'sar%M %<S1, %S0',
600 modified_flags => $status_flags
604 irn_flags => [ "rematerializable" ],
605 state => "exc_pinned",
606 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
607 ins => [ "base", "index", "mem", "count" ],
608 emit => 'sar%M %<S3, %AM',
611 modified_flags => $status_flags
615 irn_flags => [ "rematerializable" ],
616 reg_req => { in => [ "gp", "ecx" ],
617 out => [ "in_r1 !in_r2", "flags" ] },
618 ins => [ "val", "count" ],
619 outs => [ "res", "flags" ],
620 emit => 'ror%M %<S1, %S0',
623 modified_flags => $status_flags
627 irn_flags => [ "rematerializable" ],
628 state => "exc_pinned",
629 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
630 ins => [ "base", "index", "mem", "count" ],
631 emit => 'ror%M %<S3, %AM',
634 modified_flags => $status_flags
638 irn_flags => [ "rematerializable" ],
639 reg_req => { in => [ "gp", "ecx" ],
640 out => [ "in_r1 !in_r2", "flags" ] },
641 ins => [ "val", "count" ],
642 outs => [ "res", "flags" ],
643 emit => 'rol%M %<S1, %D0',
646 modified_flags => $status_flags
650 irn_flags => [ "rematerializable" ],
651 state => "exc_pinned",
652 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
653 ins => [ "base", "index", "mem", "count" ],
654 emit => 'rol%M %<S3, %AM',
657 modified_flags => $status_flags
661 irn_flags => [ "rematerializable" ],
662 reg_req => { in => [ "gp" ],
663 out => [ "in_r1", "flags" ] },
666 outs => [ "res", "flags" ],
669 modified_flags => $status_flags
673 irn_flags => [ "rematerializable" ],
674 state => "exc_pinned",
675 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
676 ins => [ "base", "index", "mem" ],
680 modified_flags => $status_flags
684 irn_flags => [ "rematerializable" ],
685 reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
686 outs => [ "low_res", "high_res" ],
688 modified_flags => $status_flags
693 irn_flags => [ "rematerializable" ],
694 reg_req => { in => [ "gp" ],
695 out => [ "in_r1", "flags" ] },
697 outs => [ "res", "flags" ],
701 modified_flags => $status_flags_wo_cf
705 irn_flags => [ "rematerializable" ],
706 state => "exc_pinned",
707 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
708 ins => [ "base", "index", "mem" ],
712 modified_flags => $status_flags_wo_cf
716 irn_flags => [ "rematerializable" ],
717 reg_req => { in => [ "gp" ],
718 out => [ "in_r1", "flags" ] },
720 outs => [ "res", "flags" ],
724 modified_flags => $status_flags_wo_cf
728 irn_flags => [ "rematerializable" ],
729 state => "exc_pinned",
730 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
731 ins => [ "base", "index", "mem" ],
735 modified_flags => $status_flags_wo_cf
739 irn_flags => [ "rematerializable" ],
740 reg_req => { in => [ "gp" ],
741 out => [ "in_r1" ] },
751 irn_flags => [ "rematerializable" ],
752 state => "exc_pinned",
753 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
754 ins => [ "base", "index", "mem" ],
762 reg_req => { in => [ "flags" ], out => [ "flags" ] },
766 modified_flags => $status_flags
770 reg_req => { out => [ "flags" ] },
774 modified_flags => $status_flags
778 irn_flags => [ "rematerializable" ],
779 state => "exc_pinned",
780 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
781 out => [ "flags", "none", "none" ] },
782 ins => [ "base", "index", "mem", "left", "right" ],
783 outs => [ "eflags", "unused", "M" ],
784 am => "source,binary",
786 attr => "bool ins_permuted",
787 init_attr => "attr->data.ins_permuted = ins_permuted;",
790 modified_flags => $status_flags
794 irn_flags => [ "rematerializable" ],
795 state => "exc_pinned",
796 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
797 out => [ "flags", "none", "none" ] },
798 ins => [ "base", "index", "mem", "left", "right" ],
799 outs => [ "eflags", "unused", "M" ],
800 am => "source,binary",
802 attr => "bool ins_permuted",
803 init_attr => "attr->data.ins_permuted = ins_permuted;",
806 modified_flags => $status_flags
810 irn_flags => [ "rematerializable" ],
811 state => "exc_pinned",
812 reg_req => { in => [ "eax ebx ecx edx" ],
813 out => [ "in_r1", "flags" ] },
814 emit => 'xorb %>S0, %<S0',
816 outs => [ "res", "flags" ],
819 modified_flags => $status_flags,
823 irn_flags => [ "rematerializable" ],
824 state => "exc_pinned",
825 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] ,
826 out => [ "flags", "none", "none" ] },
827 ins => [ "base", "index", "mem", "left", "right" ],
828 outs => [ "eflags", "unused", "M" ],
829 am => "source,binary",
831 attr => "bool ins_permuted",
832 init_attr => "attr->data.ins_permuted = ins_permuted;",
835 modified_flags => $status_flags
839 irn_flags => [ "rematerializable" ],
840 state => "exc_pinned",
841 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
842 out => [ "flags", "none", "none" ] },
843 ins => [ "base", "index", "mem", "left", "right" ],
844 outs => [ "eflags", "unused", "M" ],
845 am => "source,binary",
847 attr => "bool ins_permuted",
848 init_attr => "attr->data.ins_permuted = ins_permuted;",
851 modified_flags => $status_flags
855 #irn_flags => [ "rematerializable" ],
856 reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
859 attr_type => "ia32_condcode_attr_t",
860 attr => "ia32_condition_code_t condition_code",
861 # The way we handle Setcc with float nodes (potentially) destroys the flags
862 # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
863 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
864 . "\tif (condition_code & ia32_cc_additional_float_cases) {\n"
865 . "\t\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"
866 . "\t\t/* attr->latency = 3; */\n"
873 #irn_flags => [ "rematerializable" ],
874 state => "exc_pinned",
875 reg_req => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
876 ins => [ "base", "index", "mem","eflags" ],
877 attr_type => "ia32_condcode_attr_t",
878 attr => "ia32_condition_code_t condition_code",
879 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
880 emit => 'set%P3 %AM',
886 #irn_flags => [ "rematerializable" ],
887 state => "exc_pinned",
888 # (note: leave the false,true order intact to make it compatible with other
890 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
891 out => [ "in_r4 in_r5", "flags", "none" ] },
892 ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
893 outs => [ "res", "flags", "M" ],
894 am => "source,binary",
895 attr_type => "ia32_condcode_attr_t",
896 attr => "ia32_condition_code_t condition_code",
903 op_flags => [ "cfopcode", "forking" ],
904 reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
906 outs => [ "false", "true" ],
907 attr_type => "ia32_condcode_attr_t",
908 attr => "ia32_condition_code_t condition_code",
914 op_flags => [ "cfopcode", "forking" ],
915 reg_req => { in => [ "gp", "gp" ] },
916 ins => [ "base", "index" ],
917 out_arity => "variable",
918 attr_type => "ia32_switch_attr_t",
919 attr => "const ir_switch_table *switch_table",
925 irn_flags => [ "simple_jump" ],
926 op_flags => [ "cfopcode" ],
927 reg_req => { out => [ "none" ] },
934 op_flags => [ "cfopcode", "unknown_jump" ],
935 reg_req => { in => [ "gp", "gp", "none", "gp" ],
936 out => [ "none", "flags", "none" ] },
937 ins => [ "base", "index", "mem", "target" ],
938 outs => [ "jmp", "flags", "M" ],
939 am => "source,unary",
946 op_flags => [ "constlike" ],
947 irn_flags => [ "rematerializable" ],
948 reg_req => { out => [ "gp" ] },
949 emit => "movl %I, %D0",
950 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
951 attr_type => "ia32_immediate_attr_t",
957 op_flags => [ "constlike" ],
958 irn_flags => [ "rematerializable" ],
959 reg_req => { out => [ "gp" ] },
966 op_flags => [ "constlike" ],
967 reg_req => { out => [ "gp" ] },
970 modified_flags => $status_flags,
975 op_flags => [ "constlike", "dump_noblock" ],
976 irn_flags => [ "not_scheduled" ],
977 reg_req => { out => [ "gp_NOREG:I" ] },
984 op_flags => [ "constlike", "dump_noblock" ],
985 irn_flags => [ "not_scheduled" ],
986 reg_req => { out => [ "fp_NOREG:I" ] },
989 attr_type => "ia32_x87_attr_t",
994 op_flags => [ "constlike", "dump_noblock" ],
995 irn_flags => [ "not_scheduled" ],
996 reg_req => { out => [ "xmm_NOREG:I" ] },
1003 op_flags => [ "constlike" ],
1004 irn_flags => [ "not_scheduled" ],
1005 reg_req => { out => [ "fpcw" ] },
1008 modified_flags => $fpcw_flags
1012 op_flags => [ "uses_memory" ],
1014 reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw" ] },
1015 ins => [ "base", "index", "mem" ],
1017 emit => "fldcw %AM",
1019 modified_flags => $fpcw_flags
1023 op_flags => [ "uses_memory" ],
1025 reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1026 ins => [ "base", "index", "mem", "fpcw" ],
1028 emit => "fnstcw %AM",
1033 op_flags => [ "uses_memory" ],
1035 reg_req => { in => [ "fp_cw" ], out => [ "none" ] },
1043 # we should not rematrialize this node. It has very strict constraints.
1044 reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] },
1045 ins => [ "val", "clobbered" ],
1053 # Note that we add additional latency values depending on address mode, so a
1054 # lateny of 0 for load is correct
1057 op_flags => [ "uses_memory", "fragile" ],
1058 state => "exc_pinned",
1059 reg_req => { in => [ "gp", "gp", "none" ],
1060 out => [ "gp", "none", "none", "none", "none" ] },
1061 ins => [ "base", "index", "mem" ],
1062 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1064 emit => "mov%#Ml %AM, %D0",
1068 op_flags => [ "uses_memory", "fragile" ],
1069 state => "exc_pinned",
1070 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1071 out => [ "none", "none", "none" ] },
1072 ins => [ "base", "index", "mem", "val" ],
1073 outs => [ "M", "X_regular", "X_except" ],
1074 emit => 'mov%M %#S3, %AM',
1079 op_flags => [ "uses_memory", "fragile" ],
1080 state => "exc_pinned",
1081 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1082 out => ["none", "none", "none" ] },
1083 ins => [ "base", "index", "mem", "val" ],
1084 outs => [ "M", "X_regular", "X_except" ],
1085 emit => 'mov%M %#S3, %AM',
1090 irn_flags => [ "rematerializable" ],
1091 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1092 ins => [ "base", "index" ],
1093 emit => 'leal %AM, %D0',
1096 # lea doesn't modify the flags, but setting this seems advantageous since it
1097 # increases chances that the Lea is transformed back to an Add
1098 modified_flags => 1,
1102 state => "exc_pinned",
1103 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1104 ins => [ "base", "index", "mem", "val", "stack" ],
1105 emit => 'push%M %AS3',
1106 outs => [ "stack", "M" ],
1107 am => "source,unary",
1112 state => "exc_pinned",
1113 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1115 outs => [ "stack" ],
1116 emit => 'pushl %%eax',
1122 state => "exc_pinned",
1123 reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1124 ins => [ "mem", "stack" ],
1125 outs => [ "res", "M", "unused", "stack" ],
1126 emit => 'pop%M %D0',
1127 latency => 3, # Pop is more expensive than Push on Athlon
1131 state => "exc_pinned",
1132 reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1133 ins => [ "mem", "stack" ],
1134 outs => [ "res", "M", "unused", "stack" ],
1135 emit => 'pop%M %D0',
1136 latency => 3, # Pop is more expensive than Push on Athlon
1140 state => "exc_pinned",
1141 reg_req => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1144 emit => 'movl %S0, %D0',
1150 state => "exc_pinned",
1151 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1152 ins => [ "base", "index", "mem", "stack" ],
1153 outs => [ "unused0", "M", "unused1", "stack" ],
1154 emit => 'pop%M %AM',
1155 latency => 3, # Pop is more expensive than Push on Athlon
1159 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1161 outs => [ "frame", "stack", "M" ],
1166 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1168 outs => [ "frame", "stack" ],
1170 state => "exc_pinned",
1175 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1176 ins => [ "base", "index", "mem", "stack", "size" ],
1177 am => "source,binary",
1180 outs => [ "stack", "M" ],
1181 modified_flags => $status_flags
1186 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1187 ins => [ "base", "index", "mem", "stack", "size" ],
1188 am => "source,binary",
1189 emit => "subl %B\n".
1192 outs => [ "stack", "addr", "M" ],
1193 modified_flags => $status_flags
1197 op_flags => [ "keep" ],
1205 irn_flags => [ "rematerializable" ],
1206 reg_req => { out => [ "gp" ] },
1207 emit => "movl %%gs:0, %D0",
1213 # BT supports source address mode, but this is unused yet
1216 irn_flags => [ "rematerializable" ],
1217 state => "exc_pinned",
1218 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1219 ins => [ "left", "right" ],
1220 emit => 'bt%M %S1, %S0',
1222 mode => $mode_flags,
1223 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1227 irn_flags => [ "rematerializable" ],
1228 state => "exc_pinned",
1229 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1230 out => [ "gp", "flags", "none" ] },
1231 ins => [ "base", "index", "mem", "operand" ],
1232 outs => [ "res", "flags", "M" ],
1233 am => "source,binary",
1234 emit => 'bsf%M %AS3, %D0',
1237 modified_flags => $status_flags
1241 irn_flags => [ "rematerializable" ],
1242 state => "exc_pinned",
1243 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1244 out => [ "gp", "flags", "none" ] },
1245 ins => [ "base", "index", "mem", "operand" ],
1246 outs => [ "res", "flags", "M" ],
1247 am => "source,binary",
1248 emit => 'bsr%M %AS3, %D0',
1251 modified_flags => $status_flags
1255 # SSE4.2 or SSE4a popcnt instruction
1258 irn_flags => [ "rematerializable" ],
1259 state => "exc_pinned",
1260 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1261 out => [ "gp", "flags", "none" ] },
1262 ins => [ "base", "index", "mem", "operand" ],
1263 outs => [ "res", "flags", "M" ],
1264 am => "source,binary",
1265 emit => 'popcnt%M %AS3, %D0',
1268 modified_flags => $status_flags
1272 op_flags => [ "uses_memory", "fragile" ],
1273 state => "exc_pinned",
1275 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1276 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" ]
1278 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1279 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" ],
1280 emit => "call %*AS3",
1281 attr_type => "ia32_call_attr_t",
1282 attr => "unsigned pop, ir_type *call_tp",
1283 am => "source,unary",
1284 latency => 4, # random number
1285 modified_flags => $status_flags
1289 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1291 # PS: try gcc __builtin_frame_address(100000) :-)
1294 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1295 ins => [ "frame", "cnt", "tmp" ],
1297 latency => 4, # random number
1298 attr_type => "ia32_climbframe_attr_t",
1299 attr => "unsigned count",
1307 irn_flags => [ "rematerializable" ],
1308 reg_req => { in => [ "gp" ],
1309 out => [ "in_r1" ] },
1311 emit => 'bswap%M %S0',
1318 # bswap16, use xchg here
1321 irn_flags => [ "rematerializable" ],
1322 reg_req => { in => [ "eax ebx ecx edx" ],
1323 out => [ "in_r1" ] },
1324 emit => 'xchg %<S0, %>S0',
1335 reg_req => { in => [ "none" ], out => [ "none" ] },
1343 # Undefined Instruction on ALL x86 CPU's
1347 reg_req => { in => [ "none" ], out => [ "none" ] },
1358 irn_flags => [ "rematerializable" ],
1360 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1361 ins => [ "port", "value", "mem" ],
1362 emit => 'out%M %^S0, %#S1',
1365 modified_flags => $status_flags
1372 irn_flags => [ "rematerializable" ],
1374 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1375 ins => [ "port", "mem" ],
1376 outs => [ "res", "M" ],
1377 emit => 'in%M %#D0, %^S0',
1380 modified_flags => $status_flags
1384 # Intel style prefetching
1387 op_flags => [ "uses_memory" ],
1388 state => "exc_pinned",
1389 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1390 ins => [ "base", "index", "mem" ],
1393 emit => "prefetcht0 %AM",
1397 op_flags => [ "uses_memory" ],
1398 state => "exc_pinned",
1399 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1400 ins => [ "base", "index", "mem" ],
1403 emit => "prefetcht1 %AM",
1407 op_flags => [ "uses_memory" ],
1408 state => "exc_pinned",
1409 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1410 ins => [ "base", "index", "mem" ],
1413 emit => "prefetcht2 %AM",
1417 op_flags => [ "uses_memory" ],
1418 state => "exc_pinned",
1419 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1420 ins => [ "base", "index", "mem" ],
1423 emit => "prefetchnta %AM",
1427 # 3DNow! prefetch instructions
1430 op_flags => [ "uses_memory" ],
1431 state => "exc_pinned",
1432 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1433 ins => [ "base", "index", "mem" ],
1436 emit => "prefetch %AM",
1440 op_flags => [ "uses_memory" ],
1441 state => "exc_pinned",
1442 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1443 ins => [ "base", "index", "mem" ],
1446 emit => "prefetchw %AM",
1451 irn_flags => [ "rematerializable" ],
1452 reg_req => { out => [ "xmm" ] },
1453 emit => 'xorp%FX %D0, %D0',
1459 op_flags => [ "constlike" ],
1460 irn_flags => [ "rematerializable" ],
1461 reg_req => { out => [ "xmm" ] },
1468 irn_flags => [ "rematerializable" ],
1469 reg_req => { out => [ "xmm" ] },
1470 emit => 'pxor %D0, %D0',
1475 # produces all 1 bits
1477 irn_flags => [ "rematerializable" ],
1478 reg_req => { out => [ "xmm" ] },
1479 emit => 'pcmpeqb %D0, %D0',
1484 # integer shift left, dword
1486 irn_flags => [ "rematerializable" ],
1487 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1488 emit => 'pslld %#S1, %D0',
1493 # integer shift left, qword
1495 irn_flags => [ "rematerializable" ],
1496 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1497 emit => 'psllq %#S1, %D0',
1502 # integer shift right, dword
1504 irn_flags => [ "rematerializable" ],
1505 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1506 emit => 'psrld %#S1, %D0',
1511 # mov from integer to SSE register
1513 irn_flags => [ "rematerializable" ],
1514 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1515 emit => 'movd %S0, %D0',
1521 irn_flags => [ "rematerializable" ],
1522 state => "exc_pinned",
1523 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1524 out => [ "in_r4 in_r5", "flags", "none" ] },
1525 ins => [ "base", "index", "mem", "left", "right" ],
1526 outs => [ "res", "flags", "M" ],
1527 am => "source,binary",
1528 emit => 'adds%FX %B',
1534 irn_flags => [ "rematerializable" ],
1535 state => "exc_pinned",
1536 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1537 out => [ "in_r4 in_r5", "flags", "none" ] },
1538 ins => [ "base", "index", "mem", "left", "right" ],
1539 outs => [ "res", "flags", "M" ],
1540 am => "source,binary",
1541 emit => 'muls%FX %B',
1547 irn_flags => [ "rematerializable" ],
1548 state => "exc_pinned",
1549 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1550 out => [ "in_r4 in_r5", "flags", "none" ] },
1551 ins => [ "base", "index", "mem", "left", "right" ],
1552 outs => [ "res", "flags", "M" ],
1553 am => "source,binary",
1554 emit => 'maxs%FX %B',
1560 irn_flags => [ "rematerializable" ],
1561 state => "exc_pinned",
1562 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1563 out => [ "in_r4 in_r5", "flags", "none" ] },
1564 ins => [ "base", "index", "mem", "left", "right" ],
1565 outs => [ "res", "flags", "M" ],
1566 am => "source,binary",
1567 emit => 'mins%FX %B',
1573 irn_flags => [ "rematerializable" ],
1574 state => "exc_pinned",
1575 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1576 out => [ "in_r4 in_r5", "flags", "none" ] },
1577 ins => [ "base", "index", "mem", "left", "right" ],
1578 outs => [ "res", "flags", "M" ],
1579 am => "source,binary",
1580 emit => 'andp%FX %B',
1586 irn_flags => [ "rematerializable" ],
1587 state => "exc_pinned",
1588 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1589 out => [ "in_r4 in_r5", "flags", "none" ] },
1590 ins => [ "base", "index", "mem", "left", "right" ],
1591 outs => [ "res", "flags", "M" ],
1592 am => "source,binary",
1593 emit => 'orp%FX %B',
1599 irn_flags => [ "rematerializable" ],
1600 state => "exc_pinned",
1601 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1602 out => [ "in_r4 in_r5", "flags", "none" ] },
1603 ins => [ "base", "index", "mem", "left", "right" ],
1604 outs => [ "res", "flags", "M" ],
1605 am => "source,binary",
1606 emit => 'xorp%FX %B',
1612 irn_flags => [ "rematerializable" ],
1613 state => "exc_pinned",
1614 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1615 out => [ "in_r4 !in_r5", "flags", "none" ] },
1616 ins => [ "base", "index", "mem", "left", "right" ],
1617 outs => [ "res", "flags", "M" ],
1618 am => "source,binary",
1619 emit => 'andnp%FX %B',
1625 irn_flags => [ "rematerializable" ],
1626 state => "exc_pinned",
1627 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1628 out => [ "in_r4", "flags", "none" ] },
1629 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1630 outs => [ "res", "flags", "M" ],
1631 am => "source,binary",
1632 emit => 'subs%FX %B',
1638 irn_flags => [ "rematerializable" ],
1639 state => "exc_pinned",
1640 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1641 out => [ "in_r4 !in_r5", "flags", "none" ] },
1642 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1643 outs => [ "res", "flags", "M" ],
1644 am => "source,binary",
1645 emit => 'divs%FX %B',
1650 irn_flags => [ "rematerializable" ],
1651 state => "exc_pinned",
1652 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1653 out => [ "eflags" ] },
1654 ins => [ "base", "index", "mem", "left", "right" ],
1655 outs => [ "flags" ],
1656 am => "source,binary",
1657 attr => "bool ins_permuted",
1658 init_attr => "attr->data.ins_permuted = ins_permuted;",
1659 emit => 'ucomis%FX %B',
1661 mode => $mode_flags,
1662 modified_flags => 1,
1666 op_flags => [ "uses_memory", "fragile" ],
1667 state => "exc_pinned",
1668 reg_req => { in => [ "gp", "gp", "none" ],
1669 out => [ "xmm", "none", "none", "none", "none" ] },
1670 ins => [ "base", "index", "mem" ],
1671 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1672 emit => 'movs%FX %AM, %D0',
1673 attr => "ir_mode *load_mode",
1674 init_attr => "attr->ls_mode = load_mode;",
1679 op_flags => [ "uses_memory", "fragile" ],
1680 state => "exc_pinned",
1681 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1682 out => [ "none", "none", "none" ] },
1683 ins => [ "base", "index", "mem", "val" ],
1684 outs => [ "M", "X_regular", "X_except" ],
1685 emit => 'movs%FX %S3, %AM',
1690 op_flags => [ "uses_memory", "fragile" ],
1691 state => "exc_pinned",
1692 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1693 out => [ "none", "none", "none" ] },
1694 ins => [ "base", "index", "mem", "val" ],
1695 outs => [ "M", "X_regular", "X_except" ],
1696 emit => 'movs%FX %S3, %AM',
1701 state => "exc_pinned",
1702 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1703 ins => [ "base", "index", "mem", "val" ],
1704 am => "source,unary",
1705 emit => 'cvtsi2ss %AS3, %D0',
1711 state => "exc_pinned",
1712 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1713 ins => [ "base", "index", "mem", "val" ],
1714 am => "source,unary",
1715 emit => 'cvtsi2sd %AS3, %D0',
1722 ins => [ "val_high", "val_low" ],
1724 dump_func => "NULL",
1729 outs => [ "res_high", "res_low" ],
1731 dump_func => "NULL",
1735 op_flags => [ "uses_memory", "fragile" ],
1737 reg_req => { in => [ "edi", "esi", "ecx", "none" ],
1738 out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1739 ins => [ "dest", "source", "count", "mem" ],
1740 outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1741 attr_type => "ia32_copyb_attr_t",
1742 attr => "unsigned size",
1744 # we don't care about this flag, so no need to mark this node
1745 # modified_flags => [ "DF" ]
1749 op_flags => [ "uses_memory", "fragile" ],
1751 reg_req => { in => [ "edi", "esi", "none" ],
1752 out => [ "edi", "esi", "none", "none", "none" ] },
1753 ins => [ "dest", "source", "mem" ],
1754 outs => [ "dest", "source", "M", "X_regular", "X_except" ],
1755 attr_type => "ia32_copyb_attr_t",
1756 attr => "unsigned size",
1758 # we don't care about this flag, so no need to mark this node
1759 # modified_flags => [ "DF" ]
1763 state => "exc_pinned",
1764 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1773 op_flags => [ "uses_memory", "fragile" ],
1774 state => "exc_pinned",
1775 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1776 out => [ "gp", "none", "none", "none", "none" ] },
1777 ins => [ "base", "index", "mem", "val" ],
1778 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1779 emit => "mov%#Ml %#AS3, %D0",
1780 am => "source,unary",
1782 attr => "ir_mode *smaller_mode",
1783 init_attr => "attr->ls_mode = smaller_mode;",
1788 op_flags => [ "uses_memory", "fragile" ],
1789 state => "exc_pinned",
1790 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1791 out => [ "gp", "none", "none", "none", "none" ] },
1792 ins => [ "base", "index", "mem", "val" ],
1793 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1794 emit => "mov%#Ml %#AS3, %D0",
1795 am => "source,unary",
1797 attr => "ir_mode *smaller_mode",
1798 init_attr => "attr->ls_mode = smaller_mode;",
1803 state => "exc_pinned",
1804 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1805 ins => [ "base", "index", "mem", "val" ],
1806 am => "source,unary",
1812 state => "exc_pinned",
1813 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1814 ins => [ "base", "index", "mem", "val" ],
1815 am => "source,unary",
1821 state => "exc_pinned",
1822 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1823 ins => [ "base", "index", "mem", "val" ],
1824 am => "source,unary",
1829 # rematerialisation disabled for all float nodes for now, because the fpcw
1830 # handler runs before spilling and we might end up with wrong fpcw then
1833 # irn_flags => [ "rematerializable" ],
1834 state => "exc_pinned",
1835 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1836 out => [ "fp", "none", "none" ] },
1837 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1838 outs => [ "res", "dummy", "M" ],
1839 emit => 'fadd%FP%FM %AF',
1840 am => "source,binary",
1843 attr_type => "ia32_x87_attr_t",
1847 # irn_flags => [ "rematerializable" ],
1848 state => "exc_pinned",
1849 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1850 out => [ "fp", "none", "none" ] },
1851 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1852 outs => [ "res", "dummy", "M" ],
1853 emit => 'fmul%FP%FM %AF',
1854 am => "source,binary",
1857 attr_type => "ia32_x87_attr_t",
1861 # irn_flags => [ "rematerializable" ],
1862 state => "exc_pinned",
1863 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1864 out => [ "fp", "none", "none" ] },
1865 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
1866 outs => [ "res", "dummy", "M" ],
1867 emit => 'fsub%FR%FP%FM %AF',
1868 am => "source,binary",
1871 attr_type => "ia32_x87_attr_t",
1875 state => "exc_pinned",
1876 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1877 out => [ "fp", "none", "none" ] },
1878 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
1879 outs => [ "res", "dummy", "M" ],
1880 emit => 'fdiv%FR%FP%FM %AF',
1881 am => "source,binary",
1883 attr_type => "ia32_x87_attr_t",
1887 reg_req => { in => [ "fp", "fp", "fpcw" ], out => [ "fp" ] },
1888 ins => [ "left", "right", "fpcw" ],
1892 attr_type => "ia32_x87_attr_t",
1896 irn_flags => [ "rematerializable" ],
1897 reg_req => { in => [ "fp"], out => [ "fp" ] },
1902 attr_type => "ia32_x87_attr_t",
1906 irn_flags => [ "rematerializable" ],
1907 reg_req => { in => [ "fp"], out => [ "fp" ] },
1912 attr_type => "ia32_x87_attr_t",
1916 irn_flags => [ "rematerializable" ],
1917 op_flags => [ "uses_memory", "fragile" ],
1918 state => "exc_pinned",
1919 reg_req => { in => [ "gp", "gp", "none" ],
1920 out => [ "fp", "none", "none", "none", "none" ] },
1921 ins => [ "base", "index", "mem" ],
1922 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1923 emit => 'fld%FM %AM',
1924 attr => "ir_mode *load_mode",
1925 init_attr => "attr->attr.ls_mode = load_mode;",
1927 attr_type => "ia32_x87_attr_t",
1931 irn_flags => [ "rematerializable" ],
1932 op_flags => [ "uses_memory", "fragile" ],
1933 state => "exc_pinned",
1934 reg_req => { in => [ "gp", "gp", "none", "fp" ],
1935 out => [ "none", "none", "none" ] },
1936 ins => [ "base", "index", "mem", "val" ],
1937 outs => [ "M", "X_regular", "X_except" ],
1938 emit => 'fst%FP%FM %AM',
1939 attr => "ir_mode *store_mode",
1940 init_attr => "attr->attr.ls_mode = store_mode;",
1942 attr_type => "ia32_x87_attr_t",
1946 state => "exc_pinned",
1947 reg_req => { in => [ "gp", "gp", "none" ],
1948 out => [ "fp", "none", "none" ] },
1949 outs => [ "res", "unused", "M" ],
1950 ins => [ "base", "index", "mem" ],
1951 emit => 'fild%FM %AM',
1953 attr_type => "ia32_x87_attr_t",
1957 op_flags => [ "uses_memory", "fragile" ],
1958 state => "exc_pinned",
1959 reg_req => { in => [ "gp", "gp", "none", "fp", "fpcw" ],
1960 out => [ "none", "none", "none", "none" ] },
1961 ins => [ "base", "index", "mem", "val", "fpcw" ],
1962 outs => [ "dummy", "M", "X_regular", "X_except" ],
1963 emit => 'fist%FP%FM %AM',
1965 attr_type => "ia32_x87_attr_t",
1968 # SSE3 fisttp instruction
1970 op_flags => [ "uses_memory", "fragile" ],
1971 state => "exc_pinned",
1972 reg_req => { in => [ "gp", "gp", "none", "fp" ],
1973 out => [ "in_r4", "none", "none", "none" ]},
1974 ins => [ "base", "index", "mem", "val" ],
1975 outs => [ "res", "M", "X_regular", "X_except" ],
1976 emit => 'fisttp%FM %AM',
1978 attr_type => "ia32_x87_attr_t",
1982 irn_flags => [ "rematerializable" ],
1983 reg_req => { out => [ "fp" ] },
1988 attr_type => "ia32_x87_attr_t",
1992 irn_flags => [ "rematerializable" ],
1993 reg_req => { out => [ "fp" ] },
1998 attr_type => "ia32_x87_attr_t",
2002 irn_flags => [ "rematerializable" ],
2003 reg_req => { out => [ "fp" ] },
2008 attr_type => "ia32_x87_attr_t",
2012 irn_flags => [ "rematerializable" ],
2013 reg_req => { out => [ "fp" ] },
2018 attr_type => "ia32_x87_attr_t",
2022 irn_flags => [ "rematerializable" ],
2023 reg_req => { out => [ "fp" ] },
2028 attr_type => "ia32_x87_attr_t",
2032 irn_flags => [ "rematerializable" ],
2033 reg_req => { out => [ "fp" ] },
2038 attr_type => "ia32_x87_attr_t",
2042 irn_flags => [ "rematerializable" ],
2043 reg_req => { out => [ "fp" ] },
2048 attr_type => "ia32_x87_attr_t",
2052 # we can't allow to rematerialize this node so we don't
2053 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2054 # irn_flags => [ "rematerializable" ],
2055 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2056 ins => [ "left", "right" ],
2057 outs => [ "flags" ],
2058 emit => "fucom%FP %F0\n".
2060 attr => "bool ins_permuted",
2061 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2063 attr_type => "ia32_x87_attr_t",
2068 # we can't allow to rematerialize this node so we don't
2069 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2070 # irn_flags => [ "rematerializable" ],
2071 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2072 ins => [ "left", "right" ],
2073 outs => [ "flags" ],
2074 emit => "fucompp\n".
2076 attr => "bool ins_permuted",
2077 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2079 attr_type => "ia32_x87_attr_t",
2084 irn_flags => [ "rematerializable" ],
2085 reg_req => { in => [ "fp", "fp" ], out => [ "eflags" ] },
2086 ins => [ "left", "right" ],
2087 outs => [ "flags" ],
2088 emit => 'fucom%FPi %F0',
2089 attr => "bool ins_permuted",
2090 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2092 attr_type => "ia32_x87_attr_t",
2097 # irn_flags => [ "rematerializable" ],
2098 reg_req => { in => [ "fp" ], out => [ "eax" ] },
2100 outs => [ "flags" ],
2103 attr => "bool ins_permuted",
2104 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2106 attr_type => "ia32_x87_attr_t",
2111 irn_flags => [ "rematerializable" ],
2112 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2114 outs => [ "flags" ],
2117 mode => $mode_flags,
2121 # Note that it is NEVER allowed to do CSE on these nodes
2122 # Moreover, note the virtual register requierements!
2125 op_flags => [ "keep" ],
2126 reg_req => { out => [ "none" ] },
2127 cmp_attr => "return 1;",
2129 attr_type => "ia32_x87_attr_t",
2135 op_flags => [ "keep" ],
2136 reg_req => { out => [ "none" ] },
2137 cmp_attr => "return 1;",
2139 attr_type => "ia32_x87_attr_t",
2145 reg_req => { in => [ "fp"], out => [ "fp" ] },
2146 cmp_attr => "return 1;",
2148 attr_type => "ia32_x87_attr_t",
2153 op_flags => [ "keep" ],
2154 reg_req => { out => [ "none" ] },
2155 cmp_attr => "return 1;",
2157 attr_type => "ia32_x87_attr_t",
2163 op_flags => [ "keep" ],
2164 reg_req => { out => [ "none" ] },
2165 cmp_attr => "return 1;",
2166 emit => 'ffreep %F0',
2167 attr_type => "ia32_x87_attr_t",
2173 op_flags => [ "keep" ],
2174 reg_req => { out => [ "none" ] },
2175 cmp_attr => "return 1;",
2177 attr_type => "ia32_x87_attr_t",
2183 op_flags => [ "keep" ],
2184 reg_req => { out => [ "none" ] },
2185 cmp_attr => "return 1;",
2187 attr_type => "ia32_x87_attr_t",
2192 # Spilling and reloading of SSE registers, hardcoded, not generated #
2195 op_flags => [ "uses_memory", "fragile" ],
2196 state => "exc_pinned",
2197 reg_req => { in => [ "gp", "gp", "none" ],
2198 out => [ "xmm", "none", "none", "none" ] },
2199 emit => 'movdqu %D0, %AM',
2200 ins => [ "base", "index", "mem" ],
2201 outs => [ "res", "M", "X_regular", "X_except" ],
2206 op_flags => [ "uses_memory", "fragile" ],
2207 state => "exc_pinned",
2208 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
2209 out => [ "none", "none", "none" ] },
2210 ins => [ "base", "index", "mem", "val" ],
2211 outs => [ "M", "X_regular", "X_except" ],
2212 emit => 'movdqu %B',
2218 # Transform some attributes
2219 foreach my $op (keys(%nodes)) {
2220 my $node = $nodes{$op};
2221 my $op_attr_init = $node->{op_attr_init};
2223 if(defined($op_attr_init)) {
2224 $op_attr_init .= "\n\t";
2229 if(!defined($node->{latency})) {
2231 $node->{latency} = 0;
2233 die("Latency missing for op $op");
2236 $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2238 $node->{op_attr_init} = $op_attr_init;