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