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