diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2013-02-08 10:13:37 +0000 |
---|---|---|
committer | Georg-Johann Lay <gjl@gcc.gnu.org> | 2013-02-08 10:13:37 +0000 |
commit | 85d768f349087f3766ff84054ec7b3403c52ac7a (patch) | |
tree | c41ab849c5ffa4c56a753d5d4502a23fdc14617d /libgcc/config/avr/lib2funcs.c | |
parent | 661bc682bcb87f5faa709f9bcd1679874f6652f6 (diff) | |
download | gcc-85d768f349087f3766ff84054ec7b3403c52ac7a.zip gcc-85d768f349087f3766ff84054ec7b3403c52ac7a.tar.gz gcc-85d768f349087f3766ff84054ec7b3403c52ac7a.tar.bz2 |
re PR target/54222 ([avr] Implement fixed-point support)
gcc/
PR target/54222
* config/avr/avr.md (unspec) <UNSPEC_ROUND>: Add.
* config/avr/avr-fixed.md (ALL4QA, ALL124QA): New mode iterators.
(round<mode>3, round<mode>3_const): New expanders for fixed-mode.
(*round<mode>3.libgcc): New insns for fixed-modes.
* config/avr/builtins.def (ABSxx): Use a non-NULL LIBNAME.
(ROUNDxx, COUNTLSxx, BITSxx, xxBITS): New DEF_BUILTINs.
(ROUNDFX, COUNTLSFX, ABSFX): New DEF_BUILTINs.
* config/avr/stdfix.h (absFX, bitsFX, FXbits): Remove inline
implementations. Define to __builtin_avr_absFX,
__builtin_avr_bitsFX, __builtin_avr_FXbits, respectively.
(roundFX, countlsFX): Define to __builtin_avr_roundFX,
__builtin_avr_countlsFX, respectively.
* config/avr/avr-c.c (target.h): Include it.
(enum avr_builtin_id): New enum.
(avr_resolve_overloaded_builtin): New static function.
(avr_register_target_pragmas): Use it to set
targetm.resolve_overloaded_builtin.
* config/avr/avr.c (avr_init_builtins): Supply myriads of local
tree nodes used by DEF_BUILTIN.
(avr_expand_builtin) <AVR_BUILTIN_ROUNDxx>: Sanity-check them.
(avr_fold_builtin) <AVR_BUILTIN_BITSxx>: Fold to VIEW_COVERT_EXPR.
<AVR_BUILTIN_xxBITS>: Same.
libgcc/
PR target/54222
* config/avr/lib2funcs.c: New C sources for modules for libgcc.a.
* config/avr/lib2-object.mk: New iterator to build objects from it.
* config/avr/t-avr: Iterate lib2-object.mk to build objects from
lib2funcs.c.
(LIB2FUNCS_EXCLUDE): Add _clrsbdi2.
(LIB1ASMFUNCS): Add: _ssabs_1, _mask1, _ret, _roundqq3, _rounduqq3,
_round_s2, _round_u2, _round_2_const, _addmask_2, _round_s4,
_round_u4, _round_4_const, _addmask_4, _round_x8, _rounddq3
_roundudq3, _roundda3 _rounduda3, _roundta3 _rounduta3.
* config/avr/lib1funcs-fixed.S: Implement them.
gcc/testsuite/
PR target/54222
* gcc.target/avr/torture/builtins-4-roundfx.c: New test.
* gcc.target/avr/torture/builtins-5-countlsfx.c: New test.
From-SVN: r195878
Diffstat (limited to 'libgcc/config/avr/lib2funcs.c')
-rw-r--r-- | libgcc/config/avr/lib2funcs.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/libgcc/config/avr/lib2funcs.c b/libgcc/config/avr/lib2funcs.c new file mode 100644 index 0000000..83f2e23 --- /dev/null +++ b/libgcc/config/avr/lib2funcs.c @@ -0,0 +1,226 @@ +/* Copyright (C) 2013 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + + +/* This file supplies implementations for some AVR-specific builtin + functions so that code like the following works as expected: + + int (*f (void))(_Fract) + { + return __builtin_avr_countlsr; + } + + In this specific case, the generated code is: + + f: + ldi r24,lo8(gs(__countlsHI)) + ldi r25,hi8(gs(__countlsHI)) + ret +*/ + +/* Map fixed-point suffix to the corresponding fixed-point type. */ + +typedef short _Fract fx_hr_t; +typedef _Fract fx_r_t; +typedef long _Fract fx_lr_t; +typedef long long _Fract fx_llr_t; + +typedef unsigned short _Fract fx_uhr_t; +typedef unsigned _Fract fx_ur_t; +typedef unsigned long _Fract fx_ulr_t; +typedef unsigned long long _Fract fx_ullr_t; + +typedef short _Accum fx_hk_t; +typedef _Accum fx_k_t; +typedef long _Accum fx_lk_t; +typedef long long _Accum fx_llk_t; + +typedef unsigned short _Accum fx_uhk_t; +typedef unsigned _Accum fx_uk_t; +typedef unsigned long _Accum fx_ulk_t; +typedef unsigned long long _Accum fx_ullk_t; + +/* Map fixed-point suffix to the corresponding natural integer type. */ + +typedef char int_hr_t; +typedef int int_r_t; +typedef long int_lr_t; +typedef long long int_llr_t; + +typedef unsigned char int_uhr_t; +typedef unsigned int int_ur_t; +typedef unsigned long int_ulr_t; +typedef unsigned long long int_ullr_t; + +typedef int int_hk_t; +typedef long int_k_t; +typedef long long int_lk_t; +typedef long long int_llk_t; + +typedef unsigned int int_uhk_t; +typedef unsigned long int_uk_t; +typedef unsigned long long int_ulk_t; +typedef unsigned long long int_ullk_t; + +/* Map mode to the corresponding integer type. */ + +typedef char int_qi_t; +typedef int int_hi_t; +typedef long int_si_t; +typedef long long int_di_t; + +typedef unsigned char uint_qi_t; +typedef unsigned int uint_hi_t; +typedef unsigned long uint_si_t; +typedef unsigned long long uint_di_t; + + + +/************************************************************************/ + +/* Supply implementations / symbols for __builtin_roundFX ASM_NAME. */ + +#ifdef L_round + +#define ROUND1(FX) \ + ROUND2 (FX) + +#define ROUND2(FX) \ + extern fx_## FX ##_t __round## FX (fx_## FX ##_t x, int rpoint); \ + \ + fx_## FX ##_t \ + __round## FX (fx_## FX ##_t x, int rpoint) \ + { \ + return __builtin_avr_round ##FX (x, rpoint); \ + } + +ROUND1(L_LABEL) + +#endif /* L_round */ + + + +/*********************************************************************/ + +/* Implement some count-leading-redundant-sign-bits to be used with + coundlsFX implementation. */ + +#ifdef L__clrsbqi +extern int __clrsbqi2 (char x); + +int +__clrsbqi2 (char x) +{ + int ret; + + if (x < 0) + x = ~x; + + if (x == 0) + return 8 * sizeof (x) -1; + + ret = __builtin_clz (x << 8); + return ret - 1; +} +#endif /* L__clrsbqi */ + + +#ifdef L__clrsbdi +extern int __clrsbdi2 (long long x); + +int +__clrsbdi2 (long long x) +{ + int ret; + + if (x < 0LL) + x = ~x; + + if (x == 0LL) + return 8 * sizeof (x) -1; + + ret = __builtin_clzll ((unsigned long long) x); + return ret - 1; +} +#endif /* L__clrsbdi */ + + + +/*********************************************************************/ + +/* Supply implementations / symbols for __builtin_avr_countlsFX. */ + +/* Signed */ + +#ifdef L_countls + +#define COUNTLS1(MM) \ + COUNTLS2 (MM) + +#define COUNTLS2(MM) \ + extern int __countls## MM ##2 (int_## MM ##_t); \ + extern int __clrsb## MM ##2 (int_## MM ##_t); \ + \ + int \ + __countls## MM ##2 (int_## MM ##_t x) \ + { \ + if (x == 0) \ + return __INT8_MAX__; \ + \ + return __clrsb## MM ##2 (x); \ + } + +COUNTLS1(L_LABEL) + +#endif /* L_countls */ + +/* Unsigned */ + +#ifdef L_countlsu + +#define clz_qi2 __builtin_clz /* unused, avoid warning */ +#define clz_hi2 __builtin_clz +#define clz_si2 __builtin_clzl +#define clz_di2 __builtin_clzll + +#define COUNTLS1(MM) \ + COUNTLS2 (MM) + +#define COUNTLS2(MM) \ + extern int __countlsu## MM ##2 (uint_## MM ##_t); \ + \ + int \ + __countlsu## MM ##2 (uint_## MM ##_t x) \ + { \ + if (x == 0) \ + return __INT8_MAX__; \ + \ + if (sizeof (x) == 1) \ + return clz_hi2 (x << 8); \ + else \ + return clz_## MM ##2 (x); \ + } + +COUNTLS1(L_LABEL) + +#endif /* L_countlsu */ |