3 # This is the specification for the ia32 assembler Firm-operations
7 # The node description is done as a perl hash initializer with the
13 # op_flags => "N|L|C|X|I|F|Y|H|c|K|n",
15 # arity => "0|1|2|3 ... |variable|dynamic|any",
16 # state => "floats|pinned|mem_pinned|exc_pinned",
18 # { type => "type 1", name => "name 1" },
19 # { type => "type 2", name => "name 2" },
22 # comment => "any comment for constructor",
23 # reg_req => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] },
24 # cmp_attr => "c source code for comparing node attributes",
25 # outs => { "out1", "out2" } # optional, creates pn_op_out1, ... consts
26 # ins => { "in1", "in2" } # optional, creates n_op_in1, ... consts
27 # mode => "mode_Iu" # optional, predefines the mode
28 # emit => "emit code with templates",
29 # attr => "additional attribute arguments for constructor",
30 # init_attr => "emit attribute initialization template",
31 # hash_func => "name of the hash function for this operation",
32 # latency => "latency of this operation (can be float)"
33 # attr_type => "name of the attribute struct",
34 # modified_flags => [ "CF", ... ] # optional, list of modified flags
37 # ... # (all nodes you need to describe)
39 # ); # close the %nodes initializer
41 # state: state of the operation, OPTIONAL (default is "floats")
43 # arity: arity of the operation, MUST NOT BE OMITTED
45 # args: the OPTIONAL arguments of the node constructor (debug, irg and block
46 # are always the first 3 arguments and are always autmatically
48 # If this key is missing the following arguments will be created:
49 # for i = 1 .. arity: ir_node *op_i
52 # outs: if a node defines more than one output, the names of the projections
53 # nodes having outs having automatically the mode mode_T
54 # example: [ "frame", "stack", "M" ]
56 # comment: OPTIONAL comment for the node constructor
58 # rd_constructor: for every operation there will be a
59 # new_rd_<arch>_<op-name> function with the arguments from above
60 # which creates the ir_node corresponding to the defined operation
61 # you can either put the complete source code of this function here
63 # This key is OPTIONAL. If omitted, the following constructor will
65 # if (!op_<arch>_<op-name>) assert(0);
69 # res = new_ir_node(db, irg, block, op_<arch>_<op-name>, mode, arity, in)
72 # NOTE: rd_constructor and args are only optional if and only if arity is 0,1,2 or 3
77 # 1 - caller save (register must be saved by the caller of a function)
78 # 2 - callee save (register must be saved by the called function)
79 # 4 - ignore (do not automatically assign this register)
80 # 8 - emitter can choose an arbitrary register of this class
81 # 16 - the register is a virtual one
82 # 32 - register represents a state
83 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
86 { name => "edx", type => 1 },
87 { name => "ecx", type => 1 },
88 { name => "eax", type => 1 },
89 { name => "ebx", type => 2 },
90 { name => "esi", type => 2 },
91 { name => "edi", type => 2 },
92 { name => "ebp", type => 2 },
93 { name => "esp", type => 4 },
94 { name => "gp_NOREG", type => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes
98 { name => "mm0", type => 4 },
99 { name => "mm1", type => 4 },
100 { name => "mm2", type => 4 },
101 { name => "mm3", type => 4 },
102 { name => "mm4", type => 4 },
103 { name => "mm5", type => 4 },
104 { name => "mm6", type => 4 },
105 { name => "mm7", type => 4 },
106 { mode => "mode_E", flags => "manual_ra" }
109 { name => "xmm0", type => 1 },
110 { name => "xmm1", type => 1 },
111 { name => "xmm2", type => 1 },
112 { name => "xmm3", type => 1 },
113 { name => "xmm4", type => 1 },
114 { name => "xmm5", type => 1 },
115 { name => "xmm6", type => 1 },
116 { name => "xmm7", type => 1 },
117 { name => "xmm_NOREG", type => 4 | 16 }, # we need a dummy register for NoReg nodes
121 { name => "vf0", type => 1 },
122 { name => "vf1", type => 1 },
123 { name => "vf2", type => 1 },
124 { name => "vf3", type => 1 },
125 { name => "vf4", type => 1 },
126 { name => "vf5", type => 1 },
127 { name => "vf6", type => 1 },
128 { name => "vf7", type => 1 },
129 { name => "vfp_NOREG", type => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes
133 { name => "st0", realname => "st", type => 4 },
134 { name => "st1", realname => "st(1)", type => 4 },
135 { name => "st2", realname => "st(2)", type => 4 },
136 { name => "st3", realname => "st(3)", type => 4 },
137 { name => "st4", realname => "st(4)", type => 4 },
138 { name => "st5", realname => "st(5)", type => 4 },
139 { name => "st6", realname => "st(6)", type => 4 },
140 { name => "st7", realname => "st(7)", type => 4 },
141 { mode => "mode_E", flags => "manual_ra" }
143 fp_cw => [ # the floating point control word
144 { name => "fpcw", type => 4|32 },
145 { mode => "mode_fpcw", flags => "manual_ra|state" }
148 { name => "eflags", type => 0 },
149 { mode => "mode_Iu", flags => "manual_ra" }
154 GP => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
155 SSE => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
156 VFP => [ 1, "VFP_VF0", "VFP_VF1", "VFP_VF2", "VFP_VF3", "VFP_VF4", "VFP_VF5", "VFP_VF6", "VFP_VF7" ],
157 BRANCH => [ 1, "BRANCH1", "BRANCH2" ],
162 bundels_per_cycle => 1
166 S0 => "${arch}_emit_source_register(node, 0);",
167 S1 => "${arch}_emit_source_register(node, 1);",
168 S2 => "${arch}_emit_source_register(node, 2);",
169 S3 => "${arch}_emit_source_register(node, 3);",
170 SB0 => "${arch}_emit_8bit_source_register_or_immediate(node, 0);",
171 SB1 => "${arch}_emit_8bit_source_register_or_immediate(node, 1);",
172 SB2 => "${arch}_emit_8bit_source_register_or_immediate(node, 2);",
173 SB3 => "${arch}_emit_8bit_source_register_or_immediate(node, 3);",
174 SH0 => "${arch}_emit_8bit_high_source_register(node, 0);",
175 SS0 => "${arch}_emit_16bit_source_register_or_immediate(node, 0);",
176 SI0 => "${arch}_emit_source_register_or_immediate(node, 0);",
177 SI1 => "${arch}_emit_source_register_or_immediate(node, 1);",
178 SI3 => "${arch}_emit_source_register_or_immediate(node, 3);",
179 D0 => "${arch}_emit_dest_register(node, 0);",
180 D1 => "${arch}_emit_dest_register(node, 1);",
181 DS0 => "${arch}_emit_dest_register_size(node, 0);",
182 DB0 => "${arch}_emit_8bit_dest_register(node, 0);",
183 X0 => "${arch}_emit_x87_register(node, 0);",
184 X1 => "${arch}_emit_x87_register(node, 1);",
185 EX => "${arch}_emit_extend_suffix(node);",
186 M => "${arch}_emit_mode_suffix(node);",
187 XM => "${arch}_emit_x87_mode_suffix(node);",
188 XXM => "${arch}_emit_xmm_mode_suffix(node);",
189 XSD => "${arch}_emit_xmm_mode_suffix_s(node);",
190 AM => "${arch}_emit_am(node);",
191 unop3 => "${arch}_emit_unop(node, n_ia32_unary_op);",
192 unop4 => "${arch}_emit_unop(node, n_ia32_binary_right);",
193 binop => "${arch}_emit_binop(node);",
194 x87_binop => "${arch}_emit_x87_binop(node);",
195 CMP3 => "${arch}_emit_cmp_suffix_node(node, 3);",
201 $default_op_attr_type = "ia32_op_attr_t";
202 $default_attr_type = "ia32_attr_t";
203 $default_copy_attr = "ia32_copy_attr";
205 sub ia32_custom_init_attr {
211 if(defined($node->{modified_flags})) {
212 $res .= "\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n";
214 if(defined($node->{am})) {
215 my $am = $node->{am};
216 if($am eq "source,unary") {
217 $res .= "\tset_ia32_am_support(res, ia32_am_unary);";
218 } elsif($am eq "source,binary") {
219 $res .= "\tset_ia32_am_support(res, ia32_am_binary);";
220 } elsif($am eq "none") {
223 die("Invalid address mode '$am' specified on op $name");
226 if($node->{state} ne "exc_pinned"
227 and $node->{state} ne "pinned") {
228 die("AM nodes must have pinned or AM pinned state ($name)");
234 $custom_init_attr_func = \&ia32_custom_init_attr;
238 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
239 "\tinit_ia32_x87_attributes(res);".
240 "\tinit_ia32_asm_attributes(res);",
242 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);",
244 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
245 "\tinit_ia32_call_attributes(res, pop, call_tp);",
246 ia32_condcode_attr_t =>
247 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
248 "\tinit_ia32_condcode_attributes(res, pnc);",
250 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
251 "\tinit_ia32_copyb_attributes(res, size);",
252 ia32_immediate_attr_t =>
253 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
254 "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
256 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
257 "\tinit_ia32_x87_attributes(res);",
258 ia32_climbframe_attr_t =>
259 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
260 "\tinit_ia32_climbframe_attributes(res, count);",
264 ia32_asm_attr_t => "ia32_compare_asm_attr",
265 ia32_attr_t => "ia32_compare_nodes_attr",
266 ia32_call_attr_t => "ia32_compare_call_attr",
267 ia32_condcode_attr_t => "ia32_compare_condcode_attr",
268 ia32_copyb_attr_t => "ia32_compare_copyb_attr",
269 ia32_immediate_attr_t => "ia32_compare_immediate_attr",
270 ia32_x87_attr_t => "ia32_compare_x87_attr",
271 ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
277 $mode_xmm = "mode_E";
278 $mode_gp = "mode_Iu";
279 $mode_flags = "mode_Iu";
280 $mode_fpcw = "mode_fpcw";
281 $status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
282 $status_flags_wo_cf = [ "PF", "AF", "ZF", "SF", "OF" ];
283 $fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
284 "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
290 op_flags => [ "constlike" ],
291 reg_req => { out => [ "gp_NOREG:I" ] },
292 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
293 attr_type => "ia32_immediate_attr_t",
294 hash_func => "ia32_hash_Immediate",
302 out_arity => "variable",
303 attr_type => "ia32_asm_attr_t",
304 attr => "ident *asm_text, const ia32_asm_reg_t *register_map",
305 init_attr => "attr->asm_text = asm_text;\n".
306 "\tattr->register_map = register_map;\n",
308 modified_flags => $status_flags,
311 # "allocates" a free register
313 op_flags => [ "constlike", "cse_neutral" ],
314 irn_flags => [ "rematerializable" ],
315 reg_req => { out => [ "gp" ] },
320 cmp_attr => "return 1;",
324 irn_flags => [ "rematerializable" ],
325 state => "exc_pinned",
326 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
327 out => [ "in_r4 in_r5", "flags", "none" ] },
328 ins => [ "base", "index", "mem", "left", "right" ],
329 outs => [ "res", "flags", "M" ],
330 emit => '. add%M %binop',
331 am => "source,binary",
335 modified_flags => $status_flags
339 irn_flags => [ "rematerializable" ],
340 state => "exc_pinned",
341 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
342 ins => [ "base", "index", "mem", "val" ],
343 emit => ". add%M %SI3, %AM",
347 modified_flags => $status_flags
351 irn_flags => [ "rematerializable" ],
352 state => "exc_pinned",
353 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
354 ins => [ "base", "index", "mem", "val" ],
355 emit => ". add%M %SB3, %AM",
359 modified_flags => $status_flags
363 state => "exc_pinned",
364 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
365 out => [ "in_r4 in_r5", "flags", "none" ] },
366 ins => [ "base", "index", "mem", "left", "right", "eflags" ],
367 outs => [ "res", "flags", "M" ],
368 emit => '. adc%M %binop',
369 am => "source,binary",
373 modified_flags => $status_flags
377 op_flags => [ "constlike" ],
378 reg_req => { in => [ "none", "none" ], out => [ "none" ] },
379 ins => [ "left", "right" ],
383 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
384 ins => [ "left", "right", "eflags" ],
388 # we should not rematrialize this node. It produces 2 results and has
389 # very strict constraints
390 state => "exc_pinned",
391 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
392 out => [ "eax", "flags", "none", "edx" ] },
393 ins => [ "base", "index", "mem", "left", "right" ],
394 emit => '. mul%M %unop4',
395 outs => [ "res_low", "flags", "M", "res_high" ],
396 am => "source,binary",
399 modified_flags => $status_flags
403 # we should not rematrialize this node. It produces 2 results and has
404 # very strict constraints
405 op_flags => [ "constlike" ],
406 cmp_attr => "return 1;",
407 reg_req => { in => [ "none", "none" ],
408 out => [ "none", "none", "none", "none" ] },
409 ins => [ "left", "right" ],
410 outs => [ "res_low", "flags", "M", "res_high" ],
414 irn_flags => [ "rematerializable" ],
415 state => "exc_pinned",
416 # TODO: adjust out requirements for the 3 operand form
417 # (no need for should_be_same then)
418 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
419 out => [ "in_r4 in_r5", "flags", "none" ] },
420 ins => [ "base", "index", "mem", "left", "right" ],
421 outs => [ "res", "flags", "M" ],
422 am => "source,binary",
426 modified_flags => $status_flags
430 irn_flags => [ "rematerializable" ],
431 state => "exc_pinned",
432 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
433 out => [ "eax", "flags", "none", "edx" ] },
434 ins => [ "base", "index", "mem", "left", "right" ],
435 emit => '. imul%M %unop4',
436 outs => [ "res_low", "flags", "M", "res_high" ],
437 am => "source,binary",
440 modified_flags => $status_flags
444 op_flags => [ "constlike" ],
445 cmp_attr => "return 1;",
446 reg_req => { in => [ "none", "none" ],
447 out => [ "none", "none", "none", "none" ] },
448 ins => [ "left", "right" ],
449 outs => [ "res_low", "flags", "M", "res_high" ],
453 irn_flags => [ "rematerializable" ],
454 state => "exc_pinned",
455 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
456 out => [ "in_r4 in_r5", "flags", "none" ] },
457 ins => [ "base", "index", "mem", "left", "right" ],
458 outs => [ "res", "flags", "M" ],
459 am => "source,binary",
460 emit => '. and%M %binop',
464 modified_flags => $status_flags
468 irn_flags => [ "rematerializable" ],
469 state => "exc_pinned",
470 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
471 ins => [ "base", "index", "mem", "val" ],
472 emit => '. and%M %SI3, %AM',
476 modified_flags => $status_flags
480 irn_flags => [ "rematerializable" ],
481 state => "exc_pinned",
482 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
483 ins => [ "base", "index", "mem", "val" ],
484 emit => '. and%M %SB3, %AM',
488 modified_flags => $status_flags
492 irn_flags => [ "rematerializable" ],
493 state => "exc_pinned",
494 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
495 out => [ "in_r4 in_r5", "flags", "none" ] },
496 ins => [ "base", "index", "mem", "left", "right" ],
497 outs => [ "res", "flags", "M" ],
498 am => "source,binary",
499 emit => '. or%M %binop',
503 modified_flags => $status_flags
507 irn_flags => [ "rematerializable" ],
508 state => "exc_pinned",
509 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
510 ins => [ "base", "index", "mem", "val" ],
511 emit => '. or%M %SI3, %AM',
515 modified_flags => $status_flags
519 irn_flags => [ "rematerializable" ],
520 state => "exc_pinned",
521 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
522 ins => [ "base", "index", "mem", "val" ],
523 emit => '. or%M %SB3, %AM',
527 modified_flags => $status_flags
531 irn_flags => [ "rematerializable" ],
532 state => "exc_pinned",
533 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
534 out => [ "in_r4 in_r5", "flags", "none" ] },
535 ins => [ "base", "index", "mem", "left", "right" ],
536 outs => [ "res", "flags", "M" ],
537 am => "source,binary",
538 emit => '. xor%M %binop',
542 modified_flags => $status_flags
546 op_flags => [ "constlike" ],
547 irn_flags => [ "rematerializable" ],
548 reg_req => { out => [ "gp", "flags" ] },
549 outs => [ "res", "flags" ],
550 emit => ". xor%M %D0, %D0",
554 modified_flags => $status_flags
558 irn_flags => [ "rematerializable" ],
559 state => "exc_pinned",
560 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
561 ins => [ "base", "index", "mem", "val" ],
562 emit => '. xor%M %SI3, %AM',
566 modified_flags => $status_flags
570 irn_flags => [ "rematerializable" ],
571 state => "exc_pinned",
572 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
573 ins => [ "base", "index", "mem", "val" ],
574 emit => '. xor%M %SB3, %AM',
578 modified_flags => $status_flags
582 irn_flags => [ "rematerializable" ],
583 state => "exc_pinned",
584 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
585 out => [ "in_r4", "flags", "none" ] },
586 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
587 outs => [ "res", "flags", "M" ],
588 am => "source,binary",
589 emit => '. sub%M %binop',
593 modified_flags => $status_flags
597 irn_flags => [ "rematerializable" ],
598 state => "exc_pinned",
599 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
600 ins => [ "base", "index", "mem", "subtrahend" ],
601 emit => '. sub%M %SI3, %AM',
605 modified_flags => $status_flags
609 irn_flags => [ "rematerializable" ],
610 state => "exc_pinned",
611 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
612 ins => [ "base", "index", "mem", "subtrahend" ],
613 emit => '. sub%M %SB3, %AM',
617 modified_flags => $status_flags
621 state => "exc_pinned",
622 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
623 out => [ "in_r4 !in_r5", "flags", "none" ] },
624 ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
625 outs => [ "res", "flags", "M" ],
626 am => "source,binary",
627 emit => '. sbb%M %binop',
631 modified_flags => $status_flags
635 # Spiller currently fails when rematerializing flag consumers
636 # irn_flags => [ "rematerializable" ],
637 reg_req => { in => [ "flags" ], out => [ "gp", "flags" ] },
638 outs => [ "res", "flags" ],
639 emit => ". sbb%M %D0, %D0",
643 modified_flags => $status_flags
647 reg_req => { in => [ "none", "none" ], out => [ "none" ] },
648 ins => [ "minuend", "subtrahend" ],
652 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
653 ins => [ "minuend", "subtrahend", "eflags" ],
657 op_flags => [ "fragile", "labeled" ],
658 state => "exc_pinned",
659 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
660 out => [ "eax", "flags", "none", "edx", "none" ] },
661 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
662 outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ],
663 am => "source,unary",
664 emit => ". idiv%M %unop3",
667 modified_flags => $status_flags
671 op_flags => [ "fragile", "labeled" ],
672 state => "exc_pinned",
673 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
674 out => [ "eax", "flags", "none", "edx", "none" ] },
675 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
676 outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ],
677 am => "source,unary",
678 emit => ". div%M %unop3",
681 modified_flags => $status_flags
685 irn_flags => [ "rematerializable" ],
686 reg_req => { in => [ "gp", "ecx" ],
687 out => [ "in_r1 !in_r2", "flags" ] },
688 ins => [ "val", "count" ],
689 outs => [ "res", "flags" ],
690 emit => '. shl%M %SB1, %S0',
694 modified_flags => $status_flags
698 irn_flags => [ "rematerializable" ],
699 state => "exc_pinned",
700 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
701 ins => [ "base", "index", "mem", "count" ],
702 emit => '. shl%M %SB3, %AM',
706 modified_flags => $status_flags
710 cmp_attr => "return 1;",
711 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
712 ins => [ "val", "count", "dep" ],
716 irn_flags => [ "rematerializable" ],
717 reg_req => { in => [ "gp", "gp", "ecx" ],
718 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
719 ins => [ "val_high", "val_low", "count" ],
720 outs => [ "res", "flags" ],
721 emit => ". shld%M %SB2, %S1, %D0",
725 modified_flags => $status_flags
729 cmp_attr => "return 1;",
730 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
731 ins => [ "val_high", "val_low", "count" ],
735 irn_flags => [ "rematerializable" ],
736 reg_req => { in => [ "gp", "ecx" ],
737 out => [ "in_r1 !in_r2", "flags" ] },
738 ins => [ "val", "count" ],
739 outs => [ "res", "flags" ],
740 emit => '. shr%M %SB1, %S0',
744 modified_flags => $status_flags
748 irn_flags => [ "rematerializable" ],
749 state => "exc_pinned",
750 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
751 ins => [ "base", "index", "mem", "count" ],
752 emit => '. shr%M %SB3, %AM',
756 modified_flags => $status_flags
760 cmp_attr => "return 1;",
761 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
762 ins => [ "val", "count", "dep" ],
766 irn_flags => [ "rematerializable" ],
767 reg_req => { in => [ "gp", "gp", "ecx" ],
768 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
769 ins => [ "val_high", "val_low", "count" ],
770 outs => [ "res", "flags" ],
771 emit => ". shrd%M %SB2, %S1, %D0",
775 modified_flags => $status_flags
779 cmp_attr => "return 1;",
780 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
781 ins => [ "val_high", "val_low", "count" ],
785 irn_flags => [ "rematerializable" ],
786 reg_req => { in => [ "gp", "ecx" ],
787 out => [ "in_r1 !in_r2", "flags" ] },
788 ins => [ "val", "count" ],
789 outs => [ "res", "flags" ],
790 emit => '. sar%M %SB1, %S0',
794 modified_flags => $status_flags
798 irn_flags => [ "rematerializable" ],
799 state => "exc_pinned",
800 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
801 ins => [ "base", "index", "mem", "count" ],
802 emit => '. sar%M %SB3, %AM',
806 modified_flags => $status_flags
810 cmp_attr => "return 1;",
811 ins => [ "val", "count", "dep" ],
812 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
816 irn_flags => [ "rematerializable" ],
817 reg_req => { in => [ "gp", "ecx" ],
818 out => [ "in_r1 !in_r2", "flags" ] },
819 ins => [ "val", "count" ],
820 outs => [ "res", "flags" ],
821 emit => '. ror%M %SB1, %S0',
825 modified_flags => $status_flags
829 irn_flags => [ "rematerializable" ],
830 state => "exc_pinned",
831 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
832 ins => [ "base", "index", "mem", "count" ],
833 emit => '. ror%M %SB3, %AM',
837 modified_flags => $status_flags
841 irn_flags => [ "rematerializable" ],
842 reg_req => { in => [ "gp", "ecx" ],
843 out => [ "in_r1 !in_r2", "flags" ] },
844 ins => [ "val", "count" ],
845 outs => [ "res", "flags" ],
846 emit => '. rol%M %SB1, %S0',
850 modified_flags => $status_flags
854 irn_flags => [ "rematerializable" ],
855 state => "exc_pinned",
856 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
857 ins => [ "base", "index", "mem", "count" ],
858 emit => '. rol%M %SB3, %AM',
862 modified_flags => $status_flags
866 irn_flags => [ "rematerializable" ],
867 reg_req => { in => [ "gp" ],
868 out => [ "in_r1", "flags" ] },
869 emit => '. neg%M %S0',
871 outs => [ "res", "flags" ],
875 modified_flags => $status_flags
879 irn_flags => [ "rematerializable" ],
880 state => "exc_pinned",
881 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
882 ins => [ "base", "index", "mem" ],
883 emit => '. neg%M %AM',
887 modified_flags => $status_flags
891 irn_flags => [ "rematerializable" ],
892 reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
893 outs => [ "low_res", "high_res" ],
896 modified_flags => $status_flags
901 irn_flags => [ "rematerializable" ],
902 reg_req => { in => [ "gp" ],
903 out => [ "in_r1", "flags" ] },
905 outs => [ "res", "flags" ],
906 emit => '. inc%M %S0',
910 modified_flags => $status_flags_wo_cf
914 irn_flags => [ "rematerializable" ],
915 state => "exc_pinned",
916 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
917 ins => [ "base", "index", "mem" ],
918 emit => '. inc%M %AM',
922 modified_flags => $status_flags_wo_cf
926 irn_flags => [ "rematerializable" ],
927 reg_req => { in => [ "gp" ],
928 out => [ "in_r1", "flags" ] },
930 outs => [ "res", "flags" ],
931 emit => '. dec%M %S0',
935 modified_flags => $status_flags_wo_cf
939 irn_flags => [ "rematerializable" ],
940 state => "exc_pinned",
941 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
942 ins => [ "base", "index", "mem" ],
943 emit => '. dec%M %AM',
947 modified_flags => $status_flags_wo_cf
951 irn_flags => [ "rematerializable" ],
952 reg_req => { in => [ "gp" ],
953 out => [ "in_r1" ] },
956 emit => '. not%M %S0',
964 irn_flags => [ "rematerializable" ],
965 state => "exc_pinned",
966 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
967 ins => [ "base", "index", "mem" ],
968 emit => '. not%M %AM',
976 reg_req => { in => [ "flags" ], out => [ "flags" ] },
981 modified_flags => $status_flags
985 reg_req => { out => [ "flags" ] },
990 modified_flags => $status_flags
994 irn_flags => [ "rematerializable" ],
995 state => "exc_pinned",
996 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
997 out => [ "flags", "none", "none" ] },
998 ins => [ "base", "index", "mem", "left", "right" ],
999 outs => [ "eflags", "unused", "M" ],
1000 am => "source,binary",
1001 emit => '. cmp%M %binop',
1002 attr => "int ins_permuted, int cmp_unsigned",
1003 init_attr => "attr->data.ins_permuted = ins_permuted;\n".
1004 "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
1007 mode => $mode_flags,
1008 modified_flags => $status_flags
1012 irn_flags => [ "rematerializable" ],
1013 state => "exc_pinned",
1014 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
1015 out => [ "flags", "none", "none" ] },
1016 ins => [ "base", "index", "mem", "left", "right" ],
1017 outs => [ "eflags", "unused", "M" ],
1018 am => "source,binary",
1019 emit => '. cmpb %binop',
1020 attr => "int ins_permuted, int cmp_unsigned",
1021 init_attr => "attr->data.ins_permuted = ins_permuted;\n".
1022 "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
1025 mode => $mode_flags,
1026 modified_flags => $status_flags
1030 irn_flags => [ "rematerializable" ],
1031 state => "exc_pinned",
1032 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] ,
1033 out => [ "flags", "none", "none" ] },
1034 ins => [ "base", "index", "mem", "left", "right" ],
1035 outs => [ "eflags", "unused", "M" ],
1036 am => "source,binary",
1037 emit => '. test%M %binop',
1038 attr => "int ins_permuted, int cmp_unsigned",
1039 init_attr => "attr->data.ins_permuted = ins_permuted;\n".
1040 "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
1043 mode => $mode_flags,
1044 modified_flags => $status_flags
1048 irn_flags => [ "rematerializable" ],
1049 state => "exc_pinned",
1050 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
1051 out => [ "flags", "none", "none" ] },
1052 ins => [ "base", "index", "mem", "left", "right" ],
1053 outs => [ "eflags", "unused", "M" ],
1054 am => "source,binary",
1055 emit => '. testb %binop',
1056 attr => "int ins_permuted, int cmp_unsigned",
1057 init_attr => "attr->data.ins_permuted = ins_permuted;\n".
1058 "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
1061 mode => $mode_flags,
1062 modified_flags => $status_flags
1066 #irn_flags => [ "rematerializable" ],
1067 reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
1068 ins => [ "eflags" ],
1070 attr_type => "ia32_condcode_attr_t",
1071 attr => "pn_Cmp pnc",
1072 # The way we handle Setcc with float nodes (potentially) destroys the flags
1073 # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
1074 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
1075 . "\tif ((pnc & ia32_pn_Cmp_float) && ((pnc & 0xf) != pn_Cmp_Uo) && ((pnc & 0xf) != pn_Cmp_Leg)) {\n"
1076 . "\t\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n"
1077 . "\t\t/* attr->latency = 3; */\n"
1085 #irn_flags => [ "rematerializable" ],
1086 state => "exc_pinned",
1087 reg_req => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
1088 ins => [ "base", "index", "mem","eflags" ],
1089 attr_type => "ia32_condcode_attr_t",
1090 attr => "pn_Cmp pnc",
1091 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
1092 emit => '. set%CMP3 %AM',
1099 #irn_flags => [ "rematerializable" ],
1100 state => "exc_pinned",
1101 # (note: leave the false,true order intact to make it compatible with other
1103 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
1104 out => [ "in_r4 in_r5", "flags", "none" ] },
1105 ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
1106 outs => [ "res", "flags", "M" ],
1107 am => "source,binary",
1108 attr_type => "ia32_condcode_attr_t",
1109 attr => "pn_Cmp pnc",
1117 op_flags => [ "labeled", "cfopcode", "forking" ],
1118 reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
1119 ins => [ "eflags" ],
1120 outs => [ "false", "true" ],
1121 attr_type => "ia32_condcode_attr_t",
1122 attr => "pn_Cmp pnc",
1124 units => [ "BRANCH" ],
1129 op_flags => [ "labeled", "cfopcode", "forking" ],
1130 reg_req => { in => [ "gp" ] },
1132 attr_type => "ia32_condcode_attr_t",
1135 units => [ "BRANCH" ],
1136 modified_flags => $status_flags,
1137 init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements
1142 irn_flags => [ "simple_jump" ],
1143 op_flags => [ "cfopcode" ],
1144 reg_req => { out => [ "none" ] },
1146 units => [ "BRANCH" ],
1152 op_flags => [ "cfopcode" ],
1153 reg_req => { in => [ "gp", "gp", "none", "gp" ] },
1154 ins => [ "base", "index", "mem", "target" ],
1155 am => "source,unary",
1156 emit => '. jmp *%unop3',
1158 units => [ "BRANCH" ],
1160 init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements
1164 op_flags => [ "constlike" ],
1165 irn_flags => [ "rematerializable" ],
1166 reg_req => { out => [ "gp" ] },
1168 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
1169 attr_type => "ia32_immediate_attr_t",
1175 op_flags => [ "constlike" ],
1176 irn_flags => [ "rematerializable" ],
1177 reg_req => { out => [ "gp" ] },
1184 op_flags => [ "constlike" ],
1185 reg_req => { out => [ "gp" ] },
1189 modified_flags => $status_flags,
1194 op_flags => [ "constlike", "dump_noblock", "dump_noinput" ],
1195 reg_req => { out => [ "gp_NOREG:I" ] },
1204 op_flags => [ "constlike", "dump_noblock", "dump_noinput" ],
1205 reg_req => { out => [ "vfp_NOREG:I" ] },
1210 attr_type => "ia32_x87_attr_t",
1215 op_flags => [ "constlike", "dump_noblock", "dump_noinput" ],
1216 reg_req => { out => [ "xmm_NOREG:I" ] },
1225 op_flags => [ "constlike" ],
1226 reg_req => { out => [ "fpcw:I" ] },
1230 modified_flags => $fpcw_flags
1234 op_flags => [ "fragile", "labeled" ],
1236 reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] },
1237 ins => [ "base", "index", "mem" ],
1239 emit => ". fldcw %AM",
1242 modified_flags => $fpcw_flags
1246 op_flags => [ "fragile", "labeled" ],
1248 reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1249 ins => [ "base", "index", "mem", "fpcw" ],
1251 emit => ". fnstcw %AM",
1257 op_flags => [ "fragile", "labeled" ],
1259 reg_req => { in => [ "fp_cw" ], out => [ "none" ] },
1267 # we should not rematrialize this node. It has very strict constraints.
1268 reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] },
1269 ins => [ "val", "clobbered" ],
1278 # Note that we add additional latency values depending on address mode, so a
1279 # lateny of 0 for load is correct
1282 op_flags => [ "fragile", "labeled" ],
1283 state => "exc_pinned",
1284 reg_req => { in => [ "gp", "gp", "none" ],
1285 out => [ "gp", "none", "none", "none" ] },
1286 ins => [ "base", "index", "mem" ],
1287 outs => [ "res", "unused", "M", "X_exc" ],
1289 emit => ". mov%EX%.l %AM, %D0",
1294 op_flags => [ "fragile", "labeled" ],
1295 state => "exc_pinned",
1296 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none", "none" ] },
1297 ins => [ "base", "index", "mem", "val" ],
1298 outs => [ "M", "X_exc" ],
1299 emit => '. mov%M %SI3, %AM',
1306 op_flags => [ "fragile", "labeled" ],
1307 state => "exc_pinned",
1308 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => ["none", "none" ] },
1309 ins => [ "base", "index", "mem", "val" ],
1310 outs => [ "M", "X_exc" ],
1311 emit => '. mov%M %SB3, %AM',
1318 irn_flags => [ "rematerializable" ],
1319 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1320 ins => [ "base", "index" ],
1321 emit => '. leal %AM, %D0',
1325 # lea doesn't modify the flags, but setting this seems advantageous since it
1326 # increases chances that the Lea is transformed back to an Add
1327 modified_flags => 1,
1331 state => "exc_pinned",
1332 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1333 ins => [ "base", "index", "mem", "val", "stack" ],
1334 emit => '. push%M %unop3',
1335 outs => [ "stack", "M" ],
1336 am => "source,unary",
1342 state => "exc_pinned",
1343 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1345 outs => [ "stack" ],
1346 emit => '. pushl %%eax',
1353 state => "exc_pinned",
1354 reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1355 ins => [ "mem", "stack" ],
1356 outs => [ "res", "M", "unused", "stack" ],
1357 emit => '. pop%M %D0',
1358 latency => 3, # Pop is more expensive than Push on Athlon
1363 state => "exc_pinned",
1364 reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1365 ins => [ "mem", "stack" ],
1366 outs => [ "res", "M", "unused", "stack" ],
1367 emit => '. pop%M %D0',
1368 latency => 3, # Pop is more expensive than Push on Athlon
1373 state => "exc_pinned",
1374 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1375 ins => [ "base", "index", "mem", "stack" ],
1376 outs => [ "unused0", "M", "unused1", "stack" ],
1377 emit => '. pop%M %AM',
1378 latency => 3, # Pop is more expensive than Push on Athlon
1383 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1385 outs => [ "frame", "stack", "M" ],
1391 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1393 outs => [ "frame", "stack" ],
1400 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1401 ins => [ "base", "index", "mem", "stack", "size" ],
1402 am => "source,binary",
1403 emit => '. addl %binop',
1405 outs => [ "stack", "M" ],
1407 modified_flags => $status_flags
1412 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1413 ins => [ "base", "index", "mem", "stack", "size" ],
1414 am => "source,binary",
1415 emit => ". subl %binop\n".
1416 ". movl %%esp, %D1",
1418 outs => [ "stack", "addr", "M" ],
1420 modified_flags => $status_flags
1424 op_flags => [ "keep" ],
1432 irn_flags => [ "rematerializable" ],
1433 reg_req => { out => [ "gp" ] },
1439 # BT supports source address mode, but this is unused yet
1442 irn_flags => [ "rematerializable" ],
1443 state => "exc_pinned",
1444 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1445 ins => [ "left", "right" ],
1446 emit => '. bt%M %S1, %S0',
1449 mode => $mode_flags,
1450 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1454 irn_flags => [ "rematerializable" ],
1455 state => "exc_pinned",
1456 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1457 out => [ "gp", "flags", "none" ] },
1458 ins => [ "base", "index", "mem", "operand" ],
1459 outs => [ "res", "flags", "M" ],
1460 am => "source,binary",
1461 emit => '. bsf%M %unop3, %D0',
1465 modified_flags => $status_flags
1469 irn_flags => [ "rematerializable" ],
1470 state => "exc_pinned",
1471 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1472 out => [ "gp", "flags", "none" ] },
1473 ins => [ "base", "index", "mem", "operand" ],
1474 outs => [ "res", "flags", "M" ],
1475 am => "source,binary",
1476 emit => '. bsr%M %unop3, %D0',
1480 modified_flags => $status_flags
1484 # SSE4.2 or SSE4a popcnt instruction
1487 irn_flags => [ "rematerializable" ],
1488 state => "exc_pinned",
1489 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1490 out => [ "gp", "flags", "none" ] },
1491 ins => [ "base", "index", "mem", "operand" ],
1492 outs => [ "res", "flags", "M" ],
1493 am => "source,binary",
1494 emit => '. popcnt%M %unop3, %D0',
1498 modified_flags => $status_flags
1502 state => "exc_pinned",
1504 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1505 out => [ "esp:I|S", "fpcw:I", "none", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" ]
1507 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1508 outs => [ "stack", "fpcw", "M", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" ],
1509 attr_type => "ia32_call_attr_t",
1510 attr => "unsigned pop, ir_type *call_tp",
1511 am => "source,unary",
1512 units => [ "BRANCH" ],
1513 latency => 4, # random number
1514 modified_flags => $status_flags
1518 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1520 # PS: try gcc __builtin_frame_address(100000) :-)
1523 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1524 ins => [ "frame", "cnt", "tmp" ],
1526 latency => 4, # random number
1527 attr_type => "ia32_climbframe_attr_t",
1528 attr => "unsigned count",
1537 irn_flags => [ "rematerializable" ],
1538 reg_req => { in => [ "gp" ],
1539 out => [ "in_r1" ] },
1540 emit => '. bswap%M %S0',
1548 # bswap16, use xchg here
1551 irn_flags => [ "rematerializable" ],
1552 reg_req => { in => [ "eax ebx ecx edx" ],
1553 out => [ "in_r1" ] },
1554 emit => '. xchg %SB0, %SH0',
1566 reg_req => { in => [ "none" ], out => [ "none" ] },
1575 # Undefined Instruction on ALL x86 CPU's
1579 reg_req => { in => [ "none" ], out => [ "none" ] },
1582 emit => ". .value 0x0b0f",
1591 irn_flags => [ "rematerializable" ],
1593 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1594 ins => [ "port", "value", "mem" ],
1595 emit => '. out%M %SS0, %SI1',
1599 modified_flags => $status_flags
1606 irn_flags => [ "rematerializable" ],
1608 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1609 ins => [ "port", "mem" ],
1610 outs => [ "res", "M" ],
1611 emit => '. in%M %DS0, %SS0',
1615 modified_flags => $status_flags
1619 # Intel style prefetching
1622 op_flags => [ "fragile", "labeled" ],
1623 state => "exc_pinned",
1624 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1625 ins => [ "base", "index", "mem" ],
1628 emit => ". prefetcht0 %AM",
1633 op_flags => [ "fragile", "labeled" ],
1634 state => "exc_pinned",
1635 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1636 ins => [ "base", "index", "mem" ],
1639 emit => ". prefetcht1 %AM",
1644 op_flags => [ "fragile", "labeled" ],
1645 state => "exc_pinned",
1646 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1647 ins => [ "base", "index", "mem" ],
1650 emit => ". prefetcht2 %AM",
1655 op_flags => [ "fragile", "labeled" ],
1656 state => "exc_pinned",
1657 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1658 ins => [ "base", "index", "mem" ],
1661 emit => ". prefetchnta %AM",
1666 # 3DNow! prefetch instructions
1669 op_flags => [ "fragile", "labeled" ],
1670 state => "exc_pinned",
1671 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1672 ins => [ "base", "index", "mem" ],
1675 emit => ". prefetch %AM",
1680 op_flags => [ "fragile", "labeled" ],
1681 state => "exc_pinned",
1682 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1683 ins => [ "base", "index", "mem" ],
1686 emit => ". prefetchw %AM",
1692 irn_flags => [ "rematerializable" ],
1693 reg_req => { out => [ "xmm" ] },
1694 emit => '. xorp%XSD %D0, %D0',
1701 op_flags => [ "constlike" ],
1702 irn_flags => [ "rematerializable" ],
1703 reg_req => { out => [ "xmm" ] },
1710 irn_flags => [ "rematerializable" ],
1711 reg_req => { out => [ "xmm" ] },
1712 emit => '. pxor %D0, %D0',
1718 # produces all 1 bits
1720 irn_flags => [ "rematerializable" ],
1721 reg_req => { out => [ "xmm" ] },
1722 emit => '. pcmpeqb %D0, %D0',
1728 # integer shift left, dword
1730 irn_flags => [ "rematerializable" ],
1731 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1732 emit => '. pslld %SI1, %D0',
1738 # integer shift left, qword
1740 irn_flags => [ "rematerializable" ],
1741 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1742 emit => '. psllq %SI1, %D0',
1748 # integer shift right, dword
1750 irn_flags => [ "rematerializable" ],
1751 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1752 emit => '. psrld %SI1, %D0',
1758 # mov from integer to SSE register
1760 irn_flags => [ "rematerializable" ],
1761 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1762 emit => '. movd %S0, %D0',
1769 irn_flags => [ "rematerializable" ],
1770 state => "exc_pinned",
1771 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1772 out => [ "in_r4 in_r5", "flags", "none" ] },
1773 ins => [ "base", "index", "mem", "left", "right" ],
1774 outs => [ "res", "flags", "M" ],
1775 am => "source,binary",
1776 emit => '. add%XXM %binop',
1783 irn_flags => [ "rematerializable" ],
1784 state => "exc_pinned",
1785 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1786 out => [ "in_r4 in_r5", "flags", "none" ] },
1787 ins => [ "base", "index", "mem", "left", "right" ],
1788 outs => [ "res", "flags", "M" ],
1789 am => "source,binary",
1790 emit => '. mul%XXM %binop',
1797 irn_flags => [ "rematerializable" ],
1798 state => "exc_pinned",
1799 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1800 out => [ "in_r4 in_r5", "flags", "none" ] },
1801 ins => [ "base", "index", "mem", "left", "right" ],
1802 outs => [ "res", "flags", "M" ],
1803 am => "source,binary",
1804 emit => '. max%XXM %binop',
1811 irn_flags => [ "rematerializable" ],
1812 state => "exc_pinned",
1813 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1814 out => [ "in_r4 in_r5", "flags", "none" ] },
1815 ins => [ "base", "index", "mem", "left", "right" ],
1816 outs => [ "res", "flags", "M" ],
1817 am => "source,binary",
1818 emit => '. min%XXM %binop',
1825 irn_flags => [ "rematerializable" ],
1826 state => "exc_pinned",
1827 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1828 out => [ "in_r4 in_r5", "flags", "none" ] },
1829 ins => [ "base", "index", "mem", "left", "right" ],
1830 outs => [ "res", "flags", "M" ],
1831 am => "source,binary",
1832 emit => '. andp%XSD %binop',
1839 irn_flags => [ "rematerializable" ],
1840 state => "exc_pinned",
1841 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1842 out => [ "in_r4 in_r5", "flags", "none" ] },
1843 ins => [ "base", "index", "mem", "left", "right" ],
1844 outs => [ "res", "flags", "M" ],
1845 am => "source,binary",
1846 emit => '. orp%XSD %binop',
1853 irn_flags => [ "rematerializable" ],
1854 state => "exc_pinned",
1855 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1856 out => [ "in_r4 in_r5", "flags", "none" ] },
1857 ins => [ "base", "index", "mem", "left", "right" ],
1858 outs => [ "res", "flags", "M" ],
1859 am => "source,binary",
1860 emit => '. xorp%XSD %binop',
1867 irn_flags => [ "rematerializable" ],
1868 state => "exc_pinned",
1869 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1870 out => [ "in_r4 !in_r5", "flags", "none" ] },
1871 ins => [ "base", "index", "mem", "left", "right" ],
1872 outs => [ "res", "flags", "M" ],
1873 am => "source,binary",
1874 emit => '. andnp%XSD %binop',
1881 irn_flags => [ "rematerializable" ],
1882 state => "exc_pinned",
1883 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1884 out => [ "in_r4", "flags", "none" ] },
1885 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1886 outs => [ "res", "flags", "M" ],
1887 am => "source,binary",
1888 emit => '. sub%XXM %binop',
1895 irn_flags => [ "rematerializable" ],
1896 state => "exc_pinned",
1897 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1898 out => [ "in_r4 !in_r5", "flags", "none" ] },
1899 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1900 outs => [ "res", "flags", "M" ],
1901 am => "source,binary",
1902 emit => '. div%XXM %binop',
1908 irn_flags => [ "rematerializable" ],
1909 state => "exc_pinned",
1910 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1911 out => [ "eflags" ] },
1912 ins => [ "base", "index", "mem", "left", "right" ],
1913 outs => [ "flags" ],
1914 am => "source,binary",
1915 attr => "int ins_permuted",
1916 init_attr => "attr->data.ins_permuted = ins_permuted;",
1917 emit => ' .ucomi%XXM %binop',
1920 mode => $mode_flags,
1921 modified_flags => 1,
1925 op_flags => [ "fragile", "labeled" ],
1926 state => "exc_pinned",
1927 reg_req => { in => [ "gp", "gp", "none" ],
1928 out => [ "xmm", "none", "none", "none" ] },
1929 ins => [ "base", "index", "mem" ],
1930 outs => [ "res", "unused", "M", "X_exc" ],
1931 emit => '. mov%XXM %AM, %D0',
1932 attr => "ir_mode *load_mode",
1933 init_attr => "attr->ls_mode = load_mode;",
1939 op_flags => [ "fragile", "labeled" ],
1940 state => "exc_pinned",
1941 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "none", "none" ] },
1942 ins => [ "base", "index", "mem", "val" ],
1943 outs => [ "M", "X_exc" ],
1944 emit => '. mov%XXM %S3, %AM',
1951 op_flags => [ "fragile", "labeled" ],
1952 state => "exc_pinned",
1953 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "none" ] },
1954 ins => [ "base", "index", "mem", "val" ],
1956 emit => '. mov%XXM %S3, %AM',
1963 op_flags => [ "fragile", "labeled" ],
1964 state => "exc_pinned",
1965 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1966 ins => [ "base", "index", "mem", "val" ],
1967 am => "source,unary",
1968 emit => '. cvtsi2ss %unop3, %D0',
1975 op_flags => [ "fragile", "labeled" ],
1976 state => "exc_pinned",
1977 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1978 ins => [ "base", "index", "mem", "val" ],
1979 am => "source,unary",
1980 emit => '. cvtsi2sd %unop3, %D0',
1988 op_flags => [ "fragile", "labeled" ],
1989 cmp_attr => "return 1;",
1990 ins => [ "val_high", "val_low" ],
1991 reg_req => { in => [ "none", "none" ], out => [ "none" ] }
1995 op_flags => [ "fragile", "labeled" ],
1996 cmp_attr => "return 1;",
1998 outs => [ "res_high", "res_low" ],
1999 reg_req => { in => [ "none" ], out => [ "none", "none" ] }
2003 op_flags => [ "fragile" ],
2005 reg_req => { in => [ "edi", "esi", "ecx", "none" ], out => [ "edi", "esi", "ecx", "none" ] },
2006 outs => [ "DST", "SRC", "CNT", "M" ],
2007 attr_type => "ia32_copyb_attr_t",
2008 attr => "unsigned size",
2011 # we don't care about this flag, so no need to mark this node
2012 # modified_flags => [ "DF" ]
2016 op_flags => [ "fragile" ],
2018 reg_req => { in => [ "edi", "esi", "none" ], out => [ "edi", "esi", "none" ] },
2019 outs => [ "DST", "SRC", "M" ],
2020 attr_type => "ia32_copyb_attr_t",
2021 attr => "unsigned size",
2024 # we don't care about this flag, so no need to mark this node
2025 # modified_flags => [ "DF" ]
2029 state => "exc_pinned",
2030 reg_req => { in => [ "eax" ], out => [ "eax" ] },
2040 state => "exc_pinned",
2041 reg_req => { in => [ "gp", "gp", "none", "gp" ],
2042 out => [ "gp", "none", "none" ] },
2043 ins => [ "base", "index", "mem", "val" ],
2044 outs => [ "res", "flags", "M" ],
2045 am => "source,unary",
2048 attr => "ir_mode *smaller_mode",
2049 init_attr => "attr->ls_mode = smaller_mode;",
2054 state => "exc_pinned",
2055 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
2056 out => [ "gp", "none", "none" ] },
2057 ins => [ "base", "index", "mem", "val" ],
2058 outs => [ "res", "flags", "M" ],
2059 am => "source,unary",
2062 attr => "ir_mode *smaller_mode",
2063 init_attr => "attr->ls_mode = smaller_mode;",
2068 state => "exc_pinned",
2069 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
2070 ins => [ "base", "index", "mem", "val" ],
2071 am => "source,unary",
2078 state => "exc_pinned",
2079 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
2080 ins => [ "base", "index", "mem", "val" ],
2081 am => "source,unary",
2088 state => "exc_pinned",
2089 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
2090 ins => [ "base", "index", "mem", "val" ],
2091 am => "source,unary",
2097 # rematerialisation disabled for all float nodes for now, because the fpcw
2098 # handler runs before spilling and we might end up with wrong fpcw then
2101 # irn_flags => [ "rematerializable" ],
2102 state => "exc_pinned",
2103 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2104 out => [ "vfp", "none", "none" ] },
2105 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2106 outs => [ "res", "dummy", "M" ],
2107 am => "source,binary",
2111 attr_type => "ia32_x87_attr_t",
2115 # irn_flags => [ "rematerializable" ],
2116 state => "exc_pinned",
2117 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2118 out => [ "vfp", "none", "none" ] },
2119 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2120 outs => [ "res", "dummy", "M" ],
2121 am => "source,binary",
2125 attr_type => "ia32_x87_attr_t",
2129 # irn_flags => [ "rematerializable" ],
2130 state => "exc_pinned",
2131 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2132 out => [ "vfp", "none", "none" ] },
2133 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2134 outs => [ "res", "dummy", "M" ],
2135 am => "source,binary",
2139 attr_type => "ia32_x87_attr_t",
2143 state => "exc_pinned",
2144 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2145 out => [ "vfp", "none", "none" ] },
2146 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2147 outs => [ "res", "dummy", "M" ],
2148 am => "source,binary",
2151 attr_type => "ia32_x87_attr_t",
2155 reg_req => { in => [ "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
2156 ins => [ "left", "right", "fpcw" ],
2160 attr_type => "ia32_x87_attr_t",
2164 irn_flags => [ "rematerializable" ],
2165 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2170 attr_type => "ia32_x87_attr_t",
2174 irn_flags => [ "rematerializable" ],
2175 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2180 attr_type => "ia32_x87_attr_t",
2184 irn_flags => [ "rematerializable" ],
2185 op_flags => [ "fragile", "labeled" ],
2186 state => "exc_pinned",
2187 reg_req => { in => [ "gp", "gp", "none" ],
2188 out => [ "vfp", "none", "none", "none" ] },
2189 ins => [ "base", "index", "mem" ],
2190 outs => [ "res", "unused", "M", "X_exc" ],
2191 attr => "ir_mode *load_mode",
2192 init_attr => "attr->attr.ls_mode = load_mode;",
2195 attr_type => "ia32_x87_attr_t",
2199 irn_flags => [ "rematerializable" ],
2200 op_flags => [ "fragile", "labeled" ],
2201 state => "exc_pinned",
2202 reg_req => { in => [ "gp", "gp", "none", "vfp" ],
2203 out => [ "none", "none" ] },
2204 ins => [ "base", "index", "mem", "val" ],
2205 outs => [ "M", "X_exc" ],
2206 attr => "ir_mode *store_mode",
2207 init_attr => "attr->attr.ls_mode = store_mode;",
2211 attr_type => "ia32_x87_attr_t",
2215 state => "exc_pinned",
2216 reg_req => { in => [ "gp", "gp", "none" ],
2217 out => [ "vfp", "none", "none" ] },
2218 outs => [ "res", "unused", "M" ],
2219 ins => [ "base", "index", "mem" ],
2222 attr_type => "ia32_x87_attr_t",
2226 state => "exc_pinned",
2227 reg_req => { in => [ "gp", "gp", "none", "vfp", "fpcw" ], out => [ "none" ] },
2228 ins => [ "base", "index", "mem", "val", "fpcw" ],
2233 attr_type => "ia32_x87_attr_t",
2236 # SSE3 fisttp instruction
2238 state => "exc_pinned",
2239 reg_req => { in => [ "gp", "gp", "none", "vfp" ], out => [ "in_r4", "none" ]},
2240 ins => [ "base", "index", "mem", "val" ],
2241 outs => [ "res", "M" ],
2244 attr_type => "ia32_x87_attr_t",
2248 irn_flags => [ "rematerializable" ],
2249 reg_req => { out => [ "vfp" ] },
2254 attr_type => "ia32_x87_attr_t",
2258 irn_flags => [ "rematerializable" ],
2259 reg_req => { out => [ "vfp" ] },
2264 attr_type => "ia32_x87_attr_t",
2268 irn_flags => [ "rematerializable" ],
2269 reg_req => { out => [ "vfp" ] },
2274 attr_type => "ia32_x87_attr_t",
2278 irn_flags => [ "rematerializable" ],
2279 reg_req => { out => [ "vfp" ] },
2284 attr_type => "ia32_x87_attr_t",
2288 irn_flags => [ "rematerializable" ],
2289 reg_req => { out => [ "vfp" ] },
2294 attr_type => "ia32_x87_attr_t",
2298 irn_flags => [ "rematerializable" ],
2299 reg_req => { out => [ "vfp" ] },
2304 attr_type => "ia32_x87_attr_t",
2308 irn_flags => [ "rematerializable" ],
2309 reg_req => { out => [ "vfp" ] },
2314 attr_type => "ia32_x87_attr_t",
2318 # we can't allow to rematerialize this node so we don't
2319 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2320 # irn_flags => [ "rematerializable" ],
2321 reg_req => { in => [ "vfp", "vfp" ], out => [ "eax" ] },
2322 ins => [ "left", "right" ],
2323 outs => [ "flags" ],
2324 attr => "int ins_permuted",
2325 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2328 attr_type => "ia32_x87_attr_t",
2333 irn_flags => [ "rematerializable" ],
2334 reg_req => { in => [ "vfp", "vfp" ], out => [ "eflags" ] },
2335 ins => [ "left", "right" ],
2336 outs => [ "flags" ],
2337 attr => "int ins_permuted",
2338 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2341 attr_type => "ia32_x87_attr_t",
2346 # irn_flags => [ "rematerializable" ],
2347 reg_req => { in => [ "vfp" ], out => [ "eax" ] },
2349 outs => [ "flags" ],
2350 attr => "int ins_permuted",
2351 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2354 attr_type => "ia32_x87_attr_t",
2359 irn_flags => [ "rematerializable" ],
2360 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2362 outs => [ "flags" ],
2366 mode => $mode_flags,
2370 state => "exc_pinned",
2371 emit => '. fadd%XM %x87_binop',
2373 attr_type => "ia32_x87_attr_t",
2378 state => "exc_pinned",
2379 emit => '. faddp%XM %x87_binop',
2381 attr_type => "ia32_x87_attr_t",
2386 state => "exc_pinned",
2387 emit => '. fmul%XM %x87_binop',
2389 attr_type => "ia32_x87_attr_t",
2394 state => "exc_pinned",
2395 emit => '. fmulp%XM %x87_binop',,
2397 attr_type => "ia32_x87_attr_t",
2402 state => "exc_pinned",
2403 emit => '. fsub%XM %x87_binop',
2405 attr_type => "ia32_x87_attr_t",
2409 # Note: gas is strangely buggy: fdivrp and fdivp as well as fsubrp and fsubp
2410 # are swapped, we work this around in the emitter...
2413 state => "exc_pinned",
2414 # see note about gas bugs
2415 emit => '. fsubrp%XM %x87_binop',
2417 attr_type => "ia32_x87_attr_t",
2422 state => "exc_pinned",
2423 irn_flags => [ "rematerializable" ],
2424 emit => '. fsubr%XM %x87_binop',
2426 attr_type => "ia32_x87_attr_t",
2431 state => "exc_pinned",
2432 irn_flags => [ "rematerializable" ],
2433 # see note about gas bugs before fsubp
2434 emit => '. fsubp%XM %x87_binop',
2436 attr_type => "ia32_x87_attr_t",
2443 attr_type => "ia32_x87_attr_t",
2447 # this node is just here, to keep the simulator running
2448 # we can omit this when a fprem simulation function exists
2450 emit => '. fprem1\n'.
2453 attr_type => "ia32_x87_attr_t",
2458 state => "exc_pinned",
2459 emit => '. fdiv%XM %x87_binop',
2461 attr_type => "ia32_x87_attr_t",
2466 state => "exc_pinned",
2467 # see note about gas bugs before fsubp
2468 emit => '. fdivrp%XM %x87_binop',
2470 attr_type => "ia32_x87_attr_t",
2475 state => "exc_pinned",
2476 emit => '. fdivr%XM %x87_binop',
2478 attr_type => "ia32_x87_attr_t",
2483 state => "exc_pinned",
2484 # see note about gas bugs before fsubp
2485 emit => '. fdivp%XM %x87_binop',
2487 attr_type => "ia32_x87_attr_t",
2494 attr_type => "ia32_x87_attr_t",
2499 op_flags => [ "keep" ],
2500 irn_flags => [ "rematerializable" ],
2503 attr_type => "ia32_x87_attr_t",
2508 irn_flags => [ "rematerializable" ],
2509 op_flags => [ "fragile", "labeled" ],
2510 state => "exc_pinned",
2511 emit => '. fld%XM %AM',
2512 attr_type => "ia32_x87_attr_t",
2518 irn_flags => [ "rematerializable" ],
2519 op_flags => [ "fragile", "labeled" ],
2520 state => "exc_pinned",
2521 emit => '. fst%XM %AM',
2523 attr_type => "ia32_x87_attr_t",
2529 irn_flags => [ "rematerializable" ],
2530 op_flags => [ "fragile", "labeled" ],
2531 state => "exc_pinned",
2532 emit => '. fstp%XM %AM',
2534 attr_type => "ia32_x87_attr_t",
2540 state => "exc_pinned",
2541 emit => '. fild%XM %AM',
2542 attr_type => "ia32_x87_attr_t",
2548 state => "exc_pinned",
2549 emit => '. fist%XM %AM',
2551 attr_type => "ia32_x87_attr_t",
2557 state => "exc_pinned",
2558 emit => '. fistp%XM %AM',
2560 attr_type => "ia32_x87_attr_t",
2565 # SSE3 fisttp instruction
2567 state => "exc_pinned",
2568 emit => '. fisttp%XM %AM',
2570 attr_type => "ia32_x87_attr_t",
2576 op_flags => [ "constlike", "keep" ],
2577 irn_flags => [ "rematerializable" ],
2578 reg_req => { out => [ "vfp" ] },
2580 attr_type => "ia32_x87_attr_t",
2585 op_flags => [ "constlike", "keep" ],
2586 irn_flags => [ "rematerializable" ],
2587 reg_req => { out => [ "vfp" ] },
2589 attr_type => "ia32_x87_attr_t",
2594 op_flags => [ "constlike", "keep" ],
2595 irn_flags => [ "rematerializable" ],
2596 reg_req => { out => [ "vfp" ] },
2598 attr_type => "ia32_x87_attr_t",
2603 op_flags => [ "constlike", "keep" ],
2604 irn_flags => [ "rematerializable" ],
2605 reg_req => { out => [ "vfp" ] },
2607 attr_type => "ia32_x87_attr_t",
2612 op_flags => [ "constlike", "keep" ],
2613 irn_flags => [ "rematerializable" ],
2614 reg_req => { out => [ "vfp" ] },
2616 attr_type => "ia32_x87_attr_t",
2621 op_flags => [ "constlike", "keep" ],
2622 irn_flags => [ "rematerializable" ],
2623 reg_req => { out => [ "vfp" ] },
2624 emit => '. fldll2t',
2625 attr_type => "ia32_x87_attr_t",
2630 op_flags => [ "constlike", "keep" ],
2631 irn_flags => [ "rematerializable" ],
2632 reg_req => { out => [ "vfp" ] },
2634 attr_type => "ia32_x87_attr_t",
2639 # Note that it is NEVER allowed to do CSE on these nodes
2640 # Moreover, note the virtual register requierements!
2643 op_flags => [ "keep" ],
2644 reg_req => { out => [ "none" ] },
2645 cmp_attr => "return 1;",
2646 emit => '. fxch %X0',
2647 attr_type => "ia32_x87_attr_t",
2653 op_flags => [ "keep" ],
2654 reg_req => { out => [ "none" ] },
2655 cmp_attr => "return 1;",
2656 emit => '. fld %X0',
2657 attr_type => "ia32_x87_attr_t",
2663 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2664 cmp_attr => "return 1;",
2665 emit => '. fld %X0',
2666 attr_type => "ia32_x87_attr_t",
2671 op_flags => [ "keep" ],
2672 reg_req => { out => [ "none" ] },
2673 cmp_attr => "return 1;",
2674 emit => '. fstp %X0',
2675 attr_type => "ia32_x87_attr_t",
2681 op_flags => [ "keep" ],
2682 reg_req => { out => [ "none" ] },
2683 cmp_attr => "return 1;",
2684 emit => '. ffreep %X0',
2685 attr_type => "ia32_x87_attr_t",
2691 op_flags => [ "keep" ],
2692 reg_req => { out => [ "none" ] },
2693 cmp_attr => "return 1;",
2695 attr_type => "ia32_x87_attr_t",
2701 op_flags => [ "keep" ],
2702 reg_req => { out => [ "none" ] },
2703 cmp_attr => "return 1;",
2705 attr_type => "ia32_x87_attr_t",
2712 emit => ". fucom %X1\n".
2714 attr_type => "ia32_x87_attr_t",
2720 emit => ". fucomp %X1\n".
2722 attr_type => "ia32_x87_attr_t",
2728 emit => ". fucompp\n".
2730 attr_type => "ia32_x87_attr_t",
2736 emit => '. fucomi %X1',
2737 attr_type => "ia32_x87_attr_t",
2743 emit => '. fucompi %X1',
2744 attr_type => "ia32_x87_attr_t",
2752 attr_type => "ia32_x87_attr_t",
2756 # Spilling and reloading of SSE registers, hardcoded, not generated #
2759 op_flags => [ "fragile", "labeled" ],
2760 state => "exc_pinned",
2761 reg_req => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none" ] },
2762 emit => '. movdqu %D0, %AM',
2763 outs => [ "res", "M" ],
2769 op_flags => [ "fragile", "labeled" ],
2770 state => "exc_pinned",
2771 reg_req => { in => [ "gp", "gp", "none", "xmm" ] },
2772 ins => [ "base", "index", "mem", "val" ],
2773 emit => '. movdqu %binop',
2781 # Transform some attributes
2782 foreach my $op (keys(%nodes)) {
2783 my $node = $nodes{$op};
2784 my $op_attr_init = $node->{op_attr_init};
2786 if(defined($op_attr_init)) {
2787 $op_attr_init .= "\n\t";
2792 if(!defined($node->{latency})) {
2794 $node->{latency} = 0;
2796 die("Latency missing for op $op");
2799 $op_attr_init .= "attr->latency = ".$node->{latency} . ";";
2801 $node->{op_attr_init} = $op_attr_init;