Add round-to-nearest float-to-int conversion tests for the non-:chop variants,
sfmpy:lib with Inf-Inf to verify exception suppression, and sfinvsqrta
with a denormal input.

Signed-off-by: Brian Cain <[email protected]>
---
 tests/tcg/hexagon/fpstuff.c | 99 +++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/tests/tcg/hexagon/fpstuff.c b/tests/tcg/hexagon/fpstuff.c
index 0f28a218d84..9ea79c617d9 100644
--- a/tests/tcg/hexagon/fpstuff.c
+++ b/tests/tcg/hexagon/fpstuff.c
@@ -1017,6 +1017,102 @@ static void check_dfmpyhh(void)
     check64_ne(df_exp(result), 0x7FF0000000000000ULL);
 }
 
+/*
+ * Round-to-nearest float-to-int conversions with normal values.
+ * These test the non-:chop variants which use the USR rounding mode.
+ */
+static void check_conv_rnd(void)
+{
+    uint32_t res32;
+    uint64_t res64;
+
+    /* convert_sf2w(1.5) rounds to nearest-even = 2 */
+    asm(CLEAR_FPSTATUS
+        "%[res] = convert_sf2w(%[val])\n\t"
+        : [res] "=r"(res32)
+        : [val] "r"(0x3fc00000)    /* 1.5f */
+        : "r2", "usr");
+    check32(res32, 2);
+
+    /* convert_sf2d(1.5) = 2 */
+    asm(CLEAR_FPSTATUS
+        "%[res] = convert_sf2d(%[val])\n\t"
+        : [res] "=r"(res64)
+        : [val] "r"(0x3fc00000)    /* 1.5f */
+        : "r2", "usr");
+    check64(res64, 2ULL);
+
+    /* convert_df2w(1.5) = 2 */
+    asm(CLEAR_FPSTATUS
+        "%[res] = convert_df2w(%[val])\n\t"
+        : [res] "=r"(res32)
+        : [val] "r"(0x3FF8000000000000ULL)    /* 1.5 */
+        : "r2", "usr");
+    check32(res32, 2);
+
+    /* convert_df2d(1.5) = 2 */
+    asm(CLEAR_FPSTATUS
+        "%[res] = convert_df2d(%[val])\n\t"
+        : [res] "=r"(res64)
+        : [val] "r"(0x3FF8000000000000ULL)    /* 1.5 */
+        : "r2", "usr");
+    check64(res64, 2ULL);
+}
+
+/*
+ * Test sfmpy:lib with Inf-Inf.
+ *
+ * Rx += sfmpy(Rs, Rt):lib with Rx = -Inf, Rs*Rt -> +Inf
+ * Inf - Inf is invalid, but the :lib variant suppresses the
+ * exception and returns zero.
+ */
+static void check_sffma_lib_inf(void)
+{
+    uint32_t result;
+
+    /* +Inf += sfmpy(+Inf, 1.0):lib -> Inf (no exception, normal) */
+    result = SF_INF;
+    asm(CLEAR_FPSTATUS
+        "%[res] += sfmpy(%[a], %[b]):lib\n\t"
+        : [res] "+r"(result)
+        : [a] "r"(SF_INF), [b] "r"(SF_one)
+        : "r2", "usr");
+    check32(result, SF_INF);
+
+    /*
+     * -Inf += sfmpy(+Inf, 1.0):lib -> Inf - Inf = invalid
+     * The :lib variant should return zero for Inf - Inf.
+     */
+    result = SF_INF | (1u << 31);    /* -Inf */
+    asm(CLEAR_FPSTATUS
+        "%[res] += sfmpy(%[a], %[b]):lib\n\t"
+        : [res] "+r"(result)
+        : [a] "r"(SF_INF), [b] "r"(SF_one)
+        : "r2", "usr");
+    check32(result, 0);
+}
+
+/*
+ * Test sfinvsqrta with a denormal input.
+ */
+static void check_invsqrta_denorm(void)
+{
+    uint32_t result;
+    uint32_t predval;
+    uint32_t exp_bits;
+
+    /* Denormal positive float: 0x00400000 (small denorm) */
+    asm volatile("%[res],p0 = sfinvsqrta(%[val])\n\t"
+                 "%[pred] = p0\n\t"
+                 : [res] "=r"(result), [pred] "=r"(predval)
+                 : [val] "r"(SF_denorm)
+                 : "p0");
+    /* Result should be a valid float (not NaN/zero) */
+    check32_ne(result, 0);
+    exp_bits = (result >> 23) & 0xff;
+    check32_ne(exp_bits, 0xff);  /* not Inf/NaN */
+}
+
 int main()
 {
     check_compare_exception();
@@ -1038,6 +1134,9 @@ int main()
     check_conv_ud2df();
     check_dfmpyfix();
     check_dfmpyhh();
+    check_conv_rnd();
+    check_sffma_lib_inf();
+    check_invsqrta_denorm();
 
     puts(err ? "FAIL" : "PASS");
     return err ? 1 : 0;
-- 
2.34.1

Reply via email to