finish support for custom backend node attributes, separate x87 attributes from norma...
authorMatthias Braun <matze@braunis.de>
Mon, 4 Jun 2007 14:57:00 +0000 (14:57 +0000)
committerMatthias Braun <matze@braunis.de>
Mon, 4 Jun 2007 14:57:00 +0000 (14:57 +0000)
[r14328]

ir/be/ia32/ia32_emitter.c
ir/be/ia32/ia32_new_nodes.c
ir/be/ia32/ia32_new_nodes.h
ir/be/ia32/ia32_nodes_attr.h
ir/be/ia32/ia32_spec.pl
ir/be/ia32/ia32_x87.c
ir/be/scripts/generate_new_opcodes.pl

index 2954528..bb1648c 100644 (file)
@@ -250,7 +250,7 @@ void ia32_emit_dest_register(ia32_emit_env_t *env, const ir_node *node, int pos)
 
 void ia32_emit_x87_name(ia32_emit_env_t *env, const ir_node *node, int pos)
 {
-       const ia32_attr_t *attr = get_ia32_attr_const(node);
+       const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
 
        assert(pos < 3);
        be_emit_char(env, '%');
@@ -472,10 +472,10 @@ void ia32_emit_x87_binop(ia32_emit_env_t *env, const ir_node *node) {
                                // should not happen...
                                assert(0);
                        } else {
-                               const ia32_attr_t     *attr = get_ia32_attr_const(node);
-                               const arch_register_t *in1  attr->x87[0];
-                               const arch_register_t *in2  attr->x87[1];
-                               const arch_register_t *out  attr->x87[2];
+                               const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
+                               const arch_register_t *in1      = x87_attr->x87[0];
+                               const arch_register_t *in2      = x87_attr->x87[1];
+                               const arch_register_t *out      = x87_attr->x87[2];
                                const arch_register_t *in;
 
                                in  = out ? (REGS_ARE_EQUAL(out, in2) ? in1 : in2) : in2;
@@ -870,21 +870,21 @@ void emit_ia32_xCondJmp(ia32_emit_env_t *env, const ir_node *node) {
  */
 static
 void emit_ia32_x87CondJmp(ia32_emit_env_t *env, const ir_node *node) {
-       const ia32_attr_t *attr = get_ia32_attr_const(node);
-       const char        *reg  = attr->x87[1]->name;
-       long               pnc  = get_ia32_pncode(node);
+       const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
+       const char            *reg      = x87_attr->x87[1]->name;
+       long                   pnc      = get_ia32_pncode(node);
 
        switch (get_ia32_irn_opcode(node)) {
        case iro_ia32_fcomrJmp:
                pnc = get_inversed_pnc(pnc);
-               reg = attr->x87[0]->name;
+               reg = x87_attr->x87[0]->name;
        case iro_ia32_fcomJmp:
        default:
                be_emit_cstring(env, "\tfucom ");
                break;
        case iro_ia32_fcomrpJmp:
                pnc = get_inversed_pnc(pnc);
-               reg = attr->x87[0]->name;
+               reg = x87_attr->x87[0]->name;
        case iro_ia32_fcompJmp:
                be_emit_cstring(env, "\tfucomp ");
                break;
index 169fea6..2da3d88 100644 (file)
 #include "gen_ia32_regalloc_if.h"
 #include "gen_ia32_machine.h"
 
-/**
- * returns true if a node has x87 registers
- */
-int ia32_has_x87_register(const ir_node *n) {
-       assert(is_ia32_irn(n) && "Need ia32 node.");
-       return is_irn_machine_user(n, 0);
-}
-
 /***********************************************************************************
  *      _                                   _       _             __
  *     | |                                 (_)     | |           / _|
@@ -199,11 +191,7 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
                                for (i = 0; i < n_res; i++) {
                                        const arch_register_t *reg;
 
-                                       /* retrieve "real" x87 register */
-                                       if (ia32_has_x87_register(n))
-                                               reg = get_ia32_attr(n)->x87[i + 2];
-                                       else
-                                               reg = slots[i];
+                                       reg = slots[i];
 
                                        fprintf(F, "reg #%d = %s\n", i, reg ? arch_register_get_name(reg) : "n/a");
                                }
@@ -428,6 +416,18 @@ const ia32_attr_t *get_ia32_attr_const(const ir_node *node) {
        return (const ia32_attr_t*) get_irn_generic_attr_const(node);
 }
 
+ia32_x87_attr_t *get_ia32_x87_attr(ir_node *node) {
+       ia32_attr_t     *attr     = get_ia32_attr(node);
+       ia32_x87_attr_t *x87_attr = CAST_IA32_ATTR(ia32_x87_attr_t, attr);
+       return x87_attr;
+}
+
+const ia32_x87_attr_t *get_ia32_x87_attr_const(const ir_node *node) {
+       const ia32_attr_t     *attr     = get_ia32_attr_const(node);
+       const ia32_x87_attr_t *x87_attr = CONST_CAST_IA32_ATTR(ia32_x87_attr_t, attr);
+       return x87_attr;
+}
+
 /**
  * Gets the type of an ia32 node.
  */
@@ -1163,7 +1163,10 @@ void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
        set_ia32_out_req_all(node, out_reqs);
        set_ia32_latency(node, latency);
 
-       attr->exec_units = execution_units;
+       attr->exec_units  = execution_units;
+#ifndef NDEBUG
+       attr->attr_type  |= IA32_ATTR_ia32_attr_t;
+#endif
 
        attr->out_flags = NEW_ARR_D(int, obst, n_res);
        memset(attr->out_flags, 0, n_res * sizeof(attr->out_flags[0]));
@@ -1172,6 +1175,15 @@ void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
        memset(attr->slots, 0, n_res * sizeof(attr->slots[0]));
 }
 
+void
+init_ia32_x87_attributes(ir_node *res)
+{
+#ifndef NDEBUG
+       ia32_attr_t *attr  = get_ia32_attr(res);
+       attr->attr_type   |= IA32_ATTR_ia32_x87_attr_t;
+#endif
+}
+
 ir_node *get_ia32_result_proj(const ir_node *node)
 {
        const ir_edge_t *edge;
index 1224b34..83e7243 100644 (file)
@@ -54,6 +54,8 @@ int ia32_has_x87_register(const ir_node *n);
 ia32_attr_t *get_ia32_attr(ir_node *node);
 const ia32_attr_t *get_ia32_attr_const(const ir_node *node);
 
+ia32_x87_attr_t *get_ia32_x87_attr(ir_node *node);
+const ia32_x87_attr_t *get_ia32_x87_attr_const(const ir_node *node);
 
 /**
  * Gets the type of an ia32 node.
@@ -488,6 +490,8 @@ void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
                           const be_execution_unit_t ***execution_units,
                           int n_res, unsigned latency);
 
+void init_ia32_x87_attributes(ir_node *node);
+
 /**
  * Registers the ia32_copy_attr function for all ia32 opcodes.
  */
index 89064a7..b40413b 100644 (file)
@@ -86,6 +86,14 @@ enum {
        ia32_pn_Cmp_Unsigned = 0x100 /**< set this flag in a pnc to indicate an unsigned compare operation */
 };
 
+#ifndef NDEBUG
+typedef enum {
+       IA32_ATTR_INVALID         = 0,
+       IA32_ATTR_ia32_attr_t     = 1 << 0,
+       IA32_ATTR_ia32_x87_attr_t = 1 << 1,
+} ia32_attr_type_t;
+#endif
+
 typedef struct ia32_attr_t ia32_attr_t;
 struct ia32_attr_t {
        struct {
@@ -133,17 +141,37 @@ struct ia32_attr_t {
        unsigned latency;   /**< the latency of the instruction in clock cycles */
 
 #ifndef NDEBUG
-       const char *orig_node;      /**< holds the name of the original ir node for debugging purposes */
-#endif /* NDEBUG */
+       const char       *orig_node;      /**< holds the name of the original ir node */
+       unsigned          attr_type;      /**< bitfield indicating the attribute type */
+#endif
 
        const be_execution_unit_t ***exec_units; /**< list of units this operation can be executed on */
 
        const arch_register_req_t **in_req;  /**< register requirements for arguments */
        const arch_register_req_t **out_req; /**< register requirements for results */
 
-       const arch_register_t *x87[3];       /**< register slots for x87 register */
-
        const arch_register_t **slots;     /**< register slots for assigned registers */
 };
 
-#endif /* FIRM_BE_IA32_IA32_NODES_ATTR_H */
+typedef struct ia32_x87_attr_t ia32_x87_attr_t;
+struct ia32_x87_attr_t {
+       ia32_attr_t  attr;
+       const arch_register_t *x87[3];    /**< register slots for x87 register */
+};
+
+/* the following union is necessary to indicate to the compiler that we might want to cast
+ * the structs (we use them to simulate OO-inheritance) */
+union allow_casts_attr_t_ {
+       ia32_attr_t      attr;
+       ia32_x87_attr_t  x87_attr;
+};
+
+#ifndef NDEBUG
+#define CAST_IA32_ATTR(type,ptr)        (assert( ((const ia32_attr_t*)(ptr))->attr_type & IA32_ATTR_ ## type ), (type*) (ptr))
+#define CONST_CAST_IA32_ATTR(type,ptr)  (assert( ((const ia32_attr_t*)(ptr))->attr_type & IA32_ATTR_ ## type ), (const type*) (ptr))
+#else
+#define CAST_IA32_ATTR(type,ptr)        ((type*) (ptr))
+#define CONST_CAST_IA32_ATTR(type,ptr)  ((const type*) (ptr))
+#endif
+
+#endif
index d1adeb6..0582f82 100644 (file)
@@ -289,6 +289,13 @@ $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);",
+);
+
 %operands = (
 );
 
@@ -799,7 +806,8 @@ Unknown_VFP => {
        reg_req   => { out => [ "vfp_UKNWN" ] },
        units     => [],
        emit      => "",
-       mode      => "mode_E"
+       mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 Unknown_XMM => {
@@ -829,7 +837,8 @@ NoReg_VFP => {
        reg_req   => { out => [ "vfp_NOREG" ] },
        units     => [],
        emit      => "",
-       mode      => "mode_E"
+       mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 NoReg_XMM => {
@@ -1315,6 +1324,7 @@ vfCmpCMov => {
        latency   => 10,
        units     => [ "VFP" ],
        mode      => $mode_gp,
+       attr_type => "ia32_x87_attr_t",
 },
 
 CmpSet => {
@@ -1347,6 +1357,7 @@ vfCmpSet => {
        latency   => 10,
        units     => [ "VFP" ],
        mode      => $mode_gp,
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfCMov => {
@@ -1355,6 +1366,7 @@ vfCMov => {
        latency   => 10,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 #----------------------------------------------------------#
@@ -1377,6 +1389,7 @@ vfadd => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfmul => {
@@ -1385,6 +1398,7 @@ vfmul => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfmul => {
@@ -1399,6 +1413,7 @@ vfsub => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfsub => {
@@ -1411,6 +1426,7 @@ vfdiv => {
        outs      => [ "res", "M" ],
        latency   => 20,
        units     => [ "VFP" ],
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfdiv => {
@@ -1424,6 +1440,7 @@ vfprem => {
        latency   => 20,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfprem => {
@@ -1437,6 +1454,7 @@ vfabs => {
        latency   => 2,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfchs => {
@@ -1445,6 +1463,7 @@ vfchs => {
        latency   => 2,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfsin => {
@@ -1453,6 +1472,7 @@ vfsin => {
        latency   => 150,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfcos => {
@@ -1461,6 +1481,7 @@ vfcos => {
        latency   => 150,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfsqrt => {
@@ -1469,6 +1490,7 @@ vfsqrt => {
        latency   => 30,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # virtual Load and Store
@@ -1480,6 +1502,7 @@ vfld => {
        outs      => [ "res", "M" ],
        latency   => 2,
        units     => [ "VFP" ],
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfst => {
@@ -1489,6 +1512,7 @@ vfst => {
        latency   => 2,
        units     => [ "VFP" ],
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # Conversions
@@ -1498,6 +1522,7 @@ vfild => {
        outs      => [ "res", "M" ],
        latency   => 4,
        units     => [ "VFP" ],
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfild => {
@@ -1511,6 +1536,7 @@ vfist => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 l_vfist => {
@@ -1528,6 +1554,7 @@ vfldz => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfld1 => {
@@ -1536,6 +1563,7 @@ vfld1 => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldpi => {
@@ -1544,6 +1572,7 @@ vfldpi => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldln2 => {
@@ -1552,6 +1581,7 @@ vfldln2 => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldlg2 => {
@@ -1560,6 +1590,7 @@ vfldlg2 => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldl2t => {
@@ -1568,6 +1599,7 @@ vfldl2t => {
        latency   => 4,
        units     => [ "VFP" ],
        mode      => "mode_E",
+       attr_type => "ia32_x87_attr_t",
 },
 
 vfldl2e => {
@@ -1576,16 +1608,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
@@ -1597,6 +1630,7 @@ vfCondJmp => {
        outs      => [ "false", "true", "temp_reg_eax" ],
        latency   => 10,
        units     => [ "VFP" ],
+       attr_type => "ia32_x87_attr_t",
 },
 
 #------------------------------------------------------------------------#
@@ -1615,6 +1649,7 @@ fadd => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fadd%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 faddp => {
@@ -1622,6 +1657,7 @@ faddp => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. faddp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fmul => {
@@ -1629,6 +1665,7 @@ fmul => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fmul%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fmulp => {
@@ -1636,6 +1673,7 @@ fmulp => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fmulp %x87_binop',,
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsub => {
@@ -1643,6 +1681,7 @@ fsub => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fsub%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsubp => {
@@ -1651,6 +1690,7 @@ fsubp => {
        reg_req   => { },
 # see note about gas bugs
        emit      => '. fsubrp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsubr => {
@@ -1659,6 +1699,7 @@ fsubr => {
        irn_flags => "R",
        reg_req   => { },
        emit      => '. fsubr%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsubrp => {
@@ -1668,6 +1709,7 @@ fsubrp => {
        reg_req   => { },
 # see note about gas bugs
        emit      => '. fsubp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fprem => {
@@ -1675,6 +1717,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
@@ -1684,6 +1727,7 @@ fpremp => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fprem1',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fdiv => {
@@ -1691,6 +1735,7 @@ fdiv => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fdiv%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fdivp => {
@@ -1699,6 +1744,7 @@ fdivp => {
        reg_req   => { },
 # see note about gas bugs
        emit      => '. fdivrp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fdivr => {
@@ -1706,6 +1752,7 @@ fdivr => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fdivr%XM %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fdivrp => {
@@ -1714,6 +1761,7 @@ fdivrp => {
        reg_req   => { },
 # see note about gas bugs
        emit      => '. fdivp %x87_binop',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fabs => {
@@ -1721,6 +1769,7 @@ fabs => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fabs',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fchs => {
@@ -1728,6 +1777,7 @@ fchs => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fchs',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsin => {
@@ -1735,6 +1785,7 @@ fsin => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fsin',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fcos => {
@@ -1742,6 +1793,7 @@ fcos => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fcos',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fsqrt => {
@@ -1749,6 +1801,7 @@ fsqrt => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fsqrt $',
+       attr_type => "ia32_x87_attr_t",
 },
 
 # x87 Load and Store
@@ -1759,6 +1812,7 @@ fld => {
        state     => "exc_pinned",
        reg_req   => { },
        emit      => '. fld%XM %AM',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fst => {
@@ -1768,6 +1822,7 @@ fst => {
        reg_req   => { },
        emit      => '. fst%XM %AM',
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 fstp => {
@@ -1777,6 +1832,7 @@ fstp => {
        reg_req   => { },
        emit      => '. fstp%XM %AM',
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # Conversions
@@ -1786,6 +1842,7 @@ fild => {
        rd_constructor => "NONE",
        reg_req   => { },
        emit      => '. fild%XM %AM',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fist => {
@@ -1794,6 +1851,7 @@ fist => {
        reg_req   => { },
        emit      => '. fist%XM %AM',
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 fistp => {
@@ -1802,6 +1860,7 @@ fistp => {
        reg_req   => { },
        emit      => '. fistp%XM %AM',
        mode      => "mode_M",
+       attr_type => "ia32_x87_attr_t",
 },
 
 # constants
@@ -1811,6 +1870,7 @@ fldz => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldz',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fld1 => {
@@ -1818,6 +1878,7 @@ fld1 => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fld1',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldpi => {
@@ -1825,6 +1886,7 @@ fldpi => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldpi',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldln2 => {
@@ -1832,6 +1894,7 @@ fldln2 => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldln2',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldlg2 => {
@@ -1839,6 +1902,7 @@ fldlg2 => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldlg2',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldl2t => {
@@ -1846,6 +1910,7 @@ fldl2t => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldll2t',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fldl2e => {
@@ -1853,6 +1918,7 @@ fldl2e => {
        irn_flags  => "R",
        reg_req   => { },
        emit      => '. fldl2e',
+       attr_type => "ia32_x87_attr_t",
 },
 
 # fxch, fpush, fpop
@@ -1864,6 +1930,7 @@ fxch => {
        reg_req   => { },
        cmp_attr  => "return 1;",
        emit      => '. fxch %X0',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fpush => {
@@ -1871,6 +1938,7 @@ fpush => {
        reg_req   => {},
        cmp_attr  => "return 1;",
        emit      => '. fld %X0',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fpushCopy => {
@@ -1878,6 +1946,7 @@ fpushCopy => {
        reg_req   => { in => [ "vfp"], out => [ "vfp" ] },
        cmp_attr  => "return 1;",
        emit      => '. fld %X0',
+       attr_type => "ia32_x87_attr_t",
 },
 
 fpop => {
@@ -1885,6 +1954,7 @@ fpop => {
        reg_req   => { },
        cmp_attr  => "return 1;",
        emit      => '. fstp %X0',
+       attr_type => "ia32_x87_attr_t",
 },
 
 # compare
@@ -1892,31 +1962,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",
 },
 
 
index 1a0976c..a7803fb 100644 (file)
@@ -445,10 +445,10 @@ static INLINE const arch_register_t *x87_get_irn_register(x87_simulator *sim, co
  */
 static ir_node *x87_fxch_shuffle(x87_state *state, int pos, ir_node *block) {
        ir_node         *fxch;
-       ia32_attr_t     *attr;
+       ia32_x87_attr_t *attr;
 
        fxch = new_rd_ia32_fxch(NULL, get_irn_irg(block), block, mode_E);
-       attr = get_ia32_attr(fxch);
+       attr = get_ia32_x87_attr(fxch);
        attr->x87[0] = &ia32_st_regs[pos];
        attr->x87[2] = &ia32_st_regs[0];
 
@@ -605,15 +605,15 @@ static x87_state *x87_shuffle(x87_simulator *sim, ir_node *block, x87_state *sta
  * @return the fxch
  */
 static ir_node *x87_create_fxch(x87_state *state, ir_node *n, int pos, int op_idx) {
-       ir_node     *fxch;
-       ia32_attr_t *attr;
-       ir_graph    *irg = get_irn_irg(n);
-       ir_node     *block = get_nodes_block(n);
+       ir_node         *fxch;
+       ia32_x87_attr_t *attr;
+       ir_graph        *irg = get_irn_irg(n);
+       ir_node         *block = get_nodes_block(n);
 
        x87_fxch(state, pos);
 
        fxch = new_rd_ia32_fxch(NULL, irg, block, mode_E);
-       attr = get_ia32_attr(fxch);
+       attr = get_ia32_x87_attr(fxch);
        attr->x87[0] = &ia32_st_regs[pos];
        attr->x87[2] = &ia32_st_regs[0];
 
@@ -634,13 +634,13 @@ static ir_node *x87_create_fxch(x87_state *state, ir_node *n, int pos, int op_id
  */
 static void x87_create_fpush(x87_state *state, ir_node *n, int pos, int op_idx) {
        ir_node               *fpush, *pred = get_irn_n(n, op_idx);
-       ia32_attr_t           *attr;
+       ia32_x87_attr_t       *attr;
        const arch_register_t *out = x87_get_irn_register(state->sim, pred);
 
        x87_push_dbl(state, arch_register_get_index(out), pred);
 
        fpush = new_rd_ia32_fpush(NULL, get_irn_irg(n), get_nodes_block(n), mode_E);
-       attr  = get_ia32_attr(fpush);
+       attr  = get_ia32_x87_attr(fpush);
        attr->x87[0] = &ia32_st_regs[pos];
        attr->x87[2] = &ia32_st_regs[0];
 
@@ -662,12 +662,12 @@ static void x87_create_fpush(x87_state *state, ir_node *n, int pos, int op_idx)
 static ir_node *x87_create_fpop(x87_state *state, ir_node *n, int num)
 {
        ir_node *fpop;
-       ia32_attr_t *attr;
+       ia32_x87_attr_t *attr;
 
        while (num > 0) {
                x87_pop(state);
                fpop = new_rd_ia32_fpop(NULL, get_irn_irg(n), get_nodes_block(n), mode_E);
-               attr = get_ia32_attr(fpop);
+               attr = get_ia32_x87_attr(fpop);
                attr->x87[0] = &ia32_st_regs[0];
                attr->x87[1] = &ia32_st_regs[0];
                attr->x87[2] = &ia32_st_regs[0];
@@ -861,7 +861,7 @@ static void vfp_dump_live(vfp_liveness live) {
 static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) {
        int op2_idx = 0, op1_idx;
        int out_idx, do_pop = 0;
-       ia32_attr_t *attr;
+       ia32_x87_attr_t *attr;
        ir_node *patched_insn;
        ir_op *dst;
        x87_simulator         *sim = state->sim;
@@ -994,7 +994,7 @@ static int sim_binop(x87_state *state, ir_node *n, const exchange_tmpl *tmpl) {
        }
 
        /* patch the operation */
-       attr = get_ia32_attr(n);
+       attr = get_ia32_x87_attr(n);
        attr->x87[0] = op1 = &ia32_st_regs[op1_idx];
        if (reg_index_2 != REG_VFP_NOREG) {
                attr->x87[1] = op2 = &ia32_st_regs[op2_idx];
@@ -1028,7 +1028,7 @@ static int sim_unop(x87_state *state, ir_node *n, ir_op *op) {
        x87_simulator         *sim = state->sim;
        const arch_register_t *op1 = x87_get_irn_register(sim, get_irn_n(n, UNOP_IDX));
        const arch_register_t *out = x87_get_irn_register(sim, n);
-       ia32_attr_t *attr;
+       ia32_x87_attr_t *attr;
        unsigned live = vfp_live_args_after(sim, n, REGMASK(out));
 
        DB((dbg, LEVEL_1, ">>> %+F -> %s\n", n, out->name));
@@ -1051,7 +1051,7 @@ static int sim_unop(x87_state *state, ir_node *n, ir_op *op) {
 
        x87_set_tos(state, arch_register_get_index(out), x87_patch_insn(n, op));
        out_idx = 0;
-       attr = get_ia32_attr(n);
+       attr = get_ia32_x87_attr(n);
        attr->x87[0] = op1 = &ia32_st_regs[0];
        attr->x87[2] = out = &ia32_st_regs[0];
        DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), out->name));
@@ -1070,12 +1070,12 @@ static int sim_unop(x87_state *state, ir_node *n, ir_op *op) {
  */
 static int sim_load(x87_state *state, ir_node *n, ir_op *op) {
        const arch_register_t *out = x87_get_irn_register(state->sim, n);
-       ia32_attr_t *attr;
+       ia32_x87_attr_t *attr;
 
        DB((dbg, LEVEL_1, ">>> %+F -> %s\n", n, arch_register_get_name(out)));
        x87_push(state, arch_register_get_index(out), x87_patch_insn(n, op));
        assert(out == x87_get_irn_register(state->sim, n));
-       attr = get_ia32_attr(n);
+       attr = get_ia32_x87_attr(n);
        attr->x87[2] = out = &ia32_st_regs[0];
        DB((dbg, LEVEL_1, "<<< %s -> %s\n", get_irn_opname(n), arch_register_get_name(out)));
 
@@ -1124,7 +1124,7 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p) {
        const arch_register_t *op2 = x87_get_irn_register(sim, val);
        unsigned              live = vfp_live_args_after(sim, n, 0);
        int                   insn = NO_NODE_ADDED;
-       ia32_attr_t *attr;
+       ia32_x87_attr_t *attr;
        int op2_reg_idx, op2_idx, depth;
        int live_after_node;
        ir_mode *mode;
@@ -1226,7 +1226,7 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p) {
                x87_patch_insn(n, op_p);
        }
 
-       attr = get_ia32_attr(n);
+       attr = get_ia32_x87_attr(n);
        attr->x87[1] = op2 = &ia32_st_regs[0];
        DB((dbg, LEVEL_1, "<<< %s %s ->\n", get_irn_opname(n), arch_register_get_name(op2)));
 
@@ -1311,7 +1311,7 @@ static int sim_fCondJmp(x87_state *state, ir_node *n) {
        int op1_idx;
        int op2_idx = -1;
        int pop_cnt = 0;
-       ia32_attr_t *attr;
+       ia32_x87_attr_t *attr;
        ir_op *dst;
        x87_simulator         *sim = state->sim;
        const arch_register_t *op1 = x87_get_irn_register(sim, get_irn_n(n, BINOP_IDX_1));
@@ -1486,7 +1486,7 @@ static int sim_fCondJmp(x87_state *state, ir_node *n) {
                x87_pop(state);
 
        /* patch the operation */
-       attr = get_ia32_attr(n);
+       attr = get_ia32_x87_attr(n);
        op1 = &ia32_st_regs[op1_idx];
        attr->x87[0] = op1;
        if (op2_idx >= 0) {
@@ -1543,7 +1543,7 @@ static ir_node *create_Copy(x87_state *state, ir_node *n) {
        ir_node *res;
        const arch_register_t *out;
        const arch_register_t *op1;
-       ia32_attr_t *attr;
+       ia32_x87_attr_t *attr;
 
        /* Do not copy constants, recreate them. */
        switch (get_ia32_irn_opcode(pred)) {
@@ -1582,7 +1582,7 @@ static ir_node *create_Copy(x87_state *state, ir_node *n) {
 
                x87_push(state, arch_register_get_index(out), res);
 
-               attr = get_ia32_attr(res);
+               attr = get_ia32_x87_attr(res);
                attr->x87[2] = &ia32_st_regs[0];
        } else {
                int op1_idx = x87_on_stack(state, arch_register_get_index(op1));
@@ -1591,7 +1591,7 @@ static ir_node *create_Copy(x87_state *state, ir_node *n) {
 
                x87_push(state, arch_register_get_index(out), res);
 
-               attr = get_ia32_attr(res);
+               attr = get_ia32_x87_attr(res);
                attr->x87[0] = &ia32_st_regs[op1_idx];
                attr->x87[2] = &ia32_st_regs[0];
        }
@@ -1614,7 +1614,7 @@ static int sim_Copy(x87_state *state, ir_node *n) {
        const arch_register_t *out;
        const arch_register_t *op1;
        ir_node               *node, *next;
-       ia32_attr_t           *attr;
+       ia32_x87_attr_t       *attr;
        int                   op1_idx, out_idx;
        unsigned              live;
 
@@ -1687,7 +1687,7 @@ static int sim_Copy(x87_state *state, ir_node *n) {
                        if (out_idx == 0) {
                                /* best case, simple remove and rename */
                                x87_patch_insn(n, op_ia32_Pop);
-                               attr = get_ia32_attr(n);
+                               attr = get_ia32_x87_attr(n);
                                attr->x87[0] = op1 = &ia32_st_regs[0];
 
                                x87_pop(state);
@@ -1699,7 +1699,7 @@ static int sim_Copy(x87_state *state, ir_node *n) {
                                        op1_idx = 0;
                                }
                                x87_patch_insn(n, op_ia32_Pop);
-                               attr = get_ia32_attr(n);
+                               attr = get_ia32_x87_attr(n);
                                attr->x87[0] = op1 = &ia32_st_regs[out_idx];
 
                                x87_pop(state);
index 1aa442e..7f40f2b 100755 (executable)
@@ -40,6 +40,7 @@ our %nodes;
 our %cpu;
 our $default_cmp_attr;
 our $default_attr_type;
+our %init_attr;
 
 # include spec file
 
@@ -59,6 +60,11 @@ my $target_h = $target_dir."/gen_".$arch."_new_nodes.h";
 if(!defined($default_attr_type)) {
        $default_attr_type = "${arch}_attr_t";
 }
+if(!defined(%init_attr)) {
+       %init_attr = (
+               "$default_attr_type" => "\tinit_${arch}_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);",
+       );
+}
 
 #print Dumper(%nodes);
 #print Dumper(%operands);
@@ -423,7 +429,12 @@ foreach my $op (keys(%nodes)) {
                        $temp .= "\n";
 
                        $temp .= "\t/* init node attributes */\n";
-                       $temp .= "\tinit_$arch\_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n";
+                       # lookup init function
+                       my $attr_init_code = $init_attr{$attr_type};
+                       if(!defined($attr_init_code)) {
+                               die "Couldn't find attribute initialisation code for type '${attr_type}'";
+                       }
+                       $temp .= "${attr_init_code}\n";
                        $temp .= "\n";
 
                        # set flags for outs