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