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" ] },
165 op_flags => [ "constlike" ],
166 irn_flags => [ "not_scheduled" ],
167 reg_req => { out => [ "gp_NOREG:I" ] },
168 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
169 attr_type => "ia32_immediate_attr_t",
170 hash_func => "ia32_hash_Immediate",
178 out_arity => "variable",
179 attr_type => "ia32_asm_attr_t",
180 attr => "ident *asm_text, const ia32_asm_reg_t *register_map",
181 init_attr => "attr->asm_text = asm_text;\n".
182 "\tattr->register_map = register_map;\n",
184 modified_flags => $status_flags,
187 # "allocates" a free register
189 op_flags => [ "constlike", "cse_neutral" ],
190 irn_flags => [ "rematerializable" ],
191 reg_req => { out => [ "gp" ] },
195 cmp_attr => "return 1;",
199 irn_flags => [ "rematerializable" ],
200 state => "exc_pinned",
201 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
202 out => [ "in_r4 in_r5", "flags", "none" ] },
203 ins => [ "base", "index", "mem", "left", "right" ],
204 outs => [ "res", "flags", "M" ],
206 am => "source,binary",
209 modified_flags => $status_flags
213 irn_flags => [ "rematerializable" ],
214 state => "exc_pinned",
215 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
216 ins => [ "base", "index", "mem", "val" ],
217 emit => "add%M %#S3, %AM",
220 modified_flags => $status_flags
224 irn_flags => [ "rematerializable" ],
225 state => "exc_pinned",
226 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
227 ins => [ "base", "index", "mem", "val" ],
228 emit => "add%M %#S3, %AM",
231 modified_flags => $status_flags
235 state => "exc_pinned",
236 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
237 out => [ "in_r4 in_r5", "flags", "none" ] },
238 ins => [ "base", "index", "mem", "left", "right", "eflags" ],
239 outs => [ "res", "flags", "M" ],
241 am => "source,binary",
244 modified_flags => $status_flags
248 ins => [ "left", "right" ],
254 ins => [ "left", "right", "eflags" ],
260 # we should not rematrialize this node. It produces 2 results and has
261 # very strict constraints
262 state => "exc_pinned",
263 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
264 out => [ "eax", "flags", "none", "edx" ] },
265 ins => [ "base", "index", "mem", "left", "right" ],
266 emit => 'mul%M %AS4',
267 outs => [ "res_low", "flags", "M", "res_high" ],
268 am => "source,binary",
270 modified_flags => $status_flags
274 ins => [ "left", "right" ],
275 outs => [ "res_low", "flags", "M", "res_high" ],
281 irn_flags => [ "rematerializable" ],
282 state => "exc_pinned",
283 # TODO: adjust out requirements for the 3 operand form
284 # (no need for should_be_same then)
285 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
286 out => [ "in_r4 in_r5", "flags", "none" ] },
287 ins => [ "base", "index", "mem", "left", "right" ],
288 outs => [ "res", "flags", "M" ],
289 am => "source,binary",
292 modified_flags => $status_flags
296 irn_flags => [ "rematerializable" ],
297 state => "exc_pinned",
298 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
299 out => [ "eax", "flags", "none", "edx" ] },
300 ins => [ "base", "index", "mem", "left", "right" ],
301 emit => 'imul%M %AS4',
302 outs => [ "res_low", "flags", "M", "res_high" ],
303 am => "source,binary",
305 modified_flags => $status_flags
309 ins => [ "left", "right" ],
310 outs => [ "res_low", "flags", "M", "res_high" ],
316 irn_flags => [ "rematerializable" ],
317 state => "exc_pinned",
318 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
319 out => [ "in_r4 in_r5", "flags", "none" ] },
320 ins => [ "base", "index", "mem", "left", "right" ],
321 outs => [ "res", "flags", "M" ],
322 am => "source,binary",
326 modified_flags => $status_flags
330 irn_flags => [ "rematerializable" ],
331 state => "exc_pinned",
332 reg_req => { in => [ "gp", "gp", "none", "gp" ], 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", "eax ebx ecx edx" ], out => [ "none" ] },
344 ins => [ "base", "index", "mem", "val" ],
345 emit => 'and%M %#S3, %AM',
348 modified_flags => $status_flags
352 irn_flags => [ "rematerializable" ],
353 state => "exc_pinned",
354 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
355 out => [ "in_r4 in_r5", "flags", "none" ] },
356 ins => [ "base", "index", "mem", "left", "right" ],
357 outs => [ "res", "flags", "M" ],
358 am => "source,binary",
362 modified_flags => $status_flags
366 irn_flags => [ "rematerializable" ],
367 state => "exc_pinned",
368 reg_req => { in => [ "gp", "gp", "none", "gp" ], 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", "eax ebx ecx edx" ], out => [ "none" ] },
380 ins => [ "base", "index", "mem", "val" ],
381 emit => 'or%M %#S3, %AM',
384 modified_flags => $status_flags
388 irn_flags => [ "rematerializable" ],
389 state => "exc_pinned",
390 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
391 out => [ "in_r4 in_r5", "flags", "none" ] },
392 ins => [ "base", "index", "mem", "left", "right" ],
393 outs => [ "res", "flags", "M" ],
394 am => "source,binary",
398 modified_flags => $status_flags
402 op_flags => [ "constlike" ],
403 irn_flags => [ "rematerializable" ],
404 reg_req => { out => [ "gp", "flags" ] },
405 outs => [ "res", "flags" ],
406 emit => "xor%M %D0, %D0",
409 modified_flags => $status_flags
413 irn_flags => [ "rematerializable" ],
414 state => "exc_pinned",
415 reg_req => { in => [ "gp", "gp", "none", "gp" ], 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", "eax ebx ecx edx" ], out => [ "none" ] },
427 ins => [ "base", "index", "mem", "val" ],
428 emit => 'xor%M %#S3, %AM',
431 modified_flags => $status_flags
435 irn_flags => [ "rematerializable" ],
436 state => "exc_pinned",
437 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
438 out => [ "in_r4", "flags", "none" ] },
439 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
440 outs => [ "res", "flags", "M" ],
441 am => "source,binary",
445 modified_flags => $status_flags
449 irn_flags => [ "rematerializable" ],
450 state => "exc_pinned",
451 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
452 ins => [ "base", "index", "mem", "subtrahend" ],
453 emit => 'sub%M %#S3, %AM',
456 modified_flags => $status_flags
460 irn_flags => [ "rematerializable" ],
461 state => "exc_pinned",
462 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
463 ins => [ "base", "index", "mem", "subtrahend" ],
464 emit => 'sub%M %#S3, %AM',
467 modified_flags => $status_flags
471 state => "exc_pinned",
472 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
473 out => [ "in_r4", "flags", "none" ] },
474 ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
475 outs => [ "res", "flags", "M" ],
476 am => "source,binary",
480 modified_flags => $status_flags
484 # Spiller currently fails when rematerializing flag consumers
485 # irn_flags => [ "rematerializable" ],
486 reg_req => { in => [ "flags" ], out => [ "gp", "flags" ] },
487 outs => [ "res", "flags" ],
488 emit => "sbb%M %D0, %D0",
491 modified_flags => $status_flags
495 ins => [ "minuend", "subtrahend" ],
501 ins => [ "minuend", "subtrahend", "eflags" ],
507 op_flags => [ "fragile", "uses_memory" ],
508 state => "exc_pinned",
509 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
510 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
511 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
512 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
513 am => "source,unary",
514 emit => "idiv%M %AS3",
516 modified_flags => $status_flags
520 op_flags => [ "fragile", "uses_memory" ],
521 state => "exc_pinned",
522 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
523 out => [ "eax", "flags", "none", "edx", "none", "none" ] },
524 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
525 outs => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
526 am => "source,unary",
527 emit => "div%M %AS3",
529 modified_flags => $status_flags
533 irn_flags => [ "rematerializable" ],
534 reg_req => { in => [ "gp", "ecx" ],
535 out => [ "in_r1 !in_r2", "flags" ] },
536 ins => [ "val", "count" ],
537 outs => [ "res", "flags" ],
538 emit => 'shl%M %<S1, %S0',
541 modified_flags => $status_flags
545 irn_flags => [ "rematerializable" ],
546 state => "exc_pinned",
547 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
548 ins => [ "base", "index", "mem", "count" ],
549 emit => 'shl%M %<S3, %AM',
552 modified_flags => $status_flags
556 irn_flags => [ "rematerializable" ],
557 reg_req => { in => [ "gp", "gp", "ecx" ],
558 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
559 ins => [ "val_high", "val_low", "count" ],
560 outs => [ "res", "flags" ],
561 emit => "shld%M %<S2, %S1, %D0",
564 modified_flags => $status_flags
568 irn_flags => [ "rematerializable" ],
569 reg_req => { in => [ "gp", "ecx" ],
570 out => [ "in_r1 !in_r2", "flags" ] },
571 ins => [ "val", "count" ],
572 outs => [ "res", "flags" ],
573 emit => 'shr%M %<S1, %S0',
576 modified_flags => $status_flags
580 irn_flags => [ "rematerializable" ],
581 state => "exc_pinned",
582 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
583 ins => [ "base", "index", "mem", "count" ],
584 emit => 'shr%M %<S3, %AM',
587 modified_flags => $status_flags
591 irn_flags => [ "rematerializable" ],
592 reg_req => { in => [ "gp", "gp", "ecx" ],
593 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
594 ins => [ "val_high", "val_low", "count" ],
595 outs => [ "res", "flags" ],
596 emit => "shrd%M %<S2, %S1, %D0",
599 modified_flags => $status_flags
603 irn_flags => [ "rematerializable" ],
604 reg_req => { in => [ "gp", "ecx" ],
605 out => [ "in_r1 !in_r2", "flags" ] },
606 ins => [ "val", "count" ],
607 outs => [ "res", "flags" ],
608 emit => 'sar%M %<S1, %S0',
611 modified_flags => $status_flags
615 irn_flags => [ "rematerializable" ],
616 state => "exc_pinned",
617 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
618 ins => [ "base", "index", "mem", "count" ],
619 emit => 'sar%M %<S3, %AM',
622 modified_flags => $status_flags
626 irn_flags => [ "rematerializable" ],
627 reg_req => { in => [ "gp", "ecx" ],
628 out => [ "in_r1 !in_r2", "flags" ] },
629 ins => [ "val", "count" ],
630 outs => [ "res", "flags" ],
631 emit => 'ror%M %<S1, %S0',
634 modified_flags => $status_flags
638 irn_flags => [ "rematerializable" ],
639 state => "exc_pinned",
640 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
641 ins => [ "base", "index", "mem", "count" ],
642 emit => 'ror%M %<S3, %AM',
645 modified_flags => $status_flags
649 irn_flags => [ "rematerializable" ],
650 reg_req => { in => [ "gp", "ecx" ],
651 out => [ "in_r1 !in_r2", "flags" ] },
652 ins => [ "val", "count" ],
653 outs => [ "res", "flags" ],
654 emit => 'rol%M %<S1, %D0',
657 modified_flags => $status_flags
661 irn_flags => [ "rematerializable" ],
662 state => "exc_pinned",
663 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
664 ins => [ "base", "index", "mem", "count" ],
665 emit => 'rol%M %<S3, %AM',
668 modified_flags => $status_flags
672 irn_flags => [ "rematerializable" ],
673 reg_req => { in => [ "gp" ],
674 out => [ "in_r1", "flags" ] },
677 outs => [ "res", "flags" ],
680 modified_flags => $status_flags
684 irn_flags => [ "rematerializable" ],
685 state => "exc_pinned",
686 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
687 ins => [ "base", "index", "mem" ],
691 modified_flags => $status_flags
695 irn_flags => [ "rematerializable" ],
696 reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
697 outs => [ "low_res", "high_res" ],
699 modified_flags => $status_flags
704 irn_flags => [ "rematerializable" ],
705 reg_req => { in => [ "gp" ],
706 out => [ "in_r1", "flags" ] },
708 outs => [ "res", "flags" ],
712 modified_flags => $status_flags_wo_cf
716 irn_flags => [ "rematerializable" ],
717 state => "exc_pinned",
718 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
719 ins => [ "base", "index", "mem" ],
723 modified_flags => $status_flags_wo_cf
727 irn_flags => [ "rematerializable" ],
728 reg_req => { in => [ "gp" ],
729 out => [ "in_r1", "flags" ] },
731 outs => [ "res", "flags" ],
735 modified_flags => $status_flags_wo_cf
739 irn_flags => [ "rematerializable" ],
740 state => "exc_pinned",
741 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
742 ins => [ "base", "index", "mem" ],
746 modified_flags => $status_flags_wo_cf
750 irn_flags => [ "rematerializable" ],
751 reg_req => { in => [ "gp" ],
752 out => [ "in_r1" ] },
762 irn_flags => [ "rematerializable" ],
763 state => "exc_pinned",
764 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
765 ins => [ "base", "index", "mem" ],
773 reg_req => { in => [ "flags" ], out => [ "flags" ] },
777 modified_flags => $status_flags
781 reg_req => { out => [ "flags" ] },
785 modified_flags => $status_flags
789 irn_flags => [ "rematerializable" ],
790 state => "exc_pinned",
791 constructors => \%binop_flags_constructors,
792 ins => [ "base", "index", "mem", "left", "right" ],
793 outs => [ "eflags", "unused", "M" ],
794 am => "source,binary",
796 attr => "bool ins_permuted",
797 init_attr => "attr->data.ins_permuted = ins_permuted;",
800 modified_flags => $status_flags
804 irn_flags => [ "rematerializable" ],
805 state => "exc_pinned",
806 reg_req => { in => [ "eax ebx ecx edx" ],
807 out => [ "in_r1", "flags" ] },
808 emit => 'xorb %>S0, %<S0',
810 outs => [ "res", "flags" ],
813 modified_flags => $status_flags,
817 irn_flags => [ "rematerializable" ],
818 state => "exc_pinned",
819 constructors => \%binop_flags_constructors,
820 ins => [ "base", "index", "mem", "left", "right" ],
821 outs => [ "eflags", "unused", "M" ],
822 am => "source,binary",
824 attr => "bool ins_permuted",
825 init_attr => "attr->data.ins_permuted = ins_permuted;",
828 modified_flags => $status_flags
832 #irn_flags => [ "rematerializable" ],
833 reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
836 attr_type => "ia32_condcode_attr_t",
837 attr => "ia32_condition_code_t condition_code",
838 # The way we handle Setcc with float nodes (potentially) destroys the flags
839 # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
840 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
841 . "\tif (condition_code & ia32_cc_additional_float_cases) {\n"
842 . "\t\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"
843 . "\t\t/* attr->latency = 3; */\n"
850 #irn_flags => [ "rematerializable" ],
851 state => "exc_pinned",
852 reg_req => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
853 ins => [ "base", "index", "mem","eflags" ],
854 attr_type => "ia32_condcode_attr_t",
855 attr => "ia32_condition_code_t condition_code",
856 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
857 emit => 'set%P3 %AM',
863 #irn_flags => [ "rematerializable" ],
864 state => "exc_pinned",
865 # (note: leave the false,true order intact to make it compatible with other
867 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
868 out => [ "in_r4 in_r5", "flags", "none" ] },
869 ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
870 outs => [ "res", "flags", "M" ],
871 am => "source,binary",
872 attr_type => "ia32_condcode_attr_t",
873 attr => "ia32_condition_code_t condition_code",
880 op_flags => [ "cfopcode", "forking" ],
881 reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
883 outs => [ "false", "true" ],
884 attr_type => "ia32_condcode_attr_t",
885 attr => "ia32_condition_code_t condition_code",
891 op_flags => [ "cfopcode", "forking" ],
892 reg_req => { in => [ "gp", "gp" ] },
893 ins => [ "base", "index" ],
894 out_arity => "variable",
895 attr_type => "ia32_switch_attr_t",
896 attr => "const ir_switch_table *switch_table",
902 irn_flags => [ "simple_jump" ],
903 op_flags => [ "cfopcode" ],
904 reg_req => { out => [ "none" ] },
911 op_flags => [ "cfopcode", "unknown_jump" ],
912 reg_req => { in => [ "gp", "gp", "none", "gp" ],
913 out => [ "none", "flags", "none" ] },
914 ins => [ "base", "index", "mem", "target" ],
915 outs => [ "jmp", "flags", "M" ],
916 am => "source,unary",
923 op_flags => [ "constlike" ],
924 irn_flags => [ "rematerializable" ],
925 reg_req => { out => [ "gp" ] },
926 emit => "movl %I, %D0",
927 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
928 attr_type => "ia32_immediate_attr_t",
934 op_flags => [ "constlike" ],
935 irn_flags => [ "rematerializable" ],
936 reg_req => { out => [ "gp" ] },
943 op_flags => [ "constlike" ],
944 reg_req => { out => [ "gp" ] },
947 modified_flags => $status_flags,
952 op_flags => [ "constlike", "dump_noblock" ],
953 irn_flags => [ "not_scheduled" ],
954 reg_req => { out => [ "gp_NOREG:I" ] },
961 op_flags => [ "constlike", "dump_noblock" ],
962 irn_flags => [ "not_scheduled" ],
963 reg_req => { out => [ "fp_NOREG:I" ] },
966 attr_type => "ia32_x87_attr_t",
971 op_flags => [ "constlike", "dump_noblock" ],
972 irn_flags => [ "not_scheduled" ],
973 reg_req => { out => [ "xmm_NOREG:I" ] },
980 op_flags => [ "constlike" ],
981 irn_flags => [ "not_scheduled" ],
982 reg_req => { out => [ "fpcw" ] },
985 modified_flags => $fpcw_flags
989 op_flags => [ "uses_memory" ],
991 reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw" ] },
992 ins => [ "base", "index", "mem" ],
996 modified_flags => $fpcw_flags
1000 op_flags => [ "uses_memory" ],
1002 reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1003 ins => [ "base", "index", "mem", "fpcw" ],
1005 emit => "fnstcw %AM",
1010 op_flags => [ "uses_memory" ],
1012 reg_req => { in => [ "fp_cw" ], out => [ "none" ] },
1020 # we should not rematrialize this node. It has very strict constraints.
1021 reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] },
1022 ins => [ "val", "clobbered" ],
1030 # Note that we add additional latency values depending on address mode, so a
1031 # lateny of 0 for load is correct
1034 op_flags => [ "uses_memory", "fragile" ],
1035 state => "exc_pinned",
1036 reg_req => { in => [ "gp", "gp", "none" ],
1037 out => [ "gp", "none", "none", "none", "none" ] },
1038 ins => [ "base", "index", "mem" ],
1039 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1041 emit => "mov%#Ml %AM, %D0",
1045 op_flags => [ "uses_memory", "fragile" ],
1046 state => "exc_pinned",
1047 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1048 out => [ "none", "none", "none" ] },
1049 ins => [ "base", "index", "mem", "val" ],
1050 outs => [ "M", "X_regular", "X_except" ],
1051 emit => 'mov%M %#S3, %AM',
1056 op_flags => [ "uses_memory", "fragile" ],
1057 state => "exc_pinned",
1058 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1059 out => ["none", "none", "none" ] },
1060 ins => [ "base", "index", "mem", "val" ],
1061 outs => [ "M", "X_regular", "X_except" ],
1062 emit => 'mov%M %#S3, %AM',
1067 irn_flags => [ "rematerializable" ],
1068 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1069 ins => [ "base", "index" ],
1070 emit => 'leal %AM, %D0',
1073 # lea doesn't modify the flags, but setting this seems advantageous since it
1074 # increases chances that the Lea is transformed back to an Add
1075 modified_flags => 1,
1079 state => "exc_pinned",
1080 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1081 ins => [ "base", "index", "mem", "val", "stack" ],
1082 emit => 'push%M %AS3',
1083 outs => [ "stack", "M" ],
1084 am => "source,unary",
1089 state => "exc_pinned",
1090 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1092 outs => [ "stack" ],
1093 emit => 'pushl %%eax',
1099 state => "exc_pinned",
1100 reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1101 ins => [ "mem", "stack" ],
1102 outs => [ "res", "M", "unused", "stack" ],
1103 emit => 'pop%M %D0',
1104 latency => 3, # Pop is more expensive than Push on Athlon
1108 state => "exc_pinned",
1109 reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1110 ins => [ "mem", "stack" ],
1111 outs => [ "res", "M", "unused", "stack" ],
1112 emit => 'pop%M %D0',
1113 latency => 3, # Pop is more expensive than Push on Athlon
1117 state => "exc_pinned",
1118 reg_req => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1121 emit => 'movl %S0, %D0',
1127 state => "exc_pinned",
1128 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1129 ins => [ "base", "index", "mem", "stack" ],
1130 outs => [ "unused0", "M", "unused1", "stack" ],
1131 emit => 'pop%M %AM',
1132 latency => 3, # Pop is more expensive than Push on Athlon
1136 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1138 outs => [ "frame", "stack", "M" ],
1143 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1145 outs => [ "frame", "stack" ],
1147 state => "exc_pinned",
1152 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1153 ins => [ "base", "index", "mem", "stack", "size" ],
1154 am => "source,binary",
1157 outs => [ "stack", "M" ],
1158 modified_flags => $status_flags
1163 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1164 ins => [ "base", "index", "mem", "stack", "size" ],
1165 am => "source,binary",
1166 emit => "subl %B\n".
1169 outs => [ "stack", "addr", "M" ],
1170 modified_flags => $status_flags
1174 op_flags => [ "keep" ],
1182 irn_flags => [ "rematerializable" ],
1183 reg_req => { out => [ "gp" ] },
1184 emit => "movl %%gs:0, %D0",
1190 # BT supports source address mode, but this is unused yet
1193 irn_flags => [ "rematerializable" ],
1194 state => "exc_pinned",
1195 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1196 ins => [ "left", "right" ],
1197 emit => 'bt%M %S1, %S0',
1199 mode => $mode_flags,
1200 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1204 irn_flags => [ "rematerializable" ],
1205 state => "exc_pinned",
1206 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1207 out => [ "gp", "flags", "none" ] },
1208 ins => [ "base", "index", "mem", "operand" ],
1209 outs => [ "res", "flags", "M" ],
1210 am => "source,binary",
1211 emit => 'bsf%M %AS3, %D0',
1214 modified_flags => $status_flags
1218 irn_flags => [ "rematerializable" ],
1219 state => "exc_pinned",
1220 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1221 out => [ "gp", "flags", "none" ] },
1222 ins => [ "base", "index", "mem", "operand" ],
1223 outs => [ "res", "flags", "M" ],
1224 am => "source,binary",
1225 emit => 'bsr%M %AS3, %D0',
1228 modified_flags => $status_flags
1232 # SSE4.2 or SSE4a popcnt instruction
1235 irn_flags => [ "rematerializable" ],
1236 state => "exc_pinned",
1237 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1238 out => [ "gp", "flags", "none" ] },
1239 ins => [ "base", "index", "mem", "operand" ],
1240 outs => [ "res", "flags", "M" ],
1241 am => "source,binary",
1242 emit => 'popcnt%M %AS3, %D0',
1245 modified_flags => $status_flags
1249 op_flags => [ "uses_memory", "fragile" ],
1250 state => "exc_pinned",
1252 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1253 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" ]
1255 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1256 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" ],
1257 emit => "call %*AS3",
1258 attr_type => "ia32_call_attr_t",
1259 attr => "unsigned pop, ir_type *call_tp",
1260 am => "source,unary",
1261 latency => 4, # random number
1262 modified_flags => $status_flags
1266 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1268 # PS: try gcc __builtin_frame_address(100000) :-)
1271 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1272 ins => [ "frame", "cnt", "tmp" ],
1274 latency => 4, # random number
1275 attr_type => "ia32_climbframe_attr_t",
1276 attr => "unsigned count",
1284 irn_flags => [ "rematerializable" ],
1285 reg_req => { in => [ "gp" ],
1286 out => [ "in_r1" ] },
1288 emit => 'bswap%M %S0',
1295 # bswap16, use xchg here
1298 irn_flags => [ "rematerializable" ],
1299 reg_req => { in => [ "eax ebx ecx edx" ],
1300 out => [ "in_r1" ] },
1301 emit => 'xchg %<S0, %>S0',
1312 reg_req => { in => [ "none" ], out => [ "none" ] },
1320 # Undefined Instruction on ALL x86 CPU's
1324 reg_req => { in => [ "none" ], out => [ "none" ] },
1335 irn_flags => [ "rematerializable" ],
1337 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1338 ins => [ "port", "value", "mem" ],
1339 emit => 'out%M %^S0, %#S1',
1342 modified_flags => $status_flags
1349 irn_flags => [ "rematerializable" ],
1351 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1352 ins => [ "port", "mem" ],
1353 outs => [ "res", "M" ],
1354 emit => 'in%M %#D0, %^S0',
1357 modified_flags => $status_flags
1361 # Intel style prefetching
1364 op_flags => [ "uses_memory" ],
1365 state => "exc_pinned",
1366 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1367 ins => [ "base", "index", "mem" ],
1370 emit => "prefetcht0 %AM",
1374 op_flags => [ "uses_memory" ],
1375 state => "exc_pinned",
1376 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1377 ins => [ "base", "index", "mem" ],
1380 emit => "prefetcht1 %AM",
1384 op_flags => [ "uses_memory" ],
1385 state => "exc_pinned",
1386 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1387 ins => [ "base", "index", "mem" ],
1390 emit => "prefetcht2 %AM",
1394 op_flags => [ "uses_memory" ],
1395 state => "exc_pinned",
1396 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1397 ins => [ "base", "index", "mem" ],
1400 emit => "prefetchnta %AM",
1404 # 3DNow! prefetch instructions
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 => "prefetch %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 => "prefetchw %AM",
1428 irn_flags => [ "rematerializable" ],
1429 reg_req => { out => [ "xmm" ] },
1430 emit => 'xorp%FX %D0, %D0',
1436 op_flags => [ "constlike" ],
1437 irn_flags => [ "rematerializable" ],
1438 reg_req => { out => [ "xmm" ] },
1445 irn_flags => [ "rematerializable" ],
1446 reg_req => { out => [ "xmm" ] },
1447 emit => 'pxor %D0, %D0',
1452 # produces all 1 bits
1454 irn_flags => [ "rematerializable" ],
1455 reg_req => { out => [ "xmm" ] },
1456 emit => 'pcmpeqb %D0, %D0',
1461 # integer shift left, dword
1463 irn_flags => [ "rematerializable" ],
1464 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1465 emit => 'pslld %#S1, %D0',
1470 # integer shift left, qword
1472 irn_flags => [ "rematerializable" ],
1473 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1474 emit => 'psllq %#S1, %D0',
1479 # integer shift right, dword
1481 irn_flags => [ "rematerializable" ],
1482 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1483 emit => 'psrld %#S1, %D0',
1488 # mov from integer to SSE register
1490 irn_flags => [ "rematerializable" ],
1491 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1492 emit => 'movd %S0, %D0',
1498 irn_flags => [ "rematerializable" ],
1499 state => "exc_pinned",
1500 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1501 out => [ "in_r4 in_r5", "flags", "none" ] },
1502 ins => [ "base", "index", "mem", "left", "right" ],
1503 outs => [ "res", "flags", "M" ],
1504 am => "source,binary",
1505 emit => 'adds%FX %B',
1511 irn_flags => [ "rematerializable" ],
1512 state => "exc_pinned",
1513 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1514 out => [ "in_r4 in_r5", "flags", "none" ] },
1515 ins => [ "base", "index", "mem", "left", "right" ],
1516 outs => [ "res", "flags", "M" ],
1517 am => "source,binary",
1518 emit => 'muls%FX %B',
1524 irn_flags => [ "rematerializable" ],
1525 state => "exc_pinned",
1526 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1527 out => [ "in_r4 in_r5", "flags", "none" ] },
1528 ins => [ "base", "index", "mem", "left", "right" ],
1529 outs => [ "res", "flags", "M" ],
1530 am => "source,binary",
1531 emit => 'maxs%FX %B',
1537 irn_flags => [ "rematerializable" ],
1538 state => "exc_pinned",
1539 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1540 out => [ "in_r4 in_r5", "flags", "none" ] },
1541 ins => [ "base", "index", "mem", "left", "right" ],
1542 outs => [ "res", "flags", "M" ],
1543 am => "source,binary",
1544 emit => 'mins%FX %B',
1550 irn_flags => [ "rematerializable" ],
1551 state => "exc_pinned",
1552 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1553 out => [ "in_r4 in_r5", "flags", "none" ] },
1554 ins => [ "base", "index", "mem", "left", "right" ],
1555 outs => [ "res", "flags", "M" ],
1556 am => "source,binary",
1557 emit => 'andp%FX %B',
1563 irn_flags => [ "rematerializable" ],
1564 state => "exc_pinned",
1565 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1566 out => [ "in_r4 in_r5", "flags", "none" ] },
1567 ins => [ "base", "index", "mem", "left", "right" ],
1568 outs => [ "res", "flags", "M" ],
1569 am => "source,binary",
1570 emit => 'orp%FX %B',
1576 irn_flags => [ "rematerializable" ],
1577 state => "exc_pinned",
1578 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1579 out => [ "in_r4 in_r5", "flags", "none" ] },
1580 ins => [ "base", "index", "mem", "left", "right" ],
1581 outs => [ "res", "flags", "M" ],
1582 am => "source,binary",
1583 emit => 'xorp%FX %B',
1589 irn_flags => [ "rematerializable" ],
1590 state => "exc_pinned",
1591 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1592 out => [ "in_r4 !in_r5", "flags", "none" ] },
1593 ins => [ "base", "index", "mem", "left", "right" ],
1594 outs => [ "res", "flags", "M" ],
1595 am => "source,binary",
1596 emit => 'andnp%FX %B',
1602 irn_flags => [ "rematerializable" ],
1603 state => "exc_pinned",
1604 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1605 out => [ "in_r4", "flags", "none" ] },
1606 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1607 outs => [ "res", "flags", "M" ],
1608 am => "source,binary",
1609 emit => 'subs%FX %B',
1615 irn_flags => [ "rematerializable" ],
1616 state => "exc_pinned",
1617 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1618 out => [ "in_r4 !in_r5", "flags", "none" ] },
1619 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1620 outs => [ "res", "flags", "M" ],
1621 am => "source,binary",
1622 emit => 'divs%FX %B',
1627 irn_flags => [ "rematerializable" ],
1628 state => "exc_pinned",
1629 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1630 out => [ "eflags" ] },
1631 ins => [ "base", "index", "mem", "left", "right" ],
1632 outs => [ "flags" ],
1633 am => "source,binary",
1634 attr => "bool ins_permuted",
1635 init_attr => "attr->data.ins_permuted = ins_permuted;",
1636 emit => 'ucomis%FX %B',
1638 mode => $mode_flags,
1639 modified_flags => 1,
1643 op_flags => [ "uses_memory", "fragile" ],
1644 state => "exc_pinned",
1645 reg_req => { in => [ "gp", "gp", "none" ],
1646 out => [ "xmm", "none", "none", "none", "none" ] },
1647 ins => [ "base", "index", "mem" ],
1648 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1649 emit => 'movs%FX %AM, %D0',
1650 attr => "ir_mode *load_mode",
1651 init_attr => "attr->ls_mode = load_mode;",
1656 op_flags => [ "uses_memory", "fragile" ],
1657 state => "exc_pinned",
1658 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1659 out => [ "none", "none", "none" ] },
1660 ins => [ "base", "index", "mem", "val" ],
1661 outs => [ "M", "X_regular", "X_except" ],
1662 emit => 'movs%FX %S3, %AM',
1667 op_flags => [ "uses_memory", "fragile" ],
1668 state => "exc_pinned",
1669 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
1670 out => [ "none", "none", "none" ] },
1671 ins => [ "base", "index", "mem", "val" ],
1672 outs => [ "M", "X_regular", "X_except" ],
1673 emit => 'movs%FX %S3, %AM',
1678 state => "exc_pinned",
1679 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1680 ins => [ "base", "index", "mem", "val" ],
1681 am => "source,unary",
1682 emit => 'cvtsi2ss %AS3, %D0',
1688 state => "exc_pinned",
1689 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1690 ins => [ "base", "index", "mem", "val" ],
1691 am => "source,unary",
1692 emit => 'cvtsi2sd %AS3, %D0',
1699 ins => [ "val_high", "val_low" ],
1701 dump_func => "NULL",
1706 outs => [ "res_high", "res_low" ],
1708 dump_func => "NULL",
1712 op_flags => [ "uses_memory", "fragile" ],
1714 reg_req => { in => [ "edi", "esi", "ecx", "none" ],
1715 out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1716 ins => [ "dest", "source", "count", "mem" ],
1717 outs => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1718 attr_type => "ia32_copyb_attr_t",
1719 attr => "unsigned size",
1721 # we don't care about this flag, so no need to mark this node
1722 # modified_flags => [ "DF" ]
1726 op_flags => [ "uses_memory", "fragile" ],
1728 reg_req => { in => [ "edi", "esi", "none" ],
1729 out => [ "edi", "esi", "none", "none", "none" ] },
1730 ins => [ "dest", "source", "mem" ],
1731 outs => [ "dest", "source", "M", "X_regular", "X_except" ],
1732 attr_type => "ia32_copyb_attr_t",
1733 attr => "unsigned size",
1735 # we don't care about this flag, so no need to mark this node
1736 # modified_flags => [ "DF" ]
1740 state => "exc_pinned",
1741 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1750 op_flags => [ "uses_memory", "fragile" ],
1751 state => "exc_pinned",
1752 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1753 out => [ "gp", "none", "none", "none", "none" ] },
1754 ins => [ "base", "index", "mem", "val" ],
1755 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1756 emit => "mov%#Ml %#AS3, %D0",
1757 am => "source,unary",
1759 attr => "ir_mode *smaller_mode",
1760 init_attr => "attr->ls_mode = smaller_mode;",
1765 op_flags => [ "uses_memory", "fragile" ],
1766 state => "exc_pinned",
1767 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1768 out => [ "gp", "none", "none", "none", "none" ] },
1769 ins => [ "base", "index", "mem", "val" ],
1770 outs => [ "res", "flags", "M", "X_regular", "X_except" ],
1771 emit => "mov%#Ml %#AS3, %D0",
1772 am => "source,unary",
1774 attr => "ir_mode *smaller_mode",
1775 init_attr => "attr->ls_mode = smaller_mode;",
1780 state => "exc_pinned",
1781 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1782 ins => [ "base", "index", "mem", "val" ],
1783 am => "source,unary",
1789 state => "exc_pinned",
1790 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1791 ins => [ "base", "index", "mem", "val" ],
1792 am => "source,unary",
1798 state => "exc_pinned",
1799 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1800 ins => [ "base", "index", "mem", "val" ],
1801 am => "source,unary",
1806 # rematerialisation disabled for all float nodes for now, because the fpcw
1807 # handler runs before spilling and we might end up with wrong fpcw then
1810 # irn_flags => [ "rematerializable" ],
1811 state => "exc_pinned",
1812 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1813 out => [ "fp", "none", "none" ] },
1814 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1815 outs => [ "res", "dummy", "M" ],
1816 emit => 'fadd%FP%FM %AF',
1817 am => "source,binary",
1820 attr_type => "ia32_x87_attr_t",
1824 # irn_flags => [ "rematerializable" ],
1825 state => "exc_pinned",
1826 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1827 out => [ "fp", "none", "none" ] },
1828 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
1829 outs => [ "res", "dummy", "M" ],
1830 emit => 'fmul%FP%FM %AF',
1831 am => "source,binary",
1834 attr_type => "ia32_x87_attr_t",
1838 # irn_flags => [ "rematerializable" ],
1839 state => "exc_pinned",
1840 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1841 out => [ "fp", "none", "none" ] },
1842 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
1843 outs => [ "res", "dummy", "M" ],
1844 emit => 'fsub%FR%FP%FM %AF',
1845 am => "source,binary",
1848 attr_type => "ia32_x87_attr_t",
1852 state => "exc_pinned",
1853 reg_req => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1854 out => [ "fp", "none", "none" ] },
1855 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
1856 outs => [ "res", "dummy", "M" ],
1857 emit => 'fdiv%FR%FP%FM %AF',
1858 am => "source,binary",
1860 attr_type => "ia32_x87_attr_t",
1864 reg_req => { in => [ "fp", "fp", "fpcw" ], out => [ "fp" ] },
1865 ins => [ "left", "right", "fpcw" ],
1869 attr_type => "ia32_x87_attr_t",
1873 irn_flags => [ "rematerializable" ],
1874 reg_req => { in => [ "fp"], out => [ "fp" ] },
1879 attr_type => "ia32_x87_attr_t",
1883 irn_flags => [ "rematerializable" ],
1884 reg_req => { in => [ "fp"], out => [ "fp" ] },
1889 attr_type => "ia32_x87_attr_t",
1893 irn_flags => [ "rematerializable" ],
1894 op_flags => [ "uses_memory", "fragile" ],
1895 state => "exc_pinned",
1896 reg_req => { in => [ "gp", "gp", "none" ],
1897 out => [ "fp", "none", "none", "none", "none" ] },
1898 ins => [ "base", "index", "mem" ],
1899 outs => [ "res", "unused", "M", "X_regular", "X_except" ],
1900 emit => 'fld%FM %AM',
1901 attr => "ir_mode *load_mode",
1902 init_attr => "attr->attr.ls_mode = load_mode;",
1904 attr_type => "ia32_x87_attr_t",
1908 irn_flags => [ "rematerializable" ],
1909 op_flags => [ "uses_memory", "fragile" ],
1910 state => "exc_pinned",
1911 reg_req => { in => [ "gp", "gp", "none", "fp" ],
1912 out => [ "none", "none", "none" ] },
1913 ins => [ "base", "index", "mem", "val" ],
1914 outs => [ "M", "X_regular", "X_except" ],
1915 emit => 'fst%FP%FM %AM',
1916 attr => "ir_mode *store_mode",
1917 init_attr => "attr->attr.ls_mode = store_mode;",
1919 attr_type => "ia32_x87_attr_t",
1923 state => "exc_pinned",
1924 reg_req => { in => [ "gp", "gp", "none" ],
1925 out => [ "fp", "none", "none" ] },
1926 outs => [ "res", "unused", "M" ],
1927 ins => [ "base", "index", "mem" ],
1928 emit => 'fild%FM %AM',
1930 attr_type => "ia32_x87_attr_t",
1934 op_flags => [ "uses_memory", "fragile" ],
1935 state => "exc_pinned",
1936 reg_req => { in => [ "gp", "gp", "none", "fp", "fpcw" ],
1937 out => [ "none", "none", "none", "none" ] },
1938 ins => [ "base", "index", "mem", "val", "fpcw" ],
1939 outs => [ "dummy", "M", "X_regular", "X_except" ],
1940 emit => 'fist%FP%FM %AM',
1942 attr_type => "ia32_x87_attr_t",
1945 # SSE3 fisttp instruction
1947 op_flags => [ "uses_memory", "fragile" ],
1948 state => "exc_pinned",
1949 reg_req => { in => [ "gp", "gp", "none", "fp" ],
1950 out => [ "in_r4", "none", "none", "none" ]},
1951 ins => [ "base", "index", "mem", "val" ],
1952 outs => [ "res", "M", "X_regular", "X_except" ],
1953 emit => 'fisttp%FM %AM',
1955 attr_type => "ia32_x87_attr_t",
1959 irn_flags => [ "rematerializable" ],
1960 reg_req => { out => [ "fp" ] },
1965 attr_type => "ia32_x87_attr_t",
1969 irn_flags => [ "rematerializable" ],
1970 reg_req => { out => [ "fp" ] },
1975 attr_type => "ia32_x87_attr_t",
1979 irn_flags => [ "rematerializable" ],
1980 reg_req => { out => [ "fp" ] },
1985 attr_type => "ia32_x87_attr_t",
1989 irn_flags => [ "rematerializable" ],
1990 reg_req => { out => [ "fp" ] },
1995 attr_type => "ia32_x87_attr_t",
1999 irn_flags => [ "rematerializable" ],
2000 reg_req => { out => [ "fp" ] },
2005 attr_type => "ia32_x87_attr_t",
2009 irn_flags => [ "rematerializable" ],
2010 reg_req => { out => [ "fp" ] },
2015 attr_type => "ia32_x87_attr_t",
2019 irn_flags => [ "rematerializable" ],
2020 reg_req => { out => [ "fp" ] },
2025 attr_type => "ia32_x87_attr_t",
2029 # we can't allow to rematerialize this node so we don't
2030 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2031 # irn_flags => [ "rematerializable" ],
2032 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2033 ins => [ "left", "right" ],
2034 outs => [ "flags" ],
2035 emit => "fucom%FP %F0\n".
2037 attr => "bool ins_permuted",
2038 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2040 attr_type => "ia32_x87_attr_t",
2045 # we can't allow to rematerialize this node so we don't
2046 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2047 # irn_flags => [ "rematerializable" ],
2048 reg_req => { in => [ "fp", "fp" ], out => [ "eax" ] },
2049 ins => [ "left", "right" ],
2050 outs => [ "flags" ],
2051 emit => "fucompp\n".
2053 attr => "bool ins_permuted",
2054 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2056 attr_type => "ia32_x87_attr_t",
2061 irn_flags => [ "rematerializable" ],
2062 reg_req => { in => [ "fp", "fp" ], out => [ "eflags" ] },
2063 ins => [ "left", "right" ],
2064 outs => [ "flags" ],
2065 emit => 'fucom%FPi %F0',
2066 attr => "bool ins_permuted",
2067 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2069 attr_type => "ia32_x87_attr_t",
2074 # irn_flags => [ "rematerializable" ],
2075 reg_req => { in => [ "fp" ], out => [ "eax" ] },
2077 outs => [ "flags" ],
2080 attr => "bool ins_permuted",
2081 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2083 attr_type => "ia32_x87_attr_t",
2088 irn_flags => [ "rematerializable" ],
2089 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2091 outs => [ "flags" ],
2094 mode => $mode_flags,
2098 # Note that it is NEVER allowed to do CSE on these nodes
2099 # Moreover, note the virtual register requierements!
2102 op_flags => [ "keep" ],
2103 reg_req => { out => [ "none" ] },
2104 cmp_attr => "return 1;",
2106 attr_type => "ia32_x87_attr_t",
2112 op_flags => [ "keep" ],
2113 reg_req => { out => [ "none" ] },
2114 cmp_attr => "return 1;",
2116 attr_type => "ia32_x87_attr_t",
2122 reg_req => { in => [ "fp"], out => [ "fp" ] },
2123 cmp_attr => "return 1;",
2125 attr_type => "ia32_x87_attr_t",
2130 op_flags => [ "keep" ],
2131 reg_req => { out => [ "none" ] },
2132 cmp_attr => "return 1;",
2134 attr_type => "ia32_x87_attr_t",
2140 op_flags => [ "keep" ],
2141 reg_req => { out => [ "none" ] },
2142 cmp_attr => "return 1;",
2143 emit => 'ffreep %F0',
2144 attr_type => "ia32_x87_attr_t",
2150 op_flags => [ "keep" ],
2151 reg_req => { out => [ "none" ] },
2152 cmp_attr => "return 1;",
2154 attr_type => "ia32_x87_attr_t",
2160 op_flags => [ "keep" ],
2161 reg_req => { out => [ "none" ] },
2162 cmp_attr => "return 1;",
2164 attr_type => "ia32_x87_attr_t",
2169 # Spilling and reloading of SSE registers, hardcoded, not generated #
2172 op_flags => [ "uses_memory", "fragile" ],
2173 state => "exc_pinned",
2174 reg_req => { in => [ "gp", "gp", "none" ],
2175 out => [ "xmm", "none", "none", "none" ] },
2176 emit => 'movdqu %D0, %AM',
2177 ins => [ "base", "index", "mem" ],
2178 outs => [ "res", "M", "X_regular", "X_except" ],
2183 op_flags => [ "uses_memory", "fragile" ],
2184 state => "exc_pinned",
2185 reg_req => { in => [ "gp", "gp", "none", "xmm" ],
2186 out => [ "none", "none", "none" ] },
2187 ins => [ "base", "index", "mem", "val" ],
2188 outs => [ "M", "X_regular", "X_except" ],
2189 emit => 'movdqu %B',
2195 # Transform some attributes
2196 foreach my $op (keys(%nodes)) {
2197 my $node = $nodes{$op};
2198 my $op_attr_init = $node->{op_attr_init};
2200 if(defined($op_attr_init)) {
2201 $op_attr_init .= "\n\t";
2206 if(!defined($node->{latency})) {
2208 $node->{latency} = 0;
2210 die("Latency missing for op $op");
2213 $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2215 $node->{op_attr_init} = $op_attr_init;