3 # This is the specification for the ia32 assembler Firm-operations
8 $normal = 0; # no special type
9 $caller_save = 1; # caller save (register must be saved by the caller of a function)
10 $callee_save = 2; # callee save (register must be saved by the called function)
11 $ignore = 4; # ignore (do not assign this register)
12 $arbitrary = 8; # emitter can choose an arbitrary register of this class
13 $virtual = 16; # the register is a virtual one
14 $state = 32; # register represents a state
15 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
18 { name => "edx", type => $caller_save },
19 { name => "ecx", type => $caller_save },
20 { name => "eax", type => $caller_save },
21 { name => "ebx", type => $callee_save },
22 { name => "esi", type => $callee_save },
23 { name => "edi", type => $callee_save },
24 { name => "ebp", type => $callee_save },
25 { name => "esp", type => $ignore },
26 { name => "gp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
30 { name => "mm0", type => $ignore },
31 { name => "mm1", type => $ignore },
32 { name => "mm2", type => $ignore },
33 { name => "mm3", type => $ignore },
34 { name => "mm4", type => $ignore },
35 { name => "mm5", type => $ignore },
36 { name => "mm6", type => $ignore },
37 { name => "mm7", type => $ignore },
38 { mode => "mode_E", flags => "manual_ra" }
41 { name => "xmm0", type => $caller_save },
42 { name => "xmm1", type => $caller_save },
43 { name => "xmm2", type => $caller_save },
44 { name => "xmm3", type => $caller_save },
45 { name => "xmm4", type => $caller_save },
46 { name => "xmm5", type => $caller_save },
47 { name => "xmm6", type => $caller_save },
48 { name => "xmm7", type => $caller_save },
49 { name => "xmm_NOREG", type => $ignore | $virtual }, # we need a dummy register for NoReg nodes
53 { name => "vf0", type => $caller_save },
54 { name => "vf1", type => $caller_save },
55 { name => "vf2", type => $caller_save },
56 { name => "vf3", type => $caller_save },
57 { name => "vf4", type => $caller_save },
58 { name => "vf5", type => $caller_save },
59 { name => "vf6", type => $caller_save },
60 { name => "vf7", type => $caller_save },
61 { name => "vfp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
65 { name => "st0", realname => "st", type => $ignore },
66 { name => "st1", realname => "st(1)", type => $ignore },
67 { name => "st2", realname => "st(2)", type => $ignore },
68 { name => "st3", realname => "st(3)", type => $ignore },
69 { name => "st4", realname => "st(4)", type => $ignore },
70 { name => "st5", realname => "st(5)", type => $ignore },
71 { name => "st6", realname => "st(6)", type => $ignore },
72 { name => "st7", realname => "st(7)", type => $ignore },
73 { mode => "mode_E", flags => "manual_ra" }
75 fp_cw => [ # the floating point control word
76 { name => "fpcw", type => $ignore | $state },
77 { mode => "mode_fpcw", flags => "manual_ra|state" }
80 { name => "eflags", type => 0 },
81 { mode => "mode_Iu", flags => "manual_ra" }
86 GP => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
87 SSE => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
88 VFP => [ 1, "VFP_VF0", "VFP_VF1", "VFP_VF2", "VFP_VF3", "VFP_VF4", "VFP_VF5", "VFP_VF6", "VFP_VF7" ],
89 BRANCH => [ 1, "BRANCH1", "BRANCH2" ],
94 bundels_per_cycle => 1
98 S0 => "${arch}_emit_source_register(node, 0);",
99 S1 => "${arch}_emit_source_register(node, 1);",
100 S2 => "${arch}_emit_source_register(node, 2);",
101 S3 => "${arch}_emit_source_register(node, 3);",
102 SB0 => "${arch}_emit_8bit_source_register_or_immediate(node, 0);",
103 SB1 => "${arch}_emit_8bit_source_register_or_immediate(node, 1);",
104 SB2 => "${arch}_emit_8bit_source_register_or_immediate(node, 2);",
105 SB3 => "${arch}_emit_8bit_source_register_or_immediate(node, 3);",
106 SH0 => "${arch}_emit_8bit_high_source_register(node, 0);",
107 SS0 => "${arch}_emit_16bit_source_register_or_immediate(node, 0);",
108 SI0 => "${arch}_emit_source_register_or_immediate(node, 0);",
109 SI1 => "${arch}_emit_source_register_or_immediate(node, 1);",
110 SI3 => "${arch}_emit_source_register_or_immediate(node, 3);",
111 D0 => "${arch}_emit_dest_register(node, 0);",
112 D1 => "${arch}_emit_dest_register(node, 1);",
113 DS0 => "${arch}_emit_dest_register_size(node, 0);",
114 DB0 => "${arch}_emit_8bit_dest_register(node, 0);",
115 X0 => "${arch}_emit_x87_register(node, 0);",
116 X1 => "${arch}_emit_x87_register(node, 1);",
117 EX => "${arch}_emit_extend_suffix(node);",
118 M => "${arch}_emit_mode_suffix(node);",
119 XM => "${arch}_emit_x87_mode_suffix(node);",
120 XXM => "${arch}_emit_xmm_mode_suffix(node);",
121 XSD => "${arch}_emit_xmm_mode_suffix_s(node);",
122 AM => "${arch}_emit_am(node);",
123 unop3 => "${arch}_emit_unop(node, n_ia32_unary_op);",
124 unop4 => "${arch}_emit_unop(node, n_ia32_binary_right);",
125 binop => "${arch}_emit_binop(node);",
126 x87_binop => "${arch}_emit_x87_binop(node);",
127 CMP3 => "${arch}_emit_cmp_suffix_node(node, 3);",
133 $default_op_attr_type = "ia32_op_attr_t";
134 $default_attr_type = "ia32_attr_t";
135 $default_copy_attr = "ia32_copy_attr";
137 sub ia32_custom_init_attr {
143 if(defined($node->{modified_flags})) {
144 $res .= "\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n";
146 if(defined($node->{am})) {
147 my $am = $node->{am};
148 if($am eq "source,unary") {
149 $res .= "\tset_ia32_am_support(res, ia32_am_unary);";
150 } elsif($am eq "source,binary") {
151 $res .= "\tset_ia32_am_support(res, ia32_am_binary);";
152 } elsif($am eq "none") {
155 die("Invalid address mode '$am' specified on op $name");
158 if($node->{state} ne "exc_pinned"
159 and $node->{state} ne "pinned") {
160 die("AM nodes must have pinned or AM pinned state ($name)");
166 $custom_init_attr_func = \&ia32_custom_init_attr;
170 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
171 "\tinit_ia32_x87_attributes(res);".
172 "\tinit_ia32_asm_attributes(res);",
174 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);",
176 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
177 "\tinit_ia32_call_attributes(res, pop, call_tp);",
178 ia32_condcode_attr_t =>
179 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
180 "\tinit_ia32_condcode_attributes(res, pnc);",
182 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
183 "\tinit_ia32_copyb_attributes(res, size);",
184 ia32_immediate_attr_t =>
185 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
186 "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
188 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
189 "\tinit_ia32_x87_attributes(res);",
190 ia32_climbframe_attr_t =>
191 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
192 "\tinit_ia32_climbframe_attributes(res, count);",
196 ia32_asm_attr_t => "ia32_compare_asm_attr",
197 ia32_attr_t => "ia32_compare_nodes_attr",
198 ia32_call_attr_t => "ia32_compare_call_attr",
199 ia32_condcode_attr_t => "ia32_compare_condcode_attr",
200 ia32_copyb_attr_t => "ia32_compare_copyb_attr",
201 ia32_immediate_attr_t => "ia32_compare_immediate_attr",
202 ia32_x87_attr_t => "ia32_compare_x87_attr",
203 ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
209 $mode_xmm = "mode_E";
210 $mode_gp = "mode_Iu";
211 $mode_flags = "mode_Iu";
212 $mode_fpcw = "mode_fpcw";
213 $status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
214 $status_flags_wo_cf = [ "PF", "AF", "ZF", "SF", "OF" ];
215 $fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
216 "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
222 op_flags => [ "constlike" ],
223 reg_req => { out => [ "gp_NOREG:I" ] },
224 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
225 attr_type => "ia32_immediate_attr_t",
226 hash_func => "ia32_hash_Immediate",
234 out_arity => "variable",
235 attr_type => "ia32_asm_attr_t",
236 attr => "ident *asm_text, const ia32_asm_reg_t *register_map",
237 init_attr => "attr->asm_text = asm_text;\n".
238 "\tattr->register_map = register_map;\n",
240 modified_flags => $status_flags,
243 # "allocates" a free register
245 op_flags => [ "constlike", "cse_neutral" ],
246 irn_flags => [ "rematerializable" ],
247 reg_req => { out => [ "gp" ] },
252 cmp_attr => "return 1;",
256 irn_flags => [ "rematerializable" ],
257 state => "exc_pinned",
258 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
259 out => [ "in_r4 in_r5", "flags", "none" ] },
260 ins => [ "base", "index", "mem", "left", "right" ],
261 outs => [ "res", "flags", "M" ],
262 emit => '. add%M %binop',
263 am => "source,binary",
267 modified_flags => $status_flags
271 irn_flags => [ "rematerializable" ],
272 state => "exc_pinned",
273 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
274 ins => [ "base", "index", "mem", "val" ],
275 emit => ". add%M %SI3, %AM",
279 modified_flags => $status_flags
283 irn_flags => [ "rematerializable" ],
284 state => "exc_pinned",
285 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
286 ins => [ "base", "index", "mem", "val" ],
287 emit => ". add%M %SB3, %AM",
291 modified_flags => $status_flags
295 state => "exc_pinned",
296 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
297 out => [ "in_r4 in_r5", "flags", "none" ] },
298 ins => [ "base", "index", "mem", "left", "right", "eflags" ],
299 outs => [ "res", "flags", "M" ],
300 emit => '. adc%M %binop',
301 am => "source,binary",
305 modified_flags => $status_flags
309 op_flags => [ "constlike" ],
310 reg_req => { in => [ "none", "none" ], out => [ "none" ] },
311 ins => [ "left", "right" ],
315 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
316 ins => [ "left", "right", "eflags" ],
320 # we should not rematrialize this node. It produces 2 results and has
321 # very strict constraints
322 state => "exc_pinned",
323 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
324 out => [ "eax", "flags", "none", "edx" ] },
325 ins => [ "base", "index", "mem", "left", "right" ],
326 emit => '. mul%M %unop4',
327 outs => [ "res_low", "flags", "M", "res_high" ],
328 am => "source,binary",
331 modified_flags => $status_flags
335 # we should not rematrialize this node. It produces 2 results and has
336 # very strict constraints
337 op_flags => [ "constlike" ],
338 cmp_attr => "return 1;",
339 reg_req => { in => [ "none", "none" ],
340 out => [ "none", "none", "none", "none" ] },
341 ins => [ "left", "right" ],
342 outs => [ "res_low", "flags", "M", "res_high" ],
346 irn_flags => [ "rematerializable" ],
347 state => "exc_pinned",
348 # TODO: adjust out requirements for the 3 operand form
349 # (no need for should_be_same then)
350 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
351 out => [ "in_r4 in_r5", "flags", "none" ] },
352 ins => [ "base", "index", "mem", "left", "right" ],
353 outs => [ "res", "flags", "M" ],
354 am => "source,binary",
358 modified_flags => $status_flags
362 irn_flags => [ "rematerializable" ],
363 state => "exc_pinned",
364 reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
365 out => [ "eax", "flags", "none", "edx" ] },
366 ins => [ "base", "index", "mem", "left", "right" ],
367 emit => '. imul%M %unop4',
368 outs => [ "res_low", "flags", "M", "res_high" ],
369 am => "source,binary",
372 modified_flags => $status_flags
376 op_flags => [ "constlike" ],
377 cmp_attr => "return 1;",
378 reg_req => { in => [ "none", "none" ],
379 out => [ "none", "none", "none", "none" ] },
380 ins => [ "left", "right" ],
381 outs => [ "res_low", "flags", "M", "res_high" ],
385 irn_flags => [ "rematerializable" ],
386 state => "exc_pinned",
387 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
388 out => [ "in_r4 in_r5", "flags", "none" ] },
389 ins => [ "base", "index", "mem", "left", "right" ],
390 outs => [ "res", "flags", "M" ],
391 am => "source,binary",
392 emit => '. and%M %binop',
396 modified_flags => $status_flags
400 irn_flags => [ "rematerializable" ],
401 state => "exc_pinned",
402 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
403 ins => [ "base", "index", "mem", "val" ],
404 emit => '. and%M %SI3, %AM',
408 modified_flags => $status_flags
412 irn_flags => [ "rematerializable" ],
413 state => "exc_pinned",
414 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
415 ins => [ "base", "index", "mem", "val" ],
416 emit => '. and%M %SB3, %AM',
420 modified_flags => $status_flags
424 irn_flags => [ "rematerializable" ],
425 state => "exc_pinned",
426 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
427 out => [ "in_r4 in_r5", "flags", "none" ] },
428 ins => [ "base", "index", "mem", "left", "right" ],
429 outs => [ "res", "flags", "M" ],
430 am => "source,binary",
431 emit => '. or%M %binop',
435 modified_flags => $status_flags
439 irn_flags => [ "rematerializable" ],
440 state => "exc_pinned",
441 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
442 ins => [ "base", "index", "mem", "val" ],
443 emit => '. or%M %SI3, %AM',
447 modified_flags => $status_flags
451 irn_flags => [ "rematerializable" ],
452 state => "exc_pinned",
453 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
454 ins => [ "base", "index", "mem", "val" ],
455 emit => '. or%M %SB3, %AM',
459 modified_flags => $status_flags
463 irn_flags => [ "rematerializable" ],
464 state => "exc_pinned",
465 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
466 out => [ "in_r4 in_r5", "flags", "none" ] },
467 ins => [ "base", "index", "mem", "left", "right" ],
468 outs => [ "res", "flags", "M" ],
469 am => "source,binary",
470 emit => '. xor%M %binop',
474 modified_flags => $status_flags
478 op_flags => [ "constlike" ],
479 irn_flags => [ "rematerializable" ],
480 reg_req => { out => [ "gp", "flags" ] },
481 outs => [ "res", "flags" ],
482 emit => ". xor%M %D0, %D0",
486 modified_flags => $status_flags
490 irn_flags => [ "rematerializable" ],
491 state => "exc_pinned",
492 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
493 ins => [ "base", "index", "mem", "val" ],
494 emit => '. xor%M %SI3, %AM',
498 modified_flags => $status_flags
502 irn_flags => [ "rematerializable" ],
503 state => "exc_pinned",
504 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
505 ins => [ "base", "index", "mem", "val" ],
506 emit => '. xor%M %SB3, %AM',
510 modified_flags => $status_flags
514 irn_flags => [ "rematerializable" ],
515 state => "exc_pinned",
516 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
517 out => [ "in_r4", "flags", "none" ] },
518 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
519 outs => [ "res", "flags", "M" ],
520 am => "source,binary",
521 emit => '. sub%M %binop',
525 modified_flags => $status_flags
529 irn_flags => [ "rematerializable" ],
530 state => "exc_pinned",
531 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
532 ins => [ "base", "index", "mem", "subtrahend" ],
533 emit => '. sub%M %SI3, %AM',
537 modified_flags => $status_flags
541 irn_flags => [ "rematerializable" ],
542 state => "exc_pinned",
543 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
544 ins => [ "base", "index", "mem", "subtrahend" ],
545 emit => '. sub%M %SB3, %AM',
549 modified_flags => $status_flags
553 state => "exc_pinned",
554 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
555 out => [ "in_r4 !in_r5", "flags", "none" ] },
556 ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
557 outs => [ "res", "flags", "M" ],
558 am => "source,binary",
559 emit => '. sbb%M %binop',
563 modified_flags => $status_flags
567 # Spiller currently fails when rematerializing flag consumers
568 # irn_flags => [ "rematerializable" ],
569 reg_req => { in => [ "flags" ], out => [ "gp", "flags" ] },
570 outs => [ "res", "flags" ],
571 emit => ". sbb%M %D0, %D0",
575 modified_flags => $status_flags
579 reg_req => { in => [ "none", "none" ], out => [ "none" ] },
580 ins => [ "minuend", "subtrahend" ],
584 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
585 ins => [ "minuend", "subtrahend", "eflags" ],
589 op_flags => [ "fragile", "labeled" ],
590 state => "exc_pinned",
591 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
592 out => [ "eax", "flags", "none", "edx", "none" ] },
593 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
594 outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ],
595 am => "source,unary",
596 emit => ". idiv%M %unop3",
599 modified_flags => $status_flags
603 op_flags => [ "fragile", "labeled" ],
604 state => "exc_pinned",
605 reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
606 out => [ "eax", "flags", "none", "edx", "none" ] },
607 ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
608 outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ],
609 am => "source,unary",
610 emit => ". div%M %unop3",
613 modified_flags => $status_flags
617 irn_flags => [ "rematerializable" ],
618 reg_req => { in => [ "gp", "ecx" ],
619 out => [ "in_r1 !in_r2", "flags" ] },
620 ins => [ "val", "count" ],
621 outs => [ "res", "flags" ],
622 emit => '. shl%M %SB1, %S0',
626 modified_flags => $status_flags
630 irn_flags => [ "rematerializable" ],
631 state => "exc_pinned",
632 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
633 ins => [ "base", "index", "mem", "count" ],
634 emit => '. shl%M %SB3, %AM',
638 modified_flags => $status_flags
642 cmp_attr => "return 1;",
643 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
644 ins => [ "val", "count", "dep" ],
648 irn_flags => [ "rematerializable" ],
649 reg_req => { in => [ "gp", "gp", "ecx" ],
650 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
651 ins => [ "val_high", "val_low", "count" ],
652 outs => [ "res", "flags" ],
653 emit => ". shld%M %SB2, %S1, %D0",
657 modified_flags => $status_flags
661 cmp_attr => "return 1;",
662 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
663 ins => [ "val_high", "val_low", "count" ],
667 irn_flags => [ "rematerializable" ],
668 reg_req => { in => [ "gp", "ecx" ],
669 out => [ "in_r1 !in_r2", "flags" ] },
670 ins => [ "val", "count" ],
671 outs => [ "res", "flags" ],
672 emit => '. shr%M %SB1, %S0',
676 modified_flags => $status_flags
680 irn_flags => [ "rematerializable" ],
681 state => "exc_pinned",
682 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
683 ins => [ "base", "index", "mem", "count" ],
684 emit => '. shr%M %SB3, %AM',
688 modified_flags => $status_flags
692 cmp_attr => "return 1;",
693 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
694 ins => [ "val", "count", "dep" ],
698 irn_flags => [ "rematerializable" ],
699 reg_req => { in => [ "gp", "gp", "ecx" ],
700 out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
701 ins => [ "val_high", "val_low", "count" ],
702 outs => [ "res", "flags" ],
703 emit => ". shrd%M %SB2, %S1, %D0",
707 modified_flags => $status_flags
711 cmp_attr => "return 1;",
712 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
713 ins => [ "val_high", "val_low", "count" ],
717 irn_flags => [ "rematerializable" ],
718 reg_req => { in => [ "gp", "ecx" ],
719 out => [ "in_r1 !in_r2", "flags" ] },
720 ins => [ "val", "count" ],
721 outs => [ "res", "flags" ],
722 emit => '. sar%M %SB1, %S0',
726 modified_flags => $status_flags
730 irn_flags => [ "rematerializable" ],
731 state => "exc_pinned",
732 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
733 ins => [ "base", "index", "mem", "count" ],
734 emit => '. sar%M %SB3, %AM',
738 modified_flags => $status_flags
742 cmp_attr => "return 1;",
743 ins => [ "val", "count", "dep" ],
744 reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
748 irn_flags => [ "rematerializable" ],
749 reg_req => { in => [ "gp", "ecx" ],
750 out => [ "in_r1 !in_r2", "flags" ] },
751 ins => [ "val", "count" ],
752 outs => [ "res", "flags" ],
753 emit => '. ror%M %SB1, %S0',
757 modified_flags => $status_flags
761 irn_flags => [ "rematerializable" ],
762 state => "exc_pinned",
763 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
764 ins => [ "base", "index", "mem", "count" ],
765 emit => '. ror%M %SB3, %AM',
769 modified_flags => $status_flags
773 irn_flags => [ "rematerializable" ],
774 reg_req => { in => [ "gp", "ecx" ],
775 out => [ "in_r1 !in_r2", "flags" ] },
776 ins => [ "val", "count" ],
777 outs => [ "res", "flags" ],
778 emit => '. rol%M %SB1, %S0',
782 modified_flags => $status_flags
786 irn_flags => [ "rematerializable" ],
787 state => "exc_pinned",
788 reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
789 ins => [ "base", "index", "mem", "count" ],
790 emit => '. rol%M %SB3, %AM',
794 modified_flags => $status_flags
798 irn_flags => [ "rematerializable" ],
799 reg_req => { in => [ "gp" ],
800 out => [ "in_r1", "flags" ] },
801 emit => '. neg%M %S0',
803 outs => [ "res", "flags" ],
807 modified_flags => $status_flags
811 irn_flags => [ "rematerializable" ],
812 state => "exc_pinned",
813 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
814 ins => [ "base", "index", "mem" ],
815 emit => '. neg%M %AM',
819 modified_flags => $status_flags
823 irn_flags => [ "rematerializable" ],
824 reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
825 outs => [ "low_res", "high_res" ],
828 modified_flags => $status_flags
833 irn_flags => [ "rematerializable" ],
834 reg_req => { in => [ "gp" ],
835 out => [ "in_r1", "flags" ] },
837 outs => [ "res", "flags" ],
838 emit => '. inc%M %S0',
842 modified_flags => $status_flags_wo_cf
846 irn_flags => [ "rematerializable" ],
847 state => "exc_pinned",
848 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
849 ins => [ "base", "index", "mem" ],
850 emit => '. inc%M %AM',
854 modified_flags => $status_flags_wo_cf
858 irn_flags => [ "rematerializable" ],
859 reg_req => { in => [ "gp" ],
860 out => [ "in_r1", "flags" ] },
862 outs => [ "res", "flags" ],
863 emit => '. dec%M %S0',
867 modified_flags => $status_flags_wo_cf
871 irn_flags => [ "rematerializable" ],
872 state => "exc_pinned",
873 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
874 ins => [ "base", "index", "mem" ],
875 emit => '. dec%M %AM',
879 modified_flags => $status_flags_wo_cf
883 irn_flags => [ "rematerializable" ],
884 reg_req => { in => [ "gp" ],
885 out => [ "in_r1" ] },
888 emit => '. not%M %S0',
896 irn_flags => [ "rematerializable" ],
897 state => "exc_pinned",
898 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
899 ins => [ "base", "index", "mem" ],
900 emit => '. not%M %AM',
908 reg_req => { in => [ "flags" ], out => [ "flags" ] },
913 modified_flags => $status_flags
917 reg_req => { out => [ "flags" ] },
922 modified_flags => $status_flags
926 irn_flags => [ "rematerializable" ],
927 state => "exc_pinned",
928 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
929 out => [ "flags", "none", "none" ] },
930 ins => [ "base", "index", "mem", "left", "right" ],
931 outs => [ "eflags", "unused", "M" ],
932 am => "source,binary",
933 emit => '. cmp%M %binop',
934 attr => "int ins_permuted, int cmp_unsigned",
935 init_attr => "attr->data.ins_permuted = ins_permuted;\n".
936 "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
940 modified_flags => $status_flags
944 irn_flags => [ "rematerializable" ],
945 state => "exc_pinned",
946 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
947 out => [ "flags", "none", "none" ] },
948 ins => [ "base", "index", "mem", "left", "right" ],
949 outs => [ "eflags", "unused", "M" ],
950 am => "source,binary",
951 emit => '. cmpb %binop',
952 attr => "int ins_permuted, int cmp_unsigned",
953 init_attr => "attr->data.ins_permuted = ins_permuted;\n".
954 "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
958 modified_flags => $status_flags
962 irn_flags => [ "rematerializable" ],
963 state => "exc_pinned",
964 reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] ,
965 out => [ "flags", "none", "none" ] },
966 ins => [ "base", "index", "mem", "left", "right" ],
967 outs => [ "eflags", "unused", "M" ],
968 am => "source,binary",
969 emit => '. test%M %binop',
970 attr => "int ins_permuted, int cmp_unsigned",
971 init_attr => "attr->data.ins_permuted = ins_permuted;\n".
972 "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
976 modified_flags => $status_flags
980 irn_flags => [ "rematerializable" ],
981 state => "exc_pinned",
982 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
983 out => [ "flags", "none", "none" ] },
984 ins => [ "base", "index", "mem", "left", "right" ],
985 outs => [ "eflags", "unused", "M" ],
986 am => "source,binary",
987 emit => '. testb %binop',
988 attr => "int ins_permuted, int cmp_unsigned",
989 init_attr => "attr->data.ins_permuted = ins_permuted;\n".
990 "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
994 modified_flags => $status_flags
998 #irn_flags => [ "rematerializable" ],
999 reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
1000 ins => [ "eflags" ],
1002 attr_type => "ia32_condcode_attr_t",
1003 attr => "pn_Cmp pnc",
1004 # The way we handle Setcc with float nodes (potentially) destroys the flags
1005 # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
1006 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
1007 . "\tif ((pnc & ia32_pn_Cmp_float) && ((pnc & 0xf) != pn_Cmp_Uo) && ((pnc & 0xf) != pn_Cmp_Leg)) {\n"
1008 . "\t\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n"
1009 . "\t\t/* attr->latency = 3; */\n"
1017 #irn_flags => [ "rematerializable" ],
1018 state => "exc_pinned",
1019 reg_req => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
1020 ins => [ "base", "index", "mem","eflags" ],
1021 attr_type => "ia32_condcode_attr_t",
1022 attr => "pn_Cmp pnc",
1023 init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
1024 emit => '. set%CMP3 %AM',
1031 #irn_flags => [ "rematerializable" ],
1032 state => "exc_pinned",
1033 # (note: leave the false,true order intact to make it compatible with other
1035 reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
1036 out => [ "in_r4 in_r5", "flags", "none" ] },
1037 ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
1038 outs => [ "res", "flags", "M" ],
1039 am => "source,binary",
1040 attr_type => "ia32_condcode_attr_t",
1041 attr => "pn_Cmp pnc",
1049 op_flags => [ "labeled", "cfopcode", "forking" ],
1050 reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
1051 ins => [ "eflags" ],
1052 outs => [ "false", "true" ],
1053 attr_type => "ia32_condcode_attr_t",
1054 attr => "pn_Cmp pnc",
1056 units => [ "BRANCH" ],
1061 op_flags => [ "labeled", "cfopcode", "forking" ],
1062 reg_req => { in => [ "gp" ] },
1064 attr_type => "ia32_condcode_attr_t",
1067 units => [ "BRANCH" ],
1068 modified_flags => $status_flags,
1069 init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements
1074 irn_flags => [ "simple_jump" ],
1075 op_flags => [ "cfopcode" ],
1076 reg_req => { out => [ "none" ] },
1078 units => [ "BRANCH" ],
1084 op_flags => [ "cfopcode" ],
1085 reg_req => { in => [ "gp", "gp", "none", "gp" ] },
1086 ins => [ "base", "index", "mem", "target" ],
1087 am => "source,unary",
1088 emit => '. jmp *%unop3',
1090 units => [ "BRANCH" ],
1092 init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements
1096 op_flags => [ "constlike" ],
1097 irn_flags => [ "rematerializable" ],
1098 reg_req => { out => [ "gp" ] },
1100 attr => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
1101 attr_type => "ia32_immediate_attr_t",
1107 op_flags => [ "constlike" ],
1108 irn_flags => [ "rematerializable" ],
1109 reg_req => { out => [ "gp" ] },
1116 op_flags => [ "constlike" ],
1117 reg_req => { out => [ "gp" ] },
1121 modified_flags => $status_flags,
1126 op_flags => [ "constlike", "dump_noblock", "dump_noinput" ],
1127 reg_req => { out => [ "gp_NOREG:I" ] },
1136 op_flags => [ "constlike", "dump_noblock", "dump_noinput" ],
1137 reg_req => { out => [ "vfp_NOREG:I" ] },
1142 attr_type => "ia32_x87_attr_t",
1147 op_flags => [ "constlike", "dump_noblock", "dump_noinput" ],
1148 reg_req => { out => [ "xmm_NOREG:I" ] },
1157 op_flags => [ "constlike" ],
1158 reg_req => { out => [ "fpcw:I" ] },
1162 modified_flags => $fpcw_flags
1166 op_flags => [ "fragile", "labeled" ],
1168 reg_req => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] },
1169 ins => [ "base", "index", "mem" ],
1171 emit => ". fldcw %AM",
1174 modified_flags => $fpcw_flags
1178 op_flags => [ "fragile", "labeled" ],
1180 reg_req => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1181 ins => [ "base", "index", "mem", "fpcw" ],
1183 emit => ". fnstcw %AM",
1189 op_flags => [ "fragile", "labeled" ],
1191 reg_req => { in => [ "fp_cw" ], out => [ "none" ] },
1199 # we should not rematrialize this node. It has very strict constraints.
1200 reg_req => { in => [ "eax", "edx" ], out => [ "edx" ] },
1201 ins => [ "val", "clobbered" ],
1210 # Note that we add additional latency values depending on address mode, so a
1211 # lateny of 0 for load is correct
1214 op_flags => [ "fragile", "labeled" ],
1215 state => "exc_pinned",
1216 reg_req => { in => [ "gp", "gp", "none" ],
1217 out => [ "gp", "none", "none", "none" ] },
1218 ins => [ "base", "index", "mem" ],
1219 outs => [ "res", "unused", "M", "X_exc" ],
1221 emit => ". mov%EX%.l %AM, %D0",
1226 op_flags => [ "fragile", "labeled" ],
1227 state => "exc_pinned",
1228 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none", "none" ] },
1229 ins => [ "base", "index", "mem", "val" ],
1230 outs => [ "M", "X_exc" ],
1231 emit => '. mov%M %SI3, %AM',
1238 op_flags => [ "fragile", "labeled" ],
1239 state => "exc_pinned",
1240 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => ["none", "none" ] },
1241 ins => [ "base", "index", "mem", "val" ],
1242 outs => [ "M", "X_exc" ],
1243 emit => '. mov%M %SB3, %AM',
1250 irn_flags => [ "rematerializable" ],
1251 reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
1252 ins => [ "base", "index" ],
1253 emit => '. leal %AM, %D0',
1257 # lea doesn't modify the flags, but setting this seems advantageous since it
1258 # increases chances that the Lea is transformed back to an Add
1259 modified_flags => 1,
1263 state => "exc_pinned",
1264 reg_req => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1265 ins => [ "base", "index", "mem", "val", "stack" ],
1266 emit => '. push%M %unop3',
1267 outs => [ "stack", "M" ],
1268 am => "source,unary",
1274 state => "exc_pinned",
1275 reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1277 outs => [ "stack" ],
1278 emit => '. pushl %%eax',
1285 state => "exc_pinned",
1286 reg_req => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1287 ins => [ "mem", "stack" ],
1288 outs => [ "res", "M", "unused", "stack" ],
1289 emit => '. pop%M %D0',
1290 latency => 3, # Pop is more expensive than Push on Athlon
1295 state => "exc_pinned",
1296 reg_req => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1297 ins => [ "mem", "stack" ],
1298 outs => [ "res", "M", "unused", "stack" ],
1299 emit => '. pop%M %D0',
1300 latency => 3, # Pop is more expensive than Push on Athlon
1305 state => "exc_pinned",
1306 reg_req => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1307 ins => [ "base", "index", "mem", "stack" ],
1308 outs => [ "unused0", "M", "unused1", "stack" ],
1309 emit => '. pop%M %AM',
1310 latency => 3, # Pop is more expensive than Push on Athlon
1315 reg_req => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1317 outs => [ "frame", "stack", "M" ],
1323 reg_req => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1325 outs => [ "frame", "stack" ],
1332 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1333 ins => [ "base", "index", "mem", "stack", "size" ],
1334 am => "source,binary",
1335 emit => '. addl %binop',
1337 outs => [ "stack", "M" ],
1339 modified_flags => $status_flags
1344 reg_req => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1345 ins => [ "base", "index", "mem", "stack", "size" ],
1346 am => "source,binary",
1347 emit => ". subl %binop\n".
1348 ". movl %%esp, %D1",
1350 outs => [ "stack", "addr", "M" ],
1352 modified_flags => $status_flags
1356 op_flags => [ "keep" ],
1364 irn_flags => [ "rematerializable" ],
1365 reg_req => { out => [ "gp" ] },
1371 # BT supports source address mode, but this is unused yet
1374 irn_flags => [ "rematerializable" ],
1375 state => "exc_pinned",
1376 reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] },
1377 ins => [ "left", "right" ],
1378 emit => '. bt%M %S1, %S0',
1381 mode => $mode_flags,
1382 modified_flags => $status_flags # only CF is set, but the other flags are undefined
1386 irn_flags => [ "rematerializable" ],
1387 state => "exc_pinned",
1388 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1389 out => [ "gp", "flags", "none" ] },
1390 ins => [ "base", "index", "mem", "operand" ],
1391 outs => [ "res", "flags", "M" ],
1392 am => "source,binary",
1393 emit => '. bsf%M %unop3, %D0',
1397 modified_flags => $status_flags
1401 irn_flags => [ "rematerializable" ],
1402 state => "exc_pinned",
1403 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1404 out => [ "gp", "flags", "none" ] },
1405 ins => [ "base", "index", "mem", "operand" ],
1406 outs => [ "res", "flags", "M" ],
1407 am => "source,binary",
1408 emit => '. bsr%M %unop3, %D0',
1412 modified_flags => $status_flags
1416 # SSE4.2 or SSE4a popcnt instruction
1419 irn_flags => [ "rematerializable" ],
1420 state => "exc_pinned",
1421 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1422 out => [ "gp", "flags", "none" ] },
1423 ins => [ "base", "index", "mem", "operand" ],
1424 outs => [ "res", "flags", "M" ],
1425 am => "source,binary",
1426 emit => '. popcnt%M %unop3, %D0',
1430 modified_flags => $status_flags
1434 state => "exc_pinned",
1436 in => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1437 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" ]
1439 ins => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1440 outs => [ "stack", "fpcw", "M", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" ],
1441 attr_type => "ia32_call_attr_t",
1442 attr => "unsigned pop, ir_type *call_tp",
1443 am => "source,unary",
1444 units => [ "BRANCH" ],
1445 latency => 4, # random number
1446 modified_flags => $status_flags
1450 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1452 # PS: try gcc __builtin_frame_address(100000) :-)
1455 reg_req => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1456 ins => [ "frame", "cnt", "tmp" ],
1458 latency => 4, # random number
1459 attr_type => "ia32_climbframe_attr_t",
1460 attr => "unsigned count",
1469 irn_flags => [ "rematerializable" ],
1470 reg_req => { in => [ "gp" ],
1471 out => [ "in_r1" ] },
1472 emit => '. bswap%M %S0',
1480 # bswap16, use xchg here
1483 irn_flags => [ "rematerializable" ],
1484 reg_req => { in => [ "eax ebx ecx edx" ],
1485 out => [ "in_r1" ] },
1486 emit => '. xchg %SB0, %SH0',
1498 reg_req => { in => [ "none" ], out => [ "none" ] },
1507 # Undefined Instruction on ALL x86 CPU's
1511 reg_req => { in => [ "none" ], out => [ "none" ] },
1514 emit => ". .value 0x0b0f",
1523 irn_flags => [ "rematerializable" ],
1525 reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1526 ins => [ "port", "value", "mem" ],
1527 emit => '. out%M %SS0, %SI1',
1531 modified_flags => $status_flags
1538 irn_flags => [ "rematerializable" ],
1540 reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1541 ins => [ "port", "mem" ],
1542 outs => [ "res", "M" ],
1543 emit => '. in%M %DS0, %SS0',
1547 modified_flags => $status_flags
1551 # Intel style prefetching
1554 op_flags => [ "fragile", "labeled" ],
1555 state => "exc_pinned",
1556 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1557 ins => [ "base", "index", "mem" ],
1560 emit => ". prefetcht0 %AM",
1565 op_flags => [ "fragile", "labeled" ],
1566 state => "exc_pinned",
1567 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1568 ins => [ "base", "index", "mem" ],
1571 emit => ". prefetcht1 %AM",
1576 op_flags => [ "fragile", "labeled" ],
1577 state => "exc_pinned",
1578 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1579 ins => [ "base", "index", "mem" ],
1582 emit => ". prefetcht2 %AM",
1587 op_flags => [ "fragile", "labeled" ],
1588 state => "exc_pinned",
1589 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1590 ins => [ "base", "index", "mem" ],
1593 emit => ". prefetchnta %AM",
1598 # 3DNow! prefetch instructions
1601 op_flags => [ "fragile", "labeled" ],
1602 state => "exc_pinned",
1603 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1604 ins => [ "base", "index", "mem" ],
1607 emit => ". prefetch %AM",
1612 op_flags => [ "fragile", "labeled" ],
1613 state => "exc_pinned",
1614 reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1615 ins => [ "base", "index", "mem" ],
1618 emit => ". prefetchw %AM",
1624 irn_flags => [ "rematerializable" ],
1625 reg_req => { out => [ "xmm" ] },
1626 emit => '. xorp%XSD %D0, %D0',
1633 op_flags => [ "constlike" ],
1634 irn_flags => [ "rematerializable" ],
1635 reg_req => { out => [ "xmm" ] },
1642 irn_flags => [ "rematerializable" ],
1643 reg_req => { out => [ "xmm" ] },
1644 emit => '. pxor %D0, %D0',
1650 # produces all 1 bits
1652 irn_flags => [ "rematerializable" ],
1653 reg_req => { out => [ "xmm" ] },
1654 emit => '. pcmpeqb %D0, %D0',
1660 # integer shift left, dword
1662 irn_flags => [ "rematerializable" ],
1663 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1664 emit => '. pslld %SI1, %D0',
1670 # integer shift left, qword
1672 irn_flags => [ "rematerializable" ],
1673 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1674 emit => '. psllq %SI1, %D0',
1680 # integer shift right, dword
1682 irn_flags => [ "rematerializable" ],
1683 reg_req => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1684 emit => '. psrld %SI1, %D0',
1690 # mov from integer to SSE register
1692 irn_flags => [ "rematerializable" ],
1693 reg_req => { in => [ "gp" ], out => [ "xmm" ] },
1694 emit => '. movd %S0, %D0',
1701 irn_flags => [ "rematerializable" ],
1702 state => "exc_pinned",
1703 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1704 out => [ "in_r4 in_r5", "flags", "none" ] },
1705 ins => [ "base", "index", "mem", "left", "right" ],
1706 outs => [ "res", "flags", "M" ],
1707 am => "source,binary",
1708 emit => '. add%XXM %binop',
1715 irn_flags => [ "rematerializable" ],
1716 state => "exc_pinned",
1717 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1718 out => [ "in_r4 in_r5", "flags", "none" ] },
1719 ins => [ "base", "index", "mem", "left", "right" ],
1720 outs => [ "res", "flags", "M" ],
1721 am => "source,binary",
1722 emit => '. mul%XXM %binop',
1729 irn_flags => [ "rematerializable" ],
1730 state => "exc_pinned",
1731 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1732 out => [ "in_r4 in_r5", "flags", "none" ] },
1733 ins => [ "base", "index", "mem", "left", "right" ],
1734 outs => [ "res", "flags", "M" ],
1735 am => "source,binary",
1736 emit => '. max%XXM %binop',
1743 irn_flags => [ "rematerializable" ],
1744 state => "exc_pinned",
1745 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1746 out => [ "in_r4 in_r5", "flags", "none" ] },
1747 ins => [ "base", "index", "mem", "left", "right" ],
1748 outs => [ "res", "flags", "M" ],
1749 am => "source,binary",
1750 emit => '. min%XXM %binop',
1757 irn_flags => [ "rematerializable" ],
1758 state => "exc_pinned",
1759 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1760 out => [ "in_r4 in_r5", "flags", "none" ] },
1761 ins => [ "base", "index", "mem", "left", "right" ],
1762 outs => [ "res", "flags", "M" ],
1763 am => "source,binary",
1764 emit => '. andp%XSD %binop',
1771 irn_flags => [ "rematerializable" ],
1772 state => "exc_pinned",
1773 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1774 out => [ "in_r4 in_r5", "flags", "none" ] },
1775 ins => [ "base", "index", "mem", "left", "right" ],
1776 outs => [ "res", "flags", "M" ],
1777 am => "source,binary",
1778 emit => '. orp%XSD %binop',
1785 irn_flags => [ "rematerializable" ],
1786 state => "exc_pinned",
1787 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1788 out => [ "in_r4 in_r5", "flags", "none" ] },
1789 ins => [ "base", "index", "mem", "left", "right" ],
1790 outs => [ "res", "flags", "M" ],
1791 am => "source,binary",
1792 emit => '. xorp%XSD %binop',
1799 irn_flags => [ "rematerializable" ],
1800 state => "exc_pinned",
1801 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1802 out => [ "in_r4 !in_r5", "flags", "none" ] },
1803 ins => [ "base", "index", "mem", "left", "right" ],
1804 outs => [ "res", "flags", "M" ],
1805 am => "source,binary",
1806 emit => '. andnp%XSD %binop',
1813 irn_flags => [ "rematerializable" ],
1814 state => "exc_pinned",
1815 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1816 out => [ "in_r4", "flags", "none" ] },
1817 ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
1818 outs => [ "res", "flags", "M" ],
1819 am => "source,binary",
1820 emit => '. sub%XXM %binop',
1827 irn_flags => [ "rematerializable" ],
1828 state => "exc_pinned",
1829 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1830 out => [ "in_r4 !in_r5", "flags", "none" ] },
1831 ins => [ "base", "index", "mem", "dividend", "divisor" ],
1832 outs => [ "res", "flags", "M" ],
1833 am => "source,binary",
1834 emit => '. div%XXM %binop',
1840 irn_flags => [ "rematerializable" ],
1841 state => "exc_pinned",
1842 reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1843 out => [ "eflags" ] },
1844 ins => [ "base", "index", "mem", "left", "right" ],
1845 outs => [ "flags" ],
1846 am => "source,binary",
1847 attr => "int ins_permuted",
1848 init_attr => "attr->data.ins_permuted = ins_permuted;",
1849 emit => ' .ucomi%XXM %binop',
1852 mode => $mode_flags,
1853 modified_flags => 1,
1857 op_flags => [ "fragile", "labeled" ],
1858 state => "exc_pinned",
1859 reg_req => { in => [ "gp", "gp", "none" ],
1860 out => [ "xmm", "none", "none", "none" ] },
1861 ins => [ "base", "index", "mem" ],
1862 outs => [ "res", "unused", "M", "X_exc" ],
1863 emit => '. mov%XXM %AM, %D0',
1864 attr => "ir_mode *load_mode",
1865 init_attr => "attr->ls_mode = load_mode;",
1871 op_flags => [ "fragile", "labeled" ],
1872 state => "exc_pinned",
1873 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "none", "none" ] },
1874 ins => [ "base", "index", "mem", "val" ],
1875 outs => [ "M", "X_exc" ],
1876 emit => '. mov%XXM %S3, %AM',
1883 op_flags => [ "fragile", "labeled" ],
1884 state => "exc_pinned",
1885 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "none" ] },
1886 ins => [ "base", "index", "mem", "val" ],
1888 emit => '. mov%XXM %S3, %AM',
1895 op_flags => [ "fragile", "labeled" ],
1896 state => "exc_pinned",
1897 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1898 ins => [ "base", "index", "mem", "val" ],
1899 am => "source,unary",
1900 emit => '. cvtsi2ss %unop3, %D0',
1907 op_flags => [ "fragile", "labeled" ],
1908 state => "exc_pinned",
1909 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1910 ins => [ "base", "index", "mem", "val" ],
1911 am => "source,unary",
1912 emit => '. cvtsi2sd %unop3, %D0',
1920 op_flags => [ "fragile", "labeled" ],
1921 cmp_attr => "return 1;",
1922 ins => [ "val_high", "val_low" ],
1923 reg_req => { in => [ "none", "none" ], out => [ "none" ] }
1927 op_flags => [ "fragile", "labeled" ],
1928 cmp_attr => "return 1;",
1930 outs => [ "res_high", "res_low" ],
1931 reg_req => { in => [ "none" ], out => [ "none", "none" ] }
1935 op_flags => [ "fragile" ],
1937 reg_req => { in => [ "edi", "esi", "ecx", "none" ], out => [ "edi", "esi", "ecx", "none" ] },
1938 outs => [ "DST", "SRC", "CNT", "M" ],
1939 attr_type => "ia32_copyb_attr_t",
1940 attr => "unsigned size",
1943 # we don't care about this flag, so no need to mark this node
1944 # modified_flags => [ "DF" ]
1948 op_flags => [ "fragile" ],
1950 reg_req => { in => [ "edi", "esi", "none" ], out => [ "edi", "esi", "none" ] },
1951 outs => [ "DST", "SRC", "M" ],
1952 attr_type => "ia32_copyb_attr_t",
1953 attr => "unsigned size",
1956 # we don't care about this flag, so no need to mark this node
1957 # modified_flags => [ "DF" ]
1961 state => "exc_pinned",
1962 reg_req => { in => [ "eax" ], out => [ "eax" ] },
1972 state => "exc_pinned",
1973 reg_req => { in => [ "gp", "gp", "none", "gp" ],
1974 out => [ "gp", "none", "none" ] },
1975 ins => [ "base", "index", "mem", "val" ],
1976 outs => [ "res", "flags", "M" ],
1977 am => "source,unary",
1980 attr => "ir_mode *smaller_mode",
1981 init_attr => "attr->ls_mode = smaller_mode;",
1986 state => "exc_pinned",
1987 reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1988 out => [ "gp", "none", "none" ] },
1989 ins => [ "base", "index", "mem", "val" ],
1990 outs => [ "res", "flags", "M" ],
1991 am => "source,unary",
1994 attr => "ir_mode *smaller_mode",
1995 init_attr => "attr->ls_mode = smaller_mode;",
2000 state => "exc_pinned",
2001 reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
2002 ins => [ "base", "index", "mem", "val" ],
2003 am => "source,unary",
2010 state => "exc_pinned",
2011 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
2012 ins => [ "base", "index", "mem", "val" ],
2013 am => "source,unary",
2020 state => "exc_pinned",
2021 reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
2022 ins => [ "base", "index", "mem", "val" ],
2023 am => "source,unary",
2029 # rematerialisation disabled for all float nodes for now, because the fpcw
2030 # handler runs before spilling and we might end up with wrong fpcw then
2033 # irn_flags => [ "rematerializable" ],
2034 state => "exc_pinned",
2035 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2036 out => [ "vfp", "none", "none" ] },
2037 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2038 outs => [ "res", "dummy", "M" ],
2039 am => "source,binary",
2043 attr_type => "ia32_x87_attr_t",
2047 # irn_flags => [ "rematerializable" ],
2048 state => "exc_pinned",
2049 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2050 out => [ "vfp", "none", "none" ] },
2051 ins => [ "base", "index", "mem", "left", "right", "fpcw" ],
2052 outs => [ "res", "dummy", "M" ],
2053 am => "source,binary",
2057 attr_type => "ia32_x87_attr_t",
2061 # irn_flags => [ "rematerializable" ],
2062 state => "exc_pinned",
2063 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2064 out => [ "vfp", "none", "none" ] },
2065 ins => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2066 outs => [ "res", "dummy", "M" ],
2067 am => "source,binary",
2071 attr_type => "ia32_x87_attr_t",
2075 state => "exc_pinned",
2076 reg_req => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2077 out => [ "vfp", "none", "none" ] },
2078 ins => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2079 outs => [ "res", "dummy", "M" ],
2080 am => "source,binary",
2083 attr_type => "ia32_x87_attr_t",
2087 reg_req => { in => [ "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
2088 ins => [ "left", "right", "fpcw" ],
2092 attr_type => "ia32_x87_attr_t",
2096 irn_flags => [ "rematerializable" ],
2097 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2102 attr_type => "ia32_x87_attr_t",
2106 irn_flags => [ "rematerializable" ],
2107 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2112 attr_type => "ia32_x87_attr_t",
2116 irn_flags => [ "rematerializable" ],
2117 op_flags => [ "fragile", "labeled" ],
2118 state => "exc_pinned",
2119 reg_req => { in => [ "gp", "gp", "none" ],
2120 out => [ "vfp", "none", "none", "none" ] },
2121 ins => [ "base", "index", "mem" ],
2122 outs => [ "res", "unused", "M", "X_exc" ],
2123 attr => "ir_mode *load_mode",
2124 init_attr => "attr->attr.ls_mode = load_mode;",
2127 attr_type => "ia32_x87_attr_t",
2131 irn_flags => [ "rematerializable" ],
2132 op_flags => [ "fragile", "labeled" ],
2133 state => "exc_pinned",
2134 reg_req => { in => [ "gp", "gp", "none", "vfp" ],
2135 out => [ "none", "none" ] },
2136 ins => [ "base", "index", "mem", "val" ],
2137 outs => [ "M", "X_exc" ],
2138 attr => "ir_mode *store_mode",
2139 init_attr => "attr->attr.ls_mode = store_mode;",
2143 attr_type => "ia32_x87_attr_t",
2147 state => "exc_pinned",
2148 reg_req => { in => [ "gp", "gp", "none" ],
2149 out => [ "vfp", "none", "none" ] },
2150 outs => [ "res", "unused", "M" ],
2151 ins => [ "base", "index", "mem" ],
2154 attr_type => "ia32_x87_attr_t",
2158 state => "exc_pinned",
2159 reg_req => { in => [ "gp", "gp", "none", "vfp", "fpcw" ], out => [ "none" ] },
2160 ins => [ "base", "index", "mem", "val", "fpcw" ],
2165 attr_type => "ia32_x87_attr_t",
2168 # SSE3 fisttp instruction
2170 state => "exc_pinned",
2171 reg_req => { in => [ "gp", "gp", "none", "vfp" ], out => [ "in_r4", "none" ]},
2172 ins => [ "base", "index", "mem", "val" ],
2173 outs => [ "res", "M" ],
2176 attr_type => "ia32_x87_attr_t",
2180 irn_flags => [ "rematerializable" ],
2181 reg_req => { out => [ "vfp" ] },
2186 attr_type => "ia32_x87_attr_t",
2190 irn_flags => [ "rematerializable" ],
2191 reg_req => { out => [ "vfp" ] },
2196 attr_type => "ia32_x87_attr_t",
2200 irn_flags => [ "rematerializable" ],
2201 reg_req => { out => [ "vfp" ] },
2206 attr_type => "ia32_x87_attr_t",
2210 irn_flags => [ "rematerializable" ],
2211 reg_req => { out => [ "vfp" ] },
2216 attr_type => "ia32_x87_attr_t",
2220 irn_flags => [ "rematerializable" ],
2221 reg_req => { out => [ "vfp" ] },
2226 attr_type => "ia32_x87_attr_t",
2230 irn_flags => [ "rematerializable" ],
2231 reg_req => { out => [ "vfp" ] },
2236 attr_type => "ia32_x87_attr_t",
2240 irn_flags => [ "rematerializable" ],
2241 reg_req => { out => [ "vfp" ] },
2246 attr_type => "ia32_x87_attr_t",
2250 # we can't allow to rematerialize this node so we don't
2251 # accidently produce Phi(Fucom, Fucom(ins_permuted))
2252 # irn_flags => [ "rematerializable" ],
2253 reg_req => { in => [ "vfp", "vfp" ], out => [ "eax" ] },
2254 ins => [ "left", "right" ],
2255 outs => [ "flags" ],
2256 attr => "int ins_permuted",
2257 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2260 attr_type => "ia32_x87_attr_t",
2265 irn_flags => [ "rematerializable" ],
2266 reg_req => { in => [ "vfp", "vfp" ], out => [ "eflags" ] },
2267 ins => [ "left", "right" ],
2268 outs => [ "flags" ],
2269 attr => "int ins_permuted",
2270 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2273 attr_type => "ia32_x87_attr_t",
2278 # irn_flags => [ "rematerializable" ],
2279 reg_req => { in => [ "vfp" ], out => [ "eax" ] },
2281 outs => [ "flags" ],
2282 attr => "int ins_permuted",
2283 init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2286 attr_type => "ia32_x87_attr_t",
2291 irn_flags => [ "rematerializable" ],
2292 reg_req => { in => [ "eax" ], out => [ "eflags" ] },
2294 outs => [ "flags" ],
2298 mode => $mode_flags,
2302 state => "exc_pinned",
2303 emit => '. fadd%XM %x87_binop',
2305 attr_type => "ia32_x87_attr_t",
2310 state => "exc_pinned",
2311 emit => '. faddp%XM %x87_binop',
2313 attr_type => "ia32_x87_attr_t",
2318 state => "exc_pinned",
2319 emit => '. fmul%XM %x87_binop',
2321 attr_type => "ia32_x87_attr_t",
2326 state => "exc_pinned",
2327 emit => '. fmulp%XM %x87_binop',,
2329 attr_type => "ia32_x87_attr_t",
2334 state => "exc_pinned",
2335 emit => '. fsub%XM %x87_binop',
2337 attr_type => "ia32_x87_attr_t",
2341 # Note: gas is strangely buggy: fdivrp and fdivp as well as fsubrp and fsubp
2342 # are swapped, we work this around in the emitter...
2345 state => "exc_pinned",
2346 # see note about gas bugs
2347 emit => '. fsubrp%XM %x87_binop',
2349 attr_type => "ia32_x87_attr_t",
2354 state => "exc_pinned",
2355 irn_flags => [ "rematerializable" ],
2356 emit => '. fsubr%XM %x87_binop',
2358 attr_type => "ia32_x87_attr_t",
2363 state => "exc_pinned",
2364 irn_flags => [ "rematerializable" ],
2365 # see note about gas bugs before fsubp
2366 emit => '. fsubp%XM %x87_binop',
2368 attr_type => "ia32_x87_attr_t",
2375 attr_type => "ia32_x87_attr_t",
2379 # this node is just here, to keep the simulator running
2380 # we can omit this when a fprem simulation function exists
2382 emit => '. fprem1\n'.
2385 attr_type => "ia32_x87_attr_t",
2390 state => "exc_pinned",
2391 emit => '. fdiv%XM %x87_binop',
2393 attr_type => "ia32_x87_attr_t",
2398 state => "exc_pinned",
2399 # see note about gas bugs before fsubp
2400 emit => '. fdivrp%XM %x87_binop',
2402 attr_type => "ia32_x87_attr_t",
2407 state => "exc_pinned",
2408 emit => '. fdivr%XM %x87_binop',
2410 attr_type => "ia32_x87_attr_t",
2415 state => "exc_pinned",
2416 # see note about gas bugs before fsubp
2417 emit => '. fdivp%XM %x87_binop',
2419 attr_type => "ia32_x87_attr_t",
2426 attr_type => "ia32_x87_attr_t",
2431 op_flags => [ "keep" ],
2432 irn_flags => [ "rematerializable" ],
2435 attr_type => "ia32_x87_attr_t",
2440 irn_flags => [ "rematerializable" ],
2441 op_flags => [ "fragile", "labeled" ],
2442 state => "exc_pinned",
2443 emit => '. fld%XM %AM',
2444 attr_type => "ia32_x87_attr_t",
2450 irn_flags => [ "rematerializable" ],
2451 op_flags => [ "fragile", "labeled" ],
2452 state => "exc_pinned",
2453 emit => '. fst%XM %AM',
2455 attr_type => "ia32_x87_attr_t",
2461 irn_flags => [ "rematerializable" ],
2462 op_flags => [ "fragile", "labeled" ],
2463 state => "exc_pinned",
2464 emit => '. fstp%XM %AM',
2466 attr_type => "ia32_x87_attr_t",
2472 state => "exc_pinned",
2473 emit => '. fild%XM %AM',
2474 attr_type => "ia32_x87_attr_t",
2480 state => "exc_pinned",
2481 emit => '. fist%XM %AM',
2483 attr_type => "ia32_x87_attr_t",
2489 state => "exc_pinned",
2490 emit => '. fistp%XM %AM',
2492 attr_type => "ia32_x87_attr_t",
2497 # SSE3 fisttp instruction
2499 state => "exc_pinned",
2500 emit => '. fisttp%XM %AM',
2502 attr_type => "ia32_x87_attr_t",
2508 op_flags => [ "constlike", "keep" ],
2509 irn_flags => [ "rematerializable" ],
2510 reg_req => { out => [ "vfp" ] },
2512 attr_type => "ia32_x87_attr_t",
2517 op_flags => [ "constlike", "keep" ],
2518 irn_flags => [ "rematerializable" ],
2519 reg_req => { out => [ "vfp" ] },
2521 attr_type => "ia32_x87_attr_t",
2526 op_flags => [ "constlike", "keep" ],
2527 irn_flags => [ "rematerializable" ],
2528 reg_req => { out => [ "vfp" ] },
2530 attr_type => "ia32_x87_attr_t",
2535 op_flags => [ "constlike", "keep" ],
2536 irn_flags => [ "rematerializable" ],
2537 reg_req => { out => [ "vfp" ] },
2539 attr_type => "ia32_x87_attr_t",
2544 op_flags => [ "constlike", "keep" ],
2545 irn_flags => [ "rematerializable" ],
2546 reg_req => { out => [ "vfp" ] },
2548 attr_type => "ia32_x87_attr_t",
2553 op_flags => [ "constlike", "keep" ],
2554 irn_flags => [ "rematerializable" ],
2555 reg_req => { out => [ "vfp" ] },
2556 emit => '. fldll2t',
2557 attr_type => "ia32_x87_attr_t",
2562 op_flags => [ "constlike", "keep" ],
2563 irn_flags => [ "rematerializable" ],
2564 reg_req => { out => [ "vfp" ] },
2566 attr_type => "ia32_x87_attr_t",
2571 # Note that it is NEVER allowed to do CSE on these nodes
2572 # Moreover, note the virtual register requierements!
2575 op_flags => [ "keep" ],
2576 reg_req => { out => [ "none" ] },
2577 cmp_attr => "return 1;",
2578 emit => '. fxch %X0',
2579 attr_type => "ia32_x87_attr_t",
2585 op_flags => [ "keep" ],
2586 reg_req => { out => [ "none" ] },
2587 cmp_attr => "return 1;",
2588 emit => '. fld %X0',
2589 attr_type => "ia32_x87_attr_t",
2595 reg_req => { in => [ "vfp"], out => [ "vfp" ] },
2596 cmp_attr => "return 1;",
2597 emit => '. fld %X0',
2598 attr_type => "ia32_x87_attr_t",
2603 op_flags => [ "keep" ],
2604 reg_req => { out => [ "none" ] },
2605 cmp_attr => "return 1;",
2606 emit => '. fstp %X0',
2607 attr_type => "ia32_x87_attr_t",
2613 op_flags => [ "keep" ],
2614 reg_req => { out => [ "none" ] },
2615 cmp_attr => "return 1;",
2616 emit => '. ffreep %X0',
2617 attr_type => "ia32_x87_attr_t",
2623 op_flags => [ "keep" ],
2624 reg_req => { out => [ "none" ] },
2625 cmp_attr => "return 1;",
2627 attr_type => "ia32_x87_attr_t",
2633 op_flags => [ "keep" ],
2634 reg_req => { out => [ "none" ] },
2635 cmp_attr => "return 1;",
2637 attr_type => "ia32_x87_attr_t",
2644 emit => ". fucom %X1\n".
2646 attr_type => "ia32_x87_attr_t",
2652 emit => ". fucomp %X1\n".
2654 attr_type => "ia32_x87_attr_t",
2660 emit => ". fucompp\n".
2662 attr_type => "ia32_x87_attr_t",
2668 emit => '. fucomi %X1',
2669 attr_type => "ia32_x87_attr_t",
2675 emit => '. fucompi %X1',
2676 attr_type => "ia32_x87_attr_t",
2684 attr_type => "ia32_x87_attr_t",
2688 # Spilling and reloading of SSE registers, hardcoded, not generated #
2691 op_flags => [ "fragile", "labeled" ],
2692 state => "exc_pinned",
2693 reg_req => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none" ] },
2694 emit => '. movdqu %D0, %AM',
2695 outs => [ "res", "M" ],
2701 op_flags => [ "fragile", "labeled" ],
2702 state => "exc_pinned",
2703 reg_req => { in => [ "gp", "gp", "none", "xmm" ] },
2704 ins => [ "base", "index", "mem", "val" ],
2705 emit => '. movdqu %binop',
2713 # Transform some attributes
2714 foreach my $op (keys(%nodes)) {
2715 my $node = $nodes{$op};
2716 my $op_attr_init = $node->{op_attr_init};
2718 if(defined($op_attr_init)) {
2719 $op_attr_init .= "\n\t";
2724 if(!defined($node->{latency})) {
2726 $node->{latency} = 0;
2728 die("Latency missing for op $op");
2731 $op_attr_init .= "attr->latency = ".$node->{latency} . ";";
2733 $node->{op_attr_init} = $op_attr_init;