xref: /netbsd-src/external/gpl3/gcc.old/dist/libgcc/config/avr/lib2funcs.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1*8feb0f0bSmrg /* Copyright (C) 2013-2020 Free Software Foundation, Inc.
236ac495dSmrg 
336ac495dSmrg    This file is part of GCC.
436ac495dSmrg 
536ac495dSmrg    GCC is free software; you can redistribute it and/or modify it under
636ac495dSmrg    the terms of the GNU General Public License as published by the Free
736ac495dSmrg    Software Foundation; either version 3, or (at your option) any later
836ac495dSmrg    version.
936ac495dSmrg 
1036ac495dSmrg    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1136ac495dSmrg    WARRANTY; without even the implied warranty of MERCHANTABILITY or
1236ac495dSmrg    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1336ac495dSmrg    for more details.
1436ac495dSmrg 
1536ac495dSmrg    Under Section 7 of GPL version 3, you are granted additional
1636ac495dSmrg    permissions described in the GCC Runtime Library Exception, version
1736ac495dSmrg    3.1, as published by the Free Software Foundation.
1836ac495dSmrg 
1936ac495dSmrg    You should have received a copy of the GNU General Public License and
2036ac495dSmrg    a copy of the GCC Runtime Library Exception along with this program;
2136ac495dSmrg    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2236ac495dSmrg    <http://www.gnu.org/licenses/>.  */
2336ac495dSmrg 
2436ac495dSmrg 
2536ac495dSmrg /* This file supplies implementations for some AVR-specific builtin
2636ac495dSmrg    functions so that code like the following works as expected:
2736ac495dSmrg 
2836ac495dSmrg    int (*f (void))(_Fract)
2936ac495dSmrg    {
3036ac495dSmrg        return __builtin_avr_countlsr;
3136ac495dSmrg    }
3236ac495dSmrg 
3336ac495dSmrg    In this specific case, the generated code is:
3436ac495dSmrg 
3536ac495dSmrg    f:
3636ac495dSmrg        ldi r24,lo8(gs(__countlsHI))
3736ac495dSmrg        ldi r25,hi8(gs(__countlsHI))
3836ac495dSmrg        ret
3936ac495dSmrg */
4036ac495dSmrg 
4136ac495dSmrg /* Map fixed-point suffix to the corresponding fixed-point type.  */
4236ac495dSmrg 
4336ac495dSmrg typedef short _Fract fx_hr_t;
4436ac495dSmrg typedef _Fract fx_r_t;
4536ac495dSmrg typedef long _Fract fx_lr_t;
4636ac495dSmrg typedef long long _Fract fx_llr_t;
4736ac495dSmrg 
4836ac495dSmrg typedef unsigned short _Fract fx_uhr_t;
4936ac495dSmrg typedef unsigned _Fract fx_ur_t;
5036ac495dSmrg typedef unsigned long _Fract fx_ulr_t;
5136ac495dSmrg typedef unsigned long long _Fract fx_ullr_t;
5236ac495dSmrg 
5336ac495dSmrg typedef short _Accum fx_hk_t;
5436ac495dSmrg typedef _Accum fx_k_t;
5536ac495dSmrg typedef long _Accum fx_lk_t;
5636ac495dSmrg typedef long long _Accum fx_llk_t;
5736ac495dSmrg 
5836ac495dSmrg typedef unsigned short _Accum fx_uhk_t;
5936ac495dSmrg typedef unsigned _Accum fx_uk_t;
6036ac495dSmrg typedef unsigned long _Accum fx_ulk_t;
6136ac495dSmrg typedef unsigned long long _Accum fx_ullk_t;
6236ac495dSmrg 
6336ac495dSmrg /* Map fixed-point suffix to the corresponding natural integer type.  */
6436ac495dSmrg 
6536ac495dSmrg typedef char int_hr_t;
6636ac495dSmrg typedef int int_r_t;
6736ac495dSmrg typedef long int_lr_t;
6836ac495dSmrg typedef long long int_llr_t;
6936ac495dSmrg 
7036ac495dSmrg typedef unsigned char int_uhr_t;
7136ac495dSmrg typedef unsigned int int_ur_t;
7236ac495dSmrg typedef unsigned long int_ulr_t;
7336ac495dSmrg typedef unsigned long long int_ullr_t;
7436ac495dSmrg 
7536ac495dSmrg typedef int int_hk_t;
7636ac495dSmrg typedef long int_k_t;
7736ac495dSmrg typedef long long int_lk_t;
7836ac495dSmrg typedef long long int_llk_t;
7936ac495dSmrg 
8036ac495dSmrg typedef unsigned int int_uhk_t;
8136ac495dSmrg typedef unsigned long int_uk_t;
8236ac495dSmrg typedef unsigned long long int_ulk_t;
8336ac495dSmrg typedef unsigned long long int_ullk_t;
8436ac495dSmrg 
8536ac495dSmrg /* Map mode to the corresponding integer type.  */
8636ac495dSmrg 
8736ac495dSmrg typedef char int_qi_t;
8836ac495dSmrg typedef int int_hi_t;
8936ac495dSmrg typedef long int_si_t;
9036ac495dSmrg typedef long long int_di_t;
9136ac495dSmrg 
9236ac495dSmrg typedef unsigned char uint_qi_t;
9336ac495dSmrg typedef unsigned int uint_hi_t;
9436ac495dSmrg typedef unsigned long uint_si_t;
9536ac495dSmrg typedef unsigned long long uint_di_t;
9636ac495dSmrg 
9736ac495dSmrg 
9836ac495dSmrg 
9936ac495dSmrg /************************************************************************/
10036ac495dSmrg 
10136ac495dSmrg /* Supply implementations / symbols for __builtin_roundFX ASM_NAME.  */
10236ac495dSmrg 
10336ac495dSmrg #ifdef L_round
10436ac495dSmrg 
10536ac495dSmrg #define ROUND1(FX)                              \
10636ac495dSmrg   ROUND2 (FX)
10736ac495dSmrg 
10836ac495dSmrg #define ROUND2(FX)                                                      \
10936ac495dSmrg   extern fx_## FX ##_t __round## FX (fx_## FX ##_t x, int rpoint);      \
11036ac495dSmrg                                                                         \
11136ac495dSmrg   fx_## FX ##_t                                                         \
11236ac495dSmrg   __round## FX (fx_## FX ##_t x, int rpoint)                            \
11336ac495dSmrg   {                                                                     \
11436ac495dSmrg     return __builtin_avr_round ##FX (x, rpoint);                        \
11536ac495dSmrg   }
11636ac495dSmrg 
11736ac495dSmrg ROUND1(L_LABEL)
11836ac495dSmrg 
11936ac495dSmrg #endif /* L_round */
12036ac495dSmrg 
12136ac495dSmrg 
12236ac495dSmrg 
12336ac495dSmrg /*********************************************************************/
12436ac495dSmrg 
12536ac495dSmrg /* Implement some count-leading-redundant-sign-bits to be used with
12636ac495dSmrg    coundlsFX implementation.  */
12736ac495dSmrg 
12836ac495dSmrg #ifdef L__clrsbqi
12936ac495dSmrg extern int __clrsbqi2 (char x);
13036ac495dSmrg 
13136ac495dSmrg int
__clrsbqi2(char x)13236ac495dSmrg __clrsbqi2 (char x)
13336ac495dSmrg {
13436ac495dSmrg   int ret;
13536ac495dSmrg 
13636ac495dSmrg   if (x < 0)
13736ac495dSmrg     x = ~x;
13836ac495dSmrg 
13936ac495dSmrg   if (x == 0)
14036ac495dSmrg     return 8 * sizeof (x) -1;
14136ac495dSmrg 
14236ac495dSmrg   ret = __builtin_clz (x << 8);
14336ac495dSmrg   return ret - 1;
14436ac495dSmrg }
14536ac495dSmrg #endif /* L__clrsbqi */
14636ac495dSmrg 
14736ac495dSmrg 
14836ac495dSmrg #ifdef L__clrsbdi
14936ac495dSmrg extern int __clrsbdi2 (long long x);
15036ac495dSmrg 
15136ac495dSmrg int
__clrsbdi2(long long x)15236ac495dSmrg __clrsbdi2 (long long x)
15336ac495dSmrg {
15436ac495dSmrg   int ret;
15536ac495dSmrg 
15636ac495dSmrg   if (x < 0LL)
15736ac495dSmrg     x = ~x;
15836ac495dSmrg 
15936ac495dSmrg   if (x == 0LL)
16036ac495dSmrg     return 8 * sizeof (x) -1;
16136ac495dSmrg 
16236ac495dSmrg   ret = __builtin_clzll ((unsigned long long) x);
16336ac495dSmrg   return ret - 1;
16436ac495dSmrg }
16536ac495dSmrg #endif /* L__clrsbdi */
16636ac495dSmrg 
16736ac495dSmrg 
16836ac495dSmrg 
16936ac495dSmrg /*********************************************************************/
17036ac495dSmrg 
17136ac495dSmrg /* Supply implementations / symbols for __builtin_avr_countlsFX.  */
17236ac495dSmrg 
17336ac495dSmrg /* Signed */
17436ac495dSmrg 
17536ac495dSmrg #ifdef L_countls
17636ac495dSmrg 
17736ac495dSmrg #define COUNTLS1(MM)                            \
17836ac495dSmrg   COUNTLS2 (MM)
17936ac495dSmrg 
18036ac495dSmrg #define COUNTLS2(MM)                                                    \
18136ac495dSmrg   extern int __countls## MM ##2 (int_## MM ##_t);                       \
18236ac495dSmrg   extern int __clrsb## MM ##2 (int_## MM ##_t);                         \
18336ac495dSmrg                                                                         \
18436ac495dSmrg   int                                                                   \
18536ac495dSmrg   __countls## MM ##2 (int_## MM ##_t x)                                 \
18636ac495dSmrg   {                                                                     \
18736ac495dSmrg     if (x == 0)                                                         \
18836ac495dSmrg       return __INT8_MAX__;                                              \
18936ac495dSmrg                                                                         \
19036ac495dSmrg     return __clrsb## MM ##2 (x);                                        \
19136ac495dSmrg   }
19236ac495dSmrg 
19336ac495dSmrg COUNTLS1(L_LABEL)
19436ac495dSmrg 
19536ac495dSmrg #endif /* L_countls */
19636ac495dSmrg 
19736ac495dSmrg /* Unsigned */
19836ac495dSmrg 
19936ac495dSmrg #ifdef L_countlsu
20036ac495dSmrg 
20136ac495dSmrg #define clz_qi2 __builtin_clz /* unused, avoid warning */
20236ac495dSmrg #define clz_hi2 __builtin_clz
20336ac495dSmrg #define clz_si2 __builtin_clzl
20436ac495dSmrg #define clz_di2 __builtin_clzll
20536ac495dSmrg 
20636ac495dSmrg #define COUNTLS1(MM)                            \
20736ac495dSmrg   COUNTLS2 (MM)
20836ac495dSmrg 
20936ac495dSmrg #define COUNTLS2(MM)                                                    \
21036ac495dSmrg   extern int __countlsu## MM ##2 (uint_## MM ##_t);                     \
21136ac495dSmrg                                                                         \
21236ac495dSmrg   int                                                                   \
21336ac495dSmrg   __countlsu## MM ##2 (uint_## MM ##_t x)                               \
21436ac495dSmrg   {                                                                     \
21536ac495dSmrg     if (x == 0)                                                         \
21636ac495dSmrg       return __INT8_MAX__;                                              \
21736ac495dSmrg                                                                         \
21836ac495dSmrg     if (sizeof (x) == 1)                                                \
21936ac495dSmrg       return clz_hi2 (x << 8);                                          \
22036ac495dSmrg     else                                                                \
22136ac495dSmrg       return clz_## MM ##2 (x);                                         \
22236ac495dSmrg   }
22336ac495dSmrg 
22436ac495dSmrg COUNTLS1(L_LABEL)
22536ac495dSmrg 
22636ac495dSmrg #endif /* L_countlsu */
227