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