aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorXiao Zeng <zengxiao@eswincomputing.com>2023-08-03 16:09:46 -0400
committerJeff Law <jeffreyalaw@gmail.com>2023-08-03 16:14:02 -0400
commit9e3fd332959930efd3cabf222afbac910507d2f3 (patch)
tree5841e3a314c2b782c654499ae87338ffc5c8d2c8 /gcc
parentc2a447d840476dbd99720f72809304a74abcf040 (diff)
downloadgcc-9e3fd332959930efd3cabf222afbac910507d2f3.zip
gcc-9e3fd332959930efd3cabf222afbac910507d2f3.tar.gz
gcc-9e3fd332959930efd3cabf222afbac910507d2f3.tar.bz2
[PATCH 3/5] [RISC-V] Generate Zicond instruction for select pattern with condition eq or neq to 0
[ This is a partial commit. So not all the cases mentioned by Xiao are currently handled. ] This patch recognizes Zicond patterns when the select pattern with condition eq or neq to 0 (using eq as an example), namely: 1 rd = (rs2 == 0) ? non-imm : 0 2 rd = (rs2 == 0) ? non-imm : non-imm 3 rd = (rs2 == 0) ? reg : non-imm 4 rd = (rs2 == 0) ? reg : reg gcc/ChangeLog: * config/riscv/riscv.cc (riscv_expand_conditional_move): Recognize various Zicond patterns. * config/riscv/riscv.md (mov<mode>cc): Allow TARGET_ZICOND. Use sfb_alu_operand for both arms of the conditional move. Co-authored-by: Jeff Law <jlaw@ventanamicro.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/riscv/riscv.cc60
-rw-r--r--gcc/config/riscv/riscv.md4
2 files changed, 58 insertions, 6 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index d8fab68..8b72561 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3580,15 +3580,67 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
riscv_emit_int_compare (&code, &op0, &op1, need_eq_ne_p);
rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
- /* The expander allows (const_int 0) for CONS for the benefit of
- TARGET_XTHEADCONDMOV, but that case isn't supported for
- TARGET_SFB_ALU. So force that operand into a register if
- necessary. */
+ /* The expander is a bit loose in its specification of the true
+ arm of the conditional move. That allows us to support more
+ cases for extensions which are more general than SFB. But
+ does mean we need to force CONS into a register at this point. */
cons = force_reg (GET_MODE (dest), cons);
emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
cond, cons, alt)));
return true;
}
+ else if (TARGET_ZICOND
+ && (code == EQ || code == NE)
+ && GET_MODE_CLASS (mode) == MODE_INT)
+ {
+ /* The comparison must be comparing WORD_MODE objects. We must
+ enforce that so that we don't strip away a sign_extension
+ thinking it is unnecessary. We might consider using
+ riscv_extend_operands if they are not already properly extended. */
+ if (GET_MODE (op0) != word_mode || GET_MODE (op1) != word_mode)
+ return false;
+
+ /* 0, reg or 0, imm */
+ if (cons == CONST0_RTX (mode)
+ && (REG_P (alt)
+ || (CONST_INT_P (alt) && alt != CONST0_RTX (mode))))
+ {
+ riscv_emit_int_compare (&code, &op0, &op1, true);
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+ alt = force_reg (mode, alt);
+ emit_insn (gen_rtx_SET (dest,
+ gen_rtx_IF_THEN_ELSE (mode, cond,
+ cons, alt)));
+ return true;
+ }
+ /* imm, imm */
+ else if (CONST_INT_P (cons) && cons != CONST0_RTX (mode)
+ && CONST_INT_P (alt) && alt != CONST0_RTX (mode))
+ {
+ riscv_emit_int_compare (&code, &op0, &op1, true);
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+ HOST_WIDE_INT t = INTVAL (alt) - INTVAL (cons);
+ alt = force_reg (mode, gen_int_mode (t, mode));
+ emit_insn (gen_rtx_SET (dest,
+ gen_rtx_IF_THEN_ELSE (mode, cond,
+ CONST0_RTX (mode),
+ alt)));
+ riscv_emit_binary (PLUS, dest, dest, cons);
+ return true;
+ }
+ /* reg, 0 or imm, 0 */
+ else if ((REG_P (cons)
+ || (CONST_INT_P (cons) && cons != CONST0_RTX (mode)))
+ && alt == CONST0_RTX (mode))
+ {
+ riscv_emit_int_compare (&code, &op0, &op1, true);
+ rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+ cons = force_reg (mode, cons);
+ emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (mode, cond,
+ cons, alt)));
+ return true;
+ }
+ }
return false;
}
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 24819cc..688fd69 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2492,9 +2492,9 @@
(define_expand "mov<mode>cc"
[(set (match_operand:GPR 0 "register_operand")
(if_then_else:GPR (match_operand 1 "comparison_operator")
- (match_operand:GPR 2 "reg_or_0_operand")
+ (match_operand:GPR 2 "sfb_alu_operand")
(match_operand:GPR 3 "sfb_alu_operand")))]
- "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV"
+ "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND"
{
if (riscv_expand_conditional_move (operands[0], operands[1],
operands[2], operands[3]))