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