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