LCOV - code coverage report
Current view: top level - gcc - machmode.h (source / functions) Hit Total Coverage
Test: gcc.info Lines: 27 30 90.0 %
Date: 2023-07-19 08:18:47 Functions: 3 3 100.0 %

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

Generated by: LCOV version 1.16