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