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