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