return new_node;
}
+/**
+ * Replace Cmp(x, 0) by a Test(x, x)
+ */
+static void peephole_ia32_Cmp(ir_node *const node)
+{
+ ir_node *right;
+ ia32_immediate_attr_t const *imm;
+ dbg_info *dbgi;
+ ir_graph *irg;
+ ir_node *block;
+ ir_node *noreg;
+ ir_node *nomem;
+ ir_node *op;
+ ia32_attr_t const *attr;
+ int ins_permuted;
+ int cmp_unsigned;
+ ir_node *test;
+ arch_register_t const *reg;
+
+ if (get_ia32_op_type(node) != ia32_Normal)
+ return;
+
+ right = get_irn_n(node, n_ia32_Cmp_right);
+ if (!is_ia32_Immediate(right))
+ return;
+
+ imm = get_ia32_immediate_attr_const(right);
+ if (imm->symconst != NULL || imm->offset != 0)
+ return;
+
+ dbgi = get_irn_dbg_info(node);
+ irg = current_ir_graph;
+ block = get_nodes_block(node);
+ noreg = ia32_new_NoReg_gp(cg);
+ nomem = get_irg_no_mem(irg);
+ op = get_irn_n(node, n_ia32_Cmp_left);
+ attr = get_irn_generic_attr(node);
+ ins_permuted = attr->data.ins_permuted;
+ cmp_unsigned = attr->data.cmp_unsigned;
+
+ if (is_ia32_Cmp(node)) {
+ test = new_rd_ia32_Test(dbgi, irg, block, noreg, noreg, nomem,
+ op, op, ins_permuted, cmp_unsigned);
+ } else {
+ test = new_rd_ia32_Test8Bit(dbgi, irg, block, noreg, noreg, nomem,
+ op, op, ins_permuted, cmp_unsigned);
+ }
+ set_ia32_ls_mode(test, get_ia32_ls_mode(node));
+
+ reg = arch_get_irn_register(arch_env, node);
+ arch_set_irn_register(arch_env, test, reg);
+
+ sched_add_before(node, test);
+ be_peephole_exchange(node, test);
+}
+
/**
* Peephole optimization for Test instructions.
* We can remove the Test, if a zero flags was produced which is still
/* register peephole optimisations */
clear_irp_opcodes_generic_func();
- register_peephole_optimisation(op_ia32_Const, peephole_ia32_Const);
- register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP);
- register_peephole_optimisation(op_ia32_Lea, peephole_ia32_Lea);
- register_peephole_optimisation(op_ia32_Test, peephole_ia32_Test);
+ register_peephole_optimisation(op_ia32_Const, peephole_ia32_Const);
+ register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP);
+ register_peephole_optimisation(op_ia32_Lea, peephole_ia32_Lea);
+ register_peephole_optimisation(op_ia32_Cmp, peephole_ia32_Cmp);
+ register_peephole_optimisation(op_ia32_Cmp8Bit, peephole_ia32_Cmp);
+ register_peephole_optimisation(op_ia32_Test, peephole_ia32_Test);
register_peephole_optimisation(op_ia32_Test8Bit, peephole_ia32_Test);
- register_peephole_optimisation(op_be_Return, peephole_ia32_Return);
+ register_peephole_optimisation(op_be_Return, peephole_ia32_Return);
if (! ia32_cg_config.use_imul_mem_imm32)
register_peephole_optimisation(op_ia32_IMul, peephole_ia32_Imul_split);
if (ia32_cg_config.use_pxor)
assert(ia32_mode_needs_gp_reg(cmp_mode));
- /* we prefer the Test instruction where possible except cases where
- * we can use SourceAM */
+ /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
cmp_unsigned = !mode_is_signed(cmp_mode);
- if (is_Const_0(right)) {
- if (is_And(left) &&
- get_irn_n_edges(left) == 1 &&
- can_fold_test_and(node)) {
- /* Test(and_left, and_right) */
- ir_node *and_left = get_And_left(left);
- ir_node *and_right = get_And_right(left);
- ir_mode *mode = get_irn_mode(and_left);
-
- match_arguments(&am, block, and_left, and_right, NULL,
- match_commutative |
- match_am | match_8bit_am | match_16bit_am |
- match_am_and_immediates | match_immediate |
- match_8bit | match_16bit);
- if (get_mode_size_bits(mode) == 8) {
- new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
- addr->index, addr->mem, am.new_op1,
- am.new_op2, am.ins_permuted,
- cmp_unsigned);
- } else {
- new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
- addr->index, addr->mem, am.new_op1,
- am.new_op2, am.ins_permuted, cmp_unsigned);
- }
+ if (is_Const_0(right) &&
+ is_And(left) &&
+ get_irn_n_edges(left) == 1 &&
+ can_fold_test_and(node)) {
+ /* Test(and_left, and_right) */
+ ir_node *and_left = get_And_left(left);
+ ir_node *and_right = get_And_right(left);
+ ir_mode *mode = get_irn_mode(and_left);
+
+ match_arguments(&am, block, and_left, and_right, NULL,
+ match_commutative |
+ match_am | match_8bit_am | match_16bit_am |
+ match_am_and_immediates | match_immediate |
+ match_8bit | match_16bit);
+ if (get_mode_size_bits(mode) == 8) {
+ new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
+ addr->index, addr->mem, am.new_op1,
+ am.new_op2, am.ins_permuted,
+ cmp_unsigned);
} else {
- match_arguments(&am, block, NULL, left, NULL,
- match_am | match_8bit_am | match_16bit_am |
- match_8bit | match_16bit);
- if (am.op_type == ia32_AddrModeS) {
- /* Cmp(AM, 0) */
- ir_node *imm_zero = try_create_Immediate(right, 0);
- if (get_mode_size_bits(cmp_mode) == 8) {
- new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
- addr->index, addr->mem, am.new_op2,
- imm_zero, am.ins_permuted,
- cmp_unsigned);
- } else {
- new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
- addr->index, addr->mem, am.new_op2,
- imm_zero, am.ins_permuted, cmp_unsigned);
- }
- } else {
- /* Test(left, left) */
- if (get_mode_size_bits(cmp_mode) == 8) {
- new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
- addr->index, addr->mem, am.new_op2,
- am.new_op2, am.ins_permuted,
- cmp_unsigned);
- } else {
- new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
- addr->index, addr->mem, am.new_op2,
- am.new_op2, am.ins_permuted,
- cmp_unsigned);
- }
- }
+ new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
+ addr->index, addr->mem, am.new_op1,
+ am.new_op2, am.ins_permuted, cmp_unsigned);
}
} else {
/* Cmp(left, right) */