diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2024-06-01 12:46:31 +0200 |
---|---|---|
committer | Georg-Johann Lay <avr@gjlay.de> | 2024-06-01 12:49:45 +0200 |
commit | f12454278dc725fec3520a5d870e967d79292ee6 (patch) | |
tree | 793ea5530fc91766d772afb3d6c420454577594a | |
parent | b460ede64f9471589822831e04eecff4a3dbecf2 (diff) | |
download | gcc-f12454278dc725fec3520a5d870e967d79292ee6.zip gcc-f12454278dc725fec3520a5d870e967d79292ee6.tar.gz gcc-f12454278dc725fec3520a5d870e967d79292ee6.tar.bz2 |
AVR: target/115317 - Make isinf(-Inf) return -1.
PR target/115317
libgcc/config/avr/libf7/
* libf7-asm.sx (__isinf): Map -Inf to -1.
gcc/testsuite/
* gcc.target/avr/torture/pr115317-isinf.c: New test.
-rw-r--r-- | gcc/testsuite/gcc.target/avr/torture/pr115317-isinf.c | 55 | ||||
-rw-r--r-- | libgcc/config/avr/libf7/libf7-asm.sx | 19 |
2 files changed, 67 insertions, 7 deletions
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr115317-isinf.c b/gcc/testsuite/gcc.target/avr/torture/pr115317-isinf.c new file mode 100644 index 0000000..10f7b55 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr115317-isinf.c @@ -0,0 +1,55 @@ +/* { dg-do run { target { ! avr_tiny } } } */ + +extern int isinff (float); +extern int isinf (double); +extern int isinfl (long double); + +int tst_isinf (float x, int val) +{ + double y; + long double z; + + __asm ("" : "+r"(x)); + if (isinff (x) != val) + __builtin_exit (__LINE__); + + y = x; + __asm ("" : "+r"(y)); + if (isinf (y) != val) + __builtin_exit (__LINE__); + + z = x; + __asm ("" : "+r"(z)); + if (isinfl (z) != val) + __builtin_exit (__LINE__); +} + +static float make_f (__UINT32_TYPE__ i) +{ + float f; + __builtin_memcpy (&f, &i, 4); + return f; +} + +int main (void) +{ + tst_isinf (__builtin_huge_valf(), 1); + tst_isinf (-__builtin_huge_valf(), -1); + tst_isinf (__builtin_nanf(""), 0); + tst_isinf (0.0f, 0); + tst_isinf (-0.0f, 0); + tst_isinf (1.0f, 0); + tst_isinf (-1.0f, 0); + tst_isinf (make_f (0x7f800000), 1); + tst_isinf (make_f (0xff800000), -1); + tst_isinf (make_f (0x7f7fffff), 0); + tst_isinf (make_f (0xff7fffff), 0); + tst_isinf (make_f (0x7f800001), 0); + tst_isinf (make_f (0xff800001), 0); + tst_isinf (make_f (0x00800000), 0); + tst_isinf (make_f (0x80800000), 0); + tst_isinf (make_f (0x00400000), 0); + tst_isinf (make_f (0x80400000), 0); + + return 0; +} diff --git a/libgcc/config/avr/libf7/libf7-asm.sx b/libgcc/config/avr/libf7/libf7-asm.sx index 1f8f60a..bef62f3 100644 --- a/libgcc/config/avr/libf7/libf7-asm.sx +++ b/libgcc/config/avr/libf7/libf7-asm.sx @@ -1639,19 +1639,24 @@ _ENDF __copysign #ifdef F7MOD_D_isinf_ +;;; +Inf -> +1 +;;; -Inf -> -1 _DEFUN __isinf DALIAS isinf LALIAS isinfl + ;; Save sign for later + push R25 F7call class_D + pop TMP + ldi R24, 0 + ldi R25, 0 ;; Inf: T = Z = 1. - brtc 0f + brtc 0f ; ordinary number + brne 0f ; Nan ldi R24, 1 - breq 1f -0: - clr R24 -1: - clr R25 - ret + sbrc TMP, 7 + sbiw R24, 2 +0: ret _ENDF __isinf #endif /* F7MOD_D_isinf_ */ |