111
|
1 /* Copyright (C) 2013-2017 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
|
|
43 typedef short _Fract fx_hr_t;
|
|
44 typedef _Fract fx_r_t;
|
|
45 typedef long _Fract fx_lr_t;
|
|
46 typedef long long _Fract fx_llr_t;
|
|
47
|
|
48 typedef unsigned short _Fract fx_uhr_t;
|
|
49 typedef unsigned _Fract fx_ur_t;
|
|
50 typedef unsigned long _Fract fx_ulr_t;
|
|
51 typedef unsigned long long _Fract fx_ullr_t;
|
|
52
|
|
53 typedef short _Accum fx_hk_t;
|
|
54 typedef _Accum fx_k_t;
|
|
55 typedef long _Accum fx_lk_t;
|
|
56 typedef long long _Accum fx_llk_t;
|
|
57
|
|
58 typedef unsigned short _Accum fx_uhk_t;
|
|
59 typedef unsigned _Accum fx_uk_t;
|
|
60 typedef unsigned long _Accum fx_ulk_t;
|
|
61 typedef unsigned long long _Accum fx_ullk_t;
|
|
62
|
|
63 /* Map fixed-point suffix to the corresponding natural integer type. */
|
|
64
|
|
65 typedef char int_hr_t;
|
|
66 typedef int int_r_t;
|
|
67 typedef long int_lr_t;
|
|
68 typedef long long int_llr_t;
|
|
69
|
|
70 typedef unsigned char int_uhr_t;
|
|
71 typedef unsigned int int_ur_t;
|
|
72 typedef unsigned long int_ulr_t;
|
|
73 typedef unsigned long long int_ullr_t;
|
|
74
|
|
75 typedef int int_hk_t;
|
|
76 typedef long int_k_t;
|
|
77 typedef long long int_lk_t;
|
|
78 typedef long long int_llk_t;
|
|
79
|
|
80 typedef unsigned int int_uhk_t;
|
|
81 typedef unsigned long int_uk_t;
|
|
82 typedef unsigned long long int_ulk_t;
|
|
83 typedef unsigned long long int_ullk_t;
|
|
84
|
|
85 /* Map mode to the corresponding integer type. */
|
|
86
|
|
87 typedef char int_qi_t;
|
|
88 typedef int int_hi_t;
|
|
89 typedef long int_si_t;
|
|
90 typedef long long int_di_t;
|
|
91
|
|
92 typedef unsigned char uint_qi_t;
|
|
93 typedef unsigned int uint_hi_t;
|
|
94 typedef unsigned long uint_si_t;
|
|
95 typedef 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
|
|
117 ROUND1(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
|
|
129 extern int __clrsbqi2 (char x);
|
|
130
|
|
131 int
|
|
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
|
|
149 extern int __clrsbdi2 (long long x);
|
|
150
|
|
151 int
|
|
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
|
|
193 COUNTLS1(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
|
|
224 COUNTLS1(L_LABEL)
|
|
225
|
|
226 #endif /* L_countlsu */
|