disable experimental code for now
[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 # },
37 #
38 # ... # (all nodes you need to describe)
39 #
40 # ); # close the %nodes initializer
41
42 # op_flags: flags for the operation, OPTIONAL (default is "N")
43 # the op_flags correspond to the firm irop_flags:
44 #   N   irop_flag_none
45 #   L   irop_flag_labeled
46 #   C   irop_flag_commutative
47 #   X   irop_flag_cfopcode
48 #   I   irop_flag_ip_cfopcode
49 #   F   irop_flag_fragile
50 #   Y   irop_flag_forking
51 #   H   irop_flag_highlevel
52 #   c   irop_flag_constlike
53 #   K   irop_flag_keep
54 #
55 # irn_flags: special node flags, OPTIONAL (default is 0)
56 # following irn_flags are supported:
57 #   R   rematerializeable
58 #   N   not spillable
59 #   I   ignore for register allocation
60 #   S   modifies stack pointer
61 #
62 # state: state of the operation, OPTIONAL (default is "floats")
63 #
64 # arity: arity of the operation, MUST NOT BE OMITTED
65 #
66 # args:  the OPTIONAL arguments of the node constructor (debug, irg and block
67 #        are always the first 3 arguments and are always autmatically
68 #        created)
69 #        If this key is missing the following arguments will be created:
70 #        for i = 1 .. arity: ir_node *op_i
71 #        ir_mode *mode
72 #
73 # outs:  if a node defines more than one output, the names of the projections
74 #        nodes having outs having automatically the mode mode_T
75 #        One can also annotate some flags for each out, additional to irn_flags.
76 #        They are separated from name with a colon ':', and concatenated by pipe '|'
77 #        Only I and S are available at the moment (same meaning as in irn_flags).
78 #        example: [ "frame:I", "stack:I|S", "M" ]
79 #
80 # comment: OPTIONAL comment for the node constructor
81 #
82 # rd_constructor: for every operation there will be a
83 #      new_rd_<arch>_<op-name> function with the arguments from above
84 #      which creates the ir_node corresponding to the defined operation
85 #      you can either put the complete source code of this function here
86 #
87 #      This key is OPTIONAL. If omitted, the following constructor will
88 #      be created:
89 #      if (!op_<arch>_<op-name>) assert(0);
90 #      for i = 1 to arity
91 #         set in[i] = op_i
92 #      done
93 #      res = new_ir_node(db, irg, block, op_<arch>_<op-name>, mode, arity, in)
94 #      return res
95 #
96 # NOTE: rd_constructor and args are only optional if and only if arity is 0,1,2 or 3
97 #
98 # latency: the latency of the operation, default is 1
99 #
100
101 # register types:
102 #   0 - no special type
103 #   1 - caller save (register must be saved by the caller of a function)
104 #   2 - callee save (register must be saved by the called function)
105 #   4 - ignore (do not assign this register)
106 #   8 - emitter can choose an arbitrary register of this class
107 #  16 - the register is a virtual one
108 #  32 - register represents a state
109 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
110 %reg_classes = (
111         gp => [
112                 { name => "eax", type => 1 },
113                 { name => "edx", type => 1 },
114                 { name => "ebx", type => 2 },
115                 { name => "ecx", type => 1 },
116                 { name => "esi", type => 2 },
117                 { name => "edi", type => 2 },
118                 { name => "ebp", type => 2 },
119                 { name => "esp", type => 4 },
120                 { name => "gp_NOREG", type => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes
121                 { name => "gp_UKNWN", type => 4 | 8 | 16 },  # we need a dummy register for Unknown nodes
122                 { mode => "mode_Iu" }
123         ],
124         xmm => [
125                 { name => "xmm0", type => 1 },
126                 { name => "xmm1", type => 1 },
127                 { name => "xmm2", type => 1 },
128                 { name => "xmm3", type => 1 },
129                 { name => "xmm4", type => 1 },
130                 { name => "xmm5", type => 1 },
131                 { name => "xmm6", type => 1 },
132                 { name => "xmm7", type => 1 },
133                 { name => "xmm_NOREG", type => 4 | 16 },     # we need a dummy register for NoReg nodes
134                 { name => "xmm_UKNWN", type => 4 | 8 | 16},  # we need a dummy register for Unknown nodes
135                 { mode => "mode_E" }
136         ],
137         vfp => [
138                 { name => "vf0", type => 1 | 16 },
139                 { name => "vf1", type => 1 | 16 },
140                 { name => "vf2", type => 1 | 16 },
141                 { name => "vf3", type => 1 | 16 },
142                 { name => "vf4", type => 1 | 16 },
143                 { name => "vf5", type => 1 | 16 },
144                 { name => "vf6", type => 1 | 16 },
145                 { name => "vf7", type => 1 | 16 },
146                 { name => "vfp_NOREG", type => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes
147                 { name => "vfp_UKNWN", type => 4 | 8 | 16 },  # we need a dummy register for Unknown nodes
148                 { mode => "mode_E" }
149         ],
150         st => [
151                 { name => "st0", type => 1 },
152                 { name => "st1", type => 1 },
153                 { name => "st2", type => 1 },
154                 { name => "st3", type => 1 },
155                 { name => "st4", type => 1 },
156                 { name => "st5", type => 1 },
157                 { name => "st6", type => 1 },
158                 { name => "st7", type => 1 },
159                 { mode => "mode_E" }
160         ],
161         fp_cw => [      # the floating point control word
162                 { name => "fpcw", type => 32 },
163                 { mode => "mode_Hu" },
164         ],
165
166 ); # %reg_classes
167
168 %cpu = (
169         GP     => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
170         SSE    => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
171         VFP    => [ 1, "VFP_VF0", "VFP_VF1", "VFP_VF2", "VFP_VF3", "VFP_VF4", "VFP_VF5", "VFP_VF6", "VFP_VF7" ],
172         BRANCH => [ 1, "BRANCH1", "BRANCH2" ],
173 ); # %cpu
174
175 %vliw = (
176         bundle_size       => 1,
177         bundels_per_cycle => 1
178 ); # vliw
179
180 %emit_templates = (
181         S1 => "${arch}_emit_source_register(env, node, 0);",
182         S2 => "${arch}_emit_source_register(env, node, 1);",
183         S3 => "${arch}_emit_source_register(env, node, 2);",
184         S4 => "${arch}_emit_source_register(env, node, 3);",
185         S5 => "${arch}_emit_source_register(env, node, 4);",
186         S6 => "${arch}_emit_source_register(env, node, 5);",
187         D1 => "${arch}_emit_dest_register(env, node, 0);",
188         D2 => "${arch}_emit_dest_register(env, node, 1);",
189         D3 => "${arch}_emit_dest_register(env, node, 2);",
190         D4 => "${arch}_emit_dest_register(env, node, 3);",
191         D5 => "${arch}_emit_dest_register(env, node, 4);",
192         D6 => "${arch}_emit_dest_register(env, node, 5);",
193         A1 => "${arch}_emit_in_node_name(env, node, 0);",
194         A2 => "${arch}_emit_in_node_name(env, node, 1);",
195         A3 => "${arch}_emit_in_node_name(env, node, 2);",
196         A4 => "${arch}_emit_in_node_name(env, node, 3);",
197         A5 => "${arch}_emit_in_node_name(env, node, 4);",
198         A6 => "${arch}_emit_in_node_name(env, node, 5);",
199         X1 => "${arch}_emit_x87_name(env, node, 0);",
200         X2 => "${arch}_emit_x87_name(env, node, 1);",
201         X3 => "${arch}_emit_x87_name(env, node, 2);",
202         C  => "${arch}_emit_immediate(env, node);",
203         SE => "${arch}_emit_extend_suffix(env, get_ia32_ls_mode(node));",
204         ME => "if(get_mode_size_bits(get_ia32_ls_mode(node)) != 32)\n
205         ia32_emit_mode_suffix(env, get_ia32_ls_mode(node));",
206         M  => "${arch}_emit_mode_suffix(env, get_ia32_ls_mode(node));",
207         XM => "${arch}_emit_x87_mode_suffix(env, node);",
208         XXM => "${arch}_emit_xmm_mode_suffix(env, node);",
209         XSD => "${arch}_emit_xmm_mode_suffix_s(env, node);",
210         AM => "${arch}_emit_am(env, node);",
211         unop => "${arch}_emit_unop(env, node);",
212         binop => "${arch}_emit_binop(env, node);",
213         x87_binop => "${arch}_emit_x87_binop(env, node);",
214 );
215
216 #--------------------------------------------------#
217 #                        _                         #
218 #                       (_)                        #
219 #  _ __   _____      __  _ _ __    ___  _ __  ___  #
220 # | '_ \ / _ \ \ /\ / / | | '__|  / _ \| '_ \/ __| #
221 # | | | |  __/\ V  V /  | | |    | (_) | |_) \__ \ #
222 # |_| |_|\___| \_/\_/   |_|_|     \___/| .__/|___/ #
223 #                                      | |         #
224 #                                      |_|         #
225 #--------------------------------------------------#
226
227 $default_cmp_attr = "return ia32_compare_attr(attr_a, attr_b);";
228
229 %operands = (
230 );
231
232 %nodes = (
233
234 #-----------------------------------------------------------------#
235 #  _       _                                         _            #
236 # (_)     | |                                       | |           #
237 #  _ _ __ | |_ ___  __ _  ___ _ __   _ __   ___   __| | ___  ___  #
238 # | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| #
239 # | | | | | ||  __/ (_| |  __/ |    | | | | (_) | (_| |  __/\__ \ #
240 # |_|_| |_|\__\___|\__, |\___|_|    |_| |_|\___/ \__,_|\___||___/ #
241 #                   __/ |                                         #
242 #                  |___/                                          #
243 #-----------------------------------------------------------------#
244
245 # commutative operations
246
247 # NOTE:
248 # All nodes supporting Addressmode have 5 INs:
249 # 1 - base    r1 == NoReg in case of no AM or no base
250 # 2 - index   r2 == NoReg in case of no AM or no index
251 # 3 - op1     r3 == always present
252 # 4 - op2     r4 == NoReg in case of immediate operation
253 # 5 - mem     NoMem in case of no AM otherwise it takes the mem from the Load
254
255 Add => {
256         irn_flags => "R",
257         comment   => "construct Add: Add(a, b) = Add(b, a) = a + b",
258         reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
259         emit      => '. addl %binop',
260         units     => [ "GP" ],
261         mode      => "mode_Iu",
262 },
263
264 Adc => {
265         comment   => "construct Add with Carry: Adc(a, b) = Add(b, a) = a + b + carry",
266         reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
267         emit      => '. adcl %binop',
268         units     => [ "GP" ],
269         mode      => "mode_Iu",
270 },
271
272 Add64Bit => {
273         irn_flags => "R",
274         comment   => "construct 64Bit Add: Add(a_l, a_h, b_l, b_h) = a_l + b_l; a_h + b_h + carry",
275         arity     => 4,
276         reg_req   => { in => [ "gp", "gp", "gp", "gp" ], out => [ "!in", "!in" ] },
277         emit      => '
278 . movl %S1, %D1
279 . movl %S2, %D2
280 . addl %S3, %D1
281 . adcl %S4, %D2
282 ',
283         outs      => [ "low_res", "high_res" ],
284         units     => [ "GP" ],
285 },
286
287 l_Add => {
288         op_flags  => "C",
289         irn_flags => "R",
290         cmp_attr  => "return 1;",
291         comment   => "construct lowered Add: Add(a, b) = Add(b, a) = a + b",
292         arity     => 2,
293 },
294
295 l_Adc => {
296         op_flags  => "C",
297         cmp_attr  => "return 1;",
298         comment   => "construct lowered Add with Carry: Adc(a, b) = Adc(b, a) = a + b + carry",
299         arity     => 2,
300 },
301
302 Mul => {
303         # we should not rematrialize this node. It produces 2 results and has
304         # very strict constrains
305         comment   => "construct MulS: MulS(a, b) = MulS(b, a) = a * b",
306         reg_req   => { in => [ "gp", "gp", "eax", "gp", "none" ], out => [ "eax", "edx", "none" ] },
307         emit      => '. mull %unop',
308         outs      => [ "EAX", "EDX", "M" ],
309         latency   => 10,
310         units     => [ "GP" ],
311 },
312
313 l_Mul => {
314         # we should not rematrialize this node. It produces 2 results and has
315         # very strict constrains
316         op_flags  => "C",
317         cmp_attr  => "return 1;",
318         comment   => "construct lowered MulS: Mul(a, b) = Mul(b, a) = a * b",
319         outs      => [ "EAX", "EDX", "M" ],
320         arity     => 2
321 },
322
323 IMul => {
324         irn_flags => "R",
325         comment   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
326         reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
327         emit      => '. imull %binop',
328         latency   => 5,
329         units     => [ "GP" ],
330         mode      => "mode_Iu",
331 },
332
333 IMul1OP => {
334         irn_flags => "R",
335         comment   => "construct Mul (1 operand format): Mul(a, b) = Mul(b, a) = a * b",
336         reg_req   => { in => [ "gp", "gp", "eax", "gp", "none" ], out => [ "eax", "edx", "none" ] },
337         emit      => '. imull %unop',
338         outs      => [ "EAX", "EDX", "M" ],
339         latency   => 5,
340         units     => [ "GP" ],
341 },
342
343 l_IMul => {
344         op_flags  => "C",
345         cmp_attr  => "return 1;",
346         comment   => "construct lowered IMul: IMul(a, b) = IMul(b, a) = a * b",
347         arity     => 2
348 },
349
350 And => {
351         irn_flags => "R",
352         comment   => "construct And: And(a, b) = And(b, a) = a AND b",
353         reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
354         emit      => '. andl %binop',
355         units     => [ "GP" ],
356         mode      => "mode_Iu",
357 },
358
359 Or => {
360         irn_flags => "R",
361         comment   => "construct Or: Or(a, b) = Or(b, a) = a OR b",
362         reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
363         emit      => '. orl %binop',
364         units     => [ "GP" ],
365         mode      => "mode_Iu",
366 },
367
368 Xor => {
369         irn_flags => "R",
370         comment   => "construct Xor: Xor(a, b) = Xor(b, a) = a EOR b",
371         reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
372         emit      => '. xorl %binop',
373         units     => [ "GP" ],
374         mode      => "mode_Iu",
375 },
376
377 l_Xor => {
378         op_flags  => "C",
379         cmp_attr  => "return 1;",
380         comment   => "construct lowered Xor: Xor(a, b) = Xor(b, a) = a XOR b",
381         arity     => 2
382 },
383
384 # not commutative operations
385
386 Sub => {
387         irn_flags => "R",
388         comment   => "construct Sub: Sub(a, b) = a - b",
389         reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
390         emit      => '. subl %binop',
391         units     => [ "GP" ],
392         mode      => "mode_Iu",
393 },
394
395 Sbb => {
396         comment   => "construct Sub with Carry: SubC(a, b) = a - b - carry",
397         reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3 !in_r4" ] },
398         emit      => '. sbbl %binop',
399         units     => [ "GP" ],
400         mode      => "mode_Iu",
401 },
402
403 Sub64Bit => {
404         irn_flags => "R",
405         comment   => "construct 64Bit Sub: Sub(a_l, a_h, b_l, b_h) = a_l - b_l; a_h - b_h - borrow",
406         arity     => 4,
407         reg_req   => { in => [ "gp", "gp", "gp", "gp" ], out => [ "!in", "!in" ] },
408         emit      => '
409 . movl %S1, %D1
410 . movl %S2, %D2
411 . subl %S3, %D1
412 . sbbl %S4, %D2
413 ',
414         outs      => [ "low_res", "high_res" ],
415         units     => [ "GP" ],
416 },
417
418 l_Sub => {
419         irn_flags => "R",
420         cmp_attr  => "return 1;",
421         comment   => "construct lowered Sub: Sub(a, b) = a - b",
422         arity     => 2,
423 },
424
425 l_Sbb => {
426         cmp_attr  => "return 1;",
427         comment   => "construct lowered Sub with Carry: SubC(a, b) = a - b - carry",
428         arity     => 2,
429 },
430
431 IDiv => {
432         op_flags  => "F|L",
433         state     => "exc_pinned",
434         reg_req   => { in => [ "gp", "gp", "eax", "edx", "gp", "none" ], out => [ "eax", "edx", "none" ] },
435         attr      => "ia32_op_flavour_t dm_flav",
436         init_attr => "attr->data.op_flav = dm_flav;",
437         emit      => ". idivl %unop",
438         outs      => [ "div_res", "mod_res", "M" ],
439         latency   => 25,
440         units     => [ "GP" ],
441 },
442
443 Div => {
444         op_flags  => "F|L",
445         state     => "exc_pinned",
446         reg_req   => { in => [ "gp", "gp", "eax", "edx", "gp", "none" ], out => [ "eax", "edx", "none" ] },
447         attr      => "ia32_op_flavour_t dm_flav",
448         init_attr => "attr->data.op_flav = dm_flav;",
449         emit      => ". divl %unop",
450         outs      => [ "div_res", "mod_res", "M" ],
451         latency   => 25,
452         units     => [ "GP" ],
453 },
454
455 Shl => {
456         irn_flags => "R",
457         comment   => "construct Shl: Shl(a, b) = a << b",
458         reg_req   => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] },
459         emit      => '. shll %binop',
460         units     => [ "GP" ],
461         mode      => "mode_Iu",
462 },
463
464 l_Shl => {
465         cmp_attr  => "return 1;",
466         comment   => "construct lowered Shl: Shl(a, b) = a << b",
467         arity     => 2
468 },
469
470 ShlD => {
471         irn_flags => "R",
472         comment   => "construct ShlD: ShlD(a, b, c) = a, b << count (shift left count bits from b into a)",
473         # Out requirements is: different from all in
474         # This is because, out must be different from LowPart and ShiftCount.
475         # We could say "!ecx !in_r4" but it can occur, that all values live through
476         # this Shift and the only value dying is the ShiftCount. Then there would be a
477         # register missing, as result must not be ecx and all other registers are
478         # occupied. What we should write is "!in_r4 !in_r5", but this is not supported
479         # (and probably never will). So we create artificial interferences of the result
480         # with all inputs, so the spiller can always assure a free register.
481         reg_req   => { in => [ "gp", "gp", "gp", "gp", "ecx", "none" ], out => [ "!in" ] },
482         emit      =>
483 '
484 if (get_ia32_immop_type(node) == ia32_ImmNone) {
485         if (get_ia32_op_type(node) == ia32_AddrModeD) {
486                 . shldl %%cl, %S4, %AM
487         } else {
488                 . shldl %%cl, %S4, %S3
489         }
490 } else {
491         if (get_ia32_op_type(node) == ia32_AddrModeD) {
492                 . shldl $%C, %S4, %AM
493         } else {
494                 . shldl $%C, %S4, %S3
495         }
496 }
497 ',
498         latency   => 6,
499         units     => [ "GP" ],
500         mode      => "mode_Iu",
501 },
502
503 l_ShlD => {
504         cmp_attr  => "return 1;",
505         comment   => "construct lowered ShlD: ShlD(a, b, c) = a, b << count (shift left count bits from b into a)",
506         arity     => 3,
507 },
508
509 Shr => {
510         irn_flags => "R",
511         comment   => "construct Shr: Shr(a, b) = a >> b",
512         reg_req   => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] },
513         emit      => '. shrl %binop',
514         units     => [ "GP" ],
515         mode      => "mode_Iu",
516 },
517
518 l_Shr => {
519         cmp_attr  => "return 1;",
520         comment   => "construct lowered Shr: Shr(a, b) = a << b",
521         arity     => 2
522 },
523
524 ShrD => {
525         irn_flags => "R",
526         comment   => "construct ShrD: ShrD(a, b, c) = a, b >> count (shift rigth count bits from a into b)",
527         # Out requirements is: different from all in
528         # This is because, out must be different from LowPart and ShiftCount.
529         # We could say "!ecx !in_r4" but it can occur, that all values live through
530         # this Shift and the only value dying is the ShiftCount. Then there would be a
531         # register missing, as result must not be ecx and all other registers are
532         # occupied. What we should write is "!in_r4 !in_r5", but this is not supported
533         # (and probably never will). So we create artificial interferences of the result
534         # with all inputs, so the spiller can always assure a free register.
535         reg_req   => { in => [ "gp", "gp", "gp", "gp", "ecx", "none" ], out => [ "!in" ] },
536         emit      => '
537 if (get_ia32_immop_type(node) == ia32_ImmNone) {
538         if (get_ia32_op_type(node) == ia32_AddrModeD) {
539                 . shrdl %%cl, %S4, %AM
540         } else {
541                 . shrdl %%cl, %S4, %S3
542         }
543 } else {
544         if (get_ia32_op_type(node) == ia32_AddrModeD) {
545                 . shrdl $%C, %S4, %AM
546         } else {
547                 . shrdl $%C, %S4, %S3
548         }
549 }
550 ',
551         latency   => 6,
552         units     => [ "GP" ],
553         mode      => "mode_Iu",
554 },
555
556 l_ShrD => {
557         cmp_attr  => "return 1;",
558         comment   => "construct lowered ShrD: ShrD(a, b, c) = a, b >> count (shift rigth count bits from a into b)",
559         arity     => 3
560 },
561
562 Sar => {
563         irn_flags => "R",
564         comment   => "construct Shrs: Shrs(a, b) = a >> b",
565         reg_req   => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] },
566         emit      => '. sarl %binop',
567         units     => [ "GP" ],
568         mode      => "mode_Iu",
569 },
570
571 l_Sar => {
572         cmp_attr  => "return 1;",
573         comment   => "construct lowered Sar: Sar(a, b) = a << b",
574         arity     => 2
575 },
576
577 Ror => {
578         irn_flags => "R",
579         comment   => "construct Ror: Ror(a, b) = a ROR b",
580         reg_req   => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] },
581         emit      => '. rorl %binop',
582         units     => [ "GP" ],
583         mode      => "mode_Iu",
584 },
585
586 Rol => {
587         irn_flags => "R",
588         comment   => "construct Rol: Rol(a, b) = a ROL b",
589         reg_req   => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] },
590         emit      => '. roll %binop',
591         units     => [ "GP" ],
592         mode      => "mode_Iu",
593 },
594
595 # unary operations
596
597 Neg => {
598         irn_flags => "R",
599         comment   => "construct Minus: Minus(a) = -a",
600         reg_req   => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
601         emit      => '. negl %unop',
602         units     => [ "GP" ],
603         mode      => "mode_Iu",
604 },
605
606 Minus64Bit => {
607         irn_flags => "R",
608         comment   => "construct 64Bit Minus: Minus(a_l, a_h, 0) = 0 - a_l; 0 - a_h - borrow",
609         arity     => 4,
610         reg_req   => { in => [ "gp", "gp", "gp" ], out => [ "!in", "!in" ] },
611         emit      => '
612 . movl %S1, %D1
613 . movl %S1, %D2
614 . subl %S2, %D1
615 . sbbl %S3, %D2
616 ',
617         outs      => [ "low_res", "high_res" ],
618         units     => [ "GP" ],
619 },
620
621
622 l_Neg => {
623         cmp_attr  => "return 1;",
624         comment   => "construct lowered Minus: Minus(a) = -a",
625         arity     => 1,
626 },
627
628 Inc => {
629         irn_flags => "R",
630         comment   => "construct Increment: Inc(a) = a++",
631         reg_req   => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
632         emit      => '. incl %unop',
633         units     => [ "GP" ],
634         mode      => "mode_Iu",
635 },
636
637 Dec => {
638         irn_flags => "R",
639         comment   => "construct Decrement: Dec(a) = a--",
640         reg_req   => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
641         emit      => '. decl %unop',
642         units     => [ "GP" ],
643         mode      => "mode_Iu",
644 },
645
646 Not => {
647         irn_flags => "R",
648         comment   => "construct Not: Not(a) = !a",
649         reg_req   => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
650         emit      => '. notl %unop',
651         units     => [ "GP" ],
652         mode      => "mode_Iu",
653 },
654
655 # other operations
656
657 CondJmp => {
658         state     => "pinned",
659         op_flags  => "L|X|Y",
660         comment   => "construct conditional jump: CMP A, B && JMPxx LABEL",
661         reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ] },
662         outs      => [ "false", "true" ],
663         latency   => 3,
664         units     => [ "BRANCH" ],
665 },
666
667 TestJmp => {
668         state     => "pinned",
669         op_flags  => "L|X|Y",
670         comment   => "construct conditional jump: TEST A, B && JMPxx LABEL",
671         reg_req  => { in => [ "gp", "gp" ] },
672         outs      => [ "false", "true" ],
673         latency   => 3,
674         units     => [ "BRANCH" ],
675 },
676
677 CJmpAM => {
678         state     => "pinned",
679         op_flags  => "L|X|Y",
680         comment   => "construct conditional jump without CMP (replaces CondJmp): JMPxx LABEL",
681         reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "none", "none" ] },
682         outs      => [ "false", "true" ],
683         units     => [ "BRANCH" ],
684 },
685
686 CJmp => {
687         state     => "pinned",
688         op_flags  => "L|X|Y",
689         comment   => "construct conditional jump without CMP (replaces TestJmp): JMPxx LABEL",
690         reg_req   => { in => [ "gp", "gp" ] },
691         units     => [ "BRANCH" ],
692 },
693
694 SwitchJmp => {
695         state     => "pinned",
696         op_flags  => "L|X|Y",
697         comment   => "construct switch",
698         reg_req   => { in => [ "gp" ], out => [ "none" ] },
699         latency   => 3,
700         units     => [ "BRANCH" ],
701 },
702
703 Const => {
704         op_flags  => "c",
705         irn_flags => "R",
706         comment   => "represents an integer constant",
707         reg_req   => { out => [ "gp" ] },
708         units     => [ "GP" ],
709         mode      => "mode_Iu",
710 },
711
712 Unknown_GP => {
713         op_flags  => "c",
714         irn_flags => "I",
715         comment   => "unknown value",
716         reg_req   => { out => [ "gp_UKNWN" ] },
717         units     => [],
718         emit      => "",
719         mode      => "mode_Iu"
720 },
721
722 Unknown_VFP => {
723         op_flags  => "c",
724         irn_flags => "I",
725         comment   => "unknown value",
726         reg_req   => { out => [ "vfp_UKNWN" ] },
727         units     => [],
728         emit      => "",
729         mode      => "mode_E"
730 },
731
732 Unknown_XMM => {
733         op_flags  => "c",
734         irn_flags => "I",
735         comment   => "unknown value",
736         reg_req   => { out => [ "xmm_UKNWN" ] },
737         units     => [],
738         emit      => "",
739         mode      => "mode_E"
740 },
741
742 NoReg_GP => {
743         op_flags  => "c",
744         irn_flags => "I",
745         comment   => "unknown GP value",
746         reg_req   => { out => [ "gp_NOREG" ] },
747         units     => [],
748         emit      => "",
749         mode      => "mode_Iu"
750 },
751
752 NoReg_VFP => {
753         op_flags  => "c",
754         irn_flags => "I",
755         comment   => "unknown VFP value",
756         reg_req   => { out => [ "vfp_NOREG" ] },
757         units     => [],
758         emit      => "",
759         mode      => "mode_E"
760 },
761
762 NoReg_XMM => {
763         op_flags  => "c",
764         irn_flags => "I",
765         comment   => "unknown XMM value",
766         reg_req   => { out => [ "xmm_NOREG" ] },
767         units     => [],
768         emit      => "",
769         mode      => "mode_E"
770 },
771
772 ChangeCW => {
773         irn_flags => "R",
774         comment   => "change floating point control word",
775         reg_req   => { out => [ "fp_cw" ] },
776         mode      => "mode_Hu",
777         latency   => 3,
778         units     => [ "GP" ],
779 },
780
781 FldCW => {
782         op_flags  => "L|F",
783         state     => "exc_pinned",
784         comment   => "load floating point control word FldCW(ptr, mem) = LD ptr -> reg",
785         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "fp_cw" ] },
786         latency   => 5,
787         emit      => ". fldcw %AM",
788         mode      => "mode_Hu",
789         units     => [ "GP" ],
790 },
791
792 FstCW => {
793         op_flags  => "L|F",
794         state     => "exc_pinned",
795         comment   => "store floating point control word: FstCW(ptr, mem) = ST ptr -> reg",
796         reg_req   => { in => [ "gp", "gp", "fp_cw", "none" ] },
797         latency   => 5,
798         emit      => ". fstcw %AM",
799         mode      => "mode_M",
800         units     => [ "GP" ],
801 },
802
803 Cltd => {
804         # we should not rematrialize this node. It produces 2 results and has
805         # very strict constrains
806         comment   => "construct CDQ: sign extend EAX -> EDX:EAX",
807         reg_req   => { in => [ "gp" ], out => [ "eax in_r1", "edx" ] },
808         emit      => '. cltd',
809         outs      => [ "EAX", "EDX" ],
810         units     => [ "GP" ],
811 },
812
813 # Load / Store
814
815 Load => {
816         op_flags  => "L|F",
817         state     => "exc_pinned",
818         comment   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
819         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "gp", "none" ] },
820         latency   => 3,
821         emit      => ". mov%SE%ME%.l %AM, %D1",
822         outs      => [ "res", "M" ],
823         units     => [ "GP" ],
824 },
825
826 l_Load => {
827         op_flags  => "L|F",
828         cmp_attr  => "return 1;",
829         comment   => "construct lowered Load: Load(ptr, mem) = LD ptr -> reg",
830         outs      => [ "res", "M" ],
831         arity     => 2,
832 },
833
834 l_Store => {
835         op_flags  => "L|F",
836         cmp_attr  => "return 1;",
837         state     => "exc_pinned",
838         comment   => "construct lowered Store: Store(ptr, val, mem) = ST ptr,val",
839         arity     => 3,
840         mode      => "mode_M",
841 },
842
843 Store => {
844         op_flags  => "L|F",
845         state     => "exc_pinned",
846         comment   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
847         reg_req   => { in => [ "gp", "gp", "gp", "none" ], out => [ "none" ] },
848         emit      => '. mov%M %binop',
849         latency   => 3,
850         units     => [ "GP" ],
851         mode      => "mode_M",
852 },
853
854 Store8Bit => {
855         op_flags  => "L|F",
856         state     => "exc_pinned",
857         comment   => "construct 8Bit Store: Store(ptr, val, mem) = ST ptr,val",
858         reg_req   => { in => [ "gp", "gp", "eax ebx ecx edx", "none" ], out => ["none" ] },
859         emit      => '. mov%M %binop',
860         latency   => 3,
861         units     => [ "GP" ],
862         mode      => "mode_M",
863 },
864
865 Lea => {
866         irn_flags => "R",
867         comment   => "construct Lea: Lea(a,b) = lea [a+b*const+offs] | res = a + b * const + offs with const = 0,1,2,4,8",
868         reg_req   => { in => [ "gp", "gp" ], out => [ "in_r1" ] },
869         emit      => '. leal %AM, %D1',
870         latency   => 2,
871         units     => [ "GP" ],
872         mode      => "mode_Iu",
873 },
874
875 Push => {
876         comment   => "push on the stack",
877         reg_req   => { in => [ "gp", "gp", "gp", "esp", "none" ], out => [ "esp", "none" ] },
878         emit      => '. pushl %unop',
879         outs      => [ "stack:I|S", "M" ],
880         latency   => 3,
881         units     => [ "GP" ],
882 },
883
884 Pop => {
885         comment   => "pop a gp register from the stack",
886         reg_req   => { in => [ "gp", "gp", "esp", "none" ], out => [ "esp", "gp", "none" ] },
887         emit      => '. popl %unop',
888         outs      => [ "stack:I|S", "res", "M" ],
889         latency   => 4,
890         units     => [ "GP" ],
891 },
892
893 Enter => {
894         comment   => "create stack frame",
895         reg_req   => { in => [ "esp" ], out => [ "ebp", "esp" ] },
896         emit      => '. enter',
897         outs      => [ "frame:I", "stack:I|S", "M" ],
898         latency   => 15,
899         units     => [ "GP" ],
900 },
901
902 Leave => {
903         comment   => "destroy stack frame",
904         reg_req   => { in => [ "esp", "ebp" ], out => [ "ebp", "esp" ] },
905         emit      => '. leave',
906         outs      => [ "frame:I", "stack:I|S" ],
907         latency   => 3,
908         units     => [ "GP" ],
909 },
910
911 AddSP => {
912         irn_flags => "I",
913         comment   => "allocate space on stack",
914         reg_req   => { in => [ "gp", "gp", "esp", "gp", "none" ], out => [ "in_r3", "none" ] },
915         emit      => '. addl %binop',
916         outs      => [ "stack:S", "M" ],
917         units     => [ "GP" ],
918 },
919
920 SubSP => {
921         irn_flags => "I",
922         comment   => "free space on stack",
923         reg_req   => { in => [ "gp", "gp", "esp", "gp", "none" ], out => [ "in_r3", "none" ] },
924         emit      => '. subl %binop',
925         outs      => [ "stack:S", "M" ],
926         units     => [ "GP" ],
927 },
928
929 LdTls => {
930         irn_flags => "R",
931         comment   => "get the TLS base address",
932         reg_req   => { out => [ "gp" ] },
933         units     => [ "GP" ],
934 },
935
936
937
938 #-----------------------------------------------------------------------------#
939 #   _____ _____ ______    __ _             _                     _            #
940 #  / ____/ ____|  ____|  / _| |           | |                   | |           #
941 # | (___| (___ | |__    | |_| | ___   __ _| |_   _ __   ___   __| | ___  ___  #
942 #  \___ \\___ \|  __|   |  _| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
943 #  ____) |___) | |____  | | | | (_) | (_| | |_  | | | | (_) | (_| |  __/\__ \ #
944 # |_____/_____/|______| |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
945 #-----------------------------------------------------------------------------#
946
947 # commutative operations
948
949 xAdd => {
950         irn_flags => "R",
951         comment   => "construct SSE Add: Add(a, b) = Add(b, a) = a + b",
952         reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "in_r3" ] },
953         emit      => '. add%XXM %binop',
954         latency   => 4,
955         units     => [ "SSE" ],
956         mode      => "mode_E",
957 },
958
959 xMul => {
960         irn_flags => "R",
961         comment   => "construct SSE Mul: Mul(a, b) = Mul(b, a) = a * b",
962         reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "in_r3" ] },
963         emit      => '. mul%XXM %binop',
964         latency   => 4,
965         units     => [ "SSE" ],
966         mode      => "mode_E",
967 },
968
969 xMax => {
970         irn_flags => "R",
971         comment   => "construct SSE Max: Max(a, b) = Max(b, a) = a > b ? a : b",
972         reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "in_r3" ] },
973         emit      => '. max%XXM %binop',
974         latency   => 2,
975         units     => [ "SSE" ],
976         mode      => "mode_E",
977 },
978
979 xMin => {
980         irn_flags => "R",
981         comment   => "construct SSE Min: Min(a, b) = Min(b, a) = a < b ? a : b",
982         reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "in_r3" ] },
983         emit      => '. min%XXM %binop',
984         latency   => 2,
985         units     => [ "SSE" ],
986         mode      => "mode_E",
987 },
988
989 xAnd => {
990         irn_flags => "R",
991         comment   => "construct SSE And: And(a, b) = a AND b",
992         reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "in_r3" ] },
993         emit      => '. andp%XSD %binop',
994         latency   => 3,
995         units     => [ "SSE" ],
996         mode      => "mode_E",
997 },
998
999 xOr => {
1000         irn_flags => "R",
1001         comment   => "construct SSE Or: Or(a, b) = a OR b",
1002         reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "in_r3" ] },
1003         emit      => '. orp%XSD %binop',
1004         units     => [ "SSE" ],
1005         mode      => "mode_E",
1006 },
1007
1008 xXor => {
1009         irn_flags => "R",
1010         comment   => "construct SSE Xor: Xor(a, b) = a XOR b",
1011         reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "in_r3" ] },
1012         emit      => '. xorp%XSD %binop',
1013         latency   => 3,
1014         units     => [ "SSE" ],
1015         mode      => "mode_E",
1016 },
1017
1018 # not commutative operations
1019
1020 xAndNot => {
1021         irn_flags => "R",
1022         comment   => "construct SSE AndNot: AndNot(a, b) = a AND NOT b",
1023         reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "in_r3 !in_r4" ] },
1024         emit      => '. andnp%XSD %binop',
1025         latency   => 3,
1026         units     => [ "SSE" ],
1027         mode      => "mode_E",
1028 },
1029
1030 xSub => {
1031         irn_flags => "R",
1032         comment   => "construct SSE Sub: Sub(a, b) = a - b",
1033         reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "in_r3" ] },
1034         emit      => '. sub%XXM %binop',
1035         latency   => 4,
1036         units     => [ "SSE" ],
1037         mode      => "mode_E",
1038 },
1039
1040 xDiv => {
1041         irn_flags => "R",
1042         comment   => "construct SSE Div: Div(a, b) = a / b",
1043         reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "in_r3 !in_r4" ] },
1044         outs      => [ "res", "M" ],
1045         emit      => '. div%XXM %binop',
1046         latency   => 16,
1047         units     => [ "SSE" ],
1048 },
1049
1050 # other operations
1051
1052 xCmp => {
1053         irn_flags => "R",
1054         comment   => "construct SSE Compare: Cmp(a, b) == a = a cmp b",
1055         reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "in_r3 !in_r4" ] },
1056         latency   => 3,
1057         units     => [ "SSE" ],
1058         mode      => "mode_E",
1059 },
1060
1061 xCondJmp => {
1062         state     => "pinned",
1063         op_flags  => "L|X|Y",
1064         comment   => "construct conditional jump: UCOMIS A, B && JMPxx LABEL",
1065         reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "none", "none" ] },
1066         outs      => [ "false", "true" ],
1067         latency   => 5,
1068         units     => [ "SSE" ],
1069 },
1070
1071 xConst => {
1072         op_flags  => "c",
1073         irn_flags => "R",
1074         comment   => "represents a SSE constant",
1075         reg_req   => { out => [ "xmm" ] },
1076         emit      => '. mov%XXM $%C, %D1',
1077         latency   => 2,
1078         units     => [ "SSE" ],
1079         mode      => "mode_E",
1080 },
1081
1082 # Load / Store
1083
1084 xLoad => {
1085         op_flags  => "L|F",
1086         state     => "exc_pinned",
1087         comment   => "construct SSE Load: Load(ptr, mem) = LD ptr",
1088         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none" ] },
1089         emit      => '. mov%XXM %AM, %D1',
1090         outs      => [ "res", "M" ],
1091         latency   => 2,
1092         units     => [ "SSE" ],
1093 },
1094
1095 xStore => {
1096         op_flags => "L|F",
1097         state    => "exc_pinned",
1098         comment  => "construct Store: Store(ptr, val, mem) = ST ptr,val",
1099         reg_req  => { in => [ "gp", "gp", "xmm", "none" ] },
1100         emit     => '. mov%XXM %binop',
1101         latency  => 2,
1102         units    => [ "SSE" ],
1103         mode     => "mode_M",
1104 },
1105
1106 xStoreSimple => {
1107         op_flags => "L|F",
1108         state    => "exc_pinned",
1109         comment  => "construct Store without index: Store(ptr, val, mem) = ST ptr,val",
1110         reg_req  => { in => [ "gp", "xmm", "none" ] },
1111         emit     => '. mov%XXM %S2, %AM',
1112         latency  => 2,
1113         units    => [ "SSE" ],
1114         mode     => "mode_M",
1115 },
1116
1117 l_X87toSSE => {
1118         op_flags => "L|F",
1119         comment  => "construct: transfer a value from x87 FPU into a SSE register",
1120         cmp_attr => "return 1;",
1121         arity    => 3,
1122 },
1123
1124 l_SSEtoX87 => {
1125         op_flags => "L|F",
1126         comment  => "construct: transfer a value from SSE register to x87 FPU",
1127         cmp_attr => "return 1;",
1128         arity    => 3,
1129 },
1130
1131 GetST0 => {
1132         op_flags => "L|F",
1133         irn_flags => "I",
1134         state    => "exc_pinned",
1135         comment  => "store ST0 onto stack",
1136         reg_req  => { in => [ "gp", "gp", "none" ] },
1137         emit     => '. fstp%XM %AM',
1138         latency  => 4,
1139         units    => [ "SSE" ],
1140         mode     => "mode_M",
1141 },
1142
1143 SetST0 => {
1144         op_flags => "L|F",
1145         irn_flags => "I",
1146         state    => "exc_pinned",
1147         comment  => "load ST0 from stack",
1148         reg_req  => { in => [ "gp", "none" ], out => [ "vf0", "none" ] },
1149         emit     => '. fld%M %AM',
1150         outs     => [ "res", "M" ],
1151         latency  => 2,
1152         units     => [ "SSE" ],
1153 },
1154
1155 # CopyB
1156
1157 CopyB => {
1158         op_flags => "F|H",
1159         state    => "pinned",
1160         comment  => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)",
1161         reg_req  => { in => [ "edi", "esi", "ecx", "none" ], out => [ "edi", "esi", "ecx", "none" ] },
1162         outs     => [ "DST", "SRC", "CNT", "M" ],
1163         units     => [ "GP" ],
1164 },
1165
1166 CopyB_i => {
1167         op_flags => "F|H",
1168         state    => "pinned",
1169         comment  => "implements a memcopy: CopyB(dst, src, mem) == memcpy(dst, src, attr(size))",
1170         reg_req  => { in => [ "edi", "esi", "none" ], out => [  "edi", "esi", "none" ] },
1171         outs     => [ "DST", "SRC", "M" ],
1172         units     => [ "GP" ],
1173 },
1174
1175 # Conversions
1176
1177 Conv_I2I => {
1178         reg_req  => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3", "none" ] },
1179         comment  => "construct Conv Int -> Int",
1180         units     => [ "GP" ],
1181         mode     => "mode_Iu",
1182 },
1183
1184 Conv_I2I8Bit => {
1185         reg_req  => { in => [ "gp", "gp", "eax ebx ecx edx", "none" ], out => [ "in_r3", "none" ] },
1186         comment  => "construct Conv Int -> Int",
1187         units     => [ "GP" ],
1188         mode     => "mode_Iu",
1189 },
1190
1191 Conv_I2FP => {
1192         reg_req  => { in => [ "gp", "gp", "gp", "none" ], out => [ "xmm", "none" ] },
1193         comment  => "construct Conv Int -> Floating Point",
1194         latency  => 10,
1195         units    => [ "SSE" ],
1196         mode     => "mode_E",
1197 },
1198
1199 Conv_FP2I => {
1200         reg_req  => { in => [ "gp", "gp", "xmm", "none" ], out => [ "gp", "none" ] },
1201         comment  => "construct Conv Floating Point -> Int",
1202         latency  => 10,
1203         units    => [ "SSE" ],
1204         mode     => "mode_Iu",
1205 },
1206
1207 Conv_FP2FP => {
1208         reg_req  => { in => [ "gp", "gp", "xmm", "none" ], out => [ "xmm", "none" ] },
1209         comment  => "construct Conv Floating Point -> Floating Point",
1210         latency  => 8,
1211         units    => [ "SSE" ],
1212         mode     => "mode_E",
1213 },
1214
1215 CmpCMov => {
1216         irn_flags => "R",
1217         comment   => "construct Conditional Move: CMov(sel, a, b) == sel ? a : b",
1218         reg_req   => { in => [ "gp", "gp", "gp", "gp" ], out => [ "in_r4" ] },
1219         latency   => 2,
1220         units     => [ "GP" ],
1221         mode      => "mode_Iu",
1222 },
1223
1224 PsiCondCMov => {
1225         irn_flags => "R",
1226         comment   => "check if Psi condition tree evaluates to true and move result accordingly",
1227         reg_req   => { in => [ "gp", "gp", "gp" ], out => [ "in_r3" ] },
1228         latency   => 2,
1229         units     => [ "GP" ],
1230         mode      => "mode_Iu",
1231 },
1232
1233 xCmpCMov => {
1234         irn_flags => "R",
1235         comment   => "construct Conditional Move: SSE Compare + int CMov ",
1236         reg_req   => { in => [ "xmm", "xmm", "gp", "gp" ], out => [ "in_r4" ] },
1237         latency   => 5,
1238         units     => [ "SSE" ],
1239         mode      => "mode_Iu",
1240 },
1241
1242 vfCmpCMov => {
1243         irn_flags => "R",
1244         comment   => "construct Conditional Move: x87 Compare + int CMov",
1245         reg_req   => { in => [ "vfp", "vfp", "gp", "gp" ], out => [ "in_r4" ] },
1246         latency   => 10,
1247         units     => [ "VFP" ],
1248         mode      => "mode_Iu",
1249 },
1250
1251 CmpSet => {
1252         irn_flags => "R",
1253         comment   => "construct Set: Set(sel) == sel ? 1 : 0",
1254         reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "eax ebx ecx edx" ] },
1255         latency   => 2,
1256         units     => [ "GP" ],
1257         mode      => "mode_Iu",
1258 },
1259
1260 PsiCondSet => {
1261         irn_flags => "R",
1262         comment   => "check if Psi condition tree evaluates to true and set result accordingly",
1263         reg_req   => { in => [ "gp" ], out => [ "eax ebx ecx edx" ] },
1264         latency   => 2,
1265         units     => [ "GP" ],
1266         mode      => "mode_Iu",
1267 },
1268
1269 xCmpSet => {
1270         irn_flags => "R",
1271         comment   => "construct Set: SSE Compare + int Set",
1272         reg_req   => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "eax ebx ecx edx" ] },
1273         latency   => 5,
1274         units     => [ "SSE" ],
1275         mode      => "mode_Iu",
1276 },
1277
1278 vfCmpSet => {
1279         irn_flags => "R",
1280         comment   => "construct Set: x87 Compare + int Set",
1281         reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "eax ebx ecx edx" ] },
1282         latency   => 10,
1283         units     => [ "VFP" ],
1284         mode      => "mode_Iu",
1285 },
1286
1287 vfCMov => {
1288         irn_flags => "R",
1289         comment   => "construct x87 Conditional Move: vfCMov(sel, a, b) = sel ? a : b",
1290         reg_req   => { in => [ "vfp", "vfp", "vfp", "vfp" ], out => [ "vfp" ] },
1291         latency   => 10,
1292         units     => [ "VFP" ],
1293         mode      => "mode_E",
1294 },
1295
1296 #----------------------------------------------------------#
1297 #        _      _               _    __ _             _    #
1298 #       (_)    | |             | |  / _| |           | |   #
1299 # __   ___ _ __| |_ _   _  __ _| | | |_| | ___   __ _| |_  #
1300 # \ \ / / | '__| __| | | |/ _` | | |  _| |/ _ \ / _` | __| #
1301 #  \ V /| | |  | |_| |_| | (_| | | | | | | (_) | (_| | |_  #
1302 #   \_/ |_|_|   \__|\__,_|\__,_|_| |_| |_|\___/ \__,_|\__| #
1303 #                 | |                                      #
1304 #  _ __   ___   __| | ___  ___                             #
1305 # | '_ \ / _ \ / _` |/ _ \/ __|                            #
1306 # | | | | (_) | (_| |  __/\__ \                            #
1307 # |_| |_|\___/ \__,_|\___||___/                            #
1308 #----------------------------------------------------------#
1309
1310 vfadd => {
1311         irn_flags => "R",
1312         comment   => "virtual fp Add: Add(a, b) = Add(b, a) = a + b",
1313         reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
1314         latency   => 4,
1315         units     => [ "VFP" ],
1316         mode      => "mode_E",
1317 },
1318
1319 vfmul => {
1320         irn_flags => "R",
1321         comment   => "virtual fp Mul: Mul(a, b) = Mul(b, a) = a * b",
1322         reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
1323         latency   => 4,
1324         units     => [ "VFP" ],
1325         mode      => "mode_E",
1326 },
1327
1328 l_vfmul => {
1329         op_flags  => "C",
1330         cmp_attr  => "return 1;",
1331         comment   => "lowered virtual fp Mul: Mul(a, b) = Mul(b, a) = a * b",
1332         arity     => 2,
1333 },
1334
1335 vfsub => {
1336         irn_flags => "R",
1337         comment   => "virtual fp Sub: Sub(a, b) = a - b",
1338         reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
1339         latency   => 4,
1340         units     => [ "VFP" ],
1341         mode      => "mode_E",
1342 },
1343
1344 l_vfsub => {
1345         cmp_attr  => "return 1;",
1346         comment   => "lowered virtual fp Sub: Sub(a, b) = a - b",
1347         arity     => 2,
1348 },
1349
1350 vfdiv => {
1351         comment   => "virtual fp Div: Div(a, b) = a / b",
1352         reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
1353         outs      => [ "res", "M" ],
1354         latency   => 20,
1355         units     => [ "VFP" ],
1356 },
1357
1358 l_vfdiv => {
1359         cmp_attr  => "return 1;",
1360         comment   => "lowered virtual fp Div: Div(a, b) = a / b",
1361         outs      => [ "res", "M" ],
1362         arity     => 2,
1363 },
1364
1365 vfprem => {
1366         comment   => "virtual fp Rem: Rem(a, b) = a - Q * b (Q is integer)",
1367         reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
1368         latency   => 20,
1369         units     => [ "VFP" ],
1370         mode      => "mode_E",
1371 },
1372
1373 l_vfprem => {
1374         cmp_attr  => "return 1;",
1375         comment   => "lowered virtual fp Rem: Rem(a, b) = a - Q * b (Q is integer)",
1376         arity     => 2,
1377 },
1378
1379 vfabs => {
1380         irn_flags => "R",
1381         comment   => "virtual fp Abs: Abs(a) = |a|",
1382         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
1383         latency   => 2,
1384         units     => [ "VFP" ],
1385         mode      => "mode_E",
1386 },
1387
1388 vfchs => {
1389         irn_flags => "R",
1390         comment   => "virtual fp Chs: Chs(a) = -a",
1391         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
1392         latency   => 2,
1393         units     => [ "VFP" ],
1394         mode      => "mode_E",
1395 },
1396
1397 vfsin => {
1398         irn_flags => "R",
1399         comment   => "virtual fp Sin: Sin(a) = sin(a)",
1400         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
1401         latency   => 150,
1402         units     => [ "VFP" ],
1403         mode      => "mode_E",
1404 },
1405
1406 vfcos => {
1407         irn_flags => "R",
1408         comment   => "virtual fp Cos: Cos(a) = cos(a)",
1409         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
1410         latency   => 150,
1411         units     => [ "VFP" ],
1412         mode      => "mode_E",
1413 },
1414
1415 vfsqrt => {
1416         irn_flags => "R",
1417         comment   => "virtual fp Sqrt: Sqrt(a) = a ^ 0.5",
1418         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
1419         latency   => 30,
1420         units     => [ "VFP" ],
1421         mode      => "mode_E",
1422 },
1423
1424 # virtual Load and Store
1425
1426 vfld => {
1427         op_flags  => "L|F",
1428         state     => "exc_pinned",
1429         comment   => "virtual fp Load: Load(ptr, mem) = LD ptr -> reg",
1430         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] },
1431         outs      => [ "res", "M" ],
1432         latency   => 2,
1433         units     => [ "VFP" ],
1434 },
1435
1436 vfst => {
1437         op_flags  => "L|F",
1438         state     => "exc_pinned",
1439         comment   => "virtual fp Store: Store(ptr, val, mem) = ST ptr,val",
1440         reg_req   => { in => [ "gp", "gp", "vfp", "none" ] },
1441         latency   => 2,
1442         units     => [ "VFP" ],
1443         mode      => "mode_M",
1444 },
1445
1446 # Conversions
1447
1448 vfild => {
1449         comment   => "virtual fp integer Load: Load(ptr, mem) = iLD ptr -> reg",
1450         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] },
1451         outs      => [ "res", "M" ],
1452         latency   => 4,
1453         units     => [ "VFP" ],
1454 },
1455
1456 l_vfild => {
1457         cmp_attr  => "return 1;",
1458         comment   => "lowered virtual fp integer Load: Load(ptr, mem) = iLD ptr -> reg",
1459         outs      => [ "res", "M" ],
1460         arity     => 2,
1461 },
1462
1463 vfist => {
1464         comment   => "virtual fp integer Store: Store(ptr, val, mem) = iST ptr,val",
1465         reg_req   => { in => [ "gp", "gp", "vfp", "none" ] },
1466         latency   => 4,
1467         units     => [ "VFP" ],
1468         mode      => "mode_M",
1469 },
1470
1471 l_vfist => {
1472         cmp_attr  => "return 1;",
1473         comment   => "lowered virtual fp integer Store: Store(ptr, val, mem) = iST ptr,val",
1474         arity     => 3,
1475         mode      => "mode_M",
1476 },
1477
1478
1479 # constants
1480
1481 vfldz => {
1482         irn_flags => "R",
1483         comment   => "virtual fp Load 0.0: Ld 0.0 -> reg",
1484         reg_req   => { out => [ "vfp" ] },
1485         latency   => 4,
1486         units     => [ "VFP" ],
1487         mode      => "mode_E",
1488 },
1489
1490 vfld1 => {
1491         irn_flags => "R",
1492         comment   => "virtual fp Load 1.0: Ld 1.0 -> reg",
1493         reg_req   => { out => [ "vfp" ] },
1494         latency   => 4,
1495         units     => [ "VFP" ],
1496         mode      => "mode_E",
1497 },
1498
1499 vfldpi => {
1500         irn_flags => "R",
1501         comment   => "virtual fp Load pi: Ld pi -> reg",
1502         reg_req   => { out => [ "vfp" ] },
1503         latency   => 4,
1504         units     => [ "VFP" ],
1505         mode      => "mode_E",
1506 },
1507
1508 vfldln2 => {
1509         irn_flags => "R",
1510         comment   => "virtual fp Load ln 2: Ld ln 2 -> reg",
1511         reg_req   => { out => [ "vfp" ] },
1512         latency   => 4,
1513         units     => [ "VFP" ],
1514         mode      => "mode_E",
1515 },
1516
1517 vfldlg2 => {
1518         irn_flags => "R",
1519         comment   => "virtual fp Load lg 2: Ld lg 2 -> reg",
1520         reg_req   => { out => [ "vfp" ] },
1521         latency   => 4,
1522         units     => [ "VFP" ],
1523         mode      => "mode_E",
1524 },
1525
1526 vfldl2t => {
1527         irn_flags => "R",
1528         comment   => "virtual fp Load ld 10: Ld ld 10 -> reg",
1529         reg_req   => { out => [ "vfp" ] },
1530         latency   => 4,
1531         units     => [ "VFP" ],
1532         mode      => "mode_E",
1533 },
1534
1535 vfldl2e => {
1536         irn_flags => "R",
1537         comment   => "virtual fp Load ld e: Ld ld e -> reg",
1538         reg_req   => { out => [ "vfp" ] },
1539         latency   => 4,
1540         units     => [ "VFP" ],
1541         mode      => "mode_E",
1542 },
1543
1544 vfConst => {
1545         op_flags  => "c",
1546         irn_flags => "R",
1547 #  init_attr => "  set_ia32_ls_mode(res, mode);",
1548         comment   => "represents a virtual floating point constant",
1549         reg_req   => { out => [ "vfp" ] },
1550         latency   => 3,
1551         units     => [ "VFP" ],
1552         mode      => "mode_E",
1553 },
1554
1555 # other
1556
1557 vfCondJmp => {
1558         state     => "pinned",
1559         op_flags  => "L|X|Y",
1560         comment   => "represents a virtual floating point compare",
1561         reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "none", "none", "eax" ] },
1562         outs      => [ "false", "true", "temp_reg_eax" ],
1563         latency   => 10,
1564         units     => [ "VFP" ],
1565 },
1566
1567 #------------------------------------------------------------------------#
1568 #       ___ _____    __ _             _                     _            #
1569 # __  _( _ )___  |  / _| | ___   __ _| |_   _ __   ___   __| | ___  ___  #
1570 # \ \/ / _ \  / /  | |_| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
1571 #  >  < (_) |/ /   |  _| | (_) | (_| | |_  | | | | (_) | (_| |  __/\__ \ #
1572 # /_/\_\___//_/    |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
1573 #------------------------------------------------------------------------#
1574
1575 # Note: gas is strangely buggy: fdivrp and fdivp as well as fsubrp and fsubp
1576 #       are swapped, we work this around in the emitter...
1577
1578 fadd => {
1579         op_flags  => "R",
1580         rd_constructor => "NONE",
1581         comment   => "x87 Add: Add(a, b) = Add(b, a) = a + b",
1582         reg_req   => { },
1583         emit      => '. fadd%XM %x87_binop',
1584 },
1585
1586 faddp => {
1587         op_flags  => "R",
1588         rd_constructor => "NONE",
1589         comment   => "x87 Add: Add(a, b) = Add(b, a) = a + b",
1590         reg_req   => { },
1591         emit      => '. faddp %x87_binop',
1592 },
1593
1594 fmul => {
1595         op_flags  => "R",
1596         rd_constructor => "NONE",
1597         comment   => "x87 fp Mul: Mul(a, b) = Mul(b, a) = a + b",
1598         reg_req   => { },
1599         emit      => '. fmul%XM %x87_binop',
1600 },
1601
1602 fmulp => {
1603         op_flags  => "R",
1604         rd_constructor => "NONE",
1605         comment   => "x87 fp Mul: Mul(a, b) = Mul(b, a) = a + b",
1606         reg_req   => { },
1607         emit      => '. fmulp %x87_binop',,
1608 },
1609
1610 fsub => {
1611         op_flags  => "R",
1612         rd_constructor => "NONE",
1613         comment   => "x87 fp Sub: Sub(a, b) = a - b",
1614         reg_req   => { },
1615         emit      => '. fsub%XM %x87_binop',
1616 },
1617
1618 fsubp => {
1619         op_flags  => "R",
1620         rd_constructor => "NONE",
1621         comment   => "x87 fp Sub: Sub(a, b) = a - b",
1622         reg_req   => { },
1623 # see note about gas bugs
1624         emit      => '. fsubrp %x87_binop',
1625 },
1626
1627 fsubr => {
1628         op_flags  => "R",
1629         rd_constructor => "NONE",
1630         irn_flags => "R",
1631         comment   => "x87 fp SubR: SubR(a, b) = b - a",
1632         reg_req   => { },
1633         emit      => '. fsubr%XM %x87_binop',
1634 },
1635
1636 fsubrp => {
1637         op_flags  => "R",
1638         rd_constructor => "NONE",
1639         irn_flags => "R",
1640         comment   => "x87 fp SubR: SubR(a, b) = b - a",
1641         reg_req   => { },
1642 # see note about gas bugs
1643         emit      => '. fsubp %x87_binop',
1644 },
1645
1646 fprem => {
1647         op_flags  => "R",
1648         rd_constructor => "NONE",
1649         comment   => "x87 fp Rem: Rem(a, b) = a - Q * b (Q is integer)",
1650         reg_req   => { },
1651         emit      => '. fprem1',
1652 },
1653
1654 # this node is just here, to keep the simulator running
1655 # we can omit this when a fprem simulation function exists
1656 fpremp => {
1657         op_flags  => "R",
1658         rd_constructor => "NONE",
1659         comment   => "x87 fp Rem: Rem(a, b) = a - Q * b (Q is integer)",
1660         reg_req   => { },
1661         emit      => '. fprem1',
1662 },
1663
1664 fdiv => {
1665         op_flags  => "R",
1666         rd_constructor => "NONE",
1667         comment   => "x87 fp Div: Div(a, b) = a / b",
1668         reg_req   => { },
1669         emit      => '. fdiv%XM %x87_binop',
1670 },
1671
1672 fdivp => {
1673         op_flags  => "R",
1674         rd_constructor => "NONE",
1675         comment   => "x87 fp Div: Div(a, b) = a / b",
1676         reg_req   => { },
1677 # see note about gas bugs
1678         emit      => '. fdivrp %x87_binop',
1679 },
1680
1681 fdivr => {
1682         op_flags  => "R",
1683         rd_constructor => "NONE",
1684         comment   => "x87 fp DivR: DivR(a, b) = b / a",
1685         reg_req   => { },
1686         emit      => '. fdivr%XM %x87_binop',
1687 },
1688
1689 fdivrp => {
1690         op_flags  => "R",
1691         rd_constructor => "NONE",
1692         comment   => "x87 fp DivR: DivR(a, b) = b / a",
1693         reg_req   => { },
1694 # see note about gas bugs
1695         emit      => '. fdivp %x87_binop',
1696 },
1697
1698 fabs => {
1699         op_flags  => "R",
1700         rd_constructor => "NONE",
1701         comment   => "x87 fp Abs: Abs(a) = |a|",
1702         reg_req   => { },
1703         emit      => '. fabs',
1704 },
1705
1706 fchs => {
1707         op_flags  => "R",
1708         rd_constructor => "NONE",
1709         comment   => "x87 fp Chs: Chs(a) = -a",
1710         reg_req   => { },
1711         emit      => '. fchs',
1712 },
1713
1714 fsin => {
1715         op_flags  => "R",
1716         rd_constructor => "NONE",
1717         comment   => "x87 fp Sin: Sin(a) = sin(a)",
1718         reg_req   => { },
1719         emit      => '. fsin',
1720 },
1721
1722 fcos => {
1723         op_flags  => "R",
1724         rd_constructor => "NONE",
1725         comment   => "x87 fp Cos: Cos(a) = cos(a)",
1726         reg_req   => { },
1727         emit      => '. fcos',
1728 },
1729
1730 fsqrt => {
1731         op_flags  => "R",
1732         rd_constructor => "NONE",
1733         comment   => "x87 fp Sqrt: Sqrt(a) = a ^ 0.5",
1734         reg_req   => { },
1735         emit      => '. fsqrt $',
1736 },
1737
1738 # x87 Load and Store
1739
1740 fld => {
1741         rd_constructor => "NONE",
1742         op_flags  => "R|L|F",
1743         state     => "exc_pinned",
1744         comment   => "x87 fp Load: Load(ptr, mem) = LD ptr -> reg",
1745         reg_req   => { },
1746         emit      => '. fld%XM %AM',
1747 },
1748
1749 fst => {
1750         rd_constructor => "NONE",
1751         op_flags  => "R|L|F",
1752         state     => "exc_pinned",
1753         comment   => "x87 fp Store: Store(ptr, val, mem) = ST ptr,val",
1754         reg_req   => { },
1755         emit      => '. fst%XM %AM',
1756         mode      => "mode_M",
1757 },
1758
1759 fstp => {
1760         rd_constructor => "NONE",
1761         op_flags  => "R|L|F",
1762         state     => "exc_pinned",
1763         comment   => "x87 fp Store: Store(ptr, val, mem) = ST ptr,val",
1764         reg_req   => { },
1765         emit      => '. fstp%XM %AM',
1766         mode      => "mode_M",
1767 },
1768
1769 # Conversions
1770
1771 fild => {
1772         op_flags  => "R",
1773         rd_constructor => "NONE",
1774         comment   => "x87 fp integer Load: Load(ptr, mem) = iLD ptr -> reg",
1775         reg_req   => { },
1776         emit      => '. fild%XM %AM',
1777 },
1778
1779 fist => {
1780         op_flags  => "R",
1781         rd_constructor => "NONE",
1782         comment   => "x87 fp integer Store: Store(ptr, val, mem) = iST ptr,val",
1783         reg_req   => { },
1784         emit      => '. fist%M %AM',
1785         mode      => "mode_M",
1786 },
1787
1788 fistp => {
1789         op_flags  => "R",
1790         rd_constructor => "NONE",
1791         comment   => "x87 fp integer Store: Store(ptr, val, mem) = iST ptr,val",
1792         reg_req   => { },
1793         emit      => '. fistp%M %AM',
1794         mode      => "mode_M",
1795 },
1796
1797 # constants
1798
1799 fldz => {
1800         op_flags  => "R|c",
1801         irn_flags  => "R",
1802         comment   => "x87 fp Load 0.0: Ld 0.0 -> reg",
1803         reg_req   => { },
1804         emit      => '. fldz',
1805 },
1806
1807 fld1 => {
1808         op_flags  => "R|c",
1809         irn_flags  => "R",
1810         comment   => "x87 fp Load 1.0: Ld 1.0 -> reg",
1811         reg_req   => { },
1812         emit      => '. fld1',
1813 },
1814
1815 fldpi => {
1816         op_flags  => "R|c",
1817         irn_flags  => "R",
1818         comment   => "x87 fp Load pi: Ld pi -> reg",
1819         reg_req   => { },
1820         emit      => '. fldpi',
1821 },
1822
1823 fldln2 => {
1824         op_flags  => "R|c",
1825         irn_flags  => "R",
1826         comment   => "x87 fp Load ln 2: Ld ln 2 -> reg",
1827         reg_req   => { },
1828         emit      => '. fldln2',
1829 },
1830
1831 fldlg2 => {
1832         op_flags  => "R|c",
1833         irn_flags  => "R",
1834         comment   => "x87 fp Load lg 2: Ld lg 2 -> reg",
1835         reg_req   => { },
1836         emit      => '. fldlg2',
1837 },
1838
1839 fldl2t => {
1840         op_flags  => "R|c",
1841         irn_flags  => "R",
1842         comment   => "x87 fp Load ld 10: Ld ld 10 -> reg",
1843         reg_req   => { },
1844         emit      => '. fldll2t',
1845 },
1846
1847 fldl2e => {
1848         op_flags  => "R|c",
1849         irn_flags  => "R",
1850         comment   => "x87 fp Load ld e: Ld ld e -> reg",
1851         reg_req   => { },
1852         emit      => '. fldl2e',
1853 },
1854
1855 # fxch, fpush, fpop
1856 # Note that it is NEVER allowed to do CSE on these nodes
1857 # Moreover, note the virtual register requierements!
1858
1859 fxch => {
1860         op_flags  => "R|K",
1861         comment   => "x87 stack exchange",
1862         reg_req   => { },
1863         cmp_attr  => "return 1;",
1864         emit      => '. fxch %X1',
1865 },
1866
1867 fpush => {
1868         op_flags  => "R|K",
1869         comment   => "x87 stack push",
1870         reg_req   => {},
1871         cmp_attr  => "return 1;",
1872         emit      => '. fld %X1',
1873 },
1874
1875 fpushCopy => {
1876         op_flags  => "R",
1877         comment   => "x87 stack push",
1878         reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
1879         cmp_attr  => "return 1;",
1880         emit      => '. fld %X1',
1881 },
1882
1883 fpop => {
1884         op_flags  => "R|K",
1885         comment   => "x87 stack pop",
1886         reg_req   => { },
1887         cmp_attr  => "return 1;",
1888         emit      => '. fstp %X1',
1889 },
1890
1891 # compare
1892
1893 fcomJmp => {
1894         op_flags  => "L|X|Y",
1895         comment   => "floating point compare",
1896         reg_req   => { },
1897 },
1898
1899 fcompJmp => {
1900         op_flags  => "L|X|Y",
1901         comment   => "floating point compare and pop",
1902         reg_req   => { },
1903 },
1904
1905 fcomppJmp => {
1906         op_flags  => "L|X|Y",
1907         comment   => "floating point compare and pop twice",
1908         reg_req   => { },
1909 },
1910
1911 fcomrJmp => {
1912         op_flags  => "L|X|Y",
1913         comment   => "floating point compare reverse",
1914         reg_req   => { },
1915 },
1916
1917 fcomrpJmp => {
1918         op_flags  => "L|X|Y",
1919         comment   => "floating point compare reverse and pop",
1920         reg_req   => { },
1921 },
1922
1923 fcomrppJmp => {
1924         op_flags  => "L|X|Y",
1925         comment   => "floating point compare reverse and pop twice",
1926         reg_req   => { },
1927 },
1928
1929
1930 # -------------------------------------------------------------------------------- #
1931 #  ____ ____  _____                  _                               _             #
1932 # / ___/ ___|| ____| __   _____  ___| |_ ___  _ __   _ __   ___   __| | ___  ___   #
1933 # \___ \___ \|  _|   \ \ / / _ \/ __| __/ _ \| '__| | '_ \ / _ \ / _` |/ _ \/ __|  #
1934 #  ___) |__) | |___   \ V /  __/ (__| || (_) | |    | | | | (_) | (_| |  __/\__ \  #
1935 # |____/____/|_____|   \_/ \___|\___|\__\___/|_|    |_| |_|\___/ \__,_|\___||___/  #
1936 #                                                                                  #
1937 # -------------------------------------------------------------------------------- #
1938
1939
1940 # Spilling and reloading of SSE registers, hardcoded, not generated #
1941
1942 xxLoad => {
1943         op_flags  => "L|F",
1944         state     => "exc_pinned",
1945         comment   => "construct SSE Load: Load(ptr, mem) = LD ptr",
1946         reg_req   => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none" ] },
1947         emit      => '. movdqu %D1, %AM',
1948         outs      => [ "res", "M" ],
1949         units     => [ "SSE" ],
1950 },
1951
1952 xxStore => {
1953         op_flags => "L|F",
1954         state    => "exc_pinned",
1955         comment  => "construct Store: Store(ptr, val, mem) = ST ptr,val",
1956         reg_req  => { in => [ "gp", "gp", "xmm", "none" ] },
1957         emit     => '. movdqu %binop',
1958         units    => [ "SSE" ],
1959         mode     => "mode_M",
1960 },
1961
1962 ); # end of %nodes
1963
1964 # Include the generated SIMD node specification written by the SIMD optimization
1965 $my_script_name = dirname($myname) . "/../ia32/ia32_simd_spec.pl";
1966 unless ($return = do $my_script_name) {
1967         warn "couldn't parse $my_script_name: $@" if $@;
1968         warn "couldn't do $my_script_name: $!"    unless defined $return;
1969         warn "couldn't run $my_script_name"       unless $return;
1970 }