1 /* Machine mode definitions for GCC; included by rtl.h and tree.h.
2 Copyright (C) 1991-2025 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
20 #ifndef HAVE_MACHINE_MODES
21 #define HAVE_MACHINE_MODES
23 typedef opt_mode
<machine_mode
> opt_machine_mode
;
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
];
38 /* For use by the machmode support code only.
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:
45 return typename mode_traits<T>::from_int (mode);
47 when returning a T and:
49 res = T (typename mode_traits<T>::from_int (mode));
51 when assigning to a value RES that must be assignment-compatible
52 with (but possibly not the same as) T. */
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
58 typedef machine_mode from_int
;
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
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
};
74 struct mode_traits
<machine_mode
>
76 /* machine_mode itself needs no conversion. */
77 typedef machine_mode from_int
;
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
85 #define ONLY_FIXED_SIZE_MODES 0
88 /* Get the name of mode MODE as a string. */
90 extern const char * const mode_name
[NUM_MACHINE_MODES
];
91 #define GET_MODE_NAME(MODE) mode_name[MODE]
95 #include "mode-classes.def"
96 #define DEF_MODE_CLASS(M) M
97 enum mode_class
{ MODE_CLASSES
, MAX_MODE_CLASS
};
101 /* Get the general kind of object that mode MODE represents
102 (integer, floating, complex, etc.) */
104 extern const unsigned char mode_class
[NUM_MACHINE_MODES
];
105 #define GET_MODE_CLASS(MODE) ((enum mode_class) mode_class[MODE])
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)
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)
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)
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)
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)
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)
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)
151 /* Nonzero if MODE is a scalar fract mode. */
152 #define SCALAR_FRACT_MODE_P(MODE) \
153 (GET_MODE_CLASS (MODE) == MODE_FRACT)
155 /* Nonzero if MODE is a scalar ufract mode. */
156 #define SCALAR_UFRACT_MODE_P(MODE) \
157 (GET_MODE_CLASS (MODE) == MODE_UFRACT)
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))
163 /* Nonzero if MODE is a scalar accum mode. */
164 #define SCALAR_ACCUM_MODE_P(MODE) \
165 (GET_MODE_CLASS (MODE) == MODE_ACCUM)
167 /* Nonzero if MODE is a scalar uaccum mode. */
168 #define SCALAR_UACCUM_MODE_P(MODE) \
169 (GET_MODE_CLASS (MODE) == MODE_UACCUM)
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))
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))
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))
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))
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)
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)
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))
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)
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)
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))
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))
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))
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))
229 /* Nonzero if MODE is opaque. */
230 #define OPAQUE_MODE_P(MODE) \
231 (GET_MODE_CLASS (MODE) == MODE_OPAQUE)
233 /* Nonzero if CLASS modes can be widened. */
234 #define CLASS_HAS_WIDER_MODES_P(CLASS) \
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)
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 +------------------------+-------+
258 #define MACHINE_MODE_BITSIZE 16
260 /* An optional T (i.e. a T or nothing), where T is some form of mode class. */
265 enum from_int
{ dummy
= MAX_MACHINE_MODE
};
267 ALWAYS_INLINE CONSTEXPR
opt_mode () : m_mode (E_VOIDmode
) {}
268 ALWAYS_INLINE CONSTEXPR
opt_mode (const T
&m
) : m_mode (m
) {}
270 ALWAYS_INLINE CONSTEXPR
opt_mode (const U
&m
) : m_mode (T (m
)) {}
272 ALWAYS_INLINE CONSTEXPR
opt_mode (const opt_mode
<U
> &);
273 ALWAYS_INLINE CONSTEXPR
opt_mode (from_int m
) : m_mode (machine_mode (m
)) {}
275 machine_mode
else_void () const;
276 machine_mode
else_blk () const { return else_mode (BLKmode
); }
277 machine_mode
else_mode (machine_mode
) const;
280 bool exists () const;
281 template<typename U
> bool exists (U
*) const;
283 bool operator== (const T
&m
) const { return m_mode
== m
; }
284 bool operator!= (const T
&m
) const { return m_mode
!= m
; }
292 ALWAYS_INLINE CONSTEXPR
293 opt_mode
<T
>::opt_mode (const opt_mode
<U
> &m
)
294 : m_mode (m
.exists () ? T (m
.require ()) : E_VOIDmode
)
298 /* If the object contains a T, return its enum value, otherwise return
302 ALWAYS_INLINE machine_mode
303 opt_mode
<T
>::else_void () const
308 /* If the T exists, return its enum value, otherwise return FALLBACK. */
312 opt_mode
<T
>::else_mode (machine_mode fallback
) const
314 return m_mode
== E_VOIDmode
? fallback
: m_mode
;
317 /* Assert that the object contains a T and return it. */
321 opt_mode
<T
>::require () const
323 gcc_checking_assert (m_mode
!= E_VOIDmode
);
324 return typename mode_traits
<T
>::from_int (m_mode
);
327 /* Return true if the object contains a T rather than nothing. */
331 opt_mode
<T
>::exists () const
333 return m_mode
!= E_VOIDmode
;
336 /* Return true if the object contains a T, storing it in *MODE if so. */
341 opt_mode
<T
>::exists (U
*mode
) const
343 if (m_mode
!= E_VOIDmode
)
345 *mode
= T (typename mode_traits
<T
>::from_int (m_mode
));
351 /* A POD version of mode class T. */
356 typedef typename mode_traits
<T
>::from_int from_int
;
357 typedef typename
T::measurement_type measurement_type
;
360 ALWAYS_INLINE CONSTEXPR
361 operator machine_mode () const { return m_mode
; }
363 ALWAYS_INLINE CONSTEXPR
364 operator T () const { return from_int (m_mode
); }
366 ALWAYS_INLINE pod_mode
&operator = (const T
&m
) { m_mode
= m
; return *this; }
369 /* Return true if mode M has type T. */
373 is_a (machine_mode m
)
375 return T::includes_p (m
);
378 template<typename T
, typename U
>
380 is_a (const opt_mode
<U
> &m
)
382 return T::includes_p (m
.else_void ());
385 /* Assert that mode M has type T, and return it in that form. */
389 as_a (machine_mode m
)
391 gcc_checking_assert (T::includes_p (m
));
392 return typename mode_traits
<T
>::from_int (m
);
395 template<typename T
, typename U
>
397 as_a (const opt_mode
<U
> &m
)
399 return as_a
<T
> (m
.else_void ());
402 /* Convert M to an opt_mode<T>. */
406 dyn_cast (machine_mode m
)
408 if (T::includes_p (m
))
409 return T (typename mode_traits
<T
>::from_int (m
));
410 return opt_mode
<T
> ();
413 template<typename T
, typename U
>
415 dyn_cast (const opt_mode
<U
> &m
)
417 return dyn_cast
<T
> (m
.else_void ());
420 /* Return true if mode M has type T, storing it as a T in *RESULT
423 template<typename T
, typename U
>
425 is_a (machine_mode m
, U
*result
)
427 if (T::includes_p (m
))
429 *result
= T (typename mode_traits
<T
>::from_int (m
));
435 /* Represents a machine mode that is known to be a SCALAR_INT_MODE_P. */
436 class scalar_int_mode
439 typedef mode_traits
<scalar_int_mode
>::from_int from_int
;
440 typedef unsigned short measurement_type
;
442 ALWAYS_INLINE
scalar_int_mode () {}
444 ALWAYS_INLINE CONSTEXPR
445 scalar_int_mode (from_int m
) : m_mode (machine_mode (m
)) {}
447 ALWAYS_INLINE CONSTEXPR
operator machine_mode () const { return m_mode
; }
449 static bool includes_p (machine_mode
);
455 /* Return true if M is a scalar_int_mode. */
458 scalar_int_mode::includes_p (machine_mode m
)
460 return SCALAR_INT_MODE_P (m
);
463 /* Represents a machine mode that is known to be a SCALAR_FLOAT_MODE_P. */
464 class scalar_float_mode
467 typedef mode_traits
<scalar_float_mode
>::from_int from_int
;
468 typedef unsigned short measurement_type
;
470 ALWAYS_INLINE
scalar_float_mode () {}
472 ALWAYS_INLINE CONSTEXPR
473 scalar_float_mode (from_int m
) : m_mode (machine_mode (m
)) {}
475 ALWAYS_INLINE CONSTEXPR
operator machine_mode () const { return m_mode
; }
477 static bool includes_p (machine_mode
);
483 /* Return true if M is a scalar_float_mode. */
486 scalar_float_mode::includes_p (machine_mode m
)
488 return SCALAR_FLOAT_MODE_P (m
);
491 /* Represents a machine mode that is known to be scalar. */
495 typedef mode_traits
<scalar_mode
>::from_int from_int
;
496 typedef unsigned short measurement_type
;
498 ALWAYS_INLINE
scalar_mode () {}
500 ALWAYS_INLINE CONSTEXPR
501 scalar_mode (from_int m
) : m_mode (machine_mode (m
)) {}
503 ALWAYS_INLINE CONSTEXPR
504 scalar_mode (const scalar_int_mode
&m
) : m_mode (m
) {}
506 ALWAYS_INLINE CONSTEXPR
507 scalar_mode (const scalar_float_mode
&m
) : m_mode (m
) {}
509 ALWAYS_INLINE CONSTEXPR
510 scalar_mode (const scalar_int_mode_pod
&m
) : m_mode (m
) {}
512 ALWAYS_INLINE CONSTEXPR
operator machine_mode () const { return m_mode
; }
514 static bool includes_p (machine_mode
);
520 /* Return true if M represents some kind of scalar value. */
523 scalar_mode::includes_p (machine_mode m
)
525 switch (GET_MODE_CLASS (m
))
528 case MODE_PARTIAL_INT
:
534 case MODE_DECIMAL_FLOAT
:
541 /* Represents a machine mode that is known to be a COMPLEX_MODE_P. */
545 typedef mode_traits
<complex_mode
>::from_int from_int
;
546 typedef unsigned short measurement_type
;
548 ALWAYS_INLINE
complex_mode () {}
550 ALWAYS_INLINE CONSTEXPR
551 complex_mode (from_int m
) : m_mode (machine_mode (m
)) {}
553 ALWAYS_INLINE CONSTEXPR
operator machine_mode () const { return m_mode
; }
555 static bool includes_p (machine_mode
);
561 /* Return true if M is a complex_mode. */
564 complex_mode::includes_p (machine_mode m
)
566 return COMPLEX_MODE_P (m
);
569 /* Return the base GET_MODE_SIZE value for MODE. */
571 ALWAYS_INLINE poly_uint16
572 mode_to_bytes (machine_mode mode
)
574 #if GCC_VERSION >= 4001
575 return (__builtin_constant_p (mode
)
576 ? mode_size_inline (mode
) : mode_size
[mode
]);
578 return mode_size
[mode
];
582 /* Return the base GET_MODE_BITSIZE value for MODE. */
584 ALWAYS_INLINE poly_uint16
585 mode_to_bits (machine_mode mode
)
587 return mode_to_bytes (mode
) * BITS_PER_UNIT
;
590 /* Return the base GET_MODE_PRECISION value for MODE. */
592 ALWAYS_INLINE poly_uint16
593 mode_to_precision (machine_mode mode
)
595 return mode_precision
[mode
];
598 /* Return the base GET_MODE_INNER value for MODE. */
600 ALWAYS_INLINE scalar_mode
601 mode_to_inner (machine_mode mode
)
603 #if GCC_VERSION >= 4001
604 return scalar_mode::from_int (__builtin_constant_p (mode
)
605 ? mode_inner_inline (mode
)
608 return scalar_mode::from_int (mode_inner
[mode
]);
612 /* Return the base GET_MODE_UNIT_SIZE value for MODE. */
614 ALWAYS_INLINE
unsigned char
615 mode_to_unit_size (machine_mode mode
)
617 #if GCC_VERSION >= 4001
618 return (__builtin_constant_p (mode
)
619 ? mode_unit_size_inline (mode
) : mode_unit_size
[mode
]);
621 return mode_unit_size
[mode
];
625 /* Return the base GET_MODE_UNIT_PRECISION value for MODE. */
627 ALWAYS_INLINE
unsigned short
628 mode_to_unit_precision (machine_mode mode
)
630 #if GCC_VERSION >= 4001
631 return (__builtin_constant_p (mode
)
632 ? mode_unit_precision_inline (mode
) : mode_unit_precision
[mode
]);
634 return mode_unit_precision
[mode
];
638 /* Return the base GET_MODE_NUNITS value for MODE. */
640 ALWAYS_INLINE poly_uint16
641 mode_to_nunits (machine_mode mode
)
643 #if GCC_VERSION >= 4001
644 return (__builtin_constant_p (mode
)
645 ? mode_nunits_inline (mode
) : mode_nunits
[mode
]);
647 return mode_nunits
[mode
];
651 /* Get the size in bytes of an object of mode MODE. */
653 #if ONLY_FIXED_SIZE_MODES
654 #define GET_MODE_SIZE(MODE) ((unsigned short) mode_to_bytes (MODE).coeffs[0])
656 ALWAYS_INLINE poly_uint16
657 GET_MODE_SIZE (machine_mode mode
)
659 return mode_to_bytes (mode
);
663 ALWAYS_INLINE typename if_poly
<typename
T::measurement_type
>::type
664 GET_MODE_SIZE (const T
&mode
)
666 return mode_to_bytes (mode
);
670 ALWAYS_INLINE typename if_nonpoly
<typename
T::measurement_type
>::type
671 GET_MODE_SIZE (const T
&mode
)
673 return mode_to_bytes (mode
).coeffs
[0];
677 /* Get the size in bits of an object of mode MODE. */
679 #if ONLY_FIXED_SIZE_MODES
680 #define GET_MODE_BITSIZE(MODE) ((unsigned short) mode_to_bits (MODE).coeffs[0])
682 ALWAYS_INLINE poly_uint16
683 GET_MODE_BITSIZE (machine_mode mode
)
685 return mode_to_bits (mode
);
689 ALWAYS_INLINE typename if_poly
<typename
T::measurement_type
>::type
690 GET_MODE_BITSIZE (const T
&mode
)
692 return mode_to_bits (mode
);
696 ALWAYS_INLINE typename if_nonpoly
<typename
T::measurement_type
>::type
697 GET_MODE_BITSIZE (const T
&mode
)
699 return mode_to_bits (mode
).coeffs
[0];
703 /* Get the number of value bits of an object of mode MODE. */
705 #if ONLY_FIXED_SIZE_MODES
706 #define GET_MODE_PRECISION(MODE) \
707 ((unsigned short) mode_to_precision (MODE).coeffs[0])
709 ALWAYS_INLINE poly_uint16
710 GET_MODE_PRECISION (machine_mode mode
)
712 return mode_to_precision (mode
);
716 ALWAYS_INLINE typename if_poly
<typename
T::measurement_type
>::type
717 GET_MODE_PRECISION (const T
&mode
)
719 return mode_to_precision (mode
);
723 ALWAYS_INLINE typename if_nonpoly
<typename
T::measurement_type
>::type
724 GET_MODE_PRECISION (const T
&mode
)
726 return mode_to_precision (mode
).coeffs
[0];
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]
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]
738 /* Get a bitmask containing 1 for all bits in a word
739 that fit within mode MODE. */
741 extern CONST_MODE_MASK
unsigned HOST_WIDE_INT
742 mode_mask_array
[NUM_MACHINE_MODES
];
744 #define GET_MODE_MASK(MODE) mode_mask_array[MODE]
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. */
750 #define GET_MODE_INNER(MODE) (mode_to_inner (MODE))
752 /* Get the size in bytes or bits of the basic parts of an
753 object of mode MODE. */
755 #define GET_MODE_UNIT_SIZE(MODE) mode_to_unit_size (MODE)
757 #define GET_MODE_UNIT_BITSIZE(MODE) \
758 ((unsigned short) (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT))
760 #define GET_MODE_UNIT_PRECISION(MODE) (mode_to_unit_precision (MODE))
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. */
765 #if ONLY_FIXED_SIZE_MODES
766 #define GET_MODE_NUNITS(MODE) (mode_to_nunits (MODE).coeffs[0])
768 ALWAYS_INLINE poly_uint16
769 GET_MODE_NUNITS (machine_mode mode
)
771 return mode_to_nunits (mode
);
775 ALWAYS_INLINE typename if_poly
<typename
T::measurement_type
>::type
776 GET_MODE_NUNITS (const T
&mode
)
778 return mode_to_nunits (mode
);
782 ALWAYS_INLINE typename if_nonpoly
<typename
T::measurement_type
>::type
783 GET_MODE_NUNITS (const T
&mode
)
785 return mode_to_nunits (mode
).coeffs
[0];
789 /* Get the next natural mode (not narrower, eg, QI -> HI -> SI -> DI -> TI
790 or HF -> BF -> SF -> DF -> XF -> TF). */
793 ALWAYS_INLINE opt_mode
<T
>
794 GET_MODE_NEXT_MODE (const T
&m
)
796 return typename opt_mode
<T
>::from_int (mode_next
[m
]);
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. */
808 ALWAYS_INLINE opt_mode
<T
>
809 GET_MODE_WIDER_MODE (const T
&m
)
811 return typename opt_mode
<T
>::from_int (mode_wider
[m
]);
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. */
818 ALWAYS_INLINE opt_mode
<T
>
819 GET_MODE_2XWIDER_MODE (const T
&m
)
821 return typename opt_mode
<T
>::from_int (mode_2xwider
[m
]);
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])
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
835 typedef mode_traits
<fixed_size_mode
>::from_int from_int
;
836 typedef unsigned short measurement_type
;
838 ALWAYS_INLINE
fixed_size_mode () {}
840 ALWAYS_INLINE CONSTEXPR
841 fixed_size_mode (from_int m
) : m_mode (machine_mode (m
)) {}
843 ALWAYS_INLINE CONSTEXPR
844 fixed_size_mode (const scalar_mode
&m
) : m_mode (m
) {}
846 ALWAYS_INLINE CONSTEXPR
847 fixed_size_mode (const scalar_int_mode
&m
) : m_mode (m
) {}
849 ALWAYS_INLINE CONSTEXPR
850 fixed_size_mode (const scalar_float_mode
&m
) : m_mode (m
) {}
852 ALWAYS_INLINE CONSTEXPR
853 fixed_size_mode (const scalar_mode_pod
&m
) : m_mode (m
) {}
855 ALWAYS_INLINE CONSTEXPR
856 fixed_size_mode (const scalar_int_mode_pod
&m
) : m_mode (m
) {}
858 ALWAYS_INLINE CONSTEXPR
859 fixed_size_mode (const complex_mode
&m
) : m_mode (m
) {}
861 ALWAYS_INLINE CONSTEXPR
operator machine_mode () const { return m_mode
; }
863 static bool includes_p (machine_mode
);
869 /* Return true if MODE has a fixed size. */
872 fixed_size_mode::includes_p (machine_mode mode
)
874 return mode_to_bytes (mode
).is_constant ();
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
882 #if NUM_POLY_INT_COEFFS == 1
883 #define MACRO_MODE(MODE) (as_a <fixed_size_mode> (MODE))
885 #define MACRO_MODE(MODE) (MODE)
888 extern opt_machine_mode
mode_for_size (poly_uint64
, enum mode_class
, int);
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
894 inline opt_scalar_int_mode
895 int_mode_for_size (poly_uint64 size
, int limit
)
897 return dyn_cast
<scalar_int_mode
> (mode_for_size (size
, MODE_INT
, limit
));
900 /* Return the machine mode to use for a MODE_FLOAT of SIZE bits, if one
903 inline opt_scalar_float_mode
904 float_mode_for_size (poly_uint64 size
)
906 return dyn_cast
<scalar_float_mode
> (mode_for_size (size
, MODE_FLOAT
, 0));
909 /* Likewise for MODE_DECIMAL_FLOAT. */
911 inline opt_scalar_float_mode
912 decimal_float_mode_for_size (unsigned int size
)
914 return dyn_cast
<scalar_float_mode
>
915 (mode_for_size (size
, MODE_DECIMAL_FLOAT
, 0));
918 extern opt_machine_mode
smallest_mode_for_size (poly_uint64
, enum mode_class
);
920 /* Find the narrowest integer mode that contains at least SIZE bits,
921 if such a mode exists. */
923 inline opt_scalar_int_mode
924 smallest_int_mode_for_size (poly_uint64 size
)
926 return dyn_cast
<scalar_int_mode
> (smallest_mode_for_size (size
, MODE_INT
));
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
,
934 extern opt_machine_mode
related_int_vector_mode (machine_mode
);
936 /* A class for iterating through possible bitfield modes. */
937 class bit_field_mode_iterator
940 bit_field_mode_iterator (HOST_WIDE_INT
, HOST_WIDE_INT
,
941 poly_int64
, poly_int64
,
943 bool next_mode (scalar_int_mode
*);
944 bool prefer_smaller_modes ();
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
;
959 /* Find the best mode to use to access a bit field. */
961 extern bool get_best_mode (int, int, poly_uint64
, poly_uint64
, unsigned int,
962 unsigned HOST_WIDE_INT
, bool, scalar_int_mode
*);
964 /* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT. */
966 extern CONST_MODE_BASE_ALIGN
unsigned short mode_base_align
[NUM_MACHINE_MODES
];
968 extern unsigned get_mode_alignment (machine_mode
);
970 #define GET_MODE_ALIGNMENT(MODE) get_mode_alignment (MODE)
972 /* For each class, get the narrowest mode in that class. */
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])
978 /* The narrowest full integer mode available on the target. */
980 #define NARROWEST_INT_MODE \
982 (scalar_int_mode::from_int (class_narrowest_mode[MODE_INT])))
984 /* Return the narrowest mode in T's class. */
988 get_narrowest_mode (T mode
)
990 return typename mode_traits
<T
>::from_int
991 (class_narrowest_mode
[GET_MODE_CLASS (mode
)]);
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. */
997 extern scalar_int_mode byte_mode
;
998 extern scalar_int_mode word_mode
;
999 extern scalar_int_mode ptr_mode
;
1001 /* Target-dependent machine mode initialization - in insn-modes.cc. */
1002 extern void init_adjust_machine_modes (void);
1004 #define TRULY_NOOP_TRUNCATION_MODES_P(MODE1, MODE2) \
1005 (targetm.truly_noop_truncation (GET_MODE_PRECISION (MODE1), \
1006 GET_MODE_PRECISION (MODE2)))
1008 /* Return true if MODE is a scalar integer mode that fits in a
1012 HWI_COMPUTABLE_MODE_P (machine_mode mode
)
1014 machine_mode mme
= mode
;
1015 return (SCALAR_INT_MODE_P (mme
)
1016 && mode_to_precision (mme
).coeffs
[0] <= HOST_BITS_PER_WIDE_INT
);
1020 HWI_COMPUTABLE_MODE_P (scalar_int_mode mode
)
1022 return GET_MODE_PRECISION (mode
) <= HOST_BITS_PER_WIDE_INT
;
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 */
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
];
1037 /* Return true if MODE has class MODE_INT, storing it as a scalar_int_mode
1038 in *INT_MODE if so. */
1040 template<typename T
>
1042 is_int_mode (machine_mode mode
, T
*int_mode
)
1044 if (GET_MODE_CLASS (mode
) == MODE_INT
)
1046 *int_mode
= scalar_int_mode (scalar_int_mode::from_int (mode
));
1052 /* Return true if MODE has class MODE_FLOAT, storing it as a
1053 scalar_float_mode in *FLOAT_MODE if so. */
1055 template<typename T
>
1057 is_float_mode (machine_mode mode
, T
*float_mode
)
1059 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
1061 *float_mode
= scalar_float_mode (scalar_float_mode::from_int (mode
));
1067 /* Return true if MODE has class MODE_COMPLEX_INT, storing it as
1068 a complex_mode in *CMODE if so. */
1070 template<typename T
>
1072 is_complex_int_mode (machine_mode mode
, T
*cmode
)
1074 if (GET_MODE_CLASS (mode
) == MODE_COMPLEX_INT
)
1076 *cmode
= complex_mode (complex_mode::from_int (mode
));
1082 /* Return true if MODE has class MODE_COMPLEX_FLOAT, storing it as
1083 a complex_mode in *CMODE if so. */
1085 template<typename T
>
1087 is_complex_float_mode (machine_mode mode
, T
*cmode
)
1089 if (GET_MODE_CLASS (mode
) == MODE_COMPLEX_FLOAT
)
1091 *cmode
= complex_mode (complex_mode::from_int (mode
));
1097 /* Return true if MODE is a scalar integer mode with a precision
1098 smaller than LIMIT's precision. */
1101 is_narrower_int_mode (machine_mode mode
, scalar_int_mode limit
)
1103 scalar_int_mode int_mode
;
1104 return (is_a
<scalar_int_mode
> (mode
, &int_mode
)
1105 && GET_MODE_PRECISION (int_mode
) < GET_MODE_PRECISION (limit
));
1108 namespace mode_iterator
1110 /* Start mode iterator *ITER at the first mode in class MCLASS, if any. */
1112 template<typename T
>
1114 start (opt_mode
<T
> *iter
, enum mode_class mclass
)
1116 if (GET_CLASS_NARROWEST_MODE (mclass
) == E_VOIDmode
)
1117 *iter
= opt_mode
<T
> ();
1119 *iter
= as_a
<T
> (GET_CLASS_NARROWEST_MODE (mclass
));
1123 start (machine_mode
*iter
, enum mode_class mclass
)
1125 *iter
= GET_CLASS_NARROWEST_MODE (mclass
);
1128 /* Return true if mode iterator *ITER has not reached the end. */
1130 template<typename T
>
1132 iterate_p (opt_mode
<T
> *iter
)
1134 return iter
->exists ();
1138 iterate_p (machine_mode
*iter
)
1140 return *iter
!= E_VOIDmode
;
1143 /* Set mode iterator *ITER to the next mode in the same class,
1146 template<typename T
>
1148 get_next (opt_mode
<T
> *iter
)
1150 *iter
= GET_MODE_NEXT_MODE (iter
->require ());
1154 get_next (machine_mode
*iter
)
1156 *iter
= GET_MODE_NEXT_MODE (*iter
).else_void ();
1159 /* Set mode iterator *ITER to the next mode in the same class.
1160 Such a mode is known to exist. */
1162 template<typename T
>
1164 get_known_next (T
*iter
)
1166 *iter
= GET_MODE_NEXT_MODE (*iter
).require ();
1169 /* Set mode iterator *ITER to the next wider mode in the same class,
1172 template<typename T
>
1174 get_wider (opt_mode
<T
> *iter
)
1176 *iter
= GET_MODE_WIDER_MODE (iter
->require ());
1180 get_wider (machine_mode
*iter
)
1182 *iter
= GET_MODE_WIDER_MODE (*iter
).else_void ();
1185 /* Set mode iterator *ITER to the next wider mode in the same class.
1186 Such a mode is known to exist. */
1188 template<typename T
>
1190 get_known_wider (T
*iter
)
1192 *iter
= GET_MODE_WIDER_MODE (*iter
).require ();
1195 /* Set mode iterator *ITER to the mode that is two times wider than the
1196 current one, if such a mode exists. */
1198 template<typename T
>
1200 get_2xwider (opt_mode
<T
> *iter
)
1202 *iter
= GET_MODE_2XWIDER_MODE (iter
->require ());
1206 get_2xwider (machine_mode
*iter
)
1208 *iter
= GET_MODE_2XWIDER_MODE (*iter
).else_void ();
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)))
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)))
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)))
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)))
1240 /* Make ITERATOR iterate over modes in the range [NARROWEST, END)
1241 in order of increasing width, where NARROWEST is the narrowest mode
1243 #define FOR_EACH_MODE_UNTIL(ITERATOR, END) \
1244 FOR_EACH_MODE (ITERATOR, get_narrowest_mode (END), END)
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)))
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)))
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)))
1271 template<typename T
>
1273 gt_ggc_mx (pod_mode
<T
> *)
1277 template<typename T
>
1279 gt_pch_nx (pod_mode
<T
> *)
1283 template<typename T
>
1285 gt_pch_nx (pod_mode
<T
> *, gt_pointer_operator
, void *)
1289 #endif /* not HAVE_MACHINE_MODES */