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