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