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