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