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
|
_ENDF __powidf2
|
||||||
#endif /* F7MOD_D_powi_ */
|
#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 */
|
#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
|
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)
|
# Stuff that will be wrapped in f7-wraps.h (included by libf7-asm.sx)
|
||||||
# and give f7_asm_D_*.o modules.
|
# and give f7_asm_D_*.o modules.
|
||||||
g_ddd += add sub mul div
|
g_ddd += add sub mul div
|
||||||
|
|
Loading…
Reference in New Issue