aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@embecosm.com>2023-11-22 01:18:28 +0000
committerMaciej W. Rozycki <macro@embecosm.com>2023-11-22 01:18:28 +0000
commit40b243c4701e564d317ab35af7805ddd21a3e08f (patch)
treec439e96b2f56b8871e562ae75b47de521afafcf3
parent4111bdf99bf5c54b13e7d484fe4b75661d04a4e0 (diff)
downloadgcc-40b243c4701e564d317ab35af7805ddd21a3e08f.zip
gcc-40b243c4701e564d317ab35af7805ddd21a3e08f.tar.gz
gcc-40b243c4701e564d317ab35af7805ddd21a3e08f.tar.bz2
RISC-V: Add `addMODEcc' implementation for generic targets
Provide RTL expansion of conditional-add operations for generic targets using a suitable sequence of base integer machine instructions according to cost evaluation by if-conversion. Use existing `-mmovcc' command line option to enable this transformation. gcc/ * config/riscv/riscv.md (add<mode>cc): New expander.
-rw-r--r--gcc/config/riscv/riscv.md41
1 files changed, 41 insertions, 0 deletions
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 37860cf..86f89da8 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2655,6 +2655,8 @@
[(set_attr "type" "branch")
(set_attr "mode" "none")])
+;; Conditional move and add patterns.
+
(define_expand "mov<mode>cc"
[(set (match_operand:GPR 0 "register_operand")
(if_then_else:GPR (match_operand 1 "comparison_operator")
@@ -2670,6 +2672,45 @@
FAIL;
})
+(define_expand "add<mode>cc"
+ [(match_operand:GPR 0 "register_operand")
+ (match_operand 1 "comparison_operator")
+ (match_operand:GPR 2 "arith_operand")
+ (match_operand:GPR 3 "arith_operand")]
+ "TARGET_MOVCC"
+{
+ rtx cmp = operands[1];
+ rtx cmp0 = XEXP (cmp, 0);
+ rtx cmp1 = XEXP (cmp, 1);
+ machine_mode mode0 = GET_MODE (cmp0);
+
+ /* We only handle word mode integer compares for now. */
+ if (INTEGRAL_MODE_P (mode0) && mode0 != word_mode)
+ FAIL;
+
+ enum rtx_code code = GET_CODE (cmp);
+ rtx reg0 = gen_reg_rtx (<MODE>mode);
+ rtx reg1 = gen_reg_rtx (<MODE>mode);
+ rtx reg2 = gen_reg_rtx (<MODE>mode);
+ bool invert = false;
+
+ if (INTEGRAL_MODE_P (mode0))
+ riscv_expand_int_scc (reg0, code, cmp0, cmp1, &invert);
+ else if (FLOAT_MODE_P (mode0) && fp_scc_comparison (cmp, GET_MODE (cmp)))
+ riscv_expand_float_scc (reg0, code, cmp0, cmp1);
+ else
+ FAIL;
+
+ if (invert)
+ riscv_emit_binary (PLUS, reg1, reg0, constm1_rtx);
+ else
+ riscv_emit_unary (NEG, reg1, reg0);
+ riscv_emit_binary (AND, reg2, reg1, operands[3]);
+ riscv_emit_binary (PLUS, operands[0], reg2, operands[2]);
+
+ DONE;
+})
+
;; Patterns for implementations that optimize short forward branches.
(define_insn "*mov<GPR:mode><X:mode>cc"