if (mode_is_float(mode)) {
ir_node *res = NULL;
ir_node *load;
- ir_node *base;
ir_entity *floatent;
if (ia32_cg_config.use_sse2) {
set_ia32_ls_mode(load, mode);
res = load;
} else {
+ ir_node *base;
#ifdef CONSTRUCT_SSE_CONST
if (mode == mode_D) {
unsigned val = get_tarval_sub_bits(tv, 0) |
mode);
set_ia32_op_type(load, ia32_AddrModeS);
set_ia32_am_sc(load, floatent);
- arch_irn_add_flags(load, arch_irn_flags_rematerializable);
+ arch_add_irn_flags(load, arch_irn_flags_rematerializable);
res = new_r_Proj(load, mode_xmm, pn_ia32_xLoad_res);
}
} else {
ls_mode);
set_ia32_op_type(load, ia32_AddrModeS);
set_ia32_am_sc(load, floatent);
- arch_irn_add_flags(load, arch_irn_flags_rematerializable);
+ arch_add_irn_flags(load, arch_irn_flags_rematerializable);
res = new_r_Proj(load, mode_vfp, pn_ia32_vfld_res);
}
}
}
am->op_type = ia32_AddrModeS;
} else {
- ir_mode *mode;
am->op_type = ia32_Normal;
if (flags & match_try_am) {
{
dbg_info *dbgi;
ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
+ ir_mode *mode = get_irn_mode(node);
- assert(! mode_is_float(get_irn_mode(node)));
+ assert(! mode_is_float(mode));
assert(flags & match_immediate);
assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
+ if (get_mode_modulo_shift(mode) != 32)
+ panic("modulo shift!=32 not supported by ia32 backend");
+
if (flags & match_mode_neutral) {
op1 = ia32_skip_downconv(op1);
new_op1 = be_transform_node(op1);
- } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
+ } else if (get_mode_size_bits(mode) != 32) {
new_op1 = create_upconv(op1, node);
} else {
new_op1 = be_transform_node(op1);
static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
ia32_address_t *addr)
{
- ir_node *base, *index, *res;
+ ir_node *base;
+ ir_node *idx;
+ ir_node *res;
base = addr->base;
if (base == NULL) {
base = be_transform_node(base);
}
- index = addr->index;
- if (index == NULL) {
- index = noreg_GP;
+ idx = addr->index;
+ if (idx == NULL) {
+ idx = noreg_GP;
} else {
- index = be_transform_node(index);
+ idx = be_transform_node(idx);
}
/* segment overrides are ineffective for Leas :-( so we have to patch
addr->tls_segment = false;
}
- res = new_bd_ia32_Lea(dbgi, block, base, index);
+ res = new_bd_ia32_Lea(dbgi, block, base, idx);
set_address(res, addr);
return res;
return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
}
-static ir_node *create_abs(dbg_info *dbgi, ir_node *block, ir_node *op,
- bool negate, ir_node *node)
+static ir_node *create_float_abs(dbg_info *dbgi, ir_node *block, ir_node *op,
+ bool negate, ir_node *node)
{
ir_node *new_block = be_transform_node(block);
ir_mode *mode = get_irn_mode(op);
- ir_node *new_op;
+ ir_node *new_op = be_transform_node(op);
ir_node *new_node;
int size;
ir_entity *ent;
- if (mode_is_float(mode)) {
- new_op = be_transform_node(op);
+ assert(mode_is_float(mode));
- if (ia32_cg_config.use_sse2) {
- ir_node *noreg_fp = ia32_new_NoReg_xmm(current_ir_graph);
- new_node = new_bd_ia32_xAnd(dbgi, new_block, get_symconst_base(),
- noreg_GP, nomem, new_op, noreg_fp);
+ if (ia32_cg_config.use_sse2) {
+ ir_node *noreg_fp = ia32_new_NoReg_xmm(current_ir_graph);
+ new_node = new_bd_ia32_xAnd(dbgi, new_block, get_symconst_base(),
+ noreg_GP, nomem, new_op, noreg_fp);
- size = get_mode_size_bits(mode);
- ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
+ size = get_mode_size_bits(mode);
+ ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
- set_ia32_am_sc(new_node, ent);
+ set_ia32_am_sc(new_node, ent);
- SET_IA32_ORIG_NODE(new_node, node);
+ SET_IA32_ORIG_NODE(new_node, node);
- set_ia32_op_type(new_node, ia32_AddrModeS);
- set_ia32_ls_mode(new_node, mode);
+ set_ia32_op_type(new_node, ia32_AddrModeS);
+ set_ia32_ls_mode(new_node, mode);
- /* TODO, implement -Abs case */
- assert(!negate);
- } else {
- new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
+ /* TODO, implement -Abs case */
+ assert(!negate);
+ } else {
+ new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
+ SET_IA32_ORIG_NODE(new_node, node);
+ if (negate) {
+ new_node = new_bd_ia32_vfchs(dbgi, new_block, new_node);
SET_IA32_ORIG_NODE(new_node, node);
- if (negate) {
- new_node = new_bd_ia32_vfchs(dbgi, new_block, new_node);
- SET_IA32_ORIG_NODE(new_node, node);
- }
}
}
ir_node *new_block = be_transform_node(get_nodes_block(node));
ir_node *new_op = be_transform_node(node);
ir_node *flags = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op, new_op, false);
+ set_ia32_ls_mode(flags, get_irn_mode(new_op));
*cc_out = ia32_cc_not_equal;
return flags;
}
ir_mode *mode = get_Load_mode(node);
int throws_exception = ir_throws_exception(node);
ir_node *base;
- ir_node *index;
+ ir_node *idx;
ir_node *new_node;
ia32_address_t addr;
/* construct load address */
memset(&addr, 0, sizeof(addr));
ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
- base = addr.base;
- index = addr.index;
+ base = addr.base;
+ idx = addr.index;
if (base == NULL) {
base = noreg_GP;
base = be_transform_node(base);
}
- if (index == NULL) {
- index = noreg_GP;
+ if (idx == NULL) {
+ idx = noreg_GP;
} else {
- index = be_transform_node(index);
+ idx = be_transform_node(idx);
}
if (mode_is_float(mode)) {
if (ia32_cg_config.use_sse2) {
- new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
+ new_node = new_bd_ia32_xLoad(dbgi, block, base, idx, new_mem,
mode);
} else {
- new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
+ new_node = new_bd_ia32_vfld(dbgi, block, base, idx, new_mem,
mode);
}
} else {
/* create a conv node with address mode for smaller modes */
if (get_mode_size_bits(mode) < 32) {
- new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
+ new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, idx,
new_mem, noreg_GP, mode);
} else {
- new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
+ new_node = new_bd_ia32_Load(dbgi, block, base, idx, new_mem);
}
}
ir_set_throws_exception(new_node, throws_exception);
assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
&& (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
&& (int)pn_ia32_Load_res == (int)pn_ia32_res);
- arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
+ arch_add_irn_flags(new_node, arch_irn_flags_rematerializable);
}
SET_IA32_ORIG_NODE(new_node, node);
ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
addr.index, addr.mem, imm);
- ir_node *mem = new_r_Proj(new_node, mode_M, pn_ia32_Store_M);
+ ir_node *new_mem = new_r_Proj(new_node, mode_M, pn_ia32_Store_M);
ir_set_throws_exception(new_node, throws_exception);
set_irn_pinned(new_node, get_irn_pinned(node));
SET_IA32_ORIG_NODE(new_node, node);
assert(i < 4);
- ins[i++] = mem;
+ ins[i++] = new_mem;
size -= 4;
ofs += 4;
*/
static ir_node *create_Switch(ir_node *node)
{
- dbg_info *dbgi = get_irn_dbg_info(node);
- ir_node *block = be_transform_node(get_nodes_block(node));
- ir_node *sel = get_Cond_selector(node);
- ir_node *new_sel = be_transform_node(sel);
- long switch_min = LONG_MAX;
- long switch_max = LONG_MIN;
- long default_pn = get_Cond_default_proj(node);
- ir_node *new_node;
- const ir_edge_t *edge;
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_node *block = be_transform_node(get_nodes_block(node));
+ ir_node *sel = get_Cond_selector(node);
+ ir_node *new_sel = be_transform_node(sel);
+ long default_pn = get_Cond_default_proj(node);
+ ir_node *new_node;
+ ir_entity *entity;
assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
- /* determine the smallest switch case value */
- foreach_out_edge(node, edge) {
- ir_node *proj = get_edge_src_irn(edge);
- long pn = get_Proj_proj(proj);
- if (pn == default_pn)
- continue;
+ entity = new_entity(NULL, id_unique("TBL%u"), get_unknown_type());
+ set_entity_visibility(entity, ir_visibility_private);
+ add_entity_linkage(entity, IR_LINKAGE_CONSTANT);
- if (pn < switch_min)
- switch_min = pn;
- if (pn > switch_max)
- switch_max = pn;
- }
-
- if ((unsigned long) (switch_max - switch_min) > 128000) {
- panic("Size of switch %+F bigger than 128000", node);
- }
-
- if (switch_min != 0) {
- /* if smallest switch case is not 0 we need an additional sub */
- new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
- add_ia32_am_offs_int(new_sel, -switch_min);
- set_ia32_op_type(new_sel, ia32_AddrModeS);
-
- SET_IA32_ORIG_NODE(new_sel, node);
- }
-
- new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
+ /* TODO: we could perform some more matching here to also use the base
+ * register of the address mode */
+ new_node
+ = new_bd_ia32_SwitchJmp(dbgi, block, noreg_GP, new_sel, default_pn);
+ set_ia32_am_scale(new_node, 2);
+ set_ia32_am_sc(new_node, entity);
+ set_ia32_op_type(new_node, ia32_AddrModeS);
+ set_ia32_ls_mode(new_node, mode_Iu);
SET_IA32_ORIG_NODE(new_node, node);
+ // FIXME This seems wrong. GCC uses PIC for switch on OS X.
+ get_ia32_attr(new_node)->data.am_sc_no_pic_adjust = true;
return new_node;
}
++step;
res->steps[step].transform = SETCC_TR_NEG;
} else {
- int v = get_tarval_lowest_bit(t);
- assert(v >= 0);
+ int val = get_tarval_lowest_bit(t);
+ assert(val >= 0);
res->steps[step].transform = SETCC_TR_SHL;
- res->steps[step].scale = v;
+ res->steps[step].scale = val;
}
}
++step;
node);
} else {
ir_node *op = ir_get_abs_op(sel, mux_true, mux_false);
- return create_abs(dbgi, block, op, is_abs < 0, node);
+ return create_float_abs(dbgi, block, op, is_abs < 0, node);
}
}
ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_SubSP,
match_am | match_immediate);
assert(is_ia32_SubSP(new_node));
- arch_irn_set_register(new_node, pn_ia32_SubSP_stack,
- &ia32_registers[REG_ESP]);
+ arch_set_irn_register_out(new_node, pn_ia32_SubSP_stack,
+ &ia32_registers[REG_ESP]);
return new_node;
}
ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_AddSP,
match_am | match_immediate);
assert(is_ia32_AddSP(new_node));
- arch_irn_set_register(new_node, pn_ia32_AddSP_stack,
- &ia32_registers[REG_ESP]);
+ arch_set_irn_register_out(new_node, pn_ia32_AddSP_stack,
+ &ia32_registers[REG_ESP]);
return new_node;
}
copy_node_attr(irg, node, phi);
be_duplicate_deps(node, phi);
- arch_set_out_register_req(phi, 0, req);
+ arch_set_irn_register_req_out(phi, 0, req);
be_enqueue_preds(node);
i = get_irn_arity(node) - 1;
fpcw = be_transform_node(get_irn_n(node, i--));
for (; i >= n_be_Call_first_arg; --i) {
- arch_register_req_t const *const req = arch_get_register_req(node, i);
+ arch_register_req_t const *const req
+ = arch_get_irn_register_req_in(node, i);
ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
assert(req->type == arch_register_req_type_limited);
assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
&& (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
&& (int)pn_ia32_Load_res == (int)pn_ia32_res);
- arch_irn_add_flags(load, arch_irn_flags_rematerializable);
+ arch_add_irn_flags(load, arch_irn_flags_rematerializable);
}
SET_IA32_ORIG_NODE(load, node);
assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
&& (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
&& (int)pn_ia32_Load_res == (int)pn_ia32_res);
- arch_irn_add_flags(load, arch_irn_flags_rematerializable);
+ arch_add_irn_flags(load, arch_irn_flags_rematerializable);
}
SET_IA32_ORIG_NODE(load, node);
static ir_node *gen_prefetch(ir_node *node)
{
dbg_info *dbgi;
- ir_node *ptr, *block, *mem, *base, *index;
+ ir_node *ptr, *block, *mem, *base, *idx;
ir_node *param, *new_node;
long rw, locality;
ir_tarval *tv;
memset(&addr, 0, sizeof(addr));
ptr = get_Builtin_param(node, 0);
ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
- base = addr.base;
- index = addr.index;
+ base = addr.base;
+ idx = addr.index;
if (base == NULL) {
base = noreg_GP;
base = be_transform_node(base);
}
- if (index == NULL) {
- index = noreg_GP;
+ if (idx == NULL) {
+ idx = noreg_GP;
} else {
- index = be_transform_node(index);
+ idx = be_transform_node(idx);
}
dbgi = get_irn_dbg_info(node);
if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
/* we have 3DNow!, this was already checked above */
- new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
+ new_node = new_bd_ia32_PrefetchW(dbgi, block, base, idx, mem);
} else if (ia32_cg_config.use_sse_prefetch) {
/* note: rw == 1 is IGNORED in that case */
param = get_Builtin_param(node, 2);
/* SSE style prefetch */
switch (locality) {
case 0:
- new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
+ new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, idx, mem);
break;
case 1:
- new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
+ new_node = new_bd_ia32_Prefetch2(dbgi, block, base, idx, mem);
break;
case 2:
- new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
+ new_node = new_bd_ia32_Prefetch1(dbgi, block, base, idx, mem);
break;
default:
- new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
+ new_node = new_bd_ia32_Prefetch0(dbgi, block, base, idx, mem);
break;
}
} else {
assert(ia32_cg_config.use_3dnow_prefetch);
/* 3DNow! style prefetch */
- new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
+ new_node = new_bd_ia32_Prefetch(dbgi, block, base, idx, mem);
}
set_irn_pinned(new_node, get_irn_pinned(node));
static ir_node *gen_be_IncSP(ir_node *node)
{
ir_node *res = be_duplicate_node(node);
- arch_irn_add_flags(res, arch_irn_flags_modify_flags);
+ arch_add_irn_flags(res, arch_irn_flags_modify_flags);
return res;
}
}
/* transform call modes */
if (mode_is_data(mode)) {
- const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
+ const arch_register_class_t *cls = arch_get_irn_reg_class(node);
mode = cls->mode;
}
} else if (proj == pn_be_Call_X_regular) {
proj = pn_ia32_Call_X_regular;
} else {
- arch_register_req_t const *const req = arch_get_register_req_out(node);
- int const n_outs = arch_irn_get_n_outs(new_call);
+ arch_register_req_t const *const req = arch_get_irn_register_req(node);
+ int const n_outs = arch_get_irn_n_outs(new_call);
int i;
assert(proj >= pn_be_Call_first_res);
for (i = 0; i < n_outs; ++i) {
arch_register_req_t const *const new_req
- = arch_get_out_register_req(new_call, i);
+ = arch_get_irn_register_req_out(new_call, i);
if (!(new_req->type & arch_register_req_type_limited) ||
new_req->cls != req->cls ||
long pos = get_Proj_proj(node);
if (mode == mode_M) {
- pos = arch_irn_get_n_outs(new_pred)-1;
+ pos = arch_get_irn_n_outs(new_pred)-1;
} else if (mode_is_int(mode) || mode_is_reference(mode)) {
mode = mode_Iu;
} else if (mode_is_float(mode)) {
ir_type *res_tp = get_method_res_type(mtp, j);
ir_node *res, *new_res;
const ir_edge_t *edge, *next;
- ir_mode *mode;
+ ir_mode *res_mode;
if (! is_atomic_type(res_tp)) {
/* no floating point return */
continue;
}
- mode = get_type_mode(res_tp);
- if (! mode_is_float(mode)) {
+ res_mode = get_type_mode(res_tp);
+ if (! mode_is_float(res_mode)) {
/* no floating point return */
continue;
}
dbg_info *db = get_irn_dbg_info(succ);
ir_node *block = get_nodes_block(succ);
ir_node *base = get_irn_n(succ, n_ia32_xStore_base);
- ir_node *index = get_irn_n(succ, n_ia32_xStore_index);
+ ir_node *idx = get_irn_n(succ, n_ia32_xStore_index);
ir_node *mem = get_irn_n(succ, n_ia32_xStore_mem);
ir_node *value = get_irn_n(succ, n_ia32_xStore_val);
ir_mode *mode = get_ia32_ls_mode(succ);
- ir_node *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
+ ir_node *st = new_bd_ia32_vfst(db, block, base, idx, mem, value, mode);
//ir_node *mem = new_r_Proj(st, mode_M, pn_ia32_vfst_M);
set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
if (is_ia32_use_frame(succ))
/* store st(0) on stack */
vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem,
- res, mode);
+ res, res_mode);
set_ia32_op_type(vfst, ia32_AddrModeD);
set_ia32_use_frame(vfst);
/* load into SSE register */
xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst_mem,
- mode);
+ res_mode);
set_ia32_op_type(xld, ia32_AddrModeS);
set_ia32_use_frame(xld);
- new_res = new_r_Proj(xld, mode, pn_ia32_xLoad_res);
+ new_res = new_r_Proj(xld, res_mode, pn_ia32_xLoad_res);
new_mem = new_r_Proj(xld, mode_M, pn_ia32_xLoad_M);
if (old_mem != NULL) {