emit_jump_insn (gen_condjump (condition, label));
}
-/* Helper to emit two one-sided conditional moves for the movecc. */
-
-static void
-riscv_expand_conditional_move_onesided (rtx dest, rtx cons, rtx alt,
- rtx_code code, rtx op0, rtx op1)
-{
- machine_mode mode = GET_MODE (dest);
-
- gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
- gcc_assert (reg_or_0_operand (cons, mode));
- gcc_assert (reg_or_0_operand (alt, mode));
-
- riscv_emit_int_compare (&code, &op0, &op1, true);
- rtx cond = gen_rtx_fmt_ee (code, mode, op0, op1);
-
- rtx tmp1 = gen_reg_rtx (mode);
- rtx tmp2 = gen_reg_rtx (mode);
-
- emit_insn (gen_rtx_SET (tmp1, gen_rtx_IF_THEN_ELSE (mode, cond,
- cons, const0_rtx)));
-
- /* We need to expand a sequence for both blocks and we do that such,
- that the second conditional move will use the inverted condition.
- We use temporaries that are or'd to the dest register. */
- cond = gen_rtx_fmt_ee ((code == EQ) ? NE : EQ, mode, op0, op1);
- emit_insn (gen_rtx_SET (tmp2, gen_rtx_IF_THEN_ELSE (mode, cond,
- alt, const0_rtx)));
-
- emit_insn (gen_rtx_SET (dest, gen_rtx_IOR (mode, tmp1, tmp2)));
- }
-
/* Emit a cond move: If OP holds, move CONS to DEST; else move ALT to DEST.
Return 0 if expansion failed. */
rtx_code code = GET_CODE (op);
rtx op0 = XEXP (op, 0);
rtx op1 = XEXP (op, 1);
+ bool need_eq_ne_p = false;
if (TARGET_XTHEADCONDMOV
&& GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE (op0) == mode
&& GET_MODE (op1) == mode
&& (code == EQ || code == NE))
+ need_eq_ne_p = true;
+
+ if (need_eq_ne_p
+ || (TARGET_SFB_ALU && GET_MODE (op0) == word_mode))
{
- riscv_expand_conditional_move_onesided (dest, cons, alt, code, op0, op1);
- return true;
- }
- else if (TARGET_SFB_ALU
- && GET_MODE (op0) == word_mode)
- {
- riscv_emit_int_compare (&code, &op0, &op1);
+ 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
/* { dg-do compile } */
/* { dg-options "-O2 -march=rv32gc_xtheadcondmov -mabi=ilp32 -mriscv-attribute" } */
-/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os" "-Og" "-O3" "-Oz" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
/*
**ConEmv_imm_imm_reg:
** addi a5,a0,-1000
** li a0,10
-** th.mvnez a0,zero,a5
-** th.mveqz a1,zero,a5
-** or a0,a0,a1
+** th.mvnez a0,a1,a5
** ret
*/
int ConEmv_imm_imm_reg(int x, int y){
/*
**ConEmv_imm_reg_reg:
** addi a5,a0,-1000
-** th.mvnez a1,zero,a5
-** th.mveqz a2,zero,a5
-** or a0,a1,a2
+** th.mveqz a2,a1,a5
+** mv a0,a2
** ret
*/
int ConEmv_imm_reg_reg(int x, int y, int z){
**ConEmv_reg_imm_reg:
** sub a1,a0,a1
** li a0,10
-** th.mvnez a0,zero,a1
-** th.mveqz a2,zero,a1
-** or a0,a0,a2
+** th.mvnez a0,a2,a1
** ret
*/
int ConEmv_reg_imm_reg(int x, int y, int z){
/*
**ConEmv_reg_reg_reg:
** sub a1,a0,a1
-** th.mvnez a2,zero,a1
-** th.mveqz a3,zero,a1
-** or a0,a2,a3
+** th.mveqz a3,a2,a1
+** mv a0,a3
** ret
*/
int ConEmv_reg_reg_reg(int x, int y, int z, int n){
/*
**ConNmv_imm_imm_reg:
-** li a5,9998336
-** addi a4,a0,-1000
-** addi a5,a5,1664
-** th.mvnez a1,zero,a4
-** th.mveqz a5,zero,a4
-** or a0,a1,a5
+** addi a5,a0,-1000
+** li a0,9998336
+** addi a0,a0,1664
+** th.mveqz a0,a1,a5
** ret
*/
int ConNmv_imm_imm_reg(int x, int y){
/*
**ConNmv_imm_reg_reg:
-** addi a5,a0,-1000
-** th.mveqz a1,zero,a5
-** th.mvnez a2,zero,a5
-** or a0,a1,a2
+** addi a0,a0,-1000
+** th.mvnez a2,a1,a0
+** mv a0,a2
** ret
*/
int ConNmv_imm_reg_reg(int x, int y, int z){
**ConNmv_reg_imm_reg:
** sub a1,a0,a1
** li a0,10
-** th.mveqz a0,zero,a1
-** th.mvnez a2,zero,a1
-** or a0,a0,a2
+** th.mveqz a0,a2,a1
** ret
*/
int ConNmv_reg_imm_reg(int x, int y, int z){
/*
**ConNmv_reg_reg_reg:
-** sub a1,a0,a1
-** th.mveqz a2,zero,a1
-** th.mvnez a3,zero,a1
-** or a0,a2,a3
+** sub a0,a0,a1
+** th.mvnez a3,a2,a0
+** mv a0,a3
** ret
*/
int ConNmv_reg_reg_reg(int x, int y, int z, int n){
/* { dg-do compile } */
/* { dg-options "-O2 -march=rv64gc_xtheadcondmov -mabi=lp64d -mriscv-attribute" } */
-/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-Os" "-Og" "-O3" "-Oz" "-flto"} } */
/* { dg-final { check-function-bodies "**" "" } } */
/*
**ConEmv_imm_imm_reg:
** addi a5,a0,-1000
** li a0,10
-** th.mvnez a0,zero,a5
-** th.mveqz a1,zero,a5
-** or a0,a0,a1
+** th.mvnez a0,a1,a5
** ret
*/
int ConEmv_imm_imm_reg(int x, int y){
/*
**ConEmv_imm_reg_reg:
-** addi a5,a0,-1000
-** th.mvnez a1,zero,a5
-** th.mveqz a2,zero,a5
-** or a0,a1,a2
+** addi a0,a0,-1000
+** th.mveqz a2,a1,a5
+** mv a0,a2
** ret
*/
int ConEmv_imm_reg_reg(int x, int y, int z){
**ConEmv_reg_imm_reg:
** sub a1,a0,a1
** li a0,10
-** th.mvnez a0,zero,a1
-** th.mveqz a2,zero,a1
-** or a0,a0,a2
+** th.mvnez a0,a2,a1
** ret
*/
int ConEmv_reg_imm_reg(int x, int y, int z){
/*
**ConEmv_reg_reg_reg:
** sub a1,a0,a1
-** th.mvnez a2,zero,a1
-** th.mveqz a3,zero,a1
-** or a0,a2,a3
+** th.mveqz a3,a2,a1
+** mv a0,a3
** ret
*/
int ConEmv_reg_reg_reg(int x, int y, int z, int n){
/*
**ConNmv_imm_imm_reg:
-** li a5,9998336
-** addi a4,a0,-1000
-** addi a5,a5,1664
-** th.mvnez a1,zero,a4
-** th.mveqz a5,zero,a4
-** or a0,a1,a5
+** addi a5,a0,-1000
+** li a0,9998336
+** addi a0,a0,1664
+** th.mveqz a0,a1,a5
** ret
*/
int ConNmv_imm_imm_reg(int x, int y){
/*
**ConNmv_imm_reg_reg:
** addi a5,a0,-1000
-** th.mveqz a1,zero,a5
-** th.mvnez a2,zero,a5
-** or a0,a1,a2
+** th.mvnez a2,a1,a0
+** mv a0,a2
** ret
*/
int ConNmv_imm_reg_reg(int x, int y, int z){
**ConNmv_reg_imm_reg:
** sub a1,a0,a1
** li a0,10
-** th.mveqz a0,zero,a1
-** th.mvnez a2,zero,a1
-** or a0,a0,a2
+** th.mveqz a0,a2,a1
** ret
*/
int ConNmv_reg_imm_reg(int x, int y, int z){
/*
**ConNmv_reg_reg_reg:
-** sub a1,a0,a1
-** th.mveqz a2,zero,a1
-** th.mvnez a3,zero,a1
-** or a0,a2,a3
+** sub a0,a0,a1
+** th.mvnez a3,a2,a0
+** mv a0,a3
** ret
*/
int ConNmv_reg_reg_reg(int x, int y, int z, int n){