b95a4026e39f8b0a0e85afdafc7057408a85fc31
[libfirm] / ir / be / ia32 / ia32_spec.pl
1 # This is the specification for the ia32 assembler Firm-operations
2
3 $arch = "ia32";
4
5 $mode_xmm           = "mode_D";
6 $mode_mmx           = "mode_D";
7 $mode_fp87          = "ia32_mode_E";
8 $mode_gp            = "mode_Iu";
9 $mode_flags         = "mode_Iu";
10 $mode_fpcw          = "ia32_mode_fpcw";
11
12 %reg_classes = (
13         gp => [
14                 { name => "edx", dwarf => 2 },
15                 { name => "ecx", dwarf => 1 },
16                 { name => "eax", dwarf => 0 },
17                 { name => "ebx", dwarf => 3 },
18                 { name => "esi", dwarf => 6 },
19                 { name => "edi", dwarf => 7 },
20                 { name => "ebp", dwarf => 5 },
21                 { name => "esp", dwarf => 4, type => "ignore" },
22                 { name => "gp_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
23                 { mode => $mode_gp }
24         ],
25         mmx => [
26                 { name => "mm0", dwarf => 29, type => "ignore" },
27                 { name => "mm1", dwarf => 30, type => "ignore" },
28                 { name => "mm2", dwarf => 31, type => "ignore" },
29                 { name => "mm3", dwarf => 32, type => "ignore" },
30                 { name => "mm4", dwarf => 33, type => "ignore" },
31                 { name => "mm5", dwarf => 34, type => "ignore" },
32                 { name => "mm6", dwarf => 35, type => "ignore" },
33                 { name => "mm7", dwarf => 36, type => "ignore" },
34                 { mode => $mode_mmx, flags => "manual_ra" }
35         ],
36         xmm => [
37                 { name => "xmm0", dwarf => 21 },
38                 { name => "xmm1", dwarf => 22 },
39                 { name => "xmm2", dwarf => 23 },
40                 { name => "xmm3", dwarf => 24 },
41                 { name => "xmm4", dwarf => 25 },
42                 { name => "xmm5", dwarf => 26 },
43                 { name => "xmm6", dwarf => 27 },
44                 { name => "xmm7", dwarf => 28 },
45                 { name => "xmm_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
46                 { mode => $mode_xmm }
47         ],
48         fp => [
49                 { name => "st0", realname => "st",    dwarf => 11 },
50                 { name => "st1", realname => "st(1)", dwarf => 12 },
51                 { name => "st2", realname => "st(2)", dwarf => 13 },
52                 { name => "st3", realname => "st(3)", dwarf => 14 },
53                 { name => "st4", realname => "st(4)", dwarf => 15 },
54                 { name => "st5", realname => "st(5)", dwarf => 16 },
55                 { name => "st6", realname => "st(6)", dwarf => 17 },
56                 { name => "st7", realname => "st(7)", dwarf => 18 },
57                 { name => "fp_NOREG", type => "ignore | virtual" }, # we need a dummy register for NoReg nodes
58                 { mode => $mode_fp87 }
59         ],
60         fp_cw => [      # the floating point control word
61                 { name => "fpcw", dwarf => 37, type => "state" },
62                 { mode => $mode_fpcw, flags => "manual_ra | state" }
63         ],
64         flags => [
65                 { name => "eflags", dwarf => 9 },
66                 { mode => "mode_Iu", flags => "manual_ra" }
67         ],
68 ); # %reg_classes
69
70 $default_attr_type = "ia32_attr_t";
71 $default_copy_attr = "ia32_copy_attr";
72
73 sub ia32_custom_init_attr {
74         my $constr = shift;
75         my $node   = shift;
76         my $name   = shift;
77         my $res    = "";
78
79         if(defined($node->{modified_flags})) {
80                 $res .= "\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n";
81         }
82         if(defined($node->{am})) {
83                 my $am = $node->{am};
84                 if($am eq "source,unary") {
85                         $res .= "\tset_ia32_am_support(res, ia32_am_unary);";
86                 } elsif($am eq "source,binary") {
87                         $res .= "\tset_ia32_am_support(res, ia32_am_binary);";
88                 } elsif($am eq "none") {
89                         # nothing to do
90                 } else {
91                         die("Invalid address mode '$am' specified on op $name");
92                 }
93                 if($am ne "none") {
94                         if($node->{state} ne "exc_pinned"
95                                         and $node->{state} ne "pinned") {
96                                 die("AM nodes must have pinned or AM pinned state ($name)");
97                         }
98                 }
99         }
100         return $res;
101 }
102 $custom_init_attr_func = \&ia32_custom_init_attr;
103
104 %init_attr = (
105         ia32_asm_attr_t =>
106                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
107                 "\tinit_ia32_asm_attributes(res);",
108         ia32_attr_t     =>
109                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);",
110         ia32_call_attr_t =>
111                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
112                 "\tinit_ia32_call_attributes(res, pop, call_tp);",
113         ia32_condcode_attr_t =>
114                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
115                 "\tinit_ia32_condcode_attributes(res, condition_code);",
116         ia32_switch_attr_t =>
117                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
118                 "\tinit_ia32_switch_attributes(res, switch_table);",
119         ia32_copyb_attr_t =>
120                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
121                 "\tinit_ia32_copyb_attributes(res, size);",
122         ia32_immediate_attr_t =>
123                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
124                 "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
125         ia32_x87_attr_t =>
126                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
127                 "\tinit_ia32_x87_attributes(res);",
128         ia32_climbframe_attr_t =>
129                 "\tinit_ia32_attributes(res, irn_flags_, in_reqs, n_res);\n".
130                 "\tinit_ia32_climbframe_attributes(res, count);",
131 );
132
133 %compare_attr = (
134         ia32_asm_attr_t        => "ia32_compare_asm_attr",
135         ia32_attr_t            => "ia32_compare_nodes_attr",
136         ia32_call_attr_t       => "ia32_compare_call_attr",
137         ia32_condcode_attr_t   => "ia32_compare_condcode_attr",
138         ia32_copyb_attr_t      => "ia32_compare_copyb_attr",
139         ia32_switch_attr_t     => "ia32_compare_nodes_attr",
140         ia32_immediate_attr_t  => "ia32_compare_immediate_attr",
141         ia32_x87_attr_t        => "ia32_compare_x87_attr",
142         ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
143 );
144
145 $status_flags       = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
146 $status_flags_wo_cf = [       "PF", "AF", "ZF", "SF", "OF" ];
147 $fpcw_flags         = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
148                         "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
149
150 my %binop_flags_constructors = (
151         "" => {
152           reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
153                       out => [ "flags", "none", "none" ] },
154         },
155         "8bit" => {
156           reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ],
157                       out => [ "flags", "none", "none" ] },
158         }
159 );
160
161 my %binop_mem_constructors = (
162         ""     => { reg_req   => { in => [ "gp", "gp", "none", "gp" ],              out => [ "none" ] } },
163         "8bit" => { reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] } },
164 );
165
166 %nodes = (
167
168 Immediate => {
169         state     => "pinned",
170         op_flags  => [ "constlike" ],
171         irn_flags => [ "not_scheduled" ],
172         reg_req   => { out => [ "gp_NOREG:I" ] },
173         attr      => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
174         attr_type => "ia32_immediate_attr_t",
175         hash_func => "ia32_hash_Immediate",
176         latency   => 0,
177         mode      => $mode_gp,
178 },
179
180 Asm => {
181         mode      => "mode_T",
182         arity     => "variable",
183         out_arity => "variable",
184         attr_type => "ia32_asm_attr_t",
185         attr      => "ident *asm_text, const ia32_asm_reg_t *register_map",
186         init_attr => "attr->asm_text = asm_text;\n".
187                      "\tattr->register_map = register_map;\n",
188         latency   => 10,
189         modified_flags => $status_flags,
190 },
191
192 # "allocates" a free register
193 ProduceVal => {
194         op_flags  => [ "constlike", "cse_neutral" ],
195         irn_flags => [ "rematerializable" ],
196         reg_req   => { out => [ "gp" ] },
197         emit      => "",
198         latency   => 0,
199         mode      => $mode_gp,
200         cmp_attr  => "return 1;",
201 },
202
203 Add => {
204         irn_flags => [ "rematerializable" ],
205         state     => "exc_pinned",
206         reg_req   => { in  => [ "gp", "gp", "none", "gp", "gp" ],
207                        out => [ "in_r4 in_r5", "flags", "none" ] },
208         ins       => [ "base", "index", "mem", "left", "right" ],
209         outs      => [ "res", "flags", "M" ],
210         emit      => 'add%M %B',
211         am        => "source,binary",
212         latency   => 1,
213         mode      => $mode_gp,
214         modified_flags => $status_flags
215 },
216
217 AddMem => {
218         irn_flags => [ "rematerializable" ],
219         state     => "exc_pinned",
220         constructors => \%binop_mem_constructors,
221         ins       => [ "base", "index", "mem", "val" ],
222         emit      => "add%M %#S3, %AM",
223         latency   => 1,
224         mode      => "mode_M",
225         modified_flags => $status_flags
226 },
227
228 Adc => {
229         state     => "exc_pinned",
230         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
231                        out => [ "in_r4 in_r5", "flags", "none" ] },
232         ins       => [ "base", "index", "mem", "left", "right", "eflags" ],
233         outs      => [ "res", "flags", "M" ],
234         emit      => 'adc%M %B',
235         am        => "source,binary",
236         latency   => 1,
237         mode      => $mode_gp,
238         modified_flags => $status_flags
239 },
240
241 l_Add => {
242         ins       => [ "left", "right" ],
243         attr_type => "",
244         dump_func => "NULL",
245 },
246
247 l_Adc => {
248         ins       => [ "left", "right", "eflags" ],
249         attr_type => "",
250         dump_func => "NULL",
251 },
252
253 Mul => {
254         # we should not rematrialize this node. It produces 2 results and has
255         # very strict constraints
256         state     => "exc_pinned",
257         reg_req   => { in => [ "gp", "gp", "none", "eax", "gp" ],
258                        out => [ "eax", "flags", "none", "edx" ] },
259         ins       => [ "base", "index", "mem", "left", "right" ],
260         emit      => 'mul%M %AS4',
261         outs      => [ "res_low", "flags", "M", "res_high" ],
262         am        => "source,binary",
263         latency   => 10,
264         modified_flags => $status_flags
265 },
266
267 l_Mul => {
268         ins       => [ "left", "right" ],
269         outs      => [ "res_low", "flags", "M", "res_high" ],
270         attr_type => "",
271         dump_func => "NULL",
272 },
273
274 IMul => {
275         irn_flags => [ "rematerializable" ],
276         state     => "exc_pinned",
277         # TODO: adjust out requirements for the 3 operand form
278         # (no need for should_be_same then)
279         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
280                            out => [ "in_r4 in_r5", "flags", "none" ] },
281         ins       => [ "base", "index", "mem", "left", "right" ],
282         outs      => [ "res", "flags", "M" ],
283         am        => "source,binary",
284         latency   => 5,
285         mode      => $mode_gp,
286         modified_flags => $status_flags
287 },
288
289 IMul1OP => {
290         irn_flags => [ "rematerializable" ],
291         state     => "exc_pinned",
292         reg_req   => { in => [ "gp", "gp", "none", "eax", "gp" ],
293                        out => [ "eax", "flags", "none", "edx" ] },
294         ins       => [ "base", "index", "mem", "left", "right" ],
295         emit      => 'imul%M %AS4',
296         outs      => [ "res_low", "flags", "M", "res_high" ],
297         am        => "source,binary",
298         latency   => 5,
299         modified_flags => $status_flags
300 },
301
302 l_IMul => {
303         ins       => [ "left", "right" ],
304         outs      => [ "res_low", "flags", "M", "res_high" ],
305         attr_type => "",
306         dump_func => "NULL",
307 },
308
309 And => {
310         irn_flags => [ "rematerializable" ],
311         state     => "exc_pinned",
312         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
313                            out => [ "in_r4 in_r5", "flags", "none" ] },
314         ins       => [ "base", "index", "mem", "left", "right" ],
315         outs      => [ "res", "flags", "M" ],
316         am        => "source,binary",
317         emit      => 'and%M %B',
318         latency   => 1,
319         mode      => $mode_gp,
320         modified_flags => $status_flags
321 },
322
323 AndMem => {
324         irn_flags => [ "rematerializable" ],
325         state     => "exc_pinned",
326         constructors => \%binop_mem_constructors,
327         ins       => [ "base", "index", "mem", "val" ],
328         emit      => 'and%M %#S3, %AM',
329         latency   => 1,
330         mode      => "mode_M",
331         modified_flags => $status_flags
332 },
333
334 Or => {
335         irn_flags => [ "rematerializable" ],
336         state     => "exc_pinned",
337         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
338                        out => [ "in_r4 in_r5", "flags", "none" ] },
339         ins       => [ "base", "index", "mem", "left", "right" ],
340         outs      => [ "res", "flags", "M" ],
341         am        => "source,binary",
342         emit      => 'or%M %B',
343         latency   => 1,
344         mode      => $mode_gp,
345         modified_flags => $status_flags
346 },
347
348 OrMem => {
349         irn_flags => [ "rematerializable" ],
350         state     => "exc_pinned",
351         constructors => \%binop_mem_constructors,
352         ins       => [ "base", "index", "mem", "val" ],
353         emit      => 'or%M %#S3, %AM',
354         latency   => 1,
355         mode      => "mode_M",
356         modified_flags => $status_flags
357 },
358
359 Xor => {
360         irn_flags => [ "rematerializable" ],
361         state     => "exc_pinned",
362         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
363                        out => [ "in_r4 in_r5", "flags", "none" ] },
364         ins       => [ "base", "index", "mem", "left", "right" ],
365         outs      => [ "res", "flags", "M" ],
366         am        => "source,binary",
367         emit      => 'xor%M %B',
368         latency   => 1,
369         mode      => $mode_gp,
370         modified_flags => $status_flags
371 },
372
373 Xor0 => {
374         op_flags  => [ "constlike" ],
375         irn_flags => [ "rematerializable" ],
376         reg_req   => { out => [ "gp", "flags" ] },
377         outs      => [ "res", "flags" ],
378         emit      => "xor%M %D0, %D0",
379         latency   => 1,
380         mode      => $mode_gp,
381         modified_flags => $status_flags
382 },
383
384 XorMem => {
385         irn_flags => [ "rematerializable" ],
386         state     => "exc_pinned",
387         constructors => \%binop_mem_constructors,
388         ins       => [ "base", "index", "mem", "val" ],
389         emit      => 'xor%M %#S3, %AM',
390         latency   => 1,
391         mode      => "mode_M",
392         modified_flags => $status_flags
393 },
394
395 Sub => {
396         irn_flags => [ "rematerializable" ],
397         state     => "exc_pinned",
398         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
399                        out => [ "in_r4", "flags", "none" ] },
400         ins       => [ "base", "index", "mem", "minuend", "subtrahend" ],
401         outs      => [ "res", "flags", "M" ],
402         am        => "source,binary",
403         emit      => 'sub%M %B',
404         latency   => 1,
405         mode      => $mode_gp,
406         modified_flags => $status_flags
407 },
408
409 SubMem => {
410         irn_flags => [ "rematerializable" ],
411         state     => "exc_pinned",
412         constructors => \%binop_mem_constructors,
413         ins       => [ "base", "index", "mem", "subtrahend" ],
414         emit      => 'sub%M %#S3, %AM',
415         latency   => 1,
416         mode      => 'mode_M',
417         modified_flags => $status_flags
418 },
419
420 Sbb => {
421         state     => "exc_pinned",
422         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
423                        out => [ "in_r4", "flags", "none" ] },
424         ins       => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
425         outs      => [ "res", "flags", "M" ],
426         am        => "source,binary",
427         emit      => 'sbb%M %B',
428         latency   => 1,
429         mode      => $mode_gp,
430         modified_flags => $status_flags
431 },
432
433 Sbb0 => {
434         # Spiller currently fails when rematerializing flag consumers
435         # irn_flags => [ "rematerializable" ],
436         reg_req   => { in => [ "flags" ], out => [ "gp", "flags" ] },
437         outs      => [ "res", "flags" ],
438         emit      => "sbb%M %D0, %D0",
439         latency   => 1,
440         mode      => $mode_gp,
441         modified_flags => $status_flags
442 },
443
444 l_Sub => {
445         ins       => [ "minuend", "subtrahend" ],
446         attr_type => "",
447         dump_func => "NULL",
448 },
449
450 l_Sbb => {
451         ins       => [ "minuend", "subtrahend", "eflags" ],
452         attr_type => "",
453         dump_func => "NULL",
454 },
455
456 IDiv => {
457         op_flags  => [ "fragile", "uses_memory" ],
458         state     => "exc_pinned",
459         reg_req   => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
460                        out => [ "eax", "flags", "none", "edx", "none", "none" ] },
461         ins       => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
462         outs      => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
463         am        => "source,unary",
464         emit      => "idiv%M %AS3",
465         latency   => 25,
466         modified_flags => $status_flags
467 },
468
469 Div => {
470         op_flags  => [ "fragile", "uses_memory" ],
471         state     => "exc_pinned",
472         reg_req   => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
473                        out => [ "eax", "flags", "none", "edx", "none", "none" ] },
474         ins       => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
475         outs      => [ "div_res", "flags", "M", "mod_res", "X_regular", "X_except" ],
476         am        => "source,unary",
477         emit      => "div%M %AS3",
478         latency   => 25,
479         modified_flags => $status_flags
480 },
481
482 Shl => {
483         irn_flags => [ "rematerializable" ],
484         reg_req   => { in => [ "gp", "ecx" ],
485                        out => [ "in_r1 !in_r2", "flags" ] },
486         ins       => [ "val", "count" ],
487         outs      => [ "res", "flags" ],
488         emit      => 'shl%M %<S1, %S0',
489         latency   => 1,
490         mode      => $mode_gp,
491         modified_flags => $status_flags
492 },
493
494 ShlMem => {
495         irn_flags => [ "rematerializable" ],
496         state     => "exc_pinned",
497         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
498         ins       => [ "base", "index", "mem", "count" ],
499         emit      => 'shl%M %<S3, %AM',
500         latency   => 1,
501         mode      => "mode_M",
502         modified_flags => $status_flags
503 },
504
505 ShlD => {
506         irn_flags => [ "rematerializable" ],
507         reg_req   => { in => [ "gp", "gp", "ecx" ],
508                        out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
509         ins       => [ "val_high", "val_low", "count" ],
510         outs      => [ "res", "flags" ],
511         emit      => "shld%M %<S2, %S1, %D0",
512         latency   => 6,
513         mode      => $mode_gp,
514         modified_flags => $status_flags
515 },
516
517 Shr => {
518         irn_flags => [ "rematerializable" ],
519         reg_req   => { in => [ "gp", "ecx" ],
520                        out => [ "in_r1 !in_r2", "flags" ] },
521         ins       => [ "val", "count" ],
522         outs      => [ "res", "flags" ],
523         emit      => 'shr%M %<S1, %S0',
524         mode      => $mode_gp,
525         latency   => 1,
526         modified_flags => $status_flags
527 },
528
529 ShrMem => {
530         irn_flags => [ "rematerializable" ],
531         state     => "exc_pinned",
532         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
533         ins       => [ "base", "index", "mem", "count" ],
534         emit      => 'shr%M %<S3, %AM',
535         mode      => "mode_M",
536         latency   => 1,
537         modified_flags => $status_flags
538 },
539
540 ShrD => {
541         irn_flags => [ "rematerializable" ],
542         reg_req   => { in => [ "gp", "gp", "ecx" ],
543                        out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
544         ins       => [ "val_high", "val_low", "count" ],
545         outs      => [ "res", "flags" ],
546         emit      => "shrd%M %<S2, %S1, %D0",
547         latency   => 6,
548         mode      => $mode_gp,
549         modified_flags => $status_flags
550 },
551
552 Sar => {
553         irn_flags => [ "rematerializable" ],
554         reg_req   => { in => [ "gp", "ecx" ],
555                        out => [ "in_r1 !in_r2", "flags" ] },
556         ins       => [ "val", "count" ],
557         outs      => [ "res", "flags" ],
558         emit      => 'sar%M %<S1, %S0',
559         latency   => 1,
560         mode      => $mode_gp,
561         modified_flags => $status_flags
562 },
563
564 SarMem => {
565         irn_flags => [ "rematerializable" ],
566         state     => "exc_pinned",
567         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
568         ins       => [ "base", "index", "mem", "count" ],
569         emit      => 'sar%M %<S3, %AM',
570         latency   => 1,
571         mode      => "mode_M",
572         modified_flags => $status_flags
573 },
574
575 Ror => {
576         irn_flags => [ "rematerializable" ],
577         reg_req   => { in => [ "gp", "ecx" ],
578                        out => [ "in_r1 !in_r2", "flags" ] },
579         ins       => [ "val", "count" ],
580         outs      => [ "res", "flags" ],
581         emit      => 'ror%M %<S1, %S0',
582         latency   => 1,
583         mode      => $mode_gp,
584         modified_flags => $status_flags
585 },
586
587 RorMem => {
588         irn_flags => [ "rematerializable" ],
589         state     => "exc_pinned",
590         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
591         ins       => [ "base", "index", "mem", "count" ],
592         emit      => 'ror%M %<S3, %AM',
593         latency   => 1,
594         mode      => "mode_M",
595         modified_flags => $status_flags
596 },
597
598 Rol => {
599         irn_flags => [ "rematerializable" ],
600         reg_req   => { in => [ "gp", "ecx" ],
601                        out => [ "in_r1 !in_r2", "flags" ] },
602         ins       => [ "val", "count" ],
603         outs      => [ "res", "flags" ],
604         emit      => 'rol%M %<S1, %D0',
605         latency   => 1,
606         mode      => $mode_gp,
607         modified_flags => $status_flags
608 },
609
610 RolMem => {
611         irn_flags => [ "rematerializable" ],
612         state     => "exc_pinned",
613         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
614         ins       => [ "base", "index", "mem", "count" ],
615         emit      => 'rol%M %<S3, %AM',
616         latency   => 1,
617         mode      => "mode_M",
618         modified_flags => $status_flags
619 },
620
621 Neg => {
622         irn_flags => [ "rematerializable" ],
623         reg_req   => { in => [ "gp" ],
624                        out => [ "in_r1", "flags" ] },
625         emit      => 'neg%M %S0',
626         ins       => [ "val" ],
627         outs      => [ "res", "flags" ],
628         latency   => 1,
629         mode      => $mode_gp,
630         modified_flags => $status_flags
631 },
632
633 NegMem => {
634         irn_flags => [ "rematerializable" ],
635         state     => "exc_pinned",
636         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
637         ins       => [ "base", "index", "mem" ],
638         emit      => 'neg%M %AM',
639         latency   => 1,
640         mode      => "mode_M",
641         modified_flags => $status_flags
642 },
643
644 Minus64Bit => {
645         irn_flags => [ "rematerializable" ],
646         reg_req   => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
647         outs      => [ "low_res", "high_res" ],
648         latency   => 3,
649         modified_flags => $status_flags
650 },
651
652
653 Inc => {
654         irn_flags => [ "rematerializable" ],
655         reg_req   => { in => [ "gp" ],
656                        out => [ "in_r1", "flags" ] },
657         ins       => [ "val" ],
658         outs      => [ "res", "flags" ],
659         emit      => 'inc%M %S0',
660         mode      => $mode_gp,
661         latency   => 1,
662         modified_flags => $status_flags_wo_cf
663 },
664
665 IncMem => {
666         irn_flags => [ "rematerializable" ],
667         state     => "exc_pinned",
668         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
669         ins       => [ "base", "index", "mem" ],
670         emit      => 'inc%M %AM',
671         mode      => "mode_M",
672         latency   => 1,
673         modified_flags => $status_flags_wo_cf
674 },
675
676 Dec => {
677         irn_flags => [ "rematerializable" ],
678         reg_req   => { in => [ "gp" ],
679                        out => [ "in_r1", "flags" ] },
680         ins       => [ "val" ],
681         outs      => [ "res", "flags" ],
682         emit      => 'dec%M %S0',
683         mode      => $mode_gp,
684         latency   => 1,
685         modified_flags => $status_flags_wo_cf
686 },
687
688 DecMem => {
689         irn_flags => [ "rematerializable" ],
690         state     => "exc_pinned",
691         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
692         ins       => [ "base", "index", "mem" ],
693         emit      => 'dec%M %AM',
694         mode      => "mode_M",
695         latency   => 1,
696         modified_flags => $status_flags_wo_cf
697 },
698
699 Not => {
700         irn_flags => [ "rematerializable" ],
701         reg_req   => { in => [ "gp" ],
702                        out => [ "in_r1" ] },
703         ins       => [ "val" ],
704         outs      => [ "res" ],
705         emit      => 'not%M %S0',
706         latency   => 1,
707         mode      => $mode_gp,
708         # no flags modified
709 },
710
711 NotMem => {
712         irn_flags => [ "rematerializable" ],
713         state     => "exc_pinned",
714         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
715         ins       => [ "base", "index", "mem" ],
716         emit      => 'not%M %AM',
717         latency   => 1,
718         mode      => "mode_M",
719         # no flags modified
720 },
721
722 Cmc => {
723         reg_req   => { in => [ "flags" ], out => [ "flags" ] },
724         emit      => 'cmc',
725         latency   => 1,
726         mode      => $mode_flags,
727         modified_flags => $status_flags
728 },
729
730 Stc => {
731         reg_req   => { out => [ "flags" ] },
732         emit      => 'stc',
733         latency   => 1,
734         mode      => $mode_flags,
735         modified_flags => $status_flags
736 },
737
738 Cmp => {
739         irn_flags => [ "rematerializable" ],
740         state     => "exc_pinned",
741         constructors => \%binop_flags_constructors,
742         ins       => [ "base", "index", "mem", "left", "right" ],
743         outs      => [ "eflags", "unused", "M" ],
744         am        => "source,binary",
745         emit      => 'cmp%M %B',
746         attr      => "bool ins_permuted",
747         init_attr => "attr->data.ins_permuted   = ins_permuted;",
748         latency   => 1,
749         mode      => $mode_flags,
750         modified_flags => $status_flags
751 },
752
753 XorHighLow => {
754         irn_flags => [ "rematerializable" ],
755         state     => "exc_pinned",
756         reg_req   => { in => [ "eax ebx ecx edx" ],
757                        out => [ "in_r1", "flags" ] },
758         emit      => 'xorb %>S0, %<S0',
759         ins       => [ "value" ],
760         outs      => [ "res", "flags" ],
761         latency   => 1,
762         mode      => $mode_gp,
763         modified_flags => $status_flags,
764 },
765
766 Test => {
767         irn_flags => [ "rematerializable" ],
768         state     => "exc_pinned",
769         constructors => \%binop_flags_constructors,
770         ins       => [ "base", "index", "mem", "left", "right" ],
771         outs      => [ "eflags", "unused", "M" ],
772         am        => "source,binary",
773         emit      => 'test%M %B',
774         attr      => "bool ins_permuted",
775         init_attr => "attr->data.ins_permuted = ins_permuted;",
776         latency   => 1,
777         mode      => $mode_flags,
778         modified_flags => $status_flags
779 },
780
781 Setcc => {
782         #irn_flags => [ "rematerializable" ],
783         reg_req   => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
784         ins       => [ "eflags" ],
785         outs      => [ "res" ],
786         attr_type => "ia32_condcode_attr_t",
787         attr      => "ia32_condition_code_t condition_code",
788         # The way we handle Setcc with float nodes (potentially) destroys the flags
789         # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
790         init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
791                 . "\tif (condition_code & ia32_cc_additional_float_cases) {\n"
792                 . "\t\tarch_add_irn_flags(res, arch_irn_flags_modify_flags);\n"
793                 . "\t\t/* attr->latency = 3; */\n"
794                 . "\t}\n",
795         latency   => 1,
796         mode      => $mode_gp,
797 },
798
799 SetccMem => {
800         #irn_flags => [ "rematerializable" ],
801         state     => "exc_pinned",
802         reg_req   => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
803         ins       => [ "base", "index", "mem","eflags" ],
804         attr_type => "ia32_condcode_attr_t",
805         attr      => "ia32_condition_code_t condition_code",
806         init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
807         emit      => 'set%P3 %AM',
808         latency   => 1,
809         mode      => 'mode_M',
810 },
811
812 CMovcc => {
813         #irn_flags => [ "rematerializable" ],
814         state     => "exc_pinned",
815         # (note: leave the false,true order intact to make it compatible with other
816         #  ia32_binary ops)
817         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
818                        out => [ "in_r4 in_r5", "flags", "none" ] },
819         ins       => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
820         outs      => [ "res", "flags", "M" ],
821         am        => "source,binary",
822         attr_type => "ia32_condcode_attr_t",
823         attr      => "ia32_condition_code_t condition_code",
824         latency   => 1,
825         mode      => $mode_gp,
826 },
827
828 Jcc => {
829         state     => "pinned",
830         op_flags  => [ "cfopcode", "forking" ],
831         reg_req   => { in  => [ "eflags" ], out => [ "none", "none" ] },
832         ins       => [ "eflags" ],
833         outs      => [ "false", "true" ],
834         attr_type => "ia32_condcode_attr_t",
835         attr      => "ia32_condition_code_t condition_code",
836         latency   => 2,
837 },
838
839 SwitchJmp => {
840         state     => "pinned",
841         op_flags  => [ "cfopcode", "forking" ],
842         reg_req   => { in => [ "gp", "gp" ] },
843         ins       => [ "base", "index" ],
844         out_arity => "variable",
845         attr_type => "ia32_switch_attr_t",
846         attr      => "const ir_switch_table *switch_table",
847         latency   => 2,
848 },
849
850 Jmp => {
851         state     => "pinned",
852         irn_flags => [ "simple_jump" ],
853         op_flags  => [ "cfopcode" ],
854         reg_req   => { out => [ "none" ] },
855         latency   => 1,
856         mode      => "mode_X",
857 },
858
859 IJmp => {
860         state     => "pinned",
861         op_flags  => [ "cfopcode", "unknown_jump" ],
862         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
863                        out => [ "none", "flags", "none" ] },
864         ins       => [ "base", "index", "mem", "target" ],
865         outs      => [ "jmp", "flags", "M" ],
866         am        => "source,unary",
867         emit      => 'jmp %*AS3',
868         latency   => 1,
869         mode      => "mode_X",
870 },
871
872 Const => {
873         op_flags  => [ "constlike" ],
874         irn_flags => [ "rematerializable" ],
875         reg_req   => { out => [ "gp" ] },
876         emit      => "movl %I, %D0",
877         attr      => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
878         attr_type => "ia32_immediate_attr_t",
879         latency   => 1,
880         mode      => $mode_gp,
881 },
882
883 Unknown => {
884         op_flags  => [ "constlike" ],
885         irn_flags => [ "rematerializable" ],
886         reg_req   => { out => [ "gp" ] },
887         latency   => 0,
888         emit      => '',
889         mode      => $mode_gp,
890 },
891
892 GetEIP => {
893         op_flags => [ "constlike" ],
894         reg_req  => { out => [ "gp" ] },
895         latency  => 5,
896         mode     => $mode_gp,
897         modified_flags => $status_flags,
898 },
899
900 NoReg_GP => {
901         state     => "pinned",
902         op_flags  => [ "constlike", "dump_noblock" ],
903         irn_flags => [ "not_scheduled" ],
904         reg_req   => { out => [ "gp_NOREG:I" ] },
905         latency   => 0,
906         mode      => $mode_gp
907 },
908
909 NoReg_FP => {
910         state     => "pinned",
911         op_flags  => [ "constlike", "dump_noblock" ],
912         irn_flags => [ "not_scheduled" ],
913         reg_req   => { out => [ "fp_NOREG:I" ] },
914         mode      => $mode_fp87,
915         latency   => 0,
916         attr_type => "ia32_x87_attr_t",
917 },
918
919 NoReg_XMM => {
920         state     => "pinned",
921         op_flags  => [ "constlike", "dump_noblock" ],
922         irn_flags => [ "not_scheduled" ],
923         reg_req   => { out => [ "xmm_NOREG:I" ] },
924         latency   => 0,
925         mode      => $mode_xmm,
926 },
927
928 ChangeCW => {
929         state     => "pinned",
930         op_flags  => [ "constlike" ],
931         irn_flags => [ "not_scheduled" ],
932         reg_req   => { out => [ "fpcw" ] },
933         mode      => $mode_fpcw,
934         latency   => 3,
935         modified_flags => $fpcw_flags
936 },
937
938 FldCW => {
939         op_flags  => [ "uses_memory" ],
940         state     => "pinned",
941         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "fpcw" ] },
942         ins       => [ "base", "index", "mem" ],
943         latency   => 5,
944         emit      => "fldcw %AM",
945         mode      => $mode_fpcw,
946         modified_flags => $fpcw_flags
947 },
948
949 FnstCW => {
950         op_flags  => [ "uses_memory" ],
951         state     => "pinned",
952         reg_req   => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
953         ins       => [ "base", "index", "mem", "fpcw" ],
954         latency   => 5,
955         emit      => "fnstcw %AM",
956         mode      => "mode_M",
957 },
958
959 FnstCWNOP => {
960         op_flags  => [ "uses_memory" ],
961         state     => "pinned",
962         reg_req   => { in => [ "fp_cw" ], out => [ "none" ] },
963         ins       => [ "fpcw" ],
964         latency   => 0,
965         emit      => "",
966         mode      => "mode_M",
967 },
968
969 Cltd => {
970         # we should not rematrialize this node. It has very strict constraints.
971         reg_req   => { in => [ "eax", "edx" ], out => [ "edx" ] },
972         ins       => [ "val", "clobbered" ],
973         emit      => 'cltd',
974         latency   => 1,
975         mode      => $mode_gp,
976 },
977
978 # Load / Store
979 #
980 # Note that we add additional latency values depending on address mode, so a
981 # lateny of 0 for load is correct
982
983 Load => {
984         op_flags  => [ "uses_memory", "fragile" ],
985         state     => "exc_pinned",
986         reg_req   => { in => [ "gp", "gp", "none" ],
987                        out => [ "gp", "none", "none", "none", "none" ] },
988         ins       => [ "base", "index", "mem" ],
989         outs      => [ "res", "unused", "M", "X_regular", "X_except" ],
990         latency   => 0,
991         emit      => "mov%#Ml %AM, %D0",
992 },
993
994 Store => {
995         op_flags  => [ "uses_memory", "fragile" ],
996         state     => "exc_pinned",
997         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
998                        out => [ "none", "none", "none" ] },
999         ins       => [ "base", "index", "mem", "val" ],
1000         outs      => [ "M", "X_regular", "X_except" ],
1001         emit      => 'mov%M %#S3, %AM',
1002         latency   => 2,
1003 },
1004
1005 Store8Bit => {
1006         op_flags  => [ "uses_memory", "fragile" ],
1007         state     => "exc_pinned",
1008         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1009                        out => ["none", "none", "none" ] },
1010         ins       => [ "base", "index", "mem", "val" ],
1011         outs      => [ "M", "X_regular", "X_except" ],
1012         emit      => 'mov%M %#S3, %AM',
1013         latency   => 2,
1014 },
1015
1016 Lea => {
1017         irn_flags => [ "rematerializable" ],
1018         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
1019         ins       => [ "base", "index" ],
1020         emit      => 'leal %AM, %D0',
1021         latency   => 2,
1022         mode      => $mode_gp,
1023 # lea doesn't modify the flags, but setting this seems advantageous since it
1024 # increases chances that the Lea is transformed back to an Add
1025         modified_flags => 1,
1026 },
1027
1028 Push => {
1029         state     => "exc_pinned",
1030         reg_req   => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1031         ins       => [ "base", "index", "mem", "val", "stack" ],
1032         emit      => 'push%M %AS3',
1033         outs      => [ "stack", "M" ],
1034         am        => "source,unary",
1035         latency   => 2,
1036 },
1037
1038 PushEax => {
1039         state   => "exc_pinned",
1040         reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1041         ins     => [ "stack" ],
1042         outs    => [ "stack" ],
1043         emit    => 'pushl %%eax',
1044         latency => 2,
1045         mode    => $mode_gp,
1046 },
1047
1048 Pop => {
1049         state     => "exc_pinned",
1050         reg_req   => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1051         ins       => [ "mem", "stack" ],
1052         outs      => [ "res", "M", "unused", "stack" ],
1053         emit      => 'pop%M %D0',
1054         latency   => 3, # Pop is more expensive than Push on Athlon
1055 },
1056
1057 PopEbp => {
1058         state     => "exc_pinned",
1059         reg_req   => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1060         ins       => [ "mem", "stack" ],
1061         outs      => [ "res", "M", "unused", "stack" ],
1062         emit      => 'pop%M %D0',
1063         latency   => 3, # Pop is more expensive than Push on Athlon
1064 },
1065
1066 CopyEbpEsp => {
1067         state     => "exc_pinned",
1068         reg_req   => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1069         ins       => [ "ebp" ],
1070         outs      => [ "esp" ],
1071         emit      => 'movl %S0, %D0',
1072         latency   => 1,
1073         mode      => $mode_gp,
1074 },
1075
1076 PopMem => {
1077         state     => "exc_pinned",
1078         reg_req   => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1079         ins       => [ "base", "index", "mem", "stack" ],
1080         outs      => [ "unused0", "M", "unused1", "stack" ],
1081         emit      => 'pop%M %AM',
1082         latency   => 3, # Pop is more expensive than Push on Athlon
1083 },
1084
1085 Enter => {
1086         reg_req   => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1087         emit      => 'enter',
1088         outs      => [ "frame", "stack", "M" ],
1089         latency   => 15,
1090 },
1091
1092 Leave => {
1093         reg_req   => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1094         emit      => 'leave',
1095         outs      => [ "frame", "stack" ],
1096         latency   => 3,
1097         state     => "exc_pinned",
1098 },
1099
1100 AddSP => {
1101         state     => "pinned",
1102         reg_req   => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1103         ins       => [ "base", "index", "mem", "stack", "size" ],
1104         am        => "source,binary",
1105         emit      => 'addl %B',
1106         latency   => 1,
1107         outs      => [ "stack", "M" ],
1108         modified_flags => $status_flags
1109 },
1110
1111 SubSP => {
1112         state     => "pinned",
1113         reg_req   => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1114         ins       => [ "base", "index", "mem", "stack", "size" ],
1115         am        => "source,binary",
1116         emit      => "subl %B\n".
1117                      "movl %%esp, %D1",
1118         latency   => 2,
1119         outs      => [ "stack", "addr", "M" ],
1120         modified_flags => $status_flags
1121 },
1122
1123 RepPrefix => {
1124         op_flags  => [ "keep" ],
1125         state     => "pinned",
1126         mode      => "mode_M",
1127         emit      => "rep",
1128         latency   => 0,
1129 },
1130
1131 LdTls => {
1132         irn_flags => [ "rematerializable" ],
1133         reg_req   => { out => [ "gp" ] },
1134         emit      => "movl %%gs:0, %D0",
1135         mode      => $mode_gp,
1136         latency   => 1,
1137 },
1138
1139 #
1140 # BT supports source address mode, but this is unused yet
1141 #
1142 Bt => {
1143         irn_flags => [ "rematerializable" ],
1144         state     => "exc_pinned",
1145         reg_req   => { in => [ "gp", "gp" ], out => [ "flags" ] },
1146         ins       => [ "left", "right" ],
1147         emit      => 'bt%M %S1, %S0',
1148         latency   => 1,
1149         mode      => $mode_flags,
1150         modified_flags => $status_flags  # only CF is set, but the other flags are undefined
1151 },
1152
1153 Bsf => {
1154         irn_flags => [ "rematerializable" ],
1155         state     => "exc_pinned",
1156         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1157                        out => [ "gp", "flags", "none" ] },
1158         ins       => [ "base", "index", "mem", "operand" ],
1159         outs      => [ "res", "flags", "M" ],
1160         am        => "source,binary",
1161         emit      => 'bsf%M %AS3, %D0',
1162         latency   => 1,
1163         mode      => $mode_gp,
1164         modified_flags => $status_flags
1165 },
1166
1167 Bsr => {
1168         irn_flags => [ "rematerializable" ],
1169         state     => "exc_pinned",
1170         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1171                        out => [ "gp", "flags", "none" ] },
1172         ins       => [ "base", "index", "mem", "operand" ],
1173         outs      => [ "res", "flags", "M" ],
1174         am        => "source,binary",
1175         emit      => 'bsr%M %AS3, %D0',
1176         latency   => 1,
1177         mode      => $mode_gp,
1178         modified_flags => $status_flags
1179 },
1180
1181 #
1182 # SSE4.2 or SSE4a popcnt instruction
1183 #
1184 Popcnt => {
1185         irn_flags => [ "rematerializable" ],
1186         state     => "exc_pinned",
1187         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1188                        out => [ "gp", "flags", "none" ] },
1189         ins       => [ "base", "index", "mem", "operand" ],
1190         outs      => [ "res", "flags", "M" ],
1191         am        => "source,binary",
1192         emit      => 'popcnt%M %AS3, %D0',
1193         latency   => 1,
1194         mode      => $mode_gp,
1195         modified_flags => $status_flags
1196 },
1197
1198 Call => {
1199         op_flags  => [ "uses_memory", "fragile" ],
1200         state     => "exc_pinned",
1201         reg_req   => {
1202                 in  => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1203                 out => [ "esp:I|S", "fpcw", "none", "eax", "ecx", "edx", "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "none", "none" ]
1204         },
1205         ins       => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1206         outs      => [ "stack", "fpcw", "M", "eax", "ecx", "edx", "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "X_regular", "X_except" ],
1207         emit      => "call %*AS3",
1208         attr_type => "ia32_call_attr_t",
1209         attr      => "unsigned pop, ir_type *call_tp",
1210         am        => "source,unary",
1211         latency   => 4, # random number
1212         modified_flags => $status_flags
1213 },
1214
1215 #
1216 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1217 #
1218 # PS: try gcc __builtin_frame_address(100000) :-)
1219 #
1220 ClimbFrame => {
1221         reg_req   => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1222         ins       => [ "frame", "cnt", "tmp" ],
1223         outs      => [ "res" ],
1224         latency   => 4, # random number
1225         attr_type => "ia32_climbframe_attr_t",
1226         attr      => "unsigned count",
1227         mode      => $mode_gp
1228 },
1229
1230 #
1231 # bswap
1232 #
1233 Bswap => {
1234         irn_flags => [ "rematerializable" ],
1235         reg_req   => { in => [ "gp" ],
1236                        out => [ "in_r1" ] },
1237         outs      => [ "res" ],
1238         emit      => 'bswap%M %S0',
1239         ins       => [ "val" ],
1240         latency   => 1,
1241         mode      => $mode_gp,
1242 },
1243
1244 #
1245 # bswap16, use xchg here
1246 #
1247 Bswap16 => {
1248         irn_flags => [ "rematerializable" ],
1249         reg_req   => { in => [ "eax ebx ecx edx" ],
1250                        out => [ "in_r1" ] },
1251         emit      => 'xchg %<S0, %>S0',
1252         ins       => [ "val" ],
1253         latency   => 1,
1254         mode      => $mode_gp,
1255 },
1256
1257 #
1258 # BreakPoint
1259 #
1260 Breakpoint => {
1261         state     => "pinned",
1262         reg_req   => { in => [ "none" ], out => [ "none" ] },
1263         ins       => [ "mem" ],
1264         latency   => 0,
1265         emit      => "int3",
1266         mode      => mode_M,
1267 },
1268
1269 #
1270 # Undefined Instruction on ALL x86 CPU's
1271 #
1272 UD2 => {
1273         state     => "pinned",
1274         reg_req   => { in => [ "none" ], out => [ "none" ] },
1275         ins       => [ "mem" ],
1276         latency   => 0,
1277         emit      => "ud2",
1278         mode      => mode_M,
1279 },
1280
1281 #
1282 # outport
1283 #
1284 Outport => {
1285         irn_flags => [ "rematerializable" ],
1286         state     => "pinned",
1287         reg_req   => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1288         ins       => [ "port", "value", "mem" ],
1289         emit      => 'out%M %^S0, %#S1',
1290         latency   => 1,
1291         mode      => mode_M,
1292         modified_flags => $status_flags
1293 },
1294
1295 #
1296 # inport
1297 #
1298 Inport => {
1299         irn_flags => [ "rematerializable" ],
1300         state     => "pinned",
1301         reg_req   => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1302         ins       => [ "port", "mem" ],
1303         outs      => [ "res", "M" ],
1304         emit      => 'in%M %#D0, %^S0',
1305         latency   => 1,
1306         mode      => mode_T,
1307         modified_flags => $status_flags
1308 },
1309
1310 #
1311 # Intel style prefetching
1312 #
1313 Prefetch0 => {
1314         op_flags  => [ "uses_memory" ],
1315         state     => "exc_pinned",
1316         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1317         ins       => [ "base", "index", "mem" ],
1318         outs      => [ "M" ],
1319         latency   => 0,
1320         emit      => "prefetcht0 %AM",
1321 },
1322
1323 Prefetch1 => {
1324         op_flags  => [ "uses_memory" ],
1325         state     => "exc_pinned",
1326         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1327         ins       => [ "base", "index", "mem" ],
1328         outs      => [ "M" ],
1329         latency   => 0,
1330         emit      => "prefetcht1 %AM",
1331 },
1332
1333 Prefetch2 => {
1334         op_flags  => [ "uses_memory" ],
1335         state     => "exc_pinned",
1336         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1337         ins       => [ "base", "index", "mem" ],
1338         outs      => [ "M" ],
1339         latency   => 0,
1340         emit      => "prefetcht2 %AM",
1341 },
1342
1343 PrefetchNTA => {
1344         op_flags  => [ "uses_memory" ],
1345         state     => "exc_pinned",
1346         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1347         ins       => [ "base", "index", "mem" ],
1348         outs      => [ "M" ],
1349         latency   => 0,
1350         emit      => "prefetchnta %AM",
1351 },
1352
1353 #
1354 # 3DNow! prefetch instructions
1355 #
1356 Prefetch => {
1357         op_flags  => [ "uses_memory" ],
1358         state     => "exc_pinned",
1359         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1360         ins       => [ "base", "index", "mem" ],
1361         outs      => [ "M" ],
1362         latency   => 0,
1363         emit      => "prefetch %AM",
1364 },
1365
1366 PrefetchW => {
1367         op_flags  => [ "uses_memory" ],
1368         state     => "exc_pinned",
1369         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1370         ins       => [ "base", "index", "mem" ],
1371         outs      => [ "M" ],
1372         latency   => 0,
1373         emit      => "prefetchw %AM",
1374 },
1375
1376 # produces a 0/+0.0
1377 xZero => {
1378         irn_flags => [ "rematerializable" ],
1379         reg_req   => { out => [ "xmm" ] },
1380         emit      => 'xorp%FX %D0, %D0',
1381         latency   => 3,
1382         mode      => $mode_xmm
1383 },
1384
1385 xUnknown => {
1386         op_flags  => [ "constlike" ],
1387         irn_flags => [ "rematerializable" ],
1388         reg_req   => { out => [ "xmm" ] },
1389         emit      => '',
1390         latency   => 0,
1391         mode      => $mode_xmm
1392 },
1393
1394 xPzero => {
1395         irn_flags => [ "rematerializable" ],
1396         reg_req   => { out => [ "xmm" ] },
1397         emit      => 'pxor %D0, %D0',
1398         latency   => 3,
1399         mode      => $mode_xmm
1400 },
1401
1402 # produces all 1 bits
1403 xAllOnes => {
1404         irn_flags => [ "rematerializable" ],
1405         reg_req   => { out => [ "xmm" ] },
1406         emit      => 'pcmpeqb %D0, %D0',
1407         latency   => 3,
1408         mode      => $mode_xmm
1409 },
1410
1411 # integer shift left, dword
1412 xPslld => {
1413         irn_flags => [ "rematerializable" ],
1414         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1415         emit      => 'pslld %#S1, %D0',
1416         latency   => 3,
1417         mode      => $mode_xmm
1418 },
1419
1420 # integer shift left, qword
1421 xPsllq => {
1422         irn_flags => [ "rematerializable" ],
1423         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1424         emit      => 'psllq %#S1, %D0',
1425         latency   => 3,
1426         mode      => $mode_xmm
1427 },
1428
1429 # integer shift right, dword
1430 xPsrld => {
1431         irn_flags => [ "rematerializable" ],
1432         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1433         emit      => 'psrld %#S1, %D0',
1434         latency   => 1,
1435         mode      => $mode_xmm
1436 },
1437
1438 # mov from integer to SSE register
1439 xMovd  => {
1440         irn_flags => [ "rematerializable" ],
1441         reg_req   => { in => [ "gp" ], out => [ "xmm" ] },
1442         emit      => 'movd %S0, %D0',
1443         latency   => 1,
1444         mode      => $mode_xmm
1445 },
1446
1447 xAdd => {
1448         irn_flags => [ "rematerializable" ],
1449         state     => "exc_pinned",
1450         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1451                        out => [ "in_r4 in_r5", "flags", "none" ] },
1452         ins       => [ "base", "index", "mem", "left", "right" ],
1453         outs      => [ "res", "flags", "M" ],
1454         am        => "source,binary",
1455         emit      => 'adds%FX %B',
1456         latency   => 4,
1457         mode      => $mode_xmm
1458 },
1459
1460 xMul => {
1461         irn_flags => [ "rematerializable" ],
1462         state     => "exc_pinned",
1463         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1464                        out => [ "in_r4 in_r5", "flags", "none" ] },
1465         ins       => [ "base", "index", "mem", "left", "right" ],
1466         outs      => [ "res", "flags", "M" ],
1467         am        => "source,binary",
1468         emit      => 'muls%FX %B',
1469         latency   => 4,
1470         mode      => $mode_xmm
1471 },
1472
1473 xMax => {
1474         irn_flags => [ "rematerializable" ],
1475         state     => "exc_pinned",
1476         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1477                        out => [ "in_r4 in_r5", "flags", "none" ] },
1478         ins       => [ "base", "index", "mem", "left", "right" ],
1479         outs      => [ "res", "flags", "M" ],
1480         am        => "source,binary",
1481         emit      => 'maxs%FX %B',
1482         latency   => 2,
1483         mode      => $mode_xmm
1484 },
1485
1486 xMin => {
1487         irn_flags => [ "rematerializable" ],
1488         state     => "exc_pinned",
1489         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1490                        out => [ "in_r4 in_r5", "flags", "none" ] },
1491         ins       => [ "base", "index", "mem", "left", "right" ],
1492         outs      => [ "res", "flags", "M" ],
1493         am        => "source,binary",
1494         emit      => 'mins%FX %B',
1495         latency   => 2,
1496         mode      => $mode_xmm
1497 },
1498
1499 xAnd => {
1500         irn_flags => [ "rematerializable" ],
1501         state     => "exc_pinned",
1502         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1503                        out => [ "in_r4 in_r5", "flags", "none" ] },
1504         ins       => [ "base", "index", "mem", "left", "right" ],
1505         outs      => [ "res", "flags", "M" ],
1506         am        => "source,binary",
1507         emit      => 'andp%FX %B',
1508         latency   => 3,
1509         mode      => $mode_xmm
1510 },
1511
1512 xOr => {
1513         irn_flags => [ "rematerializable" ],
1514         state     => "exc_pinned",
1515         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1516                        out => [ "in_r4 in_r5", "flags", "none" ] },
1517         ins       => [ "base", "index", "mem", "left", "right" ],
1518         outs      => [ "res", "flags", "M" ],
1519         am        => "source,binary",
1520         emit      => 'orp%FX %B',
1521         latency   => 3,
1522         mode      => $mode_xmm
1523 },
1524
1525 xXor => {
1526         irn_flags => [ "rematerializable" ],
1527         state     => "exc_pinned",
1528         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1529                        out => [ "in_r4 in_r5", "flags", "none" ] },
1530         ins       => [ "base", "index", "mem", "left", "right" ],
1531         outs      => [ "res", "flags", "M" ],
1532         am        => "source,binary",
1533         emit      => 'xorp%FX %B',
1534         latency   => 3,
1535         mode      => $mode_xmm
1536 },
1537
1538 xAndNot => {
1539         irn_flags => [ "rematerializable" ],
1540         state     => "exc_pinned",
1541         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1542                        out => [ "in_r4 !in_r5", "flags", "none" ] },
1543         ins       => [ "base", "index", "mem", "left", "right" ],
1544         outs      => [ "res", "flags", "M" ],
1545         am        => "source,binary",
1546         emit      => 'andnp%FX %B',
1547         latency   => 3,
1548         mode      => $mode_xmm
1549 },
1550
1551 xSub => {
1552         irn_flags => [ "rematerializable" ],
1553         state     => "exc_pinned",
1554         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1555                        out => [ "in_r4", "flags", "none" ] },
1556         ins       => [ "base", "index", "mem", "minuend", "subtrahend" ],
1557         outs      => [ "res", "flags", "M" ],
1558         am        => "source,binary",
1559         emit      => 'subs%FX %B',
1560         latency   => 4,
1561         mode      => $mode_xmm
1562 },
1563
1564 xDiv => {
1565         irn_flags => [ "rematerializable" ],
1566         state     => "exc_pinned",
1567         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1568                        out => [ "in_r4 !in_r5", "flags", "none" ] },
1569         ins       => [ "base", "index", "mem", "dividend", "divisor" ],
1570         outs      => [ "res", "flags", "M" ],
1571         am        => "source,binary",
1572         emit      => 'divs%FX %B',
1573         latency   => 16,
1574 },
1575
1576 Ucomi => {
1577         irn_flags => [ "rematerializable" ],
1578         state     => "exc_pinned",
1579         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1580                        out => [ "eflags" ] },
1581         ins       => [ "base", "index", "mem", "left", "right" ],
1582         outs      => [ "flags" ],
1583         am        => "source,binary",
1584         attr      => "bool ins_permuted",
1585         init_attr => "attr->data.ins_permuted = ins_permuted;",
1586         emit      => 'ucomis%FX %B',
1587         latency   => 3,
1588         mode      => $mode_flags,
1589         modified_flags => 1,
1590 },
1591
1592 xLoad => {
1593         op_flags  => [ "uses_memory", "fragile" ],
1594         state     => "exc_pinned",
1595         reg_req   => { in => [ "gp", "gp", "none" ],
1596                        out => [ "xmm", "none", "none", "none", "none" ] },
1597         ins       => [ "base", "index", "mem" ],
1598         outs      => [ "res", "unused", "M", "X_regular", "X_except" ],
1599         emit      => 'movs%FX %AM, %D0',
1600         attr      => "ir_mode *load_mode",
1601         init_attr => "attr->ls_mode = load_mode;",
1602         latency   => 0,
1603 },
1604
1605 xStore => {
1606         op_flags => [ "uses_memory", "fragile" ],
1607         state    => "exc_pinned",
1608         reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
1609                       out => [ "none", "none", "none" ] },
1610         ins       => [ "base", "index", "mem", "val" ],
1611         outs      => [ "M", "X_regular", "X_except" ],
1612         emit     => 'movs%FX %S3, %AM',
1613         latency  => 0,
1614 },
1615
1616 xStoreSimple => {
1617         op_flags => [ "uses_memory", "fragile" ],
1618         state    => "exc_pinned",
1619         reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
1620                       out => [ "none", "none", "none" ] },
1621         ins      => [ "base", "index", "mem", "val" ],
1622         outs     => [ "M", "X_regular", "X_except" ],
1623         emit     => 'movs%FX %S3, %AM',
1624         latency  => 0,
1625 },
1626
1627 CvtSI2SS => {
1628         state     => "exc_pinned",
1629         reg_req  => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1630         ins      => [ "base", "index", "mem", "val" ],
1631         am       => "source,unary",
1632         emit     => 'cvtsi2ss %AS3, %D0',
1633         latency  => 2,
1634         mode     => $mode_xmm
1635 },
1636
1637 CvtSI2SD => {
1638         state     => "exc_pinned",
1639         reg_req  => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1640         ins      => [ "base", "index", "mem", "val" ],
1641         am       => "source,unary",
1642         emit     => 'cvtsi2sd %AS3, %D0',
1643         latency  => 2,
1644         mode     => $mode_xmm
1645 },
1646
1647
1648 l_LLtoFloat => {
1649         ins      => [ "val_high", "val_low" ],
1650         attr_type => "",
1651         dump_func => "NULL",
1652 },
1653
1654 l_FloattoLL => {
1655         ins      => [ "val" ],
1656         outs     => [ "res_high", "res_low" ],
1657         attr_type => "",
1658         dump_func => "NULL",
1659 },
1660
1661 CopyB => {
1662         op_flags  => [ "uses_memory", "fragile" ],
1663         state     => "pinned",
1664         reg_req   => { in => [ "edi", "esi", "ecx", "none" ],
1665                        out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1666         ins       => [ "dest", "source", "count", "mem" ],
1667         outs      => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1668         attr_type => "ia32_copyb_attr_t",
1669         attr      => "unsigned size",
1670         latency   => 3,
1671 # we don't care about this flag, so no need to mark this node
1672 #       modified_flags => [ "DF" ]
1673 },
1674
1675 CopyB_i => {
1676         op_flags  => [ "uses_memory", "fragile" ],
1677         state     => "pinned",
1678         reg_req   => { in => [ "edi", "esi", "none" ],
1679                        out => [  "edi", "esi", "none", "none", "none" ] },
1680         ins       => [ "dest", "source", "mem" ],
1681         outs      => [ "dest", "source", "M", "X_regular", "X_except" ],
1682         attr_type => "ia32_copyb_attr_t",
1683         attr      => "unsigned size",
1684         latency   => 3,
1685 # we don't care about this flag, so no need to mark this node
1686 #       modified_flags => [ "DF" ]
1687 },
1688
1689 Cwtl => {
1690         state     => "exc_pinned",
1691         reg_req   => { in => [ "eax" ], out => [ "eax" ] },
1692         ins       => [ "val" ],
1693         outs      => [ "res" ],
1694         emit      => 'cwtl',
1695         latency   => 1,
1696         mode      => $mode_gp,
1697 },
1698
1699 Conv_I2I => {
1700         op_flags  => [ "uses_memory", "fragile" ],
1701         state     => "exc_pinned",
1702         constructors => {
1703                 "" => {
1704                         reg_req => { in => [ "gp", "gp", "none", "gp" ],
1705                                     out => [ "gp", "none", "none", "none", "none" ] }
1706                 },
1707                 "8bit" => {
1708                         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1709                                       out => [ "gp", "none", "none", "none", "none" ] }
1710                 }
1711         },
1712         ins       => [ "base", "index", "mem", "val" ],
1713         outs      => [ "res", "flags", "M", "X_regular", "X_except" ],
1714         emit      => "mov%#Ml %#AS3, %D0",
1715         am        => "source,unary",
1716         latency   => 1,
1717         attr      => "ir_mode *smaller_mode",
1718         init_attr => "attr->ls_mode = smaller_mode;",
1719         mode      => $mode_gp,
1720 },
1721
1722 Conv_I2FP => {
1723         state     => "exc_pinned",
1724         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1725         ins       => [ "base", "index", "mem", "val" ],
1726         am        => "source,unary",
1727         latency   => 10,
1728         mode      => $mode_xmm,
1729 },
1730
1731 Conv_FP2I => {
1732         state     => "exc_pinned",
1733         reg_req   => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1734         ins       => [ "base", "index", "mem", "val" ],
1735         am        => "source,unary",
1736         latency   => 10,
1737         mode      => $mode_gp,
1738 },
1739
1740 Conv_FP2FP => {
1741         state     => "exc_pinned",
1742         reg_req   => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1743         ins       => [ "base", "index", "mem", "val" ],
1744         am        => "source,unary",
1745         latency   => 8,
1746         mode      => $mode_xmm,
1747 },
1748
1749 # rematerialisation disabled for all float nodes for now, because the fpcw
1750 # handler runs before spilling and we might end up with wrong fpcw then
1751
1752 fadd => {
1753 #       irn_flags => [ "rematerializable" ],
1754         state     => "exc_pinned",
1755         reg_req   => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1756                        out => [ "fp", "none", "none" ] },
1757         ins       => [ "base", "index", "mem", "left", "right", "fpcw" ],
1758         outs      => [ "res", "dummy", "M" ],
1759         emit      => 'fadd%FP%FM %AF',
1760         am        => "source,binary",
1761         latency   => 4,
1762         mode      => $mode_fp87,
1763         attr_type => "ia32_x87_attr_t",
1764 },
1765
1766 fmul => {
1767 #       irn_flags => [ "rematerializable" ],
1768         state     => "exc_pinned",
1769         reg_req   => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1770                        out => [ "fp", "none", "none" ] },
1771         ins       => [ "base", "index", "mem", "left", "right", "fpcw" ],
1772         outs      => [ "res", "dummy", "M" ],
1773         emit      => 'fmul%FP%FM %AF',
1774         am        => "source,binary",
1775         latency   => 4,
1776         mode      => $mode_fp87,
1777         attr_type => "ia32_x87_attr_t",
1778 },
1779
1780 fsub => {
1781 #       irn_flags => [ "rematerializable" ],
1782         state     => "exc_pinned",
1783         reg_req   => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1784                        out => [ "fp", "none", "none" ] },
1785         ins       => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
1786         outs      => [ "res", "dummy", "M" ],
1787         emit      => 'fsub%FR%FP%FM %AF',
1788         am        => "source,binary",
1789         latency   => 4,
1790         mode      => $mode_fp87,
1791         attr_type => "ia32_x87_attr_t",
1792 },
1793
1794 fdiv => {
1795         state     => "exc_pinned",
1796         reg_req   => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1797                        out => [ "fp", "none", "none" ] },
1798         ins       => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
1799         outs      => [ "res", "dummy", "M" ],
1800         emit      => 'fdiv%FR%FP%FM %AF',
1801         am        => "source,binary",
1802         latency   => 20,
1803         attr_type => "ia32_x87_attr_t",
1804 },
1805
1806 fprem => {
1807         reg_req   => { in => [ "fp", "fp", "fpcw" ], out => [ "fp" ] },
1808         ins       => [ "left", "right", "fpcw" ],
1809         emit      => 'fprem1',
1810         latency   => 20,
1811         mode      => $mode_fp87,
1812         attr_type => "ia32_x87_attr_t",
1813 },
1814
1815 fabs => {
1816         irn_flags => [ "rematerializable" ],
1817         reg_req   => { in => [ "fp"], out => [ "fp" ] },
1818         ins       => [ "value" ],
1819         emit      => 'fabs',
1820         latency   => 2,
1821         mode      => $mode_fp87,
1822         attr_type => "ia32_x87_attr_t",
1823 },
1824
1825 fchs => {
1826         irn_flags => [ "rematerializable" ],
1827         reg_req   => { in => [ "fp"], out => [ "fp" ] },
1828         emit      => 'fchs',
1829         ins       => [ "value" ],
1830         latency   => 2,
1831         mode      => $mode_fp87,
1832         attr_type => "ia32_x87_attr_t",
1833 },
1834
1835 fld => {
1836         irn_flags => [ "rematerializable" ],
1837         op_flags  => [ "uses_memory", "fragile" ],
1838         state     => "exc_pinned",
1839         reg_req   => { in => [ "gp", "gp", "none" ],
1840                        out => [ "fp", "none", "none", "none", "none" ] },
1841         ins       => [ "base", "index", "mem" ],
1842         outs      => [ "res", "unused", "M", "X_regular", "X_except" ],
1843         emit      => 'fld%FM %AM',
1844         attr      => "ir_mode *load_mode",
1845         init_attr => "attr->attr.ls_mode = load_mode;",
1846         latency   => 2,
1847         attr_type => "ia32_x87_attr_t",
1848 },
1849
1850 fst => {
1851         irn_flags => [ "rematerializable" ],
1852         op_flags  => [ "uses_memory", "fragile" ],
1853         state     => "exc_pinned",
1854         reg_req   => { in => [ "gp", "gp", "none", "fp" ],
1855                        out => [ "none", "none", "none" ] },
1856         ins       => [ "base", "index", "mem", "val" ],
1857         outs      => [ "M", "X_regular", "X_except" ],
1858         emit      => 'fst%FP%FM %AM',
1859         attr      => "ir_mode *store_mode",
1860         init_attr => "attr->attr.ls_mode = store_mode;",
1861         latency   => 2,
1862         attr_type => "ia32_x87_attr_t",
1863 },
1864
1865 fild => {
1866         state     => "exc_pinned",
1867         reg_req   => { in => [ "gp", "gp", "none" ],
1868                        out => [ "fp", "none", "none" ] },
1869         outs      => [ "res", "unused", "M" ],
1870         ins       => [ "base", "index", "mem" ],
1871         emit      => 'fild%FM %AM',
1872         latency   => 4,
1873         attr_type => "ia32_x87_attr_t",
1874 },
1875
1876 fist => {
1877         op_flags  => [ "uses_memory", "fragile" ],
1878         state     => "exc_pinned",
1879         reg_req   => { in => [ "gp", "gp", "none", "fp", "fpcw" ],
1880                        out => [ "none", "none", "none", "none" ] },
1881         ins       => [ "base", "index", "mem", "val", "fpcw" ],
1882         outs      => [ "dummy", "M", "X_regular", "X_except" ],
1883         emit      => 'fist%FP%FM %AM',
1884         latency   => 4,
1885         attr_type => "ia32_x87_attr_t",
1886 },
1887
1888 # SSE3 fisttp instruction
1889 fisttp => {
1890         op_flags  => [ "uses_memory", "fragile" ],
1891         state     => "exc_pinned",
1892         reg_req   => { in => [ "gp", "gp", "none", "fp" ],
1893                        out => [ "in_r4", "none", "none", "none" ]},
1894         ins       => [ "base", "index", "mem", "val" ],
1895         outs      => [ "res", "M", "X_regular", "X_except" ],
1896         emit      => 'fisttp%FM %AM',
1897         latency   => 4,
1898         attr_type => "ia32_x87_attr_t",
1899 },
1900
1901 fldz => {
1902         irn_flags => [ "rematerializable" ],
1903         reg_req   => { out => [ "fp" ] },
1904         outs      => [ "res" ],
1905         emit      => 'fldz',
1906         latency   => 4,
1907         mode      => $mode_fp87,
1908         attr_type => "ia32_x87_attr_t",
1909 },
1910
1911 fld1 => {
1912         irn_flags => [ "rematerializable" ],
1913         reg_req   => { out => [ "fp" ] },
1914         outs      => [ "res" ],
1915         emit      => 'fld1',
1916         latency   => 4,
1917         mode      => $mode_fp87,
1918         attr_type => "ia32_x87_attr_t",
1919 },
1920
1921 fldpi => {
1922         irn_flags => [ "rematerializable" ],
1923         reg_req   => { out => [ "fp" ] },
1924         outs      => [ "res" ],
1925         emit      => 'fldpi',
1926         latency   => 4,
1927         mode      => $mode_fp87,
1928         attr_type => "ia32_x87_attr_t",
1929 },
1930
1931 fldln2 => {
1932         irn_flags => [ "rematerializable" ],
1933         reg_req   => { out => [ "fp" ] },
1934         outs      => [ "res" ],
1935         emit      => 'fldln2',
1936         latency   => 4,
1937         mode      => $mode_fp87,
1938         attr_type => "ia32_x87_attr_t",
1939 },
1940
1941 fldlg2 => {
1942         irn_flags => [ "rematerializable" ],
1943         reg_req   => { out => [ "fp" ] },
1944         emit      => 'fldlg2',
1945         outs      => [ "res" ],
1946         latency   => 4,
1947         mode      => $mode_fp87,
1948         attr_type => "ia32_x87_attr_t",
1949 },
1950
1951 fldl2t => {
1952         irn_flags => [ "rematerializable" ],
1953         reg_req   => { out => [ "fp" ] },
1954         emit      => 'fldll2t',
1955         outs      => [ "res" ],
1956         latency   => 4,
1957         mode      => $mode_fp87,
1958         attr_type => "ia32_x87_attr_t",
1959 },
1960
1961 fldl2e => {
1962         irn_flags => [ "rematerializable" ],
1963         reg_req   => { out => [ "fp" ] },
1964         emit      => 'fldl2e',
1965         outs      => [ "res" ],
1966         latency   => 4,
1967         mode      => $mode_fp87,
1968         attr_type => "ia32_x87_attr_t",
1969 },
1970
1971 FucomFnstsw => {
1972 # we can't allow to rematerialize this node so we don't
1973 #  accidently produce Phi(Fucom, Fucom(ins_permuted))
1974 #       irn_flags => [ "rematerializable" ],
1975         reg_req   => { in => [ "fp", "fp" ], out => [ "eax" ] },
1976         ins       => [ "left", "right" ],
1977         outs      => [ "flags" ],
1978         emit      => "fucom%FP %F0\n".
1979                      "fnstsw %%ax",
1980         attr      => "bool ins_permuted",
1981         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
1982         latency   => 3,
1983         attr_type => "ia32_x87_attr_t",
1984         mode      => $mode_gp
1985 },
1986
1987 FucomppFnstsw => {
1988 # we can't allow to rematerialize this node so we don't
1989 #  accidently produce Phi(Fucom, Fucom(ins_permuted))
1990 #       irn_flags => [ "rematerializable" ],
1991         reg_req   => { in => [ "fp", "fp" ], out => [ "eax" ] },
1992         ins       => [ "left", "right" ],
1993         outs      => [ "flags" ],
1994         emit      => "fucompp\n".
1995                      "fnstsw %%ax",
1996         attr      => "bool ins_permuted",
1997         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
1998         latency   => 3,
1999         attr_type => "ia32_x87_attr_t",
2000         mode      => $mode_gp
2001 },
2002
2003 Fucomi => {
2004         irn_flags => [ "rematerializable" ],
2005         reg_req   => { in => [ "fp", "fp" ], out => [ "eflags" ] },
2006         ins       => [ "left", "right" ],
2007         outs      => [ "flags" ],
2008         emit      => 'fucom%FPi %F0',
2009         attr      => "bool ins_permuted",
2010         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2011         latency   => 3,
2012         attr_type => "ia32_x87_attr_t",
2013         mode      => $mode_gp
2014 },
2015
2016 FtstFnstsw => {
2017 #       irn_flags => [ "rematerializable" ],
2018         reg_req   => { in => [ "fp" ], out => [ "eax" ] },
2019         ins       => [ "left" ],
2020         outs      => [ "flags" ],
2021         emit      => "ftst\n".
2022                      "fnstsw %%ax",
2023         attr      => "bool ins_permuted",
2024         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2025         latency   => 3,
2026         attr_type => "ia32_x87_attr_t",
2027         mode      => $mode_gp
2028 },
2029
2030 Sahf => {
2031         irn_flags => [ "rematerializable" ],
2032         reg_req   => { in => [ "eax" ], out => [ "eflags" ] },
2033         ins       => [ "val" ],
2034         outs      => [ "flags" ],
2035         emit      => 'sahf',
2036         latency   => 1,
2037         mode      => $mode_flags,
2038 },
2039
2040 # fxch, fpush, fpop
2041 # Note that it is NEVER allowed to do CSE on these nodes
2042 # Moreover, note the virtual register requierements!
2043
2044 fxch => {
2045         op_flags  => [ "keep" ],
2046         reg_req   => { out => [ "none" ] },
2047         cmp_attr  => "return 1;",
2048         emit      => 'fxch %F0',
2049         attr_type => "ia32_x87_attr_t",
2050         mode      => "mode_ANY",
2051         latency   => 1,
2052 },
2053
2054 fpush => {
2055         op_flags  => [ "keep" ],
2056         reg_req   => { out => [ "none" ] },
2057         cmp_attr  => "return 1;",
2058         emit      => 'fld %F0',
2059         attr_type => "ia32_x87_attr_t",
2060         mode      => "mode_ANY",
2061         latency   => 1,
2062 },
2063
2064 fpushCopy => {
2065         reg_req   => { in => [ "fp"], out => [ "fp" ] },
2066         cmp_attr  => "return 1;",
2067         emit      => 'fld %F0',
2068         attr_type => "ia32_x87_attr_t",
2069         latency   => 1,
2070 },
2071
2072 fpop => {
2073         op_flags  => [ "keep" ],
2074         reg_req   => { out => [ "none" ] },
2075         cmp_attr  => "return 1;",
2076         emit      => 'fstp %F0',
2077         attr_type => "ia32_x87_attr_t",
2078         mode      => "mode_ANY",
2079         latency   => 1,
2080 },
2081
2082 ffreep => {
2083         op_flags  => [ "keep" ],
2084         reg_req   => { out => [ "none" ] },
2085         cmp_attr  => "return 1;",
2086         emit      => 'ffreep %F0',
2087         attr_type => "ia32_x87_attr_t",
2088         mode      => "mode_ANY",
2089         latency   => 1,
2090 },
2091
2092 emms => {
2093         op_flags  => [ "keep" ],
2094         reg_req   => { out => [ "none" ] },
2095         cmp_attr  => "return 1;",
2096         emit      => 'emms',
2097         attr_type => "ia32_x87_attr_t",
2098         mode      => "mode_ANY",
2099         latency   => 3,
2100 },
2101
2102 femms => {
2103         op_flags  => [ "keep" ],
2104         reg_req   => { out => [ "none" ] },
2105         cmp_attr  => "return 1;",
2106         emit      => 'femms',
2107         attr_type => "ia32_x87_attr_t",
2108         mode      => "mode_ANY",
2109         latency   => 3,
2110 },
2111
2112 # Spilling and reloading of SSE registers, hardcoded, not generated #
2113
2114 xxLoad => {
2115         op_flags  => [ "uses_memory", "fragile" ],
2116         state     => "exc_pinned",
2117         reg_req   => { in => [ "gp", "gp", "none" ],
2118                        out => [ "xmm", "none", "none", "none" ] },
2119         emit      => 'movdqu %D0, %AM',
2120         ins       => [ "base", "index", "mem" ],
2121         outs      => [ "res", "M", "X_regular", "X_except" ],
2122         latency   => 1,
2123 },
2124
2125 xxStore => {
2126         op_flags => [ "uses_memory", "fragile" ],
2127         state    => "exc_pinned",
2128         reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
2129                       out => [ "none", "none", "none" ] },
2130         ins      => [ "base", "index", "mem", "val" ],
2131         outs     => [ "M", "X_regular", "X_except" ],
2132         emit     => 'movdqu %B',
2133         latency  => 1,
2134 },
2135
2136 ); # end of %nodes
2137
2138 # Transform some attributes
2139 foreach my $op (keys(%nodes)) {
2140         my $node         = $nodes{$op};
2141         my $op_attr_init = $node->{op_attr_init};
2142
2143         if(defined($op_attr_init)) {
2144                 $op_attr_init .= "\n\t";
2145         } else {
2146                 $op_attr_init = "";
2147         }
2148
2149         if(!defined($node->{latency})) {
2150                 if($op =~ m/^l_/) {
2151                         $node->{latency} = 0;
2152                 } else {
2153                         die("Latency missing for op $op");
2154                 }
2155         }
2156         $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2157
2158         $node->{op_attr_init} = $op_attr_init;
2159 }
2160
2161 print "";