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