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