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