From: Matthias Braun Date: Mon, 4 Jun 2007 14:57:00 +0000 (+0000) Subject: finish support for custom backend node attributes, separate x87 attributes from norma... X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=89a447658953e2d62af4d2f8f74b3f22f5f52c0c;p=libfirm finish support for custom backend node attributes, separate x87 attributes from normal ia32 attributes to test this [r14328] --- diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index 295452895..bb1648cdb 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -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; diff --git a/ir/be/ia32/ia32_new_nodes.c b/ir/be/ia32/ia32_new_nodes.c index 169fea6b7..2da3d88d4 100644 --- a/ir/be/ia32/ia32_new_nodes.c +++ b/ir/be/ia32/ia32_new_nodes.c @@ -55,14 +55,6 @@ #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; diff --git a/ir/be/ia32/ia32_new_nodes.h b/ir/be/ia32/ia32_new_nodes.h index 1224b345d..83e724315 100644 --- a/ir/be/ia32/ia32_new_nodes.h +++ b/ir/be/ia32/ia32_new_nodes.h @@ -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. */ diff --git a/ir/be/ia32/ia32_nodes_attr.h b/ir/be/ia32/ia32_nodes_attr.h index 89064a736..b40413b05 100644 --- a/ir/be/ia32/ia32_nodes_attr.h +++ b/ir/be/ia32/ia32_nodes_attr.h @@ -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 diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index d1adeb6bb..0582f82e7 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -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", }, diff --git a/ir/be/ia32/ia32_x87.c b/ir/be/ia32/ia32_x87.c index 1a0976cdf..a7803fba0 100644 --- a/ir/be/ia32/ia32_x87.c +++ b/ir/be/ia32/ia32_x87.c @@ -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); diff --git a/ir/be/scripts/generate_new_opcodes.pl b/ir/be/scripts/generate_new_opcodes.pl index 1aa442e39..7f40f2bde 100755 --- a/ir/be/scripts/generate_new_opcodes.pl +++ b/ir/be/scripts/generate_new_opcodes.pl @@ -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