On 7/2/24 12:33 AM, pan2...@intel.com wrote:
The below tests suites are passed for this patch
1. The rv64gcv fully regression test.
2. The rv64gcv build with glibc
gcc/ChangeLog:
* config/riscv/iterators.md (TARGET_64BIT): Add new iterator
and related attr(s).
Rather than reference TARGET_64BIT, you should reference the new
iterators names.
* config/riscv/riscv-protos.h (riscv_expand_ustrunc): Add new
func decl for expanding ustrunc
* config/riscv/riscv.cc (riscv_expand_ustrunc): Add new func
impl to expand ustrunc.
* config/riscv/riscv.md (ustrunc<mode><anyi_narrowed>2): Add
new pattern ustrunc<m><n>2.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/sat_arith.h: Add test helper macro.
* gcc.target/riscv/sat_arith_data.h: New test.
* gcc.target/riscv/sat_u_trunc-1.c: New test.
* gcc.target/riscv/sat_u_trunc-2.c: New test.
* gcc.target/riscv/sat_u_trunc-3.c: New test.
* gcc.target/riscv/sat_u_trunc-run-1.c: New test.
* gcc.target/riscv/sat_u_trunc-run-2.c: New test.
* gcc.target/riscv/sat_u_trunc-run-3.c: New test.
* gcc.target/riscv/scalar_sat_unary.h: New test.
Signed-off-by: Pan Li <pan2...@intel.com>
---
+/* Implement the unsigned saturation truncation for int mode.
+
+ b = SAT_TRUNC (a);
+ =>
+ 1. max = half truncated max
+ 2. lt = a < max
+ 3. lt = lt - 1 (lt 0, ge -1)
+ 4. d = a | lt
+ 5. b = (trunc)d */
+
+void
+riscv_expand_ustrunc (rtx dest, rtx src)
+{
+ machine_mode omode = GET_MODE (dest);
+ rtx pmode_max = gen_reg_rtx (Pmode);
+ unsigned precision = GET_MODE_PRECISION (omode).to_constant ();
+
+ gcc_assert (precision < 64);
+
+ uint64_t max = ((uint64_t)1u << precision) - 1u;
+ rtx pmode_src = gen_lowpart (Pmode, src);
+ rtx pmode_dest = gen_reg_rtx (Pmode);
+ rtx pmode_lt = gen_reg_rtx (Pmode);
+
+ /* Step-1: max = half truncated max */
+ emit_move_insn (pmode_max, GEN_INT (max));
+
+ /* Step-2: lt = src < max */
+ riscv_emit_binary (LTU, pmode_lt, pmode_src, pmode_max);
+
+ /* Step-3: lt = lt - 1 */
+ riscv_emit_binary (PLUS, pmode_lt, pmode_lt, CONSTM1_RTX (Pmode));
+
+ /* Step-4: pmode_dest = lt | src */
+ riscv_emit_binary (IOR, pmode_dest, pmode_lt, pmode_src);
+
+ /* Step-5: dest = pmode_dest */
+ emit_move_insn (dest, gen_lowpart (omode, pmode_dest));
+}
You probably want gen_int_mode rather than GEN_INT.
Why are you using Pmode? Pmode is for pointers. This stuff looks like
basic integer ops, so I don't see why Pmode is appropriate.
jeff