aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVineet Gupta <vineetg@rivosinc.com>2023-07-25 13:59:48 -0700
committerVineet Gupta <vineetg@rivosinc.com>2023-07-27 17:33:31 -0700
commit596f7ef9f6b2d05fe9053bafe9a914df59930dcd (patch)
tree04f78a8ea0a7bc2c88ca813ebe3f401f9f831a9e
parent632ca722d4aac65a160c423f45cf791d7eb1f9ad (diff)
RISC-V: splitter to generate high bit set for -0.0devel/vineetg/optim-double-const-m0
Signed-off-by: Vineet Gupta <vineetg@rivosinc.com>
-rw-r--r--gcc/config/riscv/predicates.md4
-rw-r--r--gcc/config/riscv/riscv-protos.h1
-rw-r--r--gcc/config/riscv/riscv.cc11
-rw-r--r--gcc/config/riscv/riscv.md10
4 files changed, 26 insertions, 0 deletions
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 28843b190fa..c07ee2747b7 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -61,6 +61,10 @@
(and (match_code "const_int,const_wide_int,const_double,const_vector")
(match_test "op == CONST0_RTX (GET_MODE (op))")))
+(define_predicate "const_double_m0_operand"
+ (and (match_code "const_double")
+ (match_test "riscv_const_double_m0_rtx(op)")))
+
(define_predicate "reg_or_0_operand"
(ior (match_operand 0 "const_0_operand")
(match_operand 0 "register_operand")))
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 42f33cb6497..0eac7de3835 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -58,6 +58,7 @@ extern const char *riscv_output_move (rtx, rtx);
extern const char *riscv_output_return ();
extern bool riscv_const_double_p0_or_m0_rtx (rtx x);
extern bool riscv_const_double_m0_rtx (rtx x);
+extern void riscv_move_const_double_m0(rtx dest, rtx src);
#ifdef RTX_CODE
extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index ffddab6e52c..ee3ba410326 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -1889,6 +1889,17 @@ riscv_legitimize_const_move (machine_mode mode, rtx dest, rtx src)
riscv_emit_move (dest, src);
}
+void
+riscv_move_const_double_m0(rtx mem, rtx src)
+{
+ machine_mode src_mode = DImode; // GET_MODE (src);
+ unsigned HOST_WIDE_INT top_bit_set = (unsigned HOST_WIDE_INT)1 << 63;
+ rtx reg = gen_reg_rtx(src_mode);
+
+ riscv_move_integer(reg, reg, top_bit_set, src_mode);
+ riscv_emit_set (mem, simplify_gen_subreg (GET_MODE (mem), reg, src_mode, 0));
+}
+
/* Report when we try to do something that requires vector when vector is
disabled. This is an error of last resort and isn't very high-quality. It
usually involves attempts to measure the vector length in some way. */
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index d2d63e048d6..0a5187774b2 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2140,6 +2140,16 @@
DONE;
})
+(define_split
+ [(set (match_operand:DF 0 "nonimmediate_operand")
+ (match_operand:DF 1 "const_double_m0_operand"))]
+ "TARGET_DOUBLE_FLOAT && !reload_completed"
+ [(const_int 0)]
+{
+ riscv_move_const_double_m0(operands[0], operands[1]);
+ DONE;
+})
+
(define_expand "cpymemsi"
[(parallel [(set (match_operand:BLK 0 "general_operand")
(match_operand:BLK 1 "general_operand"))