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