a9394487ab2a770d16b221956906ae1e39c76d42
[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 $mode_xmm           = "mode_D";
8 $mode_mmx           = "mode_D";
9 $mode_fp87          = "ia32_mode_E";
10 $mode_gp            = "mode_Iu";
11 $mode_flags         = "mode_Iu";
12 $mode_fpcw          = "ia32_mode_fpcw";
13
14 # register types:
15 $normal      =  0; # no special type
16 $ignore      =  1; # ignore (do not assign this register)
17 $arbitrary   =  2; # emitter can choose an arbitrary register of this class
18 $virtual     =  4; # the register is a virtual one
19 $state       =  8; # register represents a state
20 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
21 %reg_classes = (
22         gp => [
23                 { name => "edx" },
24                 { name => "ecx" },
25                 { name => "eax" },
26                 { name => "ebx" },
27                 { name => "esi" },
28                 { name => "edi" },
29                 { name => "ebp" },
30                 { name => "esp", type => $ignore },
31                 { name => "gp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
32                 { mode => $mode_gp }
33         ],
34         mmx => [
35                 { name => "mm0", type => $ignore },
36                 { name => "mm1", type => $ignore },
37                 { name => "mm2", type => $ignore },
38                 { name => "mm3", type => $ignore },
39                 { name => "mm4", type => $ignore },
40                 { name => "mm5", type => $ignore },
41                 { name => "mm6", type => $ignore },
42                 { name => "mm7", type => $ignore },
43                 { mode => $mode_mmx, flags => "manual_ra" }
44         ],
45         xmm => [
46                 { name => "xmm0" },
47                 { name => "xmm1" },
48                 { name => "xmm2" },
49                 { name => "xmm3" },
50                 { name => "xmm4" },
51                 { name => "xmm5" },
52                 { name => "xmm6" },
53                 { name => "xmm7" },
54                 { name => "xmm_NOREG", type => $ignore | $virtual },     # we need a dummy register for NoReg nodes
55                 { mode => $mode_xmm }
56         ],
57         vfp => [
58                 { name => "vf0" },
59                 { name => "vf1" },
60                 { name => "vf2" },
61                 { name => "vf3" },
62                 { name => "vf4" },
63                 { name => "vf5" },
64                 { name => "vf6" },
65                 { name => "vf7" },
66                 { name => "vfp_NOREG", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for NoReg nodes
67                 { mode => $mode_fp87 }
68         ],
69         st => [
70                 { name => "st0", realname => "st",    type => $ignore },
71                 { name => "st1", realname => "st(1)", type => $ignore },
72                 { name => "st2", realname => "st(2)", type => $ignore },
73                 { name => "st3", realname => "st(3)", type => $ignore },
74                 { name => "st4", realname => "st(4)", type => $ignore },
75                 { name => "st5", realname => "st(5)", type => $ignore },
76                 { name => "st6", realname => "st(6)", type => $ignore },
77                 { name => "st7", realname => "st(7)", type => $ignore },
78                 { mode => $mode_fp87, flags => "manual_ra" }
79         ],
80         fp_cw => [      # the floating point control word
81                 { name => "fpcw", type => $ignore | $state },
82                 { mode => $mode_fpcw, flags => "manual_ra|state" }
83         ],
84         flags => [
85                 { name => "eflags", type => 0 },
86                 { mode => "mode_Iu", flags => "manual_ra" }
87         ],
88 ); # %reg_classes
89
90 %cpu = (
91         GP     => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
92         SSE    => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
93         VFP    => [ 1, "VFP_VF0", "VFP_VF1", "VFP_VF2", "VFP_VF3", "VFP_VF4", "VFP_VF5", "VFP_VF6", "VFP_VF7" ],
94         BRANCH => [ 1, "BRANCH1", "BRANCH2" ],
95 ); # %cpu
96
97 %vliw = (
98         bundle_size       => 1,
99         bundels_per_cycle => 1
100 ); # vliw
101
102 %emit_templates = (
103         S0 => "${arch}_emit_source_register(node, 0);",
104         S1 => "${arch}_emit_source_register(node, 1);",
105         S2 => "${arch}_emit_source_register(node, 2);",
106         S3 => "${arch}_emit_source_register(node, 3);",
107         SB0 => "${arch}_emit_8bit_source_register_or_immediate(node, 0);",
108         SB1 => "${arch}_emit_8bit_source_register_or_immediate(node, 1);",
109         SB2 => "${arch}_emit_8bit_source_register_or_immediate(node, 2);",
110         SB3 => "${arch}_emit_8bit_source_register_or_immediate(node, 3);",
111         SH0 => "${arch}_emit_8bit_high_source_register(node, 0);",
112         SS0 => "${arch}_emit_16bit_source_register_or_immediate(node, 0);",
113         SI0 => "${arch}_emit_source_register_or_immediate(node, 0);",
114         SI1 => "${arch}_emit_source_register_or_immediate(node, 1);",
115         SI3 => "${arch}_emit_source_register_or_immediate(node, 3);",
116         D0 => "${arch}_emit_dest_register(node, 0);",
117         D1 => "${arch}_emit_dest_register(node, 1);",
118         DS0 => "${arch}_emit_dest_register_size(node, 0);",
119         DB0 => "${arch}_emit_8bit_dest_register(node, 0);",
120         X0 => "${arch}_emit_x87_register(node, 0);",
121         X1 => "${arch}_emit_x87_register(node, 1);",
122         EX => "${arch}_emit_extend_suffix(node);",
123         M  => "${arch}_emit_mode_suffix(node);",
124         XM => "${arch}_emit_x87_mode_suffix(node);",
125         XXM => "${arch}_emit_xmm_mode_suffix(node);",
126         XSD => "${arch}_emit_xmm_mode_suffix_s(node);",
127         AM => "${arch}_emit_am(node);",
128         unop3 => "${arch}_emit_unop(node, n_ia32_unary_op);",
129         unop4 => "${arch}_emit_unop(node, n_ia32_binary_right);",
130         binop => "${arch}_emit_binop(node);",
131         x87_binop => "${arch}_emit_x87_binop(node);",
132         CMP3  => "${arch}_emit_cmp_suffix_node(node, 3);",
133 );
134
135
136
137
138 $default_op_attr_type = "ia32_op_attr_t";
139 $default_attr_type    = "ia32_attr_t";
140 $default_copy_attr    = "ia32_copy_attr";
141
142 sub ia32_custom_init_attr {
143         my $constr = shift;
144         my $node   = shift;
145         my $name   = shift;
146         my $res    = "";
147
148         if(defined($node->{modified_flags})) {
149                 $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n";
150         }
151         if(defined($node->{am})) {
152                 my $am = $node->{am};
153                 if($am eq "source,unary") {
154                         $res .= "\tset_ia32_am_support(res, ia32_am_unary);";
155                 } elsif($am eq "source,binary") {
156                         $res .= "\tset_ia32_am_support(res, ia32_am_binary);";
157                 } elsif($am eq "none") {
158                         # nothing to do
159                 } else {
160                         die("Invalid address mode '$am' specified on op $name");
161                 }
162                 if($am ne "none") {
163                         if($node->{state} ne "exc_pinned"
164                                         and $node->{state} ne "pinned") {
165                                 die("AM nodes must have pinned or AM pinned state ($name)");
166                         }
167                 }
168         }
169         return $res;
170 }
171 $custom_init_attr_func = \&ia32_custom_init_attr;
172
173 %init_attr = (
174         ia32_asm_attr_t =>
175                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
176                 "\tinit_ia32_x87_attributes(res);".
177                 "\tinit_ia32_asm_attributes(res);",
178         ia32_attr_t     =>
179                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);",
180         ia32_call_attr_t =>
181                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
182                 "\tinit_ia32_call_attributes(res, pop, call_tp);",
183         ia32_condcode_attr_t =>
184                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
185                 "\tinit_ia32_condcode_attributes(res, condition_code);",
186         ia32_switch_attr_t =>
187                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
188                 "\tinit_ia32_switch_attributes(res, default_pn);",
189         ia32_copyb_attr_t =>
190                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
191                 "\tinit_ia32_copyb_attributes(res, size);",
192         ia32_immediate_attr_t =>
193                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
194                 "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
195         ia32_x87_attr_t =>
196                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
197                 "\tinit_ia32_x87_attributes(res);",
198         ia32_climbframe_attr_t =>
199                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, exec_units, n_res);\n".
200                 "\tinit_ia32_climbframe_attributes(res, count);",
201 );
202
203 %compare_attr = (
204         ia32_asm_attr_t        => "ia32_compare_asm_attr",
205         ia32_attr_t            => "ia32_compare_nodes_attr",
206         ia32_call_attr_t       => "ia32_compare_call_attr",
207         ia32_condcode_attr_t   => "ia32_compare_condcode_attr",
208         ia32_switch_attr_t     => "ia32_compare_switch_attr",
209         ia32_copyb_attr_t      => "ia32_compare_copyb_attr",
210         ia32_immediate_attr_t  => "ia32_compare_immediate_attr",
211         ia32_x87_attr_t        => "ia32_compare_x87_attr",
212         ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
213 );
214
215 %operands = (
216 );
217
218 $status_flags       = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
219 $status_flags_wo_cf = [       "PF", "AF", "ZF", "SF", "OF" ];
220 $fpcw_flags         = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
221                         "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
222
223 %nodes = (
224
225 Immediate => {
226         state     => "pinned",
227         op_flags  => [ "constlike" ],
228         irn_flags => [ "not_scheduled" ],
229         reg_req   => { out => [ "gp_NOREG:I" ] },
230         attr      => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
231         attr_type => "ia32_immediate_attr_t",
232         hash_func => "ia32_hash_Immediate",
233         latency   => 0,
234         mode      => $mode_gp,
235 },
236
237 Asm => {
238         mode      => "mode_T",
239         arity     => "variable",
240         out_arity => "variable",
241         attr_type => "ia32_asm_attr_t",
242         attr      => "ident *asm_text, const ia32_asm_reg_t *register_map",
243         init_attr => "attr->asm_text = asm_text;\n".
244                      "\tattr->register_map = register_map;\n",
245         latency   => 10,
246         modified_flags => $status_flags,
247 },
248
249 # "allocates" a free register
250 ProduceVal => {
251         op_flags  => [ "constlike", "cse_neutral" ],
252         irn_flags => [ "rematerializable" ],
253         reg_req   => { out => [ "gp" ] },
254         emit      => "",
255         units     => [ ],
256         latency   => 0,
257         mode      => $mode_gp,
258         cmp_attr  => "return 1;",
259 },
260
261 Add => {
262         irn_flags => [ "rematerializable" ],
263         state     => "exc_pinned",
264         reg_req   => { in  => [ "gp", "gp", "none", "gp", "gp" ],
265                        out => [ "in_r4 in_r5", "flags", "none" ] },
266         ins       => [ "base", "index", "mem", "left", "right" ],
267         outs      => [ "res", "flags", "M" ],
268         emit      => '. add%M %binop',
269         am        => "source,binary",
270         units     => [ "GP" ],
271         latency   => 1,
272         mode      => $mode_gp,
273         modified_flags => $status_flags
274 },
275
276 AddMem => {
277         irn_flags => [ "rematerializable" ],
278         state     => "exc_pinned",
279         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
280         ins       => [ "base", "index", "mem", "val" ],
281         emit      => ". add%M %SI3, %AM",
282         units     => [ "GP" ],
283         latency   => 1,
284         mode      => "mode_M",
285         modified_flags => $status_flags
286 },
287
288 AddMem8Bit => {
289         irn_flags => [ "rematerializable" ],
290         state     => "exc_pinned",
291         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
292         ins       => [ "base", "index", "mem", "val" ],
293         emit      => ". add%M %SB3, %AM",
294         units     => [ "GP" ],
295         latency   => 1,
296         mode      => "mode_M",
297         modified_flags => $status_flags
298 },
299
300 Adc => {
301         state     => "exc_pinned",
302         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
303                        out => [ "in_r4 in_r5", "flags", "none" ] },
304         ins       => [ "base", "index", "mem", "left", "right", "eflags" ],
305         outs      => [ "res", "flags", "M" ],
306         emit      => '. adc%M %binop',
307         am        => "source,binary",
308         units     => [ "GP" ],
309         latency   => 1,
310         mode      => $mode_gp,
311         modified_flags => $status_flags
312 },
313
314 l_Add => {
315         ins       => [ "left", "right" ],
316         attr_type => "",
317         dump_func => "NULL",
318 },
319
320 l_Adc => {
321         ins       => [ "left", "right", "eflags" ],
322         attr_type => "",
323         dump_func => "NULL",
324 },
325
326 Mul => {
327         # we should not rematrialize this node. It produces 2 results and has
328         # very strict constraints
329         state     => "exc_pinned",
330         reg_req   => { in => [ "gp", "gp", "none", "eax", "gp" ],
331                        out => [ "eax", "flags", "none", "edx" ] },
332         ins       => [ "base", "index", "mem", "left", "right" ],
333         emit      => '. mul%M %unop4',
334         outs      => [ "res_low", "flags", "M", "res_high" ],
335         am        => "source,binary",
336         latency   => 10,
337         units     => [ "GP" ],
338         modified_flags => $status_flags
339 },
340
341 l_Mul => {
342         ins       => [ "left", "right" ],
343         outs      => [ "res_low", "flags", "M", "res_high" ],
344         attr_type => "",
345         dump_func => "NULL",
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         ins       => [ "left", "right" ],
380         outs      => [ "res_low", "flags", "M", "res_high" ],
381         attr_type => "",
382         dump_func => "NULL",
383 },
384
385 And => {
386         irn_flags => [ "rematerializable" ],
387         state     => "exc_pinned",
388         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
389                            out => [ "in_r4 in_r5", "flags", "none" ] },
390         ins       => [ "base", "index", "mem", "left", "right" ],
391         outs      => [ "res", "flags", "M" ],
392         am        => "source,binary",
393         emit      => '. and%M %binop',
394         units     => [ "GP" ],
395         latency   => 1,
396         mode      => $mode_gp,
397         modified_flags => $status_flags
398 },
399
400 AndMem => {
401         irn_flags => [ "rematerializable" ],
402         state     => "exc_pinned",
403         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
404         ins       => [ "base", "index", "mem", "val" ],
405         emit      => '. and%M %SI3, %AM',
406         units     => [ "GP" ],
407         latency   => 1,
408         mode      => "mode_M",
409         modified_flags => $status_flags
410 },
411
412 AndMem8Bit => {
413         irn_flags => [ "rematerializable" ],
414         state     => "exc_pinned",
415         reg_req   => { in => [ "gp", "gp", "none",  "eax ebx ecx edx" ], out => [ "none" ] },
416         ins       => [ "base", "index", "mem", "val" ],
417         emit      => '. and%M %SB3, %AM',
418         units     => [ "GP" ],
419         latency   => 1,
420         mode      => "mode_M",
421         modified_flags => $status_flags
422 },
423
424 Or => {
425         irn_flags => [ "rematerializable" ],
426         state     => "exc_pinned",
427         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
428                        out => [ "in_r4 in_r5", "flags", "none" ] },
429         ins       => [ "base", "index", "mem", "left", "right" ],
430         outs      => [ "res", "flags", "M" ],
431         am        => "source,binary",
432         emit      => '. or%M %binop',
433         units     => [ "GP" ],
434         latency   => 1,
435         mode      => $mode_gp,
436         modified_flags => $status_flags
437 },
438
439 OrMem => {
440         irn_flags => [ "rematerializable" ],
441         state     => "exc_pinned",
442         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
443         ins       => [ "base", "index", "mem", "val" ],
444         emit      => '. or%M %SI3, %AM',
445         units     => [ "GP" ],
446         latency   => 1,
447         mode      => "mode_M",
448         modified_flags => $status_flags
449 },
450
451 OrMem8Bit => {
452         irn_flags => [ "rematerializable" ],
453         state     => "exc_pinned",
454         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
455         ins       => [ "base", "index", "mem", "val" ],
456         emit      => '. or%M %SB3, %AM',
457         units     => [ "GP" ],
458         latency   => 1,
459         mode      => "mode_M",
460         modified_flags => $status_flags
461 },
462
463 Xor => {
464         irn_flags => [ "rematerializable" ],
465         state     => "exc_pinned",
466         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
467                        out => [ "in_r4 in_r5", "flags", "none" ] },
468         ins       => [ "base", "index", "mem", "left", "right" ],
469         outs      => [ "res", "flags", "M" ],
470         am        => "source,binary",
471         emit      => '. xor%M %binop',
472         units     => [ "GP" ],
473         latency   => 1,
474         mode      => $mode_gp,
475         modified_flags => $status_flags
476 },
477
478 Xor0 => {
479         op_flags  => [ "constlike" ],
480         irn_flags => [ "rematerializable" ],
481         reg_req   => { out => [ "gp", "flags" ] },
482         outs      => [ "res", "flags" ],
483         emit      => ". xor%M %D0, %D0",
484         units     => [ "GP" ],
485         latency   => 1,
486         mode      => $mode_gp,
487         modified_flags => $status_flags
488 },
489
490 XorMem => {
491         irn_flags => [ "rematerializable" ],
492         state     => "exc_pinned",
493         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
494         ins       => [ "base", "index", "mem", "val" ],
495         emit      => '. xor%M %SI3, %AM',
496         units     => [ "GP" ],
497         latency   => 1,
498         mode      => "mode_M",
499         modified_flags => $status_flags
500 },
501
502 XorMem8Bit => {
503         irn_flags => [ "rematerializable" ],
504         state     => "exc_pinned",
505         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
506         ins       => [ "base", "index", "mem", "val" ],
507         emit      => '. xor%M %SB3, %AM',
508         units     => [ "GP" ],
509         latency   => 1,
510         mode      => "mode_M",
511         modified_flags => $status_flags
512 },
513
514 Sub => {
515         irn_flags => [ "rematerializable" ],
516         state     => "exc_pinned",
517         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
518                        out => [ "in_r4", "flags", "none" ] },
519         ins       => [ "base", "index", "mem", "minuend", "subtrahend" ],
520         outs      => [ "res", "flags", "M" ],
521         am        => "source,binary",
522         emit      => '. sub%M %binop',
523         units     => [ "GP" ],
524         latency   => 1,
525         mode      => $mode_gp,
526         modified_flags => $status_flags
527 },
528
529 SubMem => {
530         irn_flags => [ "rematerializable" ],
531         state     => "exc_pinned",
532         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
533         ins       => [ "base", "index", "mem", "subtrahend" ],
534         emit      => '. sub%M %SI3, %AM',
535         units     => [ "GP" ],
536         latency   => 1,
537         mode      => 'mode_M',
538         modified_flags => $status_flags
539 },
540
541 SubMem8Bit => {
542         irn_flags => [ "rematerializable" ],
543         state     => "exc_pinned",
544         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
545         ins       => [ "base", "index", "mem", "subtrahend" ],
546         emit      => '. sub%M %SB3, %AM',
547         units     => [ "GP" ],
548         latency   => 1,
549         mode      => 'mode_M',
550         modified_flags => $status_flags
551 },
552
553 Sbb => {
554         state     => "exc_pinned",
555         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
556                        out => [ "in_r4", "flags", "none" ] },
557         ins       => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
558         outs      => [ "res", "flags", "M" ],
559         am        => "source,binary",
560         emit      => '. sbb%M %binop',
561         units     => [ "GP" ],
562         latency   => 1,
563         mode      => $mode_gp,
564         modified_flags => $status_flags
565 },
566
567 Sbb0 => {
568         # Spiller currently fails when rematerializing flag consumers
569         # irn_flags => [ "rematerializable" ],
570         reg_req   => { in => [ "flags" ], out => [ "gp", "flags" ] },
571         outs      => [ "res", "flags" ],
572         emit      => ". sbb%M %D0, %D0",
573         units     => [ "GP" ],
574         latency   => 1,
575         mode      => $mode_gp,
576         modified_flags => $status_flags
577 },
578
579 l_Sub => {
580         ins       => [ "minuend", "subtrahend" ],
581         attr_type => "",
582         dump_func => "NULL",
583 },
584
585 l_Sbb => {
586         ins       => [ "minuend", "subtrahend", "eflags" ],
587         attr_type => "",
588         dump_func => "NULL",
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_add_irn_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_fp87,
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_xmm,
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         ins      => [ "val_high", "val_low" ],
1923         attr_type => "",
1924         dump_func => "NULL",
1925 },
1926
1927 l_FloattoLL => {
1928         ins      => [ "val" ],
1929         outs     => [ "res_high", "res_low" ],
1930         attr_type => "",
1931         dump_func => "NULL",
1932 },
1933
1934 CopyB => {
1935         op_flags  => [ "fragile" ],
1936         state     => "pinned",
1937         reg_req   => { in => [ "edi", "esi", "ecx", "none" ],
1938                        out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1939         ins       => [ "dest", "source", "count", "mem" ],
1940         outs      => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1941         attr_type => "ia32_copyb_attr_t",
1942         attr      => "unsigned size",
1943         units     => [ "GP" ],
1944         latency   => 3,
1945 # we don't care about this flag, so no need to mark this node
1946 #       modified_flags => [ "DF" ]
1947 },
1948
1949 CopyB_i => {
1950         op_flags  => [ "fragile" ],
1951         state     => "pinned",
1952         reg_req   => { in => [ "edi", "esi", "none" ],
1953                        out => [  "edi", "esi", "none", "none", "none" ] },
1954         ins       => [ "dest", "source", "mem" ],
1955         outs      => [ "dest", "source", "M", "X_regular", "X_except" ],
1956         attr_type => "ia32_copyb_attr_t",
1957         attr      => "unsigned size",
1958         units     => [ "GP" ],
1959         latency   => 3,
1960 # we don't care about this flag, so no need to mark this node
1961 #       modified_flags => [ "DF" ]
1962 },
1963
1964 Cwtl => {
1965         state     => "exc_pinned",
1966         reg_req   => { in => [ "eax" ], out => [ "eax" ] },
1967         ins       => [ "val" ],
1968         outs      => [ "res" ],
1969         emit      => '. cwtl',
1970         units     => [ "GP" ],
1971         latency   => 1,
1972         mode      => $mode_gp,
1973 },
1974
1975 Conv_I2I => {
1976         op_flags  => [ "fragile" ],
1977         state     => "exc_pinned",
1978         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1979                        out => [ "gp", "none", "none", "none", "none" ] },
1980         ins       => [ "base", "index", "mem", "val" ],
1981         outs      => [ "res", "flags", "M", "X_regular", "X_except" ],
1982         am        => "source,unary",
1983         units     => [ "GP" ],
1984         latency   => 1,
1985         attr      => "ir_mode *smaller_mode",
1986         init_attr => "attr->ls_mode = smaller_mode;",
1987         mode      => $mode_gp,
1988 },
1989
1990 Conv_I2I8Bit => {
1991         op_flags  => [ "fragile" ],
1992         state     => "exc_pinned",
1993         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1994                        out => [ "gp", "none", "none", "none", "none" ] },
1995         ins       => [ "base", "index", "mem", "val" ],
1996         outs      => [ "res", "flags", "M", "X_regular", "X_except" ],
1997         am        => "source,unary",
1998         units     => [ "GP" ],
1999         latency   => 1,
2000         attr      => "ir_mode *smaller_mode",
2001         init_attr => "attr->ls_mode = smaller_mode;",
2002         mode      => $mode_gp,
2003 },
2004
2005 Conv_I2FP => {
2006         state     => "exc_pinned",
2007         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
2008         ins       => [ "base", "index", "mem", "val" ],
2009         am        => "source,unary",
2010         latency   => 10,
2011         units     => [ "SSE" ],
2012         mode      => $mode_xmm,
2013 },
2014
2015 Conv_FP2I => {
2016         state     => "exc_pinned",
2017         reg_req   => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
2018         ins       => [ "base", "index", "mem", "val" ],
2019         am        => "source,unary",
2020         latency   => 10,
2021         units     => [ "SSE" ],
2022         mode      => $mode_gp,
2023 },
2024
2025 Conv_FP2FP => {
2026         state     => "exc_pinned",
2027         reg_req   => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
2028         ins       => [ "base", "index", "mem", "val" ],
2029         am        => "source,unary",
2030         latency   => 8,
2031         units     => [ "SSE" ],
2032         mode      => $mode_xmm,
2033 },
2034
2035 # rematerialisation disabled for all float nodes for now, because the fpcw
2036 # handler runs before spilling and we might end up with wrong fpcw then
2037
2038 vfadd => {
2039 #       irn_flags => [ "rematerializable" ],
2040         state     => "exc_pinned",
2041         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2042                        out => [ "vfp", "none", "none" ] },
2043         ins       => [ "base", "index", "mem", "left", "right", "fpcw" ],
2044         outs      => [ "res", "dummy", "M" ],
2045         am        => "source,binary",
2046         latency   => 4,
2047         units     => [ "VFP" ],
2048         mode      => $mode_fp87,
2049         attr_type => "ia32_x87_attr_t",
2050 },
2051
2052 vfmul => {
2053 #       irn_flags => [ "rematerializable" ],
2054         state     => "exc_pinned",
2055         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2056                        out => [ "vfp", "none", "none" ] },
2057         ins       => [ "base", "index", "mem", "left", "right", "fpcw" ],
2058         outs      => [ "res", "dummy", "M" ],
2059         am        => "source,binary",
2060         latency   => 4,
2061         units     => [ "VFP" ],
2062         mode      => $mode_fp87,
2063         attr_type => "ia32_x87_attr_t",
2064 },
2065
2066 vfsub => {
2067 #       irn_flags => [ "rematerializable" ],
2068         state     => "exc_pinned",
2069         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2070                        out => [ "vfp", "none", "none" ] },
2071         ins       => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2072         outs      => [ "res", "dummy", "M" ],
2073         am        => "source,binary",
2074         latency   => 4,
2075         units     => [ "VFP" ],
2076         mode      => $mode_fp87,
2077         attr_type => "ia32_x87_attr_t",
2078 },
2079
2080 vfdiv => {
2081         state     => "exc_pinned",
2082         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2083                        out => [ "vfp", "none", "none" ] },
2084         ins       => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2085         outs      => [ "res", "dummy", "M" ],
2086         am        => "source,binary",
2087         latency   => 20,
2088         units     => [ "VFP" ],
2089         attr_type => "ia32_x87_attr_t",
2090 },
2091
2092 vfprem => {
2093         reg_req   => { in => [ "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
2094         ins       => [ "left", "right", "fpcw" ],
2095         latency   => 20,
2096         units     => [ "VFP" ],
2097         mode      => $mode_fp87,
2098         attr_type => "ia32_x87_attr_t",
2099 },
2100
2101 vfabs => {
2102         irn_flags => [ "rematerializable" ],
2103         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
2104         ins       => [ "value" ],
2105         latency   => 2,
2106         units     => [ "VFP" ],
2107         mode      => $mode_fp87,
2108         attr_type => "ia32_x87_attr_t",
2109 },
2110
2111 vfchs => {
2112         irn_flags => [ "rematerializable" ],
2113         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
2114         ins       => [ "value" ],
2115         latency   => 2,
2116         units     => [ "VFP" ],
2117         mode      => $mode_fp87,
2118         attr_type => "ia32_x87_attr_t",
2119 },
2120
2121 vfld => {
2122         irn_flags => [ "rematerializable" ],
2123         op_flags  => [ "fragile", "labeled" ],
2124         state     => "exc_pinned",
2125         reg_req   => { in => [ "gp", "gp", "none" ],
2126                        out => [ "vfp", "none", "none", "none", "none" ] },
2127         ins       => [ "base", "index", "mem" ],
2128         outs      => [ "res", "unused", "M", "X_regular", "X_except" ],
2129         attr      => "ir_mode *load_mode",
2130         init_attr => "attr->attr.ls_mode = load_mode;",
2131         latency   => 2,
2132         units     => [ "VFP" ],
2133         attr_type => "ia32_x87_attr_t",
2134 },
2135
2136 vfst => {
2137         irn_flags => [ "rematerializable" ],
2138         op_flags  => [ "fragile", "labeled" ],
2139         state     => "exc_pinned",
2140         reg_req   => { in => [ "gp", "gp", "none", "vfp" ],
2141                        out => [ "none", "none", "none" ] },
2142         ins       => [ "base", "index", "mem", "val" ],
2143         outs      => [ "M", "X_regular", "X_except" ],
2144         attr      => "ir_mode *store_mode",
2145         init_attr => "attr->attr.ls_mode = store_mode;",
2146         latency   => 2,
2147         units     => [ "VFP" ],
2148         attr_type => "ia32_x87_attr_t",
2149 },
2150
2151 vfild => {
2152         state     => "exc_pinned",
2153         reg_req   => { in => [ "gp", "gp", "none" ],
2154                        out => [ "vfp", "none", "none" ] },
2155         outs      => [ "res", "unused", "M" ],
2156         ins       => [ "base", "index", "mem" ],
2157         latency   => 4,
2158         units     => [ "VFP" ],
2159         attr_type => "ia32_x87_attr_t",
2160 },
2161
2162 vfist => {
2163         op_flags  => [ "fragile" ],
2164         state     => "exc_pinned",
2165         reg_req   => { in => [ "gp", "gp", "none", "vfp", "fpcw" ],
2166                        out => [ "none", "none", "none", "none" ] },
2167         ins       => [ "base", "index", "mem", "val", "fpcw" ],
2168         outs      => [ "dummy", "M", "X_regular", "X_except" ],
2169         latency   => 4,
2170         units     => [ "VFP" ],
2171         attr_type => "ia32_x87_attr_t",
2172 },
2173
2174 # SSE3 fisttp instruction
2175 vfisttp => {
2176         op_flags  => [ "fragile" ],
2177         state     => "exc_pinned",
2178         reg_req   => { in => [ "gp", "gp", "none", "vfp" ],
2179                        out => [ "in_r4", "none", "none", "none" ]},
2180         ins       => [ "base", "index", "mem", "val" ],
2181         outs      => [ "res", "M", "X_regular", "X_except" ],
2182         latency   => 4,
2183         units     => [ "VFP" ],
2184         attr_type => "ia32_x87_attr_t",
2185 },
2186
2187 vfldz => {
2188         irn_flags => [ "rematerializable" ],
2189         reg_req   => { out => [ "vfp" ] },
2190         outs      => [ "res" ],
2191         latency   => 4,
2192         units     => [ "VFP" ],
2193         mode      => $mode_fp87,
2194         attr_type => "ia32_x87_attr_t",
2195 },
2196
2197 vfld1 => {
2198         irn_flags => [ "rematerializable" ],
2199         reg_req   => { out => [ "vfp" ] },
2200         outs      => [ "res" ],
2201         latency   => 4,
2202         units     => [ "VFP" ],
2203         mode      => $mode_fp87,
2204         attr_type => "ia32_x87_attr_t",
2205 },
2206
2207 vfldpi => {
2208         irn_flags => [ "rematerializable" ],
2209         reg_req   => { out => [ "vfp" ] },
2210         outs      => [ "res" ],
2211         latency   => 4,
2212         units     => [ "VFP" ],
2213         mode      => $mode_fp87,
2214         attr_type => "ia32_x87_attr_t",
2215 },
2216
2217 vfldln2 => {
2218         irn_flags => [ "rematerializable" ],
2219         reg_req   => { out => [ "vfp" ] },
2220         outs      => [ "res" ],
2221         latency   => 4,
2222         units     => [ "VFP" ],
2223         mode      => $mode_fp87,
2224         attr_type => "ia32_x87_attr_t",
2225 },
2226
2227 vfldlg2 => {
2228         irn_flags => [ "rematerializable" ],
2229         reg_req   => { out => [ "vfp" ] },
2230         outs      => [ "res" ],
2231         latency   => 4,
2232         units     => [ "VFP" ],
2233         mode      => $mode_fp87,
2234         attr_type => "ia32_x87_attr_t",
2235 },
2236
2237 vfldl2t => {
2238         irn_flags => [ "rematerializable" ],
2239         reg_req   => { out => [ "vfp" ] },
2240         outs      => [ "res" ],
2241         latency   => 4,
2242         units     => [ "VFP" ],
2243         mode      => $mode_fp87,
2244         attr_type => "ia32_x87_attr_t",
2245 },
2246
2247 vfldl2e => {
2248         irn_flags => [ "rematerializable" ],
2249         reg_req   => { out => [ "vfp" ] },
2250         outs      => [ "res" ],
2251         latency   => 4,
2252         units     => [ "VFP" ],
2253         mode      => $mode_fp87,
2254         attr_type => "ia32_x87_attr_t",
2255 },
2256
2257 vFucomFnstsw => {
2258 # we can't allow to rematerialize this node so we don't
2259 #  accidently produce Phi(Fucom, Fucom(ins_permuted))
2260 #       irn_flags => [ "rematerializable" ],
2261         reg_req   => { in => [ "vfp", "vfp" ], out => [ "eax" ] },
2262         ins       => [ "left", "right" ],
2263         outs      => [ "flags" ],
2264         attr      => "bool ins_permuted",
2265         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2266         latency   => 3,
2267         units     => [ "VFP" ],
2268         attr_type => "ia32_x87_attr_t",
2269         mode      => $mode_gp
2270 },
2271
2272 vFucomi => {
2273         irn_flags => [ "rematerializable" ],
2274         reg_req   => { in => [ "vfp", "vfp" ], out => [ "eflags" ] },
2275         ins       => [ "left", "right" ],
2276         outs      => [ "flags" ],
2277         attr      => "bool ins_permuted",
2278         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2279         latency   => 3,
2280         units     => [ "VFP" ],
2281         attr_type => "ia32_x87_attr_t",
2282         mode      => $mode_gp
2283 },
2284
2285 vFtstFnstsw => {
2286 #       irn_flags => [ "rematerializable" ],
2287         reg_req   => { in => [ "vfp" ], out => [ "eax" ] },
2288         ins       => [ "left" ],
2289         outs      => [ "flags" ],
2290         attr      => "bool ins_permuted",
2291         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2292         latency   => 3,
2293         units     => [ "VFP" ],
2294         attr_type => "ia32_x87_attr_t",
2295         mode      => $mode_gp
2296 },
2297
2298 Sahf => {
2299         irn_flags => [ "rematerializable" ],
2300         reg_req   => { in => [ "eax" ], out => [ "eflags" ] },
2301         ins       => [ "val" ],
2302         outs      => [ "flags" ],
2303         emit      => '. sahf',
2304         latency   => 1,
2305         units     => [ "GP" ],
2306         mode      => $mode_flags,
2307 },
2308
2309 fadd => {
2310         state     => "exc_pinned",
2311         emit      => '. fadd%XM %x87_binop',
2312         latency   => 4,
2313         attr_type => "ia32_x87_attr_t",
2314         constructors => {},
2315 },
2316
2317 faddp => {
2318         state     => "exc_pinned",
2319         emit      => '. faddp%XM %x87_binop',
2320         latency   => 4,
2321         attr_type => "ia32_x87_attr_t",
2322         constructors => {},
2323 },
2324
2325 fmul => {
2326         state     => "exc_pinned",
2327         emit      => '. fmul%XM %x87_binop',
2328         latency   => 4,
2329         attr_type => "ia32_x87_attr_t",
2330         constructors => {},
2331 },
2332
2333 fmulp => {
2334         state     => "exc_pinned",
2335         emit      => '. fmulp%XM %x87_binop',,
2336         latency   => 4,
2337         attr_type => "ia32_x87_attr_t",
2338         constructors => {},
2339 },
2340
2341 fsub => {
2342         state     => "exc_pinned",
2343         emit      => '. fsub%XM %x87_binop',
2344         latency   => 4,
2345         attr_type => "ia32_x87_attr_t",
2346         constructors => {},
2347 },
2348
2349 # Note: gas is strangely buggy: fdivrp and fdivp as well as fsubrp and fsubp
2350 #       are swapped, we work this around in the emitter...
2351
2352 fsubp => {
2353         state     => "exc_pinned",
2354 # see note about gas bugs
2355         emit      => '. fsubrp%XM %x87_binop',
2356         latency   => 4,
2357         attr_type => "ia32_x87_attr_t",
2358         constructors => {},
2359 },
2360
2361 fsubr => {
2362         state     => "exc_pinned",
2363         irn_flags => [ "rematerializable" ],
2364         emit      => '. fsubr%XM %x87_binop',
2365         latency   => 4,
2366         attr_type => "ia32_x87_attr_t",
2367         constructors => {},
2368 },
2369
2370 fsubrp => {
2371         state     => "exc_pinned",
2372         irn_flags => [ "rematerializable" ],
2373 # see note about gas bugs before fsubp
2374         emit      => '. fsubp%XM %x87_binop',
2375         latency   => 4,
2376         attr_type => "ia32_x87_attr_t",
2377         constructors => {},
2378 },
2379
2380 fprem => {
2381         emit      => '. fprem1',
2382         latency   => 20,
2383         attr_type => "ia32_x87_attr_t",
2384         constructors => {},
2385 },
2386
2387 # this node is just here, to keep the simulator running
2388 # we can omit this when a fprem simulation function exists
2389 fpremp => {
2390         emit      => '. fprem1\n'.
2391                      '. fstp %X0',
2392         latency   => 20,
2393         attr_type => "ia32_x87_attr_t",
2394         constructors => {},
2395 },
2396
2397 fdiv => {
2398         state     => "exc_pinned",
2399         emit      => '. fdiv%XM %x87_binop',
2400         latency   => 20,
2401         attr_type => "ia32_x87_attr_t",
2402         constructors => {},
2403 },
2404
2405 fdivp => {
2406         state     => "exc_pinned",
2407 # see note about gas bugs before fsubp
2408         emit      => '. fdivrp%XM %x87_binop',
2409         latency   => 20,
2410         attr_type => "ia32_x87_attr_t",
2411         constructors => {},
2412 },
2413
2414 fdivr => {
2415         state     => "exc_pinned",
2416         emit      => '. fdivr%XM %x87_binop',
2417         latency   => 20,
2418         attr_type => "ia32_x87_attr_t",
2419         constructors => {},
2420 },
2421
2422 fdivrp => {
2423         state     => "exc_pinned",
2424 # see note about gas bugs before fsubp
2425         emit      => '. fdivp%XM %x87_binop',
2426         latency   => 20,
2427         attr_type => "ia32_x87_attr_t",
2428         constructors => {},
2429 },
2430
2431 fabs => {
2432         emit      => '. fabs',
2433         latency   => 4,
2434         attr_type => "ia32_x87_attr_t",
2435         constructors => {},
2436 },
2437
2438 fchs => {
2439         op_flags  => [ "keep" ],
2440         irn_flags => [ "rematerializable" ],
2441         emit      => '. fchs',
2442         latency   => 4,
2443         attr_type => "ia32_x87_attr_t",
2444         constructors => {},
2445 },
2446
2447 fld => {
2448         irn_flags => [ "rematerializable" ],
2449         op_flags  => [ "labeled" ],
2450         state     => "exc_pinned",
2451         emit      => '. fld%XM %AM',
2452         attr_type => "ia32_x87_attr_t",
2453         latency   => 2,
2454         constructors => {},
2455 },
2456
2457 fst => {
2458         irn_flags => [ "rematerializable" ],
2459         op_flags  => [ "labeled" ],
2460         state     => "exc_pinned",
2461         emit      => '. fst%XM %AM',
2462         mode      => "mode_M",
2463         attr_type => "ia32_x87_attr_t",
2464         latency   => 2,
2465         constructors => {},
2466 },
2467
2468 fstp => {
2469         irn_flags => [ "rematerializable" ],
2470         op_flags  => [ "labeled" ],
2471         state     => "exc_pinned",
2472         emit      => '. fstp%XM %AM',
2473         mode      => "mode_M",
2474         attr_type => "ia32_x87_attr_t",
2475         latency   => 2,
2476         constructors => {},
2477 },
2478
2479 fild => {
2480         state     => "exc_pinned",
2481         emit      => '. fild%XM %AM',
2482         attr_type => "ia32_x87_attr_t",
2483         latency   => 2,
2484         constructors => {},
2485 },
2486
2487 fist => {
2488         state     => "exc_pinned",
2489         emit      => '. fist%XM %AM',
2490         mode      => "mode_M",
2491         attr_type => "ia32_x87_attr_t",
2492         latency   => 2,
2493         constructors => {},
2494 },
2495
2496 fistp => {
2497         state     => "exc_pinned",
2498         emit      => '. fistp%XM %AM',
2499         mode      => "mode_M",
2500         attr_type => "ia32_x87_attr_t",
2501         latency   => 2,
2502         constructors => {},
2503 },
2504
2505 # SSE3 fisttp instruction
2506 fisttp => {
2507         state     => "exc_pinned",
2508         emit      => '. fisttp%XM %AM',
2509         mode      => "mode_M",
2510         attr_type => "ia32_x87_attr_t",
2511         latency   => 2,
2512         constructors => {},
2513 },
2514
2515 fldz => {
2516         op_flags  =>  [ "constlike", "keep" ],
2517         irn_flags => [ "rematerializable" ],
2518         reg_req   => { out => [ "vfp" ] },
2519         emit      => '. fldz',
2520         attr_type => "ia32_x87_attr_t",
2521         latency   => 2,
2522 },
2523
2524 fld1 => {
2525         op_flags  => [ "constlike", "keep" ],
2526         irn_flags => [ "rematerializable" ],
2527         reg_req   => { out => [ "vfp" ] },
2528         emit      => '. fld1',
2529         attr_type => "ia32_x87_attr_t",
2530         latency   => 2,
2531 },
2532
2533 fldpi => {
2534         op_flags  => [ "constlike", "keep" ],
2535         irn_flags => [ "rematerializable" ],
2536         reg_req   => { out => [ "vfp" ] },
2537         emit      => '. fldpi',
2538         attr_type => "ia32_x87_attr_t",
2539         latency   => 2,
2540 },
2541
2542 fldln2 => {
2543         op_flags  => [ "constlike", "keep" ],
2544         irn_flags => [ "rematerializable" ],
2545         reg_req   => { out => [ "vfp" ] },
2546         emit      => '. fldln2',
2547         attr_type => "ia32_x87_attr_t",
2548         latency   => 2,
2549 },
2550
2551 fldlg2 => {
2552         op_flags  => [ "constlike", "keep" ],
2553         irn_flags => [ "rematerializable" ],
2554         reg_req   => { out => [ "vfp" ] },
2555         emit      => '. fldlg2',
2556         attr_type => "ia32_x87_attr_t",
2557         latency   => 2,
2558 },
2559
2560 fldl2t => {
2561         op_flags  => [ "constlike", "keep" ],
2562         irn_flags => [ "rematerializable" ],
2563         reg_req   => { out => [ "vfp" ] },
2564         emit      => '. fldll2t',
2565         attr_type => "ia32_x87_attr_t",
2566         latency   => 2,
2567 },
2568
2569 fldl2e => {
2570         op_flags  => [ "constlike", "keep" ],
2571         irn_flags => [ "rematerializable" ],
2572         reg_req   => { out => [ "vfp" ] },
2573         emit      => '. fldl2e',
2574         attr_type => "ia32_x87_attr_t",
2575         latency   => 2,
2576 },
2577
2578 # fxch, fpush, fpop
2579 # Note that it is NEVER allowed to do CSE on these nodes
2580 # Moreover, note the virtual register requierements!
2581
2582 fxch => {
2583         op_flags  => [ "keep" ],
2584         reg_req   => { out => [ "none" ] },
2585         cmp_attr  => "return 1;",
2586         emit      => '. fxch %X0',
2587         attr_type => "ia32_x87_attr_t",
2588         mode      => "mode_ANY",
2589         latency   => 1,
2590 },
2591
2592 fpush => {
2593         op_flags  => [ "keep" ],
2594         reg_req   => { out => [ "none" ] },
2595         cmp_attr  => "return 1;",
2596         emit      => '. fld %X0',
2597         attr_type => "ia32_x87_attr_t",
2598         mode      => "mode_ANY",
2599         latency   => 1,
2600 },
2601
2602 fpushCopy => {
2603         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
2604         cmp_attr  => "return 1;",
2605         emit      => '. fld %X0',
2606         attr_type => "ia32_x87_attr_t",
2607         latency   => 1,
2608 },
2609
2610 fpop => {
2611         op_flags  => [ "keep" ],
2612         reg_req   => { out => [ "none" ] },
2613         cmp_attr  => "return 1;",
2614         emit      => '. fstp %X0',
2615         attr_type => "ia32_x87_attr_t",
2616         mode      => "mode_ANY",
2617         latency   => 1,
2618 },
2619
2620 ffreep => {
2621         op_flags  => [ "keep" ],
2622         reg_req   => { out => [ "none" ] },
2623         cmp_attr  => "return 1;",
2624         emit      => '. ffreep %X0',
2625         attr_type => "ia32_x87_attr_t",
2626         mode      => "mode_ANY",
2627         latency   => 1,
2628 },
2629
2630 emms => {
2631         op_flags  => [ "keep" ],
2632         reg_req   => { out => [ "none" ] },
2633         cmp_attr  => "return 1;",
2634         emit      => '. emms',
2635         attr_type => "ia32_x87_attr_t",
2636         mode      => "mode_ANY",
2637         latency   => 3,
2638 },
2639
2640 femms => {
2641         op_flags  => [ "keep" ],
2642         reg_req   => { out => [ "none" ] },
2643         cmp_attr  => "return 1;",
2644         emit      => '. femms',
2645         attr_type => "ia32_x87_attr_t",
2646         mode      => "mode_ANY",
2647         latency   => 3,
2648 },
2649
2650 FucomFnstsw => {
2651         reg_req   => { },
2652         emit      => ". fucom %X1\n".
2653                      ". fnstsw %%ax",
2654         attr_type => "ia32_x87_attr_t",
2655         latency   => 2,
2656 },
2657
2658 FucompFnstsw => {
2659         reg_req   => { },
2660         emit      => ". fucomp %X1\n".
2661                      ". fnstsw %%ax",
2662         attr_type => "ia32_x87_attr_t",
2663         latency   => 2,
2664 },
2665
2666 FucomppFnstsw => {
2667         reg_req   => { },
2668         emit      => ". fucompp\n".
2669                      ". fnstsw %%ax",
2670         attr_type => "ia32_x87_attr_t",
2671         latency   => 2,
2672 },
2673
2674 Fucomi => {
2675         reg_req   => { },
2676         emit      => '. fucomi %X1',
2677         attr_type => "ia32_x87_attr_t",
2678         latency   => 1,
2679 },
2680
2681 Fucompi => {
2682         reg_req   => { },
2683         emit      => '. fucompi %X1',
2684         attr_type => "ia32_x87_attr_t",
2685         latency   => 1,
2686 },
2687
2688 FtstFnstsw => {
2689         reg_req   => { },
2690         emit      => ". ftst\n".
2691                      ". fnstsw %%ax",
2692         attr_type => "ia32_x87_attr_t",
2693         latency   => 2,
2694 },
2695
2696 # Spilling and reloading of SSE registers, hardcoded, not generated #
2697
2698 xxLoad => {
2699         op_flags  => [ "fragile", "labeled" ],
2700         state     => "exc_pinned",
2701         reg_req   => { in => [ "gp", "gp", "none" ],
2702                        out => [ "xmm", "none", "none", "none" ] },
2703         emit      => '. movdqu %D0, %AM',
2704         ins       => [ "base", "index", "mem" ],
2705         outs      => [ "res", "M", "X_regular", "X_except" ],
2706         units     => [ "SSE" ],
2707         latency   => 1,
2708 },
2709
2710 xxStore => {
2711         op_flags => [ "fragile", "labeled" ],
2712         state    => "exc_pinned",
2713         reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
2714                       out => [ "none", "none", "none" ] },
2715         ins      => [ "base", "index", "mem", "val" ],
2716         outs     => [ "M", "X_regular", "X_except" ],
2717         emit     => '. movdqu %binop',
2718         units    => [ "SSE" ],
2719         latency  => 1,
2720 },
2721
2722 ); # end of %nodes
2723
2724 # Transform some attributes
2725 foreach my $op (keys(%nodes)) {
2726         my $node         = $nodes{$op};
2727         my $op_attr_init = $node->{op_attr_init};
2728
2729         if(defined($op_attr_init)) {
2730                 $op_attr_init .= "\n\t";
2731         } else {
2732                 $op_attr_init = "";
2733         }
2734
2735         if(!defined($node->{latency})) {
2736                 if($op =~ m/^l_/) {
2737                         $node->{latency} = 0;
2738                 } else {
2739                         die("Latency missing for op $op");
2740                 }
2741         }
2742         $op_attr_init .= "attr->latency = ".$node->{latency} . ";";
2743
2744         $node->{op_attr_init} = $op_attr_init;
2745 }
2746
2747 print "";