static INLINE int mode_needs_gp_reg(ir_mode *mode) {
if(mode == mode_fpcw)
return 0;
- return mode_is_int(mode) || mode_is_character(mode) || mode_is_reference(mode);
+ return mode_is_int(mode) || mode_is_character(mode)
+ || mode_is_reference(mode) || mode == mode_b;
}
/**
return gen_Minus_ex(node, get_Minus_op(node));
}
+static ir_node *gen_bin_Not(ir_node *node)
+{
+ ir_graph *irg = current_ir_graph;
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_node *block = be_transform_node(get_nodes_block(node));
+ ir_node *op = get_Not_op(node);
+ ir_node *new_op = be_transform_node(op);
+ ir_node *noreg = ia32_new_NoReg_gp(env_cg);
+ ir_node *nomem = new_NoMem();
+ ir_node *one = new_rd_ia32_Immediate(dbgi, irg, block, NULL, 0, 1);
+ arch_set_irn_register(env_cg->arch_env, one, &ia32_gp_regs[REG_GP_NOREG]);
+
+ return new_rd_ia32_Xor(dbgi, irg, block, noreg, noreg, new_op, one, nomem);
+}
/**
* Transforms a Not node.
* @return The created ia32 Not node
*/
static ir_node *gen_Not(ir_node *node) {
- ir_node *op = get_Not_op(node);
+ ir_node *op = get_Not_op(node);
+ ir_mode *mode = get_irn_mode(node);
+
+ if(mode == mode_b) {
+ return gen_bin_Not(node);
+ }
assert (! mode_is_float(get_irn_mode(node)));
return gen_unop(node, op, new_rd_ia32_Not);
return new_op;
}
-static ir_node *try_create_TestJmp(ir_node *block, ir_node *node, long pnc)
+static ir_node *try_create_TestJmp(ir_node *block, dbg_info *dbgi, long pnc,
+ ir_node *cmp_left, ir_node *cmp_right)
{
- ir_node *cmp_left = get_Cmp_left(node);
ir_node *new_cmp_left;
- ir_node *cmp_right = get_Cmp_right(node);
ir_node *new_cmp_right;
ir_node *and_left;
ir_node *and_right;
ir_node *res;
ir_node *noreg;
ir_node *nomem;
- dbg_info *dbgi;
long pure_pnc = pnc & ~ia32_pn_Cmp_Unsigned;
- if(!is_Const_0(cmp_right))
+ if(cmp_right != NULL && !is_Const_0(cmp_right))
return NULL;
if(is_And(cmp_left) && (pure_pnc == pn_Cmp_Eq || pure_pnc == pn_Cmp_Lg)) {
new_cmp_right = be_transform_node(cmp_left);
}
- dbgi = get_irn_dbg_info(node);
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);
set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);
- SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
return res;
}
return create_Switch(node);
}
+ if(!is_Proj(sel) || !is_Cmp(get_Proj_pred(sel))) {
+ /* it's some mode_b value 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 = get_Proj_pred(sel);
cmp_a = get_Cmp_left(cmp);
cmp_b = get_Cmp_right(cmp);
}
if(mode_needs_gp_reg(cmp_mode)) {
- res = try_create_TestJmp(block, cmp, pnc);
- if(res != NULL)
+ res = try_create_TestJmp(block, dbgi, pnc, cmp_a, cmp_b);
+ if(res != NULL) {
+ SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
return res;
+ }
}
new_cmp_a = be_transform_node(cmp_a);
ir_node *res;
/* can we use a test instruction? */
- if(is_Const_0(cmp_right)) {
+ if(cmp_right == NULL || is_Const_0(cmp_right)) {
long pure_pnc = pnc & ~ia32_pn_Cmp_Unsigned;
if(is_And(cmp_left) &&
(pure_pnc == pn_Cmp_Eq || pure_pnc == pn_Cmp_Lg)) {
assert(get_Psi_n_conds(node) == 1);
assert(get_irn_mode(cond) == mode_b);
- if(is_And(cond) || is_Or(cond)) {
- /* this is a psi with a complicated condition, we have to compare it
- * against 0 */
+ if(!is_Proj(cond) || !is_Cmp(get_Proj_pred(cond))) {
+ /* a mode_b value, we have to compare it against 0 */
cmp_left = cond;
cmp_right = new_Const_long(mode_Iu, 0);
pnc = pn_Cmp_Lg;
ir_node *nomem = new_rd_NoMem(irg);
ir_node *res;
+ if (src_mode == mode_b) {
+ assert(mode_is_int(tgt_mode));
+ /* nothing to do, we already model bools as 0/1 ints */
+ return new_op;
+ }
+
if (src_mode == tgt_mode) {
if (get_Conv_strict(node)) {
if (USE_SSE2(env_cg)) {
} else {
return gen_x87_gp_to_fp(node, src_mode);
}
+ } else if(tgt_mode == mode_b) {
+ /* to bool */
+ res = create_set(pn_Cmp_Lg, op, NULL, dbgi, block);
} else {
/* to int */
ir_mode *smaller_mode;
case iro_Call:
{
ASSERT_AND_RET(
- (proj >= 0 && mode_is_data(mode)),
+ (proj >= 0 && mode_is_datab(mode)),
"wrong Proj from Proj from Call", 0);
mt = get_Call_type(pred);
ASSERT_AND_RET(
ASSERT_AND_RET( mem_mode == mode_M, "Return node", 0 ); /* operand M */
for (i = get_Return_n_ress(n) - 1; i >= 0; --i) {
- ASSERT_AND_RET( mode_is_data(get_irn_mode(get_Return_res(n, i))), "Return node", 0 ); /* operand datai */
+ ASSERT_AND_RET( mode_is_datab(get_irn_mode(get_Return_res(n, i))), "Return node", 0 ); /* operand datai */
}
ASSERT_AND_RET( mymode == mode_X, "Result X", 0 ); /* result X */
/* Compare returned results with result types of method type */
ASSERT_AND_RET_DBG(
/* Not: BB x int --> int */
- mode_is_int(mymode) &&
+ (mode_is_int(mymode) || mymode == mode_b) &&
mymode == op1mode,
"Not node", 0,
show_unop_failure(n, "/* Not: BB x int --> int */");
);
}
}
- ASSERT_AND_RET( mode_is_dataM(mymode), "Phi node", 0 );
+ ASSERT_AND_RET(mode_is_dataM(mymode) || mymode == mode_b, "Phi node", 0 );
if (mymode == mode_M) {
for (i = get_Phi_n_preds(n) - 1; i >= 0; --i) {