- Introduce nodemap
[libfirm] / ir / be / ia32 / ia32_spec.pl
index feefb1d..ffcb5e7 100644 (file)
@@ -33,6 +33,7 @@ $arch = "ia32";
 #   init_attr => "emit attribute initialization template"
 #   rd_constructor => "c source code which constructs an ir_node"
 #   latency   => "latency of this operation (can be float)"
+#   attr_type => "name of the attribute struct",
 # },
 #
 # ... # (all nodes you need to describe)
@@ -270,7 +271,13 @@ $arch = "ia32";
        XXM => "${arch}_emit_xmm_mode_suffix(env, node);",
        XSD => "${arch}_emit_xmm_mode_suffix_s(env, node);",
        AM => "${arch}_emit_am(env, node);",
-       unop => "${arch}_emit_unop(env, node);",
+       unop0 => "${arch}_emit_unop(env, node, 0);",
+       unop1 => "${arch}_emit_unop(env, node, 1);",
+       unop2 => "${arch}_emit_unop(env, node, 2);",
+       unop3 => "${arch}_emit_unop(env, node, 3);",
+       unop4 => "${arch}_emit_unop(env, node, 4);",
+       DAM0  => "${arch}_emit_am_or_dest_register(env, node, 0);",
+       DAM1  => "${arch}_emit_am_or_dest_register(env, node, 0);",
        binop => "${arch}_emit_binop(env, node);",
        x87_binop => "${arch}_emit_x87_binop(env, node);",
 );
@@ -286,9 +293,29 @@ $arch = "ia32";
 #                                      |_|         #
 #--------------------------------------------------#
 
-$default_cmp_attr  = "return ia32_compare_attr(attr_a, attr_b);";
 $default_attr_type = "ia32_attr_t";
 
+%init_attr = (
+       ia32_attr_t     => "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);",
+       ia32_x87_attr_t =>
+               "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n".
+               "\tinit_ia32_x87_attributes(res);",
+       ia32_asm_attr_t =>
+               "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n".
+               "\tinit_ia32_x87_attributes(res);".
+               "\tinit_ia32_asm_attributes(res);",
+       ia32_immediate_attr_t =>
+               "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n".
+               "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, offset);"
+);
+
+%compare_attr = (
+       ia32_attr_t           => "ia32_compare_nodes_attr",
+       ia32_x87_attr_t       => "ia32_compare_x87_attr",
+       ia32_asm_attr_t       => "ia32_compare_asm_attr",
+       ia32_immediate_attr_t => "ia32_compare_immediate_attr",
+);
+
 %operands = (
 );
 
@@ -306,6 +333,8 @@ Immediate => {
        op_flags  => "c",
        irn_flags => "I",
        reg_req   => { out => [ "gp_NOREG" ] },
+       attr      => "ir_entity *symconst, int symconst_sign, long offset",
+       attr_type => "ia32_immediate_attr_t",
        mode      => $mode_gp,
 },
 
@@ -313,6 +342,7 @@ Asm => {
        mode      => "mode_T",
        arity     => "variable",
        out_arity => "variable",
+       attr_type => "ia32_asm_attr_t",
 },
 
 #-----------------------------------------------------------------#
@@ -386,8 +416,9 @@ Mul => {
        # we should not rematrialize this node. It produces 2 results and has
        # very strict constrains
        reg_req   => { in => [ "gp", "gp", "eax", "gp", "none" ], out => [ "eax", "edx", "none" ] },
-       emit      => '. mul%M %unop',
+       emit      => '. mul%M %unop3',
        outs      => [ "EAX", "EDX", "M" ],
+       ins       => [ "base", "index", "val_high", "val_low", "mem" ],
        latency   => 10,
        units     => [ "GP" ],
        modified_flags => $status_flags
@@ -415,8 +446,9 @@ IMul => {
 IMul1OP => {
        irn_flags => "R",
        reg_req   => { in => [ "gp", "gp", "eax", "gp", "none" ], out => [ "eax", "edx", "none" ] },
-       emit      => '. imul%M %unop',
+       emit      => '. imul%M %unop3',
        outs      => [ "EAX", "EDX", "M" ],
+       ins       => [ "base", "index", "val_high", "val_low", "mem" ],
        latency   => 5,
        units     => [ "GP" ],
        modified_flags => $status_flags
@@ -513,7 +545,7 @@ IDiv => {
        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      => ". idiv%M %unop",
+       emit      => ". idiv%M %unop4",
        outs      => [ "div_res", "mod_res", "M" ],
        latency   => 25,
        units     => [ "GP" ],
@@ -526,7 +558,7 @@ Div => {
        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      => ". div%M %unop",
+       emit      => ". div%M %unop4",
        outs      => [ "div_res", "mod_res", "M" ],
        latency   => 25,
        units     => [ "GP" ],
@@ -535,6 +567,9 @@ Div => {
 
 Shl => {
        irn_flags => "R",
+       # "in_r3" would be enough as out requirement, but the register allocator
+       # does strange things then and doesn't respect the constraint for in4
+       # if the same value is attached to in3 and in4 (if you have "i << i" in C)
        reg_req   => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] },
        ins       => [ "base", "index", "left", "right", "mem" ],
        emit      => '. shl%M %binop',
@@ -553,11 +588,12 @@ ShlD => {
        # Out requirements is: different from all in
        # This is because, out must be different from LowPart and ShiftCount.
        # We could say "!ecx !in_r4" but it can occur, that all values live through
-       # this Shift and the only value dying is the ShiftCount. Then there would be a
-       # register missing, as result must not be ecx and all other registers are
-       # occupied. What we should write is "!in_r4 !in_r5", but this is not supported
-       # (and probably never will). So we create artificial interferences of the result
-       # with all inputs, so the spiller can always assure a free register.
+       # this Shift and the only value dying is the ShiftCount. Then there would be
+       # a register missing, as result must not be ecx and all other registers are
+       # occupied. What we should write is "!in_r4 !in_r5", but this is not
+       # supported (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      =>
 '
@@ -674,7 +710,8 @@ Rol => {
 Neg => {
        irn_flags => "R",
        reg_req   => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
-       emit      => '. neg%M %unop',
+       emit      => '. neg%M %unop2',
+       ins       => [ "base", "index", "val", "mem" ],
        units     => [ "GP" ],
        mode      => $mode_gp,
        modified_flags => $status_flags
@@ -703,7 +740,7 @@ l_Neg => {
 Inc => {
        irn_flags => "R",
        reg_req   => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
-       emit      => '. inc%M %unop',
+       emit      => '. inc%M %unop2',
        units     => [ "GP" ],
        mode      => $mode_gp,
        modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ]
@@ -712,7 +749,7 @@ Inc => {
 Dec => {
        irn_flags => "R",
        reg_req   => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
-       emit      => '. dec%M %unop',
+       emit      => '. dec%M %unop2',
        units     => [ "GP" ],
        mode      => $mode_gp,
        modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ]
@@ -721,7 +758,8 @@ Dec => {
 Not => {
        irn_flags => "R",
        reg_req   => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
-       emit      => '. not%M %unop',
+       ins       => [ "base", "index", "val", "mem" ],
+       emit      => '. not%M %unop2',
        units     => [ "GP" ],
        mode      => $mode_gp,
        modified_flags => []
@@ -795,7 +833,8 @@ Unknown_VFP => {
        reg_req   => { out => [ "vfp_UKNWN" ] },
        units     => [],
        emit      => "",
-       mode      => "mode_E"
+       mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 Unknown_XMM => {
@@ -825,7 +864,8 @@ NoReg_VFP => {
        reg_req   => { out => [ "vfp_NOREG" ] },
        units     => [],
        emit      => "",
-       mode      => "mode_E"
+       mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 NoReg_XMM => {
@@ -851,7 +891,7 @@ ChangeCW => {
 
 FldCW => {
        op_flags  => "L|F",
-       state     => "exc_pinned",
+       state     => "pinned",
        reg_req   => { in => [ "gp", "gp", "none" ], out => [ "fp_cw" ] },
        latency   => 5,
        emit      => ". fldcw %AM",
@@ -862,7 +902,7 @@ FldCW => {
 
 FnstCW => {
        op_flags  => "L|F",
-       state     => "exc_pinned",
+       state     => "pinned",
        reg_req   => { in => [ "gp", "gp", "fp_cw", "none" ], out => [ "none" ] },
        latency   => 5,
        emit      => ". fnstcw %AM",
@@ -873,19 +913,23 @@ FnstCW => {
 Cltd => {
        # we should not rematrialize this node. It produces 2 results and has
        # very strict constrains
-       reg_req   => { in => [ "gp" ], out => [ "eax in_r1", "edx" ] },
+       reg_req   => { in => [ "eax" ], out => [ "edx" ] },
+       ins       => [ "val" ],
        emit      => '. cltd',
-       outs      => [ "EAX", "EDX" ],
+       mode      => $mode_gp,
        units     => [ "GP" ],
 },
 
 # Load / Store
+#
+# Note that we add additional latency values depending on address mode, so a
+# lateny of 0 for load is correct
 
 Load => {
        op_flags  => "L|F",
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none" ], out => [ "gp", "none" ] },
-       latency   => 3,
+       latency   => 0,
        emit      => ". mov%SE%ME%.l %AM, %D0",
        outs      => [ "res", "M" ],
        units     => [ "GP" ],
@@ -911,7 +955,7 @@ Store => {
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "gp", "none" ], out => [ "none" ] },
        emit      => '. mov%M %binop',
-       latency   => 3,
+       latency   => 2,
        units     => [ "GP" ],
        mode      => "mode_M",
 },
@@ -921,7 +965,7 @@ Store8Bit => {
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "eax ebx ecx edx", "none" ], out => ["none" ] },
        emit      => '. mov%M %binop',
-       latency   => 3,
+       latency   => 2,
        units     => [ "GP" ],
        mode      => "mode_M",
 },
@@ -938,18 +982,20 @@ Lea => {
 
 Push => {
        reg_req   => { in => [ "gp", "gp", "gp", "esp", "none" ], out => [ "esp", "none" ] },
-       emit      => '. push%M %unop',
+       emit      => '. push%M %unop2',
+       ins       => [ "base", "index", "val", "stack", "mem" ],
        outs      => [ "stack:I|S", "M" ],
-       latency   => 3,
+       latency   => 2,
        units     => [ "GP" ],
        modified_flags => [],
 },
 
 Pop => {
        reg_req   => { in => [ "gp", "gp", "esp", "none" ], out => [ "esp", "gp", "none" ] },
-       emit      => '. pop%M %unop',
+       emit      => '. pop%M %DAM1',
        outs      => [ "stack:I|S", "res", "M" ],
-       latency   => 4,
+       ins       => [ "base", "index", "stack", "mem" ],
+       latency   => 3, # Pop is more expensive than Push on Athlon
        units     => [ "GP" ],
        modified_flags => [],
 },
@@ -1182,7 +1228,7 @@ CvtSI2SS => {
 CvtSI2SD => {
        op_flags => "L|F",
        reg_req  => { in => [ "gp", "gp", "gp", "none" ], out => [ "xmm" ] },
-       emit     => '. cvtsi2sd %unop',
+       emit     => '. cvtsi2sd %unop2',
        latency  => 2,
        units    => [ "SSE" ],
        mode     => $mode_xmm
@@ -1204,7 +1250,7 @@ l_SSEtoX87 => {
 GetST0 => {
        op_flags => "L|F",
        irn_flags => "I",
-       state    => "exc_pinned",
+       state    => "pinned",
        reg_req  => { in => [ "gp", "gp", "none" ] },
        emit     => '. fstp%XM %AM',
        latency  => 4,
@@ -1215,7 +1261,7 @@ GetST0 => {
 SetST0 => {
        op_flags => "L|F",
        irn_flags => "I",
-       state    => "exc_pinned",
+       state    => "pinned",
        reg_req  => { in => [ "gp", "gp", "none" ], out => [ "vf0", "none" ] },
        ins      => [ "base", "index", "mem" ],
        emit     => '. fld%XM %AM',
@@ -1249,12 +1295,14 @@ CopyB_i => {
 Conv_I2I => {
        reg_req  => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3", "none" ] },
        units    => [ "GP" ],
+       ins      => [ "base", "index", "val", "mem" ],
        mode     => $mode_gp,
        modified_flags => $status_flags
 },
 
 Conv_I2I8Bit => {
        reg_req  => { in => [ "gp", "gp", "eax ebx ecx edx", "none" ], out => [ "in_r3", "none" ] },
+       ins      => [ "base", "index", "val", "mem" ],
        units    => [ "GP" ],
        mode     => $mode_gp,
        modified_flags => $status_flags
@@ -1284,14 +1332,9 @@ Conv_FP2FP => {
 CmpCMov => {
        irn_flags => "R",
        reg_req   => { in => [ "gp", "gp", "gp", "gp" ], out => [ "in_r4" ] },
-       latency   => 2,
-       units     => [ "GP" ],
-       mode      => $mode_gp,
-},
-
-PsiCondCMov => {
-       irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "gp" ], out => [ "in_r3" ] },
+       ins       => [ "cmp_left", "cmp_right", "val_true", "val_false" ],
+       attr      => "pn_Cmp pn_code",
+       init_attr => "attr->pn_code = pn_code;",
        latency   => 2,
        units     => [ "GP" ],
        mode      => $mode_gp,
@@ -1311,19 +1354,15 @@ vfCmpCMov => {
        latency   => 10,
        units     => [ "VFP" ],
        mode      => $mode_gp,
+       attr_type => "ia32_x87_attr_t",
 },
 
 CmpSet => {
        irn_flags => "R",
        reg_req   => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "eax ebx ecx edx" ] },
-       latency   => 2,
-       units     => [ "GP" ],
-       mode      => $mode_gp,
-},
-
-PsiCondSet => {
-       irn_flags => "R",
-       reg_req   => { in => [ "gp" ], out => [ "eax ebx ecx edx" ] },
+       ins       => [ "base", "index", "cmp_left", "cmp_right", "mem" ],
+       attr      => "pn_Cmp pn_code",
+       init_attr => "attr->pn_code = pn_code;",
        latency   => 2,
        units     => [ "GP" ],
        mode      => $mode_gp,
@@ -1343,6 +1382,7 @@ vfCmpSet => {
        latency   => 10,
        units     => [ "VFP" ],
        mode      => $mode_gp,
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfCMov => {
@@ -1351,6 +1391,7 @@ vfCMov => {
        latency   => 10,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 #----------------------------------------------------------#
@@ -1369,18 +1410,22 @@ vfCMov => {
 
 vfadd => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
+       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] },
+       ins       => [ "base", "index", "left", "right", "mem", "fpcw" ],
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfmul => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
+       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] },
+       ins       => [ "base", "index", "left", "right", "mem", "fpcw" ],
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfmul => {
@@ -1391,10 +1436,12 @@ l_vfmul => {
 
 vfsub => {
        irn_flags => "R",
-       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
+       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] },
+       ins       => [ "base", "index", "left", "right", "mem", "fpcw" ],
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfsub => {
@@ -1403,10 +1450,12 @@ l_vfsub => {
 },
 
 vfdiv => {
-       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp", "none" ] },
+       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp", "none" ] },
+       ins       => [ "base", "index", "left", "right", "mem", "fpcw" ],
        outs      => [ "res", "M" ],
        latency   => 20,
        units     => [ "VFP" ],
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfdiv => {
@@ -1416,10 +1465,12 @@ l_vfdiv => {
 },
 
 vfprem => {
-       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
+       reg_req   => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] },
+       ins       => [ "base", "index", "left", "right", "mem", "fpcw" ],
        latency   => 20,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfprem => {
@@ -1430,41 +1481,21 @@ l_vfprem => {
 vfabs => {
        irn_flags => "R",
        reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
+       ins       => [ "value" ],
        latency   => 2,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfchs => {
        irn_flags => "R",
        reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
+       ins       => [ "value" ],
        latency   => 2,
        units     => [ "VFP" ],
        mode      => "mode_E",
-},
-
-vfsin => {
-       irn_flags => "R",
-       reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
-       latency   => 150,
-       units     => [ "VFP" ],
-       mode      => "mode_E",
-},
-
-vfcos => {
-       irn_flags => "R",
-       reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
-       latency   => 150,
-       units     => [ "VFP" ],
-       mode      => "mode_E",
-},
-
-vfsqrt => {
-       irn_flags => "R",
-       reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
-       latency   => 30,
-       units     => [ "VFP" ],
-       mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # virtual Load and Store
@@ -1473,27 +1504,38 @@ vfld => {
        op_flags  => "L|F",
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] },
+       ins       => [ "base", "index", "mem" ],
        outs      => [ "res", "M" ],
+       attr      => "ir_mode *store_mode",
+       init_attr => "attr->attr.ls_mode = store_mode;",
        latency   => 2,
        units     => [ "VFP" ],
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfst => {
        op_flags  => "L|F",
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "vfp", "none" ] },
+       ins       => [ "base", "index", "val", "mem" ],
+       attr      => "ir_mode *store_mode",
+       init_attr => "attr->attr.ls_mode = store_mode;",
        latency   => 2,
        units     => [ "VFP" ],
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # Conversions
 
 vfild => {
+       state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] },
        outs      => [ "res", "M" ],
+       ins       => [ "base", "index", "mem" ],
        latency   => 4,
        units     => [ "VFP" ],
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfild => {
@@ -1503,14 +1545,18 @@ l_vfild => {
 },
 
 vfist => {
+       state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "vfp", "fpcw", "none" ] },
+       ins       => [ "base", "index", "val", "fpcw", "mem" ],
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfist => {
        cmp_attr  => "return 1;",
+       state     => "exc_pinned",
        arity     => 3,
        mode      => "mode_M",
 },
@@ -1524,6 +1570,7 @@ vfldz => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfld1 => {
@@ -1532,6 +1579,7 @@ vfld1 => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldpi => {
@@ -1540,6 +1588,7 @@ vfldpi => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldln2 => {
@@ -1548,6 +1597,7 @@ vfldln2 => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldlg2 => {
@@ -1556,6 +1606,7 @@ vfldlg2 => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldl2t => {
@@ -1564,6 +1615,7 @@ vfldl2t => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldl2e => {
@@ -1572,16 +1624,17 @@ vfldl2e => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfConst => {
        op_flags  => "c",
        irn_flags => "R",
-#  init_attr => "  set_ia32_ls_mode(res, mode);",
        reg_req   => { out => [ "vfp" ] },
        latency   => 3,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # other
@@ -1593,6 +1646,7 @@ vfCondJmp => {
        outs      => [ "false", "true", "temp_reg_eax" ],
        latency   => 10,
        units     => [ "VFP" ],
+       attr_type => "ia32_x87_attr_t",
 },
 
 #------------------------------------------------------------------------#
@@ -1611,6 +1665,7 @@ fadd => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fadd%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 faddp => {
@@ -1618,6 +1673,7 @@ faddp => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. faddp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fmul => {
@@ -1625,6 +1681,7 @@ fmul => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fmul%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fmulp => {
@@ -1632,6 +1689,7 @@ fmulp => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fmulp %x87_binop',,
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsub => {
@@ -1639,6 +1697,7 @@ fsub => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fsub%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsubp => {
@@ -1647,6 +1706,7 @@ fsubp => {
        reg_req   => { },
 # see note about gas bugs
        emit      => '. fsubrp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsubr => {
@@ -1655,6 +1715,7 @@ fsubr => {
        irn_flags => "R",
        reg_req   => { },
        emit      => '. fsubr%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsubrp => {
@@ -1664,6 +1725,7 @@ fsubrp => {
        reg_req   => { },
 # see note about gas bugs
        emit      => '. fsubp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fprem => {
@@ -1671,6 +1733,7 @@ fprem => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fprem1',
+       attr_type => "ia32_x87_attr_t",
 },
 
 # this node is just here, to keep the simulator running
@@ -1680,6 +1743,7 @@ fpremp => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fprem1',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fdiv => {
@@ -1687,6 +1751,7 @@ fdiv => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fdiv%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fdivp => {
@@ -1695,6 +1760,7 @@ fdivp => {
        reg_req   => { },
 # see note about gas bugs
        emit      => '. fdivrp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fdivr => {
@@ -1702,6 +1768,7 @@ fdivr => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fdivr%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fdivrp => {
@@ -1710,6 +1777,7 @@ fdivrp => {
        reg_req   => { },
 # see note about gas bugs
        emit      => '. fdivp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fabs => {
@@ -1717,6 +1785,7 @@ fabs => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fabs',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fchs => {
@@ -1724,27 +1793,7 @@ fchs => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fchs',
-},
-
-fsin => {
-       op_flags  => "R",
-       rd_constructor => "NONE",
-       reg_req   => { },
-       emit      => '. fsin',
-},
-
-fcos => {
-       op_flags  => "R",
-       rd_constructor => "NONE",
-       reg_req   => { },
-       emit      => '. fcos',
-},
-
-fsqrt => {
-       op_flags  => "R",
-       rd_constructor => "NONE",
-       reg_req   => { },
-       emit      => '. fsqrt $',
+       attr_type => "ia32_x87_attr_t",
 },
 
 # x87 Load and Store
@@ -1755,6 +1804,7 @@ fld => {
        state     => "exc_pinned",
        reg_req   => { },
        emit      => '. fld%XM %AM',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fst => {
@@ -1764,6 +1814,7 @@ fst => {
        reg_req   => { },
        emit      => '. fst%XM %AM',
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 fstp => {
@@ -1773,6 +1824,7 @@ fstp => {
        reg_req   => { },
        emit      => '. fstp%XM %AM',
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # Conversions
@@ -1782,22 +1834,27 @@ fild => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fild%XM %AM',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fist => {
        op_flags  => "R",
+       state     => "exc_pinned",
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fist%XM %AM',
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 fistp => {
        op_flags  => "R",
+       state     => "exc_pinned",
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fistp%XM %AM',
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # constants
@@ -1807,6 +1864,7 @@ fldz => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldz',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fld1 => {
@@ -1814,6 +1872,7 @@ fld1 => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fld1',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldpi => {
@@ -1821,6 +1880,7 @@ fldpi => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldpi',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldln2 => {
@@ -1828,6 +1888,7 @@ fldln2 => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldln2',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldlg2 => {
@@ -1835,6 +1896,7 @@ fldlg2 => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldlg2',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldl2t => {
@@ -1842,6 +1904,7 @@ fldl2t => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldll2t',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldl2e => {
@@ -1849,6 +1912,7 @@ fldl2e => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldl2e',
+       attr_type => "ia32_x87_attr_t",
 },
 
 # fxch, fpush, fpop
@@ -1860,6 +1924,7 @@ fxch => {
        reg_req   => { },
        cmp_attr  => "return 1;",
        emit      => '. fxch %X0',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fpush => {
@@ -1867,6 +1932,7 @@ fpush => {
        reg_req   => {},
        cmp_attr  => "return 1;",
        emit      => '. fld %X0',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fpushCopy => {
@@ -1874,6 +1940,7 @@ fpushCopy => {
        reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
        cmp_attr  => "return 1;",
        emit      => '. fld %X0',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fpop => {
@@ -1881,6 +1948,7 @@ fpop => {
        reg_req   => { },
        cmp_attr  => "return 1;",
        emit      => '. fstp %X0',
+       attr_type => "ia32_x87_attr_t",
 },
 
 # compare
@@ -1888,31 +1956,37 @@ fpop => {
 fcomJmp => {
        op_flags  => "L|X|Y",
        reg_req   => { },
+       attr_type => "ia32_x87_attr_t",
 },
 
 fcompJmp => {
        op_flags  => "L|X|Y",
        reg_req   => { },
+       attr_type => "ia32_x87_attr_t",
 },
 
 fcomppJmp => {
        op_flags  => "L|X|Y",
        reg_req   => { },
+       attr_type => "ia32_x87_attr_t",
 },
 
 fcomrJmp => {
        op_flags  => "L|X|Y",
        reg_req   => { },
+       attr_type => "ia32_x87_attr_t",
 },
 
 fcomrpJmp => {
        op_flags  => "L|X|Y",
        reg_req   => { },
+       attr_type => "ia32_x87_attr_t",
 },
 
 fcomrppJmp => {
        op_flags  => "L|X|Y",
        reg_req   => { },
+       attr_type => "ia32_x87_attr_t",
 },