lib2funcs.c revision 1.4
1/* Copyright (C) 2013-2016 Free Software Foundation, Inc.
2
3   This file is part of GCC.
4
5   GCC is free software; you can redistribute it and/or modify it under
6   the terms of the GNU General Public License as published by the Free
7   Software Foundation; either version 3, or (at your option) any later
8   version.
9
10   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11   WARRANTY; without even the implied warranty of MERCHANTABILITY or
12   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13   for more details.
14
15   Under Section 7 of GPL version 3, you are granted additional
16   permissions described in the GCC Runtime Library Exception, version
17   3.1, as published by the Free Software Foundation.
18
19   You should have received a copy of the GNU General Public License and
20   a copy of the GCC Runtime Library Exception along with this program;
21   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
22   <http://www.gnu.org/licenses/>.  */
23
24
25/* This file supplies implementations for some AVR-specific builtin
26   functions so that code like the following works as expected:
27
28   int (*f (void))(_Fract)
29   {
30       return __builtin_avr_countlsr;
31   }
32
33   In this specific case, the generated code is:
34
35   f:
36       ldi r24,lo8(gs(__countlsHI))
37       ldi r25,hi8(gs(__countlsHI))
38       ret
39*/
40
41/* Map fixed-point suffix to the corresponding fixed-point type.  */
42
43typedef short _Fract fx_hr_t;
44typedef _Fract fx_r_t;
45typedef long _Fract fx_lr_t;
46typedef long long _Fract fx_llr_t;
47
48typedef unsigned short _Fract fx_uhr_t;
49typedef unsigned _Fract fx_ur_t;
50typedef unsigned long _Fract fx_ulr_t;
51typedef unsigned long long _Fract fx_ullr_t;
52
53typedef short _Accum fx_hk_t;
54typedef _Accum fx_k_t;
55typedef long _Accum fx_lk_t;
56typedef long long _Accum fx_llk_t;
57
58typedef unsigned short _Accum fx_uhk_t;
59typedef unsigned _Accum fx_uk_t;
60typedef unsigned long _Accum fx_ulk_t;
61typedef unsigned long long _Accum fx_ullk_t;
62
63/* Map fixed-point suffix to the corresponding natural integer type.  */
64
65typedef char int_hr_t;
66typedef int int_r_t;
67typedef long int_lr_t;
68typedef long long int_llr_t;
69
70typedef unsigned char int_uhr_t;
71typedef unsigned int int_ur_t;
72typedef unsigned long int_ulr_t;
73typedef unsigned long long int_ullr_t;
74
75typedef int int_hk_t;
76typedef long int_k_t;
77typedef long long int_lk_t;
78typedef long long int_llk_t;
79
80typedef unsigned int int_uhk_t;
81typedef unsigned long int_uk_t;
82typedef unsigned long long int_ulk_t;
83typedef unsigned long long int_ullk_t;
84
85/* Map mode to the corresponding integer type.  */
86
87typedef char int_qi_t;
88typedef int int_hi_t;
89typedef long int_si_t;
90typedef long long int_di_t;
91
92typedef unsigned char uint_qi_t;
93typedef unsigned int uint_hi_t;
94typedef unsigned long uint_si_t;
95typedef unsigned long long uint_di_t;
96
97
98
99/************************************************************************/
100
101/* Supply implementations / symbols for __builtin_roundFX ASM_NAME.  */
102
103#ifdef L_round
104
105#define ROUND1(FX)                              \
106  ROUND2 (FX)
107
108#define ROUND2(FX)                                                      \
109  extern fx_## FX ##_t __round## FX (fx_## FX ##_t x, int rpoint);      \
110                                                                        \
111  fx_## FX ##_t                                                         \
112  __round## FX (fx_## FX ##_t x, int rpoint)                            \
113  {                                                                     \
114    return __builtin_avr_round ##FX (x, rpoint);                        \
115  }
116
117ROUND1(L_LABEL)
118
119#endif /* L_round */
120
121
122
123/*********************************************************************/
124
125/* Implement some count-leading-redundant-sign-bits to be used with
126   coundlsFX implementation.  */
127
128#ifdef L__clrsbqi
129extern int __clrsbqi2 (char x);
130
131int
132__clrsbqi2 (char x)
133{
134  int ret;
135
136  if (x < 0)
137    x = ~x;
138
139  if (x == 0)
140    return 8 * sizeof (x) -1;
141
142  ret = __builtin_clz (x << 8);
143  return ret - 1;
144}
145#endif /* L__clrsbqi */
146
147
148#ifdef L__clrsbdi
149extern int __clrsbdi2 (long long x);
150
151int
152__clrsbdi2 (long long x)
153{
154  int ret;
155
156  if (x < 0LL)
157    x = ~x;
158
159  if (x == 0LL)
160    return 8 * sizeof (x) -1;
161
162  ret = __builtin_clzll ((unsigned long long) x);
163  return ret - 1;
164}
165#endif /* L__clrsbdi */
166
167
168
169/*********************************************************************/
170
171/* Supply implementations / symbols for __builtin_avr_countlsFX.  */
172
173/* Signed */
174
175#ifdef L_countls
176
177#define COUNTLS1(MM)                            \
178  COUNTLS2 (MM)
179
180#define COUNTLS2(MM)                                                    \
181  extern int __countls## MM ##2 (int_## MM ##_t);                       \
182  extern int __clrsb## MM ##2 (int_## MM ##_t);                         \
183                                                                        \
184  int                                                                   \
185  __countls## MM ##2 (int_## MM ##_t x)                                 \
186  {                                                                     \
187    if (x == 0)                                                         \
188      return __INT8_MAX__;                                              \
189                                                                        \
190    return __clrsb## MM ##2 (x);                                        \
191  }
192
193COUNTLS1(L_LABEL)
194
195#endif /* L_countls */
196
197/* Unsigned */
198
199#ifdef L_countlsu
200
201#define clz_qi2 __builtin_clz /* unused, avoid warning */
202#define clz_hi2 __builtin_clz
203#define clz_si2 __builtin_clzl
204#define clz_di2 __builtin_clzll
205
206#define COUNTLS1(MM)                            \
207  COUNTLS2 (MM)
208
209#define COUNTLS2(MM)                                                    \
210  extern int __countlsu## MM ##2 (uint_## MM ##_t);                     \
211                                                                        \
212  int                                                                   \
213  __countlsu## MM ##2 (uint_## MM ##_t x)                               \
214  {                                                                     \
215    if (x == 0)                                                         \
216      return __INT8_MAX__;                                              \
217                                                                        \
218    if (sizeof (x) == 1)                                                \
219      return clz_hi2 (x << 8);                                          \
220    else                                                                \
221      return clz_## MM ##2 (x);                                         \
222  }
223
224COUNTLS1(L_LABEL)
225
226#endif /* L_countlsu */
227