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