diff options
author | David Holsgrove <david.holsgrove@xilinx.com> | 2014-02-23 18:36:38 +0000 |
---|---|---|
committer | Michael Eager <eager@gcc.gnu.org> | 2014-02-23 18:36:38 +0000 |
commit | d5a19af1beb13732288d09f21c9d28af55137b1d (patch) | |
tree | 489ca9896a54997b5f3351776fd6c7cfda7883b5 /gcc/config/microblaze/microblaze.c | |
parent | 9fbb94f2270d423ed8715578e7fa76daa8e85ab9 (diff) | |
download | gcc-d5a19af1beb13732288d09f21c9d28af55137b1d.tar.gz |
predicates.md: Add cmp_op predicate.
2014-02-23 David Holsgrove <david.holsgrove@xilinx.com>
* config/microblaze/predicates.md: Add cmp_op predicate.
* config/microblaze/microblaze.md: Add branch_compare instruction
which uses cmp_op predicate and emits cmp insn before branch.
* config/microblaze/microblaze.c (microblaze_emit_compare): Rename
to microblaze_expand_conditional_branch and consolidate logic.
(microblaze_expand_conditional_branch): emit branch_compare
insn instead of handling cmp op separate from branch insn.
From-SVN: r208055
Diffstat (limited to 'gcc/config/microblaze/microblaze.c')
-rw-r--r-- | gcc/config/microblaze/microblaze.c | 68 |
1 files changed, 24 insertions, 44 deletions
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c index cd2a788caae..985d26a40ca 100644 --- a/gcc/config/microblaze/microblaze.c +++ b/gcc/config/microblaze/microblaze.c @@ -3257,65 +3257,45 @@ microblaze_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) emit_move_insn (mem, fnaddr); } -/* Emit instruction to perform compare. - cmp is (compare_op op0 op1). */ -static rtx -microblaze_emit_compare (enum machine_mode mode, rtx cmp, enum rtx_code *cmp_code) +/* Generate conditional branch -- first, generate test condition, + second, generate correct branch instruction. */ + +void +microblaze_expand_conditional_branch (enum machine_mode mode, rtx operands[]) { - rtx cmp_op0 = XEXP (cmp, 0); - rtx cmp_op1 = XEXP (cmp, 1); + enum rtx_code code = GET_CODE (operands[0]); + rtx cmp_op0 = operands[1]; + rtx cmp_op1 = operands[2]; + rtx label1 = operands[3]; rtx comp_reg = gen_reg_rtx (SImode); - enum rtx_code code = *cmp_code; - + rtx condition; + gcc_assert ((GET_CODE (cmp_op0) == REG) || (GET_CODE (cmp_op0) == SUBREG)); /* If comparing against zero, just test source reg. */ - if (cmp_op1 == const0_rtx) - return cmp_op0; + if (cmp_op1 == const0_rtx) + { + comp_reg = cmp_op0; + condition = gen_rtx_fmt_ee (signed_condition (code), SImode, comp_reg, const0_rtx); + emit_jump_insn (gen_condjump (condition, label1)); + } - if (code == EQ || code == NE) + else if (code == EQ || code == NE) { /* Use xor for equal/not-equal comparison. */ emit_insn (gen_xorsi3 (comp_reg, cmp_op0, cmp_op1)); + condition = gen_rtx_fmt_ee (signed_condition (code), SImode, comp_reg, const0_rtx); + emit_jump_insn (gen_condjump (condition, label1)); } - else if (code == GT || code == GTU || code == LE || code == LEU) - { - /* MicroBlaze compare is not symmetrical. */ - /* Swap argument order. */ - cmp_op1 = force_reg (mode, cmp_op1); - if (code == GT || code == LE) - emit_insn (gen_signed_compare (comp_reg, cmp_op0, cmp_op1)); - else - emit_insn (gen_unsigned_compare (comp_reg, cmp_op0, cmp_op1)); - /* Translate test condition. */ - *cmp_code = swap_condition (code); - } - else /* if (code == GE || code == GEU || code == LT || code == LTU) */ + else { + /* Generate compare and branch in single instruction. */ cmp_op1 = force_reg (mode, cmp_op1); - if (code == GE || code == LT) - emit_insn (gen_signed_compare (comp_reg, cmp_op1, cmp_op0)); - else - emit_insn (gen_unsigned_compare (comp_reg, cmp_op1, cmp_op0)); + condition = gen_rtx_fmt_ee (code, mode, cmp_op0, cmp_op1); + emit_jump_insn (gen_branch_compare(condition, cmp_op0, cmp_op1, label1)); } - - return comp_reg; } -/* Generate conditional branch -- first, generate test condition, - second, generate correct branch instruction. */ - -void -microblaze_expand_conditional_branch (enum machine_mode mode, rtx operands[]) -{ - enum rtx_code code = GET_CODE (operands[0]); - rtx comp; - rtx condition; - - comp = microblaze_emit_compare (mode, operands[0], &code); - condition = gen_rtx_fmt_ee (signed_condition (code), SImode, comp, const0_rtx); - emit_jump_insn (gen_condjump (condition, operands[3])); -} void microblaze_expand_conditional_branch_sf (rtx operands[]) |