[gcc r15-1112] RISC-V: Implement .SAT_SUB for unsigned scalar int
Pan Li
panli@gcc.gnu.org
Sat Jun 8 08:36:55 GMT 2024
https://gcc.gnu.org/g:ab50ac8180beae9001c97cc036ce0df055e25b41
commit r15-1112-gab50ac8180beae9001c97cc036ce0df055e25b41
Author: Pan Li <pan2.li@intel.com>
Date: Wed Jun 5 16:42:05 2024 +0800
RISC-V: Implement .SAT_SUB for unsigned scalar int
As the middle support of .SAT_SUB committed, implement the unsigned
scalar int of .SAT_SUB for the riscv backend. Consider below example
code:
T __attribute__((noinline)) \
sat_u_sub_##T##_fmt_1 (T x, T y) \
{ \
return (x - y) & (-(T)(x >= y)); \
}
T __attribute__((noinline)) \
sat_u_sub_##T##_fmt_2 (T x, T y) \
{ \
return (x - y) & (-(T)(x > y)); \
}
DEF_SAT_U_SUB_FMT_1(uint64_t);
DEF_SAT_U_SUB_FMT_2(uint64_t);
Before this patch:
sat_u_sub_uint64_t_fmt_1:
bltu a0,a1,.L2
sub a0,a0,a1
ret
.L2:
li a0,0
ret
After this patch:
sat_u_sub_uint64_t_fmt_1:
sltu a5,a0,a1
addi a5,a5,-1
sub a0,a0,a1
and a0,a5,a0
ret
ToDo:
Only above 2 forms of .SAT_SUB are support for now, we will
support more forms of .SAT_SUB in the middle-end in short future.
The below test suites are passed for this patch.
* The rv64gcv fully regression test.
gcc/ChangeLog:
* config/riscv/riscv-protos.h (riscv_expand_ussub): Add new func
decl for ussub expanding.
* config/riscv/riscv.cc (riscv_expand_ussub): Ditto but for impl.
* config/riscv/riscv.md (ussub<mode>3): Add new pattern ussub
for scalar modes.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/sat_arith.h: Add test macros and comments.
* gcc.target/riscv/sat_u_sub-1.c: New test.
* gcc.target/riscv/sat_u_sub-2.c: New test.
* gcc.target/riscv/sat_u_sub-3.c: New test.
* gcc.target/riscv/sat_u_sub-4.c: New test.
* gcc.target/riscv/sat_u_sub-5.c: New test.
* gcc.target/riscv/sat_u_sub-6.c: New test.
* gcc.target/riscv/sat_u_sub-7.c: New test.
* gcc.target/riscv/sat_u_sub-8.c: New test.
* gcc.target/riscv/sat_u_sub-run-1.c: New test.
* gcc.target/riscv/sat_u_sub-run-2.c: New test.
* gcc.target/riscv/sat_u_sub-run-3.c: New test.
* gcc.target/riscv/sat_u_sub-run-4.c: New test.
* gcc.target/riscv/sat_u_sub-run-5.c: New test.
* gcc.target/riscv/sat_u_sub-run-6.c: New test.
* gcc.target/riscv/sat_u_sub-run-7.c: New test.
* gcc.target/riscv/sat_u_sub-run-8.c: New test.
Signed-off-by: Pan Li <pan2.li@intel.com>
Diff:
---
gcc/config/riscv/riscv-protos.h | 1 +
gcc/config/riscv/riscv.cc | 35 ++++++++++++++++++++++++
gcc/config/riscv/riscv.md | 11 ++++++++
gcc/testsuite/gcc.target/riscv/sat_arith.h | 23 ++++++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-1.c | 18 ++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-2.c | 19 +++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-3.c | 18 ++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-4.c | 17 ++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-5.c | 18 ++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-6.c | 19 +++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-7.c | 18 ++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-8.c | 17 ++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-run-1.c | 25 +++++++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-run-2.c | 25 +++++++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-run-3.c | 25 +++++++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-run-4.c | 25 +++++++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-run-5.c | 25 +++++++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-run-6.c | 25 +++++++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-run-7.c | 25 +++++++++++++++++
gcc/testsuite/gcc.target/riscv/sat_u_sub-run-8.c | 25 +++++++++++++++++
20 files changed, 414 insertions(+)
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 0704968561b..09eb3a574e3 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -134,6 +134,7 @@ extern bool
riscv_zcmp_valid_stack_adj_bytes_p (HOST_WIDE_INT, int);
extern void riscv_legitimize_poly_move (machine_mode, rtx, rtx, rtx);
extern void riscv_expand_usadd (rtx, rtx, rtx);
+extern void riscv_expand_ussub (rtx, rtx, rtx);
#ifdef RTX_CODE
extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx, bool *invert_ptr = 0);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 9704ff9c6a0..95f3636f8e4 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -11612,6 +11612,41 @@ riscv_expand_usadd (rtx dest, rtx x, rtx y)
emit_move_insn (dest, gen_lowpart (mode, xmode_dest));
}
+/* Implements the unsigned saturation sub standard name usadd for int mode.
+
+ z = SAT_SUB(x, y).
+ =>
+ 1. minus = x - y.
+ 2. lt = x < y.
+ 3. lt = lt - 1.
+ 4. z = minus & lt. */
+
+void
+riscv_expand_ussub (rtx dest, rtx x, rtx y)
+{
+ machine_mode mode = GET_MODE (dest);
+ rtx pmode_x = gen_lowpart (Pmode, x);
+ rtx pmode_y = gen_lowpart (Pmode, y);
+ rtx pmode_lt = gen_reg_rtx (Pmode);
+ rtx pmode_minus = gen_reg_rtx (Pmode);
+ rtx pmode_dest = gen_reg_rtx (Pmode);
+
+ /* Step-1: minus = x - y */
+ riscv_emit_binary (MINUS, pmode_minus, pmode_x, pmode_y);
+
+ /* Step-2: lt = x < y */
+ riscv_emit_binary (LTU, pmode_lt, pmode_x, pmode_y);
+
+ /* Step-3: lt = lt - 1 (lt + (-1)) */
+ riscv_emit_binary (PLUS, pmode_lt, pmode_lt, CONSTM1_RTX (Pmode));
+
+ /* Step-4: pmode_dest = minus & lt */
+ riscv_emit_binary (AND, pmode_dest, pmode_lt, pmode_minus);
+
+ /* Step-5: dest = pmode_dest */
+ emit_move_insn (dest, gen_lowpart (mode, pmode_dest));
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index e57bfcf616a..7a9454de430 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -4228,6 +4228,17 @@
}
)
+(define_expand "ussub<mode>3"
+ [(match_operand:ANYI 0 "register_operand")
+ (match_operand:ANYI 1 "register_operand")
+ (match_operand:ANYI 2 "register_operand")]
+ ""
+ {
+ riscv_expand_ussub (operands[0], operands[1], operands[2]);
+ DONE;
+ }
+)
+
;; These are forms of (x << C1) + C2, potentially canonicalized from
;; ((x + C2') << C1. Depending on the cost to load C2 vs C2' we may
;; want to go ahead and recognize this form as C2 may be cheaper to
diff --git a/gcc/testsuite/gcc.target/riscv/sat_arith.h b/gcc/testsuite/gcc.target/riscv/sat_arith.h
index 976ef1c44c1..9c60ac09f41 100644
--- a/gcc/testsuite/gcc.target/riscv/sat_arith.h
+++ b/gcc/testsuite/gcc.target/riscv/sat_arith.h
@@ -3,6 +3,9 @@
#include <stdint-gcc.h>
+/******************************************************************************/
+/* Saturation Add (unsigned and signed) */
+/******************************************************************************/
#define DEF_SAT_U_ADD_FMT_1(T) \
T __attribute__((noinline)) \
sat_u_add_##T##_fmt_1 (T x, T y) \
@@ -72,4 +75,24 @@ vec_sat_u_add_##T##_fmt_1 (T *out, T *op_1, T *op_2, unsigned limit) \
#define RUN_VEC_SAT_U_ADD_FMT_1(T, out, op_1, op_2, N) \
vec_sat_u_add_##T##_fmt_1(out, op_1, op_2, N)
+/******************************************************************************/
+/* Saturation Sub (Unsigned and Signed) */
+/******************************************************************************/
+#define DEF_SAT_U_SUB_FMT_1(T) \
+T __attribute__((noinline)) \
+sat_u_sub_##T##_fmt_1 (T x, T y) \
+{ \
+ return (x - y) & (-(T)(x >= y)); \
+}
+
+#define DEF_SAT_U_SUB_FMT_2(T) \
+T __attribute__((noinline)) \
+sat_u_sub_##T##_fmt_2 (T x, T y) \
+{ \
+ return (x - y) & (-(T)(x > y)); \
+}
+
+#define RUN_SAT_U_SUB_FMT_1(T, x, y) sat_u_sub_##T##_fmt_1(x, y)
+#define RUN_SAT_U_SUB_FMT_2(T, x, y) sat_u_sub_##T##_fmt_2(x, y)
+
#endif
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-1.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-1.c
new file mode 100644
index 00000000000..73be7d59422
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint8_t_fmt_1:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*a0,\s*[atx][0-9]+
+** andi\s+a0,\s*a0,\s*0xff
+** ret
+*/
+DEF_SAT_U_SUB_FMT_1(uint8_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-2.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-2.c
new file mode 100644
index 00000000000..7bd5efcd9d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint16_t_fmt_1:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*a0,\s*a1
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** slli\s+a0,\s*a0,\s*48
+** srli\s+a0,\s*a0,\s*48
+** ret
+*/
+DEF_SAT_U_SUB_FMT_1(uint16_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-3.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-3.c
new file mode 100644
index 00000000000..a60fc9ba71e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-3.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint32_t_fmt_1:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*a0,\s*a1
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** sext.w\s+a0,\s*a0
+** ret
+*/
+DEF_SAT_U_SUB_FMT_1(uint32_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-4.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-4.c
new file mode 100644
index 00000000000..bae46a0bd83
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-4.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint64_t_fmt_1:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*a0,\s*a1
+** addi\s+a0,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** ret
+*/
+DEF_SAT_U_SUB_FMT_1(uint64_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-5.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-5.c
new file mode 100644
index 00000000000..e917487a640
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-5.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint8_t_fmt_2:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*a0,\s*[atx][0-9]+
+** andi\s+a0,\s*a0,\s*0xff
+** ret
+*/
+DEF_SAT_U_SUB_FMT_2(uint8_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-6.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-6.c
new file mode 100644
index 00000000000..4e3c91d205d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-6.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint16_t_fmt_2:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*a0,\s*a1
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** slli\s+a0,\s*a0,\s*48
+** srli\s+a0,\s*a0,\s*48
+** ret
+*/
+DEF_SAT_U_SUB_FMT_2(uint16_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-7.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-7.c
new file mode 100644
index 00000000000..e1b0eaccf95
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-7.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint32_t_fmt_2:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*a0,\s*a1
+** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** sext.w\s+a0,\s*a0
+** ret
+*/
+DEF_SAT_U_SUB_FMT_2(uint32_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-8.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-8.c
new file mode 100644
index 00000000000..d73f00fcf02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-8.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O3 -fdump-rtl-expand-details -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "sat_arith.h"
+
+/*
+** sat_u_sub_uint64_t_fmt_2:
+** sub\s+[atx][0-9]+,\s*a0,\s*a1
+** sltu\s+[atx][0-9]+,\s*a0,\s*a1
+** addi\s+a0,\s*[atx][0-9]+,\s*-1
+** and\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+
+** ret
+*/
+DEF_SAT_U_SUB_FMT_2(uint64_t)
+
+/* { dg-final { scan-rtl-dump-times ".SAT_SUB " 2 "expand" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-1.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-1.c
new file mode 100644
index 00000000000..931420a3098
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-1.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T uint8_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_1
+
+DEF_SAT_U_SUB_FMT_1(T)
+
+T test_data[][3] = {
+ /* arg_0, arg_1, expect */
+ { 0, 0, 0, },
+ { 0, 1, 0, },
+ { 1, 1, 0, },
+ { 255, 254, 1, },
+ { 255, 255, 0, },
+ { 254, 255, 0, },
+ { 253, 254, 0, },
+ { 0, 255, 0, },
+ { 1, 255, 0, },
+ { 32, 5, 27, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-2.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-2.c
new file mode 100644
index 00000000000..1534cf99827
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-2.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T uint16_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_1
+
+DEF_SAT_U_SUB_FMT_1(T)
+
+T test_data[][3] = {
+ /* arg_0, arg_1, expect */
+ { 0, 0, 0, },
+ { 0, 1, 0, },
+ { 1, 1, 0, },
+ { 65535, 65534, 1, },
+ { 65535, 65535, 0, },
+ { 65534, 65535, 0, },
+ { 65533, 65534, 0, },
+ { 0, 65535, 0, },
+ { 1, 65535, 0, },
+ { 35, 5, 30, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-3.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-3.c
new file mode 100644
index 00000000000..5c60d28997f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-3.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T uint32_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_1
+
+DEF_SAT_U_SUB_FMT_1(T)
+
+T test_data[][3] = {
+ /* arg_0, arg_1, expect */
+ { 0, 0, 0, },
+ { 0, 1, 0, },
+ { 1, 1, 0, },
+ { 4294967295, 4294967294, 1, },
+ { 4294967295, 4294967295, 0, },
+ { 4294967294, 4294967295, 0, },
+ { 4294967293, 4294967294, 0, },
+ { 1, 4294967295, 0, },
+ { 2, 4294967295, 0, },
+ { 5, 1, 4, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-4.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-4.c
new file mode 100644
index 00000000000..403764c8568
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-4.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T uint64_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_1
+
+DEF_SAT_U_SUB_FMT_1(T)
+
+T test_data[][3] = {
+ /* arg_0, arg_1, expect */
+ { 0, 0, 0, },
+ { 0, 1, 0, },
+ { 1, 1, 0, },
+ { 18446744073709551615u, 18446744073709551614u, 1, },
+ { 18446744073709551615u, 18446744073709551615u, 0, },
+ { 18446744073709551614u, 18446744073709551615u, 0, },
+ { 18446744073709551613u, 18446744073709551614u, 0, },
+ { 0, 18446744073709551615u, 0, },
+ { 1, 18446744073709551615u, 0, },
+ { 43, 11, 32, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-5.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-5.c
new file mode 100644
index 00000000000..6fa44ca323b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-5.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T uint8_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_2
+
+DEF_SAT_U_SUB_FMT_2(T)
+
+T test_data[][3] = {
+ /* arg_0, arg_1, expect */
+ { 0, 0, 0, },
+ { 0, 1, 0, },
+ { 1, 1, 0, },
+ { 255, 254, 1, },
+ { 255, 255, 0, },
+ { 254, 255, 0, },
+ { 253, 254, 0, },
+ { 0, 255, 0, },
+ { 1, 255, 0, },
+ { 32, 5, 27, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-6.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-6.c
new file mode 100644
index 00000000000..7deaae9a5fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-6.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T uint16_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_2
+
+DEF_SAT_U_SUB_FMT_2(T)
+
+T test_data[][3] = {
+ /* arg_0, arg_1, expect */
+ { 0, 0, 0, },
+ { 0, 1, 0, },
+ { 1, 1, 0, },
+ { 65535, 65534, 1, },
+ { 65535, 65535, 0, },
+ { 65534, 65535, 0, },
+ { 65533, 65534, 0, },
+ { 0, 65535, 0, },
+ { 1, 65535, 0, },
+ { 35, 5, 30, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-7.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-7.c
new file mode 100644
index 00000000000..d9b1d5cbfe2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-7.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T uint32_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_2
+
+DEF_SAT_U_SUB_FMT_2(T)
+
+T test_data[][3] = {
+ /* arg_0, arg_1, expect */
+ { 0, 0, 0, },
+ { 0, 1, 0, },
+ { 1, 1, 0, },
+ { 4294967295, 4294967294, 1, },
+ { 4294967295, 4294967295, 0, },
+ { 4294967294, 4294967295, 0, },
+ { 4294967293, 4294967294, 0, },
+ { 1, 4294967295, 0, },
+ { 2, 4294967295, 0, },
+ { 5, 1, 4, },
+};
+
+#include "scalar_sat_binary.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-8.c b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-8.c
new file mode 100644
index 00000000000..2774c235cc3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat_u_sub-run-8.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+
+#define T uint64_t
+#define RUN_SAT_BINARY RUN_SAT_U_SUB_FMT_2
+
+DEF_SAT_U_SUB_FMT_2(T)
+
+T test_data[][3] = {
+ /* arg_0, arg_1, expect */
+ { 0, 0, 0, },
+ { 0, 1, 0, },
+ { 1, 1, 0, },
+ { 18446744073709551615u, 18446744073709551614u, 1, },
+ { 18446744073709551615u, 18446744073709551615u, 0, },
+ { 18446744073709551614u, 18446744073709551615u, 0, },
+ { 18446744073709551613u, 18446744073709551614u, 0, },
+ { 0, 18446744073709551615u, 0, },
+ { 1, 18446744073709551615u, 0, },
+ { 43, 11, 32, },
+};
+
+#include "scalar_sat_binary.h"
More information about the Gcc-cvs
mailing list