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