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