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