fix cvt emitter
[libfirm] / ir / be / ia32 / ia32_spec.pl
index 8a4e9cc..af4fc48 100644 (file)
@@ -2,16 +2,11 @@
 # $Id$
 # This is the specification for the ia32 assembler Firm-operations
 
+$new_emit_syntax = 1;
+
 # the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
 $arch = "ia32";
 
-# this strings mark the beginning and the end of a comment in emit
-$comment_string     = "/*";
-$comment_string_end = "*/";
-
-# the number of additional opcodes you want to register
-#$additional_opcodes = 0;
-
 # The node description is done as a perl hash initializer with the
 # following structure:
 #
@@ -109,95 +104,109 @@ $comment_string_end = "*/";
 #  16 - the register is a virtual one
 # NOTE: Last entry of each class is the largest Firm-Mode a register can hold
 %reg_classes = (
-  "gp" => [
-            { "name" => "eax", "type" => 1 },
-            { "name" => "edx", "type" => 1 },
-            { "name" => "ebx", "type" => 2 },
-            { "name" => "ecx", "type" => 1 },
-            { "name" => "esi", "type" => 2 },
-            { "name" => "edi", "type" => 2 },
-#            { "name" => "r11", "type" => 1 },
-#            { "name" => "r12", "type" => 1 },
-#            { "name" => "r13", "type" => 1 },
-#            { "name" => "r14", "type" => 1 },
-#            { "name" => "r15", "type" => 1 },
-#            { "name" => "r16", "type" => 1 },
-#            { "name" => "r17", "type" => 1 },
-#            { "name" => "r18", "type" => 1 },
-#            { "name" => "r19", "type" => 1 },
-#            { "name" => "r20", "type" => 1 },
-#            { "name" => "r21", "type" => 1 },
-#            { "name" => "r22", "type" => 1 },
-#            { "name" => "r23", "type" => 1 },
-#            { "name" => "r24", "type" => 1 },
-#            { "name" => "r25", "type" => 1 },
-#            { "name" => "r26", "type" => 1 },
-#            { "name" => "r27", "type" => 1 },
-#            { "name" => "r28", "type" => 1 },
-#            { "name" => "r29", "type" => 1 },
-#            { "name" => "r30", "type" => 1 },
-#            { "name" => "r31", "type" => 1 },
-#            { "name" => "r32", "type" => 1 },
-            { "name" => "ebp", "type" => 2 },
-            { "name" => "esp", "type" => 4 },
-            { "name" => "gp_NOREG", "type" => 2 | 4 | 16 },     # we need a dummy register for NoReg nodes
-            { "name" => "gp_UKNWN", "type" => 2 | 4 | 8 | 16},  # we need a dummy register for Unknown nodes
-                       { "mode" => "mode_P" }
-          ],
-  "xmm" => [
-            { "name" => "xmm0", "type" => 1 },
-            { "name" => "xmm1", "type" => 1 },
-            { "name" => "xmm2", "type" => 1 },
-            { "name" => "xmm3", "type" => 1 },
-            { "name" => "xmm4", "type" => 1 },
-            { "name" => "xmm5", "type" => 1 },
-            { "name" => "xmm6", "type" => 1 },
-            { "name" => "xmm7", "type" => 1 },
-            { "name" => "xmm_NOREG", "type" => 2 | 4 | 16 },     # we need a dummy register for NoReg nodes
-            { "name" => "xmm_UKNWN", "type" => 2 | 4 | 8 | 16},  # we need a dummy register for Unknown nodes
-                       { "mode" => "mode_D" }
-          ],
-  "vfp" => [
-            { "name" => "vf0", "type" => 1 | 16 },
-            { "name" => "vf1", "type" => 1 | 16 },
-            { "name" => "vf2", "type" => 1 | 16 },
-            { "name" => "vf3", "type" => 1 | 16 },
-            { "name" => "vf4", "type" => 1 | 16 },
-            { "name" => "vf5", "type" => 1 | 16 },
-            { "name" => "vf6", "type" => 1 | 16 },
-            { "name" => "vf7", "type" => 1 | 16 },
-            { "name" => "vfp_NOREG", "type" => 2 | 4 | 16 },     # we need a dummy register for NoReg nodes
-            { "name" => "vfp_UKNWN", "type" => 2 | 4 | 8 | 16},  # we need a dummy register for Unknown nodes
-                       { "mode" => "mode_E" }
-          ],
-  "st" => [
-            { "name" => "st0", "type" => 1 },
-            { "name" => "st1", "type" => 1 },
-            { "name" => "st2", "type" => 1 },
-            { "name" => "st3", "type" => 1 },
-            { "name" => "st4", "type" => 1 },
-            { "name" => "st5", "type" => 1 },
-            { "name" => "st6", "type" => 1 },
-            { "name" => "st7", "type" => 1 },
-                       { "mode" => "mode_E" }
-          ]
+       "gp" => [
+               { "name" => "eax", "type" => 1 },
+               { "name" => "edx", "type" => 1 },
+               { "name" => "ebx", "type" => 2 },
+               { "name" => "ecx", "type" => 1 },
+               { "name" => "esi", "type" => 2 },
+               { "name" => "edi", "type" => 2 },
+               { "name" => "ebp", "type" => 2 },
+               { "name" => "esp", "type" => 4 },
+               { "name" => "gp_NOREG", "type" => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes
+               { "name" => "gp_UKNWN", "type" => 4 | 8 | 16 },  # we need a dummy register for Unknown nodes
+               { "mode" => "mode_Iu" }
+       ],
+       "xmm" => [
+               { "name" => "xmm0", "type" => 1 },
+               { "name" => "xmm1", "type" => 1 },
+               { "name" => "xmm2", "type" => 1 },
+               { "name" => "xmm3", "type" => 1 },
+               { "name" => "xmm4", "type" => 1 },
+               { "name" => "xmm5", "type" => 1 },
+               { "name" => "xmm6", "type" => 1 },
+               { "name" => "xmm7", "type" => 1 },
+               { "name" => "xmm_NOREG", "type" => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes
+               { "name" => "xmm_UKNWN", "type" => 4 | 8 | 16 },  # we need a dummy register for Unknown nodes
+               { "mode" => "mode_E" }
+       ],
+       "vfp" => [
+               { "name" => "vf0", "type" => 1 | 16 },
+               { "name" => "vf1", "type" => 1 | 16 },
+               { "name" => "vf2", "type" => 1 | 16 },
+               { "name" => "vf3", "type" => 1 | 16 },
+               { "name" => "vf4", "type" => 1 | 16 },
+               { "name" => "vf5", "type" => 1 | 16 },
+               { "name" => "vf6", "type" => 1 | 16 },
+               { "name" => "vf7", "type" => 1 | 16 },
+               { "name" => "vfp_NOREG", "type" => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes
+               { "name" => "vfp_UKNWN", "type" => 4 | 8 | 16 },  # we need a dummy register for Unknown nodes
+               { "mode" => "mode_E" }
+       ],
+       "st" => [
+               { "name" => "st0", "type" => 1 },
+               { "name" => "st1", "type" => 1 },
+               { "name" => "st2", "type" => 1 },
+               { "name" => "st3", "type" => 1 },
+               { "name" => "st4", "type" => 1 },
+               { "name" => "st5", "type" => 1 },
+               { "name" => "st6", "type" => 1 },
+               { "name" => "st7", "type" => 1 },
+               { "mode" => "mode_E" }
+       ],
+       "fp_cw" => [    # the floating point control word
+               { "name" => "fpcw", "type" => 0 },
+        { "mode" => "mode_Hu" },
+       ],
 ); # %reg_classes
 
 %cpu = (
-  "ALU"    => [ 1, "ALU1", "ALU2", "ALU3", "ALU4" ],
-  "MUL"    => [ 1, "MUL1", "MUL2" ],
-  "SSE"    => [ 1, "SSE1", "SSE2" ],
-  "FPU"    => [ 1, "FPU1" ],
-  "MEM"    => [ 1, "MEM1", "MEM2" ],
+  "GP"     => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
+  "SSE"    => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
+  "VFP"    => [ 1, "VFP_VF0", "VFP_VF1", "VFP_VF2", "VFP_VF3", "VFP_VF4", "VFP_VF5", "VFP_VF6", "VFP_VF7" ],
   "BRANCH" => [ 1, "BRANCH1", "BRANCH2" ],
-  "DUMMY"  => [ 1, "DUMMY1", "DUMMY2", "DUMMY3", "DUMMY4" ]
 ); # %cpu
 
 %vliw = (
-       "bundle_size"       => 3,
-       "bundels_per_cycle" => 2
+       "bundle_size"       => 1,
+       "bundels_per_cycle" => 1
 ); # vliw
 
+%emit_templates = (
+       "S1" => "${arch}_emit_source_register(env, node, 0);",
+       "S2" => "${arch}_emit_source_register(env, node, 1);",
+       "S3" => "${arch}_emit_source_register(env, node, 2);",
+       "S4" => "${arch}_emit_source_register(env, node, 3);",
+       "S5" => "${arch}_emit_source_register(env, node, 4);",
+       "S6" => "${arch}_emit_source_register(env, node, 5);",
+       "D1" => "${arch}_emit_dest_register(env, node, 0);",
+       "D2" => "${arch}_emit_dest_register(env, node, 1);",
+       "D3" => "${arch}_emit_dest_register(env, node, 2);",
+       "D4" => "${arch}_emit_dest_register(env, node, 3);",
+       "D5" => "${arch}_emit_dest_register(env, node, 4);",
+       "D6" => "${arch}_emit_dest_register(env, node, 5);",
+       "A1" => "${arch}_emit_in_node_name(env, node, 0);",
+       "A2" => "${arch}_emit_in_node_name(env, node, 1);",
+       "A3" => "${arch}_emit_in_node_name(env, node, 2);",
+       "A4" => "${arch}_emit_in_node_name(env, node, 3);",
+       "A5" => "${arch}_emit_in_node_name(env, node, 4);",
+       "A6" => "${arch}_emit_in_node_name(env, node, 5);",
+       "X1" => "${arch}_emit_x87_name(env, node, 0);",
+       "X2" => "${arch}_emit_x87_name(env, node, 1);",
+       "X3" => "${arch}_emit_x87_name(env, node, 2);",
+       "C"  => "${arch}_emit_immediate(env, node);",
+       "SE" => "${arch}_emit_extend_suffix(env, get_ia32_ls_mode(node));",
+       "ME" => "if(get_mode_size_bits(get_ia32_ls_mode(node)) != 32)\n
+       ${arch}_emit_mode_suffix(env, get_ia32_ls_mode(node));",
+       "M"  => "${arch}_emit_mode_suffix(env, get_ia32_ls_mode(node));",
+       "XM" => "${arch}_emit_x87_mode_suffix(env, node);",
+       "XXM" => "${arch}_emit_xmm_mode_suffix(env, node);",
+       "AM" => "${arch}_emit_am(env, node);",
+       "unop" => "${arch}_emit_unop(env, node);",
+       "binop" => "${arch}_emit_binop(env, node);",
+       "x87_binop" => "${arch}_emit_x87_binop(env, node);",
+);
+
 #--------------------------------------------------#
 #                        _                         #
 #                       (_)                        #
@@ -209,7 +218,7 @@ $comment_string_end = "*/";
 #                                      |_|         #
 #--------------------------------------------------#
 
-$default_cmp_attr = "return ia32_compare_immop_attr(attr_a, attr_b);";
+$default_cmp_attr = "return ia32_compare_attr(attr_a, attr_b);";
 
 %operands = (
 );
@@ -241,15 +250,17 @@ $default_cmp_attr = "return ia32_compare_immop_attr(attr_a, attr_b);";
   "irn_flags" => "R",
   "comment"   => "construct Add: Add(a, b) = Add(b, a) = a + b",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. add %ia32_emit_binop /* Add(%A3, %A4) -> %D1 */',
-  "units"     => [ "ALU", "MEM" ],
+  "emit"      => '. addl %binop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
-"AddC" => {
-  "comment"   => "construct Add with Carry: AddC(a, b) = Add(b, a) = a + b + carry",
+"Adc" => {
+  "comment"   => "construct Add with Carry: Adc(a, b) = Add(b, a) = a + b + carry",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. adc %ia32_emit_binop /* AddC(%A3, %A4) -> %D1 */',
-  "units"     => [ "ALU", "MEM" ],
+  "emit"      => '. adcl %binop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "Add64Bit" => {
@@ -258,13 +269,13 @@ $default_cmp_attr = "return ia32_compare_immop_attr(attr_a, attr_b);";
   "arity"     => 4,
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp" ], "out" => [ "!in", "!in" ] },
   "emit"      => '
-. mov %D1, %S1 /* mov a_l into assigned l_res register */
-. mov %D2, %S2 /* mov a_h into assigned h_res register */
-. add %D1, %S3 /* a_l + b_l */
-. adc %D2, %S4 /* a_h + b_h + carry */
+. movl %S1, %D1
+. movl %S2, %D2
+. addl %S3, %D1
+. adcl %S4, %D2
 ',
   "outs"      => [ "low_res", "high_res" ],
-  "units"     => [ "ALU", "MEM" ],
+  "units"     => [ "GP" ],
 },
 
 "l_Add" => {
@@ -275,142 +286,112 @@ $default_cmp_attr = "return ia32_compare_immop_attr(attr_a, attr_b);";
   "arity"     => 2,
 },
 
-"l_AddC" => {
+"l_Adc" => {
   "op_flags"  => "C",
   "cmp_attr"  => "return 1;",
-  "comment"   => "construct lowered Add with Carry: AddC(a, b) = Add(b, a) = a + b + carry",
+  "comment"   => "construct lowered Add with Carry: Adc(a, b) = Adc(b, a) = a + b + carry",
   "arity"     => 2,
 },
 
-"MulS" => {
+"Mul" => {
   # we should not rematrialize this node. It produces 2 results and has
   # very strict constrains
   "comment"   => "construct MulS: MulS(a, b) = MulS(b, a) = a * b",
-  "reg_req"   => { "in" => [ "gp", "gp", "eax", "gp", "none" ], "out" => [ "eax", "edx" ] },
-  "emit"      => '. mul %ia32_emit_unop /* Mul(%A1, %A2) -> %D1 */',
+  "reg_req"   => { "in" => [ "gp", "gp", "eax", "gp", "none" ], "out" => [ "eax", "edx", "none" ] },
+  "emit"      => '. mull %unop',
   "outs"      => [ "EAX", "EDX", "M" ],
   "latency"   => 10,
-  "units"     => [ "MUL" ],
+  "units"     => [ "GP" ],
 },
 
-"l_MulS" => {
+"l_Mul" => {
   # we should not rematrialize this node. It produces 2 results and has
   # very strict constrains
   "op_flags"  => "C",
   "cmp_attr"  => "return 1;",
-  "comment"   => "construct lowered MulS: MulS(a, b) = MulS(b, a) = a * b",
+  "comment"   => "construct lowered MulS: Mul(a, b) = Mul(b, a) = a * b",
   "outs"      => [ "EAX", "EDX", "M" ],
   "arity"     => 2
 },
 
-"Mul" => {
+"IMul" => {
   "irn_flags" => "R",
   "comment"   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. imul %ia32_emit_binop /* Mul(%A1, %A2) -> %D1 */',
+  "emit"      => '. imull %binop',
   "latency"   => 5,
-  "units"     => [ "MUL" ],
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
-"l_Mul" => {
+"IMul1OP" => {
+  "irn_flags" => "R",
+  "comment"   => "construct Mul (1 operand format): Mul(a, b) = Mul(b, a) = a * b",
+  "reg_req"   => { "in" => [ "gp", "gp", "eax", "gp", "none" ], "out" => [ "eax", "edx", "none" ] },
+  "emit"      => '. imull %unop',
+  "outs"      => [ "EAX", "EDX", "M" ],
+  "latency"   => 5,
+  "units"     => [ "GP" ],
+},
+
+"l_IMul" => {
   "op_flags"  => "C",
   "cmp_attr"  => "return 1;",
-  "comment"   => "construct lowered Mul: Mul(a, b) = Mul(b, a) = a * b",
+  "comment"   => "construct lowered IMul: IMul(a, b) = IMul(b, a) = a * b",
   "arity"     => 2
 },
 
-# Mulh is an exception from the 4 INs with AM because the target is always EAX:EDX
-"Mulh" => {
-  # we should not rematrialize this node. It produces 2 results and has
-  # very strict constrains
-  "comment"   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
-  "reg_req"   => { "in" => [ "gp", "gp", "eax", "gp", "none" ], "out" => [ "eax", "edx" ] },
-  "emit"      => '. imul %ia32_emit_unop /* Mulh(%A1, %A2) -> %D1 */',
-  "outs"      => [ "EAX", "EDX", "M" ],
-  "latency"   => 5,
-  "units"     => [ "MUL" ],
-},
-
 "And" => {
   "irn_flags" => "R",
   "comment"   => "construct And: And(a, b) = And(b, a) = a AND b",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. and %ia32_emit_binop /* And(%A1, %A2) -> %D1 */',
-  "units"     => [ "ALU" ],
+  "emit"      => '. andl %binop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "Or" => {
   "irn_flags" => "R",
   "comment"   => "construct Or: Or(a, b) = Or(b, a) = a OR b",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. or %ia32_emit_binop /* Or(%A1, %A2) -> %D1 */',
-  "units"     => [ "ALU" ],
+  "emit"      => '. orl %binop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
-"Eor" => {
+"Xor" => {
   "irn_flags" => "R",
-  "comment"   => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
+  "comment"   => "construct Xor: Xor(a, b) = Xor(b, a) = a EOR b",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. xor %ia32_emit_binop /* Xor(%A1, %A2) -> %D1 */',
-  "units"     => [ "ALU" ],
+  "emit"      => '. xorl %binop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
-"l_Eor" => {
+"l_Xor" => {
   "op_flags"  => "C",
   "cmp_attr"  => "return 1;",
-  "comment"   => "construct lowered Eor: Eor(a, b) = Eor(b, a) = a EOR b",
+  "comment"   => "construct lowered Xor: Xor(a, b) = Xor(b, a) = a XOR b",
   "arity"     => 2
 },
 
-"Max" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Max: Max(a, b) = Max(b, a) = a > b ? a : b",
-  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
-  "emit"      =>
-'2. cmp %S1, %S2 /* prepare Max (%S1 - %S2), (%A1, %A2) */
-  if (mode_is_signed(get_irn_mode(n))) {
-4.  cmovl %D1, %S2 /* %S1 is less %S2 */
-  }
-  else {
-4.  cmovb %D1, %S2 /* %S1 is below %S2 */
-  }
-',
-  "latency"   => 2,
-  "units"     => [ "ALU" ],
-},
-
-"Min" => {
-  "irn_flags" => "R",
-  "comment"   => "construct Min: Min(a, b) = Min(b, a) = a < b ? a : b",
-  "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
-  "emit"      =>
-'2. cmp %S1, %S2 /* prepare Min (%S1 - %S2), (%A1, %A2) */
-  if (mode_is_signed(get_irn_mode(n))) {
-2.  cmovg %D1, %S2 /* %S1 is greater %S2 */
-  }
-  else {
-2.  cmova %D1, %S2, %D1 /* %S1 is above %S2 */
-  }
-',
-  "latency"   => 2,
-  "units"     => [ "ALU" ],
-},
-
 # not commutative operations
 
 "Sub" => {
   "irn_flags" => "R",
   "comment"   => "construct Sub: Sub(a, b) = a - b",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. sub %ia32_emit_binop /* Sub(%A3, %A4) -> %D1 */',
-  "units"     => [ "ALU" ],
+  "emit"      => '. subl %binop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
-"SubC" => {
+"Sbb" => {
   "comment"   => "construct Sub with Carry: SubC(a, b) = a - b - carry",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3 !in_r4" ] },
-  "emit"      => '. sbb %ia32_emit_binop /* SubC(%A3, %A4) -> %D1 */',
-  "units"     => [ "ALU" ],
+  "emit"      => '. sbbl %binop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "Sub64Bit" => {
@@ -419,13 +400,13 @@ $default_cmp_attr = "return ia32_compare_immop_attr(attr_a, attr_b);";
   "arity"     => 4,
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp" ], "out" => [ "!in", "!in" ] },
   "emit"      => '
-. mov %D1, %S1 /* mov a_l into assigned l_res register */
-. mov %D2, %S2 /* mov a_h into assigned h_res register */
-. sub %D1, %S3 /* a_l - b_l */
-. sbb %D2, %S4 /* a_h - b_h - borrow */
+. movl %S1, %D1
+. movl %S2, %D2
+. subl %S3, %D1
+. sbbl %S4, %D2
 ',
   "outs"      => [ "low_res", "high_res" ],
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
 },
 
 "l_Sub" => {
@@ -435,38 +416,43 @@ $default_cmp_attr = "return ia32_compare_immop_attr(attr_a, attr_b);";
   "arity"     => 2,
 },
 
-"l_SubC" => {
+"l_Sbb" => {
   "cmp_attr"  => "return 1;",
   "comment"   => "construct lowered Sub with Carry: SubC(a, b) = a - b - carry",
   "arity"     => 2,
 },
 
-"DivMod" => {
+"IDiv" => {
   "op_flags"  => "F|L",
   "state"     => "exc_pinned",
-  "reg_req"   => { "in" => [ "eax", "gp", "edx", "none" ], "out" => [ "eax", "edx" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "eax", "edx", "gp", "none" ], "out" => [ "eax", "edx", "none" ] },
   "attr"      => "ia32_op_flavour_t dm_flav",
-  "init_attr" => "  attr->data.op_flav = dm_flav;",
-  "cmp_attr"  => "  return attr_a->data.op_flav != attr_b->data.op_flav;\n",
-  "emit"      =>
-'  if (mode_is_signed(get_ia32_res_mode(n))) {
-4.  idiv %S2 /* signed DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3) */
-  }
-  else {
-4.  div %S2 /* unsigned DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3) */
-  }
-',
+  "init_attr" => "attr->data.op_flav = dm_flav;",
+  "emit"      => ". idivl %unop",
   "outs"      => [ "div_res", "mod_res", "M" ],
   "latency"   => 25,
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
+},
+
+"Div" => {
+  "op_flags"  => "F|L",
+  "state"     => "exc_pinned",
+  "reg_req"   => { "in" => [ "gp", "gp", "eax", "edx", "gp", "none" ], "out" => [ "eax", "edx", "none" ] },
+  "attr"      => "ia32_op_flavour_t dm_flav",
+  "init_attr" => "attr->data.op_flav = dm_flav;",
+  "emit"      => ". divl %unop",
+  "outs"      => [ "div_res", "mod_res", "M" ],
+  "latency"   => 25,
+  "units"     => [ "GP" ],
 },
 
 "Shl" => {
   "irn_flags" => "R",
   "comment"   => "construct Shl: Shl(a, b) = a << b",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
-  "emit"      => '. shl %ia32_emit_binop /* Shl(%A1, %A2) -> %D1 */',
-  "units"     => [ "ALU1", "SSE1" ],
+  "emit"      => '. shll %binop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "l_Shl" => {
@@ -489,39 +475,38 @@ $default_cmp_attr = "return ia32_compare_immop_attr(attr_a, attr_b);";
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "ecx", "none" ], "out" => [ "!in" ] },
   "emit"      =>
 '
-if (get_ia32_immop_type(n) == ia32_ImmNone) {
-  if (get_ia32_op_type(n) == ia32_AddrModeD) {
-4. shld %ia32_emit_am, %S4, %%cl /* ShlD(%A3, %A4, %A5) -> %D1 */
-  }
-  else {
-4. shld %S3, %S4, %%cl /* ShlD(%A3, %A4, %A5) -> %D1 */
-  }
-}
-else {
-  if (get_ia32_op_type(n) == ia32_AddrModeD) {
-4. shld %ia32_emit_am, %S4, %C /* ShlD(%A3, %A4, %A5) -> %D1 */
-  }
-  else {
-4. shld %S3, %S4, %C /* ShlD(%A3, %A4, %A5) -> %D1 */
-  }
+if (get_ia32_immop_type(node) == ia32_ImmNone) {
+       if (get_ia32_op_type(node) == ia32_AddrModeD) {
+               . shldl %%cl, %S4, %AM
+       } else {
+               . shldl %%cl, %S4, %S3
+       }
+} else {
+       if (get_ia32_op_type(node) == ia32_AddrModeD) {
+               . shldl $%C, %S4, %AM
+       } else {
+               . shldl $%C, %S4, %S3
+       }
 }
 ',
   "latency"   => 6,
-  "units"     => [ "ALU1", "SSE1" ],
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "l_ShlD" => {
   "cmp_attr"  => "return 1;",
   "comment"   => "construct lowered ShlD: ShlD(a, b, c) = a, b << count (shift left count bits from b into a)",
-  "arity"     => 3
+  "arity"     => 3,
 },
 
 "Shr" => {
   "irn_flags" => "R",
   "comment"   => "construct Shr: Shr(a, b) = a >> b",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
-  "emit"      => '. shr %ia32_emit_binop /* Shr(%A1, %A2) -> %D1 */',
-  "units"     => [ "ALU1", "SSE1" ],
+  "emit"      => '. shrl %binop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "l_Shr" => {
@@ -542,27 +527,24 @@ else {
   # (and probably never will). So we create artificial interferences of the result
   # with all inputs, so the spiller can always assure a free register.
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "ecx", "none" ], "out" => [ "!in" ] },
-  "emit"      =>
-'
-if (get_ia32_immop_type(n) == ia32_ImmNone) {
-  if (get_ia32_op_type(n) == ia32_AddrModeD) {
-4. shrd %ia32_emit_am, %S4, %%cl /* ShrD(%A3, %A4, %A5) -> %D1 */
-  }
-  else {
-4. shrd %S3, %S4, %%cl /* ShrD(%A3, %A4, %A5) -> %D1 */
-  }
-}
-else {
-  if (get_ia32_op_type(n) == ia32_AddrModeD) {
-4. shrd %ia32_emit_am, %S4, %C /* ShrD(%A3, %A4, %A5) -> %D1 */
-  }
-  else {
-4. shrd %S3, %S4, %C /* ShrD(%A3, %A4, %A5) -> %D1 */
-  }
+  "emit"      => '
+if (get_ia32_immop_type(node) == ia32_ImmNone) {
+       if (get_ia32_op_type(node) == ia32_AddrModeD) {
+               . shrdl %%cl, %S4, %AM
+       } else {
+               . shrdl %%cl, %S4, %S3
+       }
+} else {
+       if (get_ia32_op_type(node) == ia32_AddrModeD) {
+               . shrdl $%C, %S4, %AM
+       } else {
+               . shrdl $%C, %S4, %S3
+       }
 }
 ',
   "latency"   => 6,
-  "units"     => [ "ALU1", "SSE1" ],
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "l_ShrD" => {
@@ -571,44 +553,48 @@ else {
   "arity"     => 3
 },
 
-"Shrs" => {
+"Sar" => {
   "irn_flags" => "R",
   "comment"   => "construct Shrs: Shrs(a, b) = a >> b",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
-  "emit"      => '. sar %ia32_emit_binop /* Shrs(%A1, %A2) -> %D1 */',
-  "units"     => [ "ALU1", "SSE1" ],
+  "emit"      => '. sarl %binop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
-"l_Shrs" => {
+"l_Sar" => {
   "cmp_attr"  => "return 1;",
-  "comment"   => "construct lowered Shrs: Shrs(a, b) = a << b",
+  "comment"   => "construct lowered Sar: Sar(a, b) = a << b",
   "arity"     => 2
 },
 
-"RotR" => {
+"Ror" => {
   "irn_flags" => "R",
-  "comment"     => "construct RotR: RotR(a, b) = a ROTR b",
-  "reg_req"     => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
-  "emit"        => '. ror %ia32_emit_binop /* RotR(%A1, %A2) -> %D1 */',
-  "units"     => [ "ALU1", "SSE1" ],
+  "comment"   => "construct Ror: Ror(a, b) = a ROR b",
+  "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
+  "emit"      => '. rorl %binop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
-"RotL" => {
+"Rol" => {
   "irn_flags" => "R",
-  "comment"   => "construct RotL: RotL(a, b) = a ROTL b",
+  "comment"   => "construct Rol: Rol(a, b) = a ROL b",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
-  "emit"      => '. rol %ia32_emit_binop /* RotL(%A1, %A2) -> %D1 */',
-  "units"     => [ "ALU1", "SSE1" ],
+  "emit"      => '. roll %binop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 # unary operations
 
-"Minus" => {
+"Neg" => {
   "irn_flags" => "R",
   "comment"   => "construct Minus: Minus(a) = -a",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. neg %ia32_emit_unop /* Neg(%A1) -> %D1, (%A1) */',
-  "units"     => [ "ALU" ],
+  "emit"      => '. negl %unop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "Minus64Bit" => {
@@ -617,17 +603,17 @@ else {
   "arity"     => 4,
   "reg_req"   => { "in" => [ "gp", "gp", "gp" ], "out" => [ "!in", "!in" ] },
   "emit"      => '
-. mov %D1, %S1 /* l_res */
-. mov %D2, %S1 /* h_res */
-. sub %D1, %S2 /* 0 - a_l  ->  low_res */
-. sbb %D2, %S3 /* 0 - a_h - borrow -> high_res */
+. movl %S1, %D1
+. movl %S1, %D2
+. subl %S2, %D1
+. sbbl %S3, %D2
 ',
   "outs"      => [ "low_res", "high_res" ],
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
 },
 
 
-"l_Minus" => {
+"l_Neg" => {
   "cmp_attr"  => "return 1;",
   "comment"   => "construct lowered Minus: Minus(a) = -a",
   "arity"     => 1,
@@ -637,24 +623,27 @@ else {
   "irn_flags" => "R",
   "comment"   => "construct Increment: Inc(a) = a++",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. inc %ia32_emit_unop /* Inc(%S1) -> %D1, (%A1) */',
-  "units"     => [ "ALU" ],
+  "emit"      => '. incl %unop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "Dec" => {
   "irn_flags" => "R",
   "comment"   => "construct Decrement: Dec(a) = a--",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. dec %ia32_emit_unop /* Dec(%S1) -> %D1, (%A1) */',
-  "units"     => [ "ALU" ],
+  "emit"      => '. decl %unop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "Not" => {
   "irn_flags" => "R",
   "comment"   => "construct Not: Not(a) = !a",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. not %ia32_emit_unop /* Not(%S1) -> %D1, (%A1) */',
-  "units"     => [ "ALU" ],
+  "emit"      => '. notl %unop',
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 # other operations
@@ -705,17 +694,109 @@ else {
   "irn_flags" => "R",
   "comment"   => "represents an integer constant",
   "reg_req"   => { "out" => [ "gp" ] },
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
-"Cdq" => {
+"Unknown_GP" => {
+  "op_flags"  => "c",
+  "irn_flags" => "I",
+  "comment"   => "unknown value",
+  "reg_req"   => { "out" => [ "gp_UKNWN" ] },
+  "units"     => [],
+  "emit"      => "",
+  "mode"      => "mode_Iu"
+},
+
+"Unknown_VFP" => {
+  "op_flags"  => "c",
+  "irn_flags" => "I",
+  "comment"   => "unknown value",
+  "reg_req"   => { "out" => [ "vfp_UKNWN" ] },
+  "units"     => [],
+  "emit"      => "",
+  "mode"      => "mode_E"
+},
+
+"Unknown_XMM" => {
+  "op_flags"  => "c",
+  "irn_flags" => "I",
+  "comment"   => "unknown value",
+  "reg_req"   => { "out" => [ "xmm_UKNWN" ] },
+  "units"     => [],
+  "emit"      => "",
+  "mode"      => "mode_E"
+},
+
+"NoReg_GP" => {
+  "op_flags"  => "c",
+  "irn_flags" => "I",
+  "comment"   => "unknown GP value",
+  "reg_req"   => { "out" => [ "gp_NOREG" ] },
+  "units"     => [],
+  "emit"      => "",
+  "mode"      => "mode_Iu"
+},
+
+"NoReg_VFP" => {
+  "op_flags"  => "c",
+  "irn_flags" => "I",
+  "comment"   => "unknown VFP value",
+  "reg_req"   => { "out" => [ "vfp_NOREG" ] },
+  "units"     => [],
+  "emit"      => "",
+  "mode"      => "mode_E"
+},
+
+"NoReg_XMM" => {
+  "op_flags"  => "c",
+  "irn_flags" => "I",
+  "comment"   => "unknown XMM value",
+  "reg_req"   => { "out" => [ "xmm_NOREG" ] },
+  "units"     => [],
+  "emit"      => "",
+  "mode"      => "mode_E"
+},
+
+"ChangeCW" => {
+  "irn_flags" => "R",
+  "comment"   => "change floating point control word",
+  "reg_req"   => { "out" => [ "fp_cw" ] },
+  "mode"      => "mode_Hu",
+  "latency"   => 3,
+  "units"     => [ "GP" ],
+},
+
+"FldCW" => {
+  "op_flags"  => "L|F",
+  "state"     => "exc_pinned",
+  "comment"   => "load floating point control word FldCW(ptr, mem) = LD ptr -> reg",
+  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "fp_cw" ] },
+  "latency"   => 5,
+  "emit"      => ". fldcw %AM",
+  "mode"      => "mode_Hu",
+  "units"     => [ "GP" ],
+},
+
+"FstCW" => {
+  "op_flags"  => "L|F",
+  "state"     => "exc_pinned",
+  "comment"   => "store floating point control word: FstCW(ptr, mem) = ST ptr -> reg",
+  "reg_req"   => { "in" => [ "gp", "gp", "fp_cw", "none" ] },
+  "latency"   => 5,
+  "emit"      => ". fstcw %AM",
+  "mode"      => "mode_M",
+  "units"     => [ "GP" ],
+},
+
+"Cltd" => {
   # we should not rematrialize this node. It produces 2 results and has
   # very strict constrains
   "comment"   => "construct CDQ: sign extend EAX -> EDX:EAX",
   "reg_req"   => { "in" => [ "gp" ], "out" => [ "eax in_r1", "edx" ] },
-  "emit"      => '. cdq /* sign extend EAX -> EDX:EAX, (%A1) */',
+  "emit"      => '. cltd',
   "outs"      => [ "EAX", "EDX" ],
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
 },
 
 # Load / Store
@@ -724,18 +805,11 @@ else {
   "op_flags"  => "L|F",
   "state"     => "exc_pinned",
   "comment"   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
-  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "gp" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "gp", "none" ] },
   "latency"   => 3,
-  "emit"      =>
-'  if (get_mode_size_bits(get_ia32_ls_mode(n)) < 32) {
-4.   mov%Mx %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */
-  }
-  else {
-4.   mov %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */
-  }
-',
+  "emit"      => ". mov%SE%ME%.l %AM, %D1",
   "outs"      => [ "res", "M" ],
-  "units"     => [ "MEM" ],
+  "units"     => [ "GP" ],
 },
 
 "l_Load" => {
@@ -760,9 +834,9 @@ else {
   "state"     => "exc_pinned",
   "comment"   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ] },
-  "emit"      => '. mov %ia32_emit_binop /* Store(%A3) -> (%A1) */',
+  "emit"      => '. mov%M %binop',
   "latency"   => 3,
-  "units"     => [ "MEM" ],
+  "units"     => [ "GP" ],
   "mode"      => "mode_M",
 },
 
@@ -771,9 +845,9 @@ else {
   "state"     => "exc_pinned",
   "comment"   => "construct 8Bit Store: Store(ptr, val, mem) = ST ptr,val",
   "reg_req"   => { "in" => [ "gp", "gp", "eax ebx ecx edx", "none" ] },
-  "emit"      => '. mov %ia32_emit_binop /* Store(%A3) -> (%A1) */',
+  "emit"      => '. mov%M %binop',
   "latency"   => 3,
-  "units"     => [ "MEM" ],
+  "units"     => [ "GP" ],
   "mode"      => "mode_M",
 },
 
@@ -781,69 +855,71 @@ else {
   "irn_flags" => "R",
   "comment"   => "construct Lea: Lea(a,b) = lea [a+b*const+offs] | res = a + b * const + offs with const = 0,1,2,4,8",
   "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] },
-  "emit"      => '. lea %D1, %ia32_emit_am /* LEA(%A1, %A2) */',
+  "emit"      => '. leal %AM, %D1',
   "latency"   => 2,
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "Push" => {
   "comment"   => "push on the stack",
-  "reg_req"   => { "in" => [ "gp", "gp", "gp", "esp", "none" ], "out" => [ "esp" ] },
-  "emit"      => '. push %ia32_emit_unop /* PUSH(%A1) */',
+  "reg_req"   => { "in" => [ "gp", "gp", "gp", "esp", "none" ], "out" => [ "esp", "none" ] },
+  "emit"      => '. pushl %unop',
   "outs"      => [ "stack:I|S", "M" ],
   "latency"   => 3,
-  "units"     => [ "MEM" ],
+  "units"     => [ "GP" ],
 },
 
 "Pop" => {
-  # We don't set class modify stack here (but we will do this on proj 1)
   "comment"   => "pop a gp register from the stack",
-  "reg_req"   => { "in" => [ "gp", "gp", "esp", "none" ], "out" => [ "gp", "esp" ] },
-  "emit"      => '. pop %ia32_emit_unop /* POP(%A1) */',
-  "outs"      => [ "res", "stack:I|S", "M" ],
+  "reg_req"   => { "in" => [ "gp", "gp", "esp", "none" ], "out" => [ "esp", "gp", "none" ] },
+  "emit"      => '. popl %unop',
+  "outs"      => [ "stack:I|S", "res", "M" ],
   "latency"   => 4,
-  "units"     => [ "MEM" ],
+  "units"     => [ "GP" ],
 },
 
 "Enter" => {
   "comment"   => "create stack frame",
   "reg_req"   => { "in" => [ "esp" ], "out" => [ "ebp", "esp" ] },
-  "emit"      => '. enter /* Enter */',
+  "emit"      => '. enter',
   "outs"      => [ "frame:I", "stack:I|S", "M" ],
   "latency"   => 15,
-  "units"     => [ "MEM" ],
+  "units"     => [ "GP" ],
 },
 
 "Leave" => {
   "comment"   => "destroy stack frame",
   "reg_req"   => { "in" => [ "esp", "ebp" ], "out" => [ "ebp", "esp" ] },
-  "emit"      => '. leave /* Leave */',
-  "outs"      => [ "frame:I", "stack:I|S", "M" ],
+  "emit"      => '. leave',
+  "outs"      => [ "frame:I", "stack:I|S" ],
   "latency"   => 3,
-  "units"     => [ "MEM" ],
+  "units"     => [ "GP" ],
 },
 
 "AddSP" => {
   "irn_flags" => "I",
   "comment"   => "allocate space on stack",
-  "reg_req"   => { "in" => [ "esp", "gp" ], "out" => [ "esp", "none" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "esp", "gp", "none" ], "out" => [ "in_r3", "none" ] },
+  "emit"      => '. addl %binop',
   "outs"      => [ "stack:S", "M" ],
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
 },
 
 "SubSP" => {
   "irn_flags" => "I",
   "comment"   => "free space on stack",
-  "reg_req"   => { "in" => [ "esp", "gp" ], "out" => [ "esp", "none" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "esp", "gp", "none" ], "out" => [ "in_r3", "none" ] },
+  "emit"      => '. subl %binop',
   "outs"      => [ "stack:S", "M" ],
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
 },
 
 "LdTls" => {
   "irn_flags" => "R",
   "comment"   => "get the TLS base address",
   "reg_req"   => { "out" => [ "gp" ] },
-  "units"     => [ "MEM" ],
+  "units"     => [ "GP" ],
 },
 
 
@@ -863,62 +939,69 @@ else {
   "irn_flags" => "R",
   "comment"   => "construct SSE Add: Add(a, b) = Add(b, a) = a + b",
   "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. adds%M %ia32_emit_binop /* SSE Add(%A3, %A4) -> %D1 */',
+  "emit"      => '. add%XXM %binop',
   "latency"   => 4,
   "units"     => [ "SSE" ],
+  "mode"      => "mode_E",
 },
 
 "xMul" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE Mul: Mul(a, b) = Mul(b, a) = a * b",
   "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. muls%M %ia32_emit_binop /* SSE Mul(%A3, %A4) -> %D1 */',
+  "emit"      => '. mul%XXM %binop',
   "latency"   => 4,
   "units"     => [ "SSE" ],
+  "mode"      => "mode_E",
 },
 
 "xMax" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE Max: Max(a, b) = Max(b, a) = a > b ? a : b",
   "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. maxs%M %ia32_emit_binop /* SSE Max(%A3, %A4) -> %D1 */',
+  "emit"      => '. max%XXM %binop',
   "latency"   => 2,
   "units"     => [ "SSE" ],
+  "mode"      => "mode_E",
 },
 
 "xMin" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE Min: Min(a, b) = Min(b, a) = a < b ? a : b",
   "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. mins%M %ia32_emit_binop /* SSE Min(%A3, %A4) -> %D1 */',
+  "emit"      => '. min%XXM %binop',
   "latency"   => 2,
   "units"     => [ "SSE" ],
+  "mode"      => "mode_E",
 },
 
 "xAnd" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE And: And(a, b) = a AND b",
   "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. andp%M %ia32_emit_binop /* SSE And(%A3, %A4) -> %D1 */',
+  "emit"      => '. andp%XXM %binop',
   "latency"   => 3,
   "units"     => [ "SSE" ],
+  "mode"      => "mode_E",
 },
 
 "xOr" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE Or: Or(a, b) = a OR b",
   "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. orp%M %ia32_emit_binop /* SSE Or(%A3, %A4) -> %D1 */',
+  "emit"      => '. orp%XXM %binop',
   "units"     => [ "SSE" ],
+  "mode"      => "mode_E",
 },
 
-"xEor" => {
+"xXor" => {
   "irn_flags" => "R",
-  "comment"   => "construct SSE Eor: Eor(a, b) = a XOR b",
+  "comment"   => "construct SSE Xor: Xor(a, b) = a XOR b",
   "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. xorp%M %ia32_emit_binop /* SSE Xor(%A3, %A4) -> %D1 */',
+  "emit"      => '. xorp%XXM %binop',
   "latency"   => 3,
   "units"     => [ "SSE" ],
+  "mode"      => "mode_E",
 },
 
 # not commutative operations
@@ -927,18 +1010,20 @@ else {
   "irn_flags" => "R",
   "comment"   => "construct SSE AndNot: AndNot(a, b) = a AND NOT b",
   "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3 !in_r4" ] },
-  "emit"      => '. andnp%M %ia32_emit_binop /* SSE AndNot(%A3, %A4) -> %D1 */',
+  "emit"      => '. andnp%XXM %binop',
   "latency"   => 3,
   "units"     => [ "SSE" ],
+  "mode"      => "mode_E",
 },
 
 "xSub" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE Sub: Sub(a, b) = a - b",
   "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
-  "emit"      => '. subs%M %ia32_emit_binop /* SSE Sub(%A1, %A2) -> %D1 */',
+  "emit"      => '. sub%XXM %binop',
   "latency"   => 4,
   "units"     => [ "SSE" ],
+  "mode"      => "mode_E",
 },
 
 "xDiv" => {
@@ -946,7 +1031,7 @@ else {
   "comment"   => "construct SSE Div: Div(a, b) = a / b",
   "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3 !in_r4" ] },
   "outs"      => [ "res", "M" ],
-  "emit"      => '. divs%M %ia32_emit_binop /* SSE Div(%A1, %A2) -> %D1 */',
+  "emit"      => '. div%XXM %binop',
   "latency"   => 16,
   "units"     => [ "SSE" ],
 },
@@ -959,6 +1044,7 @@ else {
   "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3 !in_r4" ] },
   "latency"   => 3,
   "units"     => [ "SSE" ],
+  "mode"      => "mode_E",
 },
 
 "xCondJmp" => {
@@ -975,9 +1061,10 @@ else {
   "irn_flags" => "R",
   "comment"   => "represents a SSE constant",
   "reg_req"   => { "out" => [ "xmm" ] },
-  "emit"      => '. movs%M %D1, %C /* Load fConst into register */',
+  "emit"      => '. mov%XXM $%C, %D1',
   "latency"   => 2,
   "units"     => [ "SSE" ],
+  "mode"      => "mode_E",
 },
 
 # Load / Store
@@ -986,8 +1073,8 @@ else {
   "op_flags"  => "L|F",
   "state"     => "exc_pinned",
   "comment"   => "construct SSE Load: Load(ptr, mem) = LD ptr",
-  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "xmm" ] },
-  "emit"      => '. movs%M %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */',
+  "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "xmm", "none" ] },
+  "emit"      => '. mov%XXM %AM, %D1',
   "outs"      => [ "res", "M" ],
   "latency"   => 2,
   "units"     => [ "SSE" ],
@@ -998,9 +1085,9 @@ else {
   "state"    => "exc_pinned",
   "comment"  => "construct Store: Store(ptr, val, mem) = ST ptr,val",
   "reg_req"  => { "in" => [ "gp", "gp", "xmm", "none" ] },
-  "emit"     => '. movs%M %ia32_emit_binop /* Store(%S3) -> (%A1) */',
+  "emit"     => '. mov%XXM %binop',
   "latency"  => 2,
-  "units"    => [ "MEM" ],
+  "units"    => [ "SSE" ],
   "mode"     => "mode_M",
 },
 
@@ -1009,9 +1096,9 @@ else {
   "state"    => "exc_pinned",
   "comment"  => "construct Store without index: Store(ptr, val, mem) = ST ptr,val",
   "reg_req"  => { "in" => [ "gp", "xmm", "none" ] },
-  "emit"     => '. movs%M %ia32_emit_am, %S2 /* store XMM0 onto stack */',
+  "emit"     => '. mov%XXM %S2, %AM',
   "latency"  => 2,
-  "units"    => [ "MEM" ],
+  "units"    => [ "SSE" ],
   "mode"     => "mode_M",
 },
 
@@ -1035,9 +1122,9 @@ else {
   "state"    => "exc_pinned",
   "comment"  => "store ST0 onto stack",
   "reg_req"  => { "in" => [ "gp", "gp", "none" ] },
-  "emit"     => '. fstp %ia32_emit_am /* store ST0 onto stack */',
+  "emit"     => '. fstp%XM %AM',
   "latency"  => 4,
-  "units"    => [ "MEM" ],
+  "units"    => [ "SSE" ],
   "mode"     => "mode_M",
 },
 
@@ -1047,10 +1134,10 @@ else {
   "state"    => "exc_pinned",
   "comment"  => "load ST0 from stack",
   "reg_req"  => { "in" => [ "gp", "none" ], "out" => [ "vf0", "none" ] },
-  "emit"     => '. fld %ia32_emit_am /* load ST0 from stack */',
+  "emit"     => '. fld%M %AM',
   "outs"     => [ "res", "M" ],
   "latency"  => 2,
-  "units"     => [ "MEM" ],
+  "units"     => [ "SSE" ],
 },
 
 # CopyB
@@ -1061,7 +1148,7 @@ else {
   "comment"  => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)",
   "reg_req"  => { "in" => [ "edi", "esi", "ecx", "none" ], "out" => [ "edi", "esi", "ecx", "none" ] },
   "outs"     => [ "DST", "SRC", "CNT", "M" ],
-  "units"     => [ "MEM" ],
+  "units"     => [ "GP" ],
 },
 
 "CopyB_i" => {
@@ -1070,7 +1157,7 @@ else {
   "comment"  => "implements a memcopy: CopyB(dst, src, mem) == memcpy(dst, src, attr(size))",
   "reg_req"  => { "in" => [ "edi", "esi", "none" ], "out" => [  "edi", "esi", "none" ] },
   "outs"     => [ "DST", "SRC", "M" ],
-  "units"     => [ "MEM" ],
+  "units"     => [ "GP" ],
 },
 
 # Conversions
@@ -1078,34 +1165,39 @@ else {
 "Conv_I2I" => {
   "reg_req"  => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3", "none" ] },
   "comment"  => "construct Conv Int -> Int",
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
+  "mode"     => "mode_Iu",
 },
 
 "Conv_I2I8Bit" => {
   "reg_req"  => { "in" => [ "gp", "gp", "eax ebx ecx edx", "none" ], "out" => [ "in_r3", "none" ] },
   "comment"  => "construct Conv Int -> Int",
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
+  "mode"     => "mode_Iu",
 },
 
 "Conv_I2FP" => {
   "reg_req"  => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "xmm", "none" ] },
   "comment"  => "construct Conv Int -> Floating Point",
   "latency"  => 10,
-  "units"     => [ "SSE" ],
+  "units"    => [ "SSE" ],
+  "mode"     => "mode_E",
 },
 
 "Conv_FP2I" => {
   "reg_req"  => { "in" => [ "gp", "gp", "xmm", "none" ], "out" => [ "gp", "none" ] },
   "comment"  => "construct Conv Floating Point -> Int",
   "latency"  => 10,
-  "units"     => [ "SSE" ],
+  "units"    => [ "SSE" ],
+  "mode"     => "mode_Iu",
 },
 
 "Conv_FP2FP" => {
   "reg_req"  => { "in" => [ "gp", "gp", "xmm", "none" ], "out" => [ "xmm", "none" ] },
   "comment"  => "construct Conv Floating Point -> Floating Point",
   "latency"  => 8,
-  "units"     => [ "SSE" ],
+  "units"    => [ "SSE" ],
+  "mode"     => "mode_E",
 },
 
 "CmpCMov" => {
@@ -1113,7 +1205,8 @@ else {
   "comment"   => "construct Conditional Move: CMov(sel, a, b) == sel ? a : b",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp" ], "out" => [ "in_r4" ] },
   "latency"   => 2,
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "PsiCondCMov" => {
@@ -1121,7 +1214,8 @@ else {
   "comment"   => "check if Psi condition tree evaluates to true and move result accordingly",
   "reg_req"   => { "in" => [ "gp", "gp", "gp" ], "out" => [ "in_r3" ] },
   "latency"   => 2,
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "xCmpCMov" => {
@@ -1130,6 +1224,7 @@ else {
   "reg_req"   => { "in" => [ "xmm", "xmm", "gp", "gp" ], "out" => [ "in_r4" ] },
   "latency"   => 5,
   "units"     => [ "SSE" ],
+  "mode"      => "mode_Iu",
 },
 
 "vfCmpCMov" => {
@@ -1137,15 +1232,17 @@ else {
   "comment"   => "construct Conditional Move: x87 Compare + int CMov",
   "reg_req"   => { "in" => [ "vfp", "vfp", "gp", "gp" ], "out" => [ "in_r4" ] },
   "latency"   => 10,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_Iu",
 },
 
 "CmpSet" => {
   "irn_flags" => "R",
   "comment"   => "construct Set: Set(sel) == sel ? 1 : 0",
-  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "eax ebx ecx edx", "none" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "eax ebx ecx edx" ] },
   "latency"   => 2,
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "PsiCondSet" => {
@@ -1153,23 +1250,26 @@ else {
   "comment"   => "check if Psi condition tree evaluates to true and set result accordingly",
   "reg_req"   => { "in" => [ "gp" ], "out" => [ "eax ebx ecx edx" ] },
   "latency"   => 2,
-  "units"     => [ "ALU" ],
+  "units"     => [ "GP" ],
+  "mode"      => "mode_Iu",
 },
 
 "xCmpSet" => {
   "irn_flags" => "R",
   "comment"   => "construct Set: SSE Compare + int Set",
-  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "eax ebx ecx edx", "none" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "eax ebx ecx edx" ] },
   "latency"   => 5,
   "units"     => [ "SSE" ],
+  "mode"      => "mode_Iu",
 },
 
 "vfCmpSet" => {
   "irn_flags" => "R",
   "comment"   => "construct Set: x87 Compare + int Set",
-  "reg_req"   => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "eax ebx ecx edx", "none" ] },
+  "reg_req"   => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "eax ebx ecx edx" ] },
   "latency"   => 10,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_Iu",
 },
 
 "vfCMov" => {
@@ -1177,7 +1277,8 @@ else {
   "comment"   => "construct x87 Conditional Move: vfCMov(sel, a, b) = sel ? a : b",
   "reg_req"   => { "in" => [ "vfp", "vfp", "vfp", "vfp" ], "out" => [ "vfp" ] },
   "latency"   => 10,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 #----------------------------------------------------------#
@@ -1199,7 +1300,8 @@ else {
   "comment"   => "virtual fp Add: Add(a, b) = Add(b, a) = a + b",
   "reg_req"   => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "vfp" ] },
   "latency"   => 4,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "vfmul" => {
@@ -1207,7 +1309,8 @@ else {
   "comment"   => "virtual fp Mul: Mul(a, b) = Mul(b, a) = a * b",
   "reg_req"   => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "vfp" ] },
   "latency"   => 4,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "l_vfmul" => {
@@ -1222,7 +1325,8 @@ else {
   "comment"   => "virtual fp Sub: Sub(a, b) = a - b",
   "reg_req"   => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "vfp" ] },
   "latency"   => 4,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "l_vfsub" => {
@@ -1236,12 +1340,13 @@ else {
   "reg_req"   => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "vfp" ] },
   "outs"      => [ "res", "M" ],
   "latency"   => 20,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
 },
 
 "l_vfdiv" => {
   "cmp_attr"  => "return 1;",
   "comment"   => "lowered virtual fp Div: Div(a, b) = a / b",
+  "outs"      => [ "res", "M" ],
   "arity"     => 2,
 },
 
@@ -1249,7 +1354,8 @@ else {
   "comment"   => "virtual fp Rem: Rem(a, b) = a - Q * b (Q is integer)",
   "reg_req"   => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "vfp" ] },
   "latency"   => 20,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "l_vfprem" => {
@@ -1263,7 +1369,8 @@ else {
   "comment"   => "virtual fp Abs: Abs(a) = |a|",
   "reg_req"   => { "in" => [ "vfp"], "out" => [ "vfp" ] },
   "latency"   => 2,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "vfchs" => {
@@ -1271,7 +1378,8 @@ else {
   "comment"   => "virtual fp Chs: Chs(a) = -a",
   "reg_req"   => { "in" => [ "vfp"], "out" => [ "vfp" ] },
   "latency"   => 2,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "vfsin" => {
@@ -1279,7 +1387,8 @@ else {
   "comment"   => "virtual fp Sin: Sin(a) = sin(a)",
   "reg_req"   => { "in" => [ "vfp"], "out" => [ "vfp" ] },
   "latency"   => 150,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "vfcos" => {
@@ -1287,7 +1396,8 @@ else {
   "comment"   => "virtual fp Cos: Cos(a) = cos(a)",
   "reg_req"   => { "in" => [ "vfp"], "out" => [ "vfp" ] },
   "latency"   => 150,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "vfsqrt" => {
@@ -1295,7 +1405,8 @@ else {
   "comment"   => "virtual fp Sqrt: Sqrt(a) = a ^ 0.5",
   "reg_req"   => { "in" => [ "vfp"], "out" => [ "vfp" ] },
   "latency"   => 30,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 # virtual Load and Store
@@ -1307,7 +1418,7 @@ else {
   "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "vfp", "none" ] },
   "outs"      => [ "res", "M" ],
   "latency"   => 2,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
 },
 
 "vfst" => {
@@ -1316,7 +1427,7 @@ else {
   "comment"   => "virtual fp Store: Store(ptr, val, mem) = ST ptr,val",
   "reg_req"   => { "in" => [ "gp", "gp", "vfp", "none" ] },
   "latency"   => 2,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
   "mode"      => "mode_M",
 },
 
@@ -1327,7 +1438,7 @@ else {
   "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "vfp", "none" ] },
   "outs"      => [ "res", "M" ],
   "latency"   => 4,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
 },
 
 "l_vfild" => {
@@ -1341,7 +1452,7 @@ else {
   "comment"   => "virtual fp integer Store: Store(ptr, val, mem) = iST ptr,val",
   "reg_req"   => { "in" => [ "gp", "gp", "vfp", "none" ] },
   "latency"   => 4,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
   "mode"      => "mode_M",
 },
 
@@ -1360,7 +1471,8 @@ else {
   "comment"   => "virtual fp Load 0.0: Ld 0.0 -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
   "latency"   => 4,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "vfld1" => {
@@ -1368,7 +1480,8 @@ else {
   "comment"   => "virtual fp Load 1.0: Ld 1.0 -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
   "latency"   => 4,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "vfldpi" => {
@@ -1376,7 +1489,8 @@ else {
   "comment"   => "virtual fp Load pi: Ld pi -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
   "latency"   => 4,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "vfldln2" => {
@@ -1384,7 +1498,8 @@ else {
   "comment"   => "virtual fp Load ln 2: Ld ln 2 -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
   "latency"   => 4,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "vfldlg2" => {
@@ -1392,7 +1507,8 @@ else {
   "comment"   => "virtual fp Load lg 2: Ld lg 2 -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
   "latency"   => 4,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "vfldl2t" => {
@@ -1400,7 +1516,8 @@ else {
   "comment"   => "virtual fp Load ld 10: Ld ld 10 -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
   "latency"   => 4,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "vfldl2e" => {
@@ -1408,17 +1525,19 @@ else {
   "comment"   => "virtual fp Load ld e: Ld ld e -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
   "latency"   => 4,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 "vfConst" => {
   "op_flags"  => "c",
   "irn_flags" => "R",
-  "init_attr" => "  set_ia32_ls_mode(res, mode);",
+#  "init_attr" => "  set_ia32_ls_mode(res, mode);",
   "comment"   => "represents a virtual floating point constant",
   "reg_req"   => { "out" => [ "vfp" ] },
   "latency"   => 3,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
+  "mode"      => "mode_E",
 },
 
 # other
@@ -1429,7 +1548,7 @@ else {
   "reg_req"   => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "none", "none", "eax" ] },
   "outs"      => [ "false", "true", "temp_reg_eax" ],
   "latency"   => 10,
-  "units"     => [ "FPU" ],
+  "units"     => [ "VFP" ],
 },
 
 #------------------------------------------------------------------------#
@@ -1445,7 +1564,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 Add: Add(a, b) = Add(b, a) = a + b",
   "reg_req"   => { },
-  "emit"      => '. fadd %ia32_emit_x87_binop /* x87 fadd(%A3, %A4) -> %D1 */',
+  "emit"      => '. fadd%XM %x87_binop',
 },
 
 "faddp" => {
@@ -1453,7 +1572,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 Add: Add(a, b) = Add(b, a) = a + b",
   "reg_req"   => { },
-  "emit"      => '. faddp %ia32_emit_x87_binop /* x87 fadd(%A3, %A4) -> %D1 */',
+  "emit"      => '. faddp %x87_binop',
 },
 
 "fmul" => {
@@ -1461,7 +1580,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp Mul: Mul(a, b) = Mul(b, a) = a + b",
   "reg_req"   => { },
-  "emit"      => '. fmul %ia32_emit_x87_binop /* x87 fmul(%A3, %A4) -> %D1 */',
+  "emit"      => '. fmul%XM %x87_binop',
 },
 
 "fmulp" => {
@@ -1469,7 +1588,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp Mul: Mul(a, b) = Mul(b, a) = a + b",
   "reg_req"   => { },
-  "emit"      => '. fmulp %ia32_emit_x87_binop /* x87 fmul(%A3, %A4) -> %D1 */',,
+  "emit"      => '. fmulp %x87_binop',,
 },
 
 "fsub" => {
@@ -1477,7 +1596,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp Sub: Sub(a, b) = a - b",
   "reg_req"   => { },
-  "emit"      => '. fsub %ia32_emit_x87_binop /* x87 fsub(%A3, %A4) -> %D1 */',
+  "emit"      => '. fsub%XM %x87_binop',
 },
 
 "fsubp" => {
@@ -1485,7 +1604,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp Sub: Sub(a, b) = a - b",
   "reg_req"   => { },
-  "emit"      => '. fsubp %ia32_emit_x87_binop /* x87 fsub(%A3, %A4) -> %D1 */',
+  "emit"      => '. fsubp %x87_binop',
 },
 
 "fsubr" => {
@@ -1494,7 +1613,7 @@ else {
   "irn_flags" => "R",
   "comment"   => "x87 fp SubR: SubR(a, b) = b - a",
   "reg_req"   => { },
-  "emit"      => '. fsubr %ia32_emit_x87_binop /* x87 fsubr(%A3, %A4) -> %D1 */',
+  "emit"      => '. fsubr%XM %x87_binop',
 },
 
 "fsubrp" => {
@@ -1503,7 +1622,7 @@ else {
   "irn_flags" => "R",
   "comment"   => "x87 fp SubR: SubR(a, b) = b - a",
   "reg_req"   => { },
-  "emit"      => '. fsubrp %ia32_emit_x87_binop /* x87 fsubr(%A3, %A4) -> %D1 */',
+  "emit"      => '. fsubrp %x87_binop',
 },
 
 "fprem" => {
@@ -1511,7 +1630,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp Rem: Rem(a, b) = a - Q * b (Q is integer)",
   "reg_req"   => { },
-  "emit"      => '. fprem1 /* x87 fprem(%A3, %A4) -> %D1 */',
+  "emit"      => '. fprem1',
 },
 
 # this node is just here, to keep the simulator running
@@ -1521,7 +1640,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp Rem: Rem(a, b) = a - Q * b (Q is integer)",
   "reg_req"   => { },
-  "emit"      => '. fprem1 /* x87 fprem(%A3, %A4) -> %D1 WITH POP */',
+  "emit"      => '. fprem1',
 },
 
 "fdiv" => {
@@ -1529,7 +1648,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp Div: Div(a, b) = a / b",
   "reg_req"   => { },
-  "emit"      => '. fdiv %ia32_emit_x87_binop /* x87 fdiv(%A3, %A4) -> %D1 */',
+  "emit"      => '. fdiv%XM %x87_binop',
 },
 
 "fdivp" => {
@@ -1537,7 +1656,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp Div: Div(a, b) = a / b",
   "reg_req"   => { },
-  "emit"      => '. fdivp %ia32_emit_x87_binop /* x87 fdiv(%A3, %A4) -> %D1 */',
+  "emit"      => '. fdivp %x87_binop',
 },
 
 "fdivr" => {
@@ -1545,7 +1664,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp DivR: DivR(a, b) = b / a",
   "reg_req"   => { },
-  "emit"      => '. fdivr %ia32_emit_x87_binop /* x87 fdivr(%A3, %A4) -> %D1 */',
+  "emit"      => '. fdivr%XM %x87_binop',
 },
 
 "fdivrp" => {
@@ -1553,7 +1672,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp DivR: DivR(a, b) = b / a",
   "reg_req"   => { },
-  "emit"      => '. fdivrp %ia32_emit_x87_binop /* x87 fdivr(%A3, %A4) -> %D1 */',
+  "emit"      => '. fdivrp %x87_binop',
 },
 
 "fabs" => {
@@ -1561,7 +1680,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp Abs: Abs(a) = |a|",
   "reg_req"   => { },
-  "emit"      => '. fabs /* x87 fabs(%A1) -> %D1 */',
+  "emit"      => '. fabs',
 },
 
 "fchs" => {
@@ -1569,7 +1688,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp Chs: Chs(a) = -a",
   "reg_req"   => { },
-  "emit"      => '. fchs /* x87 fchs(%A1) -> %D1 */',
+  "emit"      => '. fchs',
 },
 
 "fsin" => {
@@ -1577,7 +1696,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp Sin: Sin(a) = sin(a)",
   "reg_req"   => { },
-  "emit"      => '. fsin /* x87 sin(%A1) -> %D1 */',
+  "emit"      => '. fsin',
 },
 
 "fcos" => {
@@ -1585,7 +1704,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp Cos: Cos(a) = cos(a)",
   "reg_req"   => { },
-  "emit"      => '. fcos /* x87 cos(%A1) -> %D1 */',
+  "emit"      => '. fcos',
 },
 
 "fsqrt" => {
@@ -1593,7 +1712,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp Sqrt: Sqrt(a) = a ^ 0.5",
   "reg_req"   => { },
-  "emit"      => '. fsqrt $ /* x87 sqrt(%A1) -> %D1 */',
+  "emit"      => '. fsqrt $',
 },
 
 # x87 Load and Store
@@ -1604,7 +1723,7 @@ else {
   "state"     => "exc_pinned",
   "comment"   => "x87 fp Load: Load(ptr, mem) = LD ptr -> reg",
   "reg_req"   => { },
-  "emit"      => '. fld %ia32_emit_am /* Load((%A1)) -> %D1 */',
+  "emit"      => '. fld%XM %AM',
 },
 
 "fst" => {
@@ -1613,7 +1732,7 @@ else {
   "state"     => "exc_pinned",
   "comment"   => "x87 fp Store: Store(ptr, val, mem) = ST ptr,val",
   "reg_req"   => { },
-  "emit"      => '. fst %ia32_emit_am /* Store(%A3) -> (%A1) */',
+  "emit"      => '. fst%XM %AM',
   "mode"      => "mode_M",
 },
 
@@ -1623,7 +1742,7 @@ else {
   "state"     => "exc_pinned",
   "comment"   => "x87 fp Store: Store(ptr, val, mem) = ST ptr,val",
   "reg_req"   => { },
-  "emit"      => '. fstp %ia32_emit_am /* Store(%A3) -> (%A1) and pop */',
+  "emit"      => '. fstp%XM %AM',
   "mode"      => "mode_M",
 },
 
@@ -1634,7 +1753,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp integer Load: Load(ptr, mem) = iLD ptr -> reg",
   "reg_req"   => { },
-  "emit"      => '. fild %ia32_emit_am /* integer Load((%A1)) -> %D1 */',
+  "emit"      => '. fild%XM %AM',
 },
 
 "fist" => {
@@ -1642,7 +1761,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp integer Store: Store(ptr, val, mem) = iST ptr,val",
   "reg_req"   => { },
-  "emit"      => '. fist %ia32_emit_am /* integer Store(%A3) -> (%A1) */',
+  "emit"      => '. fist%M %AM',
   "mode"      => "mode_M",
 },
 
@@ -1651,7 +1770,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "x87 fp integer Store: Store(ptr, val, mem) = iST ptr,val",
   "reg_req"   => { },
-  "emit"      => '. fistp %ia32_emit_am /* integer Store(%A3) -> (%A1) and pop */',
+  "emit"      => '. fistp%M %AM',
   "mode"      => "mode_M",
 },
 
@@ -1662,7 +1781,7 @@ else {
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load 0.0: Ld 0.0 -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
-  "emit"      => '. fldz /* x87 0.0 -> %D1 */',
+  "emit"      => '. fldz',
 },
 
 "fld1" => {
@@ -1670,7 +1789,7 @@ else {
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load 1.0: Ld 1.0 -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
-  "emit"      => '. fld1 /* x87 1.0 -> %D1 */',
+  "emit"      => '. fld1',
 },
 
 "fldpi" => {
@@ -1678,7 +1797,7 @@ else {
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load pi: Ld pi -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
-  "emit"      => '. fldpi /* x87 pi -> %D1 */',
+  "emit"      => '. fldpi',
 },
 
 "fldln2" => {
@@ -1686,7 +1805,7 @@ else {
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load ln 2: Ld ln 2 -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
-  "emit"      => '. fldln2 /* x87 ln(2) -> %D1 */',
+  "emit"      => '. fldln2',
 },
 
 "fldlg2" => {
@@ -1694,7 +1813,7 @@ else {
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load lg 2: Ld lg 2 -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
-  "emit"      => '. fldlg2 /* x87 log(2) -> %D1 */',
+  "emit"      => '. fldlg2',
 },
 
 "fldl2t" => {
@@ -1702,7 +1821,7 @@ else {
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load ld 10: Ld ld 10 -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
-  "emit"      => '. fldll2t /* x87 ld(10) -> %D1 */',
+  "emit"      => '. fldll2t',
 },
 
 "fldl2e" => {
@@ -1710,7 +1829,7 @@ else {
   "irn_flags"  => "R",
   "comment"   => "x87 fp Load ld e: Ld ld e -> reg",
   "reg_req"   => { "out" => [ "vfp" ] },
-  "emit"      => '. fldl2e /* x87 ld(e) -> %D1 */',
+  "emit"      => '. fldl2e',
 },
 
 "fldConst" => {
@@ -1719,7 +1838,7 @@ else {
   "rd_constructor" => "NONE",
   "comment"   => "represents a x87 constant",
   "reg_req"   => { "out" => [ "vfp" ] },
-  "emit"      => '. fld %ia32_emit_adr /* Load fConst into register -> %D1 */',
+  "emit"      => '. fld $%C',
 },
 
 # fxch, fpush, fpop
@@ -1731,7 +1850,7 @@ else {
   "comment"   => "x87 stack exchange",
   "reg_req"   => { },
   "cmp_attr"  => "return 1;",
-  "emit"      => '. fxch %X1 /* x87 swap %X1, %X3 */',
+  "emit"      => '. fxch %X1',
 },
 
 "fpush" => {
@@ -1739,7 +1858,7 @@ else {
   "comment"   => "x87 stack push",
   "reg_req"   => {},
   "cmp_attr"  => "return 1;",
-  "emit"      => '. fld %X1 /* x87 push %X1 */',
+  "emit"      => '. fld %X1',
 },
 
 "fpushCopy" => {
@@ -1747,7 +1866,7 @@ else {
   "comment"   => "x87 stack push",
   "reg_req"   => { "in" => [ "vfp"], "out" => [ "vfp" ] },
   "cmp_attr"  => "return 1;",
-  "emit"      => '. fld %X1 /* x87 push %X1 */',
+  "emit"      => '. fld %X1',
 },
 
 "fpop" => {
@@ -1755,7 +1874,7 @@ else {
   "comment"   => "x87 stack pop",
   "reg_req"   => { },
   "cmp_attr"  => "return 1;",
-  "emit"      => '. fstp %X1 /* x87 pop %X1 */',
+  "emit"      => '. fstp %X1',
 },
 
 # compare