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