Line data Source code
1 : /* Machine mode definitions for GCC; included by rtl.h and tree.h.
2 : Copyright (C) 1991-2023 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_pod mode_size[NUM_MACHINE_MODES];
26 : extern CONST_MODE_PRECISION poly_uint16_pod mode_precision[NUM_MACHINE_MODES];
27 : extern const unsigned short mode_inner[NUM_MACHINE_MODES];
28 : extern CONST_MODE_NUNITS poly_uint16_pod 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 : ALWAYS_INLINE CONSTEXPR opt_mode () : m_mode (E_VOIDmode) {}
268 : ALWAYS_INLINE CONSTEXPR opt_mode (const T &m) : m_mode (m) {}
269 : template<typename U>
270 : ALWAYS_INLINE CONSTEXPR opt_mode (const U &m) : m_mode (T (m)) {}
271 : ALWAYS_INLINE CONSTEXPR opt_mode (from_int m) : m_mode (machine_mode (m)) {}
272 :
273 : machine_mode else_void () const;
274 : machine_mode else_blk () const { return else_mode (BLKmode); }
275 : machine_mode else_mode (machine_mode) const;
276 : T require () const;
277 :
278 : bool exists () const;
279 : template<typename U> bool exists (U *) const;
280 :
281 : bool operator== (const T &m) const { return m_mode == m; }
282 : bool operator!= (const T &m) const { return m_mode != m; }
283 :
284 : private:
285 : machine_mode m_mode;
286 : };
287 :
288 : /* If the object contains a T, return its enum value, otherwise return
289 : E_VOIDmode. */
290 :
291 : template<typename T>
292 : ALWAYS_INLINE machine_mode
293 : opt_mode<T>::else_void () const
294 : {
295 : return m_mode;
296 : }
297 :
298 : /* If the T exists, return its enum value, otherwise return FALLBACK. */
299 :
300 : template<typename T>
301 : inline machine_mode
302 : opt_mode<T>::else_mode (machine_mode fallback) const
303 : {
304 : return m_mode == E_VOIDmode ? fallback : m_mode;
305 : }
306 :
307 : /* Assert that the object contains a T and return it. */
308 :
309 : template<typename T>
310 : inline T
311 : opt_mode<T>::require () const
312 : {
313 : gcc_checking_assert (m_mode != E_VOIDmode);
314 : return typename mode_traits<T>::from_int (m_mode);
315 : }
316 :
317 : /* Return true if the object contains a T rather than nothing. */
318 :
319 : template<typename T>
320 : ALWAYS_INLINE bool
321 : opt_mode<T>::exists () const
322 : {
323 : return m_mode != E_VOIDmode;
324 : }
325 :
326 : /* Return true if the object contains a T, storing it in *MODE if so. */
327 :
328 : template<typename T>
329 : template<typename U>
330 : inline bool
331 : opt_mode<T>::exists (U *mode) const
332 : {
333 : if (m_mode != E_VOIDmode)
334 : {
335 : *mode = T (typename mode_traits<T>::from_int (m_mode));
336 : return true;
337 : }
338 : return false;
339 : }
340 :
341 : /* A POD version of mode class T. */
342 :
343 : template<typename T>
344 : struct pod_mode
345 : {
346 : typedef typename mode_traits<T>::from_int from_int;
347 : typedef typename T::measurement_type measurement_type;
348 :
349 : machine_mode m_mode;
350 : ALWAYS_INLINE CONSTEXPR
351 : operator machine_mode () const { return m_mode; }
352 :
353 : ALWAYS_INLINE CONSTEXPR
354 : operator T () const { return from_int (m_mode); }
355 :
356 : ALWAYS_INLINE pod_mode &operator = (const T &m) { m_mode = m; return *this; }
357 : };
358 :
359 : /* Return true if mode M has type T. */
360 :
361 : template<typename T>
362 : inline bool
363 : is_a (machine_mode m)
364 : {
365 : return T::includes_p (m);
366 : }
367 :
368 : template<typename T, typename U>
369 : inline bool
370 : is_a (const opt_mode<U> &m)
371 : {
372 : return T::includes_p (m.else_void ());
373 : }
374 :
375 : /* Assert that mode M has type T, and return it in that form. */
376 :
377 : template<typename T>
378 : inline T
379 3765330 : as_a (machine_mode m)
380 : {
381 6814 : gcc_checking_assert (T::includes_p (m));
382 3765330 : return typename mode_traits<T>::from_int (m);
383 : }
384 :
385 : template<typename T, typename U>
386 : inline T
387 : as_a (const opt_mode<U> &m)
388 : {
389 : return as_a <T> (m.else_void ());
390 : }
391 :
392 : /* Convert M to an opt_mode<T>. */
393 :
394 : template<typename T>
395 : inline opt_mode<T>
396 : dyn_cast (machine_mode m)
397 : {
398 : if (T::includes_p (m))
399 : return T (typename mode_traits<T>::from_int (m));
400 : return opt_mode<T> ();
401 : }
402 :
403 : template<typename T, typename U>
404 : inline opt_mode<T>
405 : dyn_cast (const opt_mode<U> &m)
406 : {
407 : return dyn_cast <T> (m.else_void ());
408 : }
409 :
410 : /* Return true if mode M has type T, storing it as a T in *RESULT
411 : if so. */
412 :
413 : template<typename T, typename U>
414 : inline bool
415 : is_a (machine_mode m, U *result)
416 : {
417 : if (T::includes_p (m))
418 : {
419 : *result = T (typename mode_traits<T>::from_int (m));
420 : return true;
421 : }
422 : return false;
423 : }
424 :
425 : /* Represents a machine mode that is known to be a SCALAR_INT_MODE_P. */
426 : class scalar_int_mode
427 : {
428 : public:
429 : typedef mode_traits<scalar_int_mode>::from_int from_int;
430 : typedef unsigned short measurement_type;
431 :
432 : ALWAYS_INLINE scalar_int_mode () {}
433 :
434 : ALWAYS_INLINE CONSTEXPR
435 30966 : scalar_int_mode (from_int m) : m_mode (machine_mode (m)) {}
436 :
437 120036 : ALWAYS_INLINE CONSTEXPR operator machine_mode () const { return m_mode; }
438 :
439 : static bool includes_p (machine_mode);
440 :
441 : protected:
442 : machine_mode m_mode;
443 : };
444 :
445 : /* Return true if M is a scalar_int_mode. */
446 :
447 : inline bool
448 30966 : scalar_int_mode::includes_p (machine_mode m)
449 : {
450 30966 : return SCALAR_INT_MODE_P (m);
451 : }
452 :
453 : /* Represents a machine mode that is known to be a SCALAR_FLOAT_MODE_P. */
454 : class scalar_float_mode
455 : {
456 : public:
457 : typedef mode_traits<scalar_float_mode>::from_int from_int;
458 : typedef unsigned short measurement_type;
459 :
460 : ALWAYS_INLINE scalar_float_mode () {}
461 :
462 : ALWAYS_INLINE CONSTEXPR
463 3727550 : scalar_float_mode (from_int m) : m_mode (machine_mode (m)) {}
464 :
465 3727550 : ALWAYS_INLINE CONSTEXPR operator machine_mode () const { return m_mode; }
466 :
467 : static bool includes_p (machine_mode);
468 :
469 : protected:
470 : machine_mode m_mode;
471 : };
472 :
473 : /* Return true if M is a scalar_float_mode. */
474 :
475 : inline bool
476 3727550 : scalar_float_mode::includes_p (machine_mode m)
477 : {
478 3727550 : return SCALAR_FLOAT_MODE_P (m);
479 : }
480 :
481 : /* Represents a machine mode that is known to be scalar. */
482 : class scalar_mode
483 : {
484 : public:
485 : typedef mode_traits<scalar_mode>::from_int from_int;
486 : typedef unsigned short measurement_type;
487 :
488 : ALWAYS_INLINE scalar_mode () {}
489 :
490 : ALWAYS_INLINE CONSTEXPR
491 6814 : scalar_mode (from_int m) : m_mode (machine_mode (m)) {}
492 :
493 : ALWAYS_INLINE CONSTEXPR
494 : scalar_mode (const scalar_int_mode &m) : m_mode (m) {}
495 :
496 : ALWAYS_INLINE CONSTEXPR
497 : scalar_mode (const scalar_float_mode &m) : m_mode (m) {}
498 :
499 : ALWAYS_INLINE CONSTEXPR
500 : scalar_mode (const scalar_int_mode_pod &m) : m_mode (m) {}
501 :
502 6814 : ALWAYS_INLINE CONSTEXPR operator machine_mode () const { return m_mode; }
503 :
504 : static bool includes_p (machine_mode);
505 :
506 : protected:
507 : machine_mode m_mode;
508 : };
509 :
510 : /* Return true if M represents some kind of scalar value. */
511 :
512 : inline bool
513 6814 : scalar_mode::includes_p (machine_mode m)
514 : {
515 6814 : switch (GET_MODE_CLASS (m))
516 : {
517 : case MODE_INT:
518 : case MODE_PARTIAL_INT:
519 : case MODE_FRACT:
520 : case MODE_UFRACT:
521 : case MODE_ACCUM:
522 : case MODE_UACCUM:
523 : case MODE_FLOAT:
524 : case MODE_DECIMAL_FLOAT:
525 : return true;
526 0 : default:
527 0 : return false;
528 : }
529 : }
530 :
531 : /* Represents a machine mode that is known to be a COMPLEX_MODE_P. */
532 : class complex_mode
533 : {
534 : public:
535 : typedef mode_traits<complex_mode>::from_int from_int;
536 : typedef unsigned short measurement_type;
537 :
538 : ALWAYS_INLINE complex_mode () {}
539 :
540 : ALWAYS_INLINE CONSTEXPR
541 : complex_mode (from_int m) : m_mode (machine_mode (m)) {}
542 :
543 : ALWAYS_INLINE CONSTEXPR operator machine_mode () const { return m_mode; }
544 :
545 : static bool includes_p (machine_mode);
546 :
547 : protected:
548 : machine_mode m_mode;
549 : };
550 :
551 : /* Return true if M is a complex_mode. */
552 :
553 : inline bool
554 : complex_mode::includes_p (machine_mode m)
555 : {
556 : return COMPLEX_MODE_P (m);
557 : }
558 :
559 : /* Return the base GET_MODE_SIZE value for MODE. */
560 :
561 : ALWAYS_INLINE poly_uint16
562 38596 : mode_to_bytes (machine_mode mode)
563 : {
564 : #if GCC_VERSION >= 4001
565 38596 : return (__builtin_constant_p (mode)
566 38596 : ? mode_size_inline (mode) : mode_size[mode]);
567 : #else
568 : return mode_size[mode];
569 : #endif
570 : }
571 :
572 : /* Return the base GET_MODE_BITSIZE value for MODE. */
573 :
574 : ALWAYS_INLINE poly_uint16
575 7630 : mode_to_bits (machine_mode mode)
576 : {
577 7630 : return mode_to_bytes (mode) * BITS_PER_UNIT;
578 : }
579 :
580 : /* Return the base GET_MODE_PRECISION value for MODE. */
581 :
582 : ALWAYS_INLINE poly_uint16
583 : mode_to_precision (machine_mode mode)
584 : {
585 : return mode_precision[mode];
586 : }
587 :
588 : /* Return the base GET_MODE_INNER value for MODE. */
589 :
590 : ALWAYS_INLINE scalar_mode
591 3727518 : mode_to_inner (machine_mode mode)
592 : {
593 : #if GCC_VERSION >= 4001
594 3727518 : return scalar_mode::from_int (__builtin_constant_p (mode)
595 0 : ? mode_inner_inline (mode)
596 3727518 : : mode_inner[mode]);
597 : #else
598 : return scalar_mode::from_int (mode_inner[mode]);
599 : #endif
600 : }
601 :
602 : /* Return the base GET_MODE_UNIT_SIZE value for MODE. */
603 :
604 : ALWAYS_INLINE unsigned char
605 : mode_to_unit_size (machine_mode mode)
606 : {
607 : #if GCC_VERSION >= 4001
608 : return (__builtin_constant_p (mode)
609 : ? mode_unit_size_inline (mode) : mode_unit_size[mode]);
610 : #else
611 : return mode_unit_size[mode];
612 : #endif
613 : }
614 :
615 : /* Return the base GET_MODE_UNIT_PRECISION value for MODE. */
616 :
617 : ALWAYS_INLINE unsigned short
618 : mode_to_unit_precision (machine_mode mode)
619 : {
620 : #if GCC_VERSION >= 4001
621 : return (__builtin_constant_p (mode)
622 : ? mode_unit_precision_inline (mode) : mode_unit_precision[mode]);
623 : #else
624 : return mode_unit_precision[mode];
625 : #endif
626 : }
627 :
628 : /* Return the base GET_MODE_NUNITS value for MODE. */
629 :
630 : ALWAYS_INLINE poly_uint16
631 : mode_to_nunits (machine_mode mode)
632 : {
633 : #if GCC_VERSION >= 4001
634 : return (__builtin_constant_p (mode)
635 : ? mode_nunits_inline (mode) : mode_nunits[mode]);
636 : #else
637 : return mode_nunits[mode];
638 : #endif
639 : }
640 :
641 : /* Get the size in bytes of an object of mode MODE. */
642 :
643 : #if ONLY_FIXED_SIZE_MODES
644 : #define GET_MODE_SIZE(MODE) ((unsigned short) mode_to_bytes (MODE).coeffs[0])
645 : #else
646 : ALWAYS_INLINE poly_uint16
647 : GET_MODE_SIZE (machine_mode mode)
648 : {
649 : return mode_to_bytes (mode);
650 : }
651 :
652 : template<typename T>
653 : ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type
654 : GET_MODE_SIZE (const T &mode)
655 : {
656 : return mode_to_bytes (mode);
657 : }
658 :
659 : template<typename T>
660 : ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type
661 30966 : GET_MODE_SIZE (const T &mode)
662 : {
663 61932 : return mode_to_bytes (mode).coeffs[0];
664 : }
665 : #endif
666 :
667 : /* Get the size in bits of an object of mode MODE. */
668 :
669 : #if ONLY_FIXED_SIZE_MODES
670 : #define GET_MODE_BITSIZE(MODE) ((unsigned short) mode_to_bits (MODE).coeffs[0])
671 : #else
672 : ALWAYS_INLINE poly_uint16
673 : GET_MODE_BITSIZE (machine_mode mode)
674 : {
675 : return mode_to_bits (mode);
676 : }
677 :
678 : template<typename T>
679 : ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type
680 : GET_MODE_BITSIZE (const T &mode)
681 : {
682 : return mode_to_bits (mode);
683 : }
684 :
685 : template<typename T>
686 : ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type
687 7630 : GET_MODE_BITSIZE (const T &mode)
688 : {
689 15260 : return mode_to_bits (mode).coeffs[0];
690 : }
691 : #endif
692 :
693 : /* Get the number of value bits of an object of mode MODE. */
694 :
695 : #if ONLY_FIXED_SIZE_MODES
696 : #define GET_MODE_PRECISION(MODE) \
697 : ((unsigned short) mode_to_precision (MODE).coeffs[0])
698 : #else
699 : ALWAYS_INLINE poly_uint16
700 : GET_MODE_PRECISION (machine_mode mode)
701 : {
702 : return mode_to_precision (mode);
703 : }
704 :
705 : template<typename T>
706 : ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type
707 : GET_MODE_PRECISION (const T &mode)
708 : {
709 : return mode_to_precision (mode);
710 : }
711 :
712 : template<typename T>
713 : ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type
714 : GET_MODE_PRECISION (const T &mode)
715 : {
716 : return mode_to_precision (mode).coeffs[0];
717 : }
718 : #endif
719 :
720 : /* Get the number of integral bits of an object of mode MODE. */
721 : extern CONST_MODE_IBIT unsigned char mode_ibit[NUM_MACHINE_MODES];
722 : #define GET_MODE_IBIT(MODE) mode_ibit[MODE]
723 :
724 : /* Get the number of fractional bits of an object of mode MODE. */
725 : extern CONST_MODE_FBIT unsigned char mode_fbit[NUM_MACHINE_MODES];
726 : #define GET_MODE_FBIT(MODE) mode_fbit[MODE]
727 :
728 : /* Get a bitmask containing 1 for all bits in a word
729 : that fit within mode MODE. */
730 :
731 : extern CONST_MODE_MASK unsigned HOST_WIDE_INT
732 : mode_mask_array[NUM_MACHINE_MODES];
733 :
734 : #define GET_MODE_MASK(MODE) mode_mask_array[MODE]
735 :
736 : /* Return the mode of the basic parts of MODE. For vector modes this is the
737 : mode of the vector elements. For complex modes it is the mode of the real
738 : and imaginary parts. For other modes it is MODE itself. */
739 :
740 : #define GET_MODE_INNER(MODE) (mode_to_inner (MODE))
741 :
742 : /* Get the size in bytes or bits of the basic parts of an
743 : object of mode MODE. */
744 :
745 : #define GET_MODE_UNIT_SIZE(MODE) mode_to_unit_size (MODE)
746 :
747 : #define GET_MODE_UNIT_BITSIZE(MODE) \
748 : ((unsigned short) (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT))
749 :
750 : #define GET_MODE_UNIT_PRECISION(MODE) (mode_to_unit_precision (MODE))
751 :
752 : /* Get the number of units in an object of mode MODE. This is 2 for
753 : complex modes and the number of elements for vector modes. */
754 :
755 : #if ONLY_FIXED_SIZE_MODES
756 : #define GET_MODE_NUNITS(MODE) (mode_to_nunits (MODE).coeffs[0])
757 : #else
758 : ALWAYS_INLINE poly_uint16
759 : GET_MODE_NUNITS (machine_mode mode)
760 : {
761 : return mode_to_nunits (mode);
762 : }
763 :
764 : template<typename T>
765 : ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type
766 : GET_MODE_NUNITS (const T &mode)
767 : {
768 : return mode_to_nunits (mode);
769 : }
770 :
771 : template<typename T>
772 : ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type
773 : GET_MODE_NUNITS (const T &mode)
774 : {
775 : return mode_to_nunits (mode).coeffs[0];
776 : }
777 : #endif
778 :
779 : /* Get the next natural mode (not narrower, eg, QI -> HI -> SI -> DI -> TI
780 : or HF -> BF -> SF -> DF -> XF -> TF). */
781 :
782 : template<typename T>
783 : ALWAYS_INLINE opt_mode<T>
784 : GET_MODE_NEXT_MODE (const T &m)
785 : {
786 : return typename opt_mode<T>::from_int (mode_next[m]);
787 : }
788 :
789 : /* Get the next wider mode (eg, QI -> HI -> SI -> DI -> TI
790 : or { HF, BF } -> SF -> DF -> XF -> TF).
791 : This is similar to GET_MODE_NEXT_MODE, but while GET_MODE_NEXT_MODE
792 : can include mode that have the same precision (e.g.
793 : GET_MODE_NEXT_MODE (HFmode) can be BFmode even when both have the same
794 : precision), this one will skip those. And always VOIDmode for
795 : modes whose class is !CLASS_HAS_WIDER_MODES_P. */
796 :
797 : template<typename T>
798 : ALWAYS_INLINE opt_mode<T>
799 : GET_MODE_WIDER_MODE (const T &m)
800 : {
801 : return typename opt_mode<T>::from_int (mode_wider[m]);
802 : }
803 :
804 : /* For scalars, this is a mode with twice the precision. For vectors,
805 : this is a mode with the same inner mode but with twice the elements. */
806 :
807 : template<typename T>
808 : ALWAYS_INLINE opt_mode<T>
809 : GET_MODE_2XWIDER_MODE (const T &m)
810 : {
811 : return typename opt_mode<T>::from_int (mode_2xwider[m]);
812 : }
813 :
814 : /* Get the complex mode from the component mode. */
815 : extern const unsigned short mode_complex[NUM_MACHINE_MODES];
816 : #define GET_MODE_COMPLEX_MODE(MODE) ((machine_mode) mode_complex[MODE])
817 :
818 : /* Represents a machine mode that must have a fixed size. The main
819 : use of this class is to represent the modes of objects that always
820 : have static storage duration, such as constant pool entries.
821 : (No current target supports the concept of variable-size static data.) */
822 : class fixed_size_mode
823 : {
824 : public:
825 : typedef mode_traits<fixed_size_mode>::from_int from_int;
826 : typedef unsigned short measurement_type;
827 :
828 : ALWAYS_INLINE fixed_size_mode () {}
829 :
830 : ALWAYS_INLINE CONSTEXPR
831 : fixed_size_mode (from_int m) : m_mode (machine_mode (m)) {}
832 :
833 : ALWAYS_INLINE CONSTEXPR
834 : fixed_size_mode (const scalar_mode &m) : m_mode (m) {}
835 :
836 : ALWAYS_INLINE CONSTEXPR
837 : fixed_size_mode (const scalar_int_mode &m) : m_mode (m) {}
838 :
839 : ALWAYS_INLINE CONSTEXPR
840 : fixed_size_mode (const scalar_float_mode &m) : m_mode (m) {}
841 :
842 : ALWAYS_INLINE CONSTEXPR
843 : fixed_size_mode (const scalar_mode_pod &m) : m_mode (m) {}
844 :
845 : ALWAYS_INLINE CONSTEXPR
846 : fixed_size_mode (const scalar_int_mode_pod &m) : m_mode (m) {}
847 :
848 : ALWAYS_INLINE CONSTEXPR
849 : fixed_size_mode (const complex_mode &m) : m_mode (m) {}
850 :
851 : ALWAYS_INLINE CONSTEXPR operator machine_mode () const { return m_mode; }
852 :
853 : static bool includes_p (machine_mode);
854 :
855 : protected:
856 : machine_mode m_mode;
857 : };
858 :
859 : /* Return true if MODE has a fixed size. */
860 :
861 : inline bool
862 : fixed_size_mode::includes_p (machine_mode mode)
863 : {
864 : return mode_to_bytes (mode).is_constant ();
865 : }
866 :
867 : /* Wrapper for mode arguments to target macros, so that if a target
868 : doesn't need polynomial-sized modes, its header file can continue
869 : to treat everything as fixed_size_mode. This should go away once
870 : macros are moved to target hooks. It shouldn't be used in other
871 : contexts. */
872 : #if NUM_POLY_INT_COEFFS == 1
873 : #define MACRO_MODE(MODE) (as_a <fixed_size_mode> (MODE))
874 : #else
875 : #define MACRO_MODE(MODE) (MODE)
876 : #endif
877 :
878 : extern opt_machine_mode mode_for_size (poly_uint64, enum mode_class, int);
879 :
880 : /* Return the machine mode to use for a MODE_INT of SIZE bits, if one
881 : exists. If LIMIT is nonzero, modes wider than MAX_FIXED_MODE_SIZE
882 : will not be used. */
883 :
884 : inline opt_scalar_int_mode
885 : int_mode_for_size (poly_uint64 size, int limit)
886 : {
887 : return dyn_cast <scalar_int_mode> (mode_for_size (size, MODE_INT, limit));
888 : }
889 :
890 : /* Return the machine mode to use for a MODE_FLOAT of SIZE bits, if one
891 : exists. */
892 :
893 : inline opt_scalar_float_mode
894 : float_mode_for_size (poly_uint64 size)
895 : {
896 : return dyn_cast <scalar_float_mode> (mode_for_size (size, MODE_FLOAT, 0));
897 : }
898 :
899 : /* Likewise for MODE_DECIMAL_FLOAT. */
900 :
901 : inline opt_scalar_float_mode
902 : decimal_float_mode_for_size (unsigned int size)
903 : {
904 : return dyn_cast <scalar_float_mode>
905 : (mode_for_size (size, MODE_DECIMAL_FLOAT, 0));
906 : }
907 :
908 : extern machine_mode smallest_mode_for_size (poly_uint64, enum mode_class);
909 :
910 : /* Find the narrowest integer mode that contains at least SIZE bits.
911 : Such a mode must exist. */
912 :
913 : inline scalar_int_mode
914 : smallest_int_mode_for_size (poly_uint64 size)
915 : {
916 : return as_a <scalar_int_mode> (smallest_mode_for_size (size, MODE_INT));
917 : }
918 :
919 : extern opt_scalar_int_mode int_mode_for_mode (machine_mode);
920 : extern opt_machine_mode bitwise_mode_for_mode (machine_mode);
921 : extern opt_machine_mode mode_for_vector (scalar_mode, poly_uint64);
922 : extern opt_machine_mode related_vector_mode (machine_mode, scalar_mode,
923 : poly_uint64 = 0);
924 : extern opt_machine_mode related_int_vector_mode (machine_mode);
925 :
926 : /* A class for iterating through possible bitfield modes. */
927 : class bit_field_mode_iterator
928 : {
929 : public:
930 : bit_field_mode_iterator (HOST_WIDE_INT, HOST_WIDE_INT,
931 : poly_int64, poly_int64,
932 : unsigned int, bool);
933 : bool next_mode (scalar_int_mode *);
934 : bool prefer_smaller_modes ();
935 :
936 : private:
937 : opt_scalar_int_mode m_mode;
938 : /* We use signed values here because the bit position can be negative
939 : for invalid input such as gcc.dg/pr48335-8.c. */
940 : HOST_WIDE_INT m_bitsize;
941 : HOST_WIDE_INT m_bitpos;
942 : poly_int64 m_bitregion_start;
943 : poly_int64 m_bitregion_end;
944 : unsigned int m_align;
945 : bool m_volatilep;
946 : int m_count;
947 : };
948 :
949 : /* Find the best mode to use to access a bit field. */
950 :
951 : extern bool get_best_mode (int, int, poly_uint64, poly_uint64, unsigned int,
952 : unsigned HOST_WIDE_INT, bool, scalar_int_mode *);
953 :
954 : /* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT. */
955 :
956 : extern CONST_MODE_BASE_ALIGN unsigned short mode_base_align[NUM_MACHINE_MODES];
957 :
958 : extern unsigned get_mode_alignment (machine_mode);
959 :
960 : #define GET_MODE_ALIGNMENT(MODE) get_mode_alignment (MODE)
961 :
962 : /* For each class, get the narrowest mode in that class. */
963 :
964 : extern const unsigned short class_narrowest_mode[MAX_MODE_CLASS];
965 : #define GET_CLASS_NARROWEST_MODE(CLASS) \
966 : ((machine_mode) class_narrowest_mode[CLASS])
967 :
968 : /* The narrowest full integer mode available on the target. */
969 :
970 : #define NARROWEST_INT_MODE \
971 : (scalar_int_mode \
972 : (scalar_int_mode::from_int (class_narrowest_mode[MODE_INT])))
973 :
974 : /* Return the narrowest mode in T's class. */
975 :
976 : template<typename T>
977 : inline T
978 : get_narrowest_mode (T mode)
979 : {
980 : return typename mode_traits<T>::from_int
981 : (class_narrowest_mode[GET_MODE_CLASS (mode)]);
982 : }
983 :
984 : /* Define the integer modes whose sizes are BITS_PER_UNIT and BITS_PER_WORD
985 : and the mode whose class is Pmode and whose size is POINTER_SIZE. */
986 :
987 : extern scalar_int_mode byte_mode;
988 : extern scalar_int_mode word_mode;
989 : extern scalar_int_mode ptr_mode;
990 :
991 : /* Target-dependent machine mode initialization - in insn-modes.cc. */
992 : extern void init_adjust_machine_modes (void);
993 :
994 : #define TRULY_NOOP_TRUNCATION_MODES_P(MODE1, MODE2) \
995 : (targetm.truly_noop_truncation (GET_MODE_PRECISION (MODE1), \
996 : GET_MODE_PRECISION (MODE2)))
997 :
998 : /* Return true if MODE is a scalar integer mode that fits in a
999 : HOST_WIDE_INT. */
1000 :
1001 : inline bool
1002 : HWI_COMPUTABLE_MODE_P (machine_mode mode)
1003 : {
1004 : machine_mode mme = mode;
1005 : return (SCALAR_INT_MODE_P (mme)
1006 : && mode_to_precision (mme).coeffs[0] <= HOST_BITS_PER_WIDE_INT);
1007 : }
1008 :
1009 : inline bool
1010 : HWI_COMPUTABLE_MODE_P (scalar_int_mode mode)
1011 : {
1012 : return GET_MODE_PRECISION (mode) <= HOST_BITS_PER_WIDE_INT;
1013 : }
1014 :
1015 : struct int_n_data_t {
1016 : /* These parts are initailized by genmodes output */
1017 : unsigned int bitsize;
1018 : scalar_int_mode_pod m;
1019 : /* RID_* is RID_INTN_BASE + index into this array */
1020 : };
1021 :
1022 : /* This is also in tree.h. genmodes.cc guarantees the're sorted from
1023 : smallest bitsize to largest bitsize. */
1024 : extern bool int_n_enabled_p[NUM_INT_N_ENTS];
1025 : extern const int_n_data_t int_n_data[NUM_INT_N_ENTS];
1026 :
1027 : /* Return true if MODE has class MODE_INT, storing it as a scalar_int_mode
1028 : in *INT_MODE if so. */
1029 :
1030 : template<typename T>
1031 : inline bool
1032 : is_int_mode (machine_mode mode, T *int_mode)
1033 : {
1034 : if (GET_MODE_CLASS (mode) == MODE_INT)
1035 : {
1036 : *int_mode = scalar_int_mode (scalar_int_mode::from_int (mode));
1037 : return true;
1038 : }
1039 : return false;
1040 : }
1041 :
1042 : /* Return true if MODE has class MODE_FLOAT, storing it as a
1043 : scalar_float_mode in *FLOAT_MODE if so. */
1044 :
1045 : template<typename T>
1046 : inline bool
1047 : is_float_mode (machine_mode mode, T *float_mode)
1048 : {
1049 : if (GET_MODE_CLASS (mode) == MODE_FLOAT)
1050 : {
1051 : *float_mode = scalar_float_mode (scalar_float_mode::from_int (mode));
1052 : return true;
1053 : }
1054 : return false;
1055 : }
1056 :
1057 : /* Return true if MODE has class MODE_COMPLEX_INT, storing it as
1058 : a complex_mode in *CMODE if so. */
1059 :
1060 : template<typename T>
1061 : inline bool
1062 : is_complex_int_mode (machine_mode mode, T *cmode)
1063 : {
1064 : if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
1065 : {
1066 : *cmode = complex_mode (complex_mode::from_int (mode));
1067 : return true;
1068 : }
1069 : return false;
1070 : }
1071 :
1072 : /* Return true if MODE has class MODE_COMPLEX_FLOAT, storing it as
1073 : a complex_mode in *CMODE if so. */
1074 :
1075 : template<typename T>
1076 : inline bool
1077 : is_complex_float_mode (machine_mode mode, T *cmode)
1078 : {
1079 : if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
1080 : {
1081 : *cmode = complex_mode (complex_mode::from_int (mode));
1082 : return true;
1083 : }
1084 : return false;
1085 : }
1086 :
1087 : /* Return true if MODE is a scalar integer mode with a precision
1088 : smaller than LIMIT's precision. */
1089 :
1090 : inline bool
1091 : is_narrower_int_mode (machine_mode mode, scalar_int_mode limit)
1092 : {
1093 : scalar_int_mode int_mode;
1094 : return (is_a <scalar_int_mode> (mode, &int_mode)
1095 : && GET_MODE_PRECISION (int_mode) < GET_MODE_PRECISION (limit));
1096 : }
1097 :
1098 : namespace mode_iterator
1099 : {
1100 : /* Start mode iterator *ITER at the first mode in class MCLASS, if any. */
1101 :
1102 : template<typename T>
1103 : inline void
1104 : start (opt_mode<T> *iter, enum mode_class mclass)
1105 : {
1106 : if (GET_CLASS_NARROWEST_MODE (mclass) == E_VOIDmode)
1107 : *iter = opt_mode<T> ();
1108 : else
1109 : *iter = as_a<T> (GET_CLASS_NARROWEST_MODE (mclass));
1110 : }
1111 :
1112 : inline void
1113 : start (machine_mode *iter, enum mode_class mclass)
1114 : {
1115 : *iter = GET_CLASS_NARROWEST_MODE (mclass);
1116 : }
1117 :
1118 : /* Return true if mode iterator *ITER has not reached the end. */
1119 :
1120 : template<typename T>
1121 : inline bool
1122 : iterate_p (opt_mode<T> *iter)
1123 : {
1124 : return iter->exists ();
1125 : }
1126 :
1127 : inline bool
1128 : iterate_p (machine_mode *iter)
1129 : {
1130 : return *iter != E_VOIDmode;
1131 : }
1132 :
1133 : /* Set mode iterator *ITER to the next mode in the same class,
1134 : if any. */
1135 :
1136 : template<typename T>
1137 : inline void
1138 : get_next (opt_mode<T> *iter)
1139 : {
1140 : *iter = GET_MODE_NEXT_MODE (iter->require ());
1141 : }
1142 :
1143 : inline void
1144 : get_next (machine_mode *iter)
1145 : {
1146 : *iter = GET_MODE_NEXT_MODE (*iter).else_void ();
1147 : }
1148 :
1149 : /* Set mode iterator *ITER to the next mode in the same class.
1150 : Such a mode is known to exist. */
1151 :
1152 : template<typename T>
1153 : inline void
1154 : get_known_next (T *iter)
1155 : {
1156 : *iter = GET_MODE_NEXT_MODE (*iter).require ();
1157 : }
1158 :
1159 : /* Set mode iterator *ITER to the next wider mode in the same class,
1160 : if any. */
1161 :
1162 : template<typename T>
1163 : inline void
1164 : get_wider (opt_mode<T> *iter)
1165 : {
1166 : *iter = GET_MODE_WIDER_MODE (iter->require ());
1167 : }
1168 :
1169 : inline void
1170 : get_wider (machine_mode *iter)
1171 : {
1172 : *iter = GET_MODE_WIDER_MODE (*iter).else_void ();
1173 : }
1174 :
1175 : /* Set mode iterator *ITER to the next wider mode in the same class.
1176 : Such a mode is known to exist. */
1177 :
1178 : template<typename T>
1179 : inline void
1180 : get_known_wider (T *iter)
1181 : {
1182 : *iter = GET_MODE_WIDER_MODE (*iter).require ();
1183 : }
1184 :
1185 : /* Set mode iterator *ITER to the mode that is two times wider than the
1186 : current one, if such a mode exists. */
1187 :
1188 : template<typename T>
1189 : inline void
1190 : get_2xwider (opt_mode<T> *iter)
1191 : {
1192 : *iter = GET_MODE_2XWIDER_MODE (iter->require ());
1193 : }
1194 :
1195 : inline void
1196 : get_2xwider (machine_mode *iter)
1197 : {
1198 : *iter = GET_MODE_2XWIDER_MODE (*iter).else_void ();
1199 : }
1200 : }
1201 :
1202 : /* Make ITERATOR iterate over all the modes in mode class CLASS,
1203 : from narrowest to widest. */
1204 : #define FOR_EACH_MODE_IN_CLASS(ITERATOR, CLASS) \
1205 : for (mode_iterator::start (&(ITERATOR), CLASS); \
1206 : mode_iterator::iterate_p (&(ITERATOR)); \
1207 : mode_iterator::get_next (&(ITERATOR)))
1208 :
1209 : /* Make ITERATOR iterate over all the modes in the range [START, END),
1210 : in order of increasing width. */
1211 : #define FOR_EACH_MODE(ITERATOR, START, END) \
1212 : for ((ITERATOR) = (START); \
1213 : (ITERATOR) != (END); \
1214 : mode_iterator::get_known_next (&(ITERATOR)))
1215 :
1216 : /* Make ITERATOR iterate over START and all non-narrower modes in the same
1217 : class, in order of increasing width. */
1218 : #define FOR_EACH_MODE_FROM(ITERATOR, START) \
1219 : for ((ITERATOR) = (START); \
1220 : mode_iterator::iterate_p (&(ITERATOR)); \
1221 : mode_iterator::get_next (&(ITERATOR)))
1222 :
1223 : /* Make ITERATOR iterate over START and all wider modes in the same
1224 : class, in order of strictly increasing width. */
1225 : #define FOR_EACH_WIDER_MODE_FROM(ITERATOR, START) \
1226 : for ((ITERATOR) = (START); \
1227 : mode_iterator::iterate_p (&(ITERATOR)); \
1228 : mode_iterator::get_wider (&(ITERATOR)))
1229 :
1230 : /* Make ITERATOR iterate over modes in the range [NARROWEST, END)
1231 : in order of increasing width, where NARROWEST is the narrowest mode
1232 : in END's class. */
1233 : #define FOR_EACH_MODE_UNTIL(ITERATOR, END) \
1234 : FOR_EACH_MODE (ITERATOR, get_narrowest_mode (END), END)
1235 :
1236 : /* Make ITERATOR iterate over modes in the same class as MODE, in order
1237 : of non-decreasing width. Start at next such mode after START,
1238 : or don't iterate at all if there is no such mode. */
1239 : #define FOR_EACH_NEXT_MODE(ITERATOR, START) \
1240 : for ((ITERATOR) = (START), mode_iterator::get_next (&(ITERATOR)); \
1241 : mode_iterator::iterate_p (&(ITERATOR)); \
1242 : mode_iterator::get_next (&(ITERATOR)))
1243 :
1244 : /* Make ITERATOR iterate over modes in the same class as MODE, in order
1245 : of increasing width. Start at the first mode wider than START,
1246 : or don't iterate at all if there is no wider mode. */
1247 : #define FOR_EACH_WIDER_MODE(ITERATOR, START) \
1248 : for ((ITERATOR) = (START), mode_iterator::get_wider (&(ITERATOR)); \
1249 : mode_iterator::iterate_p (&(ITERATOR)); \
1250 : mode_iterator::get_wider (&(ITERATOR)))
1251 :
1252 : /* Make ITERATOR iterate over modes in the same class as MODE, in order
1253 : of increasing width, and with each mode being twice the width of the
1254 : previous mode. Start at the mode that is two times wider than START,
1255 : or don't iterate at all if there is no such mode. */
1256 : #define FOR_EACH_2XWIDER_MODE(ITERATOR, START) \
1257 : for ((ITERATOR) = (START), mode_iterator::get_2xwider (&(ITERATOR)); \
1258 : mode_iterator::iterate_p (&(ITERATOR)); \
1259 : mode_iterator::get_2xwider (&(ITERATOR)))
1260 :
1261 : template<typename T>
1262 : void
1263 : gt_ggc_mx (pod_mode<T> *)
1264 : {
1265 : }
1266 :
1267 : template<typename T>
1268 : void
1269 : gt_pch_nx (pod_mode<T> *)
1270 : {
1271 : }
1272 :
1273 : template<typename T>
1274 : void
1275 : gt_pch_nx (pod_mode<T> *, gt_pointer_operator, void *)
1276 : {
1277 : }
1278 :
1279 : #endif /* not HAVE_MACHINE_MODES */
|