- not really necessary, but makes the array size again as big as it was before iro_La...
[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" ] , out => [ "flags" ] },
1013         ins       => [ "base", "index", "mem", "left", "right" ],
1014         outs      => [ "eflags" ],
1015         am        => "source,binary",
1016         emit      => '. cmp%M %binop',
1017         attr      => "int ins_permuted, int cmp_unsigned",
1018         init_attr => "attr->data.ins_permuted   = ins_permuted;\n".
1019                      "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
1020         latency   => 1,
1021         units     => [ "GP" ],
1022         mode      => $mode_flags,
1023         modified_flags => $status_flags
1024 },
1025
1026 Cmp8Bit => {
1027         irn_flags => "R",
1028         state     => "exc_pinned",
1029         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] , out => [ "flags" ] },
1030         ins       => [ "base", "index", "mem", "left", "right" ],
1031         outs      => [ "eflags" ],
1032         am        => "source,binary",
1033         emit      => '. cmpb %binop',
1034         attr      => "int ins_permuted, int cmp_unsigned",
1035         init_attr => "attr->data.ins_permuted   = ins_permuted;\n".
1036                      "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
1037         latency   => 1,
1038         units     => [ "GP" ],
1039         mode      => $mode_flags,
1040         modified_flags => $status_flags
1041 },
1042
1043 Test => {
1044         irn_flags => "R",
1045         state     => "exc_pinned",
1046         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp" ] , out => [ "flags" ] },
1047         ins       => [ "base", "index", "mem", "left", "right" ],
1048         outs      => [ "eflags" ],
1049         am        => "source,binary",
1050         emit      => '. test%M %binop',
1051         attr      => "int ins_permuted, int cmp_unsigned",
1052         init_attr => "attr->data.ins_permuted = ins_permuted;\n".
1053                      "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
1054         latency   => 1,
1055         units     => [ "GP" ],
1056         mode      => $mode_flags,
1057         modified_flags => $status_flags
1058 },
1059
1060 Test8Bit => {
1061         irn_flags => "R",
1062         state     => "exc_pinned",
1063         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] , out => [ "flags" ] },
1064         ins       => [ "base", "index", "mem", "left", "right" ],
1065         outs      => [ "eflags" ],
1066         am        => "source,binary",
1067         emit      => '. testb %binop',
1068         attr      => "int ins_permuted, int cmp_unsigned",
1069         init_attr => "attr->data.ins_permuted = ins_permuted;\n".
1070                      "\tattr->data.cmp_unsigned = cmp_unsigned;\n",
1071         latency   => 1,
1072         units     => [ "GP" ],
1073         mode      => $mode_flags,
1074         modified_flags => $status_flags
1075 },
1076
1077 Set => {
1078         #irn_flags => "R",
1079         reg_req   => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
1080         ins       => [ "eflags" ],
1081         attr_type => "ia32_condcode_attr_t",
1082         attr      => "pn_Cmp pnc, int ins_permuted",
1083         init_attr => "attr->attr.data.ins_permuted = ins_permuted;\n".
1084                       "\tset_ia32_ls_mode(res, mode_Bu);\n",
1085         emit      => '. set%CMP0 %DB0',
1086         latency   => 1,
1087         units     => [ "GP" ],
1088         mode      => $mode_gp,
1089 },
1090
1091 SetMem => {
1092         #irn_flags => "R",
1093         state     => "exc_pinned",
1094         reg_req   => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] },
1095         ins       => [ "base", "index", "mem","eflags" ],
1096         attr_type => "ia32_condcode_attr_t",
1097         attr      => "pn_Cmp pnc, int ins_permuted",
1098         init_attr => "attr->attr.data.ins_permuted = ins_permuted;\n".
1099                       "\tset_ia32_ls_mode(res, mode_Bu);\n",
1100         emit      => '. set%CMP3 %AM',
1101         latency   => 1,
1102         units     => [ "GP" ],
1103         mode      => 'mode_M',
1104 },
1105
1106 CMov => {
1107         #irn_flags => "R",
1108         # (note: leave the false,true order intact to make it compatible with other
1109         #  ia32_binary ops)
1110         state     => "exc_pinned",
1111         reg_req   => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ], out => [ "in_r4 in_r5" ] },
1112         ins       => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
1113         am        => "source,binary",
1114         attr_type => "ia32_condcode_attr_t",
1115         attr      => "int ins_permuted, pn_Cmp pnc",
1116         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
1117         latency   => 1,
1118         units     => [ "GP" ],
1119         mode      => $mode_gp,
1120 },
1121
1122 Jcc => {
1123         state     => "pinned",
1124         op_flags  => "L|X|Y",
1125         reg_req   => { in  => [ "eflags" ], out => [ "none", "none" ] },
1126         ins       => [ "eflags" ],
1127         outs      => [ "false", "true" ],
1128         attr_type => "ia32_condcode_attr_t",
1129         attr      => "pn_Cmp pnc",
1130         latency   => 2,
1131         units     => [ "BRANCH" ],
1132 },
1133
1134 SwitchJmp => {
1135         state     => "pinned",
1136         op_flags  => "L|X|Y",
1137         reg_req   => { in => [ "gp" ], out => [ "none" ] },
1138         mode      => "mode_T",
1139         attr_type => "ia32_condcode_attr_t",
1140         attr      => "pn_Cmp pnc",
1141         latency   => 3,
1142         units     => [ "BRANCH" ],
1143         modified_flags => $status_flags,
1144 },
1145
1146 IJmp => {
1147         state     => "pinned",
1148         op_flags  => "X",
1149         reg_req   => { in => [ "gp", "gp", "none", "gp" ] },
1150         ins       => [ "base", "index", "mem", "target" ],
1151         am        => "source,unary",
1152         emit      => '. jmp *%unop3',
1153         latency   => 1,
1154         units     => [ "BRANCH" ],
1155         mode      => "mode_X",
1156 },
1157
1158 Const => {
1159         op_flags  => "c",
1160         irn_flags => "R",
1161         reg_req   => { out => [ "gp" ] },
1162         units     => [ "GP" ],
1163         attr      => "ir_entity *symconst, int symconst_sign, long offset",
1164         attr_type => "ia32_immediate_attr_t",
1165         latency   => 1,
1166         mode      => $mode_gp,
1167 },
1168
1169 GetEIP => {
1170         op_flags => "c",
1171         reg_req  => { out => [ "gp" ] },
1172         units    => [ "GP" ],
1173         latency  => 5,
1174         mode     => $mode_gp,
1175         modified_flags => $status_flags,
1176 },
1177
1178 Unknown_GP => {
1179         state     => "pinned",
1180         op_flags  => "c",
1181         irn_flags => "I",
1182         reg_req   => { out => [ "gp_UKNWN" ] },
1183         units     => [],
1184         emit      => "",
1185         latency   => 0,
1186         mode      => $mode_gp
1187 },
1188
1189 Unknown_VFP => {
1190         state     => "pinned",
1191         op_flags  => "c",
1192         irn_flags => "I",
1193         reg_req   => { out => [ "vfp_UKNWN" ] },
1194         units     => [],
1195         emit      => "",
1196         mode      => "mode_E",
1197         latency   => 0,
1198         attr_type => "ia32_x87_attr_t",
1199 },
1200
1201 Unknown_XMM => {
1202         state     => "pinned",
1203         op_flags  => "c",
1204         irn_flags => "I",
1205         reg_req   => { out => [ "xmm_UKNWN" ] },
1206         units     => [],
1207         emit      => "",
1208         latency   => 0,
1209         mode      => $mode_xmm
1210 },
1211
1212 NoReg_GP => {
1213         state     => "pinned",
1214         op_flags  => "c",
1215         irn_flags => "I",
1216         reg_req   => { out => [ "gp_NOREG" ] },
1217         units     => [],
1218         emit      => "",
1219         latency   => 0,
1220         mode      => $mode_gp
1221 },
1222
1223 NoReg_VFP => {
1224         state     => "pinned",
1225         op_flags  => "c",
1226         irn_flags => "I",
1227         reg_req   => { out => [ "vfp_NOREG" ] },
1228         units     => [],
1229         emit      => "",
1230         mode      => "mode_E",
1231         latency   => 0,
1232         attr_type => "ia32_x87_attr_t",
1233 },
1234
1235 NoReg_XMM => {
1236         state     => "pinned",
1237         op_flags  => "c",
1238         irn_flags => "I",
1239         reg_req   => { out => [ "xmm_NOREG" ] },
1240         units     => [],
1241         emit      => "",
1242         latency   => 0,
1243         mode      => "mode_E"
1244 },
1245
1246 ChangeCW => {
1247         state     => "pinned",
1248         op_flags  => "c",
1249         irn_flags => "I",
1250         reg_req   => { out => [ "fp_cw" ] },
1251         mode      => $mode_fpcw,
1252         latency   => 3,
1253         units     => [ "GP" ],
1254         modified_flags => $fpcw_flags
1255 },
1256
1257 FldCW => {
1258         op_flags  => "L|F",
1259         state     => "pinned",
1260         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "fp_cw" ] },
1261         ins       => [ "base", "index", "mem" ],
1262         latency   => 5,
1263         emit      => ". fldcw %AM",
1264         mode      => $mode_fpcw,
1265         units     => [ "GP" ],
1266         modified_flags => $fpcw_flags
1267 },
1268
1269 FnstCW => {
1270         op_flags  => "L|F",
1271         state     => "pinned",
1272         reg_req   => { in => [ "gp", "gp", "none", "fp_cw" ], out => [ "none" ] },
1273         ins       => [ "base", "index", "mem", "fpcw" ],
1274         latency   => 5,
1275         emit      => ". fnstcw %AM",
1276         mode      => "mode_M",
1277         units     => [ "GP" ],
1278 },
1279
1280 FnstCWNOP => {
1281         op_flags  => "L|F",
1282         state     => "pinned",
1283         reg_req   => { in => [ "fp_cw" ], out => [ "none" ] },
1284         ins       => [ "fpcw" ],
1285         latency   => 0,
1286         emit      => "",
1287         mode      => "mode_M",
1288 },
1289
1290 Cltd => {
1291         # we should not rematrialize this node. It has very strict constraints.
1292         reg_req   => { in => [ "eax", "edx" ], out => [ "edx" ] },
1293         ins       => [ "val", "clobbered" ],
1294         emit      => '. cltd',
1295         latency   => 1,
1296         mode      => $mode_gp,
1297         units     => [ "GP" ],
1298 },
1299
1300 # Load / Store
1301 #
1302 # Note that we add additional latency values depending on address mode, so a
1303 # lateny of 0 for load is correct
1304
1305 Load => {
1306         op_flags  => "L|F",
1307         state     => "exc_pinned",
1308         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "gp", "none", "none" ] },
1309         ins       => [ "base", "index", "mem" ],
1310         outs      => [ "res", "M", "X_exc" ],
1311         latency   => 0,
1312         emit      => ". mov%SE%ME%.l %AM, %D0",
1313         units     => [ "GP" ],
1314 },
1315
1316 l_Load => {
1317         op_flags  => "L|F",
1318         cmp_attr  => "return 1;",
1319         outs      => [ "res", "M" ],
1320         arity     => 2,
1321 },
1322
1323 l_Store => {
1324         op_flags  => "L|F",
1325         cmp_attr  => "return 1;",
1326         state     => "exc_pinned",
1327         arity     => 3,
1328         mode      => "mode_M",
1329 },
1330
1331 Store => {
1332         op_flags  => "L|F",
1333         state     => "exc_pinned",
1334         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none", "none" ] },
1335         ins       => [ "base", "index", "mem", "val" ],
1336         outs      => [ "M", "X_exc" ],
1337         emit      => '. mov%M %SI3, %AM',
1338         latency   => 2,
1339         units     => [ "GP" ],
1340         mode      => "mode_M",
1341 },
1342
1343 Store8Bit => {
1344         op_flags  => "L|F",
1345         state     => "exc_pinned",
1346         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => ["none", "none" ] },
1347         ins       => [ "base", "index", "mem", "val" ],
1348         outs      => [ "M", "X_exc" ],
1349         emit      => '. mov%M %SB3, %AM',
1350         latency   => 2,
1351         units     => [ "GP" ],
1352         mode      => "mode_M",
1353 },
1354
1355 Lea => {
1356         irn_flags => "R",
1357         reg_req   => { in => [ "gp", "gp" ], out => [ "gp" ] },
1358         ins       => [ "base", "index" ],
1359         emit      => '. leal %AM, %D0',
1360         latency   => 2,
1361         units     => [ "GP" ],
1362         mode      => $mode_gp,
1363 # lea doesn't modify the flags, but setting this seems advantageous since it
1364 # increases chances that the Lea is transformed back to an Add
1365         modified_flags => 1,
1366 },
1367
1368 Push => {
1369         state     => "exc_pinned",
1370         reg_req   => { in => [ "gp", "gp", "none", "gp", "esp" ], out => [ "esp", "none" ] },
1371         ins       => [ "base", "index", "mem", "val", "stack" ],
1372         emit      => '. push%M %unop3',
1373         outs      => [ "stack:I|S", "M" ],
1374         am        => "source,binary",
1375         latency   => 2,
1376         units     => [ "GP" ],
1377 },
1378
1379 Pop => {
1380         state     => "exc_pinned",
1381         reg_req   => { in => [ "none", "esp" ], out => [ "gp", "none", "none", "esp" ] },
1382         ins       => [ "mem", "stack" ],
1383         outs      => [ "res", "M", "unused", "stack:I|S" ],
1384         emit      => '. pop%M %D0',
1385         latency   => 3, # Pop is more expensive than Push on Athlon
1386         units     => [ "GP" ],
1387 },
1388
1389 PopMem => {
1390         state     => "exc_pinned",
1391         reg_req   => { in => [ "gp", "gp", "none", "esp" ], out => [ "none", "none", "none", "esp" ] },
1392         ins       => [ "base", "index", "mem", "stack" ],
1393         outs      => [ "unused0", "M", "unused1", "stack:I|S" ],
1394         emit      => '. pop%M %AM',
1395         latency   => 3, # Pop is more expensive than Push on Athlon
1396         units     => [ "GP" ],
1397 },
1398
1399 Enter => {
1400         reg_req   => { in => [ "esp" ], out => [ "ebp", "esp", "none" ] },
1401         emit      => '. enter',
1402         outs      => [ "frame:I", "stack:I|S", "M" ],
1403         latency   => 15,
1404         units     => [ "GP" ],
1405 },
1406
1407 Leave => {
1408         reg_req   => { in => [ "esp", "ebp" ], out => [ "ebp", "esp" ] },
1409         emit      => '. leave',
1410         outs      => [ "frame:I", "stack:I|S" ],
1411         latency   => 3,
1412         units     => [ "GP" ],
1413 },
1414
1415 AddSP => {
1416         irn_flags => "I",
1417         state     => "pinned",
1418         reg_req   => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "in_r4", "none" ] },
1419         ins       => [ "base", "index", "mem", "stack", "size" ],
1420         am        => "source,binary",
1421         emit      => '. addl %binop',
1422         latency   => 1,
1423         outs      => [ "stack:I|S", "M" ],
1424         units     => [ "GP" ],
1425         modified_flags => $status_flags
1426 },
1427
1428 SubSP => {
1429 #irn_flags => "I",
1430         state     => "pinned",
1431         reg_req   => { in => [ "gp", "gp", "none", "esp", "gp" ], out => [ "in_r4", "gp", "none" ] },
1432         ins       => [ "base", "index", "mem", "stack", "size" ],
1433         am        => "source,binary",
1434         emit      => ". subl %binop\n".
1435                      ". movl %%esp, %D1",
1436         latency   => 2,
1437         outs      => [ "stack:I|S", "addr", "M" ],
1438         units     => [ "GP" ],
1439         modified_flags => $status_flags
1440 },
1441
1442 RepPrefix => {
1443         op_flags  => "K",
1444         state     => "pinned",
1445         mode      => "mode_M",
1446         emit      => ". rep",
1447         latency   => 0,
1448 },
1449
1450 LdTls => {
1451         irn_flags => "R",
1452         reg_req   => { out => [ "gp" ] },
1453         units     => [ "GP" ],
1454         latency   => 1,
1455 },
1456
1457 Bt => {
1458         irn_flags => "R",
1459         state     => "exc_pinned",
1460         reg_req   => { in => [ "gp", "gp" ], out => [ "flags" ] },
1461         ins       => [ "left", "right" ],
1462         emit      => '. bt%M %S1, %S0',
1463         units     => [ "GP" ],
1464         latency   => 1,
1465         mode      => $mode_flags,
1466         modified_flags => $status_flags  # only CF is set, but the other flags are undefined
1467 },
1468
1469 #-----------------------------------------------------------------------------#
1470 #   _____ _____ ______    __ _             _                     _            #
1471 #  / ____/ ____|  ____|  / _| |           | |                   | |           #
1472 # | (___| (___ | |__    | |_| | ___   __ _| |_   _ __   ___   __| | ___  ___  #
1473 #  \___ \\___ \|  __|   |  _| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
1474 #  ____) |___) | |____  | | | | (_) | (_| | |_  | | | | (_) | (_| |  __/\__ \ #
1475 # |_____/_____/|______| |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
1476 #-----------------------------------------------------------------------------#
1477
1478 # produces a 0/+0.0
1479 xZero => {
1480         irn_flags => "R",
1481         reg_req   => { out => [ "xmm" ] },
1482         emit      => '. xorp%XSD %D0, %D0',
1483         latency   => 3,
1484         units     => [ "SSE" ],
1485         mode      => $mode_xmm
1486 },
1487
1488 xPzero => {
1489         irn_flags => "R",
1490         reg_req   => { out => [ "xmm" ] },
1491         emit      => '. pxor %D0, %D0',
1492         latency   => 3,
1493         units     => [ "SSE" ],
1494         mode      => $mode_xmm
1495 },
1496
1497 # produces all 1 bits
1498 xAllOnes => {
1499         irn_flags => "R",
1500         reg_req   => { out => [ "xmm" ] },
1501         emit      => '. pcmpeqb %D0, %D0',
1502         latency   => 3,
1503         units     => [ "SSE" ],
1504         mode      => $mode_xmm
1505 },
1506
1507 # integer shift left, dword
1508 xPslld => {
1509         irn_flags => "R",
1510         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1511         emit      => '. pslld %SI1, %D0',
1512         latency   => 3,
1513         units     => [ "SSE" ],
1514         mode      => $mode_xmm
1515 },
1516
1517 # integer shift left, qword
1518 xPsllq => {
1519         irn_flags => "R",
1520         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1521         emit      => '. psllq %SI1, %D0',
1522         latency   => 3,
1523         units     => [ "SSE" ],
1524         mode      => $mode_xmm
1525 },
1526
1527 # integer shift right, dword
1528 xPsrld => {
1529         irn_flags => "R",
1530         reg_req   => { in => [ "xmm", "xmm" ], out => [ "in_r1 !in_r2" ] },
1531         emit      => '. psrld %SI1, %D0',
1532         latency   => 1,
1533         units     => [ "SSE" ],
1534         mode      => $mode_xmm
1535 },
1536
1537 # mov from integer to SSE register
1538 xMovd  => {
1539         irn_flags => "R",
1540         reg_req   => { in => [ "gp" ], out => [ "xmm" ] },
1541         emit      => '. movd %S0, %D0',
1542         latency   => 1,
1543         units     => [ "SSE" ],
1544         mode      => $mode_xmm
1545 },
1546
1547 # commutative operations
1548
1549 xAdd => {
1550         irn_flags => "R",
1551         state     => "exc_pinned",
1552         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
1553         ins       => [ "base", "index", "mem", "left", "right" ],
1554         am        => "source,binary",
1555         emit      => '. add%XXM %binop',
1556         latency   => 4,
1557         units     => [ "SSE" ],
1558         mode      => $mode_xmm
1559 },
1560
1561 xMul => {
1562         irn_flags => "R",
1563         state     => "exc_pinned",
1564         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
1565         ins       => [ "base", "index", "mem", "left", "right" ],
1566         am        => "source,binary",
1567         emit      => '. mul%XXM %binop',
1568         latency   => 4,
1569         units     => [ "SSE" ],
1570         mode      => $mode_xmm
1571 },
1572
1573 xMax => {
1574         irn_flags => "R",
1575         state     => "exc_pinned",
1576         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
1577         ins       => [ "base", "index", "mem", "left", "right" ],
1578         am        => "source,binary",
1579         emit      => '. max%XXM %binop',
1580         latency   => 2,
1581         units     => [ "SSE" ],
1582         mode      => $mode_xmm
1583 },
1584
1585 xMin => {
1586         irn_flags => "R",
1587         state     => "exc_pinned",
1588         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
1589         ins       => [ "base", "index", "mem", "left", "right" ],
1590         am        => "source,binary",
1591         emit      => '. min%XXM %binop',
1592         latency   => 2,
1593         units     => [ "SSE" ],
1594         mode      => $mode_xmm
1595 },
1596
1597 xAnd => {
1598         irn_flags => "R",
1599         state     => "exc_pinned",
1600         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
1601         ins       => [ "base", "index", "mem", "left", "right" ],
1602         am        => "source,binary",
1603         emit      => '. andp%XSD %binop',
1604         latency   => 3,
1605         units     => [ "SSE" ],
1606         mode      => $mode_xmm
1607 },
1608
1609 xOr => {
1610         irn_flags => "R",
1611         state     => "exc_pinned",
1612         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
1613         ins       => [ "base", "index", "mem", "left", "right" ],
1614         am        => "source,binary",
1615         emit      => '. orp%XSD %binop',
1616         latency   => 3,
1617         units     => [ "SSE" ],
1618         mode      => $mode_xmm
1619 },
1620
1621 xXor => {
1622         irn_flags => "R",
1623         state     => "exc_pinned",
1624         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 in_r5" ] },
1625         ins       => [ "base", "index", "mem", "left", "right" ],
1626         am        => "source,binary",
1627         emit      => '. xorp%XSD %binop',
1628         latency   => 3,
1629         units     => [ "SSE" ],
1630         mode      => $mode_xmm
1631 },
1632
1633 # not commutative operations
1634
1635 xAndNot => {
1636         irn_flags => "R",
1637         state     => "exc_pinned",
1638         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 !in_r5" ] },
1639         ins       => [ "base", "index", "mem", "left", "right" ],
1640         am        => "source,binary",
1641         emit      => '. andnp%XSD %binop',
1642         latency   => 3,
1643         units     => [ "SSE" ],
1644         mode      => $mode_xmm
1645 },
1646
1647 xSub => {
1648         irn_flags => "R",
1649         state     => "exc_pinned",
1650         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4" ] },
1651         ins       => [ "base", "index", "mem", "minuend", "subtrahend" ],
1652         am        => "source,binary",
1653         emit      => '. sub%XXM %binop',
1654         latency   => 4,
1655         units     => [ "SSE" ],
1656         mode      => $mode_xmm
1657 },
1658
1659 xDiv => {
1660         irn_flags => "R",
1661         state     => "exc_pinned",
1662         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 !in_r5", "none" ] },
1663         ins       => [ "base", "index", "mem", "dividend", "divisor" ],
1664         am        => "source,binary",
1665         outs      => [ "res", "M" ],
1666         emit      => '. div%XXM %binop',
1667         latency   => 16,
1668         units     => [ "SSE" ],
1669 },
1670
1671 # other operations
1672
1673 Ucomi => {
1674         irn_flags => "R",
1675         state     => "exc_pinned",
1676         reg_req   => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "eflags" ] },
1677         ins       => [ "base", "index", "mem", "left", "right" ],
1678         outs      => [ "flags" ],
1679         am        => "source,binary",
1680         attr      => "int ins_permuted",
1681         init_attr => "attr->data.ins_permuted = ins_permuted;",
1682         emit      => ' .ucomi%XXM %binop',
1683         latency   => 3,
1684         units     => [ "SSE" ],
1685         mode      => $mode_flags,
1686         modified_flags => 1,
1687 },
1688
1689 # Load / Store
1690
1691 xLoad => {
1692         op_flags  => "L|F",
1693         state     => "exc_pinned",
1694         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none", "none" ] },
1695         ins       => [ "base", "index", "mem" ],
1696         outs      => [ "res", "M", "X_exc" ],
1697         emit      => '. mov%XXM %AM, %D0',
1698         attr      => "ir_mode *load_mode",
1699         init_attr => "attr->ls_mode = load_mode;",
1700         latency   => 0,
1701         units     => [ "SSE" ],
1702 },
1703
1704 xStore => {
1705         op_flags => "L|F",
1706         state    => "exc_pinned",
1707         reg_req  => { in => [ "gp", "gp", "none", "xmm" ], out => [ "none", "none" ] },
1708         ins       => [ "base", "index", "mem", "val" ],
1709         outs      => [ "M", "X_exc" ],
1710         emit     => '. mov%XXM %S3, %AM',
1711         latency  => 0,
1712         units    => [ "SSE" ],
1713         mode     => "mode_M",
1714 },
1715
1716 xStoreSimple => {
1717         op_flags => "L|F",
1718         state    => "exc_pinned",
1719         reg_req  => { in => [ "gp", "gp", "none", "xmm" ] },
1720         ins      => [ "base", "index", "mem", "val" ],
1721         emit     => '. mov%XXM %S3, %AM',
1722         latency  => 0,
1723         units    => [ "SSE" ],
1724         mode     => "mode_M",
1725 },
1726
1727 CvtSI2SS => {
1728         op_flags => "L|F",
1729         state     => "exc_pinned",
1730         reg_req  => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1731         ins      => [ "base", "index", "mem", "val" ],
1732         am       => "source,unary",
1733         emit     => '. cvtsi2ss %unop3, %D0',
1734         latency  => 2,
1735         units    => [ "SSE" ],
1736         mode     => $mode_xmm
1737 },
1738
1739 CvtSI2SD => {
1740         op_flags => "L|F",
1741         state     => "exc_pinned",
1742         reg_req  => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm" ] },
1743         ins      => [ "base", "index", "mem", "val" ],
1744         am       => "source,unary",
1745         emit     => '. cvtsi2sd %unop3, %D0',
1746         latency  => 2,
1747         units    => [ "SSE" ],
1748         mode     => $mode_xmm
1749 },
1750
1751
1752 l_LLtoFloat => {
1753         op_flags => "L|F",
1754         cmp_attr => "return 1;",
1755         ins      => [ "val_high", "val_low" ],
1756 },
1757
1758 l_FloattoLL => {
1759         op_flags => "L|F",
1760         cmp_attr => "return 1;",
1761         ins      => [ "val" ],
1762         outs     => [ "res_high", "res_low" ],
1763 },
1764
1765 # CopyB
1766
1767 CopyB => {
1768         op_flags  => "F|H",
1769         state     => "pinned",
1770         reg_req   => { in => [ "edi", "esi", "ecx", "none" ], out => [ "edi", "esi", "ecx", "none" ] },
1771         outs      => [ "DST", "SRC", "CNT", "M" ],
1772         attr_type => "ia32_copyb_attr_t",
1773         attr      => "unsigned size",
1774         units     => [ "GP" ],
1775         latency  => 3,
1776 # we don't care about this flag, so no need to mark this node
1777 #       modified_flags => [ "DF" ]
1778 },
1779
1780 CopyB_i => {
1781         op_flags  => "F|H",
1782         state     => "pinned",
1783         reg_req   => { in => [ "edi", "esi", "none" ], out => [  "edi", "esi", "none" ] },
1784         outs      => [ "DST", "SRC", "M" ],
1785         attr_type => "ia32_copyb_attr_t",
1786         attr      => "unsigned size",
1787         units     => [ "GP" ],
1788         latency  => 3,
1789 # we don't care about this flag, so no need to mark this node
1790 #       modified_flags => [ "DF" ]
1791 },
1792
1793 # Conversions
1794
1795 Conv_I2I => {
1796         state     => "exc_pinned",
1797         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "gp", "none" ] },
1798         ins       => [ "base", "index", "mem", "val" ],
1799         am        => "source,unary",
1800         units     => [ "GP" ],
1801         latency   => 1,
1802         attr      => "ir_mode *smaller_mode",
1803         init_attr => "attr->ls_mode = smaller_mode;",
1804         mode      => $mode_gp,
1805 },
1806
1807 Conv_I2I8Bit => {
1808         state     => "exc_pinned",
1809         reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "gp", "none" ] },
1810         ins       => [ "base", "index", "mem", "val" ],
1811         am        => "source,unary",
1812         units     => [ "GP" ],
1813         latency   => 1,
1814         attr      => "ir_mode *smaller_mode",
1815         init_attr => "attr->ls_mode = smaller_mode;",
1816         mode      => $mode_gp,
1817 },
1818
1819 Conv_I2FP => {
1820         state     => "exc_pinned",
1821         reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "xmm", "none" ] },
1822         ins       => [ "base", "index", "mem", "val" ],
1823         am        => "source,unary",
1824         latency   => 10,
1825         units     => [ "SSE" ],
1826         mode      => $mode_xmm,
1827 },
1828
1829 Conv_FP2I => {
1830         state     => "exc_pinned",
1831         reg_req   => { in => [ "gp", "gp", "none", "xmm" ], out => [ "gp", "none" ] },
1832         ins       => [ "base", "index", "mem", "val" ],
1833         am        => "source,unary",
1834         latency   => 10,
1835         units     => [ "SSE" ],
1836         mode      => $mode_gp,
1837 },
1838
1839 Conv_FP2FP => {
1840         state     => "exc_pinned",
1841         reg_req   => { in => [ "gp", "gp", "none", "xmm" ], out => [ "xmm", "none" ] },
1842         ins       => [ "base", "index", "mem", "val" ],
1843         am        => "source,unary",
1844         latency   => 8,
1845         units     => [ "SSE" ],
1846         mode      => $mode_xmm,
1847 },
1848
1849 #----------------------------------------------------------#
1850 #        _      _               _    __ _             _    #
1851 #       (_)    | |             | |  / _| |           | |   #
1852 # __   ___ _ __| |_ _   _  __ _| | | |_| | ___   __ _| |_  #
1853 # \ \ / / | '__| __| | | |/ _` | | |  _| |/ _ \ / _` | __| #
1854 #  \ V /| | |  | |_| |_| | (_| | | | | | | (_) | (_| | |_  #
1855 #   \_/ |_|_|   \__|\__,_|\__,_|_| |_| |_|\___/ \__,_|\__| #
1856 #                 | |                                      #
1857 #  _ __   ___   __| | ___  ___                             #
1858 # | '_ \ / _ \ / _` |/ _ \/ __|                            #
1859 # | | | | (_) | (_| |  __/\__ \                            #
1860 # |_| |_|\___/ \__,_|\___||___/                            #
1861 #----------------------------------------------------------#
1862
1863 # rematerialisation disabled for all float nodes for now, because the fpcw
1864 # handler runs before spilling and we might end up with wrong fpcw then
1865
1866 vfadd => {
1867 #       irn_flags => "R",
1868         state     => "exc_pinned",
1869         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
1870         ins       => [ "base", "index", "mem", "left", "right", "fpcw" ],
1871         am        => "source,binary",
1872         latency   => 4,
1873         units     => [ "VFP" ],
1874         mode      => "mode_E",
1875         attr_type => "ia32_x87_attr_t",
1876 },
1877
1878 vfmul => {
1879 #       irn_flags => "R",
1880         state     => "exc_pinned",
1881         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
1882         ins       => [ "base", "index", "mem", "left", "right", "fpcw" ],
1883         am        => "source,binary",
1884         latency   => 4,
1885         units     => [ "VFP" ],
1886         mode      => "mode_E",
1887         attr_type => "ia32_x87_attr_t",
1888 },
1889
1890 vfsub => {
1891 #       irn_flags => "R",
1892         state     => "exc_pinned",
1893         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
1894         ins       => [ "base", "index", "mem", "minuend", "subtrahend", "fpcw" ],
1895         am        => "source,binary",
1896         latency   => 4,
1897         units     => [ "VFP" ],
1898         mode      => "mode_E",
1899         attr_type => "ia32_x87_attr_t",
1900 },
1901
1902 vfdiv => {
1903         state     => "exc_pinned",
1904         reg_req   => { in => [ "gp", "gp", "none", "vfp", "vfp", "fpcw" ], out => [ "vfp", "none" ] },
1905         ins       => [ "base", "index", "mem", "dividend", "divisor", "fpcw" ],
1906         am        => "source,binary",
1907         outs      => [ "res", "M" ],
1908         latency   => 20,
1909         units     => [ "VFP" ],
1910         attr_type => "ia32_x87_attr_t",
1911 },
1912
1913 vfprem => {
1914         reg_req   => { in => [ "vfp", "vfp", "fpcw" ], out => [ "vfp" ] },
1915         ins       => [ "left", "right", "fpcw" ],
1916         latency   => 20,
1917         units     => [ "VFP" ],
1918         mode      => "mode_E",
1919         attr_type => "ia32_x87_attr_t",
1920 },
1921
1922 vfabs => {
1923         irn_flags => "R",
1924         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
1925         ins       => [ "value" ],
1926         latency   => 2,
1927         units     => [ "VFP" ],
1928         mode      => "mode_E",
1929         attr_type => "ia32_x87_attr_t",
1930 },
1931
1932 vfchs => {
1933         irn_flags => "R",
1934         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
1935         ins       => [ "value" ],
1936         latency   => 2,
1937         units     => [ "VFP" ],
1938         mode      => "mode_E",
1939         attr_type => "ia32_x87_attr_t",
1940 },
1941
1942 # virtual Load and Store
1943
1944 vfld => {
1945         irn_flags => "R",
1946         op_flags  => "L|F",
1947         state     => "exc_pinned",
1948         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none", "none" ] },
1949         ins       => [ "base", "index", "mem" ],
1950         outs      => [ "res", "M", "X_exc" ],
1951         attr      => "ir_mode *load_mode",
1952         init_attr => "attr->attr.ls_mode = load_mode;",
1953         latency   => 2,
1954         units     => [ "VFP" ],
1955         attr_type => "ia32_x87_attr_t",
1956 },
1957
1958 vfst => {
1959         irn_flags => "R",
1960         op_flags  => "L|F",
1961         state     => "exc_pinned",
1962         reg_req   => { in => [ "gp", "gp", "none", "vfp" ], out => [ "none", "none" ] },
1963         ins       => [ "base", "index", "mem", "val" ],
1964         outs      => [ "M", "X_exc" ],
1965         attr      => "ir_mode *store_mode",
1966         init_attr => "attr->attr.ls_mode = store_mode;",
1967         latency   => 2,
1968         units     => [ "VFP" ],
1969         mode      => "mode_M",
1970         attr_type => "ia32_x87_attr_t",
1971 },
1972
1973 # Conversions
1974
1975 vfild => {
1976         state     => "exc_pinned",
1977         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] },
1978         outs      => [ "res", "M" ],
1979         ins       => [ "base", "index", "mem" ],
1980         latency   => 4,
1981         units     => [ "VFP" ],
1982         attr_type => "ia32_x87_attr_t",
1983 },
1984
1985 l_vfild => {
1986         cmp_attr  => "return 1;",
1987         outs      => [ "res", "M" ],
1988         arity     => 2,
1989 },
1990
1991 vfist => {
1992         state     => "exc_pinned",
1993         reg_req   => { in => [ "gp", "gp", "none", "vfp", "fpcw" ] },
1994         ins       => [ "base", "index", "mem", "val", "fpcw" ],
1995         latency   => 4,
1996         units     => [ "VFP" ],
1997         mode      => "mode_M",
1998         attr_type => "ia32_x87_attr_t",
1999 },
2000
2001 # SSE3 fisttp instruction
2002 vfisttp => {
2003         state     => "exc_pinned",
2004         reg_req   => { in => [ "gp", "gp", "none", "vfp" ], out => [ "in_r4", "none" ]},
2005         ins       => [ "base", "index", "mem", "val" ],
2006         outs      => [ "res", "M" ],
2007         latency   => 4,
2008         units     => [ "VFP" ],
2009         attr_type => "ia32_x87_attr_t",
2010 },
2011
2012 l_vfist => {
2013         cmp_attr  => "return 1;",
2014         state     => "exc_pinned",
2015         arity     => 3,
2016         mode      => "mode_M",
2017 },
2018
2019
2020 # constants
2021
2022 vfldz => {
2023         irn_flags => "R",
2024         reg_req   => { out => [ "vfp" ] },
2025         latency   => 4,
2026         units     => [ "VFP" ],
2027         mode      => "mode_E",
2028         attr_type => "ia32_x87_attr_t",
2029 },
2030
2031 vfld1 => {
2032         irn_flags => "R",
2033         reg_req   => { out => [ "vfp" ] },
2034         latency   => 4,
2035         units     => [ "VFP" ],
2036         mode      => "mode_E",
2037         attr_type => "ia32_x87_attr_t",
2038 },
2039
2040 vfldpi => {
2041         irn_flags => "R",
2042         reg_req   => { out => [ "vfp" ] },
2043         latency   => 4,
2044         units     => [ "VFP" ],
2045         mode      => "mode_E",
2046         attr_type => "ia32_x87_attr_t",
2047 },
2048
2049 vfldln2 => {
2050         irn_flags => "R",
2051         reg_req   => { out => [ "vfp" ] },
2052         latency   => 4,
2053         units     => [ "VFP" ],
2054         mode      => "mode_E",
2055         attr_type => "ia32_x87_attr_t",
2056 },
2057
2058 vfldlg2 => {
2059         irn_flags => "R",
2060         reg_req   => { out => [ "vfp" ] },
2061         latency   => 4,
2062         units     => [ "VFP" ],
2063         mode      => "mode_E",
2064         attr_type => "ia32_x87_attr_t",
2065 },
2066
2067 vfldl2t => {
2068         irn_flags => "R",
2069         reg_req   => { out => [ "vfp" ] },
2070         latency   => 4,
2071         units     => [ "VFP" ],
2072         mode      => "mode_E",
2073         attr_type => "ia32_x87_attr_t",
2074 },
2075
2076 vfldl2e => {
2077         irn_flags => "R",
2078         reg_req   => { out => [ "vfp" ] },
2079         latency   => 4,
2080         units     => [ "VFP" ],
2081         mode      => "mode_E",
2082         attr_type => "ia32_x87_attr_t",
2083 },
2084
2085 # other
2086
2087 vFucomFnstsw => {
2088 # we can't allow to rematerialize this node so we don't have
2089 #  accidently produce Phi(Fucom, Fucom(ins_permuted))
2090 #       irn_flags => "R",
2091         reg_req   => { in => [ "vfp", "vfp" ], out => [ "eax" ] },
2092         ins       => [ "left", "right" ],
2093         outs      => [ "flags" ],
2094         attr      => "int ins_permuted",
2095         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2096         latency   => 3,
2097         units     => [ "VFP" ],
2098         attr_type => "ia32_x87_attr_t",
2099         mode      => $mode_gp
2100 },
2101
2102 vFucomi => {
2103         irn_flags => "R",
2104         reg_req   => { in => [ "vfp", "vfp" ], out => [ "eflags" ] },
2105         ins       => [ "left", "right" ],
2106         outs      => [ "flags" ],
2107         attr      => "int ins_permuted",
2108         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2109         latency   => 3,
2110         units     => [ "VFP" ],
2111         attr_type => "ia32_x87_attr_t",
2112         mode      => $mode_gp
2113 },
2114
2115 vFtstFnstsw => {
2116 #       irn_flags => "R",
2117         reg_req   => { in => [ "vfp" ], out => [ "eax" ] },
2118         ins       => [ "left" ],
2119         outs      => [ "flags" ],
2120         attr      => "int ins_permuted",
2121         init_attr => "attr->attr.data.ins_permuted = ins_permuted;",
2122         latency   => 3,
2123         units     => [ "VFP" ],
2124         attr_type => "ia32_x87_attr_t",
2125         mode      => $mode_gp
2126 },
2127
2128 Sahf => {
2129         irn_flags => "R",
2130         reg_req   => { in => [ "eax" ], out => [ "eflags" ] },
2131         ins       => [ "val" ],
2132         outs      => [ "flags" ],
2133         emit      => '. sahf',
2134         latency   => 1,
2135         units     => [ "GP" ],
2136         mode      => $mode_flags,
2137 },
2138
2139 #------------------------------------------------------------------------#
2140 #       ___ _____    __ _             _                     _            #
2141 # __  _( _ )___  |  / _| | ___   __ _| |_   _ __   ___   __| | ___  ___  #
2142 # \ \/ / _ \  / /  | |_| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
2143 #  >  < (_) |/ /   |  _| | (_) | (_| | |_  | | | | (_) | (_| |  __/\__ \ #
2144 # /_/\_\___//_/    |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
2145 #------------------------------------------------------------------------#
2146
2147 # Note: gas is strangely buggy: fdivrp and fdivp as well as fsubrp and fsubp
2148 #       are swapped, we work this around in the emitter...
2149
2150 fadd => {
2151         state     => "exc_pinned",
2152         rd_constructor => "NONE",
2153         reg_req   => { },
2154         emit      => '. fadd%XM %x87_binop',
2155         latency   => 4,
2156         attr_type => "ia32_x87_attr_t",
2157 },
2158
2159 faddp => {
2160         state     => "exc_pinned",
2161         rd_constructor => "NONE",
2162         reg_req   => { },
2163         emit      => '. faddp%XM %x87_binop',
2164         latency   => 4,
2165         attr_type => "ia32_x87_attr_t",
2166 },
2167
2168 fmul => {
2169         state     => "exc_pinned",
2170         rd_constructor => "NONE",
2171         reg_req   => { },
2172         emit      => '. fmul%XM %x87_binop',
2173         latency   => 4,
2174         attr_type => "ia32_x87_attr_t",
2175 },
2176
2177 fmulp => {
2178         state     => "exc_pinned",
2179         rd_constructor => "NONE",
2180         reg_req   => { },
2181         emit      => '. fmulp%XM %x87_binop',,
2182         latency   => 4,
2183         attr_type => "ia32_x87_attr_t",
2184 },
2185
2186 fsub => {
2187         state     => "exc_pinned",
2188         rd_constructor => "NONE",
2189         reg_req   => { },
2190         emit      => '. fsub%XM %x87_binop',
2191         latency   => 4,
2192         attr_type => "ia32_x87_attr_t",
2193 },
2194
2195 fsubp => {
2196         state     => "exc_pinned",
2197         rd_constructor => "NONE",
2198         reg_req   => { },
2199 # see note about gas bugs
2200         emit      => '. fsubrp%XM %x87_binop',
2201         latency   => 4,
2202         attr_type => "ia32_x87_attr_t",
2203 },
2204
2205 fsubr => {
2206         state     => "exc_pinned",
2207         rd_constructor => "NONE",
2208         irn_flags => "R",
2209         reg_req   => { },
2210         emit      => '. fsubr%XM %x87_binop',
2211         latency   => 4,
2212         attr_type => "ia32_x87_attr_t",
2213 },
2214
2215 fsubrp => {
2216         state     => "exc_pinned",
2217         rd_constructor => "NONE",
2218         irn_flags => "R",
2219         reg_req   => { },
2220 # see note about gas bugs
2221         emit      => '. fsubp%XM %x87_binop',
2222         latency   => 4,
2223         attr_type => "ia32_x87_attr_t",
2224 },
2225
2226 fprem => {
2227         rd_constructor => "NONE",
2228         reg_req   => { },
2229         emit      => '. fprem1',
2230         latency   => 20,
2231         attr_type => "ia32_x87_attr_t",
2232 },
2233
2234 # this node is just here, to keep the simulator running
2235 # we can omit this when a fprem simulation function exists
2236 fpremp => {
2237         rd_constructor => "NONE",
2238         reg_req   => { },
2239         emit      => '. fprem1\n'.
2240                      '. fstp %X0',
2241         latency   => 20,
2242         attr_type => "ia32_x87_attr_t",
2243 },
2244
2245 fdiv => {
2246         state     => "exc_pinned",
2247         rd_constructor => "NONE",
2248         reg_req   => { },
2249         emit      => '. fdiv%XM %x87_binop',
2250         latency   => 20,
2251         attr_type => "ia32_x87_attr_t",
2252 },
2253
2254 fdivp => {
2255         state     => "exc_pinned",
2256         rd_constructor => "NONE",
2257         reg_req   => { },
2258 # see note about gas bugs
2259         emit      => '. fdivrp%XM %x87_binop',
2260         latency   => 20,
2261         attr_type => "ia32_x87_attr_t",
2262 },
2263
2264 fdivr => {
2265         state     => "exc_pinned",
2266         rd_constructor => "NONE",
2267         reg_req   => { },
2268         emit      => '. fdivr%XM %x87_binop',
2269         latency   => 20,
2270         attr_type => "ia32_x87_attr_t",
2271 },
2272
2273 fdivrp => {
2274         state     => "exc_pinned",
2275         rd_constructor => "NONE",
2276         reg_req   => { },
2277 # see note about gas bugs
2278         emit      => '. fdivp%XM %x87_binop',
2279         latency   => 20,
2280         attr_type => "ia32_x87_attr_t",
2281 },
2282
2283 fabs => {
2284         rd_constructor => "NONE",
2285         reg_req   => { },
2286         emit      => '. fabs',
2287         latency   => 4,
2288         attr_type => "ia32_x87_attr_t",
2289 },
2290
2291 fchs => {
2292         op_flags  => "R|K",
2293         rd_constructor => "NONE",
2294         reg_req   => { },
2295         emit      => '. fchs',
2296         latency   => 4,
2297         attr_type => "ia32_x87_attr_t",
2298 },
2299
2300 # x87 Load and Store
2301
2302 fld => {
2303         rd_constructor => "NONE",
2304         op_flags  => "R|L|F",
2305         state     => "exc_pinned",
2306         reg_req   => { },
2307         emit      => '. fld%XM %AM',
2308         attr_type => "ia32_x87_attr_t",
2309         latency   => 2,
2310 },
2311
2312 fst => {
2313         rd_constructor => "NONE",
2314         op_flags  => "R|L|F",
2315         state     => "exc_pinned",
2316         reg_req   => { },
2317         emit      => '. fst%XM %AM',
2318         mode      => "mode_M",
2319         attr_type => "ia32_x87_attr_t",
2320         latency   => 2,
2321 },
2322
2323 fstp => {
2324         rd_constructor => "NONE",
2325         op_flags  => "R|L|F",
2326         state     => "exc_pinned",
2327         reg_req   => { },
2328         emit      => '. fstp%XM %AM',
2329         mode      => "mode_M",
2330         attr_type => "ia32_x87_attr_t",
2331         latency   => 2,
2332 },
2333
2334 # Conversions
2335
2336 fild => {
2337         state     => "exc_pinned",
2338         rd_constructor => "NONE",
2339         reg_req   => { },
2340         emit      => '. fild%M %AM',
2341         attr_type => "ia32_x87_attr_t",
2342         latency   => 2,
2343 },
2344
2345 fist => {
2346         state     => "exc_pinned",
2347         rd_constructor => "NONE",
2348         reg_req   => { },
2349         emit      => '. fist%M %AM',
2350         mode      => "mode_M",
2351         attr_type => "ia32_x87_attr_t",
2352         latency   => 2,
2353 },
2354
2355 fistp => {
2356         state     => "exc_pinned",
2357         rd_constructor => "NONE",
2358         reg_req   => { },
2359         emit      => '. fistp%M %AM',
2360         mode      => "mode_M",
2361         attr_type => "ia32_x87_attr_t",
2362         latency   => 2,
2363 },
2364
2365 # SSE3 firsttp instruction
2366 fisttp => {
2367         state     => "exc_pinned",
2368         rd_constructor => "NONE",
2369         reg_req   => { },
2370         emit      => '. fisttp%M %AM',
2371         mode      => "mode_M",
2372         attr_type => "ia32_x87_attr_t",
2373         latency   => 2,
2374 },
2375
2376 # constants
2377
2378 fldz => {
2379         op_flags  => "R|c|K",
2380         irn_flags => "R",
2381         reg_req   => { out => [ "vfp" ] },
2382         emit      => '. fldz',
2383         attr_type => "ia32_x87_attr_t",
2384         latency   => 2,
2385 },
2386
2387 fld1 => {
2388         op_flags  => "R|c|K",
2389         irn_flags => "R",
2390         reg_req   => { out => [ "vfp" ] },
2391         emit      => '. fld1',
2392         attr_type => "ia32_x87_attr_t",
2393         latency   => 2,
2394 },
2395
2396 fldpi => {
2397         op_flags  => "R|c|K",
2398         irn_flags => "R",
2399         reg_req   => { out => [ "vfp" ] },
2400         emit      => '. fldpi',
2401         attr_type => "ia32_x87_attr_t",
2402         latency   => 2,
2403 },
2404
2405 fldln2 => {
2406         op_flags  => "R|c|K",
2407         irn_flags => "R",
2408         reg_req   => { out => [ "vfp" ] },
2409         emit      => '. fldln2',
2410         attr_type => "ia32_x87_attr_t",
2411         latency   => 2,
2412 },
2413
2414 fldlg2 => {
2415         op_flags  => "R|c|K",
2416         irn_flags => "R",
2417         reg_req   => { out => [ "vfp" ] },
2418         emit      => '. fldlg2',
2419         attr_type => "ia32_x87_attr_t",
2420         latency   => 2,
2421 },
2422
2423 fldl2t => {
2424         op_flags  => "R|c|K",
2425         irn_flags => "R",
2426         reg_req   => { out => [ "vfp" ] },
2427         emit      => '. fldll2t',
2428         attr_type => "ia32_x87_attr_t",
2429         latency   => 2,
2430 },
2431
2432 fldl2e => {
2433         op_flags  => "R|c|K",
2434         irn_flags => "R",
2435         reg_req   => { out => [ "vfp" ] },
2436         emit      => '. fldl2e',
2437         attr_type => "ia32_x87_attr_t",
2438         latency   => 2,
2439 },
2440
2441 # fxch, fpush, fpop
2442 # Note that it is NEVER allowed to do CSE on these nodes
2443 # Moreover, note the virtual register requierements!
2444
2445 fxch => {
2446         op_flags  => "R|K",
2447         reg_req   => { },
2448         cmp_attr  => "return 1;",
2449         emit      => '. fxch %X0',
2450         attr_type => "ia32_x87_attr_t",
2451         mode      => "mode_ANY",
2452         latency   => 1,
2453 },
2454
2455 fpush => {
2456         op_flags  => "R|K",
2457         reg_req   => {},
2458         cmp_attr  => "return 1;",
2459         emit      => '. fld %X0',
2460         attr_type => "ia32_x87_attr_t",
2461         mode      => "mode_ANY",
2462         latency   => 1,
2463 },
2464
2465 fpushCopy => {
2466         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
2467         cmp_attr  => "return 1;",
2468         emit      => '. fld %X0',
2469         attr_type => "ia32_x87_attr_t",
2470         latency   => 1,
2471 },
2472
2473 fpop => {
2474         op_flags  => "K",
2475         reg_req   => { },
2476         cmp_attr  => "return 1;",
2477         emit      => '. fstp %X0',
2478         attr_type => "ia32_x87_attr_t",
2479         mode      => "mode_ANY",
2480         latency   => 1,
2481 },
2482
2483 ffreep => {
2484         op_flags  => "K",
2485         reg_req   => { },
2486         cmp_attr  => "return 1;",
2487         emit      => '. ffreep %X0',
2488         attr_type => "ia32_x87_attr_t",
2489         mode      => "mode_ANY",
2490         latency   => 1,
2491 },
2492
2493 emms => {
2494         op_flags  => "K",
2495         reg_req   => { },
2496         cmp_attr  => "return 1;",
2497         emit      => '. emms',
2498         attr_type => "ia32_x87_attr_t",
2499         mode      => "mode_ANY",
2500         latency   => 3,
2501 },
2502
2503 femms => {
2504         op_flags  => "K",
2505         reg_req   => { },
2506         cmp_attr  => "return 1;",
2507         emit      => '. femms',
2508         attr_type => "ia32_x87_attr_t",
2509         mode      => "mode_ANY",
2510         latency   => 3,
2511 },
2512
2513 # compare
2514
2515 FucomFnstsw => {
2516         reg_req   => { },
2517         emit      => ". fucom %X1\n".
2518                      ". fnstsw %%ax",
2519         attr_type => "ia32_x87_attr_t",
2520         latency   => 2,
2521 },
2522
2523 FucompFnstsw => {
2524         reg_req   => { },
2525         emit      => ". fucomp %X1\n".
2526                      ". fnstsw %%ax",
2527         attr_type => "ia32_x87_attr_t",
2528         latency   => 2,
2529 },
2530
2531 FucomppFnstsw => {
2532         reg_req   => { },
2533         emit      => ". fucompp\n".
2534                      ". fnstsw %%ax",
2535         attr_type => "ia32_x87_attr_t",
2536         latency   => 2,
2537 },
2538
2539 Fucomi => {
2540         reg_req   => { },
2541         emit      => '. fucomi %X1',
2542         attr_type => "ia32_x87_attr_t",
2543         latency   => 1,
2544 },
2545
2546 Fucompi => {
2547         reg_req   => { },
2548         emit      => '. fucompi %X1',
2549         attr_type => "ia32_x87_attr_t",
2550         latency   => 1,
2551 },
2552
2553 FtstFnstsw => {
2554         reg_req   => { },
2555         emit      => ". ftst\n".
2556                      ". fnstsw %%ax",
2557         attr_type => "ia32_x87_attr_t",
2558         latency   => 2,
2559 },
2560
2561
2562 # -------------------------------------------------------------------------------- #
2563 #  ____ ____  _____                  _                               _             #
2564 # / ___/ ___|| ____| __   _____  ___| |_ ___  _ __   _ __   ___   __| | ___  ___   #
2565 # \___ \___ \|  _|   \ \ / / _ \/ __| __/ _ \| '__| | '_ \ / _ \ / _` |/ _ \/ __|  #
2566 #  ___) |__) | |___   \ V /  __/ (__| || (_) | |    | | | | (_) | (_| |  __/\__ \  #
2567 # |____/____/|_____|   \_/ \___|\___|\__\___/|_|    |_| |_|\___/ \__,_|\___||___/  #
2568 #                                                                                  #
2569 # -------------------------------------------------------------------------------- #
2570
2571
2572 # Spilling and reloading of SSE registers, hardcoded, not generated #
2573
2574 xxLoad => {
2575         op_flags  => "L|F",
2576         state     => "exc_pinned",
2577         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none" ] },
2578         emit      => '. movdqu %D0, %AM',
2579         outs      => [ "res", "M" ],
2580         units     => [ "SSE" ],
2581         latency   => 1,
2582 },
2583
2584 xxStore => {
2585         op_flags => "L|F",
2586         state    => "exc_pinned",
2587         reg_req  => { in => [ "gp", "gp", "none", "xmm" ] },
2588         ins      => [ "base", "index", "mem", "val" ],
2589         emit     => '. movdqu %binop',
2590         units    => [ "SSE" ],
2591         latency   => 1,
2592         mode     => "mode_M",
2593 },
2594
2595 ); # end of %nodes
2596
2597 # Include the generated SIMD node specification written by the SIMD optimization
2598 $my_script_name = dirname($myname) . "/../ia32/ia32_simd_spec.pl";
2599 unless ($return = do $my_script_name) {
2600         warn "couldn't parse $my_script_name: $@" if $@;
2601         warn "couldn't do $my_script_name: $!"    unless defined $return;
2602         warn "couldn't run $my_script_name"       unless $return;
2603 }
2604
2605 # Transform some attributes
2606 foreach my $op (keys(%nodes)) {
2607         my $node         = $nodes{$op};
2608         my $op_attr_init = $node->{op_attr_init};
2609
2610         if(defined($op_attr_init)) {
2611                 $op_attr_init .= "\n\t";
2612         } else {
2613                 $op_attr_init = "";
2614         }
2615
2616         if(!defined($node->{latency})) {
2617                 if($op =~ m/^l_/) {
2618                         $node->{latency} = 0;
2619                 } else {
2620                         die("Latency missing for op $op");
2621                 }
2622         }
2623         $op_attr_init .= "attr->latency = ".$node->{latency} . ";";
2624
2625         $node->{op_attr_init} = $op_attr_init;
2626 }
2627
2628 print "";