reenable femms
[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         constructors => {
998                 ""     => {
999                         reg_req => { in => [ "gp", "gp", "none", "gp" ],
1000                                     out => [ "none", "none", "none" ] }
1001                 },
1002                 "8bit" => {
1003                         reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1004                                     out => [ "none", "none", "none" ] }
1005                 }
1006         },
1007         ins       => [ "base", "index", "mem", "val" ],
1008         outs      => [ "M", "X_regular", "X_except" ],
1009         emit      => 'mov%M %#S3, %AM',
1010         latency   => 2,
1011 },
1012
1013 Lea => {
1014         irn_flags => [ "rematerializable" ],
1015         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
1016         ins       => [ "base", "index" ],
1017         emit      => 'leal %AM, %D0',
1018         latency   => 2,
1019         mode      => $mode_gp,
1020 # lea doesn't modify the flags, but setting this seems advantageous since it
1021 # increases chances that the Lea is transformed back to an Add
1022         modified_flags => 1,
1023 },
1024
1025 Push => {
1026         state     => "exc_pinned",
1027         reg_req   => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1028         ins       => [ "base", "index", "mem", "val", "stack" ],
1029         emit      => 'push%M %AS3',
1030         outs      => [ "stack", "M" ],
1031         am        => "source,unary",
1032         latency   => 2,
1033 },
1034
1035 PushEax => {
1036         state   => "exc_pinned",
1037         reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1038         ins     => [ "stack" ],
1039         outs    => [ "stack" ],
1040         emit    => 'pushl %%eax',
1041         latency => 2,
1042         mode    => $mode_gp,
1043 },
1044
1045 Pop => {
1046         state     => "exc_pinned",
1047         reg_req   => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1048         ins       => [ "mem", "stack" ],
1049         outs      => [ "res", "M", "unused", "stack" ],
1050         emit      => 'pop%M %D0',
1051         latency   => 3, # Pop is more expensive than Push on Athlon
1052 },
1053
1054 PopEbp => {
1055         state     => "exc_pinned",
1056         reg_req   => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1057         ins       => [ "mem", "stack" ],
1058         outs      => [ "res", "M", "unused", "stack" ],
1059         emit      => 'pop%M %D0',
1060         latency   => 3, # Pop is more expensive than Push on Athlon
1061 },
1062
1063 CopyEbpEsp => {
1064         state     => "exc_pinned",
1065         reg_req   => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1066         ins       => [ "ebp" ],
1067         outs      => [ "esp" ],
1068         emit      => 'movl %S0, %D0',
1069         latency   => 1,
1070         mode      => $mode_gp,
1071 },
1072
1073 PopMem => {
1074         state     => "exc_pinned",
1075         reg_req   => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1076         ins       => [ "base", "index", "mem", "stack" ],
1077         outs      => [ "unused0", "M", "unused1", "stack" ],
1078         emit      => 'pop%M %AM',
1079         latency   => 3, # Pop is more expensive than Push on Athlon
1080 },
1081
1082 Enter => {
1083         reg_req   => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1084         emit      => 'enter',
1085         outs      => [ "frame", "stack", "M" ],
1086         latency   => 15,
1087 },
1088
1089 Leave => {
1090         reg_req   => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1091         emit      => 'leave',
1092         outs      => [ "frame", "stack" ],
1093         latency   => 3,
1094         state     => "exc_pinned",
1095 },
1096
1097 AddSP => {
1098         state     => "pinned",
1099         reg_req   => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1100         ins       => [ "base", "index", "mem", "stack", "size" ],
1101         am        => "source,binary",
1102         emit      => 'addl %B',
1103         latency   => 1,
1104         outs      => [ "stack", "M" ],
1105         modified_flags => $status_flags
1106 },
1107
1108 SubSP => {
1109         state     => "pinned",
1110         reg_req   => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1111         ins       => [ "base", "index", "mem", "stack", "size" ],
1112         am        => "source,binary",
1113         emit      => "subl %B\n".
1114                      "movl %%esp, %D1",
1115         latency   => 2,
1116         outs      => [ "stack", "addr", "M" ],
1117         modified_flags => $status_flags
1118 },
1119
1120 RepPrefix => {
1121         op_flags  => [ "keep" ],
1122         state     => "pinned",
1123         mode      => "mode_M",
1124         emit      => "rep",
1125         latency   => 0,
1126 },
1127
1128 LdTls => {
1129         irn_flags => [ "rematerializable" ],
1130         reg_req   => { out => [ "gp" ] },
1131         emit      => "movl %%gs:0, %D0",
1132         mode      => $mode_gp,
1133         latency   => 1,
1134 },
1135
1136 #
1137 # BT supports source address mode, but this is unused yet
1138 #
1139 Bt => {
1140         irn_flags => [ "rematerializable" ],
1141         state     => "exc_pinned",
1142         reg_req   => { in => [ "gp", "gp" ], out => [ "flags" ] },
1143         ins       => [ "left", "right" ],
1144         emit      => 'bt%M %S1, %S0',
1145         latency   => 1,
1146         mode      => $mode_flags,
1147         modified_flags => $status_flags  # only CF is set, but the other flags are undefined
1148 },
1149
1150 Bsf => {
1151         irn_flags => [ "rematerializable" ],
1152         state     => "exc_pinned",
1153         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1154                        out => [ "gp", "flags", "none" ] },
1155         ins       => [ "base", "index", "mem", "operand" ],
1156         outs      => [ "res", "flags", "M" ],
1157         am        => "source,binary",
1158         emit      => 'bsf%M %AS3, %D0',
1159         latency   => 1,
1160         mode      => $mode_gp,
1161         modified_flags => $status_flags
1162 },
1163
1164 Bsr => {
1165         irn_flags => [ "rematerializable" ],
1166         state     => "exc_pinned",
1167         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1168                        out => [ "gp", "flags", "none" ] },
1169         ins       => [ "base", "index", "mem", "operand" ],
1170         outs      => [ "res", "flags", "M" ],
1171         am        => "source,binary",
1172         emit      => 'bsr%M %AS3, %D0',
1173         latency   => 1,
1174         mode      => $mode_gp,
1175         modified_flags => $status_flags
1176 },
1177
1178 #
1179 # SSE4.2 or SSE4a popcnt instruction
1180 #
1181 Popcnt => {
1182         irn_flags => [ "rematerializable" ],
1183         state     => "exc_pinned",
1184         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1185                        out => [ "gp", "flags", "none" ] },
1186         ins       => [ "base", "index", "mem", "operand" ],
1187         outs      => [ "res", "flags", "M" ],
1188         am        => "source,binary",
1189         emit      => 'popcnt%M %AS3, %D0',
1190         latency   => 1,
1191         mode      => $mode_gp,
1192         modified_flags => $status_flags
1193 },
1194
1195 Call => {
1196         op_flags  => [ "uses_memory", "fragile" ],
1197         state     => "exc_pinned",
1198         reg_req   => {
1199                 in  => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1200                 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" ]
1201         },
1202         ins       => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1203         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" ],
1204         emit      => "call %*AS3",
1205         attr_type => "ia32_call_attr_t",
1206         attr      => "unsigned pop, ir_type *call_tp",
1207         am        => "source,unary",
1208         latency   => 4, # random number
1209         modified_flags => $status_flags
1210 },
1211
1212 #
1213 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1214 #
1215 # PS: try gcc __builtin_frame_address(100000) :-)
1216 #
1217 ClimbFrame => {
1218         reg_req   => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1219         ins       => [ "frame", "cnt", "tmp" ],
1220         outs      => [ "res" ],
1221         latency   => 4, # random number
1222         attr_type => "ia32_climbframe_attr_t",
1223         attr      => "unsigned count",
1224         mode      => $mode_gp
1225 },
1226
1227 #
1228 # bswap
1229 #
1230 Bswap => {
1231         irn_flags => [ "rematerializable" ],
1232         reg_req   => { in => [ "gp" ],
1233                        out => [ "in_r1" ] },
1234         outs      => [ "res" ],
1235         emit      => 'bswap%M %S0',
1236         ins       => [ "val" ],
1237         latency   => 1,
1238         mode      => $mode_gp,
1239 },
1240
1241 #
1242 # bswap16, use xchg here
1243 #
1244 Bswap16 => {
1245         irn_flags => [ "rematerializable" ],
1246         reg_req   => { in => [ "eax ebx ecx edx" ],
1247                        out => [ "in_r1" ] },
1248         emit      => 'xchg %<S0, %>S0',
1249         ins       => [ "val" ],
1250         latency   => 1,
1251         mode      => $mode_gp,
1252 },
1253
1254 #
1255 # BreakPoint
1256 #
1257 Breakpoint => {
1258         state     => "pinned",
1259         reg_req   => { in => [ "none" ], out => [ "none" ] },
1260         ins       => [ "mem" ],
1261         latency   => 0,
1262         emit      => "int3",
1263         mode      => mode_M,
1264 },
1265
1266 #
1267 # Undefined Instruction on ALL x86 CPU's
1268 #
1269 UD2 => {
1270         state     => "pinned",
1271         reg_req   => { in => [ "none" ], out => [ "none" ] },
1272         ins       => [ "mem" ],
1273         latency   => 0,
1274         emit      => "ud2",
1275         mode      => mode_M,
1276 },
1277
1278 #
1279 # outport
1280 #
1281 Outport => {
1282         irn_flags => [ "rematerializable" ],
1283         state     => "pinned",
1284         reg_req   => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1285         ins       => [ "port", "value", "mem" ],
1286         emit      => 'out%M %^S0, %#S1',
1287         latency   => 1,
1288         mode      => mode_M,
1289         modified_flags => $status_flags
1290 },
1291
1292 #
1293 # inport
1294 #
1295 Inport => {
1296         irn_flags => [ "rematerializable" ],
1297         state     => "pinned",
1298         reg_req   => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1299         ins       => [ "port", "mem" ],
1300         outs      => [ "res", "M" ],
1301         emit      => 'in%M %#D0, %^S0',
1302         latency   => 1,
1303         mode      => mode_T,
1304         modified_flags => $status_flags
1305 },
1306
1307 #
1308 # Intel style prefetching
1309 #
1310 Prefetch0 => {
1311         op_flags  => [ "uses_memory" ],
1312         state     => "exc_pinned",
1313         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1314         ins       => [ "base", "index", "mem" ],
1315         outs      => [ "M" ],
1316         latency   => 0,
1317         emit      => "prefetcht0 %AM",
1318 },
1319
1320 Prefetch1 => {
1321         op_flags  => [ "uses_memory" ],
1322         state     => "exc_pinned",
1323         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1324         ins       => [ "base", "index", "mem" ],
1325         outs      => [ "M" ],
1326         latency   => 0,
1327         emit      => "prefetcht1 %AM",
1328 },
1329
1330 Prefetch2 => {
1331         op_flags  => [ "uses_memory" ],
1332         state     => "exc_pinned",
1333         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1334         ins       => [ "base", "index", "mem" ],
1335         outs      => [ "M" ],
1336         latency   => 0,
1337         emit      => "prefetcht2 %AM",
1338 },
1339
1340 PrefetchNTA => {
1341         op_flags  => [ "uses_memory" ],
1342         state     => "exc_pinned",
1343         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1344         ins       => [ "base", "index", "mem" ],
1345         outs      => [ "M" ],
1346         latency   => 0,
1347         emit      => "prefetchnta %AM",
1348 },
1349
1350 #
1351 # 3DNow! prefetch instructions
1352 #
1353 Prefetch => {
1354         op_flags  => [ "uses_memory" ],
1355         state     => "exc_pinned",
1356         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1357         ins       => [ "base", "index", "mem" ],
1358         outs      => [ "M" ],
1359         latency   => 0,
1360         emit      => "prefetch %AM",
1361 },
1362
1363 PrefetchW => {
1364         op_flags  => [ "uses_memory" ],
1365         state     => "exc_pinned",
1366         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1367         ins       => [ "base", "index", "mem" ],
1368         outs      => [ "M" ],
1369         latency   => 0,
1370         emit      => "prefetchw %AM",
1371 },
1372
1373 # produces a 0/+0.0
1374 xZero => {
1375         irn_flags => [ "rematerializable" ],
1376         reg_req   => { out => [ "xmm" ] },
1377         emit      => 'xorp%FX %D0, %D0',
1378         latency   => 3,
1379         mode      => $mode_xmm
1380 },
1381
1382 xUnknown => {
1383         op_flags  => [ "constlike" ],
1384         irn_flags => [ "rematerializable" ],
1385         reg_req   => { out => [ "xmm" ] },
1386         emit      => '',
1387         latency   => 0,
1388         mode      => $mode_xmm
1389 },
1390
1391 xPzero => {
1392         irn_flags => [ "rematerializable" ],
1393         reg_req   => { out => [ "xmm" ] },
1394         emit      => 'pxor %D0, %D0',
1395         latency   => 3,
1396         mode      => $mode_xmm
1397 },
1398
1399 # produces all 1 bits
1400 xAllOnes => {
1401         irn_flags => [ "rematerializable" ],
1402         reg_req   => { out => [ "xmm" ] },
1403         emit      => 'pcmpeqb %D0, %D0',
1404         latency   => 3,
1405         mode      => $mode_xmm
1406 },
1407
1408 # integer shift left, dword
1409 xPslld => {
1410         irn_flags => [ "rematerializable" ],
1411         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1412         emit      => 'pslld %#S1, %D0',
1413         latency   => 3,
1414         mode      => $mode_xmm
1415 },
1416
1417 # integer shift left, qword
1418 xPsllq => {
1419         irn_flags => [ "rematerializable" ],
1420         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1421         emit      => 'psllq %#S1, %D0',
1422         latency   => 3,
1423         mode      => $mode_xmm
1424 },
1425
1426 # integer shift right, dword
1427 xPsrld => {
1428         irn_flags => [ "rematerializable" ],
1429         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1430         emit      => 'psrld %#S1, %D0',
1431         latency   => 1,
1432         mode      => $mode_xmm
1433 },
1434
1435 # mov from integer to SSE register
1436 xMovd  => {
1437         irn_flags => [ "rematerializable" ],
1438         reg_req   => { in => [ "gp" ], out => [ "xmm" ] },
1439         emit      => 'movd %S0, %D0',
1440         latency   => 1,
1441         mode      => $mode_xmm
1442 },
1443
1444 xAdd => {
1445         irn_flags => [ "rematerializable" ],
1446         state     => "exc_pinned",
1447         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1448                        out => [ "in_r4 in_r5", "flags", "none" ] },
1449         ins       => [ "base", "index", "mem", "left", "right" ],
1450         outs      => [ "res", "flags", "M" ],
1451         am        => "source,binary",
1452         emit      => 'adds%FX %B',
1453         latency   => 4,
1454         mode      => $mode_xmm
1455 },
1456
1457 xMul => {
1458         irn_flags => [ "rematerializable" ],
1459         state     => "exc_pinned",
1460         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1461                        out => [ "in_r4 in_r5", "flags", "none" ] },
1462         ins       => [ "base", "index", "mem", "left", "right" ],
1463         outs      => [ "res", "flags", "M" ],
1464         am        => "source,binary",
1465         emit      => 'muls%FX %B',
1466         latency   => 4,
1467         mode      => $mode_xmm
1468 },
1469
1470 xMax => {
1471         irn_flags => [ "rematerializable" ],
1472         state     => "exc_pinned",
1473         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1474                        out => [ "in_r4 in_r5", "flags", "none" ] },
1475         ins       => [ "base", "index", "mem", "left", "right" ],
1476         outs      => [ "res", "flags", "M" ],
1477         am        => "source,binary",
1478         emit      => 'maxs%FX %B',
1479         latency   => 2,
1480         mode      => $mode_xmm
1481 },
1482
1483 xMin => {
1484         irn_flags => [ "rematerializable" ],
1485         state     => "exc_pinned",
1486         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1487                        out => [ "in_r4 in_r5", "flags", "none" ] },
1488         ins       => [ "base", "index", "mem", "left", "right" ],
1489         outs      => [ "res", "flags", "M" ],
1490         am        => "source,binary",
1491         emit      => 'mins%FX %B',
1492         latency   => 2,
1493         mode      => $mode_xmm
1494 },
1495
1496 xAnd => {
1497         irn_flags => [ "rematerializable" ],
1498         state     => "exc_pinned",
1499         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1500                        out => [ "in_r4 in_r5", "flags", "none" ] },
1501         ins       => [ "base", "index", "mem", "left", "right" ],
1502         outs      => [ "res", "flags", "M" ],
1503         am        => "source,binary",
1504         emit      => 'andp%FX %B',
1505         latency   => 3,
1506         mode      => $mode_xmm
1507 },
1508
1509 xOr => {
1510         irn_flags => [ "rematerializable" ],
1511         state     => "exc_pinned",
1512         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1513                        out => [ "in_r4 in_r5", "flags", "none" ] },
1514         ins       => [ "base", "index", "mem", "left", "right" ],
1515         outs      => [ "res", "flags", "M" ],
1516         am        => "source,binary",
1517         emit      => 'orp%FX %B',
1518         latency   => 3,
1519         mode      => $mode_xmm
1520 },
1521
1522 xXor => {
1523         irn_flags => [ "rematerializable" ],
1524         state     => "exc_pinned",
1525         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1526                        out => [ "in_r4 in_r5", "flags", "none" ] },
1527         ins       => [ "base", "index", "mem", "left", "right" ],
1528         outs      => [ "res", "flags", "M" ],
1529         am        => "source,binary",
1530         emit      => 'xorp%FX %B',
1531         latency   => 3,
1532         mode      => $mode_xmm
1533 },
1534
1535 xAndNot => {
1536         irn_flags => [ "rematerializable" ],
1537         state     => "exc_pinned",
1538         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1539                        out => [ "in_r4 !in_r5", "flags", "none" ] },
1540         ins       => [ "base", "index", "mem", "left", "right" ],
1541         outs      => [ "res", "flags", "M" ],
1542         am        => "source,binary",
1543         emit      => 'andnp%FX %B',
1544         latency   => 3,
1545         mode      => $mode_xmm
1546 },
1547
1548 xSub => {
1549         irn_flags => [ "rematerializable" ],
1550         state     => "exc_pinned",
1551         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1552                        out => [ "in_r4", "flags", "none" ] },
1553         ins       => [ "base", "index", "mem", "minuend", "subtrahend" ],
1554         outs      => [ "res", "flags", "M" ],
1555         am        => "source,binary",
1556         emit      => 'subs%FX %B',
1557         latency   => 4,
1558         mode      => $mode_xmm
1559 },
1560
1561 xDiv => {
1562         irn_flags => [ "rematerializable" ],
1563         state     => "exc_pinned",
1564         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1565                        out => [ "in_r4 !in_r5", "flags", "none" ] },
1566         ins       => [ "base", "index", "mem", "dividend", "divisor" ],
1567         outs      => [ "res", "flags", "M" ],
1568         am        => "source,binary",
1569         emit      => 'divs%FX %B',
1570         latency   => 16,
1571 },
1572
1573 Ucomi => {
1574         irn_flags => [ "rematerializable" ],
1575         state     => "exc_pinned",
1576         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1577                        out => [ "eflags" ] },
1578         ins       => [ "base", "index", "mem", "left", "right" ],
1579         outs      => [ "flags" ],
1580         am        => "source,binary",
1581         attr      => "bool ins_permuted",
1582         init_attr => "attr->data.ins_permuted = ins_permuted;",
1583         emit      => 'ucomis%FX %B',
1584         latency   => 3,
1585         mode      => $mode_flags,
1586         modified_flags => 1,
1587 },
1588
1589 xLoad => {
1590         op_flags  => [ "uses_memory", "fragile" ],
1591         state     => "exc_pinned",
1592         reg_req   => { in => [ "gp", "gp", "none" ],
1593                        out => [ "xmm", "none", "none", "none", "none" ] },
1594         ins       => [ "base", "index", "mem" ],
1595         outs      => [ "res", "unused", "M", "X_regular", "X_except" ],
1596         emit      => 'movs%FX %AM, %D0',
1597         attr      => "ir_mode *load_mode",
1598         init_attr => "attr->ls_mode = load_mode;",
1599         latency   => 0,
1600 },
1601
1602 xStore => {
1603         op_flags => [ "uses_memory", "fragile" ],
1604         state    => "exc_pinned",
1605         reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
1606                       out => [ "none", "none", "none" ] },
1607         ins       => [ "base", "index", "mem", "val" ],
1608         outs      => [ "M", "X_regular", "X_except" ],
1609         emit     => 'movs%FX %S3, %AM',
1610         latency  => 0,
1611 },
1612
1613 xStoreSimple => {
1614         op_flags => [ "uses_memory", "fragile" ],
1615         state    => "exc_pinned",
1616         reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
1617                       out => [ "none", "none", "none" ] },
1618         ins      => [ "base", "index", "mem", "val" ],
1619         outs     => [ "M", "X_regular", "X_except" ],
1620         emit     => 'movs%FX %S3, %AM',
1621         latency  => 0,
1622 },
1623
1624 CvtSI2SS => {
1625         state     => "exc_pinned",
1626         reg_req  => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1627         ins      => [ "base", "index", "mem", "val" ],
1628         am       => "source,unary",
1629         emit     => 'cvtsi2ss %AS3, %D0',
1630         latency  => 2,
1631         mode     => $mode_xmm
1632 },
1633
1634 CvtSI2SD => {
1635         state     => "exc_pinned",
1636         reg_req  => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1637         ins      => [ "base", "index", "mem", "val" ],
1638         am       => "source,unary",
1639         emit     => 'cvtsi2sd %AS3, %D0',
1640         latency  => 2,
1641         mode     => $mode_xmm
1642 },
1643
1644
1645 l_LLtoFloat => {
1646         ins      => [ "val_high", "val_low" ],
1647         attr_type => "",
1648         dump_func => "NULL",
1649 },
1650
1651 l_FloattoLL => {
1652         ins      => [ "val" ],
1653         outs     => [ "res_high", "res_low" ],
1654         attr_type => "",
1655         dump_func => "NULL",
1656 },
1657
1658 CopyB => {
1659         op_flags  => [ "uses_memory", "fragile" ],
1660         state     => "pinned",
1661         reg_req   => { in => [ "edi", "esi", "ecx", "none" ],
1662                        out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1663         ins       => [ "dest", "source", "count", "mem" ],
1664         outs      => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1665         attr_type => "ia32_copyb_attr_t",
1666         attr      => "unsigned size",
1667         latency   => 3,
1668 # we don't care about this flag, so no need to mark this node
1669 #       modified_flags => [ "DF" ]
1670 },
1671
1672 CopyB_i => {
1673         op_flags  => [ "uses_memory", "fragile" ],
1674         state     => "pinned",
1675         reg_req   => { in => [ "edi", "esi", "none" ],
1676                        out => [  "edi", "esi", "none", "none", "none" ] },
1677         ins       => [ "dest", "source", "mem" ],
1678         outs      => [ "dest", "source", "M", "X_regular", "X_except" ],
1679         attr_type => "ia32_copyb_attr_t",
1680         attr      => "unsigned size",
1681         latency   => 3,
1682 # we don't care about this flag, so no need to mark this node
1683 #       modified_flags => [ "DF" ]
1684 },
1685
1686 Cwtl => {
1687         state     => "exc_pinned",
1688         reg_req   => { in => [ "eax" ], out => [ "eax" ] },
1689         ins       => [ "val" ],
1690         outs      => [ "res" ],
1691         emit      => 'cwtl',
1692         latency   => 1,
1693         mode      => $mode_gp,
1694 },
1695
1696 Conv_I2I => {
1697         op_flags  => [ "uses_memory", "fragile" ],
1698         state     => "exc_pinned",
1699         constructors => {
1700                 "" => {
1701                         reg_req => { in => [ "gp", "gp", "none", "gp" ],
1702                                     out => [ "gp", "none", "none", "none", "none" ] }
1703                 },
1704                 "8bit" => {
1705                         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1706                                       out => [ "gp", "none", "none", "none", "none" ] }
1707                 }
1708         },
1709         ins       => [ "base", "index", "mem", "val" ],
1710         outs      => [ "res", "flags", "M", "X_regular", "X_except" ],
1711         emit      => "mov%#Ml %#AS3, %D0",
1712         am        => "source,unary",
1713         latency   => 1,
1714         attr      => "ir_mode *smaller_mode",
1715         init_attr => "attr->ls_mode = smaller_mode;",
1716         mode      => $mode_gp,
1717 },
1718
1719 Conv_I2FP => {
1720         state     => "exc_pinned",
1721         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1722         ins       => [ "base", "index", "mem", "val" ],
1723         am        => "source,unary",
1724         latency   => 10,
1725         mode      => $mode_xmm,
1726 },
1727
1728 Conv_FP2I => {
1729         state     => "exc_pinned",
1730         reg_req   => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1731         ins       => [ "base", "index", "mem", "val" ],
1732         am        => "source,unary",
1733         latency   => 10,
1734         mode      => $mode_gp,
1735 },
1736
1737 Conv_FP2FP => {
1738         state     => "exc_pinned",
1739         reg_req   => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1740         ins       => [ "base", "index", "mem", "val" ],
1741         am        => "source,unary",
1742         latency   => 8,
1743         mode      => $mode_xmm,
1744 },
1745
1746 # rematerialisation disabled for all float nodes for now, because the fpcw
1747 # handler runs before spilling and we might end up with wrong fpcw then
1748
1749 fadd => {
1750 #       irn_flags => [ "rematerializable" ],
1751         state     => "exc_pinned",
1752         reg_req   => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1753                        out => [ "fp", "none", "none" ] },
1754         ins       => [ "base", "index", "mem", "left", "right", "fpcw" ],
1755         outs      => [ "res", "dummy", "M" ],
1756         emit      => 'fadd%FP%FM %AF',
1757         am        => "source,binary",
1758         latency   => 4,
1759         mode      => $mode_fp87,
1760         attr_type => "ia32_x87_attr_t",
1761 },
1762
1763 fmul => {
1764 #       irn_flags => [ "rematerializable" ],
1765         state     => "exc_pinned",
1766         reg_req   => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1767                        out => [ "fp", "none", "none" ] },
1768         ins       => [ "base", "index", "mem", "left", "right", "fpcw" ],
1769         outs      => [ "res", "dummy", "M" ],
1770         emit      => 'fmul%FP%FM %AF',
1771         am        => "source,binary",
1772         latency   => 4,
1773         mode      => $mode_fp87,
1774         attr_type => "ia32_x87_attr_t",
1775 },
1776
1777 fsub => {
1778 #       irn_flags => [ "rematerializable" ],
1779         state     => "exc_pinned",
1780         reg_req   => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1781                        out => [ "fp", "none", "none" ] },
1782         ins       => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
1783         outs      => [ "res", "dummy", "M" ],
1784         emit      => 'fsub%FR%FP%FM %AF',
1785         am        => "source,binary",
1786         latency   => 4,
1787         mode      => $mode_fp87,
1788         attr_type => "ia32_x87_attr_t",
1789 },
1790
1791 fdiv => {
1792         state     => "exc_pinned",
1793         reg_req   => { in => [ "gp", "gp", "none", "fp", "fp", "fpcw" ],
1794                        out => [ "fp", "none", "none" ] },
1795         ins       => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
1796         outs      => [ "res", "dummy", "M" ],
1797         emit      => 'fdiv%FR%FP%FM %AF',
1798         am        => "source,binary",
1799         latency   => 20,
1800         attr_type => "ia32_x87_attr_t",
1801 },
1802
1803 fprem => {
1804         reg_req   => { in => [ "fp", "fp", "fpcw" ], out => [ "fp" ] },
1805         ins       => [ "left", "right", "fpcw" ],
1806         emit      => 'fprem1',
1807         latency   => 20,
1808         mode      => $mode_fp87,
1809         attr_type => "ia32_x87_attr_t",
1810 },
1811
1812 fabs => {
1813         irn_flags => [ "rematerializable" ],
1814         reg_req   => { in => [ "fp"], out => [ "fp" ] },
1815         ins       => [ "value" ],
1816         emit      => 'fabs',
1817         latency   => 2,
1818         mode      => $mode_fp87,
1819         attr_type => "ia32_x87_attr_t",
1820 },
1821
1822 fchs => {
1823         irn_flags => [ "rematerializable" ],
1824         reg_req   => { in => [ "fp"], out => [ "fp" ] },
1825         emit      => 'fchs',
1826         ins       => [ "value" ],
1827         latency   => 2,
1828         mode      => $mode_fp87,
1829         attr_type => "ia32_x87_attr_t",
1830 },
1831
1832 fld => {
1833         irn_flags => [ "rematerializable" ],
1834         op_flags  => [ "uses_memory", "fragile" ],
1835         state     => "exc_pinned",
1836         reg_req   => { in => [ "gp", "gp", "none" ],
1837                        out => [ "fp", "none", "none", "none", "none" ] },
1838         ins       => [ "base", "index", "mem" ],
1839         outs      => [ "res", "unused", "M", "X_regular", "X_except" ],
1840         emit      => 'fld%FM %AM',
1841         attr      => "ir_mode *load_mode",
1842         init_attr => "attr->attr.ls_mode = load_mode;",
1843         latency   => 2,
1844         attr_type => "ia32_x87_attr_t",
1845 },
1846
1847 fst => {
1848         irn_flags => [ "rematerializable" ],
1849         op_flags  => [ "uses_memory", "fragile" ],
1850         state     => "exc_pinned",
1851         reg_req   => { in => [ "gp", "gp", "none", "fp" ],
1852                        out => [ "none", "none", "none" ] },
1853         ins       => [ "base", "index", "mem", "val" ],
1854         outs      => [ "M", "X_regular", "X_except" ],
1855         emit      => 'fst%FP%FM %AM',
1856         attr      => "ir_mode *store_mode",
1857         init_attr => "attr->attr.ls_mode = store_mode;",
1858         latency   => 2,
1859         attr_type => "ia32_x87_attr_t",
1860 },
1861
1862 fild => {
1863         state     => "exc_pinned",
1864         reg_req   => { in => [ "gp", "gp", "none" ],
1865                        out => [ "fp", "none", "none" ] },
1866         outs      => [ "res", "unused", "M" ],
1867         ins       => [ "base", "index", "mem" ],
1868         emit      => 'fild%FM %AM',
1869         latency   => 4,
1870         attr_type => "ia32_x87_attr_t",
1871 },
1872
1873 fist => {
1874         op_flags  => [ "uses_memory", "fragile" ],
1875         state     => "exc_pinned",
1876         reg_req   => { in => [ "gp", "gp", "none", "fp", "fpcw" ],
1877                        out => [ "none", "none", "none", "none" ] },
1878         ins       => [ "base", "index", "mem", "val", "fpcw" ],
1879         outs      => [ "dummy", "M", "X_regular", "X_except" ],
1880         emit      => 'fist%FP%FM %AM',
1881         latency   => 4,
1882         attr_type => "ia32_x87_attr_t",
1883 },
1884
1885 # SSE3 fisttp instruction
1886 fisttp => {
1887         op_flags  => [ "uses_memory", "fragile" ],
1888         state     => "exc_pinned",
1889         reg_req   => { in => [ "gp", "gp", "none", "fp" ],
1890                        out => [ "in_r4", "none", "none", "none" ]},
1891         ins       => [ "base", "index", "mem", "val" ],
1892         outs      => [ "res", "M", "X_regular", "X_except" ],
1893         emit      => 'fisttp%FM %AM',
1894         latency   => 4,
1895         attr_type => "ia32_x87_attr_t",
1896 },
1897
1898 fldz => {
1899         irn_flags => [ "rematerializable" ],
1900         reg_req   => { out => [ "fp" ] },
1901         outs      => [ "res" ],
1902         emit      => 'fldz',
1903         latency   => 4,
1904         mode      => $mode_fp87,
1905         attr_type => "ia32_x87_attr_t",
1906 },
1907
1908 fld1 => {
1909         irn_flags => [ "rematerializable" ],
1910         reg_req   => { out => [ "fp" ] },
1911         outs      => [ "res" ],
1912         emit      => 'fld1',
1913         latency   => 4,
1914         mode      => $mode_fp87,
1915         attr_type => "ia32_x87_attr_t",
1916 },
1917
1918 fldpi => {
1919         irn_flags => [ "rematerializable" ],
1920         reg_req   => { out => [ "fp" ] },
1921         outs      => [ "res" ],
1922         emit      => 'fldpi',
1923         latency   => 4,
1924         mode      => $mode_fp87,
1925         attr_type => "ia32_x87_attr_t",
1926 },
1927
1928 fldln2 => {
1929         irn_flags => [ "rematerializable" ],
1930         reg_req   => { out => [ "fp" ] },
1931         outs      => [ "res" ],
1932         emit      => 'fldln2',
1933         latency   => 4,
1934         mode      => $mode_fp87,
1935         attr_type => "ia32_x87_attr_t",
1936 },
1937
1938 fldlg2 => {
1939         irn_flags => [ "rematerializable" ],
1940         reg_req   => { out => [ "fp" ] },
1941         emit      => 'fldlg2',
1942         outs      => [ "res" ],
1943         latency   => 4,
1944         mode      => $mode_fp87,
1945         attr_type => "ia32_x87_attr_t",
1946 },
1947
1948 fldl2t => {
1949         irn_flags => [ "rematerializable" ],
1950         reg_req   => { out => [ "fp" ] },
1951         emit      => 'fldll2t',
1952         outs      => [ "res" ],
1953         latency   => 4,
1954         mode      => $mode_fp87,
1955         attr_type => "ia32_x87_attr_t",
1956 },
1957
1958 fldl2e => {
1959         irn_flags => [ "rematerializable" ],
1960         reg_req   => { out => [ "fp" ] },
1961         emit      => 'fldl2e',
1962         outs      => [ "res" ],
1963         latency   => 4,
1964         mode      => $mode_fp87,
1965         attr_type => "ia32_x87_attr_t",
1966 },
1967
1968 FucomFnstsw => {
1969 # we can't allow to rematerialize this node so we don't
1970 #  accidently produce Phi(Fucom, Fucom(ins_permuted))
1971 #       irn_flags => [ "rematerializable" ],
1972         reg_req   => { in => [ "fp", "fp" ], out => [ "eax" ] },
1973         ins       => [ "left", "right" ],
1974         outs      => [ "flags" ],
1975         emit      => "fucom%FP %F0\n".
1976                      "fnstsw %%ax",
1977         attr      => "bool ins_permuted",
1978         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
1979         latency   => 3,
1980         attr_type => "ia32_x87_attr_t",
1981         mode      => $mode_gp
1982 },
1983
1984 FucomppFnstsw => {
1985 # we can't allow to rematerialize this node so we don't
1986 #  accidently produce Phi(Fucom, Fucom(ins_permuted))
1987 #       irn_flags => [ "rematerializable" ],
1988         reg_req   => { in => [ "fp", "fp" ], out => [ "eax" ] },
1989         ins       => [ "left", "right" ],
1990         outs      => [ "flags" ],
1991         emit      => "fucompp\n".
1992                      "fnstsw %%ax",
1993         attr      => "bool ins_permuted",
1994         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
1995         latency   => 3,
1996         attr_type => "ia32_x87_attr_t",
1997         mode      => $mode_gp
1998 },
1999
2000 Fucomi => {
2001         irn_flags => [ "rematerializable" ],
2002         reg_req   => { in => [ "fp", "fp" ], out => [ "eflags" ] },
2003         ins       => [ "left", "right" ],
2004         outs      => [ "flags" ],
2005         emit      => 'fucom%FPi %F0',
2006         attr      => "bool ins_permuted",
2007         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2008         latency   => 3,
2009         attr_type => "ia32_x87_attr_t",
2010         mode      => $mode_gp
2011 },
2012
2013 FtstFnstsw => {
2014 #       irn_flags => [ "rematerializable" ],
2015         reg_req   => { in => [ "fp" ], out => [ "eax" ] },
2016         ins       => [ "left" ],
2017         outs      => [ "flags" ],
2018         emit      => "ftst\n".
2019                      "fnstsw %%ax",
2020         attr      => "bool ins_permuted",
2021         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2022         latency   => 3,
2023         attr_type => "ia32_x87_attr_t",
2024         mode      => $mode_gp
2025 },
2026
2027 Sahf => {
2028         irn_flags => [ "rematerializable" ],
2029         reg_req   => { in => [ "eax" ], out => [ "eflags" ] },
2030         ins       => [ "val" ],
2031         outs      => [ "flags" ],
2032         emit      => 'sahf',
2033         latency   => 1,
2034         mode      => $mode_flags,
2035 },
2036
2037 # fxch, fpush, fpop
2038 # Note that it is NEVER allowed to do CSE on these nodes
2039 # Moreover, note the virtual register requierements!
2040
2041 fxch => {
2042         op_flags  => [ "keep" ],
2043         reg_req   => { out => [ "none" ] },
2044         cmp_attr  => "return 1;",
2045         emit      => 'fxch %F0',
2046         attr_type => "ia32_x87_attr_t",
2047         mode      => "mode_ANY",
2048         latency   => 1,
2049 },
2050
2051 fpush => {
2052         op_flags  => [ "keep" ],
2053         reg_req   => { out => [ "none" ] },
2054         cmp_attr  => "return 1;",
2055         emit      => 'fld %F0',
2056         attr_type => "ia32_x87_attr_t",
2057         mode      => "mode_ANY",
2058         latency   => 1,
2059 },
2060
2061 fpushCopy => {
2062         reg_req   => { in => [ "fp"], out => [ "fp" ] },
2063         cmp_attr  => "return 1;",
2064         emit      => 'fld %F0',
2065         attr_type => "ia32_x87_attr_t",
2066         latency   => 1,
2067 },
2068
2069 fpop => {
2070         op_flags  => [ "keep" ],
2071         reg_req   => { out => [ "none" ] },
2072         cmp_attr  => "return 1;",
2073         emit      => 'fstp %F0',
2074         attr_type => "ia32_x87_attr_t",
2075         mode      => "mode_ANY",
2076         latency   => 1,
2077 },
2078
2079 ffreep => {
2080         op_flags  => [ "keep" ],
2081         reg_req   => { out => [ "none" ] },
2082         cmp_attr  => "return 1;",
2083         emit      => 'ffreep %F0',
2084         attr_type => "ia32_x87_attr_t",
2085         mode      => "mode_ANY",
2086         latency   => 1,
2087 },
2088
2089 emms => {
2090         op_flags  => [ "keep" ],
2091         reg_req   => { out => [ "none" ] },
2092         cmp_attr  => "return 1;",
2093         emit      => 'emms',
2094         attr_type => "ia32_x87_attr_t",
2095         mode      => "mode_ANY",
2096         latency   => 3,
2097 },
2098
2099 femms => {
2100         op_flags  => [ "keep" ],
2101         reg_req   => { out => [ "none" ] },
2102         cmp_attr  => "return 1;",
2103         emit      => 'femms',
2104         attr_type => "ia32_x87_attr_t",
2105         mode      => "mode_ANY",
2106         latency   => 3,
2107 },
2108
2109 # Spilling and reloading of SSE registers, hardcoded, not generated #
2110
2111 xxLoad => {
2112         op_flags  => [ "uses_memory", "fragile" ],
2113         state     => "exc_pinned",
2114         reg_req   => { in => [ "gp", "gp", "none" ],
2115                        out => [ "xmm", "none", "none", "none" ] },
2116         emit      => 'movdqu %D0, %AM',
2117         ins       => [ "base", "index", "mem" ],
2118         outs      => [ "res", "M", "X_regular", "X_except" ],
2119         latency   => 1,
2120 },
2121
2122 xxStore => {
2123         op_flags => [ "uses_memory", "fragile" ],
2124         state    => "exc_pinned",
2125         reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
2126                       out => [ "none", "none", "none" ] },
2127         ins      => [ "base", "index", "mem", "val" ],
2128         outs     => [ "M", "X_regular", "X_except" ],
2129         emit     => 'movdqu %B',
2130         latency  => 1,
2131 },
2132
2133 ); # end of %nodes
2134
2135 # Transform some attributes
2136 foreach my $op (keys(%nodes)) {
2137         my $node         = $nodes{$op};
2138         my $op_attr_init = $node->{op_attr_init};
2139
2140         if(defined($op_attr_init)) {
2141                 $op_attr_init .= "\n\t";
2142         } else {
2143                 $op_attr_init = "";
2144         }
2145
2146         if(!defined($node->{latency})) {
2147                 if($op =~ m/^l_/) {
2148                         $node->{latency} = 0;
2149                 } else {
2150                         die("Latency missing for op $op");
2151                 }
2152         }
2153         $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2154
2155         $node->{op_attr_init} = $op_attr_init;
2156 }
2157
2158 print "";