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