Renamed ia32 Push0 to PushEax (because this is the generated instruction).
[libfirm] / ir / be / ia32 / ia32_spec.pl
1 # Creation: 2005/10/19
2 # $Id$
3 # This is the specification for the ia32 assembler Firm-operations
4
5 use File::Basename;
6
7 my $myname = $0;
8
9 # the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
10 $arch = "ia32";
11
12 # The node description is done as a perl hash initializer with the
13 # following structure:
14 #
15 # %nodes = (
16 #
17 # <op-name> => {
18 #   op_flags  => "N|L|C|X|I|F|Y|H|c|K|n",
19 #   irn_flags => "R|N"
20 #   arity     => "0|1|2|3 ... |variable|dynamic|any",
21 #   state     => "floats|pinned|mem_pinned|exc_pinned",
22 #   args      => [
23 #                    { type => "type 1", name => "name 1" },
24 #                    { type => "type 2", name => "name 2" },
25 #                    ...
26 #                  ],
27 #   comment   => "any comment for constructor",
28 #   reg_req   => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] },
29 #   cmp_attr  => "c source code for comparing node attributes",
30 #   outs      => { "out1", "out2" } # optional, creates pn_op_out1, ... consts
31 #   ins       => { "in1", "in2" }   # optional, creates n_op_in1, ... consts
32 #   mode      => "mode_Iu"          # optional, predefines the mode
33 #   emit      => "emit code with templates",
34 #   attr      => "additional attribute arguments for constructor",
35 #   init_attr => "emit attribute initialization template",
36 #   hash_func => "name of the hash function for this operation",
37 #   latency   => "latency of this operation (can be float)"
38 #   attr_type => "name of the attribute struct",
39 #   modified_flags =>  [ "CF", ... ] # optional, list of modified flags
40 # },
41 #
42 # ... # (all nodes you need to describe)
43 #
44 # ); # close the %nodes initializer
45
46 # op_flags: flags for the operation, OPTIONAL (default is "N")
47 # the op_flags correspond to the firm irop_flags:
48 #   N   irop_flag_none
49 #   L   irop_flag_labeled
50 #   C   irop_flag_commutative
51 #   X   irop_flag_cfopcode
52 #   I   irop_flag_ip_cfopcode
53 #   F   irop_flag_fragile
54 #   Y   irop_flag_forking
55 #   H   irop_flag_highlevel
56 #   c   irop_flag_constlike
57 #   K   irop_flag_keep
58 #   NB  irop_flag_dump_noblock
59 #   NI  irop_flag_dump_noinput
60 #
61 # irn_flags: special node flags, OPTIONAL (default is 0)
62 # following irn_flags are supported:
63 #   R   rematerializeable
64 #   N   not spillable
65 #
66 # state: state of the operation, OPTIONAL (default is "floats")
67 #
68 # arity: arity of the operation, MUST NOT BE OMITTED
69 #
70 # args:  the OPTIONAL arguments of the node constructor (debug, irg and block
71 #        are always the first 3 arguments and are always autmatically
72 #        created)
73 #        If this key is missing the following arguments will be created:
74 #        for i = 1 .. arity: ir_node *op_i
75 #        ir_mode *mode
76 #
77 # outs:  if a node defines more than one output, the names of the projections
78 #        nodes having outs having automatically the mode mode_T
79 #        example: [ "frame", "stack", "M" ]
80 #
81 # comment: OPTIONAL comment for the node constructor
82 #
83 # rd_constructor: for every operation there will be a
84 #      new_rd_<arch>_<op-name> function with the arguments from above
85 #      which creates the ir_node corresponding to the defined operation
86 #      you can either put the complete source code of this function here
87 #
88 #      This key is OPTIONAL. If omitted, the following constructor will
89 #      be created:
90 #      if (!op_<arch>_<op-name>) assert(0);
91 #      for i = 1 to arity
92 #         set in[i] = op_i
93 #      done
94 #      res = new_ir_node(db, irg, block, op_<arch>_<op-name>, mode, arity, in)
95 #      return res
96 #
97 # NOTE: rd_constructor and args are only optional if and only if arity is 0,1,2 or 3
98 #
99
100 # register types:
101 #   0 - no special type
102 #   1 - caller save (register must be saved by the caller of a function)
103 #   2 - callee save (register must be saved by the called function)
104 #   4 - ignore (do not automatically assign this register)
105 #   8 - emitter can choose an arbitrary register of this class
106 #  16 - the register is a virtual one
107 #  32 - register represents a state
108 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
109 %reg_classes = (
110         gp => [
111                 { name => "edx", type => 1 },
112                 { name => "ecx", type => 1 },
113                 { name => "eax", type => 1 },
114                 { name => "ebx", type => 2 },
115                 { name => "esi", type => 2 },
116                 { name => "edi", type => 2 },
117                 { name => "ebp", type => 2 },
118                 { name => "esp", type => 4 },
119                 { name => "gp_NOREG", type => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes
120                 { mode => "mode_Iu" }
121         ],
122         mmx => [
123                 { name => "mm0", type => 4 },
124                 { name => "mm1", type => 4 },
125                 { name => "mm2", type => 4 },
126                 { name => "mm3", type => 4 },
127                 { name => "mm4", type => 4 },
128                 { name => "mm5", type => 4 },
129                 { name => "mm6", type => 4 },
130                 { name => "mm7", type => 4 },
131                 { mode => "mode_E", flags => "manual_ra" }
132         ],
133         xmm => [
134                 { name => "xmm0", type => 1 },
135                 { name => "xmm1", type => 1 },
136                 { name => "xmm2", type => 1 },
137                 { name => "xmm3", type => 1 },
138                 { name => "xmm4", type => 1 },
139                 { name => "xmm5", type => 1 },
140                 { name => "xmm6", type => 1 },
141                 { name => "xmm7", type => 1 },
142                 { name => "xmm_NOREG", type => 4 | 16 },     # we need a dummy register for NoReg nodes
143                 { mode => "mode_E" }
144         ],
145         vfp => [
146                 { name => "vf0", type => 1 },
147                 { name => "vf1", type => 1 },
148                 { name => "vf2", type => 1 },
149                 { name => "vf3", type => 1 },
150                 { name => "vf4", type => 1 },
151                 { name => "vf5", type => 1 },
152                 { name => "vf6", type => 1 },
153                 { name => "vf7", type => 1 },
154                 { name => "vfp_NOREG", type => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes
155                 { mode => "mode_E" }
156         ],
157         st => [
158                 { name => "st0", realname => "st",    type => 4 },
159                 { name => "st1", realname => "st(1)", type => 4 },
160                 { name => "st2", realname => "st(2)", type => 4 },
161                 { name => "st3", realname => "st(3)", type => 4 },
162                 { name => "st4", realname => "st(4)", type => 4 },
163                 { name => "st5", realname => "st(5)", type => 4 },
164                 { name => "st6", realname => "st(6)", type => 4 },
165                 { name => "st7", realname => "st(7)", type => 4 },
166                 { mode => "mode_E", flags => "manual_ra" }
167         ],
168         fp_cw => [      # the floating point control word
169                 { name => "fpcw", type => 4|32 },
170                 { mode => "mode_fpcw", flags => "manual_ra|state" }
171         ],
172         flags => [
173                 { name => "eflags", type => 0 },
174                 { mode => "mode_Iu", flags => "manual_ra" }
175         ],
176 ); # %reg_classes
177
178 %cpu = (
179         GP     => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
180         SSE    => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
181         VFP    => [ 1, "VFP_VF0", "VFP_VF1", "VFP_VF2", "VFP_VF3", "VFP_VF4", "VFP_VF5", "VFP_VF6", "VFP_VF7" ],
182         BRANCH => [ 1, "BRANCH1", "BRANCH2" ],
183 ); # %cpu
184
185 %vliw = (
186         bundle_size       => 1,
187         bundels_per_cycle => 1
188 ); # vliw
189
190 %emit_templates = (
191         S0 => "${arch}_emit_source_register(node, 0);",
192         S1 => "${arch}_emit_source_register(node, 1);",
193         S2 => "${arch}_emit_source_register(node, 2);",
194         S3 => "${arch}_emit_source_register(node, 3);",
195         SB0 => "${arch}_emit_8bit_source_register_or_immediate(node, 0);",
196         SB1 => "${arch}_emit_8bit_source_register_or_immediate(node, 1);",
197         SB2 => "${arch}_emit_8bit_source_register_or_immediate(node, 2);",
198         SB3 => "${arch}_emit_8bit_source_register_or_immediate(node, 3);",
199         SH0 => "${arch}_emit_8bit_high_source_register(node, 0);",
200         SS0 => "${arch}_emit_16bit_source_register_or_immediate(node, 0);",
201         SI0 => "${arch}_emit_source_register_or_immediate(node, 0);",
202         SI1 => "${arch}_emit_source_register_or_immediate(node, 1);",
203         SI3 => "${arch}_emit_source_register_or_immediate(node, 3);",
204         D0 => "${arch}_emit_dest_register(node, 0);",
205         D1 => "${arch}_emit_dest_register(node, 1);",
206         DS0 => "${arch}_emit_dest_register_size(node, 0);",
207         DB0 => "${arch}_emit_8bit_dest_register(node, 0);",
208         X0 => "${arch}_emit_x87_register(node, 0);",
209         X1 => "${arch}_emit_x87_register(node, 1);",
210         EX => "${arch}_emit_extend_suffix(node);",
211         M  => "${arch}_emit_mode_suffix(node);",
212         XM => "${arch}_emit_x87_mode_suffix(node);",
213         XXM => "${arch}_emit_xmm_mode_suffix(node);",
214         XSD => "${arch}_emit_xmm_mode_suffix_s(node);",
215         AM => "${arch}_emit_am(node);",
216         unop3 => "${arch}_emit_unop(node, n_ia32_unary_op);",
217         unop4 => "${arch}_emit_unop(node, n_ia32_binary_right);",
218         binop => "${arch}_emit_binop(node);",
219         x87_binop => "${arch}_emit_x87_binop(node);",
220         CMP3  => "${arch}_emit_cmp_suffix_node(node, 3);",
221 );
222
223
224
225
226 $default_op_attr_type = "ia32_op_attr_t";
227 $default_attr_type    = "ia32_attr_t";
228 $default_copy_attr    = "ia32_copy_attr";
229
230 sub ia32_custom_init_attr {
231         my $constr = shift;
232         my $node   = shift;
233         my $name   = shift;
234         my $res    = "";
235
236         if(defined($node->{modified_flags})) {
237                 $res .= "\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n";
238         }
239         if(defined($node->{am})) {
240                 my $am = $node->{am};
241                 if($am eq "source,unary") {
242                         $res .= "\tset_ia32_am_support(res, ia32_am_unary);";
243                 } elsif($am eq "source,binary") {
244                         $res .= "\tset_ia32_am_support(res, ia32_am_binary);";
245                 } elsif($am eq "none") {
246                         # nothing to do
247                 } else {
248                         die("Invalid address mode '$am' specified on op $name");
249                 }
250                 if($am ne "none") {
251                         if($node->{state} ne "exc_pinned"
252                                         and $node->{state} ne "pinned") {
253                                 die("AM nodes must have pinned or AM pinned state ($name)");
254                         }
255                 }
256         }
257         return $res;
258 }
259 $custom_init_attr_func = \&ia32_custom_init_attr;
260
261 %init_attr = (
262         ia32_asm_attr_t =>
263                 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
264                 "\tinit_ia32_x87_attributes(res);".
265                 "\tinit_ia32_asm_attributes(res);",
266         ia32_attr_t     =>
267                 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);",
268         ia32_call_attr_t =>
269                 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
270                 "\tinit_ia32_call_attributes(res, pop, call_tp);",
271         ia32_condcode_attr_t =>
272                 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
273                 "\tinit_ia32_condcode_attributes(res, pnc);",
274         ia32_copyb_attr_t =>
275                 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
276                 "\tinit_ia32_copyb_attributes(res, size);",
277         ia32_immediate_attr_t =>
278                 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
279                 "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, no_pic_adjust, offset);",
280         ia32_x87_attr_t =>
281                 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
282                 "\tinit_ia32_x87_attributes(res);",
283         ia32_climbframe_attr_t =>
284                 "\tinit_ia32_attributes(res, flags, in_reqs, exec_units, n_res);\n".
285                 "\tinit_ia32_climbframe_attributes(res, count);",
286 );
287
288 %compare_attr = (
289         ia32_asm_attr_t       => "ia32_compare_asm_attr",
290         ia32_attr_t            => "ia32_compare_nodes_attr",
291         ia32_call_attr_t       => "ia32_compare_call_attr",
292         ia32_condcode_attr_t   => "ia32_compare_condcode_attr",
293         ia32_copyb_attr_t      => "ia32_compare_copyb_attr",
294         ia32_immediate_attr_t  => "ia32_compare_immediate_attr",
295         ia32_x87_attr_t        => "ia32_compare_x87_attr",
296         ia32_climbframe_attr_t => "ia32_compare_climbframe_attr",
297 );
298
299 %operands = (
300 );
301
302 $mode_xmm           = "mode_E";
303 $mode_gp            = "mode_Iu";
304 $mode_flags         = "mode_Iu";
305 $mode_fpcw          = "mode_fpcw";
306 $status_flags       = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
307 $status_flags_wo_cf = [       "PF", "AF", "ZF", "SF", "OF" ];
308 $fpcw_flags         = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
309                         "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
310
311 %nodes = (
312
313 Immediate => {
314         state     => "pinned",
315         op_flags  => "c",
316         reg_req   => { out => [ "gp_NOREG:I" ] },
317         attr      => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
318         attr_type => "ia32_immediate_attr_t",
319         hash_func => "ia32_hash_Immediate",
320         latency   => 0,
321         mode      => $mode_gp,
322 },
323
324 Asm => {
325         mode      => "mode_T",
326         arity     => "variable",
327         out_arity => "variable",
328         attr_type => "ia32_asm_attr_t",
329         attr      => "ident *asm_text, const ia32_asm_reg_t *register_map",
330         init_attr => "attr->asm_text = asm_text;\n".
331                      "\tattr->register_map = register_map;\n",
332         latency   => 10,
333         modified_flags => $status_flags,
334 },
335
336 # "allocates" a free register
337 ProduceVal => {
338         op_flags  => "c|n",
339         irn_flags => "R",
340         reg_req   => { out => [ "gp" ] },
341         emit      => "",
342         units     => [ ],
343         latency   => 0,
344         mode      => $mode_gp,
345         cmp_attr  => "return 1;",
346 },
347
348 Add => {
349         irn_flags => "R",
350         state     => "exc_pinned",
351         reg_req   => { in  => [ "gp", "gp", "none", "gp", "gp" ],
352                        out => [ "in_r4 in_r5", "flags", "none" ] },
353         ins       => [ "base", "index", "mem", "left", "right" ],
354         outs      => [ "res", "flags", "M" ],
355         emit      => '. add%M %binop',
356         am        => "source,binary",
357         units     => [ "GP" ],
358         latency   => 1,
359         mode      => $mode_gp,
360         modified_flags => $status_flags
361 },
362
363 AddMem => {
364         irn_flags => "R",
365         state     => "exc_pinned",
366         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
367         ins       => [ "base", "index", "mem", "val" ],
368         emit      => ". add%M %SI3, %AM",
369         units     => [ "GP" ],
370         latency   => 1,
371         mode      => "mode_M",
372         modified_flags => $status_flags
373 },
374
375 AddMem8Bit => {
376         irn_flags => "R",
377         state     => "exc_pinned",
378         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
379         ins       => [ "base", "index", "mem", "val" ],
380         emit      => ". add%M %SB3, %AM",
381         units     => [ "GP" ],
382         latency   => 1,
383         mode      => "mode_M",
384         modified_flags => $status_flags
385 },
386
387 Adc => {
388         state     => "exc_pinned",
389         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
390                        out => [ "in_r4 in_r5", "flags", "none" ] },
391         ins       => [ "base", "index", "mem", "left", "right", "eflags" ],
392         outs      => [ "res", "flags", "M" ],
393         emit      => '. adc%M %binop',
394         am        => "source,binary",
395         units     => [ "GP" ],
396         latency   => 1,
397         mode      => $mode_gp,
398         modified_flags => $status_flags
399 },
400
401 l_Add => {
402         op_flags  => "C",
403         reg_req   => { in => [ "none", "none" ], out => [ "none" ] },
404         ins       => [ "left", "right" ],
405 },
406
407 l_Adc => {
408         reg_req   => { in => [ "none", "none", "none" ], out => [ "none" ] },
409         ins       => [ "left", "right", "eflags" ],
410 },
411
412 Mul => {
413         # we should not rematrialize this node. It produces 2 results and has
414         # very strict constraints
415         state     => "exc_pinned",
416         reg_req   => { in => [ "gp", "gp", "none", "eax", "gp" ],
417                        out => [ "eax", "flags", "none", "edx" ] },
418         ins       => [ "base", "index", "mem", "left", "right" ],
419         emit      => '. mul%M %unop4',
420         outs      => [ "res_low", "flags", "M", "res_high" ],
421         am        => "source,binary",
422         latency   => 10,
423         units     => [ "GP" ],
424         modified_flags => $status_flags
425 },
426
427 l_Mul => {
428         # we should not rematrialize this node. It produces 2 results and has
429         # very strict constraints
430         op_flags  => "C",
431         cmp_attr  => "return 1;",
432         reg_req   => { in => [ "none", "none" ],
433                        out => [ "none", "none", "none", "none" ] },
434         ins       => [ "left", "right" ],
435         outs      => [ "res_low", "flags", "M", "res_high" ],
436 },
437
438 IMul => {
439         irn_flags => "R",
440         state     => "exc_pinned",
441         # TODO: adjust out requirements for the 3 operand form
442         # (no need for should_be_same then)
443         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
444                            out => [ "in_r4 in_r5", "flags", "none" ] },
445         ins       => [ "base", "index", "mem", "left", "right" ],
446         outs      => [ "res", "flags", "M" ],
447         am        => "source,binary",
448         latency   => 5,
449         units     => [ "GP" ],
450         mode      => $mode_gp,
451         modified_flags => $status_flags
452 },
453
454 IMul1OP => {
455         irn_flags => "R",
456         state     => "exc_pinned",
457         reg_req   => { in => [ "gp", "gp", "none", "eax", "gp" ],
458                        out => [ "eax", "flags", "none", "edx" ] },
459         ins       => [ "base", "index", "mem", "left", "right" ],
460         emit      => '. imul%M %unop4',
461         outs      => [ "res_low", "flags", "M", "res_high" ],
462         am        => "source,binary",
463         latency   => 5,
464         units     => [ "GP" ],
465         modified_flags => $status_flags
466 },
467
468 l_IMul => {
469         op_flags  => "C",
470         cmp_attr  => "return 1;",
471         reg_req   => { in => [ "none", "none" ],
472                        out => [ "none", "none", "none", "none" ] },
473         ins       => [ "left", "right" ],
474         outs      => [ "res_low", "flags", "M", "res_high" ],
475 },
476
477 And => {
478         irn_flags => "R",
479         state     => "exc_pinned",
480         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
481                            out => [ "in_r4 in_r5", "flags", "none" ] },
482         ins       => [ "base", "index", "mem", "left", "right" ],
483         outs      => [ "res", "flags", "M" ],
484         am        => "source,binary",
485         emit      => '. and%M %binop',
486         units     => [ "GP" ],
487         latency   => 1,
488         mode      => $mode_gp,
489         modified_flags => $status_flags
490 },
491
492 AndMem => {
493         irn_flags => "R",
494         state     => "exc_pinned",
495         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
496         ins       => [ "base", "index", "mem", "val" ],
497         emit      => '. and%M %SI3, %AM',
498         units     => [ "GP" ],
499         latency   => 1,
500         mode      => "mode_M",
501         modified_flags => $status_flags
502 },
503
504 AndMem8Bit => {
505         irn_flags => "R",
506         state     => "exc_pinned",
507         reg_req   => { in => [ "gp", "gp", "none",  "eax ebx ecx edx" ], out => [ "none" ] },
508         ins       => [ "base", "index", "mem", "val" ],
509         emit      => '. and%M %SB3, %AM',
510         units     => [ "GP" ],
511         latency   => 1,
512         mode      => "mode_M",
513         modified_flags => $status_flags
514 },
515
516 Or => {
517         irn_flags => "R",
518         state     => "exc_pinned",
519         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
520                        out => [ "in_r4 in_r5", "flags", "none" ] },
521         ins       => [ "base", "index", "mem", "left", "right" ],
522         outs      => [ "res", "flags", "M" ],
523         am        => "source,binary",
524         emit      => '. or%M %binop',
525         units     => [ "GP" ],
526         latency   => 1,
527         mode      => $mode_gp,
528         modified_flags => $status_flags
529 },
530
531 OrMem => {
532         irn_flags => "R",
533         state     => "exc_pinned",
534         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
535         ins       => [ "base", "index", "mem", "val" ],
536         emit      => '. or%M %SI3, %AM',
537         units     => [ "GP" ],
538         latency   => 1,
539         mode      => "mode_M",
540         modified_flags => $status_flags
541 },
542
543 OrMem8Bit => {
544         irn_flags => "R",
545         state     => "exc_pinned",
546         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
547         ins       => [ "base", "index", "mem", "val" ],
548         emit      => '. or%M %SB3, %AM',
549         units     => [ "GP" ],
550         latency   => 1,
551         mode      => "mode_M",
552         modified_flags => $status_flags
553 },
554
555 Xor => {
556         irn_flags => "R",
557         state     => "exc_pinned",
558         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
559                        out => [ "in_r4 in_r5", "flags", "none" ] },
560         ins       => [ "base", "index", "mem", "left", "right" ],
561         outs      => [ "res", "flags", "M" ],
562         am        => "source,binary",
563         emit      => '. xor%M %binop',
564         units     => [ "GP" ],
565         latency   => 1,
566         mode      => $mode_gp,
567         modified_flags => $status_flags
568 },
569
570 Xor0 => {
571         op_flags  => "c",
572         irn_flags => "R",
573         reg_req   => { out => [ "gp", "flags" ] },
574         outs      => [ "res", "flags" ],
575         emit      => ". xor%M %D0, %D0",
576         units     => [ "GP" ],
577         latency   => 1,
578         mode      => $mode_gp,
579         modified_flags => $status_flags
580 },
581
582 XorMem => {
583         irn_flags => "R",
584         state     => "exc_pinned",
585         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
586         ins       => [ "base", "index", "mem", "val" ],
587         emit      => '. xor%M %SI3, %AM',
588         units     => [ "GP" ],
589         latency   => 1,
590         mode      => "mode_M",
591         modified_flags => $status_flags
592 },
593
594 XorMem8Bit => {
595         irn_flags => "R",
596         state     => "exc_pinned",
597         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
598         ins       => [ "base", "index", "mem", "val" ],
599         emit      => '. xor%M %SB3, %AM',
600         units     => [ "GP" ],
601         latency   => 1,
602         mode      => "mode_M",
603         modified_flags => $status_flags
604 },
605
606 Sub => {
607         irn_flags => "R",
608         state     => "exc_pinned",
609         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ],
610                        out => [ "in_r4", "flags", "none" ] },
611         ins       => [ "base", "index", "mem", "minuend", "subtrahend" ],
612         outs      => [ "res", "flags", "M" ],
613         am        => "source,binary",
614         emit      => '. sub%M %binop',
615         units     => [ "GP" ],
616         latency   => 1,
617         mode      => $mode_gp,
618         modified_flags => $status_flags
619 },
620
621 SubMem => {
622         irn_flags => "R",
623         state     => "exc_pinned",
624         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
625         ins       => [ "base", "index", "mem", "subtrahend" ],
626         emit      => '. sub%M %SI3, %AM',
627         units     => [ "GP" ],
628         latency   => 1,
629         mode      => 'mode_M',
630         modified_flags => $status_flags
631 },
632
633 SubMem8Bit => {
634         irn_flags => "R",
635         state     => "exc_pinned",
636         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
637         ins       => [ "base", "index", "mem", "subtrahend" ],
638         emit      => '. sub%M %SB3, %AM',
639         units     => [ "GP" ],
640         latency   => 1,
641         mode      => 'mode_M',
642         modified_flags => $status_flags
643 },
644
645 Sbb => {
646         state     => "exc_pinned",
647         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
648                        out => [ "in_r4 !in_r5", "flags", "none" ] },
649         ins       => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
650         outs      => [ "res", "flags", "M" ],
651         am        => "source,binary",
652         emit      => '. sbb%M %binop',
653         units     => [ "GP" ],
654         latency   => 1,
655         mode      => $mode_gp,
656         modified_flags => $status_flags
657 },
658
659 Sbb0 => {
660         # Spiller currently fails when rematerializing flag consumers
661         # irn_flags => "R",
662         reg_req   => { in => [ "flags" ], out => [ "gp", "flags" ] },
663         outs      => [ "res", "flags" ],
664         emit      => ". sbb%M %D0, %D0",
665         units     => [ "GP" ],
666         latency   => 1,
667         mode      => $mode_gp,
668         modified_flags => $status_flags
669 },
670
671 l_Sub => {
672         reg_req   => { in => [ "none", "none" ], out => [ "none" ] },
673         ins       => [ "minuend", "subtrahend" ],
674 },
675
676 l_Sbb => {
677         reg_req   => { in => [ "none", "none", "none" ], out => [ "none" ] },
678         ins       => [ "minuend", "subtrahend", "eflags" ],
679 },
680
681 IDiv => {
682         op_flags  => "F|L",
683         state     => "exc_pinned",
684         reg_req   => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
685                        out => [ "eax", "flags", "none", "edx", "none" ] },
686         ins       => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
687         outs      => [ "div_res", "flags", "M", "mod_res", "X_exc" ],
688         am        => "source,unary",
689         emit      => ". idiv%M %unop3",
690         latency   => 25,
691         units     => [ "GP" ],
692         modified_flags => $status_flags
693 },
694
695 Div => {
696         op_flags  => "F|L",
697         state     => "exc_pinned",
698         reg_req   => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
699                        out => [ "eax", "flags", "none", "edx", "none" ] },
700         ins       => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
701         outs      => [ "div_res", "flags", "M", "mod_res", "X_exc" ],
702         am        => "source,unary",
703         emit      => ". div%M %unop3",
704         latency   => 25,
705         units     => [ "GP" ],
706         modified_flags => $status_flags
707 },
708
709 Shl => {
710         irn_flags => "R",
711         reg_req   => { in => [ "gp", "ecx" ],
712                        out => [ "in_r1 !in_r2", "flags" ] },
713         ins       => [ "val", "count" ],
714         outs      => [ "res", "flags" ],
715         emit      => '. shl%M %SB1, %S0',
716         units     => [ "GP" ],
717         latency   => 1,
718         mode      => $mode_gp,
719         modified_flags => $status_flags
720 },
721
722 ShlMem => {
723         irn_flags => "R",
724         state     => "exc_pinned",
725         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
726         ins       => [ "base", "index", "mem", "count" ],
727         emit      => '. shl%M %SB3, %AM',
728         units     => [ "GP" ],
729         latency   => 1,
730         mode      => "mode_M",
731         modified_flags => $status_flags
732 },
733
734 l_ShlDep => {
735         cmp_attr => "return 1;",
736         reg_req  => { in => [ "none", "none", "none" ], out => [ "none" ] },
737         ins      => [ "val", "count", "dep" ],
738 },
739
740 ShlD => {
741         irn_flags => "R",
742         reg_req   => { in => [ "gp", "gp", "ecx" ],
743                        out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
744         ins       => [ "val_high", "val_low", "count" ],
745         outs      => [ "res", "flags" ],
746         emit      => ". shld%M %SB2, %S1, %D0",
747         latency   => 6,
748         units     => [ "GP" ],
749         mode      => $mode_gp,
750         modified_flags => $status_flags
751 },
752
753 l_ShlD => {
754         cmp_attr  => "return 1;",
755         reg_req  => { in => [ "none", "none", "none" ], out => [ "none" ] },
756         ins       => [ "val_high", "val_low", "count" ],
757 },
758
759 Shr => {
760         irn_flags => "R",
761         reg_req   => { in => [ "gp", "ecx" ],
762                        out => [ "in_r1 !in_r2", "flags" ] },
763         ins       => [ "val", "count" ],
764         outs      => [ "res", "flags" ],
765         emit      => '. shr%M %SB1, %S0',
766         units     => [ "GP" ],
767         mode      => $mode_gp,
768         latency   => 1,
769         modified_flags => $status_flags
770 },
771
772 ShrMem => {
773         irn_flags => "R",
774         state     => "exc_pinned",
775         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
776         ins       => [ "base", "index", "mem", "count" ],
777         emit      => '. shr%M %SB3, %AM',
778         units     => [ "GP" ],
779         mode      => "mode_M",
780         latency   => 1,
781         modified_flags => $status_flags
782 },
783
784 l_ShrDep => {
785         cmp_attr  => "return 1;",
786         reg_req   => { in => [ "none", "none", "none" ], out => [ "none" ] },
787         ins       => [ "val", "count", "dep" ],
788 },
789
790 ShrD => {
791         irn_flags => "R",
792         reg_req   => { in => [ "gp", "gp", "ecx" ],
793                        out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
794         ins       => [ "val_high", "val_low", "count" ],
795         outs      => [ "res", "flags" ],
796         emit      => ". shrd%M %SB2, %S1, %D0",
797         latency   => 6,
798         units     => [ "GP" ],
799         mode      => $mode_gp,
800         modified_flags => $status_flags
801 },
802
803 l_ShrD => {
804         cmp_attr  => "return 1;",
805         reg_req   => { in => [ "none", "none", "none" ], out => [ "none" ] },
806         ins       => [ "val_high", "val_low", "count" ],
807 },
808
809 Sar => {
810         irn_flags => "R",
811         reg_req   => { in => [ "gp", "ecx" ],
812                        out => [ "in_r1 !in_r2", "flags" ] },
813         ins       => [ "val", "count" ],
814         outs      => [ "res", "flags" ],
815         emit      => '. sar%M %SB1, %S0',
816         units     => [ "GP" ],
817         latency   => 1,
818         mode      => $mode_gp,
819         modified_flags => $status_flags
820 },
821
822 SarMem => {
823         irn_flags => "R",
824         state     => "exc_pinned",
825         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
826         ins       => [ "base", "index", "mem", "count" ],
827         emit      => '. sar%M %SB3, %AM',
828         units     => [ "GP" ],
829         latency   => 1,
830         mode      => "mode_M",
831         modified_flags => $status_flags
832 },
833
834 l_SarDep => {
835         cmp_attr  => "return 1;",
836         ins       => [ "val", "count", "dep" ],
837         reg_req   => { in => [ "none", "none", "none" ], out => [ "none" ] },
838 },
839
840 Ror => {
841         irn_flags => "R",
842         reg_req   => { in => [ "gp", "ecx" ],
843                        out => [ "in_r1 !in_r2", "flags" ] },
844         ins       => [ "val", "count" ],
845         outs      => [ "res", "flags" ],
846         emit      => '. ror%M %SB1, %S0',
847         units     => [ "GP" ],
848         latency   => 1,
849         mode      => $mode_gp,
850         modified_flags => $status_flags
851 },
852
853 RorMem => {
854         irn_flags => "R",
855         state     => "exc_pinned",
856         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
857         ins       => [ "base", "index", "mem", "count" ],
858         emit      => '. ror%M %SB3, %AM',
859         units     => [ "GP" ],
860         latency   => 1,
861         mode      => "mode_M",
862         modified_flags => $status_flags
863 },
864
865 Rol => {
866         irn_flags => "R",
867         reg_req   => { in => [ "gp", "ecx" ],
868                        out => [ "in_r1 !in_r2", "flags" ] },
869         ins       => [ "val", "count" ],
870         outs      => [ "res", "flags" ],
871         emit      => '. rol%M %SB1, %S0',
872         units     => [ "GP" ],
873         latency   => 1,
874         mode      => $mode_gp,
875         modified_flags => $status_flags
876 },
877
878 RolMem => {
879         irn_flags => "R",
880         state     => "exc_pinned",
881         reg_req   => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
882         ins       => [ "base", "index", "mem", "count" ],
883         emit      => '. rol%M %SB3, %AM',
884         units     => [ "GP" ],
885         latency   => 1,
886         mode      => "mode_M",
887         modified_flags => $status_flags
888 },
889
890 Neg => {
891         irn_flags => "R",
892         reg_req   => { in => [ "gp" ],
893                        out => [ "in_r1", "flags" ] },
894         emit      => '. neg%M %S0',
895         ins       => [ "val" ],
896         outs      => [ "res", "flags" ],
897         units     => [ "GP" ],
898         latency   => 1,
899         mode      => $mode_gp,
900         modified_flags => $status_flags
901 },
902
903 NegMem => {
904         irn_flags => "R",
905         state     => "exc_pinned",
906         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
907         ins       => [ "base", "index", "mem" ],
908         emit      => '. neg%M %AM',
909         units     => [ "GP" ],
910         latency   => 1,
911         mode      => "mode_M",
912         modified_flags => $status_flags
913 },
914
915 Minus64Bit => {
916         irn_flags => "R",
917         reg_req   => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
918         outs      => [ "low_res", "high_res" ],
919         units     => [ "GP" ],
920         latency   => 3,
921         modified_flags => $status_flags
922 },
923
924
925 Inc => {
926         irn_flags => "R",
927         reg_req   => { in => [ "gp" ],
928                        out => [ "in_r1", "flags" ] },
929         ins       => [ "val" ],
930         outs      => [ "res", "flags" ],
931         emit      => '. inc%M %S0',
932         units     => [ "GP" ],
933         mode      => $mode_gp,
934         latency   => 1,
935         modified_flags => $status_flags_wo_cf
936 },
937
938 IncMem => {
939         irn_flags => "R",
940         state     => "exc_pinned",
941         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
942         ins       => [ "base", "index", "mem" ],
943         emit      => '. inc%M %AM',
944         units     => [ "GP" ],
945         mode      => "mode_M",
946         latency   => 1,
947         modified_flags => $status_flags_wo_cf
948 },
949
950 Dec => {
951         irn_flags => "R",
952         reg_req   => { in => [ "gp" ],
953                        out => [ "in_r1", "flags" ] },
954         ins       => [ "val" ],
955         outs      => [ "res", "flags" ],
956         emit      => '. dec%M %S0',
957         units     => [ "GP" ],
958         mode      => $mode_gp,
959         latency   => 1,
960         modified_flags => $status_flags_wo_cf
961 },
962
963 DecMem => {
964         irn_flags => "R",
965         state     => "exc_pinned",
966         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
967         ins       => [ "base", "index", "mem" ],
968         emit      => '. dec%M %AM',
969         units     => [ "GP" ],
970         mode      => "mode_M",
971         latency   => 1,
972         modified_flags => $status_flags_wo_cf
973 },
974
975 Not => {
976         irn_flags => "R",
977         reg_req   => { in => [ "gp" ],
978                        out => [ "in_r1", "flags" ] },
979         ins       => [ "val" ],
980         outs      => [ "res", "flags" ],
981         emit      => '. not%M %S0',
982         units     => [ "GP" ],
983         latency   => 1,
984         mode      => $mode_gp,
985         # no flags modified
986 },
987
988 NotMem => {
989         irn_flags => "R",
990         state     => "exc_pinned",
991         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
992         ins       => [ "base", "index", "mem" ],
993         emit      => '. not%M %AM',
994         units     => [ "GP" ],
995         latency   => 1,
996         mode      => "mode_M",
997         # no flags modified
998 },
999
1000 Cmc => {
1001         reg_req   => { in => [ "flags" ], out => [ "flags" ] },
1002         emit      => '.cmc',
1003         units     => [ "GP" ],
1004         latency   => 1,
1005         mode      => $mode_flags,
1006         modified_flags => $status_flags
1007 },
1008
1009 Stc => {
1010         reg_req   => { out => [ "flags" ] },
1011         emit      => '.stc',
1012         units     => [ "GP" ],
1013         latency   => 1,
1014         mode      => $mode_flags,
1015         modified_flags => $status_flags
1016 },
1017
1018 Cmp => {
1019         irn_flags => "R",
1020         state     => "exc_pinned",
1021         reg_req   => { in  => [ "gp", "gp", "none", "gp", "gp" ],
1022                        out => [ "flags", "none", "none" ] },
1023         ins       => [ "base", "index", "mem", "left", "right" ],
1024         outs      => [ "eflags", "unused", "M" ],
1025         am        => "source,binary",
1026         emit      => '. cmp%M %binop',
1027         attr      => "int ins_permuted, int cmp_unsigned",
1028         init_attr => "attr->data.ins_permuted   = ins_permuted;\n".
1029                      "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
1030         latency   => 1,
1031         units     => [ "GP" ],
1032         mode      => $mode_flags,
1033         modified_flags => $status_flags
1034 },
1035
1036 Cmp8Bit => {
1037         irn_flags => "R",
1038         state     => "exc_pinned",
1039         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
1040                        out => [ "flags", "none", "none" ] },
1041         ins       => [ "base", "index", "mem", "left", "right" ],
1042         outs      => [ "eflags", "unused", "M" ],
1043         am        => "source,binary",
1044         emit      => '. cmpb %binop',
1045         attr      => "int ins_permuted, int cmp_unsigned",
1046         init_attr => "attr->data.ins_permuted   = ins_permuted;\n".
1047                      "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
1048         latency   => 1,
1049         units     => [ "GP" ],
1050         mode      => $mode_flags,
1051         modified_flags => $status_flags
1052 },
1053
1054 Test => {
1055         irn_flags => "R",
1056         state     => "exc_pinned",
1057         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ] ,
1058                        out => [ "flags", "none", "none" ] },
1059         ins       => [ "base", "index", "mem", "left", "right" ],
1060         outs      => [ "eflags", "unused", "M" ],
1061         am        => "source,binary",
1062         emit      => '. test%M %binop',
1063         attr      => "int ins_permuted, int cmp_unsigned",
1064         init_attr => "attr->data.ins_permuted = ins_permuted;\n".
1065                      "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
1066         latency   => 1,
1067         units     => [ "GP" ],
1068         mode      => $mode_flags,
1069         modified_flags => $status_flags
1070 },
1071
1072 Test8Bit => {
1073         irn_flags => "R",
1074         state     => "exc_pinned",
1075         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] ,
1076                        out => [ "flags", "none", "none" ] },
1077         ins       => [ "base", "index", "mem", "left", "right" ],
1078         outs      => [ "eflags", "unused", "M" ],
1079         am        => "source,binary",
1080         emit      => '. testb %binop',
1081         attr      => "int ins_permuted, int cmp_unsigned",
1082         init_attr => "attr->data.ins_permuted = ins_permuted;\n".
1083                      "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
1084         latency   => 1,
1085         units     => [ "GP" ],
1086         mode      => $mode_flags,
1087         modified_flags => $status_flags
1088 },
1089
1090 Setcc => {
1091         #irn_flags => "R",
1092         reg_req   => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
1093         ins       => [ "eflags" ],
1094         outs      => [ "res" ],
1095         attr_type => "ia32_condcode_attr_t",
1096         attr      => "pn_Cmp pnc",
1097         # The way we handle Setcc with float nodes (potentially) destroys the flags
1098         # (when we emit the setX; setp; orb and the setX;setnp;andb sequences)
1099         init_attr => "set_ia32_ls_mode(res, mode_Bu);\n"
1100                 . "\tif ((pnc & ia32_pn_Cmp_float) && ((pnc & 0xf) != pn_Cmp_Uo) && ((pnc & 0xf) != pn_Cmp_Leg)) {\n"
1101                 . "\t\tarch_irn_add_flags(res, arch_irn_flags_modify_flags);\n"
1102                 . "\t\t/* attr->latency = 3; */\n"
1103                 . "\t}\n",
1104         latency   => 1,
1105         units     => [ "GP" ],
1106         mode      => $mode_gp,
1107 },
1108
1109 SetccMem => {
1110         #irn_flags => "R",
1111         state     => "exc_pinned",
1112         reg_req   => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
1113         ins       => [ "base", "index", "mem","eflags" ],
1114         attr_type => "ia32_condcode_attr_t",
1115         attr      => "pn_Cmp pnc",
1116         init_attr => "set_ia32_ls_mode(res, mode_Bu);\n",
1117         emit      => '. set%CMP3 %AM',
1118         latency   => 1,
1119         units     => [ "GP" ],
1120         mode      => 'mode_M',
1121 },
1122
1123 CMovcc => {
1124         #irn_flags => "R",
1125         state     => "exc_pinned",
1126         # (note: leave the false,true order intact to make it compatible with other
1127         #  ia32_binary ops)
1128         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ],
1129                        out => [ "in_r4 in_r5", "flags", "none" ] },
1130         ins       => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
1131         outs      => [ "res", "flags", "M" ],
1132         am        => "source,binary",
1133         attr_type => "ia32_condcode_attr_t",
1134         attr      => "pn_Cmp pnc",
1135         latency   => 1,
1136         units     => [ "GP" ],
1137         mode      => $mode_gp,
1138 },
1139
1140 Jcc => {
1141         state     => "pinned",
1142         op_flags  => "L|X|Y",
1143         reg_req   => { in  => [ "eflags" ], out => [ "none", "none" ] },
1144         ins       => [ "eflags" ],
1145         outs      => [ "false", "true" ],
1146         attr_type => "ia32_condcode_attr_t",
1147         attr      => "pn_Cmp pnc",
1148         latency   => 2,
1149         units     => [ "BRANCH" ],
1150 },
1151
1152 SwitchJmp => {
1153         state     => "pinned",
1154         op_flags  => "L|X|Y",
1155         reg_req   => { in => [ "gp" ] },
1156         mode      => "mode_T",
1157         attr_type => "ia32_condcode_attr_t",
1158         attr      => "long pnc",
1159         latency   => 3,
1160         units     => [ "BRANCH" ],
1161         modified_flags => $status_flags,
1162         init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements
1163 },
1164
1165 Jmp => {
1166         state     => "pinned",
1167         irn_flags => "J",
1168         op_flags  => "X",
1169         reg_req   => { out => [ "none" ] },
1170         latency   => 1,
1171         units     => [ "BRANCH" ],
1172         mode      => "mode_X",
1173 },
1174
1175 IJmp => {
1176         state     => "pinned",
1177         op_flags  => "X",
1178         reg_req   => { in => [ "gp", "gp", "none", "gp" ] },
1179         ins       => [ "base", "index", "mem", "target" ],
1180         am        => "source,unary",
1181         emit      => '. jmp *%unop3',
1182         latency   => 1,
1183         units     => [ "BRANCH" ],
1184         mode      => "mode_X",
1185         init_attr => "info->out_infos = NULL;", # XXX ugly hack for out requirements
1186 },
1187
1188 Const => {
1189         op_flags  => "c",
1190         irn_flags => "R",
1191         reg_req   => { out => [ "gp" ] },
1192         units     => [ "GP" ],
1193         attr      => "ir_entity *symconst, int symconst_sign, int no_pic_adjust, long offset",
1194         attr_type => "ia32_immediate_attr_t",
1195         latency   => 1,
1196         mode      => $mode_gp,
1197 },
1198
1199 Unknown => {
1200         op_flags  => "c",
1201         irn_flags => "R",
1202         reg_req   => { out => [ "gp" ] },
1203         latency   => 0,
1204         emit      => '',
1205         mode      => $mode_gp,
1206 },
1207
1208 GetEIP => {
1209         op_flags => "c",
1210         reg_req  => { out => [ "gp" ] },
1211         units    => [ "GP" ],
1212         latency  => 5,
1213         mode     => $mode_gp,
1214         modified_flags => $status_flags,
1215 },
1216
1217 NoReg_GP => {
1218         state     => "pinned",
1219         op_flags  => "c|NB|NI",
1220         reg_req   => { out => [ "gp_NOREG:I" ] },
1221         units     => [],
1222         emit      => "",
1223         latency   => 0,
1224         mode      => $mode_gp
1225 },
1226
1227 NoReg_VFP => {
1228         state     => "pinned",
1229         op_flags  => "c|NB|NI",
1230         reg_req   => { out => [ "vfp_NOREG:I" ] },
1231         units     => [],
1232         emit      => "",
1233         mode      => "mode_E",
1234         latency   => 0,
1235         attr_type => "ia32_x87_attr_t",
1236 },
1237
1238 NoReg_XMM => {
1239         state     => "pinned",
1240         op_flags  => "c|NB|NI",
1241         reg_req   => { out => [ "xmm_NOREG:I" ] },
1242         units     => [],
1243         emit      => "",
1244         latency   => 0,
1245         mode      => "mode_E"
1246 },
1247
1248 ChangeCW => {
1249         state     => "pinned",
1250         op_flags  => "c",
1251         reg_req   => { out => [ "fpcw:I" ] },
1252         mode      => $mode_fpcw,
1253         latency   => 3,
1254         units     => [ "GP" ],
1255         modified_flags => $fpcw_flags
1256 },
1257
1258 FldCW => {
1259         op_flags  => "L|F",
1260         state     => "pinned",
1261         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "fpcw:I" ] },
1262         ins       => [ "base", "index", "mem" ],
1263         latency   => 5,
1264         emit      => ". fldcw %AM",
1265         mode      => $mode_fpcw,
1266         units     => [ "GP" ],
1267         modified_flags => $fpcw_flags
1268 },
1269
1270 FnstCW => {
1271         op_flags  => "L|F",
1272         state     => "pinned",
1273         reg_req   => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1274         ins       => [ "base", "index", "mem", "fpcw" ],
1275         latency   => 5,
1276         emit      => ". fnstcw %AM",
1277         mode      => "mode_M",
1278         units     => [ "GP" ],
1279 },
1280
1281 FnstCWNOP => {
1282         op_flags  => "L|F",
1283         state     => "pinned",
1284         reg_req   => { in => [ "fp_cw" ], out => [ "none" ] },
1285         ins       => [ "fpcw" ],
1286         latency   => 0,
1287         emit      => "",
1288         mode      => "mode_M",
1289 },
1290
1291 Cltd => {
1292         # we should not rematrialize this node. It has very strict constraints.
1293         reg_req   => { in => [ "eax", "edx" ], out => [ "edx" ] },
1294         ins       => [ "val", "clobbered" ],
1295         emit      => '. cltd',
1296         latency   => 1,
1297         mode      => $mode_gp,
1298         units     => [ "GP" ],
1299 },
1300
1301 # Load / Store
1302 #
1303 # Note that we add additional latency values depending on address mode, so a
1304 # lateny of 0 for load is correct
1305
1306 Load => {
1307         op_flags  => "L|F",
1308         state     => "exc_pinned",
1309         reg_req   => { in => [ "gp", "gp", "none" ],
1310                        out => [ "gp", "none", "none", "none" ] },
1311         ins       => [ "base", "index", "mem" ],
1312         outs      => [ "res", "unused", "M", "X_exc" ],
1313         latency   => 0,
1314         emit      => ". mov%EX%.l %AM, %D0",
1315         units     => [ "GP" ],
1316 },
1317
1318 Store => {
1319         op_flags  => "L|F",
1320         state     => "exc_pinned",
1321         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none", "none" ] },
1322         ins       => [ "base", "index", "mem", "val" ],
1323         outs      => [ "M", "X_exc" ],
1324         emit      => '. mov%M %SI3, %AM',
1325         latency   => 2,
1326         units     => [ "GP" ],
1327         mode      => "mode_M",
1328 },
1329
1330 Store8Bit => {
1331         op_flags  => "L|F",
1332         state     => "exc_pinned",
1333         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => ["none", "none" ] },
1334         ins       => [ "base", "index", "mem", "val" ],
1335         outs      => [ "M", "X_exc" ],
1336         emit      => '. mov%M %SB3, %AM',
1337         latency   => 2,
1338         units     => [ "GP" ],
1339         mode      => "mode_M",
1340 },
1341
1342 Lea => {
1343         irn_flags => "R",
1344         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
1345         ins       => [ "base", "index" ],
1346         emit      => '. leal %AM, %D0',
1347         latency   => 2,
1348         units     => [ "GP" ],
1349         mode      => $mode_gp,
1350 # lea doesn't modify the flags, but setting this seems advantageous since it
1351 # increases chances that the Lea is transformed back to an Add
1352         modified_flags => 1,
1353 },
1354
1355 Push => {
1356         state     => "exc_pinned",
1357         reg_req   => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp:I|S", "none" ] },
1358         ins       => [ "base", "index", "mem", "val", "stack" ],
1359         emit      => '. push%M %unop3',
1360         outs      => [ "stack", "M" ],
1361         am        => "source,unary",
1362         latency   => 2,
1363         units     => [ "GP" ],
1364 },
1365
1366 PushEax => {
1367         state   => "exc_pinned",
1368         reg_req => { in => [ "esp" ], out => [ "esp:I|S" ] },
1369         ins     => [ "stack" ],
1370         outs    => [ "stack" ],
1371         emit    => '. pushl %%eax',
1372         latency => 2,
1373         units   => [ "GP" ],
1374         mode    => $mode_gp,
1375 },
1376
1377 Pop => {
1378         state     => "exc_pinned",
1379         reg_req   => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp:I|S" ] },
1380         ins       => [ "mem", "stack" ],
1381         outs      => [ "res", "M", "unused", "stack" ],
1382         emit      => '. pop%M %D0',
1383         latency   => 3, # Pop is more expensive than Push on Athlon
1384         units     => [ "GP" ],
1385 },
1386
1387 PopEbp => {
1388         state     => "exc_pinned",
1389         reg_req   => { in => [ "none", "esp" ], out => [ "ebp:I", "none", "none", "esp:I|S" ] },
1390         ins       => [ "mem", "stack" ],
1391         outs      => [ "res", "M", "unused", "stack" ],
1392         emit      => '. pop%M %D0',
1393         latency   => 3, # Pop is more expensive than Push on Athlon
1394         units     => [ "GP" ],
1395 },
1396
1397 PopMem => {
1398         state     => "exc_pinned",
1399         reg_req   => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp:I|S" ] },
1400         ins       => [ "base", "index", "mem", "stack" ],
1401         outs      => [ "unused0", "M", "unused1", "stack" ],
1402         emit      => '. pop%M %AM',
1403         latency   => 3, # Pop is more expensive than Push on Athlon
1404         units     => [ "GP" ],
1405 },
1406
1407 Enter => {
1408         reg_req   => { in => [ "esp" ], out => [ "ebp", "esp:I|S", "none" ] },
1409         emit      => '. enter',
1410         outs      => [ "frame", "stack", "M" ],
1411         latency   => 15,
1412         units     => [ "GP" ],
1413 },
1414
1415 Leave => {
1416         reg_req   => { in => [ "ebp" ], out => [ "ebp:I", "esp:I|S" ] },
1417         emit      => '. leave',
1418         outs      => [ "frame", "stack" ],
1419         latency   => 3,
1420         units     => [ "GP" ],
1421 },
1422
1423 AddSP => {
1424         state     => "pinned",
1425         reg_req   => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "none" ] },
1426         ins       => [ "base", "index", "mem", "stack", "size" ],
1427         am        => "source,binary",
1428         emit      => '. addl %binop',
1429         latency   => 1,
1430         outs      => [ "stack", "M" ],
1431         units     => [ "GP" ],
1432         modified_flags => $status_flags
1433 },
1434
1435 SubSP => {
1436         state     => "pinned",
1437         reg_req   => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "esp:I|S", "gp", "none" ] },
1438         ins       => [ "base", "index", "mem", "stack", "size" ],
1439         am        => "source,binary",
1440         emit      => ". subl %binop\n".
1441                      ". movl %%esp, %D1",
1442         latency   => 2,
1443         outs      => [ "stack", "addr", "M" ],
1444         units     => [ "GP" ],
1445         modified_flags => $status_flags
1446 },
1447
1448 RepPrefix => {
1449         op_flags  => "K",
1450         state     => "pinned",
1451         mode      => "mode_M",
1452         emit      => ". rep",
1453         latency   => 0,
1454 },
1455
1456 LdTls => {
1457         irn_flags => "R",
1458         reg_req   => { out => [ "gp" ] },
1459         units     => [ "GP" ],
1460         latency   => 1,
1461 },
1462
1463 #
1464 # BT supports source address mode, but this is unused yet
1465 #
1466 Bt => {
1467         irn_flags => "R",
1468         state     => "exc_pinned",
1469         reg_req   => { in => [ "gp", "gp" ], out => [ "flags" ] },
1470         ins       => [ "left", "right" ],
1471         emit      => '. bt%M %S1, %S0',
1472         units     => [ "GP" ],
1473         latency   => 1,
1474         mode      => $mode_flags,
1475         modified_flags => $status_flags  # only CF is set, but the other flags are undefined
1476 },
1477
1478 Bsf => {
1479         irn_flags => "R",
1480         state     => "exc_pinned",
1481         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1482                        out => [ "gp", "flags", "none" ] },
1483         ins       => [ "base", "index", "mem", "operand" ],
1484         outs      => [ "res", "flags", "M" ],
1485         am        => "source,binary",
1486         emit      => '. bsf%M %unop3, %D0',
1487         units     => [ "GP" ],
1488         latency   => 1,
1489         mode      => $mode_gp,
1490         modified_flags => $status_flags
1491 },
1492
1493 Bsr => {
1494         irn_flags => "R",
1495         state     => "exc_pinned",
1496         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1497                        out => [ "gp", "flags", "none" ] },
1498         ins       => [ "base", "index", "mem", "operand" ],
1499         outs      => [ "res", "flags", "M" ],
1500         am        => "source,binary",
1501         emit      => '. bsr%M %unop3, %D0',
1502         units     => [ "GP" ],
1503         latency   => 1,
1504         mode      => $mode_gp,
1505         modified_flags => $status_flags
1506 },
1507
1508 #
1509 # SSE4.2 or SSE4a popcnt instruction
1510 #
1511 Popcnt => {
1512         irn_flags => "R",
1513         state     => "exc_pinned",
1514         reg_req   => { in => [ "gp", "gp", "none", "gp" ],
1515                        out => [ "gp", "flags", "none" ] },
1516         ins       => [ "base", "index", "mem", "operand" ],
1517         outs      => [ "res", "flags", "M" ],
1518         am        => "source,binary",
1519         emit      => '. popcnt%M %unop3, %D0',
1520         units     => [ "GP" ],
1521         latency   => 1,
1522         mode      => $mode_gp,
1523         modified_flags => $status_flags
1524 },
1525
1526 Call => {
1527         state     => "exc_pinned",
1528         reg_req   => {
1529                 in  => [ "gp", "gp", "none", "gp", "esp", "fpcw", "eax", "ecx", "edx" ],
1530                 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" ]
1531         },
1532         ins       => [ "base", "index", "mem", "addr", "stack", "fpcw", "eax", "ecx", "edx" ],
1533         outs      => [ "stack", "fpcw", "M", "eax", "ecx", "edx", "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" ],
1534         attr_type => "ia32_call_attr_t",
1535         attr      => "unsigned pop, ir_type *call_tp",
1536         am        => "source,unary",
1537         units     => [ "BRANCH" ],
1538         latency   => 4, # random number
1539         modified_flags => $status_flags
1540 },
1541
1542 #
1543 # a Helper node for frame-climbing, needed for __builtin_(frame|return)_address
1544 #
1545 # PS: try gcc __builtin_frame_address(100000) :-)
1546 #
1547 ClimbFrame => {
1548         reg_req   => { in => [ "gp", "gp", "gp"], out => [ "in_r3" ] },
1549         ins       => [ "frame", "cnt", "tmp" ],
1550         outs      => [ "res" ],
1551         latency   => 4, # random number
1552         attr_type => "ia32_climbframe_attr_t",
1553         attr      => "unsigned count",
1554         units     => [ "GP" ],
1555         mode      => $mode_gp
1556 },
1557
1558 #
1559 # bswap
1560 #
1561 Bswap => {
1562         irn_flags => "R",
1563         reg_req   => { in => [ "gp" ],
1564                        out => [ "in_r1" ] },
1565         emit      => '. bswap%M %S0',
1566         ins       => [ "val" ],
1567         units     => [ "GP" ],
1568         latency   => 1,
1569         mode      => $mode_gp,
1570 },
1571
1572 #
1573 # bswap16, use xchg here
1574 #
1575 Bswap16 => {
1576         irn_flags => "R",
1577         reg_req   => { in => [ "eax ebx ecx edx" ],
1578                        out => [ "in_r1" ] },
1579         emit      => '. xchg %SB0, %SH0',
1580         ins       => [ "val" ],
1581         units     => [ "GP" ],
1582         latency   => 1,
1583         mode      => $mode_gp,
1584 },
1585
1586 #
1587 # BreakPoint
1588 #
1589 Breakpoint => {
1590         state     => "pinned",
1591         reg_req   => { in => [ "none" ], out => [ "none" ] },
1592         ins       => [ "mem" ],
1593         latency   => 0,
1594         emit      => ". int3",
1595         units     => [ "GP" ],
1596         mode      => mode_M,
1597 },
1598
1599 #
1600 # Undefined Instruction on ALL x86 CPU's
1601 #
1602 UD2 => {
1603         state     => "pinned",
1604         reg_req   => { in => [ "none" ], out => [ "none" ] },
1605         ins       => [ "mem" ],
1606         latency   => 0,
1607         emit      => ". .value  0x0b0f",
1608         units     => [ "GP" ],
1609         mode      => mode_M,
1610 },
1611
1612 #
1613 # outport
1614 #
1615 Outport => {
1616         irn_flags => "R",
1617         state     => "pinned",
1618         reg_req   => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
1619         ins       => [ "port", "value", "mem" ],
1620         emit      => '. out%M %SS0, %SI1',
1621         units     => [ "GP" ],
1622         latency   => 1,
1623         mode      => mode_M,
1624         modified_flags => $status_flags
1625 },
1626
1627 #
1628 # inport
1629 #
1630 Inport => {
1631         irn_flags => "R",
1632         state     => "pinned",
1633         reg_req   => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
1634         ins       => [ "port", "mem" ],
1635         outs      => [ "res", "M" ],
1636         emit      => '. in%M %DS0, %SS0',
1637         units     => [ "GP" ],
1638         latency   => 1,
1639         mode      => mode_T,
1640         modified_flags => $status_flags
1641 },
1642
1643 #
1644 # Intel style prefetching
1645 #
1646 Prefetch0 => {
1647         op_flags  => "L|F",
1648         state     => "exc_pinned",
1649         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1650         ins       => [ "base", "index", "mem" ],
1651         outs      => [ "M" ],
1652         latency   => 0,
1653         emit      => ". prefetcht0 %AM",
1654         units     => [ "GP" ],
1655 },
1656
1657 Prefetch1 => {
1658         op_flags  => "L|F",
1659         state     => "exc_pinned",
1660         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1661         ins       => [ "base", "index", "mem" ],
1662         outs      => [ "M" ],
1663         latency   => 0,
1664         emit      => ". prefetcht1 %AM",
1665         units     => [ "GP" ],
1666 },
1667
1668 Prefetch2 => {
1669         op_flags  => "L|F",
1670         state     => "exc_pinned",
1671         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1672         ins       => [ "base", "index", "mem" ],
1673         outs      => [ "M" ],
1674         latency   => 0,
1675         emit      => ". prefetcht2 %AM",
1676         units     => [ "GP" ],
1677 },
1678
1679 PrefetchNTA => {
1680         op_flags  => "L|F",
1681         state     => "exc_pinned",
1682         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1683         ins       => [ "base", "index", "mem" ],
1684         outs      => [ "M" ],
1685         latency   => 0,
1686         emit      => ". prefetchnta %AM",
1687         units     => [ "GP" ],
1688 },
1689
1690 #
1691 # 3DNow! prefetch instructions
1692 #
1693 Prefetch => {
1694         op_flags  => "L|F",
1695         state     => "exc_pinned",
1696         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1697         ins       => [ "base", "index", "mem" ],
1698         outs      => [ "M" ],
1699         latency   => 0,
1700         emit      => ". prefetch %AM",
1701         units     => [ "GP" ],
1702 },
1703
1704 PrefetchW => {
1705         op_flags  => "L|F",
1706         state     => "exc_pinned",
1707         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
1708         ins       => [ "base", "index", "mem" ],
1709         outs      => [ "M" ],
1710         latency   => 0,
1711         emit      => ". prefetchw %AM",
1712         units     => [ "GP" ],
1713 },
1714
1715 # produces a 0/+0.0
1716 xZero => {
1717         irn_flags => "R",
1718         reg_req   => { out => [ "xmm" ] },
1719         emit      => '. xorp%XSD %D0, %D0',
1720         latency   => 3,
1721         units     => [ "SSE" ],
1722         mode      => $mode_xmm
1723 },
1724
1725 xUnknown => {
1726         op_flags  => "c",
1727         irn_flags => "R",
1728         reg_req   => { out => [ "xmm" ] },
1729         emit      => '',
1730         latency   => 0,
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 "";