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