x87: Simplify x87 code generation.
[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                        out => [ "none", "flags", "none" ] },
1031         ins       => [ "base", "index", "mem", "target" ],
1032         outs      => [ "jmp", "flags", "M" ],
1033         am        => "source,unary",
1034         emit      => 'jmp %*AS3',
1035         latency   => 1,
1036         units     => [ "BRANCH" ],
1037         mode      => "mode_X",
1038 },
1039
1040 Const => {
1041         op_flags  => [ "constlike" ],
1042         irn_flags => [ "rematerializable" ],
1043         reg_req   => { out => [ "gp" ] },
1044         emit      => "movl %I, %D0",
1045         units     => [ "GP" ],
1046         attr      => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
1047         attr_type => "ia32_immediate_attr_t",
1048         latency   => 1,
1049         mode      => $mode_gp,
1050 },
1051
1052 Unknown => {
1053         op_flags  => [ "constlike" ],
1054         irn_flags => [ "rematerializable" ],
1055         reg_req   => { out => [ "gp" ] },
1056         latency   => 0,
1057         emit      => '',
1058         mode      => $mode_gp,
1059 },
1060
1061 GetEIP => {
1062         op_flags => [ "constlike" ],
1063         reg_req  => { out => [ "gp" ] },
1064         units    => [ "GP" ],
1065         latency  => 5,
1066         mode     => $mode_gp,
1067         modified_flags => $status_flags,
1068 },
1069
1070 NoReg_GP => {
1071         state     => "pinned",
1072         op_flags  => [ "constlike", "dump_noblock" ],
1073         irn_flags => [ "not_scheduled" ],
1074         reg_req   => { out => [ "gp_NOREG:I" ] },
1075         units     => [],
1076         emit      => "",
1077         latency   => 0,
1078         mode      => $mode_gp
1079 },
1080
1081 NoReg_VFP => {
1082         state     => "pinned",
1083         op_flags  => [ "constlike", "dump_noblock" ],
1084         irn_flags => [ "not_scheduled" ],
1085         reg_req   => { out => [ "vfp_NOREG:I" ] },
1086         units     => [],
1087         emit      => "",
1088         mode      => $mode_fp87,
1089         latency   => 0,
1090         attr_type => "ia32_x87_attr_t",
1091 },
1092
1093 NoReg_XMM => {
1094         state     => "pinned",
1095         op_flags  => [ "constlike", "dump_noblock" ],
1096         irn_flags => [ "not_scheduled" ],
1097         reg_req   => { out => [ "xmm_NOREG:I" ] },
1098         units     => [],
1099         emit      => "",
1100         latency   => 0,
1101         mode      => $mode_xmm,
1102 },
1103
1104 ChangeCW => {
1105         state     => "pinned",
1106         op_flags  => [ "constlike" ],
1107         irn_flags => [ "not_scheduled" ],
1108         reg_req   => { out => [ "fpcw:I" ] },
1109         mode      => $mode_fpcw,
1110         latency   => 3,
1111         units     => [ "GP" ],
1112         modified_flags => $fpcw_flags
1113 },
1114
1115 FldCW => {
1116         op_flags  => [ "uses_memory" ],
1117         state     => "pinned",
1118         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] },
1119         ins       => [ "base", "index", "mem" ],
1120         latency   => 5,
1121         emit      => "fldcw %AM",
1122         mode      => $mode_fpcw,
1123         units     => [ "GP" ],
1124         modified_flags => $fpcw_flags
1125 },
1126
1127 FnstCW => {
1128         op_flags  => [ "uses_memory" ],
1129         state     => "pinned",
1130         reg_req   => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1131         ins       => [ "base", "index", "mem", "fpcw" ],
1132         latency   => 5,
1133         emit      => "fnstcw %AM",
1134         mode      => "mode_M",
1135         units     => [ "GP" ],
1136 },
1137
1138 FnstCWNOP => {
1139         op_flags  => [ "uses_memory" ],
1140         state     => "pinned",
1141         reg_req   => { in => [ "fp_cw" ], out => [ "none" ] },
1142         ins       => [ "fpcw" ],
1143         latency   => 0,
1144         emit      => "",
1145         mode      => "mode_M",
1146 },
1147
1148 Cltd => {
1149         # we should not rematrialize this node. It has very strict constraints.
1150         reg_req   => { in => [ "eax", "edx" ], out => [ "edx" ] },
1151         ins       => [ "val", "clobbered" ],
1152         emit      => 'cltd',
1153         latency   => 1,
1154         mode      => $mode_gp,
1155         units     => [ "GP" ],
1156 },
1157
1158 # Load / Store
1159 #
1160 # Note that we add additional latency values depending on address mode, so a
1161 # lateny of 0 for load is correct
1162
1163 Load => {
1164         op_flags  => [ "uses_memory", "fragile" ],
1165         state     => "exc_pinned",
1166         reg_req   => { in => [ "gp", "gp", "none" ],
1167                        out => [ "gp", "none", "none", "none", "none" ] },
1168         ins       => [ "base", "index", "mem" ],
1169         outs      => [ "res", "unused", "M", "X_regular", "X_except" ],
1170         latency   => 0,
1171         emit      => "mov%#Ml %AM, %D0",
1172         units     => [ "GP" ],
1173 },
1174
1175 Store => {
1176         op_flags  => [ "uses_memory", "fragile" ],
1177         state     => "exc_pinned",
1178         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1179                        out => [ "none", "none", "none" ] },
1180         ins       => [ "base", "index", "mem", "val" ],
1181         outs      => [ "M", "X_regular", "X_except" ],
1182         emit      => 'mov%M %#S3, %AM',
1183         latency   => 2,
1184         units     => [ "GP" ],
1185 },
1186
1187 Store8Bit => {
1188         op_flags  => [ "uses_memory", "fragile" ],
1189         state     => "exc_pinned",
1190         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1191                        out => ["none", "none", "none" ] },
1192         ins       => [ "base", "index", "mem", "val" ],
1193         outs      => [ "M", "X_regular", "X_except" ],
1194         emit      => 'mov%M %#S3, %AM',
1195         latency   => 2,
1196         units     => [ "GP" ],
1197 },
1198
1199 Lea => {
1200         irn_flags => [ "rematerializable" ],
1201         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
1202         ins       => [ "base", "index" ],
1203         emit      => 'leal %AM, %D0',
1204         latency   => 2,
1205         units     => [ "GP" ],
1206         mode      => $mode_gp,
1207 # lea doesn't modify the flags, but setting this seems advantageous since it
1208 # increases chances that the Lea is transformed back to an Add
1209         modified_flags => 1,
1210 },
1211
1212 Push => {
1213         state     => "exc_pinned",
1214         reg_req   => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1215         ins       => [ "base", "index", "mem", "val", "stack" ],
1216         emit      => 'push%M %AS3',
1217         outs      => [ "stack", "M" ],
1218         am        => "source,unary",
1219         latency   => 2,
1220         units     => [ "GP" ],
1221 },
1222
1223 PushEax => {
1224         state   => "exc_pinned",
1225         reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1226         ins     => [ "stack" ],
1227         outs    => [ "stack" ],
1228         emit    => 'pushl %%eax',
1229         latency => 2,
1230         units   => [ "GP" ],
1231         mode    => $mode_gp,
1232 },
1233
1234 Pop => {
1235         state     => "exc_pinned",
1236         reg_req   => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1237         ins       => [ "mem", "stack" ],
1238         outs      => [ "res", "M", "unused", "stack" ],
1239         emit      => 'pop%M %D0',
1240         latency   => 3, # Pop is more expensive than Push on Athlon
1241         units     => [ "GP" ],
1242 },
1243
1244 PopEbp => {
1245         state     => "exc_pinned",
1246         reg_req   => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1247         ins       => [ "mem", "stack" ],
1248         outs      => [ "res", "M", "unused", "stack" ],
1249         emit      => 'pop%M %D0',
1250         latency   => 3, # Pop is more expensive than Push on Athlon
1251         units     => [ "GP" ],
1252 },
1253
1254 CopyEbpEsp => {
1255         state     => "exc_pinned",
1256         reg_req   => { in => [ "ebp" ], out => [ "esp:I|S" ] },
1257         ins       => [ "ebp" ],
1258         outs      => [ "esp" ],
1259         emit      => 'movl %S0, %D0',
1260         latency   => 1,
1261         units     => [ "GP" ],
1262         mode      => $mode_gp,
1263 },
1264
1265 PopMem => {
1266         state     => "exc_pinned",
1267         reg_req   => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1268         ins       => [ "base", "index", "mem", "stack" ],
1269         outs      => [ "unused0", "M", "unused1", "stack" ],
1270         emit      => 'pop%M %AM',
1271         latency   => 3, # Pop is more expensive than Push on Athlon
1272         units     => [ "GP" ],
1273 },
1274
1275 Enter => {
1276         reg_req   => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1277         emit      => 'enter',
1278         outs      => [ "frame", "stack", "M" ],
1279         latency   => 15,
1280         units     => [ "GP" ],
1281 },
1282
1283 Leave => {
1284         reg_req   => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1285         emit      => 'leave',
1286         outs      => [ "frame", "stack" ],
1287         latency   => 3,
1288         units     => [ "GP" ],
1289         state     => "exc_pinned",
1290 },
1291
1292 AddSP => {
1293         state     => "pinned",
1294         reg_req   => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1295         ins       => [ "base", "index", "mem", "stack", "size" ],
1296         am        => "source,binary",
1297         emit      => 'addl %B',
1298         latency   => 1,
1299         outs      => [ "stack", "M" ],
1300         units     => [ "GP" ],
1301         modified_flags => $status_flags
1302 },
1303
1304 SubSP => {
1305         state     => "pinned",
1306         reg_req   => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1307         ins       => [ "base", "index", "mem", "stack", "size" ],
1308         am        => "source,binary",
1309         emit      => "subl %B\n".
1310                      "movl %%esp, %D1",
1311         latency   => 2,
1312         outs      => [ "stack", "addr", "M" ],
1313         units     => [ "GP" ],
1314         modified_flags => $status_flags
1315 },
1316
1317 RepPrefix => {
1318         op_flags  => [ "keep" ],
1319         state     => "pinned",
1320         mode      => "mode_M",
1321         emit      => "rep",
1322         latency   => 0,
1323 },
1324
1325 LdTls => {
1326         irn_flags => [ "rematerializable" ],
1327         reg_req   => { out => [ "gp" ] },
1328         units     => [ "GP" ],
1329         emit      => "movl %%gs:0, %D0",
1330         mode      => $mode_gp,
1331         latency   => 1,
1332 },
1333
1334 #
1335 # BT supports source address mode, but this is unused yet
1336 #
1337 Bt => {
1338         irn_flags => [ "rematerializable" ],
1339         state     => "exc_pinned",
1340         reg_req   => { in => [ "gp", "gp" ], out => [ "flags" ] },
1341         ins       => [ "left", "right" ],
1342         emit      => 'bt%M %S1, %S0',
1343         units     => [ "GP" ],
1344         latency   => 1,
1345         mode      => $mode_flags,
1346         modified_flags => $status_flags  # only CF is set, but the other flags are undefined
1347 },
1348
1349 Bsf => {
1350         irn_flags => [ "rematerializable" ],
1351         state     => "exc_pinned",
1352         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1353                        out => [ "gp", "flags", "none" ] },
1354         ins       => [ "base", "index", "mem", "operand" ],
1355         outs      => [ "res", "flags", "M" ],
1356         am        => "source,binary",
1357         emit      => 'bsf%M %AS3, %D0',
1358         units     => [ "GP" ],
1359         latency   => 1,
1360         mode      => $mode_gp,
1361         modified_flags => $status_flags
1362 },
1363
1364 Bsr => {
1365         irn_flags => [ "rematerializable" ],
1366         state     => "exc_pinned",
1367         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1368                        out => [ "gp", "flags", "none" ] },
1369         ins       => [ "base", "index", "mem", "operand" ],
1370         outs      => [ "res", "flags", "M" ],
1371         am        => "source,binary",
1372         emit      => 'bsr%M %AS3, %D0',
1373         units     => [ "GP" ],
1374         latency   => 1,
1375         mode      => $mode_gp,
1376         modified_flags => $status_flags
1377 },
1378
1379 #
1380 # SSE4.2 or SSE4a popcnt instruction
1381 #
1382 Popcnt => {
1383         irn_flags => [ "rematerializable" ],
1384         state     => "exc_pinned",
1385         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1386                        out => [ "gp", "flags", "none" ] },
1387         ins       => [ "base", "index", "mem", "operand" ],
1388         outs      => [ "res", "flags", "M" ],
1389         am        => "source,binary",
1390         emit      => 'popcnt%M %AS3, %D0',
1391         units     => [ "GP" ],
1392         latency   => 1,
1393         mode      => $mode_gp,
1394         modified_flags => $status_flags
1395 },
1396
1397 Call => {
1398         op_flags  => [ "uses_memory", "fragile" ],
1399         state     => "exc_pinned",
1400         reg_req   => {
1401                 in  => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1402                 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" ]
1403         },
1404         ins       => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1405         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" ],
1406         emit      => "call %*AS3",
1407         attr_type => "ia32_call_attr_t",
1408         attr      => "unsigned pop, ir_type *call_tp",
1409         am        => "source,unary",
1410         units     => [ "BRANCH" ],
1411         latency   => 4, # random number
1412         modified_flags => $status_flags
1413 },
1414
1415 #
1416 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1417 #
1418 # PS: try gcc __builtin_frame_address(100000) :-)
1419 #
1420 ClimbFrame => {
1421         reg_req   => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1422         ins       => [ "frame", "cnt", "tmp" ],
1423         outs      => [ "res" ],
1424         latency   => 4, # random number
1425         attr_type => "ia32_climbframe_attr_t",
1426         attr      => "unsigned count",
1427         units     => [ "GP" ],
1428         mode      => $mode_gp
1429 },
1430
1431 #
1432 # bswap
1433 #
1434 Bswap => {
1435         irn_flags => [ "rematerializable" ],
1436         reg_req   => { in => [ "gp" ],
1437                        out => [ "in_r1" ] },
1438         outs      => [ "res" ],
1439         emit      => 'bswap%M %S0',
1440         ins       => [ "val" ],
1441         units     => [ "GP" ],
1442         latency   => 1,
1443         mode      => $mode_gp,
1444 },
1445
1446 #
1447 # bswap16, use xchg here
1448 #
1449 Bswap16 => {
1450         irn_flags => [ "rematerializable" ],
1451         reg_req   => { in => [ "eax ebx ecx edx" ],
1452                        out => [ "in_r1" ] },
1453         emit      => 'xchg %<S0, %>S0',
1454         ins       => [ "val" ],
1455         units     => [ "GP" ],
1456         latency   => 1,
1457         mode      => $mode_gp,
1458 },
1459
1460 #
1461 # BreakPoint
1462 #
1463 Breakpoint => {
1464         state     => "pinned",
1465         reg_req   => { in => [ "none" ], out => [ "none" ] },
1466         ins       => [ "mem" ],
1467         latency   => 0,
1468         emit      => "int3",
1469         units     => [ "GP" ],
1470         mode      => mode_M,
1471 },
1472
1473 #
1474 # Undefined Instruction on ALL x86 CPU's
1475 #
1476 UD2 => {
1477         state     => "pinned",
1478         reg_req   => { in => [ "none" ], out => [ "none" ] },
1479         ins       => [ "mem" ],
1480         latency   => 0,
1481         emit      => "ud2",
1482         units     => [ "GP" ],
1483         mode      => mode_M,
1484 },
1485
1486 #
1487 # outport
1488 #
1489 Outport => {
1490         irn_flags => [ "rematerializable" ],
1491         state     => "pinned",
1492         reg_req   => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1493         ins       => [ "port", "value", "mem" ],
1494         emit      => 'out%M %^S0, %#S1',
1495         units     => [ "GP" ],
1496         latency   => 1,
1497         mode      => mode_M,
1498         modified_flags => $status_flags
1499 },
1500
1501 #
1502 # inport
1503 #
1504 Inport => {
1505         irn_flags => [ "rematerializable" ],
1506         state     => "pinned",
1507         reg_req   => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1508         ins       => [ "port", "mem" ],
1509         outs      => [ "res", "M" ],
1510         emit      => 'in%M %#D0, %^S0',
1511         units     => [ "GP" ],
1512         latency   => 1,
1513         mode      => mode_T,
1514         modified_flags => $status_flags
1515 },
1516
1517 #
1518 # Intel style prefetching
1519 #
1520 Prefetch0 => {
1521         op_flags  => [ "uses_memory" ],
1522         state     => "exc_pinned",
1523         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1524         ins       => [ "base", "index", "mem" ],
1525         outs      => [ "M" ],
1526         latency   => 0,
1527         emit      => "prefetcht0 %AM",
1528         units     => [ "GP" ],
1529 },
1530
1531 Prefetch1 => {
1532         op_flags  => [ "uses_memory" ],
1533         state     => "exc_pinned",
1534         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1535         ins       => [ "base", "index", "mem" ],
1536         outs      => [ "M" ],
1537         latency   => 0,
1538         emit      => "prefetcht1 %AM",
1539         units     => [ "GP" ],
1540 },
1541
1542 Prefetch2 => {
1543         op_flags  => [ "uses_memory" ],
1544         state     => "exc_pinned",
1545         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1546         ins       => [ "base", "index", "mem" ],
1547         outs      => [ "M" ],
1548         latency   => 0,
1549         emit      => "prefetcht2 %AM",
1550         units     => [ "GP" ],
1551 },
1552
1553 PrefetchNTA => {
1554         op_flags  => [ "uses_memory" ],
1555         state     => "exc_pinned",
1556         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1557         ins       => [ "base", "index", "mem" ],
1558         outs      => [ "M" ],
1559         latency   => 0,
1560         emit      => "prefetchnta %AM",
1561         units     => [ "GP" ],
1562 },
1563
1564 #
1565 # 3DNow! prefetch instructions
1566 #
1567 Prefetch => {
1568         op_flags  => [ "uses_memory" ],
1569         state     => "exc_pinned",
1570         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1571         ins       => [ "base", "index", "mem" ],
1572         outs      => [ "M" ],
1573         latency   => 0,
1574         emit      => "prefetch %AM",
1575         units     => [ "GP" ],
1576 },
1577
1578 PrefetchW => {
1579         op_flags  => [ "uses_memory" ],
1580         state     => "exc_pinned",
1581         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1582         ins       => [ "base", "index", "mem" ],
1583         outs      => [ "M" ],
1584         latency   => 0,
1585         emit      => "prefetchw %AM",
1586         units     => [ "GP" ],
1587 },
1588
1589 # produces a 0/+0.0
1590 xZero => {
1591         irn_flags => [ "rematerializable" ],
1592         reg_req   => { out => [ "xmm" ] },
1593         emit      => 'xorp%FX %D0, %D0',
1594         latency   => 3,
1595         units     => [ "SSE" ],
1596         mode      => $mode_xmm
1597 },
1598
1599 xUnknown => {
1600         op_flags  => [ "constlike" ],
1601         irn_flags => [ "rematerializable" ],
1602         reg_req   => { out => [ "xmm" ] },
1603         emit      => '',
1604         latency   => 0,
1605         mode      => $mode_xmm
1606 },
1607
1608 xPzero => {
1609         irn_flags => [ "rematerializable" ],
1610         reg_req   => { out => [ "xmm" ] },
1611         emit      => 'pxor %D0, %D0',
1612         latency   => 3,
1613         units     => [ "SSE" ],
1614         mode      => $mode_xmm
1615 },
1616
1617 # produces all 1 bits
1618 xAllOnes => {
1619         irn_flags => [ "rematerializable" ],
1620         reg_req   => { out => [ "xmm" ] },
1621         emit      => 'pcmpeqb %D0, %D0',
1622         latency   => 3,
1623         units     => [ "SSE" ],
1624         mode      => $mode_xmm
1625 },
1626
1627 # integer shift left, dword
1628 xPslld => {
1629         irn_flags => [ "rematerializable" ],
1630         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1631         emit      => 'pslld %#S1, %D0',
1632         latency   => 3,
1633         units     => [ "SSE" ],
1634         mode      => $mode_xmm
1635 },
1636
1637 # integer shift left, qword
1638 xPsllq => {
1639         irn_flags => [ "rematerializable" ],
1640         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1641         emit      => 'psllq %#S1, %D0',
1642         latency   => 3,
1643         units     => [ "SSE" ],
1644         mode      => $mode_xmm
1645 },
1646
1647 # integer shift right, dword
1648 xPsrld => {
1649         irn_flags => [ "rematerializable" ],
1650         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1651         emit      => 'psrld %#S1, %D0',
1652         latency   => 1,
1653         units     => [ "SSE" ],
1654         mode      => $mode_xmm
1655 },
1656
1657 # mov from integer to SSE register
1658 xMovd  => {
1659         irn_flags => [ "rematerializable" ],
1660         reg_req   => { in => [ "gp" ], out => [ "xmm" ] },
1661         emit      => 'movd %S0, %D0',
1662         latency   => 1,
1663         units     => [ "SSE" ],
1664         mode      => $mode_xmm
1665 },
1666
1667 xAdd => {
1668         irn_flags => [ "rematerializable" ],
1669         state     => "exc_pinned",
1670         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1671                        out => [ "in_r4 in_r5", "flags", "none" ] },
1672         ins       => [ "base", "index", "mem", "left", "right" ],
1673         outs      => [ "res", "flags", "M" ],
1674         am        => "source,binary",
1675         emit      => 'adds%FX %B',
1676         latency   => 4,
1677         units     => [ "SSE" ],
1678         mode      => $mode_xmm
1679 },
1680
1681 xMul => {
1682         irn_flags => [ "rematerializable" ],
1683         state     => "exc_pinned",
1684         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1685                        out => [ "in_r4 in_r5", "flags", "none" ] },
1686         ins       => [ "base", "index", "mem", "left", "right" ],
1687         outs      => [ "res", "flags", "M" ],
1688         am        => "source,binary",
1689         emit      => 'muls%FX %B',
1690         latency   => 4,
1691         units     => [ "SSE" ],
1692         mode      => $mode_xmm
1693 },
1694
1695 xMax => {
1696         irn_flags => [ "rematerializable" ],
1697         state     => "exc_pinned",
1698         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1699                        out => [ "in_r4 in_r5", "flags", "none" ] },
1700         ins       => [ "base", "index", "mem", "left", "right" ],
1701         outs      => [ "res", "flags", "M" ],
1702         am        => "source,binary",
1703         emit      => 'maxs%FX %B',
1704         latency   => 2,
1705         units     => [ "SSE" ],
1706         mode      => $mode_xmm
1707 },
1708
1709 xMin => {
1710         irn_flags => [ "rematerializable" ],
1711         state     => "exc_pinned",
1712         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1713                        out => [ "in_r4 in_r5", "flags", "none" ] },
1714         ins       => [ "base", "index", "mem", "left", "right" ],
1715         outs      => [ "res", "flags", "M" ],
1716         am        => "source,binary",
1717         emit      => 'mins%FX %B',
1718         latency   => 2,
1719         units     => [ "SSE" ],
1720         mode      => $mode_xmm
1721 },
1722
1723 xAnd => {
1724         irn_flags => [ "rematerializable" ],
1725         state     => "exc_pinned",
1726         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1727                        out => [ "in_r4 in_r5", "flags", "none" ] },
1728         ins       => [ "base", "index", "mem", "left", "right" ],
1729         outs      => [ "res", "flags", "M" ],
1730         am        => "source,binary",
1731         emit      => 'andp%FX %B',
1732         latency   => 3,
1733         units     => [ "SSE" ],
1734         mode      => $mode_xmm
1735 },
1736
1737 xOr => {
1738         irn_flags => [ "rematerializable" ],
1739         state     => "exc_pinned",
1740         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1741                        out => [ "in_r4 in_r5", "flags", "none" ] },
1742         ins       => [ "base", "index", "mem", "left", "right" ],
1743         outs      => [ "res", "flags", "M" ],
1744         am        => "source,binary",
1745         emit      => 'orp%FX %B',
1746         latency   => 3,
1747         units     => [ "SSE" ],
1748         mode      => $mode_xmm
1749 },
1750
1751 xXor => {
1752         irn_flags => [ "rematerializable" ],
1753         state     => "exc_pinned",
1754         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1755                        out => [ "in_r4 in_r5", "flags", "none" ] },
1756         ins       => [ "base", "index", "mem", "left", "right" ],
1757         outs      => [ "res", "flags", "M" ],
1758         am        => "source,binary",
1759         emit      => 'xorp%FX %B',
1760         latency   => 3,
1761         units     => [ "SSE" ],
1762         mode      => $mode_xmm
1763 },
1764
1765 xAndNot => {
1766         irn_flags => [ "rematerializable" ],
1767         state     => "exc_pinned",
1768         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1769                        out => [ "in_r4 !in_r5", "flags", "none" ] },
1770         ins       => [ "base", "index", "mem", "left", "right" ],
1771         outs      => [ "res", "flags", "M" ],
1772         am        => "source,binary",
1773         emit      => 'andnp%FX %B',
1774         latency   => 3,
1775         units     => [ "SSE" ],
1776         mode      => $mode_xmm
1777 },
1778
1779 xSub => {
1780         irn_flags => [ "rematerializable" ],
1781         state     => "exc_pinned",
1782         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1783                        out => [ "in_r4", "flags", "none" ] },
1784         ins       => [ "base", "index", "mem", "minuend", "subtrahend" ],
1785         outs      => [ "res", "flags", "M" ],
1786         am        => "source,binary",
1787         emit      => 'subs%FX %B',
1788         latency   => 4,
1789         units     => [ "SSE" ],
1790         mode      => $mode_xmm
1791 },
1792
1793 xDiv => {
1794         irn_flags => [ "rematerializable" ],
1795         state     => "exc_pinned",
1796         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1797                        out => [ "in_r4 !in_r5", "flags", "none" ] },
1798         ins       => [ "base", "index", "mem", "dividend", "divisor" ],
1799         outs      => [ "res", "flags", "M" ],
1800         am        => "source,binary",
1801         emit      => 'divs%FX %B',
1802         latency   => 16,
1803         units     => [ "SSE" ],
1804 },
1805
1806 Ucomi => {
1807         irn_flags => [ "rematerializable" ],
1808         state     => "exc_pinned",
1809         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ],
1810                        out => [ "eflags" ] },
1811         ins       => [ "base", "index", "mem", "left", "right" ],
1812         outs      => [ "flags" ],
1813         am        => "source,binary",
1814         attr      => "bool ins_permuted",
1815         init_attr => "attr->data.ins_permuted = ins_permuted;",
1816         emit      => 'ucomis%FX %B',
1817         latency   => 3,
1818         units     => [ "SSE" ],
1819         mode      => $mode_flags,
1820         modified_flags => 1,
1821 },
1822
1823 xLoad => {
1824         op_flags  => [ "uses_memory", "fragile" ],
1825         state     => "exc_pinned",
1826         reg_req   => { in => [ "gp", "gp", "none" ],
1827                        out => [ "xmm", "none", "none", "none", "none" ] },
1828         ins       => [ "base", "index", "mem" ],
1829         outs      => [ "res", "unused", "M", "X_regular", "X_except" ],
1830         emit      => 'movs%FX %AM, %D0',
1831         attr      => "ir_mode *load_mode",
1832         init_attr => "attr->ls_mode = load_mode;",
1833         latency   => 0,
1834         units     => [ "SSE" ],
1835 },
1836
1837 xStore => {
1838         op_flags => [ "uses_memory", "fragile" ],
1839         state    => "exc_pinned",
1840         reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
1841                       out => [ "none", "none", "none" ] },
1842         ins       => [ "base", "index", "mem", "val" ],
1843         outs      => [ "M", "X_regular", "X_except" ],
1844         emit     => 'movs%FX %S3, %AM',
1845         latency  => 0,
1846         units    => [ "SSE" ],
1847 },
1848
1849 xStoreSimple => {
1850         op_flags => [ "uses_memory", "fragile" ],
1851         state    => "exc_pinned",
1852         reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
1853                       out => [ "none", "none", "none" ] },
1854         ins      => [ "base", "index", "mem", "val" ],
1855         outs     => [ "M", "X_regular", "X_except" ],
1856         emit     => 'movs%FX %S3, %AM',
1857         latency  => 0,
1858         units    => [ "SSE" ],
1859 },
1860
1861 CvtSI2SS => {
1862         state     => "exc_pinned",
1863         reg_req  => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1864         ins      => [ "base", "index", "mem", "val" ],
1865         am       => "source,unary",
1866         emit     => 'cvtsi2ss %AS3, %D0',
1867         latency  => 2,
1868         units    => [ "SSE" ],
1869         mode     => $mode_xmm
1870 },
1871
1872 CvtSI2SD => {
1873         state     => "exc_pinned",
1874         reg_req  => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1875         ins      => [ "base", "index", "mem", "val" ],
1876         am       => "source,unary",
1877         emit     => 'cvtsi2sd %AS3, %D0',
1878         latency  => 2,
1879         units    => [ "SSE" ],
1880         mode     => $mode_xmm
1881 },
1882
1883
1884 l_LLtoFloat => {
1885         ins      => [ "val_high", "val_low" ],
1886         attr_type => "",
1887         dump_func => "NULL",
1888 },
1889
1890 l_FloattoLL => {
1891         ins      => [ "val" ],
1892         outs     => [ "res_high", "res_low" ],
1893         attr_type => "",
1894         dump_func => "NULL",
1895 },
1896
1897 CopyB => {
1898         op_flags  => [ "uses_memory", "fragile" ],
1899         state     => "pinned",
1900         reg_req   => { in => [ "edi", "esi", "ecx", "none" ],
1901                        out => [ "edi", "esi", "ecx", "none", "none", "none" ] },
1902         ins       => [ "dest", "source", "count", "mem" ],
1903         outs      => [ "dest", "source", "count", "M", "X_regular", "X_except" ],
1904         attr_type => "ia32_copyb_attr_t",
1905         attr      => "unsigned size",
1906         units     => [ "GP" ],
1907         latency   => 3,
1908 # we don't care about this flag, so no need to mark this node
1909 #       modified_flags => [ "DF" ]
1910 },
1911
1912 CopyB_i => {
1913         op_flags  => [ "uses_memory", "fragile" ],
1914         state     => "pinned",
1915         reg_req   => { in => [ "edi", "esi", "none" ],
1916                        out => [  "edi", "esi", "none", "none", "none" ] },
1917         ins       => [ "dest", "source", "mem" ],
1918         outs      => [ "dest", "source", "M", "X_regular", "X_except" ],
1919         attr_type => "ia32_copyb_attr_t",
1920         attr      => "unsigned size",
1921         units     => [ "GP" ],
1922         latency   => 3,
1923 # we don't care about this flag, so no need to mark this node
1924 #       modified_flags => [ "DF" ]
1925 },
1926
1927 Cwtl => {
1928         state     => "exc_pinned",
1929         reg_req   => { in => [ "eax" ], out => [ "eax" ] },
1930         ins       => [ "val" ],
1931         outs      => [ "res" ],
1932         emit      => 'cwtl',
1933         units     => [ "GP" ],
1934         latency   => 1,
1935         mode      => $mode_gp,
1936 },
1937
1938 Conv_I2I => {
1939         op_flags  => [ "uses_memory", "fragile" ],
1940         state     => "exc_pinned",
1941         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1942                        out => [ "gp", "none", "none", "none", "none" ] },
1943         ins       => [ "base", "index", "mem", "val" ],
1944         outs      => [ "res", "flags", "M", "X_regular", "X_except" ],
1945         emit      => "mov%#Ml %#AS3, %D0",
1946         am        => "source,unary",
1947         units     => [ "GP" ],
1948         latency   => 1,
1949         attr      => "ir_mode *smaller_mode",
1950         init_attr => "attr->ls_mode = smaller_mode;",
1951         mode      => $mode_gp,
1952 },
1953
1954 Conv_I2I8Bit => {
1955         op_flags  => [ "uses_memory", "fragile" ],
1956         state     => "exc_pinned",
1957         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ],
1958                        out => [ "gp", "none", "none", "none", "none" ] },
1959         ins       => [ "base", "index", "mem", "val" ],
1960         outs      => [ "res", "flags", "M", "X_regular", "X_except" ],
1961         emit      => "mov%#Ml %#AS3, %D0",
1962         am        => "source,unary",
1963         units     => [ "GP" ],
1964         latency   => 1,
1965         attr      => "ir_mode *smaller_mode",
1966         init_attr => "attr->ls_mode = smaller_mode;",
1967         mode      => $mode_gp,
1968 },
1969
1970 Conv_I2FP => {
1971         state     => "exc_pinned",
1972         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1973         ins       => [ "base", "index", "mem", "val" ],
1974         am        => "source,unary",
1975         latency   => 10,
1976         units     => [ "SSE" ],
1977         mode      => $mode_xmm,
1978 },
1979
1980 Conv_FP2I => {
1981         state     => "exc_pinned",
1982         reg_req   => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1983         ins       => [ "base", "index", "mem", "val" ],
1984         am        => "source,unary",
1985         latency   => 10,
1986         units     => [ "SSE" ],
1987         mode      => $mode_gp,
1988 },
1989
1990 Conv_FP2FP => {
1991         state     => "exc_pinned",
1992         reg_req   => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1993         ins       => [ "base", "index", "mem", "val" ],
1994         am        => "source,unary",
1995         latency   => 8,
1996         units     => [ "SSE" ],
1997         mode      => $mode_xmm,
1998 },
1999
2000 # rematerialisation disabled for all float nodes for now, because the fpcw
2001 # handler runs before spilling and we might end up with wrong fpcw then
2002
2003 vfadd => {
2004 #       irn_flags => [ "rematerializable" ],
2005         state     => "exc_pinned",
2006         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2007                        out => [ "vfp", "none", "none" ] },
2008         ins       => [ "base", "index", "mem", "left", "right", "fpcw" ],
2009         outs      => [ "res", "dummy", "M" ],
2010         am        => "source,binary",
2011         latency   => 4,
2012         units     => [ "VFP" ],
2013         mode      => $mode_fp87,
2014         attr_type => "ia32_x87_attr_t",
2015 },
2016
2017 vfmul => {
2018 #       irn_flags => [ "rematerializable" ],
2019         state     => "exc_pinned",
2020         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2021                        out => [ "vfp", "none", "none" ] },
2022         ins       => [ "base", "index", "mem", "left", "right", "fpcw" ],
2023         outs      => [ "res", "dummy", "M" ],
2024         am        => "source,binary",
2025         latency   => 4,
2026         units     => [ "VFP" ],
2027         mode      => $mode_fp87,
2028         attr_type => "ia32_x87_attr_t",
2029 },
2030
2031 vfsub => {
2032 #       irn_flags => [ "rematerializable" ],
2033         state     => "exc_pinned",
2034         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2035                        out => [ "vfp", "none", "none" ] },
2036         ins       => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
2037         outs      => [ "res", "dummy", "M" ],
2038         am        => "source,binary",
2039         latency   => 4,
2040         units     => [ "VFP" ],
2041         mode      => $mode_fp87,
2042         attr_type => "ia32_x87_attr_t",
2043 },
2044
2045 vfdiv => {
2046         state     => "exc_pinned",
2047         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ],
2048                        out => [ "vfp", "none", "none" ] },
2049         ins       => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
2050         outs      => [ "res", "dummy", "M" ],
2051         am        => "source,binary",
2052         latency   => 20,
2053         units     => [ "VFP" ],
2054         attr_type => "ia32_x87_attr_t",
2055 },
2056
2057 vfprem => {
2058         reg_req   => { in => [ "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
2059         ins       => [ "left", "right", "fpcw" ],
2060         latency   => 20,
2061         units     => [ "VFP" ],
2062         mode      => $mode_fp87,
2063         attr_type => "ia32_x87_attr_t",
2064 },
2065
2066 vfabs => {
2067         irn_flags => [ "rematerializable" ],
2068         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
2069         ins       => [ "value" ],
2070         latency   => 2,
2071         units     => [ "VFP" ],
2072         mode      => $mode_fp87,
2073         attr_type => "ia32_x87_attr_t",
2074 },
2075
2076 vfchs => {
2077         irn_flags => [ "rematerializable" ],
2078         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
2079         ins       => [ "value" ],
2080         latency   => 2,
2081         units     => [ "VFP" ],
2082         mode      => $mode_fp87,
2083         attr_type => "ia32_x87_attr_t",
2084 },
2085
2086 vfld => {
2087         irn_flags => [ "rematerializable" ],
2088         op_flags  => [ "uses_memory", "fragile" ],
2089         state     => "exc_pinned",
2090         reg_req   => { in => [ "gp", "gp", "none" ],
2091                        out => [ "vfp", "none", "none", "none", "none" ] },
2092         ins       => [ "base", "index", "mem" ],
2093         outs      => [ "res", "unused", "M", "X_regular", "X_except" ],
2094         attr      => "ir_mode *load_mode",
2095         init_attr => "attr->attr.ls_mode = load_mode;",
2096         latency   => 2,
2097         units     => [ "VFP" ],
2098         attr_type => "ia32_x87_attr_t",
2099 },
2100
2101 vfst => {
2102         irn_flags => [ "rematerializable" ],
2103         op_flags  => [ "uses_memory", "fragile" ],
2104         state     => "exc_pinned",
2105         reg_req   => { in => [ "gp", "gp", "none", "vfp" ],
2106                        out => [ "none", "none", "none" ] },
2107         ins       => [ "base", "index", "mem", "val" ],
2108         outs      => [ "M", "X_regular", "X_except" ],
2109         attr      => "ir_mode *store_mode",
2110         init_attr => "attr->attr.ls_mode = store_mode;",
2111         latency   => 2,
2112         units     => [ "VFP" ],
2113         attr_type => "ia32_x87_attr_t",
2114 },
2115
2116 vfild => {
2117         state     => "exc_pinned",
2118         reg_req   => { in => [ "gp", "gp", "none" ],
2119                        out => [ "vfp", "none", "none" ] },
2120         outs      => [ "res", "unused", "M" ],
2121         ins       => [ "base", "index", "mem" ],
2122         latency   => 4,
2123         units     => [ "VFP" ],
2124         attr_type => "ia32_x87_attr_t",
2125 },
2126
2127 vfist => {
2128         op_flags  => [ "uses_memory", "fragile" ],
2129         state     => "exc_pinned",
2130         reg_req   => { in => [ "gp", "gp", "none", "vfp", "fpcw" ],
2131                        out => [ "none", "none", "none", "none" ] },
2132         ins       => [ "base", "index", "mem", "val", "fpcw" ],
2133         outs      => [ "dummy", "M", "X_regular", "X_except" ],
2134         latency   => 4,
2135         units     => [ "VFP" ],
2136         attr_type => "ia32_x87_attr_t",
2137 },
2138
2139 # SSE3 fisttp instruction
2140 vfisttp => {
2141         op_flags  => [ "uses_memory", "fragile" ],
2142         state     => "exc_pinned",
2143         reg_req   => { in => [ "gp", "gp", "none", "vfp" ],
2144                        out => [ "in_r4", "none", "none", "none" ]},
2145         ins       => [ "base", "index", "mem", "val" ],
2146         outs      => [ "res", "M", "X_regular", "X_except" ],
2147         latency   => 4,
2148         units     => [ "VFP" ],
2149         attr_type => "ia32_x87_attr_t",
2150 },
2151
2152 vfldz => {
2153         irn_flags => [ "rematerializable" ],
2154         reg_req   => { out => [ "vfp" ] },
2155         outs      => [ "res" ],
2156         latency   => 4,
2157         units     => [ "VFP" ],
2158         mode      => $mode_fp87,
2159         attr_type => "ia32_x87_attr_t",
2160 },
2161
2162 vfld1 => {
2163         irn_flags => [ "rematerializable" ],
2164         reg_req   => { out => [ "vfp" ] },
2165         outs      => [ "res" ],
2166         latency   => 4,
2167         units     => [ "VFP" ],
2168         mode      => $mode_fp87,
2169         attr_type => "ia32_x87_attr_t",
2170 },
2171
2172 vfldpi => {
2173         irn_flags => [ "rematerializable" ],
2174         reg_req   => { out => [ "vfp" ] },
2175         outs      => [ "res" ],
2176         latency   => 4,
2177         units     => [ "VFP" ],
2178         mode      => $mode_fp87,
2179         attr_type => "ia32_x87_attr_t",
2180 },
2181
2182 vfldln2 => {
2183         irn_flags => [ "rematerializable" ],
2184         reg_req   => { out => [ "vfp" ] },
2185         outs      => [ "res" ],
2186         latency   => 4,
2187         units     => [ "VFP" ],
2188         mode      => $mode_fp87,
2189         attr_type => "ia32_x87_attr_t",
2190 },
2191
2192 vfldlg2 => {
2193         irn_flags => [ "rematerializable" ],
2194         reg_req   => { out => [ "vfp" ] },
2195         outs      => [ "res" ],
2196         latency   => 4,
2197         units     => [ "VFP" ],
2198         mode      => $mode_fp87,
2199         attr_type => "ia32_x87_attr_t",
2200 },
2201
2202 vfldl2t => {
2203         irn_flags => [ "rematerializable" ],
2204         reg_req   => { out => [ "vfp" ] },
2205         outs      => [ "res" ],
2206         latency   => 4,
2207         units     => [ "VFP" ],
2208         mode      => $mode_fp87,
2209         attr_type => "ia32_x87_attr_t",
2210 },
2211
2212 vfldl2e => {
2213         irn_flags => [ "rematerializable" ],
2214         reg_req   => { out => [ "vfp" ] },
2215         outs      => [ "res" ],
2216         latency   => 4,
2217         units     => [ "VFP" ],
2218         mode      => $mode_fp87,
2219         attr_type => "ia32_x87_attr_t",
2220 },
2221
2222 vFucomFnstsw => {
2223 # we can't allow to rematerialize this node so we don't
2224 #  accidently produce Phi(Fucom, Fucom(ins_permuted))
2225 #       irn_flags => [ "rematerializable" ],
2226         reg_req   => { in => [ "vfp", "vfp" ], out => [ "eax" ] },
2227         ins       => [ "left", "right" ],
2228         outs      => [ "flags" ],
2229         attr      => "bool ins_permuted",
2230         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2231         latency   => 3,
2232         units     => [ "VFP" ],
2233         attr_type => "ia32_x87_attr_t",
2234         mode      => $mode_gp
2235 },
2236
2237 vFucomi => {
2238         irn_flags => [ "rematerializable" ],
2239         reg_req   => { in => [ "vfp", "vfp" ], out => [ "eflags" ] },
2240         ins       => [ "left", "right" ],
2241         outs      => [ "flags" ],
2242         attr      => "bool ins_permuted",
2243         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2244         latency   => 3,
2245         units     => [ "VFP" ],
2246         attr_type => "ia32_x87_attr_t",
2247         mode      => $mode_gp
2248 },
2249
2250 vFtstFnstsw => {
2251 #       irn_flags => [ "rematerializable" ],
2252         reg_req   => { in => [ "vfp" ], out => [ "eax" ] },
2253         ins       => [ "left" ],
2254         outs      => [ "flags" ],
2255         attr      => "bool ins_permuted",
2256         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2257         latency   => 3,
2258         units     => [ "VFP" ],
2259         attr_type => "ia32_x87_attr_t",
2260         mode      => $mode_gp
2261 },
2262
2263 Sahf => {
2264         irn_flags => [ "rematerializable" ],
2265         reg_req   => { in => [ "eax" ], out => [ "eflags" ] },
2266         ins       => [ "val" ],
2267         outs      => [ "flags" ],
2268         emit      => 'sahf',
2269         latency   => 1,
2270         units     => [ "GP" ],
2271         mode      => $mode_flags,
2272 },
2273
2274 fadd => {
2275         state     => "exc_pinned",
2276         emit      => 'fadd%FP%FM %AF',
2277         latency   => 4,
2278         attr_type => "ia32_x87_attr_t",
2279         constructors => {},
2280 },
2281
2282 fmul => {
2283         state     => "exc_pinned",
2284         emit      => 'fmul%FP%FM %AF',
2285         latency   => 4,
2286         attr_type => "ia32_x87_attr_t",
2287         constructors => {},
2288 },
2289
2290 fsub => {
2291         state     => "exc_pinned",
2292         emit      => 'fsub%FR%FP%FM %AF',
2293         latency   => 4,
2294         attr_type => "ia32_x87_attr_t",
2295         constructors => {},
2296 },
2297
2298 fprem => {
2299         emit      => 'fprem1',
2300         latency   => 20,
2301         attr_type => "ia32_x87_attr_t",
2302         constructors => {},
2303 },
2304
2305 fdiv => {
2306         state     => "exc_pinned",
2307         emit      => 'fdiv%FR%FP%FM %AF',
2308         latency   => 20,
2309         attr_type => "ia32_x87_attr_t",
2310         constructors => {},
2311 },
2312
2313 fabs => {
2314         emit      => 'fabs',
2315         latency   => 4,
2316         attr_type => "ia32_x87_attr_t",
2317         constructors => {},
2318 },
2319
2320 fchs => {
2321         op_flags  => [ "keep" ],
2322         irn_flags => [ "rematerializable" ],
2323         emit      => 'fchs',
2324         latency   => 4,
2325         attr_type => "ia32_x87_attr_t",
2326         constructors => {},
2327 },
2328
2329 fld => {
2330         irn_flags => [ "rematerializable" ],
2331         state     => "exc_pinned",
2332         emit      => 'fld%FM %AM',
2333         attr_type => "ia32_x87_attr_t",
2334         latency   => 2,
2335         constructors => {},
2336 },
2337
2338 fst => {
2339         irn_flags => [ "rematerializable" ],
2340         state     => "exc_pinned",
2341         emit      => 'fst%FP%FM %AM',
2342         mode      => "mode_M",
2343         attr_type => "ia32_x87_attr_t",
2344         latency   => 2,
2345         constructors => {},
2346 },
2347
2348 fild => {
2349         state     => "exc_pinned",
2350         emit      => 'fild%FM %AM',
2351         attr_type => "ia32_x87_attr_t",
2352         latency   => 2,
2353         constructors => {},
2354 },
2355
2356 fist => {
2357         state     => "exc_pinned",
2358         emit      => 'fist%FP%FM %AM',
2359         mode      => "mode_M",
2360         attr_type => "ia32_x87_attr_t",
2361         latency   => 2,
2362         constructors => {},
2363 },
2364
2365 # SSE3 fisttp instruction
2366 fisttp => {
2367         state     => "exc_pinned",
2368         emit      => 'fisttp%FM %AM',
2369         mode      => "mode_M",
2370         attr_type => "ia32_x87_attr_t",
2371         latency   => 2,
2372         constructors => {},
2373 },
2374
2375 fldz => {
2376         op_flags  =>  [ "constlike", "keep" ],
2377         irn_flags => [ "rematerializable" ],
2378         reg_req   => { out => [ "vfp" ] },
2379         emit      => 'fldz',
2380         attr_type => "ia32_x87_attr_t",
2381         latency   => 2,
2382 },
2383
2384 fld1 => {
2385         op_flags  => [ "constlike", "keep" ],
2386         irn_flags => [ "rematerializable" ],
2387         reg_req   => { out => [ "vfp" ] },
2388         emit      => 'fld1',
2389         attr_type => "ia32_x87_attr_t",
2390         latency   => 2,
2391 },
2392
2393 fldpi => {
2394         op_flags  => [ "constlike", "keep" ],
2395         irn_flags => [ "rematerializable" ],
2396         reg_req   => { out => [ "vfp" ] },
2397         emit      => 'fldpi',
2398         attr_type => "ia32_x87_attr_t",
2399         latency   => 2,
2400 },
2401
2402 fldln2 => {
2403         op_flags  => [ "constlike", "keep" ],
2404         irn_flags => [ "rematerializable" ],
2405         reg_req   => { out => [ "vfp" ] },
2406         emit      => 'fldln2',
2407         attr_type => "ia32_x87_attr_t",
2408         latency   => 2,
2409 },
2410
2411 fldlg2 => {
2412         op_flags  => [ "constlike", "keep" ],
2413         irn_flags => [ "rematerializable" ],
2414         reg_req   => { out => [ "vfp" ] },
2415         emit      => 'fldlg2',
2416         attr_type => "ia32_x87_attr_t",
2417         latency   => 2,
2418 },
2419
2420 fldl2t => {
2421         op_flags  => [ "constlike", "keep" ],
2422         irn_flags => [ "rematerializable" ],
2423         reg_req   => { out => [ "vfp" ] },
2424         emit      => 'fldll2t',
2425         attr_type => "ia32_x87_attr_t",
2426         latency   => 2,
2427 },
2428
2429 fldl2e => {
2430         op_flags  => [ "constlike", "keep" ],
2431         irn_flags => [ "rematerializable" ],
2432         reg_req   => { out => [ "vfp" ] },
2433         emit      => 'fldl2e',
2434         attr_type => "ia32_x87_attr_t",
2435         latency   => 2,
2436 },
2437
2438 # fxch, fpush, fpop
2439 # Note that it is NEVER allowed to do CSE on these nodes
2440 # Moreover, note the virtual register requierements!
2441
2442 fxch => {
2443         op_flags  => [ "keep" ],
2444         reg_req   => { out => [ "none" ] },
2445         cmp_attr  => "return 1;",
2446         emit      => 'fxch %F0',
2447         attr_type => "ia32_x87_attr_t",
2448         mode      => "mode_ANY",
2449         latency   => 1,
2450 },
2451
2452 fpush => {
2453         op_flags  => [ "keep" ],
2454         reg_req   => { out => [ "none" ] },
2455         cmp_attr  => "return 1;",
2456         emit      => 'fld %F0',
2457         attr_type => "ia32_x87_attr_t",
2458         mode      => "mode_ANY",
2459         latency   => 1,
2460 },
2461
2462 fpushCopy => {
2463         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
2464         cmp_attr  => "return 1;",
2465         emit      => 'fld %F0',
2466         attr_type => "ia32_x87_attr_t",
2467         latency   => 1,
2468 },
2469
2470 fpop => {
2471         op_flags  => [ "keep" ],
2472         reg_req   => { out => [ "none" ] },
2473         cmp_attr  => "return 1;",
2474         emit      => 'fstp %F0',
2475         attr_type => "ia32_x87_attr_t",
2476         mode      => "mode_ANY",
2477         latency   => 1,
2478 },
2479
2480 ffreep => {
2481         op_flags  => [ "keep" ],
2482         reg_req   => { out => [ "none" ] },
2483         cmp_attr  => "return 1;",
2484         emit      => 'ffreep %F0',
2485         attr_type => "ia32_x87_attr_t",
2486         mode      => "mode_ANY",
2487         latency   => 1,
2488 },
2489
2490 emms => {
2491         op_flags  => [ "keep" ],
2492         reg_req   => { out => [ "none" ] },
2493         cmp_attr  => "return 1;",
2494         emit      => 'emms',
2495         attr_type => "ia32_x87_attr_t",
2496         mode      => "mode_ANY",
2497         latency   => 3,
2498 },
2499
2500 femms => {
2501         op_flags  => [ "keep" ],
2502         reg_req   => { out => [ "none" ] },
2503         cmp_attr  => "return 1;",
2504         emit      => 'femms',
2505         attr_type => "ia32_x87_attr_t",
2506         mode      => "mode_ANY",
2507         latency   => 3,
2508 },
2509
2510 FucomFnstsw => {
2511         reg_req   => { },
2512         emit      => "fucom%FP %F0\n".
2513                      "fnstsw %%ax",
2514         attr_type => "ia32_x87_attr_t",
2515         latency   => 2,
2516 },
2517
2518 FucomppFnstsw => {
2519         reg_req   => { },
2520         emit      => "fucompp\n".
2521                      "fnstsw %%ax",
2522         attr_type => "ia32_x87_attr_t",
2523         latency   => 2,
2524 },
2525
2526 Fucomi => {
2527         reg_req   => { },
2528         emit      => 'fucom%FPi %F0',
2529         attr_type => "ia32_x87_attr_t",
2530         latency   => 1,
2531 },
2532
2533 FtstFnstsw => {
2534         reg_req   => { },
2535         emit      => "ftst\n".
2536                      "fnstsw %%ax",
2537         attr_type => "ia32_x87_attr_t",
2538         latency   => 2,
2539 },
2540
2541 # Spilling and reloading of SSE registers, hardcoded, not generated #
2542
2543 xxLoad => {
2544         op_flags  => [ "uses_memory", "fragile" ],
2545         state     => "exc_pinned",
2546         reg_req   => { in => [ "gp", "gp", "none" ],
2547                        out => [ "xmm", "none", "none", "none" ] },
2548         emit      => 'movdqu %D0, %AM',
2549         ins       => [ "base", "index", "mem" ],
2550         outs      => [ "res", "M", "X_regular", "X_except" ],
2551         units     => [ "SSE" ],
2552         latency   => 1,
2553 },
2554
2555 xxStore => {
2556         op_flags => [ "uses_memory", "fragile" ],
2557         state    => "exc_pinned",
2558         reg_req  => { in => [ "gp", "gp", "none", "xmm" ],
2559                       out => [ "none", "none", "none" ] },
2560         ins      => [ "base", "index", "mem", "val" ],
2561         outs     => [ "M", "X_regular", "X_except" ],
2562         emit     => 'movdqu %B',
2563         units    => [ "SSE" ],
2564         latency  => 1,
2565 },
2566
2567 ); # end of %nodes
2568
2569 # Transform some attributes
2570 foreach my $op (keys(%nodes)) {
2571         my $node         = $nodes{$op};
2572         my $op_attr_init = $node->{op_attr_init};
2573
2574         if(defined($op_attr_init)) {
2575                 $op_attr_init .= "\n\t";
2576         } else {
2577                 $op_attr_init = "";
2578         }
2579
2580         if(!defined($node->{latency})) {
2581                 if($op =~ m/^l_/) {
2582                         $node->{latency} = 0;
2583                 } else {
2584                         die("Latency missing for op $op");
2585                 }
2586         }
2587         $op_attr_init .= "ia32_init_op(op, ".$node->{latency} . ");";
2588
2589         $node->{op_attr_init} = $op_attr_init;
2590 }
2591
2592 print "";