mirror of git://gcc.gnu.org/git/gcc.git
AVR: target/122210 - Add fixed-point -> double conversions.
PR target/122210
libgcc/config/avr/libf7/
* libf7-common.mk (F7_ASM_PARTS): Add <fx>2D modules.
* libf7-asm.sx: Implement the <fx>2D modules.
gcc/testsuite/
* gcc.target/avr/fxtod.c: New test.
(cherry picked from commit 7304e83f1f
)
This commit is contained in:
parent
3b70c3d654
commit
5ce2681ca0
|
@ -0,0 +1,115 @@
|
|||
/* { dg-do run { target { ! avr_tiny } } } */
|
||||
/* { dg-additional-options { -std=gnu99 -Os -mcall-prologues -fwrapv -Wno-overflow } } */
|
||||
|
||||
#include <stdfix.h>
|
||||
|
||||
#if __SIZEOF_LONG_DOUBLE__ == 8
|
||||
|
||||
#define NI __attribute__((noipa))
|
||||
|
||||
typedef long double D;
|
||||
|
||||
extern D ldexpl (D, int);
|
||||
|
||||
typedef short fract hr_t;
|
||||
typedef unsigned short fract uhr_t;
|
||||
typedef fract r_t;
|
||||
typedef unsigned fract ur_t;
|
||||
|
||||
typedef short accum hk_t;
|
||||
typedef unsigned short accum uhk_t;
|
||||
typedef accum k_t;
|
||||
typedef unsigned accum uk_t;
|
||||
|
||||
#define FBITuhr 8
|
||||
#define FBIThr 7
|
||||
#define FBITur 16
|
||||
#define FBITr 15
|
||||
|
||||
#define FBITuhk 8
|
||||
#define FBIThk 7
|
||||
#define FBITuk 16
|
||||
#define FBITk 15
|
||||
|
||||
#define VALff(S) ((2ul << (8 * sizeof (S##bits(0)) - 1)) - 1)
|
||||
#define VAL80(S) (1ul << (8 * sizeof (S##bits(0)) - 1))
|
||||
#define VAL00(S) 0
|
||||
#define VAL01(S) 1
|
||||
|
||||
|
||||
#define TEST_U(S, V) \
|
||||
NI void test_##S##_##V (void) \
|
||||
{ \
|
||||
S##_t x = S##bits (VAL##V (S)); \
|
||||
__asm ("" : "+r" (x)); \
|
||||
D d = (D) x; \
|
||||
D z = ldexpl (VAL##V (S), - FBIT##S); \
|
||||
if (d != z) \
|
||||
__builtin_exit (1); \
|
||||
}
|
||||
|
||||
#define TEST_S(S, V) \
|
||||
NI void test_##S##_##V (void) \
|
||||
{ \
|
||||
uint32_t u32 = (VAL##V (S) & VAL80 (S)) \
|
||||
? 1u + (VAL##V (S) ^ VALff (S)) \
|
||||
: VAL##V (S); \
|
||||
S##_t x = S##bits (VAL##V (S)); \
|
||||
__asm ("" : "+r" (x)); \
|
||||
D d = (D) x; \
|
||||
D z = ldexpl (u32, - FBIT##S); \
|
||||
int s = (VAL##V (S) & VAL80 (S)) != 0; \
|
||||
if (s == 0 && d != z) \
|
||||
__builtin_exit (2); \
|
||||
if (s == 1 && d != -z) \
|
||||
__builtin_exit (3); \
|
||||
}
|
||||
|
||||
#define TESTS_U(S) \
|
||||
TEST_U (S, 00) \
|
||||
TEST_U (S, 01) \
|
||||
TEST_U (S, ff) \
|
||||
TEST_U (S, 80)
|
||||
|
||||
#define TESTS_S(S) \
|
||||
TEST_S (S, 00) \
|
||||
TEST_S (S, 01) \
|
||||
TEST_S (S, ff) \
|
||||
TEST_S (S, 80)
|
||||
|
||||
TESTS_U (uhr)
|
||||
TESTS_U (ur)
|
||||
TESTS_U (uhk)
|
||||
TESTS_U (uk)
|
||||
|
||||
TESTS_S (hr)
|
||||
TESTS_S (r)
|
||||
TESTS_S (hk)
|
||||
TESTS_S (k)
|
||||
|
||||
#define RUN(S) \
|
||||
test_##S##_00 (); \
|
||||
test_##S##_01 (); \
|
||||
test_##S##_ff (); \
|
||||
test_##S##_80 ()
|
||||
|
||||
int main (void)
|
||||
{
|
||||
RUN (uhr);
|
||||
RUN (ur);
|
||||
RUN (uhk);
|
||||
RUN (uk);
|
||||
|
||||
RUN (hr);
|
||||
RUN (r);
|
||||
RUN (hk);
|
||||
RUN (k);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -2209,4 +2209,116 @@ _DEFUN __powidf2
|
|||
_ENDF __powidf2
|
||||
#endif /* F7MOD_D_powi_ */
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Fixed-point -> double conversions.
|
||||
|
||||
;;; 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))
|
||||
|
||||
#ifdef F7MOD_usa2D_
|
||||
_DEFUN __fractusadf
|
||||
;; Convert USI to DF.
|
||||
XCALL __floatunsidf
|
||||
;; The MSB indicates a value of 0.
|
||||
cpse r25, __zero_reg__
|
||||
;; Divide non-zero values by 2^16 in order to adjust for FBIT = 16.
|
||||
subi r25, dex_hi (16)
|
||||
ret
|
||||
_ENDF __fractusadf
|
||||
#endif /* F7MOD_usa2D_ */
|
||||
|
||||
#ifdef F7MOD_sa2D_
|
||||
_DEFUN __fractsadf
|
||||
;; Convert SI to DF.
|
||||
XCALL __floatsidf
|
||||
;; The MSB indicates a value of 0.
|
||||
tst r25
|
||||
breq 0f
|
||||
;; Divide non-zero values by 2^15 in order to adjust for FBIT = 15.
|
||||
subi r24, dex_lo (15)
|
||||
sbci r25, dex_hi (15)
|
||||
0: ret
|
||||
_ENDF __fractsadf
|
||||
#endif /* F7MOD_sa2D_ */
|
||||
|
||||
#ifdef F7MOD_uha2D_
|
||||
_DEFUN __fractuhadf
|
||||
;; Extend UHA to USA.
|
||||
clr r22
|
||||
mov r23, r24
|
||||
mov r24, r25
|
||||
clr r25
|
||||
XJMP __fractusadf
|
||||
_ENDF __fractuhadf
|
||||
#endif /* F7MOD_uha2D_ */
|
||||
|
||||
#ifdef F7MOD_ha2D_
|
||||
_DEFUN __fracthadf
|
||||
;; Extend HA to SA.
|
||||
clr r22
|
||||
mov r23, r24
|
||||
mov r24, r25
|
||||
lsl r25
|
||||
sbc r25, r25
|
||||
XJMP __fractsadf
|
||||
_ENDF __fracthadf
|
||||
#endif /* F7MOD_ha2D_ */
|
||||
|
||||
|
||||
#ifdef F7MOD_usq2D_
|
||||
_DEFUN __fractusqdf
|
||||
;; Convert USI to DF.
|
||||
XCALL __floatunsidf
|
||||
;; The MSB indicates a value of 0.
|
||||
cpse r25, __zero_reg__
|
||||
;; Divide non-zero values by 2^32 in order to adjust for FBIT = 32.
|
||||
subi r25, dex_hi (32)
|
||||
ret
|
||||
_ENDF __fractusqdf
|
||||
#endif /* F7MOD_usq2D_ */
|
||||
|
||||
#ifdef F7MOD_sq2D_
|
||||
_DEFUN __fractsqdf
|
||||
;; Convert SI to DF.
|
||||
XCALL __floatsidf
|
||||
;; The MSB indicates a value of 0.
|
||||
tst r25
|
||||
breq 0f
|
||||
;; Divide non-zero values by 2^31 in order to adjust for FBIT = 31.
|
||||
subi r24, dex_lo (31)
|
||||
sbci r25, dex_hi (31)
|
||||
0: ret
|
||||
_ENDF __fractsqdf
|
||||
#endif /* F7MOD_sq2D_ */
|
||||
|
||||
#ifdef F7MOD_uqq2D_
|
||||
_DEFUN __fractuqqdf
|
||||
;; Extend UQQ to UHQ.
|
||||
mov r25, r24
|
||||
clr r24
|
||||
_LABEL __fractuhqdf
|
||||
;; Extend UHQ to USQ.
|
||||
clr r23
|
||||
clr r22
|
||||
XJMP __fractusqdf
|
||||
_ENDF __fractuqqdf
|
||||
#endif /* F7MOD_uqq2D_ */
|
||||
|
||||
#ifdef F7MOD_qq2D_
|
||||
_DEFUN __fractqqdf
|
||||
;; Extend QQ to HQ.
|
||||
mov r25, r24
|
||||
clr r24
|
||||
_LABEL __fracthqdf
|
||||
;; Extend HQ to SQ.
|
||||
clr r23
|
||||
clr r22
|
||||
XJMP __fractsqdf
|
||||
_ENDF __fractqqdf
|
||||
#endif /* F7MOD_qq2D_ */
|
||||
|
||||
|
||||
#endif /* !AVR_TINY */
|
||||
|
|
|
@ -28,6 +28,10 @@ F7_ASM_PARTS += D_cmp D_eq D_ne D_ge D_gt D_le D_lt D_unord D_fminfmax
|
|||
|
||||
F7_ASM_PARTS += call_dd call_ddd
|
||||
|
||||
# Fixed-point -> double conversions
|
||||
F7_ASM_PARTS += qq2D uqq2D sq2D usq2D
|
||||
F7_ASM_PARTS += ha2D uha2D sa2D usa2D
|
||||
|
||||
# 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
|
||||
|
|
Loading…
Reference in New Issue