static ir_node *create_immediate_or_transform(ir_node *node,
char immediate_constraint_type);
+static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
+ dbg_info *dbgi, ir_node *new_block,
+ ir_node *new_op);
+
/**
* Return true if a mode can be stored in the GP register set
*/
res_mode = mode_vfp;
}
} else {
+ if(mode == mode_b)
+ mode = mode_Iu;
+
new_op = new_rd_ia32_Load(dbgi, irg, block, lptr, noreg, new_mem);
res_mode = mode_Iu;
}
}
} else {
new_val = create_immediate_or_transform(val, 0);
+ if(mode == mode_b)
+ mode = mode_Iu;
if (get_mode_size_bits(mode) == 8) {
new_op = new_rd_ia32_Store8Bit(dbgi, irg, block, sptr, noreg,
return new_op;
}
+static ir_node *maybe_scale_up(ir_node *new_op, ir_mode *mode, dbg_info *dbgi)
+{
+ ir_mode *tgt_mode;
+ ir_node *block;
+
+ if(get_mode_size_bits(mode) == 32)
+ return new_op;
+ if(mode == mode_b)
+ return new_op;
+ if(is_ia32_Immediate(new_op))
+ return new_op;
+
+ if(mode_is_signed(mode))
+ tgt_mode = mode_Is;
+ else
+ tgt_mode = mode_Iu;
+
+ block = get_nodes_block(new_op);
+ return create_I2I_Conv(mode, tgt_mode, dbgi, block, new_op);
+}
+
static ir_node *try_create_TestJmp(ir_node *block, dbg_info *dbgi, long pnc,
ir_node *cmp_left, ir_node *cmp_right)
{
ir_node *res;
ir_node *noreg;
ir_node *nomem;
+ ir_mode *mode;
long pure_pnc = pnc & ~ia32_pn_Cmp_Unsigned;
if(cmp_right != NULL && !is_Const_0(cmp_right))
and_left = get_And_left(cmp_left);
and_right = get_And_right(cmp_left);
+ mode = get_irn_mode(and_left);
new_cmp_left = be_transform_node(and_left);
new_cmp_right = create_immediate_or_transform(and_right, 0);
} else {
+ mode = get_irn_mode(cmp_left);
new_cmp_left = be_transform_node(cmp_left);
new_cmp_right = be_transform_node(cmp_left);
}
- noreg = ia32_new_NoReg_gp(env_cg);
- nomem = new_NoMem();
+ assert(get_mode_size_bits(mode) <= 32);
+ new_cmp_left = maybe_scale_up(new_cmp_left, mode, dbgi);
+ new_cmp_right = maybe_scale_up(new_cmp_right, mode, dbgi);
+ noreg = ia32_new_NoReg_gp(env_cg);
+ nomem = new_NoMem();
res = new_rd_ia32_TestJmp(dbgi, current_ir_graph, block, noreg, noreg,
new_cmp_left, new_cmp_right, nomem, pnc);
int switch_min = INT_MAX;
const ir_edge_t *edge;
+ 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);
}
if(!is_Proj(sel) || !is_Cmp(get_Proj_pred(sel))) {
- /* it's some mode_b value not a direct comparison -> create a testjmp */
+ /* it's some mode_b value but not a direct comparison -> create a
+ * testjmp */
res = try_create_TestJmp(block, dbgi, pn_Cmp_Lg, sel, NULL);
SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
return res;
cmp_a = get_Cmp_left(cmp);
cmp_b = get_Cmp_right(cmp);
cmp_mode = get_irn_mode(cmp_a);
- pnc = get_Proj_proj(sel);
+ pnc = get_Proj_proj(sel);
if(mode_is_float(cmp_mode) || !mode_is_signed(cmp_mode)) {
pnc |= ia32_pn_Cmp_Unsigned;
}
set_ia32_commutative(res);
}
} else {
- assert(get_mode_size_bits(cmp_mode) == 32);
+ /** workaround smaller compare modes with converts...
+ * We could easily support 16bit compares, for 8 bit we have to set
+ * additional register constraints, which we don't do yet
+ */
+ new_cmp_a = maybe_scale_up(new_cmp_a, cmp_mode, dbgi);
+ new_cmp_b = maybe_scale_up(new_cmp_b, cmp_mode, dbgi);
+
res = new_rd_ia32_CondJmp(dbgi, irg, block, noreg, noreg,
new_cmp_a, new_cmp_b, nomem, pnc);
set_ia32_commutative(res);
ir_graph *irg = current_ir_graph;
ir_node *noreg = ia32_new_NoReg_gp(env_cg);
ir_node *nomem = new_rd_NoMem(irg);
+ ir_mode *mode;
ir_node *new_cmp_left;
ir_node *new_cmp_right;
ir_node *res;
ir_node *and_left = get_And_left(cmp_left);
ir_node *and_right = get_And_right(cmp_left);
+ mode = get_irn_mode(and_left);
new_cmp_left = be_transform_node(and_left);
new_cmp_right = create_immediate_or_transform(and_right, 0);
} else {
+ mode = get_irn_mode(cmp_left);
new_cmp_left = be_transform_node(cmp_left);
new_cmp_right = be_transform_node(cmp_left);
}
+ assert(get_mode_size_bits(mode) <= 32);
+ new_cmp_left = maybe_scale_up(new_cmp_left, mode, dbgi);
+ new_cmp_right = maybe_scale_up(new_cmp_right, mode, dbgi);
+
res = new_rd_ia32_TestSet(dbgi, current_ir_graph, block, noreg, noreg,
new_cmp_left, new_cmp_right, nomem, pnc);
set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);
return res;
}
+ mode = get_irn_mode(cmp_left);
+
new_cmp_left = be_transform_node(cmp_left);
new_cmp_right = create_immediate_or_transform(cmp_right, 0);
+
+ assert(get_mode_size_bits(mode) <= 32);
+ new_cmp_left = maybe_scale_up(new_cmp_left, mode, dbgi);
+ new_cmp_right = maybe_scale_up(new_cmp_right, mode, dbgi);
+
res = new_rd_ia32_CmpSet(dbgi, irg, block, noreg, noreg,
new_cmp_left, new_cmp_right, nomem, pnc);
return res;
}
+static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
+ dbg_info *dbgi, ir_node *new_block,
+ ir_node *new_op)
+{
+ ir_graph *irg = current_ir_graph;
+ int src_bits = get_mode_size_bits(src_mode);
+ int tgt_bits = get_mode_size_bits(tgt_mode);
+ ir_node *noreg = ia32_new_NoReg_gp(env_cg);
+ ir_node *nomem = new_rd_NoMem(irg);
+ ir_node *res;
+ ir_mode *smaller_mode;
+ int smaller_bits;
+
+ if (src_bits < tgt_bits) {
+ smaller_mode = src_mode;
+ smaller_bits = src_bits;
+ } else {
+ smaller_mode = tgt_mode;
+ smaller_bits = tgt_bits;
+ }
+
+ DB((dbg, LEVEL_1, "create Conv(int, int) ...", src_mode, tgt_mode));
+ if (smaller_bits == 8) {
+ res = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
+ new_op, nomem);
+ set_ia32_ls_mode(res, smaller_mode);
+ } else {
+ res = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, noreg, noreg, new_op,
+ nomem);
+ set_ia32_ls_mode(res, smaller_mode);
+ }
+ set_ia32_am_support(res, ia32_am_Source, ia32_am_unary);
+
+ return res;
+}
+
/**
* Transforms a Conv node.
*
return res;
}
} else if(tgt_mode == mode_b) {
- /* to bool */
-#if 0
- res = create_set(pn_Cmp_Lg, op, NULL, dbgi, block);
-#else
- DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...", src_mode, tgt_mode));
+ /* mode_b lowering already took care that we only have 0/1 values */
+ DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
+ src_mode, tgt_mode));
return new_op;
-#endif
} else {
/* to int */
- ir_mode *smaller_mode;
- int smaller_bits;
-
if (src_bits == tgt_bits) {
DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
src_mode, tgt_mode));
return new_op;
}
- if (src_bits < tgt_bits) {
- smaller_mode = src_mode;
- smaller_bits = src_bits;
- } else {
- smaller_mode = tgt_mode;
- smaller_bits = tgt_bits;
- }
-
- DB((dbg, LEVEL_1, "create Conv(int, int) ...", src_mode, tgt_mode));
- if (smaller_bits == 8) {
- res = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, new_op, nomem);
- set_ia32_ls_mode(res, smaller_mode);
- } else {
- res = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, new_op, nomem);
- set_ia32_ls_mode(res, smaller_mode);
- }
- set_ia32_am_support(res, ia32_am_Source, ia32_am_unary);
+ res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, new_op);
}
}