From a46cf1d2f3b22b1d54f71ddb3a99aa16f9e75a94 Mon Sep 17 00:00:00 2001
From: Dominic Symes <dominic.symes@arm.com>
Date: Tue, 7 Nov 2023 11:46:16 +0000
Subject: Main Conformance: Update RSQRT precision

Change RSQRT precision to 2 ulp to allow
unfused square root and reciprocal.

Also fixes:
- a typo in EXP and POW conformance
- exp2() handling of large negative values
- symmetry about 0 of test set S=4 data generation
- err_bnd cannot be negative
- ulp not taken for reference value of 0

Change-Id: Idaeeb7b615f1634e8e09dea5f82827039780b462
Signed-off-by: Dominic Symes <dominic.symes@arm.com>
---
 chapters/pseudocode.adoc | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

(limited to 'chapters/pseudocode.adoc')

diff --git a/chapters/pseudocode.adoc b/chapters/pseudocode.adoc
index 0a8f598..0de7f39 100644
--- a/chapters/pseudocode.adoc
+++ b/chapters/pseudocode.adoc
@@ -422,7 +422,10 @@ The functions below return the ranges according to type.
 [source,c++]
 ----
 fp64_t exp2(int n) {
-    REQUIRE(-1022 <= n && n <= 1023);
+    if (n < -1075) {
+        return 0.0; // smaller than smallest denormal
+    }
+    REQUIRE(n <= 1023);
     fp64_t v = 1.0;
     while (n > 0) { v = v*2.0; n--; }
     while (n < 0) { v = v/2.0; n++; }
@@ -472,7 +475,7 @@ For the second function, the permitted error range is specified as an absolute e
 ----
 bool tosa_reference_check_fp<in_t>(in_t test_value, fp64_t ref_value, fp64_t num_ulp) {
   fp64_t err_bnd = 0.0;
-  if (is_normal_fp64(ref_value)) {
+  if (is_normal_fp64(ref_value) && abs(ref_value) != 0) {
     int ref_exp = ilog2(abs(ref_value));
     fp64_t ref_pow2 = max(exp2(ref_exp), normal_min<in_t>);
     fp64_t val_ulp  = ref_pow2 * exp2(-normal_frac<in_t>);
@@ -485,6 +488,7 @@ bool tosa_reference_check_fp_bnd<in_t>(in_t test_value, fp64_t ref_value, fp64_t
   if (is_a_NaN(ref_value)) {
     return is_a_NaN(test_value);
   }
+  REQUIRE(err_bnd >= 0.0);
   if (ref_value < 0) {
     ref_value  = -ref_value;
     test_value = -test_value;
-- 
cgit v1.2.1

