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, '%');
// 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;
*/
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;
#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);
-}
-
/***********************************************************************************
* _ _ _ __
* | | (_) | | / _|
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");
}
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.
*/
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]));
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;
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.
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.
*/
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 {
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
$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 = (
);
reg_req => { out => [ "vfp_UKNWN" ] },
units => [],
emit => "",
- mode => "mode_E"
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
Unknown_XMM => {
reg_req => { out => [ "vfp_NOREG" ] },
units => [],
emit => "",
- mode => "mode_E"
+ mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
NoReg_XMM => {
latency => 10,
units => [ "VFP" ],
mode => $mode_gp,
+ attr_type => "ia32_x87_attr_t",
},
CmpSet => {
latency => 10,
units => [ "VFP" ],
mode => $mode_gp,
+ attr_type => "ia32_x87_attr_t",
},
vfCMov => {
latency => 10,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
#----------------------------------------------------------#
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
vfmul => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
l_vfmul => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
l_vfsub => {
outs => [ "res", "M" ],
latency => 20,
units => [ "VFP" ],
+ attr_type => "ia32_x87_attr_t",
},
l_vfdiv => {
latency => 20,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
l_vfprem => {
latency => 2,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
vfchs => {
latency => 2,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
vfsin => {
latency => 150,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
vfcos => {
latency => 150,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
vfsqrt => {
latency => 30,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
# virtual Load and Store
outs => [ "res", "M" ],
latency => 2,
units => [ "VFP" ],
+ attr_type => "ia32_x87_attr_t",
},
vfst => {
latency => 2,
units => [ "VFP" ],
mode => "mode_M",
+ attr_type => "ia32_x87_attr_t",
},
# Conversions
outs => [ "res", "M" ],
latency => 4,
units => [ "VFP" ],
+ attr_type => "ia32_x87_attr_t",
},
l_vfild => {
latency => 4,
units => [ "VFP" ],
mode => "mode_M",
+ attr_type => "ia32_x87_attr_t",
},
l_vfist => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
vfld1 => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
vfldpi => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
vfldln2 => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
vfldlg2 => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
vfldl2t => {
latency => 4,
units => [ "VFP" ],
mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
},
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
outs => [ "false", "true", "temp_reg_eax" ],
latency => 10,
units => [ "VFP" ],
+ attr_type => "ia32_x87_attr_t",
},
#------------------------------------------------------------------------#
rd_constructor => "NONE",
reg_req => { },
emit => '. fadd%XM %x87_binop',
+ attr_type => "ia32_x87_attr_t",
},
faddp => {
rd_constructor => "NONE",
reg_req => { },
emit => '. faddp %x87_binop',
+ attr_type => "ia32_x87_attr_t",
},
fmul => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fmul%XM %x87_binop',
+ attr_type => "ia32_x87_attr_t",
},
fmulp => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fmulp %x87_binop',,
+ attr_type => "ia32_x87_attr_t",
},
fsub => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fsub%XM %x87_binop',
+ attr_type => "ia32_x87_attr_t",
},
fsubp => {
reg_req => { },
# see note about gas bugs
emit => '. fsubrp %x87_binop',
+ attr_type => "ia32_x87_attr_t",
},
fsubr => {
irn_flags => "R",
reg_req => { },
emit => '. fsubr%XM %x87_binop',
+ attr_type => "ia32_x87_attr_t",
},
fsubrp => {
reg_req => { },
# see note about gas bugs
emit => '. fsubp %x87_binop',
+ attr_type => "ia32_x87_attr_t",
},
fprem => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fprem1',
+ attr_type => "ia32_x87_attr_t",
},
# this node is just here, to keep the simulator running
rd_constructor => "NONE",
reg_req => { },
emit => '. fprem1',
+ attr_type => "ia32_x87_attr_t",
},
fdiv => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fdiv%XM %x87_binop',
+ attr_type => "ia32_x87_attr_t",
},
fdivp => {
reg_req => { },
# see note about gas bugs
emit => '. fdivrp %x87_binop',
+ attr_type => "ia32_x87_attr_t",
},
fdivr => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fdivr%XM %x87_binop',
+ attr_type => "ia32_x87_attr_t",
},
fdivrp => {
reg_req => { },
# see note about gas bugs
emit => '. fdivp %x87_binop',
+ attr_type => "ia32_x87_attr_t",
},
fabs => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fabs',
+ attr_type => "ia32_x87_attr_t",
},
fchs => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fchs',
+ attr_type => "ia32_x87_attr_t",
},
fsin => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fsin',
+ attr_type => "ia32_x87_attr_t",
},
fcos => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fcos',
+ attr_type => "ia32_x87_attr_t",
},
fsqrt => {
rd_constructor => "NONE",
reg_req => { },
emit => '. fsqrt $',
+ attr_type => "ia32_x87_attr_t",
},
# x87 Load and Store
state => "exc_pinned",
reg_req => { },
emit => '. fld%XM %AM',
+ attr_type => "ia32_x87_attr_t",
},
fst => {
reg_req => { },
emit => '. fst%XM %AM',
mode => "mode_M",
+ attr_type => "ia32_x87_attr_t",
},
fstp => {
reg_req => { },
emit => '. fstp%XM %AM',
mode => "mode_M",
+ attr_type => "ia32_x87_attr_t",
},
# Conversions
rd_constructor => "NONE",
reg_req => { },
emit => '. fild%XM %AM',
+ attr_type => "ia32_x87_attr_t",
},
fist => {
reg_req => { },
emit => '. fist%XM %AM',
mode => "mode_M",
+ attr_type => "ia32_x87_attr_t",
},
fistp => {
reg_req => { },
emit => '. fistp%XM %AM',
mode => "mode_M",
+ attr_type => "ia32_x87_attr_t",
},
# constants
irn_flags => "R",
reg_req => { },
emit => '. fldz',
+ attr_type => "ia32_x87_attr_t",
},
fld1 => {
irn_flags => "R",
reg_req => { },
emit => '. fld1',
+ attr_type => "ia32_x87_attr_t",
},
fldpi => {
irn_flags => "R",
reg_req => { },
emit => '. fldpi',
+ attr_type => "ia32_x87_attr_t",
},
fldln2 => {
irn_flags => "R",
reg_req => { },
emit => '. fldln2',
+ attr_type => "ia32_x87_attr_t",
},
fldlg2 => {
irn_flags => "R",
reg_req => { },
emit => '. fldlg2',
+ attr_type => "ia32_x87_attr_t",
},
fldl2t => {
irn_flags => "R",
reg_req => { },
emit => '. fldll2t',
+ attr_type => "ia32_x87_attr_t",
},
fldl2e => {
irn_flags => "R",
reg_req => { },
emit => '. fldl2e',
+ attr_type => "ia32_x87_attr_t",
},
# fxch, fpush, fpop
reg_req => { },
cmp_attr => "return 1;",
emit => '. fxch %X0',
+ attr_type => "ia32_x87_attr_t",
},
fpush => {
reg_req => {},
cmp_attr => "return 1;",
emit => '. fld %X0',
+ attr_type => "ia32_x87_attr_t",
},
fpushCopy => {
reg_req => { in => [ "vfp"], out => [ "vfp" ] },
cmp_attr => "return 1;",
emit => '. fld %X0',
+ attr_type => "ia32_x87_attr_t",
},
fpop => {
reg_req => { },
cmp_attr => "return 1;",
emit => '. fstp %X0',
+ attr_type => "ia32_x87_attr_t",
},
# compare
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",
},
*/
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];
* @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];
*/
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];
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];
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;
}
/* 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];
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));
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));
*/
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)));
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;
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)));
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));
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) {
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)) {
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));
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];
}
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;
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);
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);
our %cpu;
our $default_cmp_attr;
our $default_attr_type;
+our %init_attr;
# include spec file
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);
$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