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