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