machmode.h revision 1.9 1 1.1 mrg /* Machine mode definitions for GCC; included by rtl.h and tree.h.
2 1.9 mrg Copyright (C) 1991-2018 Free Software Foundation, Inc.
3 1.1 mrg
4 1.1 mrg This file is part of GCC.
5 1.1 mrg
6 1.1 mrg GCC is free software; you can redistribute it and/or modify it under
7 1.1 mrg the terms of the GNU General Public License as published by the Free
8 1.1 mrg Software Foundation; either version 3, or (at your option) any later
9 1.1 mrg version.
10 1.1 mrg
11 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 1.1 mrg for more details.
15 1.1 mrg
16 1.1 mrg You should have received a copy of the GNU General Public License
17 1.1 mrg along with GCC; see the file COPYING3. If not see
18 1.1 mrg <http://www.gnu.org/licenses/>. */
19 1.1 mrg
20 1.1 mrg #ifndef HAVE_MACHINE_MODES
21 1.1 mrg #define HAVE_MACHINE_MODES
22 1.1 mrg
23 1.9 mrg typedef opt_mode<machine_mode> opt_machine_mode;
24 1.9 mrg
25 1.9 mrg extern CONST_MODE_SIZE poly_uint16_pod mode_size[NUM_MACHINE_MODES];
26 1.9 mrg extern CONST_MODE_PRECISION poly_uint16_pod mode_precision[NUM_MACHINE_MODES];
27 1.9 mrg extern const unsigned char mode_inner[NUM_MACHINE_MODES];
28 1.9 mrg extern CONST_MODE_NUNITS poly_uint16_pod mode_nunits[NUM_MACHINE_MODES];
29 1.9 mrg extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];
30 1.9 mrg extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];
31 1.9 mrg extern const unsigned char mode_wider[NUM_MACHINE_MODES];
32 1.9 mrg extern const unsigned char mode_2xwider[NUM_MACHINE_MODES];
33 1.9 mrg
34 1.9 mrg template<typename T>
35 1.9 mrg struct mode_traits
36 1.9 mrg {
37 1.9 mrg /* For use by the machmode support code only.
38 1.9 mrg
39 1.9 mrg There are cases in which the machmode support code needs to forcibly
40 1.9 mrg convert a machine_mode to a specific mode class T, and in which the
41 1.9 mrg context guarantees that this is valid without the need for an assert.
42 1.9 mrg This can be done using:
43 1.9 mrg
44 1.9 mrg return typename mode_traits<T>::from_int (mode);
45 1.9 mrg
46 1.9 mrg when returning a T and:
47 1.9 mrg
48 1.9 mrg res = T (typename mode_traits<T>::from_int (mode));
49 1.9 mrg
50 1.9 mrg when assigning to a value RES that must be assignment-compatible
51 1.9 mrg with (but possibly not the same as) T. */
52 1.9 mrg #ifdef USE_ENUM_MODES
53 1.9 mrg /* Allow direct conversion of enums to specific mode classes only
54 1.9 mrg when USE_ENUM_MODES is defined. This is only intended for use
55 1.9 mrg by gencondmd, so that it can tell more easily when .md conditions
56 1.9 mrg are always false. */
57 1.9 mrg typedef machine_mode from_int;
58 1.9 mrg #else
59 1.9 mrg /* Here we use an enum type distinct from machine_mode but with the
60 1.9 mrg same range as machine_mode. T should have a constructor that
61 1.9 mrg accepts this enum type; it should not have a constructor that
62 1.9 mrg accepts machine_mode.
63 1.9 mrg
64 1.9 mrg We use this somewhat indirect approach to avoid too many constructor
65 1.9 mrg calls when the compiler is built with -O0. For example, even in
66 1.9 mrg unoptimized code, the return statement above would construct the
67 1.9 mrg returned T directly from the numerical value of MODE. */
68 1.9 mrg enum from_int { dummy = MAX_MACHINE_MODE };
69 1.9 mrg #endif
70 1.9 mrg };
71 1.9 mrg
72 1.9 mrg template<>
73 1.9 mrg struct mode_traits<machine_mode>
74 1.9 mrg {
75 1.9 mrg /* machine_mode itself needs no conversion. */
76 1.9 mrg typedef machine_mode from_int;
77 1.9 mrg };
78 1.9 mrg
79 1.9 mrg /* Always treat machine modes as fixed-size while compiling code specific
80 1.9 mrg to targets that have no variable-size modes. */
81 1.9 mrg #if defined (IN_TARGET_CODE) && NUM_POLY_INT_COEFFS == 1
82 1.9 mrg #define ONLY_FIXED_SIZE_MODES 1
83 1.9 mrg #else
84 1.9 mrg #define ONLY_FIXED_SIZE_MODES 0
85 1.9 mrg #endif
86 1.1 mrg
87 1.1 mrg /* Get the name of mode MODE as a string. */
88 1.1 mrg
89 1.1 mrg extern const char * const mode_name[NUM_MACHINE_MODES];
90 1.1 mrg #define GET_MODE_NAME(MODE) mode_name[MODE]
91 1.1 mrg
92 1.1 mrg /* Mode classes. */
93 1.1 mrg
94 1.1 mrg #include "mode-classes.def"
95 1.1 mrg #define DEF_MODE_CLASS(M) M
96 1.1 mrg enum mode_class { MODE_CLASSES, MAX_MODE_CLASS };
97 1.1 mrg #undef DEF_MODE_CLASS
98 1.1 mrg #undef MODE_CLASSES
99 1.1 mrg
100 1.1 mrg /* Get the general kind of object that mode MODE represents
101 1.1 mrg (integer, floating, complex, etc.) */
102 1.1 mrg
103 1.1 mrg extern const unsigned char mode_class[NUM_MACHINE_MODES];
104 1.1 mrg #define GET_MODE_CLASS(MODE) ((enum mode_class) mode_class[MODE])
105 1.1 mrg
106 1.1 mrg /* Nonzero if MODE is an integral mode. */
107 1.1 mrg #define INTEGRAL_MODE_P(MODE) \
108 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_INT \
109 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT \
110 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \
111 1.9 mrg || GET_MODE_CLASS (MODE) == MODE_VECTOR_BOOL \
112 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_VECTOR_INT)
113 1.1 mrg
114 1.1 mrg /* Nonzero if MODE is a floating-point mode. */
115 1.1 mrg #define FLOAT_MODE_P(MODE) \
116 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_FLOAT \
117 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_DECIMAL_FLOAT \
118 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
119 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT)
120 1.1 mrg
121 1.1 mrg /* Nonzero if MODE is a complex mode. */
122 1.1 mrg #define COMPLEX_MODE_P(MODE) \
123 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \
124 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)
125 1.1 mrg
126 1.1 mrg /* Nonzero if MODE is a vector mode. */
127 1.9 mrg #define VECTOR_MODE_P(MODE) \
128 1.9 mrg (GET_MODE_CLASS (MODE) == MODE_VECTOR_BOOL \
129 1.9 mrg || GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \
130 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT \
131 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_VECTOR_FRACT \
132 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_VECTOR_UFRACT \
133 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_VECTOR_ACCUM \
134 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_VECTOR_UACCUM)
135 1.1 mrg
136 1.1 mrg /* Nonzero if MODE is a scalar integral mode. */
137 1.1 mrg #define SCALAR_INT_MODE_P(MODE) \
138 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_INT \
139 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT)
140 1.1 mrg
141 1.1 mrg /* Nonzero if MODE is a scalar floating point mode. */
142 1.1 mrg #define SCALAR_FLOAT_MODE_P(MODE) \
143 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_FLOAT \
144 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_DECIMAL_FLOAT)
145 1.1 mrg
146 1.1 mrg /* Nonzero if MODE is a decimal floating point mode. */
147 1.1 mrg #define DECIMAL_FLOAT_MODE_P(MODE) \
148 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_DECIMAL_FLOAT)
149 1.1 mrg
150 1.1 mrg /* Nonzero if MODE is a scalar fract mode. */
151 1.1 mrg #define SCALAR_FRACT_MODE_P(MODE) \
152 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_FRACT)
153 1.1 mrg
154 1.1 mrg /* Nonzero if MODE is a scalar ufract mode. */
155 1.1 mrg #define SCALAR_UFRACT_MODE_P(MODE) \
156 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_UFRACT)
157 1.1 mrg
158 1.1 mrg /* Nonzero if MODE is a scalar fract or ufract mode. */
159 1.1 mrg #define ALL_SCALAR_FRACT_MODE_P(MODE) \
160 1.1 mrg (SCALAR_FRACT_MODE_P (MODE) || SCALAR_UFRACT_MODE_P (MODE))
161 1.1 mrg
162 1.1 mrg /* Nonzero if MODE is a scalar accum mode. */
163 1.1 mrg #define SCALAR_ACCUM_MODE_P(MODE) \
164 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_ACCUM)
165 1.1 mrg
166 1.1 mrg /* Nonzero if MODE is a scalar uaccum mode. */
167 1.1 mrg #define SCALAR_UACCUM_MODE_P(MODE) \
168 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_UACCUM)
169 1.1 mrg
170 1.1 mrg /* Nonzero if MODE is a scalar accum or uaccum mode. */
171 1.1 mrg #define ALL_SCALAR_ACCUM_MODE_P(MODE) \
172 1.1 mrg (SCALAR_ACCUM_MODE_P (MODE) || SCALAR_UACCUM_MODE_P (MODE))
173 1.1 mrg
174 1.1 mrg /* Nonzero if MODE is a scalar fract or accum mode. */
175 1.1 mrg #define SIGNED_SCALAR_FIXED_POINT_MODE_P(MODE) \
176 1.1 mrg (SCALAR_FRACT_MODE_P (MODE) || SCALAR_ACCUM_MODE_P (MODE))
177 1.1 mrg
178 1.1 mrg /* Nonzero if MODE is a scalar ufract or uaccum mode. */
179 1.1 mrg #define UNSIGNED_SCALAR_FIXED_POINT_MODE_P(MODE) \
180 1.1 mrg (SCALAR_UFRACT_MODE_P (MODE) || SCALAR_UACCUM_MODE_P (MODE))
181 1.1 mrg
182 1.1 mrg /* Nonzero if MODE is a scalar fract, ufract, accum or uaccum mode. */
183 1.1 mrg #define ALL_SCALAR_FIXED_POINT_MODE_P(MODE) \
184 1.1 mrg (SIGNED_SCALAR_FIXED_POINT_MODE_P (MODE) \
185 1.1 mrg || UNSIGNED_SCALAR_FIXED_POINT_MODE_P (MODE))
186 1.1 mrg
187 1.1 mrg /* Nonzero if MODE is a scalar/vector fract mode. */
188 1.1 mrg #define FRACT_MODE_P(MODE) \
189 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_FRACT \
190 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_VECTOR_FRACT)
191 1.1 mrg
192 1.1 mrg /* Nonzero if MODE is a scalar/vector ufract mode. */
193 1.1 mrg #define UFRACT_MODE_P(MODE) \
194 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_UFRACT \
195 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_VECTOR_UFRACT)
196 1.1 mrg
197 1.1 mrg /* Nonzero if MODE is a scalar/vector fract or ufract mode. */
198 1.1 mrg #define ALL_FRACT_MODE_P(MODE) \
199 1.1 mrg (FRACT_MODE_P (MODE) || UFRACT_MODE_P (MODE))
200 1.1 mrg
201 1.1 mrg /* Nonzero if MODE is a scalar/vector accum mode. */
202 1.1 mrg #define ACCUM_MODE_P(MODE) \
203 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_ACCUM \
204 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_VECTOR_ACCUM)
205 1.1 mrg
206 1.1 mrg /* Nonzero if MODE is a scalar/vector uaccum mode. */
207 1.1 mrg #define UACCUM_MODE_P(MODE) \
208 1.1 mrg (GET_MODE_CLASS (MODE) == MODE_UACCUM \
209 1.1 mrg || GET_MODE_CLASS (MODE) == MODE_VECTOR_UACCUM)
210 1.1 mrg
211 1.1 mrg /* Nonzero if MODE is a scalar/vector accum or uaccum mode. */
212 1.1 mrg #define ALL_ACCUM_MODE_P(MODE) \
213 1.1 mrg (ACCUM_MODE_P (MODE) || UACCUM_MODE_P (MODE))
214 1.1 mrg
215 1.1 mrg /* Nonzero if MODE is a scalar/vector fract or accum mode. */
216 1.1 mrg #define SIGNED_FIXED_POINT_MODE_P(MODE) \
217 1.1 mrg (FRACT_MODE_P (MODE) || ACCUM_MODE_P (MODE))
218 1.1 mrg
219 1.1 mrg /* Nonzero if MODE is a scalar/vector ufract or uaccum mode. */
220 1.1 mrg #define UNSIGNED_FIXED_POINT_MODE_P(MODE) \
221 1.1 mrg (UFRACT_MODE_P (MODE) || UACCUM_MODE_P (MODE))
222 1.1 mrg
223 1.1 mrg /* Nonzero if MODE is a scalar/vector fract, ufract, accum or uaccum mode. */
224 1.1 mrg #define ALL_FIXED_POINT_MODE_P(MODE) \
225 1.1 mrg (SIGNED_FIXED_POINT_MODE_P (MODE) \
226 1.1 mrg || UNSIGNED_FIXED_POINT_MODE_P (MODE))
227 1.1 mrg
228 1.1 mrg /* Nonzero if CLASS modes can be widened. */
229 1.1 mrg #define CLASS_HAS_WIDER_MODES_P(CLASS) \
230 1.1 mrg (CLASS == MODE_INT \
231 1.3 mrg || CLASS == MODE_PARTIAL_INT \
232 1.1 mrg || CLASS == MODE_FLOAT \
233 1.1 mrg || CLASS == MODE_DECIMAL_FLOAT \
234 1.1 mrg || CLASS == MODE_COMPLEX_FLOAT \
235 1.1 mrg || CLASS == MODE_FRACT \
236 1.1 mrg || CLASS == MODE_UFRACT \
237 1.1 mrg || CLASS == MODE_ACCUM \
238 1.1 mrg || CLASS == MODE_UACCUM)
239 1.1 mrg
240 1.5 mrg #define POINTER_BOUNDS_MODE_P(MODE) \
241 1.5 mrg (GET_MODE_CLASS (MODE) == MODE_POINTER_BOUNDS)
242 1.5 mrg
243 1.9 mrg /* An optional T (i.e. a T or nothing), where T is some form of mode class. */
244 1.9 mrg template<typename T>
245 1.9 mrg class opt_mode
246 1.9 mrg {
247 1.9 mrg public:
248 1.9 mrg enum from_int { dummy = MAX_MACHINE_MODE };
249 1.9 mrg
250 1.9 mrg ALWAYS_INLINE opt_mode () : m_mode (E_VOIDmode) {}
251 1.9 mrg ALWAYS_INLINE opt_mode (const T &m) : m_mode (m) {}
252 1.9 mrg template<typename U>
253 1.9 mrg ALWAYS_INLINE opt_mode (const U &m) : m_mode (T (m)) {}
254 1.9 mrg ALWAYS_INLINE opt_mode (from_int m) : m_mode (machine_mode (m)) {}
255 1.9 mrg
256 1.9 mrg machine_mode else_void () const;
257 1.9 mrg machine_mode else_blk () const;
258 1.9 mrg T require () const;
259 1.9 mrg
260 1.9 mrg bool exists () const;
261 1.9 mrg template<typename U> bool exists (U *) const;
262 1.9 mrg
263 1.9 mrg private:
264 1.9 mrg machine_mode m_mode;
265 1.9 mrg };
266 1.9 mrg
267 1.9 mrg /* If the object contains a T, return its enum value, otherwise return
268 1.9 mrg E_VOIDmode. */
269 1.9 mrg
270 1.9 mrg template<typename T>
271 1.9 mrg ALWAYS_INLINE machine_mode
272 1.9 mrg opt_mode<T>::else_void () const
273 1.9 mrg {
274 1.9 mrg return m_mode;
275 1.9 mrg }
276 1.9 mrg
277 1.9 mrg /* If the T exists, return its enum value, otherwise return E_BLKmode. */
278 1.9 mrg
279 1.9 mrg template<typename T>
280 1.9 mrg inline machine_mode
281 1.9 mrg opt_mode<T>::else_blk () const
282 1.9 mrg {
283 1.9 mrg return m_mode == E_VOIDmode ? E_BLKmode : m_mode;
284 1.9 mrg }
285 1.9 mrg
286 1.9 mrg /* Assert that the object contains a T and return it. */
287 1.9 mrg
288 1.9 mrg template<typename T>
289 1.9 mrg inline T
290 1.9 mrg opt_mode<T>::require () const
291 1.9 mrg {
292 1.9 mrg gcc_checking_assert (m_mode != E_VOIDmode);
293 1.9 mrg return typename mode_traits<T>::from_int (m_mode);
294 1.9 mrg }
295 1.9 mrg
296 1.9 mrg /* Return true if the object contains a T rather than nothing. */
297 1.9 mrg
298 1.9 mrg template<typename T>
299 1.9 mrg ALWAYS_INLINE bool
300 1.9 mrg opt_mode<T>::exists () const
301 1.9 mrg {
302 1.9 mrg return m_mode != E_VOIDmode;
303 1.9 mrg }
304 1.9 mrg
305 1.9 mrg /* Return true if the object contains a T, storing it in *MODE if so. */
306 1.9 mrg
307 1.9 mrg template<typename T>
308 1.9 mrg template<typename U>
309 1.9 mrg inline bool
310 1.9 mrg opt_mode<T>::exists (U *mode) const
311 1.9 mrg {
312 1.9 mrg if (m_mode != E_VOIDmode)
313 1.9 mrg {
314 1.9 mrg *mode = T (typename mode_traits<T>::from_int (m_mode));
315 1.9 mrg return true;
316 1.9 mrg }
317 1.9 mrg return false;
318 1.9 mrg }
319 1.9 mrg
320 1.9 mrg /* A POD version of mode class T. */
321 1.9 mrg
322 1.9 mrg template<typename T>
323 1.9 mrg struct pod_mode
324 1.9 mrg {
325 1.9 mrg typedef typename mode_traits<T>::from_int from_int;
326 1.9 mrg typedef typename T::measurement_type measurement_type;
327 1.9 mrg
328 1.9 mrg machine_mode m_mode;
329 1.9 mrg ALWAYS_INLINE operator machine_mode () const { return m_mode; }
330 1.9 mrg ALWAYS_INLINE operator T () const { return from_int (m_mode); }
331 1.9 mrg ALWAYS_INLINE pod_mode &operator = (const T &m) { m_mode = m; return *this; }
332 1.9 mrg };
333 1.9 mrg
334 1.9 mrg /* Return true if mode M has type T. */
335 1.9 mrg
336 1.9 mrg template<typename T>
337 1.9 mrg inline bool
338 1.9 mrg is_a (machine_mode m)
339 1.9 mrg {
340 1.9 mrg return T::includes_p (m);
341 1.9 mrg }
342 1.9 mrg
343 1.9 mrg template<typename T, typename U>
344 1.9 mrg inline bool
345 1.9 mrg is_a (const opt_mode<U> &m)
346 1.9 mrg {
347 1.9 mrg return T::includes_p (m.else_void ());
348 1.9 mrg }
349 1.9 mrg
350 1.9 mrg /* Assert that mode M has type T, and return it in that form. */
351 1.9 mrg
352 1.9 mrg template<typename T>
353 1.9 mrg inline T
354 1.9 mrg as_a (machine_mode m)
355 1.9 mrg {
356 1.9 mrg gcc_checking_assert (T::includes_p (m));
357 1.9 mrg return typename mode_traits<T>::from_int (m);
358 1.9 mrg }
359 1.9 mrg
360 1.9 mrg template<typename T, typename U>
361 1.9 mrg inline T
362 1.9 mrg as_a (const opt_mode<U> &m)
363 1.9 mrg {
364 1.9 mrg return as_a <T> (m.else_void ());
365 1.9 mrg }
366 1.9 mrg
367 1.9 mrg /* Convert M to an opt_mode<T>. */
368 1.9 mrg
369 1.9 mrg template<typename T>
370 1.9 mrg inline opt_mode<T>
371 1.9 mrg dyn_cast (machine_mode m)
372 1.9 mrg {
373 1.9 mrg if (T::includes_p (m))
374 1.9 mrg return T (typename mode_traits<T>::from_int (m));
375 1.9 mrg return opt_mode<T> ();
376 1.9 mrg }
377 1.9 mrg
378 1.9 mrg template<typename T, typename U>
379 1.9 mrg inline opt_mode<T>
380 1.9 mrg dyn_cast (const opt_mode<U> &m)
381 1.9 mrg {
382 1.9 mrg return dyn_cast <T> (m.else_void ());
383 1.9 mrg }
384 1.9 mrg
385 1.9 mrg /* Return true if mode M has type T, storing it as a T in *RESULT
386 1.9 mrg if so. */
387 1.1 mrg
388 1.9 mrg template<typename T, typename U>
389 1.9 mrg inline bool
390 1.9 mrg is_a (machine_mode m, U *result)
391 1.9 mrg {
392 1.9 mrg if (T::includes_p (m))
393 1.9 mrg {
394 1.9 mrg *result = T (typename mode_traits<T>::from_int (m));
395 1.9 mrg return true;
396 1.9 mrg }
397 1.9 mrg return false;
398 1.9 mrg }
399 1.9 mrg
400 1.9 mrg /* Represents a machine mode that is known to be a SCALAR_INT_MODE_P. */
401 1.9 mrg class scalar_int_mode
402 1.9 mrg {
403 1.9 mrg public:
404 1.9 mrg typedef mode_traits<scalar_int_mode>::from_int from_int;
405 1.9 mrg typedef unsigned short measurement_type;
406 1.9 mrg
407 1.9 mrg ALWAYS_INLINE scalar_int_mode () {}
408 1.9 mrg ALWAYS_INLINE scalar_int_mode (from_int m) : m_mode (machine_mode (m)) {}
409 1.9 mrg ALWAYS_INLINE operator machine_mode () const { return m_mode; }
410 1.9 mrg
411 1.9 mrg static bool includes_p (machine_mode);
412 1.9 mrg
413 1.9 mrg protected:
414 1.9 mrg machine_mode m_mode;
415 1.9 mrg };
416 1.9 mrg
417 1.9 mrg /* Return true if M is a scalar_int_mode. */
418 1.9 mrg
419 1.9 mrg inline bool
420 1.9 mrg scalar_int_mode::includes_p (machine_mode m)
421 1.9 mrg {
422 1.9 mrg return SCALAR_INT_MODE_P (m);
423 1.9 mrg }
424 1.9 mrg
425 1.9 mrg /* Represents a machine mode that is known to be a SCALAR_FLOAT_MODE_P. */
426 1.9 mrg class scalar_float_mode
427 1.9 mrg {
428 1.9 mrg public:
429 1.9 mrg typedef mode_traits<scalar_float_mode>::from_int from_int;
430 1.9 mrg typedef unsigned short measurement_type;
431 1.9 mrg
432 1.9 mrg ALWAYS_INLINE scalar_float_mode () {}
433 1.9 mrg ALWAYS_INLINE scalar_float_mode (from_int m) : m_mode (machine_mode (m)) {}
434 1.9 mrg ALWAYS_INLINE operator machine_mode () const { return m_mode; }
435 1.9 mrg
436 1.9 mrg static bool includes_p (machine_mode);
437 1.9 mrg
438 1.9 mrg protected:
439 1.9 mrg machine_mode m_mode;
440 1.9 mrg };
441 1.9 mrg
442 1.9 mrg /* Return true if M is a scalar_float_mode. */
443 1.9 mrg
444 1.9 mrg inline bool
445 1.9 mrg scalar_float_mode::includes_p (machine_mode m)
446 1.9 mrg {
447 1.9 mrg return SCALAR_FLOAT_MODE_P (m);
448 1.9 mrg }
449 1.9 mrg
450 1.9 mrg /* Represents a machine mode that is known to be scalar. */
451 1.9 mrg class scalar_mode
452 1.9 mrg {
453 1.9 mrg public:
454 1.9 mrg typedef mode_traits<scalar_mode>::from_int from_int;
455 1.9 mrg typedef unsigned short measurement_type;
456 1.9 mrg
457 1.9 mrg ALWAYS_INLINE scalar_mode () {}
458 1.9 mrg ALWAYS_INLINE scalar_mode (from_int m) : m_mode (machine_mode (m)) {}
459 1.9 mrg ALWAYS_INLINE scalar_mode (const scalar_int_mode &m) : m_mode (m) {}
460 1.9 mrg ALWAYS_INLINE scalar_mode (const scalar_float_mode &m) : m_mode (m) {}
461 1.9 mrg ALWAYS_INLINE scalar_mode (const scalar_int_mode_pod &m) : m_mode (m) {}
462 1.9 mrg ALWAYS_INLINE operator machine_mode () const { return m_mode; }
463 1.9 mrg
464 1.9 mrg static bool includes_p (machine_mode);
465 1.9 mrg
466 1.9 mrg protected:
467 1.9 mrg machine_mode m_mode;
468 1.9 mrg };
469 1.9 mrg
470 1.9 mrg /* Return true if M represents some kind of scalar value. */
471 1.9 mrg
472 1.9 mrg inline bool
473 1.9 mrg scalar_mode::includes_p (machine_mode m)
474 1.9 mrg {
475 1.9 mrg switch (GET_MODE_CLASS (m))
476 1.9 mrg {
477 1.9 mrg case MODE_INT:
478 1.9 mrg case MODE_PARTIAL_INT:
479 1.9 mrg case MODE_FRACT:
480 1.9 mrg case MODE_UFRACT:
481 1.9 mrg case MODE_ACCUM:
482 1.9 mrg case MODE_UACCUM:
483 1.9 mrg case MODE_FLOAT:
484 1.9 mrg case MODE_DECIMAL_FLOAT:
485 1.9 mrg case MODE_POINTER_BOUNDS:
486 1.9 mrg return true;
487 1.9 mrg default:
488 1.9 mrg return false;
489 1.9 mrg }
490 1.9 mrg }
491 1.9 mrg
492 1.9 mrg /* Represents a machine mode that is known to be a COMPLEX_MODE_P. */
493 1.9 mrg class complex_mode
494 1.9 mrg {
495 1.9 mrg public:
496 1.9 mrg typedef mode_traits<complex_mode>::from_int from_int;
497 1.9 mrg typedef unsigned short measurement_type;
498 1.9 mrg
499 1.9 mrg ALWAYS_INLINE complex_mode () {}
500 1.9 mrg ALWAYS_INLINE complex_mode (from_int m) : m_mode (machine_mode (m)) {}
501 1.9 mrg ALWAYS_INLINE operator machine_mode () const { return m_mode; }
502 1.9 mrg
503 1.9 mrg static bool includes_p (machine_mode);
504 1.9 mrg
505 1.9 mrg protected:
506 1.9 mrg machine_mode m_mode;
507 1.9 mrg };
508 1.9 mrg
509 1.9 mrg /* Return true if M is a complex_mode. */
510 1.9 mrg
511 1.9 mrg inline bool
512 1.9 mrg complex_mode::includes_p (machine_mode m)
513 1.9 mrg {
514 1.9 mrg return COMPLEX_MODE_P (m);
515 1.9 mrg }
516 1.9 mrg
517 1.9 mrg /* Return the base GET_MODE_SIZE value for MODE. */
518 1.9 mrg
519 1.9 mrg ALWAYS_INLINE poly_uint16
520 1.9 mrg mode_to_bytes (machine_mode mode)
521 1.9 mrg {
522 1.5 mrg #if GCC_VERSION >= 4001
523 1.9 mrg return (__builtin_constant_p (mode)
524 1.9 mrg ? mode_size_inline (mode) : mode_size[mode]);
525 1.5 mrg #else
526 1.9 mrg return mode_size[mode];
527 1.9 mrg #endif
528 1.9 mrg }
529 1.9 mrg
530 1.9 mrg /* Return the base GET_MODE_BITSIZE value for MODE. */
531 1.9 mrg
532 1.9 mrg ALWAYS_INLINE poly_uint16
533 1.9 mrg mode_to_bits (machine_mode mode)
534 1.9 mrg {
535 1.9 mrg return mode_to_bytes (mode) * BITS_PER_UNIT;
536 1.9 mrg }
537 1.9 mrg
538 1.9 mrg /* Return the base GET_MODE_PRECISION value for MODE. */
539 1.9 mrg
540 1.9 mrg ALWAYS_INLINE poly_uint16
541 1.9 mrg mode_to_precision (machine_mode mode)
542 1.9 mrg {
543 1.9 mrg return mode_precision[mode];
544 1.9 mrg }
545 1.9 mrg
546 1.9 mrg /* Return the base GET_MODE_INNER value for MODE. */
547 1.9 mrg
548 1.9 mrg ALWAYS_INLINE scalar_mode
549 1.9 mrg mode_to_inner (machine_mode mode)
550 1.9 mrg {
551 1.9 mrg #if GCC_VERSION >= 4001
552 1.9 mrg return scalar_mode::from_int (__builtin_constant_p (mode)
553 1.9 mrg ? mode_inner_inline (mode)
554 1.9 mrg : mode_inner[mode]);
555 1.9 mrg #else
556 1.9 mrg return scalar_mode::from_int (mode_inner[mode]);
557 1.9 mrg #endif
558 1.9 mrg }
559 1.9 mrg
560 1.9 mrg /* Return the base GET_MODE_UNIT_SIZE value for MODE. */
561 1.9 mrg
562 1.9 mrg ALWAYS_INLINE unsigned char
563 1.9 mrg mode_to_unit_size (machine_mode mode)
564 1.9 mrg {
565 1.9 mrg #if GCC_VERSION >= 4001
566 1.9 mrg return (__builtin_constant_p (mode)
567 1.9 mrg ? mode_unit_size_inline (mode) : mode_unit_size[mode]);
568 1.9 mrg #else
569 1.9 mrg return mode_unit_size[mode];
570 1.9 mrg #endif
571 1.9 mrg }
572 1.9 mrg
573 1.9 mrg /* Return the base GET_MODE_UNIT_PRECISION value for MODE. */
574 1.9 mrg
575 1.9 mrg ALWAYS_INLINE unsigned short
576 1.9 mrg mode_to_unit_precision (machine_mode mode)
577 1.9 mrg {
578 1.9 mrg #if GCC_VERSION >= 4001
579 1.9 mrg return (__builtin_constant_p (mode)
580 1.9 mrg ? mode_unit_precision_inline (mode) : mode_unit_precision[mode]);
581 1.9 mrg #else
582 1.9 mrg return mode_unit_precision[mode];
583 1.9 mrg #endif
584 1.9 mrg }
585 1.9 mrg
586 1.9 mrg /* Return the base GET_MODE_NUNITS value for MODE. */
587 1.9 mrg
588 1.9 mrg ALWAYS_INLINE poly_uint16
589 1.9 mrg mode_to_nunits (machine_mode mode)
590 1.9 mrg {
591 1.9 mrg #if GCC_VERSION >= 4001
592 1.9 mrg return (__builtin_constant_p (mode)
593 1.9 mrg ? mode_nunits_inline (mode) : mode_nunits[mode]);
594 1.9 mrg #else
595 1.9 mrg return mode_nunits[mode];
596 1.9 mrg #endif
597 1.9 mrg }
598 1.9 mrg
599 1.9 mrg /* Get the size in bytes of an object of mode MODE. */
600 1.9 mrg
601 1.9 mrg #if ONLY_FIXED_SIZE_MODES
602 1.9 mrg #define GET_MODE_SIZE(MODE) ((unsigned short) mode_to_bytes (MODE).coeffs[0])
603 1.9 mrg #else
604 1.9 mrg ALWAYS_INLINE poly_uint16
605 1.9 mrg GET_MODE_SIZE (machine_mode mode)
606 1.9 mrg {
607 1.9 mrg return mode_to_bytes (mode);
608 1.9 mrg }
609 1.9 mrg
610 1.9 mrg template<typename T>
611 1.9 mrg ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type
612 1.9 mrg GET_MODE_SIZE (const T &mode)
613 1.9 mrg {
614 1.9 mrg return mode_to_bytes (mode);
615 1.9 mrg }
616 1.9 mrg
617 1.9 mrg template<typename T>
618 1.9 mrg ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type
619 1.9 mrg GET_MODE_SIZE (const T &mode)
620 1.9 mrg {
621 1.9 mrg return mode_to_bytes (mode).coeffs[0];
622 1.9 mrg }
623 1.9 mrg #endif
624 1.9 mrg
625 1.9 mrg /* Get the size in bits of an object of mode MODE. */
626 1.9 mrg
627 1.9 mrg #if ONLY_FIXED_SIZE_MODES
628 1.9 mrg #define GET_MODE_BITSIZE(MODE) ((unsigned short) mode_to_bits (MODE).coeffs[0])
629 1.9 mrg #else
630 1.9 mrg ALWAYS_INLINE poly_uint16
631 1.9 mrg GET_MODE_BITSIZE (machine_mode mode)
632 1.9 mrg {
633 1.9 mrg return mode_to_bits (mode);
634 1.9 mrg }
635 1.9 mrg
636 1.9 mrg template<typename T>
637 1.9 mrg ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type
638 1.9 mrg GET_MODE_BITSIZE (const T &mode)
639 1.9 mrg {
640 1.9 mrg return mode_to_bits (mode);
641 1.9 mrg }
642 1.9 mrg
643 1.9 mrg template<typename T>
644 1.9 mrg ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type
645 1.9 mrg GET_MODE_BITSIZE (const T &mode)
646 1.9 mrg {
647 1.9 mrg return mode_to_bits (mode).coeffs[0];
648 1.9 mrg }
649 1.5 mrg #endif
650 1.1 mrg
651 1.1 mrg /* Get the number of value bits of an object of mode MODE. */
652 1.9 mrg
653 1.9 mrg #if ONLY_FIXED_SIZE_MODES
654 1.9 mrg #define GET_MODE_PRECISION(MODE) \
655 1.9 mrg ((unsigned short) mode_to_precision (MODE).coeffs[0])
656 1.9 mrg #else
657 1.9 mrg ALWAYS_INLINE poly_uint16
658 1.9 mrg GET_MODE_PRECISION (machine_mode mode)
659 1.9 mrg {
660 1.9 mrg return mode_to_precision (mode);
661 1.9 mrg }
662 1.9 mrg
663 1.9 mrg template<typename T>
664 1.9 mrg ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type
665 1.9 mrg GET_MODE_PRECISION (const T &mode)
666 1.9 mrg {
667 1.9 mrg return mode_to_precision (mode);
668 1.9 mrg }
669 1.9 mrg
670 1.9 mrg template<typename T>
671 1.9 mrg ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type
672 1.9 mrg GET_MODE_PRECISION (const T &mode)
673 1.9 mrg {
674 1.9 mrg return mode_to_precision (mode).coeffs[0];
675 1.9 mrg }
676 1.9 mrg #endif
677 1.1 mrg
678 1.1 mrg /* Get the number of integral bits of an object of mode MODE. */
679 1.1 mrg extern CONST_MODE_IBIT unsigned char mode_ibit[NUM_MACHINE_MODES];
680 1.1 mrg #define GET_MODE_IBIT(MODE) mode_ibit[MODE]
681 1.1 mrg
682 1.1 mrg /* Get the number of fractional bits of an object of mode MODE. */
683 1.1 mrg extern CONST_MODE_FBIT unsigned char mode_fbit[NUM_MACHINE_MODES];
684 1.1 mrg #define GET_MODE_FBIT(MODE) mode_fbit[MODE]
685 1.1 mrg
686 1.1 mrg /* Get a bitmask containing 1 for all bits in a word
687 1.1 mrg that fit within mode MODE. */
688 1.1 mrg
689 1.1 mrg extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES];
690 1.1 mrg
691 1.1 mrg #define GET_MODE_MASK(MODE) mode_mask_array[MODE]
692 1.1 mrg
693 1.6 mrg /* Return the mode of the basic parts of MODE. For vector modes this is the
694 1.6 mrg mode of the vector elements. For complex modes it is the mode of the real
695 1.6 mrg and imaginary parts. For other modes it is MODE itself. */
696 1.1 mrg
697 1.9 mrg #define GET_MODE_INNER(MODE) (mode_to_inner (MODE))
698 1.1 mrg
699 1.6 mrg /* Get the size in bytes or bits of the basic parts of an
700 1.3 mrg object of mode MODE. */
701 1.1 mrg
702 1.9 mrg #define GET_MODE_UNIT_SIZE(MODE) mode_to_unit_size (MODE)
703 1.1 mrg
704 1.3 mrg #define GET_MODE_UNIT_BITSIZE(MODE) \
705 1.3 mrg ((unsigned short) (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT))
706 1.3 mrg
707 1.9 mrg #define GET_MODE_UNIT_PRECISION(MODE) (mode_to_unit_precision (MODE))
708 1.9 mrg
709 1.9 mrg /* Get the number of units in an object of mode MODE. This is 2 for
710 1.9 mrg complex modes and the number of elements for vector modes. */
711 1.9 mrg
712 1.9 mrg #if ONLY_FIXED_SIZE_MODES
713 1.9 mrg #define GET_MODE_NUNITS(MODE) (mode_to_nunits (MODE).coeffs[0])
714 1.6 mrg #else
715 1.9 mrg ALWAYS_INLINE poly_uint16
716 1.9 mrg GET_MODE_NUNITS (machine_mode mode)
717 1.9 mrg {
718 1.9 mrg return mode_to_nunits (mode);
719 1.9 mrg }
720 1.6 mrg
721 1.9 mrg template<typename T>
722 1.9 mrg ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type
723 1.9 mrg GET_MODE_NUNITS (const T &mode)
724 1.9 mrg {
725 1.9 mrg return mode_to_nunits (mode);
726 1.9 mrg }
727 1.3 mrg
728 1.9 mrg template<typename T>
729 1.9 mrg ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type
730 1.9 mrg GET_MODE_NUNITS (const T &mode)
731 1.9 mrg {
732 1.9 mrg return mode_to_nunits (mode).coeffs[0];
733 1.9 mrg }
734 1.5 mrg #endif
735 1.1 mrg
736 1.1 mrg /* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */
737 1.1 mrg
738 1.9 mrg template<typename T>
739 1.9 mrg ALWAYS_INLINE opt_mode<T>
740 1.9 mrg GET_MODE_WIDER_MODE (const T &m)
741 1.9 mrg {
742 1.9 mrg return typename opt_mode<T>::from_int (mode_wider[m]);
743 1.9 mrg }
744 1.1 mrg
745 1.3 mrg /* For scalars, this is a mode with twice the precision. For vectors,
746 1.3 mrg this is a mode with the same inner mode but with twice the elements. */
747 1.9 mrg
748 1.9 mrg template<typename T>
749 1.9 mrg ALWAYS_INLINE opt_mode<T>
750 1.9 mrg GET_MODE_2XWIDER_MODE (const T &m)
751 1.9 mrg {
752 1.9 mrg return typename opt_mode<T>::from_int (mode_2xwider[m]);
753 1.9 mrg }
754 1.1 mrg
755 1.6 mrg /* Get the complex mode from the component mode. */
756 1.6 mrg extern const unsigned char mode_complex[NUM_MACHINE_MODES];
757 1.6 mrg #define GET_MODE_COMPLEX_MODE(MODE) ((machine_mode) mode_complex[MODE])
758 1.6 mrg
759 1.9 mrg /* Represents a machine mode that must have a fixed size. The main
760 1.9 mrg use of this class is to represent the modes of objects that always
761 1.9 mrg have static storage duration, such as constant pool entries.
762 1.9 mrg (No current target supports the concept of variable-size static data.) */
763 1.9 mrg class fixed_size_mode
764 1.9 mrg {
765 1.9 mrg public:
766 1.9 mrg typedef mode_traits<fixed_size_mode>::from_int from_int;
767 1.9 mrg typedef unsigned short measurement_type;
768 1.1 mrg
769 1.9 mrg ALWAYS_INLINE fixed_size_mode () {}
770 1.9 mrg ALWAYS_INLINE fixed_size_mode (from_int m) : m_mode (machine_mode (m)) {}
771 1.9 mrg ALWAYS_INLINE fixed_size_mode (const scalar_mode &m) : m_mode (m) {}
772 1.9 mrg ALWAYS_INLINE fixed_size_mode (const scalar_int_mode &m) : m_mode (m) {}
773 1.9 mrg ALWAYS_INLINE fixed_size_mode (const scalar_float_mode &m) : m_mode (m) {}
774 1.9 mrg ALWAYS_INLINE fixed_size_mode (const scalar_mode_pod &m) : m_mode (m) {}
775 1.9 mrg ALWAYS_INLINE fixed_size_mode (const scalar_int_mode_pod &m) : m_mode (m) {}
776 1.9 mrg ALWAYS_INLINE fixed_size_mode (const complex_mode &m) : m_mode (m) {}
777 1.9 mrg ALWAYS_INLINE operator machine_mode () const { return m_mode; }
778 1.1 mrg
779 1.9 mrg static bool includes_p (machine_mode);
780 1.9 mrg
781 1.9 mrg protected:
782 1.9 mrg machine_mode m_mode;
783 1.9 mrg };
784 1.1 mrg
785 1.9 mrg /* Return true if MODE has a fixed size. */
786 1.1 mrg
787 1.9 mrg inline bool
788 1.9 mrg fixed_size_mode::includes_p (machine_mode mode)
789 1.9 mrg {
790 1.9 mrg return mode_to_bytes (mode).is_constant ();
791 1.9 mrg }
792 1.9 mrg
793 1.9 mrg /* Wrapper for mode arguments to target macros, so that if a target
794 1.9 mrg doesn't need polynomial-sized modes, its header file can continue
795 1.9 mrg to treat everything as fixed_size_mode. This should go away once
796 1.9 mrg macros are moved to target hooks. It shouldn't be used in other
797 1.9 mrg contexts. */
798 1.9 mrg #if NUM_POLY_INT_COEFFS == 1
799 1.9 mrg #define MACRO_MODE(MODE) (as_a <fixed_size_mode> (MODE))
800 1.9 mrg #else
801 1.9 mrg #define MACRO_MODE(MODE) (MODE)
802 1.9 mrg #endif
803 1.9 mrg
804 1.9 mrg extern opt_machine_mode mode_for_size (poly_uint64, enum mode_class, int);
805 1.9 mrg
806 1.9 mrg /* Return the machine mode to use for a MODE_INT of SIZE bits, if one
807 1.9 mrg exists. If LIMIT is nonzero, modes wider than MAX_FIXED_MODE_SIZE
808 1.9 mrg will not be used. */
809 1.9 mrg
810 1.9 mrg inline opt_scalar_int_mode
811 1.9 mrg int_mode_for_size (poly_uint64 size, int limit)
812 1.9 mrg {
813 1.9 mrg return dyn_cast <scalar_int_mode> (mode_for_size (size, MODE_INT, limit));
814 1.9 mrg }
815 1.9 mrg
816 1.9 mrg /* Return the machine mode to use for a MODE_FLOAT of SIZE bits, if one
817 1.9 mrg exists. */
818 1.9 mrg
819 1.9 mrg inline opt_scalar_float_mode
820 1.9 mrg float_mode_for_size (poly_uint64 size)
821 1.9 mrg {
822 1.9 mrg return dyn_cast <scalar_float_mode> (mode_for_size (size, MODE_FLOAT, 0));
823 1.9 mrg }
824 1.9 mrg
825 1.9 mrg /* Likewise for MODE_DECIMAL_FLOAT. */
826 1.9 mrg
827 1.9 mrg inline opt_scalar_float_mode
828 1.9 mrg decimal_float_mode_for_size (unsigned int size)
829 1.9 mrg {
830 1.9 mrg return dyn_cast <scalar_float_mode>
831 1.9 mrg (mode_for_size (size, MODE_DECIMAL_FLOAT, 0));
832 1.9 mrg }
833 1.1 mrg
834 1.9 mrg extern machine_mode smallest_mode_for_size (poly_uint64, enum mode_class);
835 1.1 mrg
836 1.9 mrg /* Find the narrowest integer mode that contains at least SIZE bits.
837 1.9 mrg Such a mode must exist. */
838 1.5 mrg
839 1.9 mrg inline scalar_int_mode
840 1.9 mrg smallest_int_mode_for_size (poly_uint64 size)
841 1.9 mrg {
842 1.9 mrg return as_a <scalar_int_mode> (smallest_mode_for_size (size, MODE_INT));
843 1.9 mrg }
844 1.1 mrg
845 1.9 mrg extern opt_scalar_int_mode int_mode_for_mode (machine_mode);
846 1.9 mrg extern opt_machine_mode bitwise_mode_for_mode (machine_mode);
847 1.9 mrg extern opt_machine_mode mode_for_vector (scalar_mode, poly_uint64);
848 1.9 mrg extern opt_machine_mode mode_for_int_vector (unsigned int, poly_uint64);
849 1.9 mrg
850 1.9 mrg /* Return the integer vector equivalent of MODE, if one exists. In other
851 1.9 mrg words, return the mode for an integer vector that has the same number
852 1.9 mrg of bits as MODE and the same number of elements as MODE, with the
853 1.9 mrg latter being 1 if MODE is scalar. The returned mode can be either
854 1.9 mrg an integer mode or a vector mode. */
855 1.3 mrg
856 1.9 mrg inline opt_machine_mode
857 1.9 mrg mode_for_int_vector (machine_mode mode)
858 1.9 mrg {
859 1.9 mrg return mode_for_int_vector (GET_MODE_UNIT_BITSIZE (mode),
860 1.9 mrg GET_MODE_NUNITS (mode));
861 1.9 mrg }
862 1.3 mrg
863 1.3 mrg /* A class for iterating through possible bitfield modes. */
864 1.3 mrg class bit_field_mode_iterator
865 1.3 mrg {
866 1.3 mrg public:
867 1.3 mrg bit_field_mode_iterator (HOST_WIDE_INT, HOST_WIDE_INT,
868 1.9 mrg poly_int64, poly_int64,
869 1.3 mrg unsigned int, bool);
870 1.9 mrg bool next_mode (scalar_int_mode *);
871 1.3 mrg bool prefer_smaller_modes ();
872 1.3 mrg
873 1.3 mrg private:
874 1.9 mrg opt_scalar_int_mode m_mode;
875 1.3 mrg /* We use signed values here because the bit position can be negative
876 1.3 mrg for invalid input such as gcc.dg/pr48335-8.c. */
877 1.5 mrg HOST_WIDE_INT m_bitsize;
878 1.5 mrg HOST_WIDE_INT m_bitpos;
879 1.9 mrg poly_int64 m_bitregion_start;
880 1.9 mrg poly_int64 m_bitregion_end;
881 1.5 mrg unsigned int m_align;
882 1.5 mrg bool m_volatilep;
883 1.5 mrg int m_count;
884 1.3 mrg };
885 1.3 mrg
886 1.1 mrg /* Find the best mode to use to access a bit field. */
887 1.1 mrg
888 1.9 mrg extern bool get_best_mode (int, int, poly_uint64, poly_uint64, unsigned int,
889 1.9 mrg unsigned HOST_WIDE_INT, bool, scalar_int_mode *);
890 1.1 mrg
891 1.1 mrg /* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT. */
892 1.1 mrg
893 1.8 mrg extern CONST_MODE_BASE_ALIGN unsigned short mode_base_align[NUM_MACHINE_MODES];
894 1.1 mrg
895 1.5 mrg extern unsigned get_mode_alignment (machine_mode);
896 1.1 mrg
897 1.1 mrg #define GET_MODE_ALIGNMENT(MODE) get_mode_alignment (MODE)
898 1.1 mrg
899 1.1 mrg /* For each class, get the narrowest mode in that class. */
900 1.1 mrg
901 1.1 mrg extern const unsigned char class_narrowest_mode[MAX_MODE_CLASS];
902 1.1 mrg #define GET_CLASS_NARROWEST_MODE(CLASS) \
903 1.5 mrg ((machine_mode) class_narrowest_mode[CLASS])
904 1.1 mrg
905 1.9 mrg /* The narrowest full integer mode available on the target. */
906 1.9 mrg
907 1.9 mrg #define NARROWEST_INT_MODE \
908 1.9 mrg (scalar_int_mode \
909 1.9 mrg (scalar_int_mode::from_int (class_narrowest_mode[MODE_INT])))
910 1.9 mrg
911 1.9 mrg /* Return the narrowest mode in T's class. */
912 1.9 mrg
913 1.9 mrg template<typename T>
914 1.9 mrg inline T
915 1.9 mrg get_narrowest_mode (T mode)
916 1.9 mrg {
917 1.9 mrg return typename mode_traits<T>::from_int
918 1.9 mrg (class_narrowest_mode[GET_MODE_CLASS (mode)]);
919 1.9 mrg }
920 1.9 mrg
921 1.1 mrg /* Define the integer modes whose sizes are BITS_PER_UNIT and BITS_PER_WORD
922 1.1 mrg and the mode whose class is Pmode and whose size is POINTER_SIZE. */
923 1.1 mrg
924 1.9 mrg extern scalar_int_mode byte_mode;
925 1.9 mrg extern scalar_int_mode word_mode;
926 1.9 mrg extern scalar_int_mode ptr_mode;
927 1.1 mrg
928 1.1 mrg /* Target-dependent machine mode initialization - in insn-modes.c. */
929 1.1 mrg extern void init_adjust_machine_modes (void);
930 1.1 mrg
931 1.3 mrg #define TRULY_NOOP_TRUNCATION_MODES_P(MODE1, MODE2) \
932 1.9 mrg (targetm.truly_noop_truncation (GET_MODE_PRECISION (MODE1), \
933 1.9 mrg GET_MODE_PRECISION (MODE2)))
934 1.3 mrg
935 1.9 mrg /* Return true if MODE is a scalar integer mode that fits in a
936 1.9 mrg HOST_WIDE_INT. */
937 1.9 mrg
938 1.9 mrg inline bool
939 1.9 mrg HWI_COMPUTABLE_MODE_P (machine_mode mode)
940 1.9 mrg {
941 1.9 mrg machine_mode mme = mode;
942 1.9 mrg return (SCALAR_INT_MODE_P (mme)
943 1.9 mrg && mode_to_precision (mme).coeffs[0] <= HOST_BITS_PER_WIDE_INT);
944 1.9 mrg }
945 1.9 mrg
946 1.9 mrg inline bool
947 1.9 mrg HWI_COMPUTABLE_MODE_P (scalar_int_mode mode)
948 1.9 mrg {
949 1.9 mrg return GET_MODE_PRECISION (mode) <= HOST_BITS_PER_WIDE_INT;
950 1.9 mrg }
951 1.3 mrg
952 1.6 mrg struct int_n_data_t {
953 1.5 mrg /* These parts are initailized by genmodes output */
954 1.5 mrg unsigned int bitsize;
955 1.9 mrg scalar_int_mode_pod m;
956 1.5 mrg /* RID_* is RID_INTN_BASE + index into this array */
957 1.6 mrg };
958 1.5 mrg
959 1.5 mrg /* This is also in tree.h. genmodes.c guarantees the're sorted from
960 1.5 mrg smallest bitsize to largest bitsize. */
961 1.5 mrg extern bool int_n_enabled_p[NUM_INT_N_ENTS];
962 1.5 mrg extern const int_n_data_t int_n_data[NUM_INT_N_ENTS];
963 1.5 mrg
964 1.9 mrg /* Return true if MODE has class MODE_INT, storing it as a scalar_int_mode
965 1.9 mrg in *INT_MODE if so. */
966 1.9 mrg
967 1.9 mrg template<typename T>
968 1.9 mrg inline bool
969 1.9 mrg is_int_mode (machine_mode mode, T *int_mode)
970 1.9 mrg {
971 1.9 mrg if (GET_MODE_CLASS (mode) == MODE_INT)
972 1.9 mrg {
973 1.9 mrg *int_mode = scalar_int_mode (scalar_int_mode::from_int (mode));
974 1.9 mrg return true;
975 1.9 mrg }
976 1.9 mrg return false;
977 1.9 mrg }
978 1.9 mrg
979 1.9 mrg /* Return true if MODE has class MODE_FLOAT, storing it as a
980 1.9 mrg scalar_float_mode in *FLOAT_MODE if so. */
981 1.9 mrg
982 1.9 mrg template<typename T>
983 1.9 mrg inline bool
984 1.9 mrg is_float_mode (machine_mode mode, T *float_mode)
985 1.9 mrg {
986 1.9 mrg if (GET_MODE_CLASS (mode) == MODE_FLOAT)
987 1.9 mrg {
988 1.9 mrg *float_mode = scalar_float_mode (scalar_float_mode::from_int (mode));
989 1.9 mrg return true;
990 1.9 mrg }
991 1.9 mrg return false;
992 1.9 mrg }
993 1.9 mrg
994 1.9 mrg /* Return true if MODE has class MODE_COMPLEX_INT, storing it as
995 1.9 mrg a complex_mode in *CMODE if so. */
996 1.9 mrg
997 1.9 mrg template<typename T>
998 1.9 mrg inline bool
999 1.9 mrg is_complex_int_mode (machine_mode mode, T *cmode)
1000 1.9 mrg {
1001 1.9 mrg if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
1002 1.9 mrg {
1003 1.9 mrg *cmode = complex_mode (complex_mode::from_int (mode));
1004 1.9 mrg return true;
1005 1.9 mrg }
1006 1.9 mrg return false;
1007 1.9 mrg }
1008 1.9 mrg
1009 1.9 mrg /* Return true if MODE has class MODE_COMPLEX_FLOAT, storing it as
1010 1.9 mrg a complex_mode in *CMODE if so. */
1011 1.9 mrg
1012 1.9 mrg template<typename T>
1013 1.9 mrg inline bool
1014 1.9 mrg is_complex_float_mode (machine_mode mode, T *cmode)
1015 1.9 mrg {
1016 1.9 mrg if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
1017 1.9 mrg {
1018 1.9 mrg *cmode = complex_mode (complex_mode::from_int (mode));
1019 1.9 mrg return true;
1020 1.9 mrg }
1021 1.9 mrg return false;
1022 1.9 mrg }
1023 1.9 mrg
1024 1.9 mrg /* Return true if MODE is a scalar integer mode with a precision
1025 1.9 mrg smaller than LIMIT's precision. */
1026 1.9 mrg
1027 1.9 mrg inline bool
1028 1.9 mrg is_narrower_int_mode (machine_mode mode, scalar_int_mode limit)
1029 1.9 mrg {
1030 1.9 mrg scalar_int_mode int_mode;
1031 1.9 mrg return (is_a <scalar_int_mode> (mode, &int_mode)
1032 1.9 mrg && GET_MODE_PRECISION (int_mode) < GET_MODE_PRECISION (limit));
1033 1.9 mrg }
1034 1.9 mrg
1035 1.9 mrg namespace mode_iterator
1036 1.9 mrg {
1037 1.9 mrg /* Start mode iterator *ITER at the first mode in class MCLASS, if any. */
1038 1.9 mrg
1039 1.9 mrg template<typename T>
1040 1.9 mrg inline void
1041 1.9 mrg start (opt_mode<T> *iter, enum mode_class mclass)
1042 1.9 mrg {
1043 1.9 mrg if (GET_CLASS_NARROWEST_MODE (mclass) == E_VOIDmode)
1044 1.9 mrg *iter = opt_mode<T> ();
1045 1.9 mrg else
1046 1.9 mrg *iter = as_a<T> (GET_CLASS_NARROWEST_MODE (mclass));
1047 1.9 mrg }
1048 1.9 mrg
1049 1.9 mrg inline void
1050 1.9 mrg start (machine_mode *iter, enum mode_class mclass)
1051 1.9 mrg {
1052 1.9 mrg *iter = GET_CLASS_NARROWEST_MODE (mclass);
1053 1.9 mrg }
1054 1.9 mrg
1055 1.9 mrg /* Return true if mode iterator *ITER has not reached the end. */
1056 1.9 mrg
1057 1.9 mrg template<typename T>
1058 1.9 mrg inline bool
1059 1.9 mrg iterate_p (opt_mode<T> *iter)
1060 1.9 mrg {
1061 1.9 mrg return iter->exists ();
1062 1.9 mrg }
1063 1.9 mrg
1064 1.9 mrg inline bool
1065 1.9 mrg iterate_p (machine_mode *iter)
1066 1.9 mrg {
1067 1.9 mrg return *iter != E_VOIDmode;
1068 1.9 mrg }
1069 1.9 mrg
1070 1.9 mrg /* Set mode iterator *ITER to the next widest mode in the same class,
1071 1.9 mrg if any. */
1072 1.9 mrg
1073 1.9 mrg template<typename T>
1074 1.9 mrg inline void
1075 1.9 mrg get_wider (opt_mode<T> *iter)
1076 1.9 mrg {
1077 1.9 mrg *iter = GET_MODE_WIDER_MODE (iter->require ());
1078 1.9 mrg }
1079 1.9 mrg
1080 1.9 mrg inline void
1081 1.9 mrg get_wider (machine_mode *iter)
1082 1.9 mrg {
1083 1.9 mrg *iter = GET_MODE_WIDER_MODE (*iter).else_void ();
1084 1.9 mrg }
1085 1.9 mrg
1086 1.9 mrg /* Set mode iterator *ITER to the next widest mode in the same class.
1087 1.9 mrg Such a mode is known to exist. */
1088 1.9 mrg
1089 1.9 mrg template<typename T>
1090 1.9 mrg inline void
1091 1.9 mrg get_known_wider (T *iter)
1092 1.9 mrg {
1093 1.9 mrg *iter = GET_MODE_WIDER_MODE (*iter).require ();
1094 1.9 mrg }
1095 1.9 mrg
1096 1.9 mrg /* Set mode iterator *ITER to the mode that is two times wider than the
1097 1.9 mrg current one, if such a mode exists. */
1098 1.9 mrg
1099 1.9 mrg template<typename T>
1100 1.9 mrg inline void
1101 1.9 mrg get_2xwider (opt_mode<T> *iter)
1102 1.9 mrg {
1103 1.9 mrg *iter = GET_MODE_2XWIDER_MODE (iter->require ());
1104 1.9 mrg }
1105 1.9 mrg
1106 1.9 mrg inline void
1107 1.9 mrg get_2xwider (machine_mode *iter)
1108 1.9 mrg {
1109 1.9 mrg *iter = GET_MODE_2XWIDER_MODE (*iter).else_void ();
1110 1.9 mrg }
1111 1.9 mrg }
1112 1.9 mrg
1113 1.9 mrg /* Make ITERATOR iterate over all the modes in mode class CLASS,
1114 1.9 mrg from narrowest to widest. */
1115 1.9 mrg #define FOR_EACH_MODE_IN_CLASS(ITERATOR, CLASS) \
1116 1.9 mrg for (mode_iterator::start (&(ITERATOR), CLASS); \
1117 1.9 mrg mode_iterator::iterate_p (&(ITERATOR)); \
1118 1.9 mrg mode_iterator::get_wider (&(ITERATOR)))
1119 1.9 mrg
1120 1.9 mrg /* Make ITERATOR iterate over all the modes in the range [START, END),
1121 1.9 mrg in order of increasing width. */
1122 1.9 mrg #define FOR_EACH_MODE(ITERATOR, START, END) \
1123 1.9 mrg for ((ITERATOR) = (START); \
1124 1.9 mrg (ITERATOR) != (END); \
1125 1.9 mrg mode_iterator::get_known_wider (&(ITERATOR)))
1126 1.9 mrg
1127 1.9 mrg /* Make ITERATOR iterate over START and all wider modes in the same
1128 1.9 mrg class, in order of increasing width. */
1129 1.9 mrg #define FOR_EACH_MODE_FROM(ITERATOR, START) \
1130 1.9 mrg for ((ITERATOR) = (START); \
1131 1.9 mrg mode_iterator::iterate_p (&(ITERATOR)); \
1132 1.9 mrg mode_iterator::get_wider (&(ITERATOR)))
1133 1.9 mrg
1134 1.9 mrg /* Make ITERATOR iterate over modes in the range [NARROWEST, END)
1135 1.9 mrg in order of increasing width, where NARROWEST is the narrowest mode
1136 1.9 mrg in END's class. */
1137 1.9 mrg #define FOR_EACH_MODE_UNTIL(ITERATOR, END) \
1138 1.9 mrg FOR_EACH_MODE (ITERATOR, get_narrowest_mode (END), END)
1139 1.9 mrg
1140 1.9 mrg /* Make ITERATOR iterate over modes in the same class as MODE, in order
1141 1.9 mrg of increasing width. Start at the first mode wider than START,
1142 1.9 mrg or don't iterate at all if there is no wider mode. */
1143 1.9 mrg #define FOR_EACH_WIDER_MODE(ITERATOR, START) \
1144 1.9 mrg for ((ITERATOR) = (START), mode_iterator::get_wider (&(ITERATOR)); \
1145 1.9 mrg mode_iterator::iterate_p (&(ITERATOR)); \
1146 1.9 mrg mode_iterator::get_wider (&(ITERATOR)))
1147 1.9 mrg
1148 1.9 mrg /* Make ITERATOR iterate over modes in the same class as MODE, in order
1149 1.9 mrg of increasing width, and with each mode being twice the width of the
1150 1.9 mrg previous mode. Start at the mode that is two times wider than START,
1151 1.9 mrg or don't iterate at all if there is no such mode. */
1152 1.9 mrg #define FOR_EACH_2XWIDER_MODE(ITERATOR, START) \
1153 1.9 mrg for ((ITERATOR) = (START), mode_iterator::get_2xwider (&(ITERATOR)); \
1154 1.9 mrg mode_iterator::iterate_p (&(ITERATOR)); \
1155 1.9 mrg mode_iterator::get_2xwider (&(ITERATOR)))
1156 1.9 mrg
1157 1.9 mrg template<typename T>
1158 1.9 mrg void
1159 1.9 mrg gt_ggc_mx (pod_mode<T> *)
1160 1.9 mrg {
1161 1.9 mrg }
1162 1.9 mrg
1163 1.9 mrg template<typename T>
1164 1.9 mrg void
1165 1.9 mrg gt_pch_nx (pod_mode<T> *)
1166 1.9 mrg {
1167 1.9 mrg }
1168 1.9 mrg
1169 1.9 mrg template<typename T>
1170 1.9 mrg void
1171 1.9 mrg gt_pch_nx (pod_mode<T> *, void (*) (void *, void *), void *)
1172 1.9 mrg {
1173 1.9 mrg }
1174 1.9 mrg
1175 1.1 mrg #endif /* not HAVE_MACHINE_MODES */
1176