mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
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:
60
gcc/testsuite/gcc.target/avr/pr122222-sitod.c
Normal file
60
gcc/testsuite/gcc.target/avr/pr122222-sitod.c
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user