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