AVR: target/122222 - Add modules for __floatsidf, __floatunsidf.

PR target/122222
libgcc/config/avr/libf7/
	* libf7-asm.sx (D_floatsidf, D_floatunsidf): New modules.
	* libf7-common.mk (F7_ASM_PARTS): Add D_floatsidf, D_floatunsidf.
	(F7F, g_dx): Remove floatunsidf, floatsidf.
	* libf7.c (f7_set_s32): Don't alias to f7_floatsidf.
	(f7_set_u32): Don't alias to f7_floatunsidf.
	* f7-renames.h: Rebuild
	* f7-wraps.h: Rebuild.

gcc/testsuite/
	* gcc.target/avr/pr122222-sitod.c: New test.
This commit is contained in:
Georg-Johann Lay
2025-10-09 18:35:34 +02:00
parent 3ea09e4d43
commit 078208cf15
6 changed files with 148 additions and 29 deletions

View File

@@ -0,0 +1,60 @@
/* { dg-do run { target { ! avr_tiny } } } */
/* { dg-additional-options { -std=gnu99 -Os -mcall-prologues } } */
#if __SIZEOF_LONG_DOUBLE__ == 8
typedef long double D;
typedef __INT32_TYPE__ int32_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __UINT8_TYPE__ uint8_t;
#define ARRAY_SIZE(X) (sizeof(X) / sizeof(*X))
void testu (void)
{
static const volatile __flash uint32_t vals[] =
{
0, 1ul, -1ul, (-1ul) << 1,
1ul << 31, 1ul << 30, 1ul << 29, 1ul << 28, 1ul << 27, 1ul << 26,
1ul << 25, 1ul << 24, 0xff, 123456789
};
for (uint8_t i = 0; i < ARRAY_SIZE (vals); ++i)
{
D x = (D) vals[i];
__asm ("" : "+r" (x));
if ((uint32_t) x != vals[i])
__builtin_exit (__LINE__);
}
}
void tests (void)
{
static const volatile __flash int32_t vals[] =
{
0, 1L, -1L, 0x7fffffff, -0x7fffffff, -0x7fffffff - 1,
-123456789
};
for (uint8_t i = 0; i < ARRAY_SIZE (vals); ++i)
{
D x = (D) vals[i];
__asm ("" : "+r" (x));
if ((int32_t) x != vals[i])
__builtin_exit (__LINE__);
}
}
int main (void)
{
testu ();
tests ();
return 0;
}
#else
int main (void)
{
return 0;
}
#endif

View File

@@ -159,8 +159,6 @@
#define f7_min __f7_min
#define f7_max __f7_max
#define f7_exp10 __f7_exp10
#define f7_floatunsidf __f7_floatunsidf
#define f7_floatsidf __f7_floatsidf
#define f7_extendsfdf2 __f7_extendsfdf2
#define f7_fixdfsi __f7_fixdfsi
#define f7_fixdfdi __f7_fixdfdi

View File

@@ -135,27 +135,7 @@ _ENDF __truncdfsf2
#endif /* F7MOD_D_truncdfsf2_ */
;; Functions that usually live in libgcc: __<name> for <name> in:
;; floatunsidf floatsidf extendsfdf2
;; double __floatunsidf (type_t) ; floatunsidf
#ifdef F7MOD_D_floatunsidf_
_DEFUN __floatunsidf
.global F7_NAME(floatunsidf)
ldi ZH, hi8(gs(F7_NAME(floatunsidf)))
ldi ZL, lo8(gs(F7_NAME(floatunsidf)))
F7jmp call_dx
_ENDF __floatunsidf
#endif /* F7MOD_D_floatunsidf_ */
;; double __floatsidf (type_t) ; floatsidf
#ifdef F7MOD_D_floatsidf_
_DEFUN __floatsidf
.global F7_NAME(floatsidf)
ldi ZH, hi8(gs(F7_NAME(floatsidf)))
ldi ZL, lo8(gs(F7_NAME(floatsidf)))
F7jmp call_dx
_ENDF __floatsidf
#endif /* F7MOD_D_floatsidf_ */
;; extendsfdf2
;; double __extendsfdf2 (type_t) ; extendsfdf2
#ifdef F7MOD_D_extendsfdf2_

View File

@@ -2201,8 +2201,9 @@ _ENDF __powidf2
;;; The double exponent starts at bit 52 since the encoded mantissa has 52 bits.
;;; Note that when X is a multiple of 16, then dex_lo(x) evaluates to 0.
#define dex_lo(x) hlo8((x) << (52 - 32))
#define dex_hi(x) hhi8((x) << (52 - 32))
#define DEX16(x) (x) << (52 - 48)
#define dex_lo(x) lo8 (DEX16 (x))
#define dex_hi(x) hi8 (DEX16 (x))
#ifdef F7MOD_usa2D_
_DEFUN __fractusadf
@@ -2388,4 +2389,83 @@ _ENDF __fractdfusa
#endif /* F7MOD_D2usa_ */
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; [u]int32_t -> double conversions.
;; double __floatsidf (int32_t);
#ifdef F7MOD_D_floatsidf_
_DEFUN __floatsidf
bst r25, 7
brtc 0f
XCALL __negsi2
0: XJMP __floatunsidf.ge0
_ENDF __floatsidf
#endif /* F7MOD_D_floatsidf_ */
;; double __floatunsidf (uint32_t);
#ifdef F7MOD_D_floatunsidf_
_DEFUN __floatunsidf
clt
_LABEL __floatunsidf.ge0
;; Zero-extend SI at the low end.
clr r18
clr r19
wmov r20, r18
;; Input is zero?
sbiw r24, 0
sbci r23, 0
sbci r22, 0
breq 9f
;; No: The double exponent of 0x80000000 is 31 plus a bias of 1023.
;; Align the SI value such that the MSBit is as R25.4.
;; For each << we have to subtract 1 from the exponent, and for
;; each >> we have to add 1. Since we want the MSB in R25.4 and
;; not in R25.7, the initial exponent must be reduced by 3.
ldi Xl, dex_lo (31 + 1023 - 3)
ldi Xh, dex_hi (31 + 1023 - 3)
;; Move the MSByte to R25.
1: tst r25
brne 2f
subi Xl, dex_lo (8)
sbci Xh, dex_hi (8)
mov r25, r24
mov r24, r23
mov r23, r22
clr r22
rjmp 1b
2: ;; Now we have R25 != 0.
cpi r25, 0x20
brlo 3f
adiw Xl, DEX16 (1)
lsr r25
ror r24
ror r23
ror r22
ror r21
rjmp 2b
3: cpi r25, 0x10
brsh 4f
sbiw Xl, DEX16 (1)
lsl r22
rol r23
rol r24
rol r25
rjmp 3b
4: ;; Move the mantissa into place and clear the redundant leading 1.
cbr r25, 0x10
mov r20, r21
mov r21, r22
mov r22, r23
mov r23, r24
mov r24, r25
;; Insert the biased exponent.
or r24, Xl
mov r25, Xh
;; Insert the sign.
bld r25, 7
9: ret
_ENDF __floatunsidf
#endif /* F7MOD_D_floatunsidf_ */
#endif /* !AVR_TINY */

View File

@@ -36,11 +36,14 @@ F7_ASM_PARTS += ha2D uha2D sa2D usa2D
F7_ASM_PARTS += D2qq D2uqq D2hq D2uhq
F7_ASM_PARTS += D2ha D2uha D2sa D2usa
# Integer -> double conversions
F7_ASM_PARTS += D_floatsidf D_floatunsidf
# Stuff that will be wrapped in f7-wraps.h (included by libf7-asm.sx)
# and give f7_asm_D_*.o modules.
g_ddd += add sub mul div
g_xdd_cmp +=
g_dx += floatunsidf floatsidf extendsfdf2
g_dx += extendsfdf2
g_xd += fixdfsi fixdfdi fixunsdfdi fixunsdfsi truncdfsf2
m_ddd += pow fmod hypot atan2 fdim
@@ -91,7 +94,7 @@ F7F += set_eps set_1pow2
# Renames for ALIASes without own module.
F7F += min max exp10
F7F += floatunsidf floatsidf extendsfdf2
F7F += extendsfdf2
F7F += fixdfsi fixdfdi fixunsdfdi fixunsdfsi truncdfsf2
# Renames for f7-const.def.

View File

@@ -207,7 +207,6 @@ f7_t* f7_set_s32 (f7_t *cc, int32_t i32)
cc->flags = flags;
return cc;
}
ALIAS (f7_set_s32, f7_floatsidf)
#endif // F7MOD_set_s32_
@@ -219,7 +218,6 @@ f7_t* f7_set_u32 (f7_t *cc, uint32_t u32)
cc->expo = 31;
return f7_normalize_asm (cc);
}
ALIAS (f7_set_u32, f7_floatunsidf)
#endif // F7MOD_set_u32_