RISC-V: Implement scalar SAT_TRUNC for signed integer
This patch would like to implement the sstrunc for scalar signed
integer.
Form 1:
#define DEF_SAT_S_TRUNC_FMT_1(WT, NT, NT_MIN, NT_MAX) \
NT __attribute__((noinline)) \
sat_s_trunc_##WT##_to_##NT##_fmt_1 (WT x) \
{ \
NT trunc = (NT)x; \
return (WT)NT_MIN <= x && x <= (WT)NT_MAX \
? trunc \
: x < 0 ? NT_MIN : NT_MAX; \
}
DEF_SAT_S_TRUNC_FMT_1(int64_t, int32_t, INT32_MIN, INT32_MAX)
Before this patch:
10 │ sat_s_trunc_int64_t_to_int32_t_fmt_1:
11 │ li a5,1
12 │ slli a5,a5,31
13 │ li a4,-1
14 │ add a5,a0,a5
15 │ srli a4,a4,32
16 │ bgtu a5,a4,.L2
17 │ sext.w a0,a0
18 │ ret
19 │ .L2:
20 │ srai a5,a0,63
21 │ li a0,-
2147483648
22 │ xor a0,a0,a5
23 │ not a0,a0
24 │ ret
After this patch:
10 │ sat_s_trunc_int64_t_to_int32_t_fmt_1:
11 │ li a5,-
2147483648
12 │ xori a3,a5,-1
13 │ slt a4,a0,a3
14 │ slt a5,a5,a0
15 │ and a5,a4,a5
16 │ srai a4,a0,63
17 │ xor a4,a4,a3
18 │ addi a3,a5,-1
19 │ neg a5,a5
20 │ and a4,a4,a3
21 │ and a0,a0,a5
22 │ or a0,a0,a4
23 │ sext.w a0,a0
24 │ ret
The below test suites are passed for this patch.
* The rv64gcv fully regression test.
gcc/ChangeLog:
* config/riscv/riscv-protos.h (riscv_expand_sstrunc): Add new
func decl to expand SAT_TRUNC.
* config/riscv/riscv.cc (riscv_expand_sstrunc): Add new func
impl to expand SAT_TRUNC.
* config/riscv/riscv.md (sstrunc<mode><anyi_double_truncated>2):
Add new pattern for double truncation.
(sstrunc<mode><anyi_quad_truncated>2): Ditto but for quad.
(sstrunc<mode><anyi_oct_truncated>2): Ditto but for oct.
Signed-off-by: Pan Li <pan2.li@intel.com>