diff options
author | Pan Li <pan2.li@intel.com> | 2024-08-29 11:25:44 +0800 |
---|---|---|
committer | Pan Li <pan2.li@intel.com> | 2024-09-03 09:51:33 +0800 |
commit | 539fcaae67c88886cf54bd377eba6c9d5b1792a3 (patch) | |
tree | 6b574d3319e20e0f9e1c3aaae372f256e1efe912 | |
parent | 519ec1cfe9d2c6a1d06709c52cb103508d2c42a7 (diff) | |
download | gcc-539fcaae67c88886cf54bd377eba6c9d5b1792a3.zip gcc-539fcaae67c88886cf54bd377eba6c9d5b1792a3.tar.gz gcc-539fcaae67c88886cf54bd377eba6c9d5b1792a3.tar.bz2 |
RISC-V: Support form 1 of integer scalar .SAT_ADD
This patch would like to support the scalar signed ssadd pattern
for the RISC-V backend. Aka
Form 1:
#define DEF_SAT_S_ADD_FMT_1(T, UT, MIN, MAX) \
T __attribute__((noinline)) \
sat_s_add_##T##_fmt_1 (T x, T y) \
{ \
T sum = (UT)x + (UT)y; \
return (x ^ y) < 0 \
? sum \
: (sum ^ x) >= 0 \
? sum \
: x < 0 ? MIN : MAX; \
}
DEF_SAT_S_ADD_FMT_1(int64_t, uint64_t, INT64_MIN, INT64_MAX)
Before this patch:
10 │ sat_s_add_int64_t_fmt_1:
11 │ mv a5,a0
12 │ add a0,a0,a1
13 │ xor a1,a5,a1
14 │ not a1,a1
15 │ xor a4,a5,a0
16 │ and a1,a1,a4
17 │ blt a1,zero,.L5
18 │ ret
19 │ .L5:
20 │ srai a5,a5,63
21 │ li a0,-1
22 │ srli a0,a0,1
23 │ xor a0,a5,a0
24 │ ret
After this patch:
10 │ sat_s_add_int64_t_fmt_1:
11 │ add a2,a0,a1
12 │ xor a1,a0,a1
13 │ xor a5,a0,a2
14 │ srli a5,a5,63
15 │ srli a1,a1,63
16 │ xori a1,a1,1
17 │ and a5,a5,a1
18 │ srai a4,a0,63
19 │ li a3,-1
20 │ srli a3,a3,1
21 │ xor a3,a3,a4
22 │ neg a4,a5
23 │ and a3,a3,a4
24 │ addi a5,a5,-1
25 │ and a0,a2,a5
26 │ or a0,a0,a3
27 │ ret
The below test suites are passed for this patch:
1. The rv64gcv fully regression test.
gcc/ChangeLog:
* config/riscv/riscv-protos.h (riscv_expand_ssadd): Add new func
decl for expanding ssadd.
* config/riscv/riscv.cc (riscv_gen_sign_max_cst): Add new func
impl to gen the max int rtx.
(riscv_expand_ssadd): Add new func impl to expand the ssadd.
* config/riscv/riscv.md (ssadd<mode>3): Add new pattern for
signed integer .SAT_ADD.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/sat_arith.h: Add test helper macros.
* gcc.target/riscv/sat_arith_data.h: Add test data.
* gcc.target/riscv/sat_s_add-1.c: New test.
* gcc.target/riscv/sat_s_add-2.c: New test.
* gcc.target/riscv/sat_s_add-3.c: New test.
* gcc.target/riscv/sat_s_add-4.c: New test.
* gcc.target/riscv/sat_s_add-run-1.c: New test.
* gcc.target/riscv/sat_s_add-run-2.c: New test.
* gcc.target/riscv/sat_s_add-run-3.c: New test.
* gcc.target/riscv/sat_s_add-run-4.c: New test.
* gcc.target/riscv/scalar_sat_binary_run_xxx.h: New test.
Signed-off-by: Pan Li <pan2.li@intel.com>
-rw-r--r-- | gcc/config/riscv/riscv-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/riscv/riscv.cc | 90 | ||||
-rw-r--r-- | gcc/config/riscv/riscv.md | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/sat_arith.h | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/sat_arith_data.h | 85 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/sat_s_add-1.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/sat_s_add-2.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/sat_s_add-3.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/sat_s_add-4.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/sat_s_add-run-1.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/sat_s_add-run-2.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/sat_s_add-run-3.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/sat_s_add-run-4.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/scalar_sat_binary_run_xxx.h | 26 |
14 files changed, 417 insertions, 0 deletions
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 926899c..3358e38 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_ssadd (rtx, rtx, rtx); extern void riscv_expand_ussub (rtx, rtx, rtx); extern void riscv_expand_ustrunc (rtx, rtx); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index d03e51f..9872061 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -12001,6 +12001,96 @@ riscv_expand_usadd (rtx dest, rtx x, rtx y) emit_move_insn (dest, gen_lowpart (mode, xmode_dest)); } +/* Return a new const RTX of MAX value based on given mode. Only + int scalar mode is allowed. */ + +static rtx +riscv_gen_sign_max_cst (machine_mode mode) +{ + switch (mode) + { + case QImode: + return GEN_INT (INT8_MAX); + case HImode: + return GEN_INT (INT16_MAX); + case SImode: + return GEN_INT (INT32_MAX); + case DImode: + return GEN_INT (INT64_MAX); + default: + gcc_unreachable (); + } +} + +/* Implements the signed saturation sub standard name ssadd for int mode. + + z = SAT_ADD(x, y). + => + 1. sum = x + y + 2. xor_0 = x ^ y + 3. xor_1 = x ^ sum + 4. lt = xor_1 < 0 + 5. ge = xor_0 >= 0 + 6. and = ge & lt + 7. lt = x < 0 + 8. neg = -lt + 9. max = INT_MAX + 10. max = max ^ neg + 11. neg = -and + 12. max = max & neg + 13. and = and - 1 + 14. z = sum & and + 15. z = z | max */ + +void +riscv_expand_ssadd (rtx dest, rtx x, rtx y) +{ + machine_mode mode = GET_MODE (dest); + unsigned bitsize = GET_MODE_BITSIZE (mode).to_constant (); + rtx shift_bits = GEN_INT (bitsize - 1); + rtx xmode_x = gen_lowpart (Xmode, x); + rtx xmode_y = gen_lowpart (Xmode, y); + rtx xmode_sum = gen_reg_rtx (Xmode); + rtx xmode_dest = gen_reg_rtx (Xmode); + rtx xmode_xor_0 = gen_reg_rtx (Xmode); + rtx xmode_xor_1 = gen_reg_rtx (Xmode); + rtx xmode_ge = gen_reg_rtx (Xmode); + rtx xmode_lt = gen_reg_rtx (Xmode); + rtx xmode_neg = gen_reg_rtx (Xmode); + rtx xmode_and = gen_reg_rtx (Xmode); + rtx xmode_max = gen_reg_rtx (Xmode); + + /* Step-1: sum = x + y, xor_0 = x ^ y, xor_1 = x ^ sum. */ + riscv_emit_binary (PLUS, xmode_sum, xmode_x, xmode_y); + riscv_emit_binary (XOR, xmode_xor_0, xmode_x, xmode_y); + riscv_emit_binary (XOR, xmode_xor_1, xmode_x, xmode_sum); + + /* Step-2: lt = xor_1 < 0, ge = xor_0 >= 0, and = ge & lt. */ + riscv_emit_binary (LSHIFTRT, xmode_lt, xmode_xor_1, shift_bits); + riscv_emit_binary (LSHIFTRT, xmode_ge, xmode_xor_0, shift_bits); + riscv_emit_binary (XOR, xmode_ge, xmode_ge, CONST1_RTX (Xmode)); + riscv_emit_binary (AND, xmode_and, xmode_lt, xmode_ge); + riscv_emit_binary (AND, xmode_and, xmode_and, CONST1_RTX (Xmode)); + + /* Step-3: lt = x < 0, neg = -lt */ + riscv_emit_binary (LT, xmode_lt, xmode_x, CONST0_RTX (Xmode)); + riscv_emit_unary (NEG, xmode_neg, xmode_lt); + + /* Step-4: max = 0x7f..., max = max ^ neg, neg = -and, max = max & neg */ + riscv_emit_move (xmode_max, riscv_gen_sign_max_cst (mode)); + riscv_emit_binary (XOR, xmode_max, xmode_max, xmode_neg); + riscv_emit_unary (NEG, xmode_neg, xmode_and); + riscv_emit_binary (AND, xmode_max, xmode_max, xmode_neg); + + /* Step-5: and = and - 1, dest = sum & and */ + riscv_emit_binary (PLUS, xmode_and, xmode_and, CONSTM1_RTX (Xmode)); + riscv_emit_binary (AND, xmode_dest, xmode_sum, xmode_and); + + /* Step-6: xmode_dest = xmode_dest | xmode_max, dest = xmode_dest */ + riscv_emit_binary (IOR, xmode_dest, xmode_dest, xmode_max); + 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). diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 3289ed2..789faf6 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -4367,6 +4367,17 @@ } ) +(define_expand "ssadd<mode>3" + [(match_operand:ANYI 0 "register_operand") + (match_operand:ANYI 1 "register_operand") + (match_operand:ANYI 2 "register_operand")] + "" + { + riscv_expand_ssadd (operands[0], operands[1], operands[2]); + DONE; + } +) + (define_expand "ussub<mode>3" [(match_operand:ANYI 0 "register_operand") (match_operand:ANYI 1 "reg_or_int_operand") diff --git a/gcc/testsuite/gcc.target/riscv/sat_arith.h b/gcc/testsuite/gcc.target/riscv/sat_arith.h index a899979..86cd6be 100644 --- a/gcc/testsuite/gcc.target/riscv/sat_arith.h +++ b/gcc/testsuite/gcc.target/riscv/sat_arith.h @@ -118,6 +118,23 @@ sat_u_add_imm_type_check##_##T##_fmt_2 (T x) \ #define RUN_SAT_U_ADD_IMM_FMT_4(T, x, IMM, expect) \ if (sat_u_add_imm##IMM##_##T##_fmt_4(x) != expect) __builtin_abort () +#define DEF_SAT_S_ADD_FMT_1(T, UT, MIN, MAX) \ +T __attribute__((noinline)) \ +sat_s_add_##T##_fmt_1 (T x, T y) \ +{ \ + T sum = (UT)x + (UT)y; \ + return (x ^ y) < 0 \ + ? sum \ + : (sum ^ x) >= 0 \ + ? sum \ + : x < 0 ? MIN : MAX; \ +} +#define DEF_SAT_S_ADD_FMT_1_WRAP(T, UT, MIN, MAX) \ + DEF_SAT_S_ADD_FMT_1(T, UT, MIN, MAX) + +#define RUN_SAT_S_ADD_FMT_1(T, x, y) sat_s_add_##T##_fmt_1(x, y) +#define RUN_SAT_S_ADD_FMT_1_WRAP(T, x, y) RUN_SAT_S_ADD_FMT_1(T, x, y) + /******************************************************************************/ /* Saturation Sub (Unsigned and Signed) */ /******************************************************************************/ diff --git a/gcc/testsuite/gcc.target/riscv/sat_arith_data.h b/gcc/testsuite/gcc.target/riscv/sat_arith_data.h index 52e4e2b..75037c5 100644 --- a/gcc/testsuite/gcc.target/riscv/sat_arith_data.h +++ b/gcc/testsuite/gcc.target/riscv/sat_arith_data.h @@ -10,9 +10,21 @@ T2 from; \ }; +#define TEST_BINARY_STRUCT_NAME(T, NAME) test_##T##_##NAME##_s +#define TEST_BINARY_STRUCT_DECL(T, NAME) struct TEST_BINARY_STRUCT_NAME(T, NAME) +#define TEST_BINARY_STRUCT(T, NAME) \ + struct TEST_BINARY_STRUCT_NAME(T, NAME) \ + { \ + T a, b; \ + T expect; \ + }; + #define TEST_UNARY_DATA(T1, T2) t_##T1##_##T2##_s #define TEST_UNARY_DATA_WRAP(T1, T2) TEST_UNARY_DATA(T1, T2) +#define TEST_BINARY_DATA(T, NAME) t_##T##_##NAME##_s +#define TEST_BINARY_DATA_WRAP(T, NAME) TEST_BINARY_DATA(T, NAME) + TEST_UNARY_STRUCT (uint8_t, uint16_t) TEST_UNARY_STRUCT (uint8_t, uint32_t) TEST_UNARY_STRUCT (uint8_t, uint64_t) @@ -20,6 +32,11 @@ TEST_UNARY_STRUCT (uint16_t, uint32_t) TEST_UNARY_STRUCT (uint16_t, uint64_t) TEST_UNARY_STRUCT (uint32_t, uint64_t) +TEST_BINARY_STRUCT (int8_t, ssadd) +TEST_BINARY_STRUCT (int16_t, ssadd) +TEST_BINARY_STRUCT (int32_t, ssadd) +TEST_BINARY_STRUCT (int64_t, ssadd) + TEST_UNARY_STRUCT_DECL(uint8_t, uint16_t) \ TEST_UNARY_DATA(uint8_t, uint16_t)[] = { @@ -104,4 +121,72 @@ TEST_UNARY_STRUCT_DECL(uint32_t, uint64_t) \ {4294967295, 18446744073709551615u}, }; +TEST_BINARY_STRUCT_DECL(int8_t, ssadd) TEST_BINARY_DATA(int8_t, ssadd)[] = +{ + { 0, 0, 0}, + { 2, 2, 4}, + { 126, 1, 127}, + { 127, 1, 127}, + { 127, 127, 127}, + { -7, -4, -11}, + {-128, -1, -128}, + {-127, -1, -128}, + {-128, -128, -128}, + {-128, 127, -1}, + {-127, 127, 0}, + {-122, 105, -17}, + {-122, 125, 3}, +}; + +TEST_BINARY_STRUCT_DECL(int16_t, ssadd) TEST_BINARY_DATA(int16_t, ssadd)[] = +{ + { 0, 0, 0}, + { 2, 2, 4}, + { 32766, 1, 32767}, + { 32767, 1, 32767}, + { 32767, 32767, 32767}, + { -7, -4, -11}, + {-32768, -1, -32768}, + {-32767, -1, -32768}, + {-32768, -32768, -32768}, + {-32768, 32767, -1}, + {-32767, 32767, 0}, + {-32732, 32712, -20}, + {-32732, 32734, 2}, +}; + +TEST_BINARY_STRUCT_DECL(int32_t, ssadd) TEST_BINARY_DATA(int32_t, ssadd)[] = +{ + { 0, 0, 0}, + { 2, 2, 4}, + { 2147483646, 1, 2147483647}, + { 2147483647, 1, 2147483647}, + { 2147483647, 2147483647, 2147483647}, + { -7, -4, -11}, + {-2147483648, -1, -2147483648}, + {-2147483647, -1, -2147483648}, + {-2147483648, -2147483648, -2147483648}, + {-2147483648, 2147483647, -1}, + {-2147483647, 2147483647, 0}, + {-2147483613, 2147483601, -12}, + {-2147483613, 2147483637, 24}, +}; + +TEST_BINARY_STRUCT_DECL(int64_t, ssadd) TEST_BINARY_DATA(int64_t, ssadd)[] = +{ + { 0, 0, 0}, + { 2, 2, 4}, + { 9223372036854775806ll, 1, 9223372036854775807ll}, + { 9223372036854775807ll, 1, 9223372036854775807ll}, + { 9223372036854775807ll, 9223372036854775807ll, 9223372036854775807ll}, + { -7, -4, -11}, + {-9223372036854775808ull, -1, -9223372036854775808ull}, + { -9223372036854775807ll, -1, -9223372036854775808ull}, + {-9223372036854775808ull, -9223372036854775808ull, -9223372036854775808ull}, + {-9223372036854775808ull, 9223372036854775807ll, -1}, + { -9223372036854775807ll, 9223372036854775807ll, 0}, + { -9223372036854775803ll, 9223372036854775800ll, -3}, + { -9223372036854775803ll, 9223372036854775805ll, 2}, +}; + #endif diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-1.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-1.c new file mode 100644 index 0000000..f85675c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-1.c @@ -0,0 +1,30 @@ +/* { 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_s_add_int8_t_fmt_1: +** add\s+[atx][0-9]+,\s*a0,\s*a1 +** xor\s+[atx][0-9]+,\s*a0,\s*a1 +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 +** neg\s+[atx][0-9]+,\s*[atx][0-9]+ +** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ +** slliw\s+a0,\s*a0,\s*24 +** sraiw\s+a0,\s*a0,\s*24 +** ret +*/ +DEF_SAT_S_ADD_FMT_1(int8_t, uint8_t, INT8_MIN, INT8_MAX) + +/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-2.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-2.c new file mode 100644 index 0000000..6a2f8d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-2.c @@ -0,0 +1,32 @@ +/* { 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_s_add_int16_t_fmt_1: +** add\s+[atx][0-9]+,\s*a0,\s*a1 +** xor\s+[atx][0-9]+,\s*a0,\s*a1 +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*15 +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 +** li\s+[atx][0-9]+,\s*32768 +** addi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 +** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** neg\s+[atx][0-9]+,\s*[atx][0-9]+ +** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ +** slliw\s+a0,\s*a0,\s*16 +** sraiw\s+a0,\s*a0,\s*16 +** ret +*/ +DEF_SAT_S_ADD_FMT_1(int16_t, uint16_t, INT16_MIN, INT16_MAX) + +/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-3.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-3.c new file mode 100644 index 0000000..adfed83 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-3.c @@ -0,0 +1,31 @@ +/* { 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_s_add_int32_t_fmt_1: +** add\s+[atx][0-9]+,\s*a0,\s*a1 +** xor\s+[atx][0-9]+,\s*a0,\s*a1 +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*31 +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 +** li\s+[atx][0-9]+,\s*-2147483648 +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*-1 +** xor\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** neg\s+[atx][0-9]+,\s*[atx][0-9]+ +** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ +** sext\.w\s+a0,\s*a0 +** ret +*/ +DEF_SAT_S_ADD_FMT_1(int32_t, uint32_t, INT32_MIN, INT32_MAX) + +/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-4.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-4.c new file mode 100644 index 0000000..f85675c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-4.c @@ -0,0 +1,30 @@ +/* { 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_s_add_int8_t_fmt_1: +** add\s+[atx][0-9]+,\s*a0,\s*a1 +** xor\s+[atx][0-9]+,\s*a0,\s*a1 +** xor\s+[atx][0-9]+,\s*a0,\s*[atx][0-9]+ +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 +** srli\s+[atx][0-9]+,\s*[atx][0-9]+,\s*7 +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 +** and\s+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** andi\s+[atx][0-9]+,\s*[atx][0-9]+,\s*1 +** srai\s+[atx][0-9]+,\s*[atx][0-9]+,\s*63 +** xori\s+[atx][0-9]+,\s*[atx][0-9]+,\s*127 +** neg\s+[atx][0-9]+,\s*[atx][0-9]+ +** and\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+[atx][0-9]+,\s*[atx][0-9]+,\s*[atx][0-9]+ +** or\s+a0,\s*[atx][0-9]+,\s*[atx][0-9]+ +** slliw\s+a0,\s*a0,\s*24 +** sraiw\s+a0,\s*a0,\s*24 +** ret +*/ +DEF_SAT_S_ADD_FMT_1(int8_t, uint8_t, INT8_MIN, INT8_MAX) + +/* { dg-final { scan-rtl-dump-times ".SAT_ADD " 2 "expand" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-1.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-1.c new file mode 100644 index 0000000..9a4ce33 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-1.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 int8_t +#define T2 uint8_t + +DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT8_MIN, INT8_MAX) + +#define DATA TEST_BINARY_DATA_WRAP(T1, ssadd) +#define T TEST_BINARY_STRUCT_DECL(T1, ssadd) +#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-2.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-2.c new file mode 100644 index 0000000..34459b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-2.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 int16_t +#define T2 uint16_t + +DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT16_MIN, INT16_MAX) + +#define DATA TEST_BINARY_DATA_WRAP(T1, ssadd) +#define T TEST_BINARY_STRUCT_DECL(T1, ssadd) +#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-3.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-3.c new file mode 100644 index 0000000..4d4841f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-3.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 int32_t +#define T2 uint32_t + +DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT32_MIN, INT32_MAX) + +#define DATA TEST_BINARY_DATA_WRAP(T1, ssadd) +#define T TEST_BINARY_STRUCT_DECL(T1, ssadd) +#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat_s_add-run-4.c b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-4.c new file mode 100644 index 0000000..df81887 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat_s_add-run-4.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99" } */ + +#include "sat_arith.h" +#include "sat_arith_data.h" + +#define T1 int64_t +#define T2 uint64_t + +DEF_SAT_S_ADD_FMT_1_WRAP(T1, T2, INT64_MIN, INT64_MAX) + +#define DATA TEST_BINARY_DATA_WRAP(T1, ssadd) +#define T TEST_BINARY_STRUCT_DECL(T1, ssadd) +#define RUN_BINARY(x, y) RUN_SAT_S_ADD_FMT_1_WRAP(T1, x, y) + +#include "scalar_sat_binary_run_xxx.h" diff --git a/gcc/testsuite/gcc.target/riscv/scalar_sat_binary_run_xxx.h b/gcc/testsuite/gcc.target/riscv/scalar_sat_binary_run_xxx.h new file mode 100644 index 0000000..7578453 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/scalar_sat_binary_run_xxx.h @@ -0,0 +1,26 @@ +#ifndef HAVE_DEFINED_SCALAR_SAT_BINARY_RUN_XXX +#define HAVE_DEFINED_SCALAR_SAT_BINARY_RUN_XXX + +#include <stdio.h> + +int +main () +{ + unsigned i; + T d; + + for (i = 0; i < sizeof (DATA) / sizeof (DATA[0]); i++) + { + d = DATA[i]; + + if (RUN_BINARY (d.a, d.b) != d.expect) + { + printf ("%d + %d = %d, but %d\n", d.a, d.b, d.expect, RUN_BINARY (d.a, d.b)); + __builtin_abort (); + } + } + + return 0; +} + +#endif |