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