some cleanups for middleend node creation in backends
[libfirm] / ir / be / ia32 / ia32_spec.pl
1 # Creation: 2005/10/19
2 # $Id$
3 # This is the specification for the ia32 assembler Firm-operations
4
5 $arch = "ia32";
6
7 # register types:
8 $normal      =  0; # no special type
9 $ignore      =  1; # ignore (do not assign this register)
10 $arbitrary   =  2; # emitter can choose an arbitrary register of this class
11 $virtual     =  4; # the register is a virtual one
12 $state       =  8; # register represents a state
13 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
14 %reg_classes = (
15         gp => [
16                 { name => "edx" },
17                 { name => "ecx" },
18                 { name => "eax" },
19                 { name => "ebx" },
20                 { name => "esi" },
21                 { name => "edi" },
22                 { name => "ebp" },
23                 { name => "esp", type => $ignore },
24                 { name => "gp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
25                 { mode => "mode_Iu" }
26         ],
27         mmx => [
28                 { name => "mm0", type => $ignore },
29                 { name => "mm1", type => $ignore },
30                 { name => "mm2", type => $ignore },
31                 { name => "mm3", type => $ignore },
32                 { name => "mm4", type => $ignore },
33                 { name => "mm5", type => $ignore },
34                 { name => "mm6", type => $ignore },
35                 { name => "mm7", type => $ignore },
36                 { mode => "mode_E", flags => "manual_ra" }
37         ],
38         xmm => [
39                 { name => "xmm0" },
40                 { name => "xmm1" },
41                 { name => "xmm2" },
42                 { name => "xmm3" },
43                 { name => "xmm4" },
44                 { name => "xmm5" },
45                 { name => "xmm6" },
46                 { name => "xmm7" },
47                 { name => "xmm_NOREG", type => $ignore | $virtual },     # we need a dummy register for NoReg nodes
48                 { mode => "mode_E" }
49         ],
50         vfp => [
51                 { name => "vf0" },
52                 { name => "vf1" },
53                 { name => "vf2" },
54                 { name => "vf3" },
55                 { name => "vf4" },
56                 { name => "vf5" },
57                 { name => "vf6" },
58                 { name => "vf7" },
59                 { name => "vfp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
60                 { mode => "mode_E" }
61         ],
62         st => [
63                 { name => "st0", realname => "st",    type => $ignore },
64                 { name => "st1", realname => "st(1)", type => $ignore },
65                 { name => "st2", realname => "st(2)", type => $ignore },
66                 { name => "st3", realname => "st(3)", type => $ignore },
67                 { name => "st4", realname => "st(4)", type => $ignore },
68                 { name => "st5", realname => "st(5)", type => $ignore },
69                 { name => "st6", realname => "st(6)", type => $ignore },
70                 { name => "st7", realname => "st(7)", type => $ignore },
71                 { mode => "mode_E", flags => "manual_ra" }
72         ],
73         fp_cw => [      # the floating point control word
74                 { name => "fpcw", type => $ignore | $state },
75                 { mode => "ia32_mode_fpcw", flags => "manual_ra|state" }
76         ],
77         flags => [
78                 { name => "eflags", type => 0 },
79                 { mode => "mode_Iu", flags => "manual_ra" }
80         ],
81 ); # %reg_classes
82
83 %cpu = (
84         GP     => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
85         SSE    => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
86         VFP    => [ 1, "VFP_VF0", "VFP_VF1", "VFP_VF2", "VFP_VF3", "VFP_VF4", "VFP_VF5", "VFP_VF6", "VFP_VF7" ],
87         BRANCH => [ 1, "BRANCH1", "BRANCH2" ],
88 ); # %cpu
89
90 %vliw = (
91         bundle_size       => 1,
92         bundels_per_cycle => 1
93 ); # vliw
94
95 %emit_templates = (
96         S0 => "${arch}_emit_source_register(node, 0);",
97         S1 => "${arch}_emit_source_register(node, 1);",
98         S2 => "${arch}_emit_source_register(node, 2);",
99         S3 => "${arch}_emit_source_register(node, 3);",
100         SB0 => "${arch}_emit_8bit_source_register_or_immediate(node, 0);",
101         SB1 => "${arch}_emit_8bit_source_register_or_immediate(node, 1);",
102         SB2 => "${arch}_emit_8bit_source_register_or_immediate(node, 2);",
103         SB3 => "${arch}_emit_8bit_source_register_or_immediate(node, 3);",
104         SH0 => "${arch}_emit_8bit_high_source_register(node, 0);",
105         SS0 => "${arch}_emit_16bit_source_register_or_immediate(node, 0);",
106         SI0 => "${arch}_emit_source_register_or_immediate(node, 0);",
107         SI1 => "${arch}_emit_source_register_or_immediate(node, 1);",
108         SI3 => "${arch}_emit_source_register_or_immediate(node, 3);",
109         D0 => "${arch}_emit_dest_register(node, 0);",
110         D1 => "${arch}_emit_dest_register(node, 1);",
111         DS0 => "${arch}_emit_dest_register_size(node, 0);",
112         DB0 => "${arch}_emit_8bit_dest_register(node, 0);",
113         X0 => "${arch}_emit_x87_register(node, 0);",
114         X1 => "${arch}_emit_x87_register(node, 1);",
115         EX => "${arch}_emit_extend_suffix(node);",
116         M  => "${arch}_emit_mode_suffix(node);",
117         XM => "${arch}_emit_x87_mode_suffix(node);",
118         XXM => "${arch}_emit_xmm_mode_suffix(node);",
119         XSD => "${arch}_emit_xmm_mode_suffix_s(node);",
120         AM => "${arch}_emit_am(node);",
121         unop3 => "${arch}_emit_unop(node, n_ia32_unary_op);",
122         unop4 => "${arch}_emit_unop(node, n_ia32_binary_right);",
123         binop => "${arch}_emit_binop(node);",
124         x87_binop => "${arch}_emit_x87_binop(node);",
125         CMP3  => "${arch}_emit_cmp_suffix_node(node, 3);",
126 );
127
128
129
130
131 $default_op_attr_type = "ia32_op_attr_t";
132 $default_attr_type    = "ia32_attr_t";
133 $default_copy_attr    = "ia32_copy_attr";
134
135 sub ia32_custom_init_attr {
136         my $constr = shift;
137         my $node   = shift;
138         my $name   = shift;
139         my $res    = "";
140
141         if(defined($node->{modified_flags})) {
142                 $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n";
143         }
144         if(defined($node->{am})) {
145                 my $am = $node->{am};
146                 if($am eq "source,unary") {
147                         $res .= "\tset_ia32_am_support(res, ia32_am_unary);";
148                 } elsif($am eq "source,binary") {
149                         $res .= "\tset_ia32_am_support(res, ia32_am_binary);";
150                 } elsif($am eq "none") {
151                         # nothing to do
152                 } else {
153                         die("Invalid address mode '$am' specified on op $name");
154                 }
155                 if($am ne "none") {
156                         if($node->{state} ne "exc_pinned"
157                                         and $node->{state} ne "pinned") {
158                                 die("AM nodes must have pinned or AM pinned state ($name)");
159                         }
160                 }
161         }
162         return $res;
163 }
164 $custom_init_attr_func = \&ia32_custom_init_attr;
165
166 %init_attr = (
167         ia32_asm_attr_t =>
168                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
169                 "\tinit_ia32_x87_attributes(res);".
170                 "\tinit_ia32_asm_attributes(res);",
171         ia32_attr_t     =>
172                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);",
173         ia32_call_attr_t =>
174                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
175                 "\tinit_ia32_call_attributes(res, pop, call_tp);",
176         ia32_condcode_attr_t =>
177                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
178                 "\tinit_ia32_condcode_attributes(res, condition_code);",
179         ia32_switch_attr_t =>
180                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
181                 "\tinit_ia32_switch_attributes(res, default_pn);",
182         ia32_copyb_attr_t =>
183                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
184                 "\tinit_ia32_copyb_attributes(res, size);",
185         ia32_immediate_attr_t =>
186                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
187                 "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
188         ia32_x87_attr_t =>
189                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
190                 "\tinit_ia32_x87_attributes(res);",
191         ia32_climbframe_attr_t =>
192                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
193                 "\tinit_ia32_climbframe_attributes(res, count);",
194 );
195
196 %compare_attr = (
197         ia32_asm_attr_t        => "ia32_compare_asm_attr",
198         ia32_attr_t            => "ia32_compare_nodes_attr",
199         ia32_call_attr_t       => "ia32_compare_call_attr",
200         ia32_condcode_attr_t   => "ia32_compare_condcode_attr",
201         ia32_switch_attr_t     => "ia32_compare_switch_attr",
202         ia32_copyb_attr_t      => "ia32_compare_copyb_attr",
203         ia32_immediate_attr_t  => "ia32_compare_immediate_attr",
204         ia32_x87_attr_t        => "ia32_compare_x87_attr",
205         ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
206 );
207
208 %operands = (
209 );
210
211 $mode_xmm           = "mode_E";
212 $mode_gp            = "mode_Iu";
213 $mode_flags         = "mode_Iu";
214 $mode_fpcw          = "ia32_mode_fpcw";
215 $status_flags       = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
216 $status_flags_wo_cf = [       "PF", "AF", "ZF", "SF", "OF" ];
217 $fpcw_flags         = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
218                         "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
219
220 %nodes = (
221
222 Immediate => {
223         state     => "pinned",
224         op_flags  => [ "constlike" ],
225         irn_flags => [ "not_scheduled" ],
226         reg_req   => { out => [ "gp_NOREG:I" ] },
227         attr      => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
228         attr_type => "ia32_immediate_attr_t",
229         hash_func => "ia32_hash_Immediate",
230         latency   => 0,
231         mode      => $mode_gp,
232 },
233
234 Asm => {
235         mode      => "mode_T",
236         arity     => "variable",
237         out_arity => "variable",
238         attr_type => "ia32_asm_attr_t",
239         attr      => "ident *asm_text, const ia32_asm_reg_t *register_map",
240         init_attr => "attr->asm_text = asm_text;\n".
241                      "\tattr->register_map = register_map;\n",
242         latency   => 10,
243         modified_flags => $status_flags,
244 },
245
246 # "allocates" a free register
247 ProduceVal => {
248         op_flags  => [ "constlike", "cse_neutral" ],
249         irn_flags => [ "rematerializable" ],
250         reg_req   => { out => [ "gp" ] },
251         emit      => "",
252         units     => [ ],
253         latency   => 0,
254         mode      => $mode_gp,
255         cmp_attr  => "return 1;",
256 },
257
258 Add => {
259         irn_flags => [ "rematerializable" ],
260         state     => "exc_pinned",
261         reg_req   => { in  => [ "gp", "gp", "none", "gp", "gp" ],
262                        out => [ "in_r4 in_r5", "flags", "none" ] },
263         ins       => [ "base", "index", "mem", "left", "right" ],
264         outs      => [ "res", "flags", "M" ],
265         emit      => '. add%M %binop',
266         am        => "source,binary",
267         units     => [ "GP" ],
268         latency   => 1,
269         mode      => $mode_gp,
270         modified_flags => $status_flags
271 },
272
273 AddMem => {
274         irn_flags => [ "rematerializable" ],
275         state     => "exc_pinned",
276         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
277         ins       => [ "base", "index", "mem", "val" ],
278         emit      => ". add%M %SI3, %AM",
279         units     => [ "GP" ],
280         latency   => 1,
281         mode      => "mode_M",
282         modified_flags => $status_flags
283 },
284
285 AddMem8Bit => {
286         irn_flags => [ "rematerializable" ],
287         state     => "exc_pinned",
288         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
289         ins       => [ "base", "index", "mem", "val" ],
290         emit      => ". add%M %SB3, %AM",
291         units     => [ "GP" ],
292         latency   => 1,
293         mode      => "mode_M",
294         modified_flags => $status_flags
295 },
296
297 Adc => {
298         state     => "exc_pinned",
299         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
300                        out => [ "in_r4 in_r5", "flags", "none" ] },
301         ins       => [ "base", "index", "mem", "left", "right", "eflags" ],
302         outs      => [ "res", "flags", "M" ],
303         emit      => '. adc%M %binop',
304         am        => "source,binary",
305         units     => [ "GP" ],
306         latency   => 1,
307         mode      => $mode_gp,
308         modified_flags => $status_flags
309 },
310
311 l_Add => {
312         ins       => [ "left", "right" ],
313         attr_type => "",
314         dump_func => "NULL",
315 },
316
317 l_Adc => {
318         ins       => [ "left", "right", "eflags" ],
319         attr_type => "",
320         dump_func => "NULL",
321 },
322
323 Mul => {
324         # we should not rematrialize this node. It produces 2 results and has
325         # very strict constraints
326         state     => "exc_pinned",
327         reg_req   => { in => [ "gp", "gp", "none", "eax", "gp" ],
328                        out => [ "eax", "flags", "none", "edx" ] },
329         ins       => [ "base", "index", "mem", "left", "right" ],
330         emit      => '. mul%M %unop4',
331         outs      => [ "res_low", "flags", "M", "res_high" ],
332         am        => "source,binary",
333         latency   => 10,
334         units     => [ "GP" ],
335         modified_flags => $status_flags
336 },
337
338 l_Mul => {
339         ins       => [ "left", "right" ],
340         outs      => [ "res_low", "flags", "M", "res_high" ],
341         attr_type => "",
342         dump_func => "NULL",
343 },
344
345 IMul => {
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",
355         latency   => 5,
356         units     => [ "GP" ],
357         mode      => $mode_gp,
358         modified_flags => $status_flags
359 },
360
361 IMul1OP => {
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",
370         latency   => 5,
371         units     => [ "GP" ],
372         modified_flags => $status_flags
373 },
374
375 l_IMul => {
376         ins       => [ "left", "right" ],
377         outs      => [ "res_low", "flags", "M", "res_high" ],
378         attr_type => "",
379         dump_func => "NULL",
380 },
381
382 And => {
383         irn_flags => [ "rematerializable" ],
384         state     => "exc_pinned",
385         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
386                            out => [ "in_r4 in_r5", "flags", "none" ] },
387         ins       => [ "base", "index", "mem", "left", "right" ],
388         outs      => [ "res", "flags", "M" ],
389         am        => "source,binary",
390         emit      => '. and%M %binop',
391         units     => [ "GP" ],
392         latency   => 1,
393         mode      => $mode_gp,
394         modified_flags => $status_flags
395 },
396
397 AndMem => {
398         irn_flags => [ "rematerializable" ],
399         state     => "exc_pinned",
400         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
401         ins       => [ "base", "index", "mem", "val" ],
402         emit      => '. and%M %SI3, %AM',
403         units     => [ "GP" ],
404         latency   => 1,
405         mode      => "mode_M",
406         modified_flags => $status_flags
407 },
408
409 AndMem8Bit => {
410         irn_flags => [ "rematerializable" ],
411         state     => "exc_pinned",
412         reg_req   => { in => [ "gp", "gp", "none",  "eax ebx ecx edx" ], out => [ "none" ] },
413         ins       => [ "base", "index", "mem", "val" ],
414         emit      => '. and%M %SB3, %AM',
415         units     => [ "GP" ],
416         latency   => 1,
417         mode      => "mode_M",
418         modified_flags => $status_flags
419 },
420
421 Or => {
422         irn_flags => [ "rematerializable" ],
423         state     => "exc_pinned",
424         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
425                        out => [ "in_r4 in_r5", "flags", "none" ] },
426         ins       => [ "base", "index", "mem", "left", "right" ],
427         outs      => [ "res", "flags", "M" ],
428         am        => "source,binary",
429         emit      => '. or%M %binop',
430         units     => [ "GP" ],
431         latency   => 1,
432         mode      => $mode_gp,
433         modified_flags => $status_flags
434 },
435
436 OrMem => {
437         irn_flags => [ "rematerializable" ],
438         state     => "exc_pinned",
439         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
440         ins       => [ "base", "index", "mem", "val" ],
441         emit      => '. or%M %SI3, %AM',
442         units     => [ "GP" ],
443         latency   => 1,
444         mode      => "mode_M",
445         modified_flags => $status_flags
446 },
447
448 OrMem8Bit => {
449         irn_flags => [ "rematerializable" ],
450         state     => "exc_pinned",
451         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
452         ins       => [ "base", "index", "mem", "val" ],
453         emit      => '. or%M %SB3, %AM',
454         units     => [ "GP" ],
455         latency   => 1,
456         mode      => "mode_M",
457         modified_flags => $status_flags
458 },
459
460 Xor => {
461         irn_flags => [ "rematerializable" ],
462         state     => "exc_pinned",
463         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
464                        out => [ "in_r4 in_r5", "flags", "none" ] },
465         ins       => [ "base", "index", "mem", "left", "right" ],
466         outs      => [ "res", "flags", "M" ],
467         am        => "source,binary",
468         emit      => '. xor%M %binop',
469         units     => [ "GP" ],
470         latency   => 1,
471         mode      => $mode_gp,
472         modified_flags => $status_flags
473 },
474
475 Xor0 => {
476         op_flags  => [ "constlike" ],
477         irn_flags => [ "rematerializable" ],
478         reg_req   => { out => [ "gp", "flags" ] },
479         outs      => [ "res", "flags" ],
480         emit      => ". xor%M %D0, %D0",
481         units     => [ "GP" ],
482         latency   => 1,
483         mode      => $mode_gp,
484         modified_flags => $status_flags
485 },
486
487 XorMem => {
488         irn_flags => [ "rematerializable" ],
489         state     => "exc_pinned",
490         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
491         ins       => [ "base", "index", "mem", "val" ],
492         emit      => '. xor%M %SI3, %AM',
493         units     => [ "GP" ],
494         latency   => 1,
495         mode      => "mode_M",
496         modified_flags => $status_flags
497 },
498
499 XorMem8Bit => {
500         irn_flags => [ "rematerializable" ],
501         state     => "exc_pinned",
502         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
503         ins       => [ "base", "index", "mem", "val" ],
504         emit      => '. xor%M %SB3, %AM',
505         units     => [ "GP" ],
506         latency   => 1,
507         mode      => "mode_M",
508         modified_flags => $status_flags
509 },
510
511 Sub => {
512         irn_flags => [ "rematerializable" ],
513         state     => "exc_pinned",
514         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
515                        out => [ "in_r4", "flags", "none" ] },
516         ins       => [ "base", "index", "mem", "minuend", "subtrahend" ],
517         outs      => [ "res", "flags", "M" ],
518         am        => "source,binary",
519         emit      => '. sub%M %binop',
520         units     => [ "GP" ],
521         latency   => 1,
522         mode      => $mode_gp,
523         modified_flags => $status_flags
524 },
525
526 SubMem => {
527         irn_flags => [ "rematerializable" ],
528         state     => "exc_pinned",
529         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
530         ins       => [ "base", "index", "mem", "subtrahend" ],
531         emit      => '. sub%M %SI3, %AM',
532         units     => [ "GP" ],
533         latency   => 1,
534         mode      => 'mode_M',
535         modified_flags => $status_flags
536 },
537
538 SubMem8Bit => {
539         irn_flags => [ "rematerializable" ],
540         state     => "exc_pinned",
541         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
542         ins       => [ "base", "index", "mem", "subtrahend" ],
543         emit      => '. sub%M %SB3, %AM',
544         units     => [ "GP" ],
545         latency   => 1,
546         mode      => 'mode_M',
547         modified_flags => $status_flags
548 },
549
550 Sbb => {
551         state     => "exc_pinned",
552         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
553                        out => [ "in_r4", "flags", "none" ] },
554         ins       => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
555         outs      => [ "res", "flags", "M" ],
556         am        => "source,binary",
557         emit      => '. sbb%M %binop',
558         units     => [ "GP" ],
559         latency   => 1,
560         mode      => $mode_gp,
561         modified_flags => $status_flags
562 },
563
564 Sbb0 => {
565         # Spiller currently fails when rematerializing flag consumers
566         # irn_flags => [ "rematerializable" ],
567         reg_req   => { in => [ "flags" ], out => [ "gp", "flags" ] },
568         outs      => [ "res", "flags" ],
569         emit      => ". sbb%M %D0, %D0",
570         units     => [ "GP" ],
571         latency   => 1,
572         mode      => $mode_gp,
573         modified_flags => $status_flags
574 },
575
576 l_Sub => {
577         ins       => [ "minuend", "subtrahend" ],
578         attr_type => "",
579         dump_func => "NULL",
580 },
581
582 l_Sbb => {
583         ins       => [ "minuend", "subtrahend", "eflags" ],
584         attr_type => "",
585         dump_func => "NULL",
586 },
587
588 IDiv => {
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", "none" ] },
593         ins       => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
594         outs      => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
595         am        => "source,unary",
596         emit      => ". idiv%M %unop3",
597         latency   => 25,
598         units     => [ "GP" ],
599         modified_flags => $status_flags
600 },
601
602 Div => {
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", "none" ] },
607         ins       => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
608         outs      => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
609         am        => "source,unary",
610         emit      => ". div%M %unop3",
611         latency   => 25,
612         units     => [ "GP" ],
613         modified_flags => $status_flags
614 },
615
616 Shl => {
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',
623         units     => [ "GP" ],
624         latency   => 1,
625         mode      => $mode_gp,
626         modified_flags => $status_flags
627 },
628
629 ShlMem => {
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',
635         units     => [ "GP" ],
636         latency   => 1,
637         mode      => "mode_M",
638         modified_flags => $status_flags
639 },
640
641 ShlD => {
642         irn_flags => [ "rematerializable" ],
643         reg_req   => { in => [ "gp", "gp", "ecx" ],
644                        out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
645         ins       => [ "val_high", "val_low", "count" ],
646         outs      => [ "res", "flags" ],
647         emit      => ". shld%M %SB2, %S1, %D0",
648         latency   => 6,
649         units     => [ "GP" ],
650         mode      => $mode_gp,
651         modified_flags => $status_flags
652 },
653
654 Shr => {
655         irn_flags => [ "rematerializable" ],
656         reg_req   => { in => [ "gp", "ecx" ],
657                        out => [ "in_r1 !in_r2", "flags" ] },
658         ins       => [ "val", "count" ],
659         outs      => [ "res", "flags" ],
660         emit      => '. shr%M %SB1, %S0',
661         units     => [ "GP" ],
662         mode      => $mode_gp,
663         latency   => 1,
664         modified_flags => $status_flags
665 },
666
667 ShrMem => {
668         irn_flags => [ "rematerializable" ],
669         state     => "exc_pinned",
670         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
671         ins       => [ "base", "index", "mem", "count" ],
672         emit      => '. shr%M %SB3, %AM',
673         units     => [ "GP" ],
674         mode      => "mode_M",
675         latency   => 1,
676         modified_flags => $status_flags
677 },
678
679 ShrD => {
680         irn_flags => [ "rematerializable" ],
681         reg_req   => { in => [ "gp", "gp", "ecx" ],
682                        out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
683         ins       => [ "val_high", "val_low", "count" ],
684         outs      => [ "res", "flags" ],
685         emit      => ". shrd%M %SB2, %S1, %D0",
686         latency   => 6,
687         units     => [ "GP" ],
688         mode      => $mode_gp,
689         modified_flags => $status_flags
690 },
691
692 Sar => {
693         irn_flags => [ "rematerializable" ],
694         reg_req   => { in => [ "gp", "ecx" ],
695                        out => [ "in_r1 !in_r2", "flags" ] },
696         ins       => [ "val", "count" ],
697         outs      => [ "res", "flags" ],
698         emit      => '. sar%M %SB1, %S0',
699         units     => [ "GP" ],
700         latency   => 1,
701         mode      => $mode_gp,
702         modified_flags => $status_flags
703 },
704
705 SarMem => {
706         irn_flags => [ "rematerializable" ],
707         state     => "exc_pinned",
708         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
709         ins       => [ "base", "index", "mem", "count" ],
710         emit      => '. sar%M %SB3, %AM',
711         units     => [ "GP" ],
712         latency   => 1,
713         mode      => "mode_M",
714         modified_flags => $status_flags
715 },
716
717 Ror => {
718         irn_flags => [ "rematerializable" ],
719         reg_req   => { in => [ "gp", "ecx" ],
720                        out => [ "in_r1 !in_r2", "flags" ] },
721         ins       => [ "val", "count" ],
722         outs      => [ "res", "flags" ],
723         emit      => '. ror%M %SB1, %S0',
724         units     => [ "GP" ],
725         latency   => 1,
726         mode      => $mode_gp,
727         modified_flags => $status_flags
728 },
729
730 RorMem => {
731         irn_flags => [ "rematerializable" ],
732         state     => "exc_pinned",
733         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
734         ins       => [ "base", "index", "mem", "count" ],
735         emit      => '. ror%M %SB3, %AM',
736         units     => [ "GP" ],
737         latency   => 1,
738         mode      => "mode_M",
739         modified_flags => $status_flags
740 },
741
742 Rol => {
743         irn_flags => [ "rematerializable" ],
744         reg_req   => { in => [ "gp", "ecx" ],
745                        out => [ "in_r1 !in_r2", "flags" ] },
746         ins       => [ "val", "count" ],
747         outs      => [ "res", "flags" ],
748         emit      => '. rol%M %SB1, %S0',
749         units     => [ "GP" ],
750         latency   => 1,
751         mode      => $mode_gp,
752         modified_flags => $status_flags
753 },
754
755 RolMem => {
756         irn_flags => [ "rematerializable" ],
757         state     => "exc_pinned",
758         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
759         ins       => [ "base", "index", "mem", "count" ],
760         emit      => '. rol%M %SB3, %AM',
761         units     => [ "GP" ],
762         latency   => 1,
763         mode      => "mode_M",
764         modified_flags => $status_flags
765 },
766
767 Neg => {
768         irn_flags => [ "rematerializable" ],
769         reg_req   => { in => [ "gp" ],
770                        out => [ "in_r1", "flags" ] },
771         emit      => '. neg%M %S0',
772         ins       => [ "val" ],
773         outs      => [ "res", "flags" ],
774         units     => [ "GP" ],
775         latency   => 1,
776         mode      => $mode_gp,
777         modified_flags => $status_flags
778 },
779
780 NegMem => {
781         irn_flags => [ "rematerializable" ],
782         state     => "exc_pinned",
783         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
784         ins       => [ "base", "index", "mem" ],
785         emit      => '. neg%M %AM',
786         units     => [ "GP" ],
787         latency   => 1,
788         mode      => "mode_M",
789         modified_flags => $status_flags
790 },
791
792 Minus64Bit => {
793         irn_flags => [ "rematerializable" ],
794         reg_req   => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
795         outs      => [ "low_res", "high_res" ],
796         units     => [ "GP" ],
797         latency   => 3,
798         modified_flags => $status_flags
799 },
800
801
802 Inc => {
803         irn_flags => [ "rematerializable" ],
804         reg_req   => { in => [ "gp" ],
805                        out => [ "in_r1", "flags" ] },
806         ins       => [ "val" ],
807         outs      => [ "res", "flags" ],
808         emit      => '. inc%M %S0',
809         units     => [ "GP" ],
810         mode      => $mode_gp,
811         latency   => 1,
812         modified_flags => $status_flags_wo_cf
813 },
814
815 IncMem => {
816         irn_flags => [ "rematerializable" ],
817         state     => "exc_pinned",
818         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
819         ins       => [ "base", "index", "mem" ],
820         emit      => '. inc%M %AM',
821         units     => [ "GP" ],
822         mode      => "mode_M",
823         latency   => 1,
824         modified_flags => $status_flags_wo_cf
825 },
826
827 Dec => {
828         irn_flags => [ "rematerializable" ],
829         reg_req   => { in => [ "gp" ],
830                        out => [ "in_r1", "flags" ] },
831         ins       => [ "val" ],
832         outs      => [ "res", "flags" ],
833         emit      => '. dec%M %S0',
834         units     => [ "GP" ],
835         mode      => $mode_gp,
836         latency   => 1,
837         modified_flags => $status_flags_wo_cf
838 },
839
840 DecMem => {
841         irn_flags => [ "rematerializable" ],
842         state     => "exc_pinned",
843         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
844         ins       => [ "base", "index", "mem" ],
845         emit      => '. dec%M %AM',
846         units     => [ "GP" ],
847         mode      => "mode_M",
848         latency   => 1,
849         modified_flags => $status_flags_wo_cf
850 },
851
852 Not => {
853         irn_flags => [ "rematerializable" ],
854         reg_req   => { in => [ "gp" ],
855                        out => [ "in_r1" ] },
856         ins       => [ "val" ],
857         outs      => [ "res" ],
858         emit      => '. not%M %S0',
859         units     => [ "GP" ],
860         latency   => 1,
861         mode      => $mode_gp,
862         # no flags modified
863 },
864
865 NotMem => {
866         irn_flags => [ "rematerializable" ],
867         state     => "exc_pinned",
868         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
869         ins       => [ "base", "index", "mem" ],
870         emit      => '. not%M %AM',
871         units     => [ "GP" ],
872         latency   => 1,
873         mode      => "mode_M",
874         # no flags modified
875 },
876
877 Cmc => {
878         reg_req   => { in => [ "flags" ], out => [ "flags" ] },
879         emit      => '.cmc',
880         units     => [ "GP" ],
881         latency   => 1,
882         mode      => $mode_flags,
883         modified_flags => $status_flags
884 },
885
886 Stc => {
887         reg_req   => { out => [ "flags" ] },
888         emit      => '.stc',
889         units     => [ "GP" ],
890         latency   => 1,
891         mode      => $mode_flags,
892         modified_flags => $status_flags
893 },
894
895 Cmp => {
896         irn_flags => [ "rematerializable" ],
897         state     => "exc_pinned",
898         reg_req   => { in  => [ "gp", "gp", "none", "gp", "gp" ],
899                        out => [ "flags", "none", "none" ] },
900         ins       => [ "base", "index", "mem", "left", "right" ],
901         outs      => [ "eflags", "unused", "M" ],
902         am        => "source,binary",
903         emit      => '. cmp%M %binop',
904         attr      => "bool ins_permuted",
905         init_attr => "attr->data.ins_permuted   = ins_permuted;",
906         latency   => 1,
907         units     => [ "GP" ],
908         mode      => $mode_flags,
909         modified_flags => $status_flags
910 },
911
912 Cmp8Bit => {
913         irn_flags => [ "rematerializable" ],
914         state     => "exc_pinned",
915         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
916                        out => [ "flags", "none", "none" ] },
917         ins       => [ "base", "index", "mem", "left", "right" ],
918         outs      => [ "eflags", "unused", "M" ],
919         am        => "source,binary",
920         emit      => '. cmpb %binop',
921         attr      => "bool ins_permuted",
922         init_attr => "attr->data.ins_permuted   = ins_permuted;",
923         latency   => 1,
924         units     => [ "GP" ],
925         mode      => $mode_flags,
926         modified_flags => $status_flags
927 },
928
929 XorHighLow => {
930         irn_flags => [ "rematerializable" ],
931         state     => "exc_pinned",
932         reg_req   => { in => [ "eax ebx ecx edx" ],
933                        out => [ "in_r1", "flags" ] },
934         emit      => '. xorb %SH0, %SB0',
935         ins       => [ "value" ],
936         outs      => [ "res", "flags" ],
937         units     => [ "GP" ],
938         latency   => 1,
939         mode      => $mode_gp,
940         modified_flags => $status_flags,
941 },
942
943 Test => {
944         irn_flags => [ "rematerializable" ],
945         state     => "exc_pinned",
946         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ] ,
947                        out => [ "flags", "none", "none" ] },
948         ins       => [ "base", "index", "mem", "left", "right" ],
949         outs      => [ "eflags", "unused", "M" ],
950         am        => "source,binary",
951         emit      => '. test%M %binop',
952         attr      => "bool ins_permuted",
953         init_attr => "attr->data.ins_permuted = ins_permuted;",
954         latency   => 1,
955         units     => [ "GP" ],
956         mode      => $mode_flags,
957         modified_flags => $status_flags
958 },
959
960 Test8Bit => {
961         irn_flags => [ "rematerializable" ],
962         state     => "exc_pinned",
963         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
964                        out => [ "flags", "none", "none" ] },
965         ins       => [ "base", "index", "mem", "left", "right" ],
966         outs      => [ "eflags", "unused", "M" ],
967         am        => "source,binary",
968         emit      => '. testb %binop',
969         attr      => "bool ins_permuted",
970         init_attr => "attr->data.ins_permuted = ins_permuted;",
971         latency   => 1,
972         units     => [ "GP" ],
973         mode      => $mode_flags,
974         modified_flags => $status_flags
975 },
976
977 l_Setcc => {
978         ins       => [ "cond" ],
979         outs      => [ "res" ],
980         mode      => "mode_Bu",
981         attr_type => "",
982         dump_func => "NULL",
983 },
984
985 Setcc => {
986         #irn_flags => [ "rematerializable" ],
987         reg_req   => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
988         ins       => [ "eflags" ],
989         outs      => [ "res" ],
990         attr_type => "ia32_condcode_attr_t",
991         attr      => "ia32_condition_code_t condition_code",
992         # The way we handle Setcc with float nodes (potentially) destroys the flags
993         # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
994         init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
995                 . "\tif (condition_code & ia32_cc_additional_float_cases) {\n"
996                 . "\t\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"
997                 . "\t\t/* attr->latency = 3; */\n"
998                 . "\t}\n",
999         latency   => 1,
1000         units     => [ "GP" ],
1001         mode      => $mode_gp,
1002 },
1003
1004 SetccMem => {
1005         #irn_flags => [ "rematerializable" ],
1006         state     => "exc_pinned",
1007         reg_req   => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
1008         ins       => [ "base", "index", "mem","eflags" ],
1009         attr_type => "ia32_condcode_attr_t",
1010         attr      => "ia32_condition_code_t condition_code",
1011         init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
1012         emit      => '. set%CMP3 %AM',
1013         latency   => 1,
1014         units     => [ "GP" ],
1015         mode      => 'mode_M',
1016 },
1017
1018 CMovcc => {
1019         #irn_flags => [ "rematerializable" ],
1020         state     => "exc_pinned",
1021         # (note: leave the false,true order intact to make it compatible with other
1022         #  ia32_binary ops)
1023         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
1024                        out => [ "in_r4 in_r5", "flags", "none" ] },
1025         ins       => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
1026         outs      => [ "res", "flags", "M" ],
1027         am        => "source,binary",
1028         attr_type => "ia32_condcode_attr_t",
1029         attr      => "ia32_condition_code_t condition_code",
1030         latency   => 1,
1031         units     => [ "GP" ],
1032         mode      => $mode_gp,
1033 },
1034
1035 Jcc => {
1036         state     => "pinned",
1037         op_flags  => [ "labeled", "cfopcode", "forking" ],
1038         reg_req   => { in  => [ "eflags" ], out => [ "none", "none" ] },
1039         ins       => [ "eflags" ],
1040         outs      => [ "false", "true" ],
1041         attr_type => "ia32_condcode_attr_t",
1042         attr      => "ia32_condition_code_t condition_code",
1043         latency   => 2,
1044         units     => [ "BRANCH" ],
1045 },
1046
1047 SwitchJmp => {
1048         state     => "pinned",
1049         op_flags  => [ "labeled", "cfopcode", "forking" ],
1050         reg_req   => { in => [ "gp", "gp" ] },
1051         ins       => [ "base", "index" ],
1052         mode      => "mode_T",
1053         attr_type => "ia32_switch_attr_t",
1054         attr      => "long default_pn",
1055         latency   => 2,
1056         units     => [ "BRANCH" ],
1057         init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements
1058 },
1059
1060 Jmp => {
1061         state     => "pinned",
1062         irn_flags => [ "simple_jump" ],
1063         op_flags  => [ "cfopcode" ],
1064         reg_req   => { out => [ "none" ] },
1065         latency   => 1,
1066         units     => [ "BRANCH" ],
1067         mode      => "mode_X",
1068 },
1069
1070 IJmp => {
1071         state     => "pinned",
1072         op_flags  => [ "cfopcode", "unknown_jump" ],
1073         reg_req   => { in => [ "gp", "gp", "none", "gp" ] },
1074         ins       => [ "base", "index", "mem", "target" ],
1075         am        => "source,unary",
1076         emit      => '. jmp *%unop3',
1077         latency   => 1,
1078         units     => [ "BRANCH" ],
1079         mode      => "mode_X",
1080         init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements
1081 },
1082
1083 Const => {
1084         op_flags  => [ "constlike" ],
1085         irn_flags => [ "rematerializable" ],
1086         reg_req   => { out => [ "gp" ] },
1087         units     => [ "GP" ],
1088         attr      => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
1089         attr_type => "ia32_immediate_attr_t",
1090         latency   => 1,
1091         mode      => $mode_gp,
1092 },
1093
1094 Unknown => {
1095         op_flags  => [ "constlike" ],
1096         irn_flags => [ "rematerializable" ],
1097         reg_req   => { out => [ "gp" ] },
1098         latency   => 0,
1099         emit      => '',
1100         mode      => $mode_gp,
1101 },
1102
1103 GetEIP => {
1104         op_flags => [ "constlike" ],
1105         reg_req  => { out => [ "gp" ] },
1106         units    => [ "GP" ],
1107         latency  => 5,
1108         mode     => $mode_gp,
1109         modified_flags => $status_flags,
1110 },
1111
1112 NoReg_GP => {
1113         state     => "pinned",
1114         op_flags  => [ "constlike", "dump_noblock", "dump_noinput" ],
1115         irn_flags => [ "not_scheduled" ],
1116         reg_req   => { out => [ "gp_NOREG:I" ] },
1117         units     => [],
1118         emit      => "",
1119         latency   => 0,
1120         mode      => $mode_gp
1121 },
1122
1123 NoReg_VFP => {
1124         state     => "pinned",
1125         op_flags  => [ "constlike", "dump_noblock", "dump_noinput" ],
1126         irn_flags => [ "not_scheduled" ],
1127         reg_req   => { out => [ "vfp_NOREG:I" ] },
1128         units     => [],
1129         emit      => "",
1130         mode      => "mode_E",
1131         latency   => 0,
1132         attr_type => "ia32_x87_attr_t",
1133 },
1134
1135 NoReg_XMM => {
1136         state     => "pinned",
1137         op_flags  => [ "constlike", "dump_noblock", "dump_noinput" ],
1138         irn_flags => [ "not_scheduled" ],
1139         reg_req   => { out => [ "xmm_NOREG:I" ] },
1140         units     => [],
1141         emit      => "",
1142         latency   => 0,
1143         mode      => "mode_E"
1144 },
1145
1146 ChangeCW => {
1147         state     => "pinned",
1148         op_flags  => [ "constlike" ],
1149         irn_flags => [ "not_scheduled" ],
1150         reg_req   => { out => [ "fpcw:I" ] },
1151         mode      => $mode_fpcw,
1152         latency   => 3,
1153         units     => [ "GP" ],
1154         modified_flags => $fpcw_flags
1155 },
1156
1157 FldCW => {
1158         op_flags  => [ "labeled" ],
1159         state     => "pinned",
1160         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] },
1161         ins       => [ "base", "index", "mem" ],
1162         latency   => 5,
1163         emit      => ". fldcw %AM",
1164         mode      => $mode_fpcw,
1165         units     => [ "GP" ],
1166         modified_flags => $fpcw_flags
1167 },
1168
1169 FnstCW => {
1170         op_flags  => [ "labeled" ],
1171         state     => "pinned",
1172         reg_req   => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1173         ins       => [ "base", "index", "mem", "fpcw" ],
1174         latency   => 5,
1175         emit      => ". fnstcw %AM",
1176         mode      => "mode_M",
1177         units     => [ "GP" ],
1178 },
1179
1180 FnstCWNOP => {
1181         op_flags  => [ "labeled" ],
1182         state     => "pinned",
1183         reg_req   => { in => [ "fp_cw" ], out => [ "none" ] },
1184         ins       => [ "fpcw" ],
1185         latency   => 0,
1186         emit      => "",
1187         mode      => "mode_M",
1188 },
1189
1190 Cltd => {
1191         # we should not rematrialize this node. It has very strict constraints.
1192         reg_req   => { in => [ "eax", "edx" ], out => [ "edx" ] },
1193         ins       => [ "val", "clobbered" ],
1194         emit      => '. cltd',
1195         latency   => 1,
1196         mode      => $mode_gp,
1197         units     => [ "GP" ],
1198 },
1199
1200 # Load / Store
1201 #
1202 # Note that we add additional latency values depending on address mode, so a
1203 # lateny of 0 for load is correct
1204
1205 Load => {
1206         op_flags  => [ "fragile", "labeled" ],
1207         state     => "exc_pinned",
1208         reg_req   => { in => [ "gp", "gp", "none" ],
1209                        out => [ "gp", "none", "none", "none", "none" ] },
1210         ins       => [ "base", "index", "mem" ],
1211         outs      => [ "res", "unused", "M", "X_regular", "X_except" ],
1212         latency   => 0,
1213         emit      => ". mov%EX%.l %AM, %D0",
1214         units     => [ "GP" ],
1215 },
1216
1217 Store => {
1218         op_flags  => [ "fragile", "labeled" ],
1219         state     => "exc_pinned",
1220         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1221                        out => [ "none", "none", "none" ] },
1222         ins       => [ "base", "index", "mem", "val" ],
1223         outs      => [ "M", "X_regular", "X_except" ],
1224         emit      => '. mov%M %SI3, %AM',
1225         latency   => 2,
1226         units     => [ "GP" ],
1227 },
1228
1229 Store8Bit => {
1230         op_flags  => [ "fragile", "labeled" ],
1231         state     => "exc_pinned",
1232         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1233                        out => ["none", "none", "none" ] },
1234         ins       => [ "base", "index", "mem", "val" ],
1235         outs      => [ "M", "X_regular", "X_except" ],
1236         emit      => '. mov%M %SB3, %AM',
1237         latency   => 2,
1238         units     => [ "GP" ],
1239 },
1240
1241 Lea => {
1242         irn_flags => [ "rematerializable" ],
1243         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
1244         ins       => [ "base", "index" ],
1245         emit      => '. leal %AM, %D0',
1246         latency   => 2,
1247         units     => [ "GP" ],
1248         mode      => $mode_gp,
1249 # lea doesn't modify the flags, but setting this seems advantageous since it
1250 # increases chances that the Lea is transformed back to an Add
1251         modified_flags => 1,
1252 },
1253
1254 Push => {
1255         state     => "exc_pinned",
1256         reg_req   => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1257         ins       => [ "base", "index", "mem", "val", "stack" ],
1258         emit      => '. push%M %unop3',
1259         outs      => [ "stack", "M" ],
1260         am        => "source,unary",
1261         latency   => 2,
1262         units     => [ "GP" ],
1263 },
1264
1265 PushEax => {
1266         state   => "exc_pinned",
1267         reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1268         ins     => [ "stack" ],
1269         outs    => [ "stack" ],
1270         emit    => '. pushl %%eax',
1271         latency => 2,
1272         units   => [ "GP" ],
1273         mode    => $mode_gp,
1274 },
1275
1276 Pop => {
1277         state     => "exc_pinned",
1278         reg_req   => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1279         ins       => [ "mem", "stack" ],
1280         outs      => [ "res", "M", "unused", "stack" ],
1281         emit      => '. pop%M %D0',
1282         latency   => 3, # Pop is more expensive than Push on Athlon
1283         units     => [ "GP" ],
1284 },
1285
1286 PopEbp => {
1287         state     => "exc_pinned",
1288         reg_req   => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1289         ins       => [ "mem", "stack" ],
1290         outs      => [ "res", "M", "unused", "stack" ],
1291         emit      => '. pop%M %D0',
1292         latency   => 3, # Pop is more expensive than Push on Athlon
1293         units     => [ "GP" ],
1294 },
1295
1296 CopyEbpEsp => {
1297         state     => "exc_pinned",
1298         reg_req   => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1299         ins       => [ "ebp" ],
1300         outs      => [ "esp" ],
1301         emit      => '. movl %S0, %D0',
1302         latency   => 1,
1303         units     => [ "GP" ],
1304         mode      => $mode_gp,
1305 },
1306
1307 PopMem => {
1308         state     => "exc_pinned",
1309         reg_req   => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1310         ins       => [ "base", "index", "mem", "stack" ],
1311         outs      => [ "unused0", "M", "unused1", "stack" ],
1312         emit      => '. pop%M %AM',
1313         latency   => 3, # Pop is more expensive than Push on Athlon
1314         units     => [ "GP" ],
1315 },
1316
1317 Enter => {
1318         reg_req   => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1319         emit      => '. enter',
1320         outs      => [ "frame", "stack", "M" ],
1321         latency   => 15,
1322         units     => [ "GP" ],
1323 },
1324
1325 Leave => {
1326         reg_req   => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1327         emit      => '. leave',
1328         outs      => [ "frame", "stack" ],
1329         latency   => 3,
1330         units     => [ "GP" ],
1331         state     => "exc_pinned",
1332 },
1333
1334 AddSP => {
1335         state     => "pinned",
1336         reg_req   => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1337         ins       => [ "base", "index", "mem", "stack", "size" ],
1338         am        => "source,binary",
1339         emit      => '. addl %binop',
1340         latency   => 1,
1341         outs      => [ "stack", "M" ],
1342         units     => [ "GP" ],
1343         modified_flags => $status_flags
1344 },
1345
1346 SubSP => {
1347         state     => "pinned",
1348         reg_req   => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1349         ins       => [ "base", "index", "mem", "stack", "size" ],
1350         am        => "source,binary",
1351         emit      => ". subl %binop\n".
1352                      ". movl %%esp, %D1",
1353         latency   => 2,
1354         outs      => [ "stack", "addr", "M" ],
1355         units     => [ "GP" ],
1356         modified_flags => $status_flags
1357 },
1358
1359 RepPrefix => {
1360         op_flags  => [ "keep" ],
1361         state     => "pinned",
1362         mode      => "mode_M",
1363         emit      => ". rep",
1364         latency   => 0,
1365 },
1366
1367 LdTls => {
1368         irn_flags => [ "rematerializable" ],
1369         reg_req   => { out => [ "gp" ] },
1370         units     => [ "GP" ],
1371         emit      => ". movl %%gs:0, %D0",
1372         mode      => $mode_gp,
1373         latency   => 1,
1374 },
1375
1376 #
1377 # BT supports source address mode, but this is unused yet
1378 #
1379 Bt => {
1380         irn_flags => [ "rematerializable" ],
1381         state     => "exc_pinned",
1382         reg_req   => { in => [ "gp", "gp" ], out => [ "flags" ] },
1383         ins       => [ "left", "right" ],
1384         emit      => '. bt%M %S1, %S0',
1385         units     => [ "GP" ],
1386         latency   => 1,
1387         mode      => $mode_flags,
1388         modified_flags => $status_flags  # only CF is set, but the other flags are undefined
1389 },
1390
1391 Bsf => {
1392         irn_flags => [ "rematerializable" ],
1393         state     => "exc_pinned",
1394         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1395                        out => [ "gp", "flags", "none" ] },
1396         ins       => [ "base", "index", "mem", "operand" ],
1397         outs      => [ "res", "flags", "M" ],
1398         am        => "source,binary",
1399         emit      => '. bsf%M %unop3, %D0',
1400         units     => [ "GP" ],
1401         latency   => 1,
1402         mode      => $mode_gp,
1403         modified_flags => $status_flags
1404 },
1405
1406 Bsr => {
1407         irn_flags => [ "rematerializable" ],
1408         state     => "exc_pinned",
1409         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1410                        out => [ "gp", "flags", "none" ] },
1411         ins       => [ "base", "index", "mem", "operand" ],
1412         outs      => [ "res", "flags", "M" ],
1413         am        => "source,binary",
1414         emit      => '. bsr%M %unop3, %D0',
1415         units     => [ "GP" ],
1416         latency   => 1,
1417         mode      => $mode_gp,
1418         modified_flags => $status_flags
1419 },
1420
1421 #
1422 # SSE4.2 or SSE4a popcnt instruction
1423 #
1424 Popcnt => {
1425         irn_flags => [ "rematerializable" ],
1426         state     => "exc_pinned",
1427         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1428                        out => [ "gp", "flags", "none" ] },
1429         ins       => [ "base", "index", "mem", "operand" ],
1430         outs      => [ "res", "flags", "M" ],
1431         am        => "source,binary",
1432         emit      => '. popcnt%M %unop3, %D0',
1433         units     => [ "GP" ],
1434         latency   => 1,
1435         mode      => $mode_gp,
1436         modified_flags => $status_flags
1437 },
1438
1439 Call => {
1440         op_flags  => [ "fragile" ],
1441         state     => "exc_pinned",
1442         reg_req   => {
1443                 in  => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1444                 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", "none", "none" ]
1445         },
1446         ins       => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1447         outs      => [ "stack", "fpcw", "M", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "X_regular", "X_except" ],
1448         attr_type => "ia32_call_attr_t",
1449         attr      => "unsigned pop, ir_type *call_tp",
1450         am        => "source,unary",
1451         units     => [ "BRANCH" ],
1452         latency   => 4, # random number
1453         modified_flags => $status_flags
1454 },
1455
1456 #
1457 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1458 #
1459 # PS: try gcc __builtin_frame_address(100000) :-)
1460 #
1461 ClimbFrame => {
1462         reg_req   => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1463         ins       => [ "frame", "cnt", "tmp" ],
1464         outs      => [ "res" ],
1465         latency   => 4, # random number
1466         attr_type => "ia32_climbframe_attr_t",
1467         attr      => "unsigned count",
1468         units     => [ "GP" ],
1469         mode      => $mode_gp
1470 },
1471
1472 #
1473 # bswap
1474 #
1475 Bswap => {
1476         irn_flags => [ "rematerializable" ],
1477         reg_req   => { in => [ "gp" ],
1478                        out => [ "in_r1" ] },
1479         emit      => '. bswap%M %S0',
1480         ins       => [ "val" ],
1481         units     => [ "GP" ],
1482         latency   => 1,
1483         mode      => $mode_gp,
1484 },
1485
1486 #
1487 # bswap16, use xchg here
1488 #
1489 Bswap16 => {
1490         irn_flags => [ "rematerializable" ],
1491         reg_req   => { in => [ "eax ebx ecx edx" ],
1492                        out => [ "in_r1" ] },
1493         emit      => '. xchg %SB0, %SH0',
1494         ins       => [ "val" ],
1495         units     => [ "GP" ],
1496         latency   => 1,
1497         mode      => $mode_gp,
1498 },
1499
1500 #
1501 # BreakPoint
1502 #
1503 Breakpoint => {
1504         state     => "pinned",
1505         reg_req   => { in => [ "none" ], out => [ "none" ] },
1506         ins       => [ "mem" ],
1507         latency   => 0,
1508         emit      => ". int3",
1509         units     => [ "GP" ],
1510         mode      => mode_M,
1511 },
1512
1513 #
1514 # Undefined Instruction on ALL x86 CPU's
1515 #
1516 UD2 => {
1517         state     => "pinned",
1518         reg_req   => { in => [ "none" ], out => [ "none" ] },
1519         ins       => [ "mem" ],
1520         latency   => 0,
1521         emit      => ". .value  0x0b0f",
1522         units     => [ "GP" ],
1523         mode      => mode_M,
1524 },
1525
1526 #
1527 # outport
1528 #
1529 Outport => {
1530         irn_flags => [ "rematerializable" ],
1531         state     => "pinned",
1532         reg_req   => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1533         ins       => [ "port", "value", "mem" ],
1534         emit      => '. out%M %SS0, %SI1',
1535         units     => [ "GP" ],
1536         latency   => 1,
1537         mode      => mode_M,
1538         modified_flags => $status_flags
1539 },
1540
1541 #
1542 # inport
1543 #
1544 Inport => {
1545         irn_flags => [ "rematerializable" ],
1546         state     => "pinned",
1547         reg_req   => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1548         ins       => [ "port", "mem" ],
1549         outs      => [ "res", "M" ],
1550         emit      => '. in%M %DS0, %SS0',
1551         units     => [ "GP" ],
1552         latency   => 1,
1553         mode      => mode_T,
1554         modified_flags => $status_flags
1555 },
1556
1557 #
1558 # Intel style prefetching
1559 #
1560 Prefetch0 => {
1561         op_flags  => [ "labeled" ],
1562         state     => "exc_pinned",
1563         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1564         ins       => [ "base", "index", "mem" ],
1565         outs      => [ "M" ],
1566         latency   => 0,
1567         emit      => ". prefetcht0 %AM",
1568         units     => [ "GP" ],
1569 },
1570
1571 Prefetch1 => {
1572         op_flags  => [ "labeled" ],
1573         state     => "exc_pinned",
1574         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1575         ins       => [ "base", "index", "mem" ],
1576         outs      => [ "M" ],
1577         latency   => 0,
1578         emit      => ". prefetcht1 %AM",
1579         units     => [ "GP" ],
1580 },
1581
1582 Prefetch2 => {
1583         op_flags  => [ "labeled" ],
1584         state     => "exc_pinned",
1585         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1586         ins       => [ "base", "index", "mem" ],
1587         outs      => [ "M" ],
1588         latency   => 0,
1589         emit      => ". prefetcht2 %AM",
1590         units     => [ "GP" ],
1591 },
1592
1593 PrefetchNTA => {
1594         op_flags  => [ "labeled" ],
1595         state     => "exc_pinned",
1596         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1597         ins       => [ "base", "index", "mem" ],
1598         outs      => [ "M" ],
1599         latency   => 0,
1600         emit      => ". prefetchnta %AM",
1601         units     => [ "GP" ],
1602 },
1603
1604 #
1605 # 3DNow! prefetch instructions
1606 #
1607 Prefetch => {
1608         op_flags  => [ "labeled" ],
1609         state     => "exc_pinned",
1610         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1611         ins       => [ "base", "index", "mem" ],
1612         outs      => [ "M" ],
1613         latency   => 0,
1614         emit      => ". prefetch %AM",
1615         units     => [ "GP" ],
1616 },
1617
1618 PrefetchW => {
1619         op_flags  => [ "labeled" ],
1620         state     => "exc_pinned",
1621         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1622         ins       => [ "base", "index", "mem" ],
1623         outs      => [ "M" ],
1624         latency   => 0,
1625         emit      => ". prefetchw %AM",
1626         units     => [ "GP" ],
1627 },
1628
1629 # produces a 0/+0.0
1630 xZero => {
1631         irn_flags => [ "rematerializable" ],
1632         reg_req   => { out => [ "xmm" ] },
1633         emit      => '. xorp%XSD %D0, %D0',
1634         latency   => 3,
1635         units     => [ "SSE" ],
1636         mode      => $mode_xmm
1637 },
1638
1639 xUnknown => {
1640         op_flags  => [ "constlike" ],
1641         irn_flags => [ "rematerializable" ],
1642         reg_req   => { out => [ "xmm" ] },
1643         emit      => '',
1644         latency   => 0,
1645         mode      => $mode_xmm
1646 },
1647
1648 xPzero => {
1649         irn_flags => [ "rematerializable" ],
1650         reg_req   => { out => [ "xmm" ] },
1651         emit      => '. pxor %D0, %D0',
1652         latency   => 3,
1653         units     => [ "SSE" ],
1654         mode      => $mode_xmm
1655 },
1656
1657 # produces all 1 bits
1658 xAllOnes => {
1659         irn_flags => [ "rematerializable" ],
1660         reg_req   => { out => [ "xmm" ] },
1661         emit      => '. pcmpeqb %D0, %D0',
1662         latency   => 3,
1663         units     => [ "SSE" ],
1664         mode      => $mode_xmm
1665 },
1666
1667 # integer shift left, dword
1668 xPslld => {
1669         irn_flags => [ "rematerializable" ],
1670         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1671         emit      => '. pslld %SI1, %D0',
1672         latency   => 3,
1673         units     => [ "SSE" ],
1674         mode      => $mode_xmm
1675 },
1676
1677 # integer shift left, qword
1678 xPsllq => {
1679         irn_flags => [ "rematerializable" ],
1680         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1681         emit      => '. psllq %SI1, %D0',
1682         latency   => 3,
1683         units     => [ "SSE" ],
1684         mode      => $mode_xmm
1685 },
1686
1687 # integer shift right, dword
1688 xPsrld => {
1689         irn_flags => [ "rematerializable" ],
1690         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1691         emit      => '. psrld %SI1, %D0',
1692         latency   => 1,
1693         units     => [ "SSE" ],
1694         mode      => $mode_xmm
1695 },
1696
1697 # mov from integer to SSE register
1698 xMovd  => {
1699         irn_flags => [ "rematerializable" ],
1700         reg_req   => { in => [ "gp" ], out => [ "xmm" ] },
1701         emit      => '. movd %S0, %D0',
1702         latency   => 1,
1703         units     => [ "SSE" ],
1704         mode      => $mode_xmm
1705 },
1706
1707 xAdd => {
1708         irn_flags => [ "rematerializable" ],
1709         state     => "exc_pinned",
1710         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1711                        out => [ "in_r4 in_r5", "flags", "none" ] },
1712         ins       => [ "base", "index", "mem", "left", "right" ],
1713         outs      => [ "res", "flags", "M" ],
1714         am        => "source,binary",
1715         emit      => '. add%XXM %binop',
1716         latency   => 4,
1717         units     => [ "SSE" ],
1718         mode      => $mode_xmm
1719 },
1720
1721 xMul => {
1722         irn_flags => [ "rematerializable" ],
1723         state     => "exc_pinned",
1724         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1725                        out => [ "in_r4 in_r5", "flags", "none" ] },
1726         ins       => [ "base", "index", "mem", "left", "right" ],
1727         outs      => [ "res", "flags", "M" ],
1728         am        => "source,binary",
1729         emit      => '. mul%XXM %binop',
1730         latency   => 4,
1731         units     => [ "SSE" ],
1732         mode      => $mode_xmm
1733 },
1734
1735 xMax => {
1736         irn_flags => [ "rematerializable" ],
1737         state     => "exc_pinned",
1738         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1739                        out => [ "in_r4 in_r5", "flags", "none" ] },
1740         ins       => [ "base", "index", "mem", "left", "right" ],
1741         outs      => [ "res", "flags", "M" ],
1742         am        => "source,binary",
1743         emit      => '. max%XXM %binop',
1744         latency   => 2,
1745         units     => [ "SSE" ],
1746         mode      => $mode_xmm
1747 },
1748
1749 xMin => {
1750         irn_flags => [ "rematerializable" ],
1751         state     => "exc_pinned",
1752         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1753                        out => [ "in_r4 in_r5", "flags", "none" ] },
1754         ins       => [ "base", "index", "mem", "left", "right" ],
1755         outs      => [ "res", "flags", "M" ],
1756         am        => "source,binary",
1757         emit      => '. min%XXM %binop',
1758         latency   => 2,
1759         units     => [ "SSE" ],
1760         mode      => $mode_xmm
1761 },
1762
1763 xAnd => {
1764         irn_flags => [ "rematerializable" ],
1765         state     => "exc_pinned",
1766         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1767                        out => [ "in_r4 in_r5", "flags", "none" ] },
1768         ins       => [ "base", "index", "mem", "left", "right" ],
1769         outs      => [ "res", "flags", "M" ],
1770         am        => "source,binary",
1771         emit      => '. andp%XSD %binop',
1772         latency   => 3,
1773         units     => [ "SSE" ],
1774         mode      => $mode_xmm
1775 },
1776
1777 xOr => {
1778         irn_flags => [ "rematerializable" ],
1779         state     => "exc_pinned",
1780         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1781                        out => [ "in_r4 in_r5", "flags", "none" ] },
1782         ins       => [ "base", "index", "mem", "left", "right" ],
1783         outs      => [ "res", "flags", "M" ],
1784         am        => "source,binary",
1785         emit      => '. orp%XSD %binop',
1786         latency   => 3,
1787         units     => [ "SSE" ],
1788         mode      => $mode_xmm
1789 },
1790
1791 xXor => {
1792         irn_flags => [ "rematerializable" ],
1793         state     => "exc_pinned",
1794         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1795                        out => [ "in_r4 in_r5", "flags", "none" ] },
1796         ins       => [ "base", "index", "mem", "left", "right" ],
1797         outs      => [ "res", "flags", "M" ],
1798         am        => "source,binary",
1799         emit      => '. xorp%XSD %binop',
1800         latency   => 3,
1801         units     => [ "SSE" ],
1802         mode      => $mode_xmm
1803 },
1804
1805 xAndNot => {
1806         irn_flags => [ "rematerializable" ],
1807         state     => "exc_pinned",
1808         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1809                        out => [ "in_r4 !in_r5", "flags", "none" ] },
1810         ins       => [ "base", "index", "mem", "left", "right" ],
1811         outs      => [ "res", "flags", "M" ],
1812         am        => "source,binary",
1813         emit      => '. andnp%XSD %binop',
1814         latency   => 3,
1815         units     => [ "SSE" ],
1816         mode      => $mode_xmm
1817 },
1818
1819 xSub => {
1820         irn_flags => [ "rematerializable" ],
1821         state     => "exc_pinned",
1822         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1823                        out => [ "in_r4", "flags", "none" ] },
1824         ins       => [ "base", "index", "mem", "minuend", "subtrahend" ],
1825         outs      => [ "res", "flags", "M" ],
1826         am        => "source,binary",
1827         emit      => '. sub%XXM %binop',
1828         latency   => 4,
1829         units     => [ "SSE" ],
1830         mode      => $mode_xmm
1831 },
1832
1833 xDiv => {
1834         irn_flags => [ "rematerializable" ],
1835         state     => "exc_pinned",
1836         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1837                        out => [ "in_r4 !in_r5", "flags", "none" ] },
1838         ins       => [ "base", "index", "mem", "dividend", "divisor" ],
1839         outs      => [ "res", "flags", "M" ],
1840         am        => "source,binary",
1841         emit      => '. div%XXM %binop',
1842         latency   => 16,
1843         units     => [ "SSE" ],
1844 },
1845
1846 Ucomi => {
1847         irn_flags => [ "rematerializable" ],
1848         state     => "exc_pinned",
1849         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1850                        out => [ "eflags" ] },
1851         ins       => [ "base", "index", "mem", "left", "right" ],
1852         outs      => [ "flags" ],
1853         am        => "source,binary",
1854         attr      => "bool ins_permuted",
1855         init_attr => "attr->data.ins_permuted = ins_permuted;",
1856         emit      => ' .ucomi%XXM %binop',
1857         latency   => 3,
1858         units     => [ "SSE" ],
1859         mode      => $mode_flags,
1860         modified_flags => 1,
1861 },
1862
1863 xLoad => {
1864         op_flags  => [ "fragile", "labeled" ],
1865         state     => "exc_pinned",
1866         reg_req   => { in => [ "gp", "gp", "none" ],
1867                        out => [ "xmm", "none", "none", "none", "none" ] },
1868         ins       => [ "base", "index", "mem" ],
1869         outs      => [ "res", "unused", "M", "X_regular", "X_except" ],
1870         emit      => '. mov%XXM %AM, %D0',
1871         attr      => "ir_mode *load_mode",
1872         init_attr => "attr->ls_mode = load_mode;",
1873         latency   => 0,
1874         units     => [ "SSE" ],
1875 },
1876
1877 xStore => {
1878         op_flags => [ "fragile", "labeled" ],
1879         state    => "exc_pinned",
1880         reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
1881                       out => [ "none", "none", "none" ] },
1882         ins       => [ "base", "index", "mem", "val" ],
1883         outs      => [ "M", "X_regular", "X_except" ],
1884         emit     => '. mov%XXM %S3, %AM',
1885         latency  => 0,
1886         units    => [ "SSE" ],
1887 },
1888
1889 xStoreSimple => {
1890         op_flags => [ "fragile", "labeled" ],
1891         state    => "exc_pinned",
1892         reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
1893                       out => [ "none", "none", "none" ] },
1894         ins      => [ "base", "index", "mem", "val" ],
1895         outs     => [ "M", "X_regular", "X_except" ],
1896         emit     => '. mov%XXM %S3, %AM',
1897         latency  => 0,
1898         units    => [ "SSE" ],
1899 },
1900
1901 CvtSI2SS => {
1902         op_flags => [ "labeled" ],
1903         state     => "exc_pinned",
1904         reg_req  => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1905         ins      => [ "base", "index", "mem", "val" ],
1906         am       => "source,unary",
1907         emit     => '. cvtsi2ss %unop3, %D0',
1908         latency  => 2,
1909         units    => [ "SSE" ],
1910         mode     => $mode_xmm
1911 },
1912
1913 CvtSI2SD => {
1914         op_flags => [ "labeled" ],
1915         state     => "exc_pinned",
1916         reg_req  => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1917         ins      => [ "base", "index", "mem", "val" ],
1918         am       => "source,unary",
1919         emit     => '. cvtsi2sd %unop3, %D0',
1920         latency  => 2,
1921         units    => [ "SSE" ],
1922         mode     => $mode_xmm
1923 },
1924
1925
1926 l_LLtoFloat => {
1927         ins      => [ "val_high", "val_low" ],
1928         attr_type => "",
1929         dump_func => "NULL",
1930 },
1931
1932 l_FloattoLL => {
1933         ins      => [ "val" ],
1934         outs     => [ "res_high", "res_low" ],
1935         attr_type => "",
1936         dump_func => "NULL",
1937 },
1938
1939 CopyB => {
1940         op_flags  => [ "fragile" ],
1941         state     => "pinned",
1942         reg_req   => { in => [ "edi", "esi", "ecx", "none" ],
1943                        out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1944         ins       => [ "dest", "source", "count", "mem" ],
1945         outs      => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1946         attr_type => "ia32_copyb_attr_t",
1947         attr      => "unsigned size",
1948         units     => [ "GP" ],
1949         latency   => 3,
1950 # we don't care about this flag, so no need to mark this node
1951 #       modified_flags => [ "DF" ]
1952 },
1953
1954 CopyB_i => {
1955         op_flags  => [ "fragile" ],
1956         state     => "pinned",
1957         reg_req   => { in => [ "edi", "esi", "none" ],
1958                        out => [  "edi", "esi", "none", "none", "none" ] },
1959         ins       => [ "dest", "source", "mem" ],
1960         outs      => [ "dest", "source", "M", "X_regular", "X_except" ],
1961         attr_type => "ia32_copyb_attr_t",
1962         attr      => "unsigned size",
1963         units     => [ "GP" ],
1964         latency   => 3,
1965 # we don't care about this flag, so no need to mark this node
1966 #       modified_flags => [ "DF" ]
1967 },
1968
1969 Cwtl => {
1970         state     => "exc_pinned",
1971         reg_req   => { in => [ "eax" ], out => [ "eax" ] },
1972         ins       => [ "val" ],
1973         outs      => [ "res" ],
1974         emit      => '. cwtl',
1975         units     => [ "GP" ],
1976         latency   => 1,
1977         mode      => $mode_gp,
1978 },
1979
1980 Conv_I2I => {
1981         op_flags  => [ "fragile" ],
1982         state     => "exc_pinned",
1983         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1984                        out => [ "gp", "none", "none", "none", "none" ] },
1985         ins       => [ "base", "index", "mem", "val" ],
1986         outs      => [ "res", "flags", "M", "X_regular", "X_except" ],
1987         am        => "source,unary",
1988         units     => [ "GP" ],
1989         latency   => 1,
1990         attr      => "ir_mode *smaller_mode",
1991         init_attr => "attr->ls_mode = smaller_mode;",
1992         mode      => $mode_gp,
1993 },
1994
1995 Conv_I2I8Bit => {
1996         op_flags  => [ "fragile" ],
1997         state     => "exc_pinned",
1998         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1999                        out => [ "gp", "none", "none", "none", "none" ] },
2000         ins       => [ "base", "index", "mem", "val" ],
2001         outs      => [ "res", "flags", "M", "X_regular", "X_except" ],
2002         am        => "source,unary",
2003         units     => [ "GP" ],
2004         latency   => 1,
2005         attr      => "ir_mode *smaller_mode",
2006         init_attr => "attr->ls_mode = smaller_mode;",
2007         mode      => $mode_gp,
2008 },
2009
2010 Conv_I2FP => {
2011         state     => "exc_pinned",
2012         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
2013         ins       => [ "base", "index", "mem", "val" ],
2014         am        => "source,unary",
2015         latency   => 10,
2016         units     => [ "SSE" ],
2017         mode      => $mode_xmm,
2018 },
2019
2020 Conv_FP2I => {
2021         state     => "exc_pinned",
2022         reg_req   => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
2023         ins       => [ "base", "index", "mem", "val" ],
2024         am        => "source,unary",
2025         latency   => 10,
2026         units     => [ "SSE" ],
2027         mode      => $mode_gp,
2028 },
2029
2030 Conv_FP2FP => {
2031         state     => "exc_pinned",
2032         reg_req   => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
2033         ins       => [ "base", "index", "mem", "val" ],
2034         am        => "source,unary",
2035         latency   => 8,
2036         units     => [ "SSE" ],
2037         mode      => $mode_xmm,
2038 },
2039
2040 # rematerialisation disabled for all float nodes for now, because the fpcw
2041 # handler runs before spilling and we might end up with wrong fpcw then
2042
2043 vfadd => {
2044 #       irn_flags => [ "rematerializable" ],
2045         state     => "exc_pinned",
2046         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2047                        out => [ "vfp", "none", "none" ] },
2048         ins       => [ "base", "index", "mem", "left", "right", "fpcw" ],
2049         outs      => [ "res", "dummy", "M" ],
2050         am        => "source,binary",
2051         latency   => 4,
2052         units     => [ "VFP" ],
2053         mode      => "mode_E",
2054         attr_type => "ia32_x87_attr_t",
2055 },
2056
2057 vfmul => {
2058 #       irn_flags => [ "rematerializable" ],
2059         state     => "exc_pinned",
2060         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2061                        out => [ "vfp", "none", "none" ] },
2062         ins       => [ "base", "index", "mem", "left", "right", "fpcw" ],
2063         outs      => [ "res", "dummy", "M" ],
2064         am        => "source,binary",
2065         latency   => 4,
2066         units     => [ "VFP" ],
2067         mode      => "mode_E",
2068         attr_type => "ia32_x87_attr_t",
2069 },
2070
2071 vfsub => {
2072 #       irn_flags => [ "rematerializable" ],
2073         state     => "exc_pinned",
2074         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2075                        out => [ "vfp", "none", "none" ] },
2076         ins       => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2077         outs      => [ "res", "dummy", "M" ],
2078         am        => "source,binary",
2079         latency   => 4,
2080         units     => [ "VFP" ],
2081         mode      => "mode_E",
2082         attr_type => "ia32_x87_attr_t",
2083 },
2084
2085 vfdiv => {
2086         state     => "exc_pinned",
2087         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2088                        out => [ "vfp", "none", "none" ] },
2089         ins       => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2090         outs      => [ "res", "dummy", "M" ],
2091         am        => "source,binary",
2092         latency   => 20,
2093         units     => [ "VFP" ],
2094         attr_type => "ia32_x87_attr_t",
2095 },
2096
2097 vfprem => {
2098         reg_req   => { in => [ "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
2099         ins       => [ "left", "right", "fpcw" ],
2100         latency   => 20,
2101         units     => [ "VFP" ],
2102         mode      => "mode_E",
2103         attr_type => "ia32_x87_attr_t",
2104 },
2105
2106 vfabs => {
2107         irn_flags => [ "rematerializable" ],
2108         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
2109         ins       => [ "value" ],
2110         latency   => 2,
2111         units     => [ "VFP" ],
2112         mode      => "mode_E",
2113         attr_type => "ia32_x87_attr_t",
2114 },
2115
2116 vfchs => {
2117         irn_flags => [ "rematerializable" ],
2118         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
2119         ins       => [ "value" ],
2120         latency   => 2,
2121         units     => [ "VFP" ],
2122         mode      => "mode_E",
2123         attr_type => "ia32_x87_attr_t",
2124 },
2125
2126 vfld => {
2127         irn_flags => [ "rematerializable" ],
2128         op_flags  => [ "fragile", "labeled" ],
2129         state     => "exc_pinned",
2130         reg_req   => { in => [ "gp", "gp", "none" ],
2131                        out => [ "vfp", "none", "none", "none", "none" ] },
2132         ins       => [ "base", "index", "mem" ],
2133         outs      => [ "res", "unused", "M", "X_regular", "X_except" ],
2134         attr      => "ir_mode *load_mode",
2135         init_attr => "attr->attr.ls_mode = load_mode;",
2136         latency   => 2,
2137         units     => [ "VFP" ],
2138         attr_type => "ia32_x87_attr_t",
2139 },
2140
2141 vfst => {
2142         irn_flags => [ "rematerializable" ],
2143         op_flags  => [ "fragile", "labeled" ],
2144         state     => "exc_pinned",
2145         reg_req   => { in => [ "gp", "gp", "none", "vfp" ],
2146                        out => [ "none", "none", "none" ] },
2147         ins       => [ "base", "index", "mem", "val" ],
2148         outs      => [ "M", "X_regular", "X_except" ],
2149         attr      => "ir_mode *store_mode",
2150         init_attr => "attr->attr.ls_mode = store_mode;",
2151         latency   => 2,
2152         units     => [ "VFP" ],
2153         attr_type => "ia32_x87_attr_t",
2154 },
2155
2156 vfild => {
2157         state     => "exc_pinned",
2158         reg_req   => { in => [ "gp", "gp", "none" ],
2159                        out => [ "vfp", "none", "none" ] },
2160         outs      => [ "res", "unused", "M" ],
2161         ins       => [ "base", "index", "mem" ],
2162         latency   => 4,
2163         units     => [ "VFP" ],
2164         attr_type => "ia32_x87_attr_t",
2165 },
2166
2167 vfist => {
2168         op_flags  => [ "fragile" ],
2169         state     => "exc_pinned",
2170         reg_req   => { in => [ "gp", "gp", "none", "vfp", "fpcw" ],
2171                        out => [ "none", "none", "none", "none" ] },
2172         ins       => [ "base", "index", "mem", "val", "fpcw" ],
2173         outs      => [ "dummy", "M", "X_regular", "X_except" ],
2174         latency   => 4,
2175         units     => [ "VFP" ],
2176         attr_type => "ia32_x87_attr_t",
2177 },
2178
2179 # SSE3 fisttp instruction
2180 vfisttp => {
2181         op_flags  => [ "fragile" ],
2182         state     => "exc_pinned",
2183         reg_req   => { in => [ "gp", "gp", "none", "vfp" ],
2184                        out => [ "in_r4", "none", "none", "none" ]},
2185         ins       => [ "base", "index", "mem", "val" ],
2186         outs      => [ "res", "M", "X_regular", "X_except" ],
2187         latency   => 4,
2188         units     => [ "VFP" ],
2189         attr_type => "ia32_x87_attr_t",
2190 },
2191
2192 vfldz => {
2193         irn_flags => [ "rematerializable" ],
2194         reg_req   => { out => [ "vfp" ] },
2195         outs      => [ "res" ],
2196         latency   => 4,
2197         units     => [ "VFP" ],
2198         mode      => "mode_E",
2199         attr_type => "ia32_x87_attr_t",
2200 },
2201
2202 vfld1 => {
2203         irn_flags => [ "rematerializable" ],
2204         reg_req   => { out => [ "vfp" ] },
2205         outs      => [ "res" ],
2206         latency   => 4,
2207         units     => [ "VFP" ],
2208         mode      => "mode_E",
2209         attr_type => "ia32_x87_attr_t",
2210 },
2211
2212 vfldpi => {
2213         irn_flags => [ "rematerializable" ],
2214         reg_req   => { out => [ "vfp" ] },
2215         outs      => [ "res" ],
2216         latency   => 4,
2217         units     => [ "VFP" ],
2218         mode      => "mode_E",
2219         attr_type => "ia32_x87_attr_t",
2220 },
2221
2222 vfldln2 => {
2223         irn_flags => [ "rematerializable" ],
2224         reg_req   => { out => [ "vfp" ] },
2225         outs      => [ "res" ],
2226         latency   => 4,
2227         units     => [ "VFP" ],
2228         mode      => "mode_E",
2229         attr_type => "ia32_x87_attr_t",
2230 },
2231
2232 vfldlg2 => {
2233         irn_flags => [ "rematerializable" ],
2234         reg_req   => { out => [ "vfp" ] },
2235         outs      => [ "res" ],
2236         latency   => 4,
2237         units     => [ "VFP" ],
2238         mode      => "mode_E",
2239         attr_type => "ia32_x87_attr_t",
2240 },
2241
2242 vfldl2t => {
2243         irn_flags => [ "rematerializable" ],
2244         reg_req   => { out => [ "vfp" ] },
2245         outs      => [ "res" ],
2246         latency   => 4,
2247         units     => [ "VFP" ],
2248         mode      => "mode_E",
2249         attr_type => "ia32_x87_attr_t",
2250 },
2251
2252 vfldl2e => {
2253         irn_flags => [ "rematerializable" ],
2254         reg_req   => { out => [ "vfp" ] },
2255         outs      => [ "res" ],
2256         latency   => 4,
2257         units     => [ "VFP" ],
2258         mode      => "mode_E",
2259         attr_type => "ia32_x87_attr_t",
2260 },
2261
2262 vFucomFnstsw => {
2263 # we can't allow to rematerialize this node so we don't
2264 #  accidently produce Phi(Fucom, Fucom(ins_permuted))
2265 #       irn_flags => [ "rematerializable" ],
2266         reg_req   => { in => [ "vfp", "vfp" ], out => [ "eax" ] },
2267         ins       => [ "left", "right" ],
2268         outs      => [ "flags" ],
2269         attr      => "bool ins_permuted",
2270         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2271         latency   => 3,
2272         units     => [ "VFP" ],
2273         attr_type => "ia32_x87_attr_t",
2274         mode      => $mode_gp
2275 },
2276
2277 vFucomi => {
2278         irn_flags => [ "rematerializable" ],
2279         reg_req   => { in => [ "vfp", "vfp" ], out => [ "eflags" ] },
2280         ins       => [ "left", "right" ],
2281         outs      => [ "flags" ],
2282         attr      => "bool ins_permuted",
2283         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2284         latency   => 3,
2285         units     => [ "VFP" ],
2286         attr_type => "ia32_x87_attr_t",
2287         mode      => $mode_gp
2288 },
2289
2290 vFtstFnstsw => {
2291 #       irn_flags => [ "rematerializable" ],
2292         reg_req   => { in => [ "vfp" ], out => [ "eax" ] },
2293         ins       => [ "left" ],
2294         outs      => [ "flags" ],
2295         attr      => "bool ins_permuted",
2296         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2297         latency   => 3,
2298         units     => [ "VFP" ],
2299         attr_type => "ia32_x87_attr_t",
2300         mode      => $mode_gp
2301 },
2302
2303 Sahf => {
2304         irn_flags => [ "rematerializable" ],
2305         reg_req   => { in => [ "eax" ], out => [ "eflags" ] },
2306         ins       => [ "val" ],
2307         outs      => [ "flags" ],
2308         emit      => '. sahf',
2309         latency   => 1,
2310         units     => [ "GP" ],
2311         mode      => $mode_flags,
2312 },
2313
2314 fadd => {
2315         state     => "exc_pinned",
2316         emit      => '. fadd%XM %x87_binop',
2317         latency   => 4,
2318         attr_type => "ia32_x87_attr_t",
2319         constructors => {},
2320 },
2321
2322 faddp => {
2323         state     => "exc_pinned",
2324         emit      => '. faddp%XM %x87_binop',
2325         latency   => 4,
2326         attr_type => "ia32_x87_attr_t",
2327         constructors => {},
2328 },
2329
2330 fmul => {
2331         state     => "exc_pinned",
2332         emit      => '. fmul%XM %x87_binop',
2333         latency   => 4,
2334         attr_type => "ia32_x87_attr_t",
2335         constructors => {},
2336 },
2337
2338 fmulp => {
2339         state     => "exc_pinned",
2340         emit      => '. fmulp%XM %x87_binop',,
2341         latency   => 4,
2342         attr_type => "ia32_x87_attr_t",
2343         constructors => {},
2344 },
2345
2346 fsub => {
2347         state     => "exc_pinned",
2348         emit      => '. fsub%XM %x87_binop',
2349         latency   => 4,
2350         attr_type => "ia32_x87_attr_t",
2351         constructors => {},
2352 },
2353
2354 # Note: gas is strangely buggy: fdivrp and fdivp as well as fsubrp and fsubp
2355 #       are swapped, we work this around in the emitter...
2356
2357 fsubp => {
2358         state     => "exc_pinned",
2359 # see note about gas bugs
2360         emit      => '. fsubrp%XM %x87_binop',
2361         latency   => 4,
2362         attr_type => "ia32_x87_attr_t",
2363         constructors => {},
2364 },
2365
2366 fsubr => {
2367         state     => "exc_pinned",
2368         irn_flags => [ "rematerializable" ],
2369         emit      => '. fsubr%XM %x87_binop',
2370         latency   => 4,
2371         attr_type => "ia32_x87_attr_t",
2372         constructors => {},
2373 },
2374
2375 fsubrp => {
2376         state     => "exc_pinned",
2377         irn_flags => [ "rematerializable" ],
2378 # see note about gas bugs before fsubp
2379         emit      => '. fsubp%XM %x87_binop',
2380         latency   => 4,
2381         attr_type => "ia32_x87_attr_t",
2382         constructors => {},
2383 },
2384
2385 fprem => {
2386         emit      => '. fprem1',
2387         latency   => 20,
2388         attr_type => "ia32_x87_attr_t",
2389         constructors => {},
2390 },
2391
2392 # this node is just here, to keep the simulator running
2393 # we can omit this when a fprem simulation function exists
2394 fpremp => {
2395         emit      => '. fprem1\n'.
2396                      '. fstp %X0',
2397         latency   => 20,
2398         attr_type => "ia32_x87_attr_t",
2399         constructors => {},
2400 },
2401
2402 fdiv => {
2403         state     => "exc_pinned",
2404         emit      => '. fdiv%XM %x87_binop',
2405         latency   => 20,
2406         attr_type => "ia32_x87_attr_t",
2407         constructors => {},
2408 },
2409
2410 fdivp => {
2411         state     => "exc_pinned",
2412 # see note about gas bugs before fsubp
2413         emit      => '. fdivrp%XM %x87_binop',
2414         latency   => 20,
2415         attr_type => "ia32_x87_attr_t",
2416         constructors => {},
2417 },
2418
2419 fdivr => {
2420         state     => "exc_pinned",
2421         emit      => '. fdivr%XM %x87_binop',
2422         latency   => 20,
2423         attr_type => "ia32_x87_attr_t",
2424         constructors => {},
2425 },
2426
2427 fdivrp => {
2428         state     => "exc_pinned",
2429 # see note about gas bugs before fsubp
2430         emit      => '. fdivp%XM %x87_binop',
2431         latency   => 20,
2432         attr_type => "ia32_x87_attr_t",
2433         constructors => {},
2434 },
2435
2436 fabs => {
2437         emit      => '. fabs',
2438         latency   => 4,
2439         attr_type => "ia32_x87_attr_t",
2440         constructors => {},
2441 },
2442
2443 fchs => {
2444         op_flags  => [ "keep" ],
2445         irn_flags => [ "rematerializable" ],
2446         emit      => '. fchs',
2447         latency   => 4,
2448         attr_type => "ia32_x87_attr_t",
2449         constructors => {},
2450 },
2451
2452 fld => {
2453         irn_flags => [ "rematerializable" ],
2454         op_flags  => [ "labeled" ],
2455         state     => "exc_pinned",
2456         emit      => '. fld%XM %AM',
2457         attr_type => "ia32_x87_attr_t",
2458         latency   => 2,
2459         constructors => {},
2460 },
2461
2462 fst => {
2463         irn_flags => [ "rematerializable" ],
2464         op_flags  => [ "labeled" ],
2465         state     => "exc_pinned",
2466         emit      => '. fst%XM %AM',
2467         mode      => "mode_M",
2468         attr_type => "ia32_x87_attr_t",
2469         latency   => 2,
2470         constructors => {},
2471 },
2472
2473 fstp => {
2474         irn_flags => [ "rematerializable" ],
2475         op_flags  => [ "labeled" ],
2476         state     => "exc_pinned",
2477         emit      => '. fstp%XM %AM',
2478         mode      => "mode_M",
2479         attr_type => "ia32_x87_attr_t",
2480         latency   => 2,
2481         constructors => {},
2482 },
2483
2484 fild => {
2485         state     => "exc_pinned",
2486         emit      => '. fild%XM %AM',
2487         attr_type => "ia32_x87_attr_t",
2488         latency   => 2,
2489         constructors => {},
2490 },
2491
2492 fist => {
2493         state     => "exc_pinned",
2494         emit      => '. fist%XM %AM',
2495         mode      => "mode_M",
2496         attr_type => "ia32_x87_attr_t",
2497         latency   => 2,
2498         constructors => {},
2499 },
2500
2501 fistp => {
2502         state     => "exc_pinned",
2503         emit      => '. fistp%XM %AM',
2504         mode      => "mode_M",
2505         attr_type => "ia32_x87_attr_t",
2506         latency   => 2,
2507         constructors => {},
2508 },
2509
2510 # SSE3 fisttp instruction
2511 fisttp => {
2512         state     => "exc_pinned",
2513         emit      => '. fisttp%XM %AM',
2514         mode      => "mode_M",
2515         attr_type => "ia32_x87_attr_t",
2516         latency   => 2,
2517         constructors => {},
2518 },
2519
2520 fldz => {
2521         op_flags  =>  [ "constlike", "keep" ],
2522         irn_flags => [ "rematerializable" ],
2523         reg_req   => { out => [ "vfp" ] },
2524         emit      => '. fldz',
2525         attr_type => "ia32_x87_attr_t",
2526         latency   => 2,
2527 },
2528
2529 fld1 => {
2530         op_flags  => [ "constlike", "keep" ],
2531         irn_flags => [ "rematerializable" ],
2532         reg_req   => { out => [ "vfp" ] },
2533         emit      => '. fld1',
2534         attr_type => "ia32_x87_attr_t",
2535         latency   => 2,
2536 },
2537
2538 fldpi => {
2539         op_flags  => [ "constlike", "keep" ],
2540         irn_flags => [ "rematerializable" ],
2541         reg_req   => { out => [ "vfp" ] },
2542         emit      => '. fldpi',
2543         attr_type => "ia32_x87_attr_t",
2544         latency   => 2,
2545 },
2546
2547 fldln2 => {
2548         op_flags  => [ "constlike", "keep" ],
2549         irn_flags => [ "rematerializable" ],
2550         reg_req   => { out => [ "vfp" ] },
2551         emit      => '. fldln2',
2552         attr_type => "ia32_x87_attr_t",
2553         latency   => 2,
2554 },
2555
2556 fldlg2 => {
2557         op_flags  => [ "constlike", "keep" ],
2558         irn_flags => [ "rematerializable" ],
2559         reg_req   => { out => [ "vfp" ] },
2560         emit      => '. fldlg2',
2561         attr_type => "ia32_x87_attr_t",
2562         latency   => 2,
2563 },
2564
2565 fldl2t => {
2566         op_flags  => [ "constlike", "keep" ],
2567         irn_flags => [ "rematerializable" ],
2568         reg_req   => { out => [ "vfp" ] },
2569         emit      => '. fldll2t',
2570         attr_type => "ia32_x87_attr_t",
2571         latency   => 2,
2572 },
2573
2574 fldl2e => {
2575         op_flags  => [ "constlike", "keep" ],
2576         irn_flags => [ "rematerializable" ],
2577         reg_req   => { out => [ "vfp" ] },
2578         emit      => '. fldl2e',
2579         attr_type => "ia32_x87_attr_t",
2580         latency   => 2,
2581 },
2582
2583 # fxch, fpush, fpop
2584 # Note that it is NEVER allowed to do CSE on these nodes
2585 # Moreover, note the virtual register requierements!
2586
2587 fxch => {
2588         op_flags  => [ "keep" ],
2589         reg_req   => { out => [ "none" ] },
2590         cmp_attr  => "return 1;",
2591         emit      => '. fxch %X0',
2592         attr_type => "ia32_x87_attr_t",
2593         mode      => "mode_ANY",
2594         latency   => 1,
2595 },
2596
2597 fpush => {
2598         op_flags  => [ "keep" ],
2599         reg_req   => { out => [ "none" ] },
2600         cmp_attr  => "return 1;",
2601         emit      => '. fld %X0',
2602         attr_type => "ia32_x87_attr_t",
2603         mode      => "mode_ANY",
2604         latency   => 1,
2605 },
2606
2607 fpushCopy => {
2608         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
2609         cmp_attr  => "return 1;",
2610         emit      => '. fld %X0',
2611         attr_type => "ia32_x87_attr_t",
2612         latency   => 1,
2613 },
2614
2615 fpop => {
2616         op_flags  => [ "keep" ],
2617         reg_req   => { out => [ "none" ] },
2618         cmp_attr  => "return 1;",
2619         emit      => '. fstp %X0',
2620         attr_type => "ia32_x87_attr_t",
2621         mode      => "mode_ANY",
2622         latency   => 1,
2623 },
2624
2625 ffreep => {
2626         op_flags  => [ "keep" ],
2627         reg_req   => { out => [ "none" ] },
2628         cmp_attr  => "return 1;",
2629         emit      => '. ffreep %X0',
2630         attr_type => "ia32_x87_attr_t",
2631         mode      => "mode_ANY",
2632         latency   => 1,
2633 },
2634
2635 emms => {
2636         op_flags  => [ "keep" ],
2637         reg_req   => { out => [ "none" ] },
2638         cmp_attr  => "return 1;",
2639         emit      => '. emms',
2640         attr_type => "ia32_x87_attr_t",
2641         mode      => "mode_ANY",
2642         latency   => 3,
2643 },
2644
2645 femms => {
2646         op_flags  => [ "keep" ],
2647         reg_req   => { out => [ "none" ] },
2648         cmp_attr  => "return 1;",
2649         emit      => '. femms',
2650         attr_type => "ia32_x87_attr_t",
2651         mode      => "mode_ANY",
2652         latency   => 3,
2653 },
2654
2655 FucomFnstsw => {
2656         reg_req   => { },
2657         emit      => ". fucom %X1\n".
2658                      ". fnstsw %%ax",
2659         attr_type => "ia32_x87_attr_t",
2660         latency   => 2,
2661 },
2662
2663 FucompFnstsw => {
2664         reg_req   => { },
2665         emit      => ". fucomp %X1\n".
2666                      ". fnstsw %%ax",
2667         attr_type => "ia32_x87_attr_t",
2668         latency   => 2,
2669 },
2670
2671 FucomppFnstsw => {
2672         reg_req   => { },
2673         emit      => ". fucompp\n".
2674                      ". fnstsw %%ax",
2675         attr_type => "ia32_x87_attr_t",
2676         latency   => 2,
2677 },
2678
2679 Fucomi => {
2680         reg_req   => { },
2681         emit      => '. fucomi %X1',
2682         attr_type => "ia32_x87_attr_t",
2683         latency   => 1,
2684 },
2685
2686 Fucompi => {
2687         reg_req   => { },
2688         emit      => '. fucompi %X1',
2689         attr_type => "ia32_x87_attr_t",
2690         latency   => 1,
2691 },
2692
2693 FtstFnstsw => {
2694         reg_req   => { },
2695         emit      => ". ftst\n".
2696                      ". fnstsw %%ax",
2697         attr_type => "ia32_x87_attr_t",
2698         latency   => 2,
2699 },
2700
2701 # Spilling and reloading of SSE registers, hardcoded, not generated #
2702
2703 xxLoad => {
2704         op_flags  => [ "fragile", "labeled" ],
2705         state     => "exc_pinned",
2706         reg_req   => { in => [ "gp", "gp", "none" ],
2707                        out => [ "xmm", "none", "none", "none" ] },
2708         emit      => '. movdqu %D0, %AM',
2709         ins       => [ "base", "index", "mem" ],
2710         outs      => [ "res", "M", "X_regular", "X_except" ],
2711         units     => [ "SSE" ],
2712         latency   => 1,
2713 },
2714
2715 xxStore => {
2716         op_flags => [ "fragile", "labeled" ],
2717         state    => "exc_pinned",
2718         reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
2719                       out => [ "none", "none", "none" ] },
2720         ins      => [ "base", "index", "mem", "val" ],
2721         outs     => [ "M", "X_regular", "X_except" ],
2722         emit     => '. movdqu %binop',
2723         units    => [ "SSE" ],
2724         latency  => 1,
2725 },
2726
2727 ); # end of %nodes
2728
2729 # Transform some attributes
2730 foreach my $op (keys(%nodes)) {
2731         my $node         = $nodes{$op};
2732         my $op_attr_init = $node->{op_attr_init};
2733
2734         if(defined($op_attr_init)) {
2735                 $op_attr_init .= "\n\t";
2736         } else {
2737                 $op_attr_init = "";
2738         }
2739
2740         if(!defined($node->{latency})) {
2741                 if($op =~ m/^l_/) {
2742                         $node->{latency} = 0;
2743                 } else {
2744                         die("Latency missing for op $op");
2745                 }
2746         }
2747         $op_attr_init .= "attr->latency = ".$node->{latency} . ";";
2748
2749         $node->{op_attr_init} = $op_attr_init;
2750 }
2751
2752 print "";