1111
1212#include "fp_test.h"
1313
14- // Returns: a + b
14+ // By default this test uses compareResultF to check the returned floats, which
15+ // accepts any returned NaN if the expected result is the canonical NaN value
16+ // 0x7fc00000. For the Thumb1 optimized FP implementation, which commits to a
17+ // more detailed handling of NaNs, we tighten up the check and include some
18+ // extra test cases specific to that NaN policy.
19+ #if __thumb__ && !__thumb2__
20+ # define EXPECT_EXACT_RESULTS
21+ # define ARM_NAN_HANDLING
22+ #endif
23+
24+ // Returns: a - b
1525COMPILER_RT_ABI float __subsf3 (float a , float b );
1626
1727int test__subsf3 (uint32_t a_rep , uint32_t b_rep , uint32_t expected_rep ) {
1828 float a = fromRep32 (a_rep ), b = fromRep32 (b_rep );
1929 float x = __subsf3 (a , b );
30+ #ifdef EXPECT_EXACT_RESULTS
31+ int ret = toRep32 (x ) == expected_rep ;
32+ #else
2033 int ret = compareResultF (x , expected_rep );
34+ #endif
2135
2236 if (ret ) {
2337 printf ("error in test__subsf3(%08" PRIx32 ", %08" PRIx32 ") = %08" PRIx32
@@ -273,10 +287,23 @@ int main() {
273287 status |= test__subsf3 (0x007ffff7 , 0x00f7ffff , 0x80780008 );
274288 status |= test__subsf3 (0x80ffffbf , 0x80800000 , 0x807fffbf );
275289
276- #if __thumb__ && !__thumb2__
277- // These tests depend on Arm-specific IEEE 754 implementation choices
278- // regarding NaNs, which are satisfied by arm/addsf3.S but not guaranteed by
279- // other implementations:
290+ // Test that the result of an operation is a NaN at all when it should be.
291+ //
292+ // In most configurations these tests' results are checked compared using
293+ // compareResultF, so we set all the answers to the canonical NaN 0x7fc00000,
294+ // which causes compareResultF to accept any NaN encoding. We also use the
295+ // same value as the input NaN in tests that have one, so that even in
296+ // EXPECT_EXACT_RESULTS mode these tests should pass, because 0x7fc00000 is
297+ // still the exact expected NaN.
298+ status |= test__subsf3 (0x7f800000 , 0x7f800000 , 0x7fc00000 );
299+ status |= test__subsf3 (0xff800000 , 0xff800000 , 0x7fc00000 );
300+ status |= test__subsf3 (0x3f800000 , 0x7fc00000 , 0x7fc00000 );
301+ status |= test__subsf3 (0x7fc00000 , 0x3f800000 , 0x7fc00000 );
302+ status |= test__subsf3 (0x7fc00000 , 0x7fc00000 , 0x7fc00000 );
303+
304+ #ifdef ARM_NAN_HANDLING
305+ // Tests specific to the NaN handling of Arm hardware, mimicked by the
306+ // subtraction function in arm/addsf3.S:
280307 //
281308 // - a quiet NaN is distinguished by the top mantissa bit being 1
282309 //
@@ -290,10 +317,8 @@ int main() {
290317 // - if both operands are quiet NaNs then the output NaN is the first
291318 // operand
292319 //
293- // - subtraction is treated as a first-class operation, not just "flip the
294- // sign of operand 2 and add". So if the output is a NaN derived from
295- // second operand (with or without quietening), the sign bit is the same
296- // as that of the original operand.
320+ // - invalid operations not involving an input NaN return the quiet
321+ // NaN with fewest bits set, 0x7fc00000.
297322
298323 status |= test__subsf3 (0x00000000 , 0x7fad4be3 , 0x7fed4be3 );
299324 status |= test__subsf3 (0x00000000 , 0x7fdf48c7 , 0x7fdf48c7 );
@@ -349,7 +374,7 @@ int main() {
349374 status |= test__subsf3 (0xff800000 , 0x7f857fdc , 0x7fc57fdc );
350375 status |= test__subsf3 (0xff800000 , 0x7fde0397 , 0x7fde0397 );
351376 status |= test__subsf3 (0xff800000 , 0xff800000 , 0x7fc00000 );
352- #endif // __arm__
377+ #endif // ARM_NAN_HANDLING
353378
354379 return status ;
355380}
0 commit comments