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


Reply via email to