1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171 |
- /* Machine mode definitions for GCC; included by rtl.h and tree.h.
- Copyright (C) 1991-2019 Free Software Foundation, Inc.
- This file is part of GCC.
- GCC is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 3, or (at your option) any later
- version.
- GCC is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
- #ifndef HAVE_MACHINE_MODES
- #define HAVE_MACHINE_MODES
- typedef opt_mode<machine_mode> opt_machine_mode;
- extern CONST_MODE_SIZE poly_uint16_pod mode_size[NUM_MACHINE_MODES];
- extern CONST_MODE_PRECISION poly_uint16_pod mode_precision[NUM_MACHINE_MODES];
- extern const unsigned char mode_inner[NUM_MACHINE_MODES];
- extern CONST_MODE_NUNITS poly_uint16_pod mode_nunits[NUM_MACHINE_MODES];
- extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];
- extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];
- extern const unsigned char mode_wider[NUM_MACHINE_MODES];
- extern const unsigned char mode_2xwider[NUM_MACHINE_MODES];
- template<typename T>
- struct mode_traits
- {
- /* For use by the machmode support code only.
- There are cases in which the machmode support code needs to forcibly
- convert a machine_mode to a specific mode class T, and in which the
- context guarantees that this is valid without the need for an assert.
- This can be done using:
- return typename mode_traits<T>::from_int (mode);
- when returning a T and:
- res = T (typename mode_traits<T>::from_int (mode));
- when assigning to a value RES that must be assignment-compatible
- with (but possibly not the same as) T. */
- #ifdef USE_ENUM_MODES
- /* Allow direct conversion of enums to specific mode classes only
- when USE_ENUM_MODES is defined. This is only intended for use
- by gencondmd, so that it can tell more easily when .md conditions
- are always false. */
- typedef machine_mode from_int;
- #else
- /* Here we use an enum type distinct from machine_mode but with the
- same range as machine_mode. T should have a constructor that
- accepts this enum type; it should not have a constructor that
- accepts machine_mode.
- We use this somewhat indirect approach to avoid too many constructor
- calls when the compiler is built with -O0. For example, even in
- unoptimized code, the return statement above would construct the
- returned T directly from the numerical value of MODE. */
- enum from_int { dummy = MAX_MACHINE_MODE };
- #endif
- };
- template<>
- struct mode_traits<machine_mode>
- {
- /* machine_mode itself needs no conversion. */
- typedef machine_mode from_int;
- };
- /* Always treat machine modes as fixed-size while compiling code specific
- to targets that have no variable-size modes. */
- #if defined (IN_TARGET_CODE) && NUM_POLY_INT_COEFFS == 1
- #define ONLY_FIXED_SIZE_MODES 1
- #else
- #define ONLY_FIXED_SIZE_MODES 0
- #endif
- /* Get the name of mode MODE as a string. */
- extern const char * const mode_name[NUM_MACHINE_MODES];
- #define GET_MODE_NAME(MODE) mode_name[MODE]
- /* Mode classes. */
- #include "mode-classes.def"
- #define DEF_MODE_CLASS(M) M
- enum mode_class { MODE_CLASSES, MAX_MODE_CLASS };
- #undef DEF_MODE_CLASS
- #undef MODE_CLASSES
- /* Get the general kind of object that mode MODE represents
- (integer, floating, complex, etc.) */
- extern const unsigned char mode_class[NUM_MACHINE_MODES];
- #define GET_MODE_CLASS(MODE) ((enum mode_class) mode_class[MODE])
- /* Nonzero if MODE is an integral mode. */
- #define INTEGRAL_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_INT \
- || GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT \
- || GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \
- || GET_MODE_CLASS (MODE) == MODE_VECTOR_BOOL \
- || GET_MODE_CLASS (MODE) == MODE_VECTOR_INT)
- /* Nonzero if MODE is a floating-point mode. */
- #define FLOAT_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- || GET_MODE_CLASS (MODE) == MODE_DECIMAL_FLOAT \
- || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
- || GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT)
- /* Nonzero if MODE is a complex mode. */
- #define COMPLEX_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \
- || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)
- /* Nonzero if MODE is a vector mode. */
- #define VECTOR_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_VECTOR_BOOL \
- || GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \
- || GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT \
- || GET_MODE_CLASS (MODE) == MODE_VECTOR_FRACT \
- || GET_MODE_CLASS (MODE) == MODE_VECTOR_UFRACT \
- || GET_MODE_CLASS (MODE) == MODE_VECTOR_ACCUM \
- || GET_MODE_CLASS (MODE) == MODE_VECTOR_UACCUM)
- /* Nonzero if MODE is a scalar integral mode. */
- #define SCALAR_INT_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_INT \
- || GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT)
- /* Nonzero if MODE is a scalar floating point mode. */
- #define SCALAR_FLOAT_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- || GET_MODE_CLASS (MODE) == MODE_DECIMAL_FLOAT)
- /* Nonzero if MODE is a decimal floating point mode. */
- #define DECIMAL_FLOAT_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_DECIMAL_FLOAT)
- /* Nonzero if MODE is a scalar fract mode. */
- #define SCALAR_FRACT_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_FRACT)
- /* Nonzero if MODE is a scalar ufract mode. */
- #define SCALAR_UFRACT_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_UFRACT)
- /* Nonzero if MODE is a scalar fract or ufract mode. */
- #define ALL_SCALAR_FRACT_MODE_P(MODE) \
- (SCALAR_FRACT_MODE_P (MODE) || SCALAR_UFRACT_MODE_P (MODE))
- /* Nonzero if MODE is a scalar accum mode. */
- #define SCALAR_ACCUM_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_ACCUM)
- /* Nonzero if MODE is a scalar uaccum mode. */
- #define SCALAR_UACCUM_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_UACCUM)
- /* Nonzero if MODE is a scalar accum or uaccum mode. */
- #define ALL_SCALAR_ACCUM_MODE_P(MODE) \
- (SCALAR_ACCUM_MODE_P (MODE) || SCALAR_UACCUM_MODE_P (MODE))
- /* Nonzero if MODE is a scalar fract or accum mode. */
- #define SIGNED_SCALAR_FIXED_POINT_MODE_P(MODE) \
- (SCALAR_FRACT_MODE_P (MODE) || SCALAR_ACCUM_MODE_P (MODE))
- /* Nonzero if MODE is a scalar ufract or uaccum mode. */
- #define UNSIGNED_SCALAR_FIXED_POINT_MODE_P(MODE) \
- (SCALAR_UFRACT_MODE_P (MODE) || SCALAR_UACCUM_MODE_P (MODE))
- /* Nonzero if MODE is a scalar fract, ufract, accum or uaccum mode. */
- #define ALL_SCALAR_FIXED_POINT_MODE_P(MODE) \
- (SIGNED_SCALAR_FIXED_POINT_MODE_P (MODE) \
- || UNSIGNED_SCALAR_FIXED_POINT_MODE_P (MODE))
- /* Nonzero if MODE is a scalar/vector fract mode. */
- #define FRACT_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_FRACT \
- || GET_MODE_CLASS (MODE) == MODE_VECTOR_FRACT)
- /* Nonzero if MODE is a scalar/vector ufract mode. */
- #define UFRACT_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_UFRACT \
- || GET_MODE_CLASS (MODE) == MODE_VECTOR_UFRACT)
- /* Nonzero if MODE is a scalar/vector fract or ufract mode. */
- #define ALL_FRACT_MODE_P(MODE) \
- (FRACT_MODE_P (MODE) || UFRACT_MODE_P (MODE))
- /* Nonzero if MODE is a scalar/vector accum mode. */
- #define ACCUM_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_ACCUM \
- || GET_MODE_CLASS (MODE) == MODE_VECTOR_ACCUM)
- /* Nonzero if MODE is a scalar/vector uaccum mode. */
- #define UACCUM_MODE_P(MODE) \
- (GET_MODE_CLASS (MODE) == MODE_UACCUM \
- || GET_MODE_CLASS (MODE) == MODE_VECTOR_UACCUM)
- /* Nonzero if MODE is a scalar/vector accum or uaccum mode. */
- #define ALL_ACCUM_MODE_P(MODE) \
- (ACCUM_MODE_P (MODE) || UACCUM_MODE_P (MODE))
- /* Nonzero if MODE is a scalar/vector fract or accum mode. */
- #define SIGNED_FIXED_POINT_MODE_P(MODE) \
- (FRACT_MODE_P (MODE) || ACCUM_MODE_P (MODE))
- /* Nonzero if MODE is a scalar/vector ufract or uaccum mode. */
- #define UNSIGNED_FIXED_POINT_MODE_P(MODE) \
- (UFRACT_MODE_P (MODE) || UACCUM_MODE_P (MODE))
- /* Nonzero if MODE is a scalar/vector fract, ufract, accum or uaccum mode. */
- #define ALL_FIXED_POINT_MODE_P(MODE) \
- (SIGNED_FIXED_POINT_MODE_P (MODE) \
- || UNSIGNED_FIXED_POINT_MODE_P (MODE))
- /* Nonzero if CLASS modes can be widened. */
- #define CLASS_HAS_WIDER_MODES_P(CLASS) \
- (CLASS == MODE_INT \
- || CLASS == MODE_PARTIAL_INT \
- || CLASS == MODE_FLOAT \
- || CLASS == MODE_DECIMAL_FLOAT \
- || CLASS == MODE_COMPLEX_FLOAT \
- || CLASS == MODE_FRACT \
- || CLASS == MODE_UFRACT \
- || CLASS == MODE_ACCUM \
- || CLASS == MODE_UACCUM)
- /* An optional T (i.e. a T or nothing), where T is some form of mode class. */
- template<typename T>
- class opt_mode
- {
- public:
- enum from_int { dummy = MAX_MACHINE_MODE };
- ALWAYS_INLINE opt_mode () : m_mode (E_VOIDmode) {}
- ALWAYS_INLINE opt_mode (const T &m) : m_mode (m) {}
- template<typename U>
- ALWAYS_INLINE opt_mode (const U &m) : m_mode (T (m)) {}
- ALWAYS_INLINE opt_mode (from_int m) : m_mode (machine_mode (m)) {}
- machine_mode else_void () const;
- machine_mode else_blk () const;
- T require () const;
- bool exists () const;
- template<typename U> bool exists (U *) const;
- private:
- machine_mode m_mode;
- };
- /* If the object contains a T, return its enum value, otherwise return
- E_VOIDmode. */
- template<typename T>
- ALWAYS_INLINE machine_mode
- opt_mode<T>::else_void () const
- {
- return m_mode;
- }
- /* If the T exists, return its enum value, otherwise return E_BLKmode. */
- template<typename T>
- inline machine_mode
- opt_mode<T>::else_blk () const
- {
- return m_mode == E_VOIDmode ? E_BLKmode : m_mode;
- }
- /* Assert that the object contains a T and return it. */
- template<typename T>
- inline T
- opt_mode<T>::require () const
- {
- gcc_checking_assert (m_mode != E_VOIDmode);
- return typename mode_traits<T>::from_int (m_mode);
- }
- /* Return true if the object contains a T rather than nothing. */
- template<typename T>
- ALWAYS_INLINE bool
- opt_mode<T>::exists () const
- {
- return m_mode != E_VOIDmode;
- }
- /* Return true if the object contains a T, storing it in *MODE if so. */
- template<typename T>
- template<typename U>
- inline bool
- opt_mode<T>::exists (U *mode) const
- {
- if (m_mode != E_VOIDmode)
- {
- *mode = T (typename mode_traits<T>::from_int (m_mode));
- return true;
- }
- return false;
- }
- /* A POD version of mode class T. */
- template<typename T>
- struct pod_mode
- {
- typedef typename mode_traits<T>::from_int from_int;
- typedef typename T::measurement_type measurement_type;
- machine_mode m_mode;
- ALWAYS_INLINE operator machine_mode () const { return m_mode; }
- ALWAYS_INLINE operator T () const { return from_int (m_mode); }
- ALWAYS_INLINE pod_mode &operator = (const T &m) { m_mode = m; return *this; }
- };
- /* Return true if mode M has type T. */
- template<typename T>
- inline bool
- is_a (machine_mode m)
- {
- return T::includes_p (m);
- }
- template<typename T, typename U>
- inline bool
- is_a (const opt_mode<U> &m)
- {
- return T::includes_p (m.else_void ());
- }
- /* Assert that mode M has type T, and return it in that form. */
- template<typename T>
- inline T
- as_a (machine_mode m)
- {
- gcc_checking_assert (T::includes_p (m));
- return typename mode_traits<T>::from_int (m);
- }
- template<typename T, typename U>
- inline T
- as_a (const opt_mode<U> &m)
- {
- return as_a <T> (m.else_void ());
- }
- /* Convert M to an opt_mode<T>. */
- template<typename T>
- inline opt_mode<T>
- dyn_cast (machine_mode m)
- {
- if (T::includes_p (m))
- return T (typename mode_traits<T>::from_int (m));
- return opt_mode<T> ();
- }
- template<typename T, typename U>
- inline opt_mode<T>
- dyn_cast (const opt_mode<U> &m)
- {
- return dyn_cast <T> (m.else_void ());
- }
- /* Return true if mode M has type T, storing it as a T in *RESULT
- if so. */
- template<typename T, typename U>
- inline bool
- is_a (machine_mode m, U *result)
- {
- if (T::includes_p (m))
- {
- *result = T (typename mode_traits<T>::from_int (m));
- return true;
- }
- return false;
- }
- /* Represents a machine mode that is known to be a SCALAR_INT_MODE_P. */
- class scalar_int_mode
- {
- public:
- typedef mode_traits<scalar_int_mode>::from_int from_int;
- typedef unsigned short measurement_type;
- ALWAYS_INLINE scalar_int_mode () {}
- ALWAYS_INLINE scalar_int_mode (from_int m) : m_mode (machine_mode (m)) {}
- ALWAYS_INLINE operator machine_mode () const { return m_mode; }
- static bool includes_p (machine_mode);
- protected:
- machine_mode m_mode;
- };
- /* Return true if M is a scalar_int_mode. */
- inline bool
- scalar_int_mode::includes_p (machine_mode m)
- {
- return SCALAR_INT_MODE_P (m);
- }
- /* Represents a machine mode that is known to be a SCALAR_FLOAT_MODE_P. */
- class scalar_float_mode
- {
- public:
- typedef mode_traits<scalar_float_mode>::from_int from_int;
- typedef unsigned short measurement_type;
- ALWAYS_INLINE scalar_float_mode () {}
- ALWAYS_INLINE scalar_float_mode (from_int m) : m_mode (machine_mode (m)) {}
- ALWAYS_INLINE operator machine_mode () const { return m_mode; }
- static bool includes_p (machine_mode);
- protected:
- machine_mode m_mode;
- };
- /* Return true if M is a scalar_float_mode. */
- inline bool
- scalar_float_mode::includes_p (machine_mode m)
- {
- return SCALAR_FLOAT_MODE_P (m);
- }
- /* Represents a machine mode that is known to be scalar. */
- class scalar_mode
- {
- public:
- typedef mode_traits<scalar_mode>::from_int from_int;
- typedef unsigned short measurement_type;
- ALWAYS_INLINE scalar_mode () {}
- ALWAYS_INLINE scalar_mode (from_int m) : m_mode (machine_mode (m)) {}
- ALWAYS_INLINE scalar_mode (const scalar_int_mode &m) : m_mode (m) {}
- ALWAYS_INLINE scalar_mode (const scalar_float_mode &m) : m_mode (m) {}
- ALWAYS_INLINE scalar_mode (const scalar_int_mode_pod &m) : m_mode (m) {}
- ALWAYS_INLINE operator machine_mode () const { return m_mode; }
- static bool includes_p (machine_mode);
- protected:
- machine_mode m_mode;
- };
- /* Return true if M represents some kind of scalar value. */
- inline bool
- scalar_mode::includes_p (machine_mode m)
- {
- switch (GET_MODE_CLASS (m))
- {
- case MODE_INT:
- case MODE_PARTIAL_INT:
- case MODE_FRACT:
- case MODE_UFRACT:
- case MODE_ACCUM:
- case MODE_UACCUM:
- case MODE_FLOAT:
- case MODE_DECIMAL_FLOAT:
- return true;
- default:
- return false;
- }
- }
- /* Represents a machine mode that is known to be a COMPLEX_MODE_P. */
- class complex_mode
- {
- public:
- typedef mode_traits<complex_mode>::from_int from_int;
- typedef unsigned short measurement_type;
- ALWAYS_INLINE complex_mode () {}
- ALWAYS_INLINE complex_mode (from_int m) : m_mode (machine_mode (m)) {}
- ALWAYS_INLINE operator machine_mode () const { return m_mode; }
- static bool includes_p (machine_mode);
- protected:
- machine_mode m_mode;
- };
- /* Return true if M is a complex_mode. */
- inline bool
- complex_mode::includes_p (machine_mode m)
- {
- return COMPLEX_MODE_P (m);
- }
- /* Return the base GET_MODE_SIZE value for MODE. */
- ALWAYS_INLINE poly_uint16
- mode_to_bytes (machine_mode mode)
- {
- #if GCC_VERSION >= 4001
- return (__builtin_constant_p (mode)
- ? mode_size_inline (mode) : mode_size[mode]);
- #else
- return mode_size[mode];
- #endif
- }
- /* Return the base GET_MODE_BITSIZE value for MODE. */
- ALWAYS_INLINE poly_uint16
- mode_to_bits (machine_mode mode)
- {
- return mode_to_bytes (mode) * BITS_PER_UNIT;
- }
- /* Return the base GET_MODE_PRECISION value for MODE. */
- ALWAYS_INLINE poly_uint16
- mode_to_precision (machine_mode mode)
- {
- return mode_precision[mode];
- }
- /* Return the base GET_MODE_INNER value for MODE. */
- ALWAYS_INLINE scalar_mode
- mode_to_inner (machine_mode mode)
- {
- #if GCC_VERSION >= 4001
- return scalar_mode::from_int (__builtin_constant_p (mode)
- ? mode_inner_inline (mode)
- : mode_inner[mode]);
- #else
- return scalar_mode::from_int (mode_inner[mode]);
- #endif
- }
- /* Return the base GET_MODE_UNIT_SIZE value for MODE. */
- ALWAYS_INLINE unsigned char
- mode_to_unit_size (machine_mode mode)
- {
- #if GCC_VERSION >= 4001
- return (__builtin_constant_p (mode)
- ? mode_unit_size_inline (mode) : mode_unit_size[mode]);
- #else
- return mode_unit_size[mode];
- #endif
- }
- /* Return the base GET_MODE_UNIT_PRECISION value for MODE. */
- ALWAYS_INLINE unsigned short
- mode_to_unit_precision (machine_mode mode)
- {
- #if GCC_VERSION >= 4001
- return (__builtin_constant_p (mode)
- ? mode_unit_precision_inline (mode) : mode_unit_precision[mode]);
- #else
- return mode_unit_precision[mode];
- #endif
- }
- /* Return the base GET_MODE_NUNITS value for MODE. */
- ALWAYS_INLINE poly_uint16
- mode_to_nunits (machine_mode mode)
- {
- #if GCC_VERSION >= 4001
- return (__builtin_constant_p (mode)
- ? mode_nunits_inline (mode) : mode_nunits[mode]);
- #else
- return mode_nunits[mode];
- #endif
- }
- /* Get the size in bytes of an object of mode MODE. */
- #if ONLY_FIXED_SIZE_MODES
- #define GET_MODE_SIZE(MODE) ((unsigned short) mode_to_bytes (MODE).coeffs[0])
- #else
- ALWAYS_INLINE poly_uint16
- GET_MODE_SIZE (machine_mode mode)
- {
- return mode_to_bytes (mode);
- }
- template<typename T>
- ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type
- GET_MODE_SIZE (const T &mode)
- {
- return mode_to_bytes (mode);
- }
- template<typename T>
- ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type
- GET_MODE_SIZE (const T &mode)
- {
- return mode_to_bytes (mode).coeffs[0];
- }
- #endif
- /* Get the size in bits of an object of mode MODE. */
- #if ONLY_FIXED_SIZE_MODES
- #define GET_MODE_BITSIZE(MODE) ((unsigned short) mode_to_bits (MODE).coeffs[0])
- #else
- ALWAYS_INLINE poly_uint16
- GET_MODE_BITSIZE (machine_mode mode)
- {
- return mode_to_bits (mode);
- }
- template<typename T>
- ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type
- GET_MODE_BITSIZE (const T &mode)
- {
- return mode_to_bits (mode);
- }
- template<typename T>
- ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type
- GET_MODE_BITSIZE (const T &mode)
- {
- return mode_to_bits (mode).coeffs[0];
- }
- #endif
- /* Get the number of value bits of an object of mode MODE. */
- #if ONLY_FIXED_SIZE_MODES
- #define GET_MODE_PRECISION(MODE) \
- ((unsigned short) mode_to_precision (MODE).coeffs[0])
- #else
- ALWAYS_INLINE poly_uint16
- GET_MODE_PRECISION (machine_mode mode)
- {
- return mode_to_precision (mode);
- }
- template<typename T>
- ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type
- GET_MODE_PRECISION (const T &mode)
- {
- return mode_to_precision (mode);
- }
- template<typename T>
- ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type
- GET_MODE_PRECISION (const T &mode)
- {
- return mode_to_precision (mode).coeffs[0];
- }
- #endif
- /* Get the number of integral bits of an object of mode MODE. */
- extern CONST_MODE_IBIT unsigned char mode_ibit[NUM_MACHINE_MODES];
- #define GET_MODE_IBIT(MODE) mode_ibit[MODE]
- /* Get the number of fractional bits of an object of mode MODE. */
- extern CONST_MODE_FBIT unsigned char mode_fbit[NUM_MACHINE_MODES];
- #define GET_MODE_FBIT(MODE) mode_fbit[MODE]
- /* Get a bitmask containing 1 for all bits in a word
- that fit within mode MODE. */
- extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES];
- #define GET_MODE_MASK(MODE) mode_mask_array[MODE]
- /* Return the mode of the basic parts of MODE. For vector modes this is the
- mode of the vector elements. For complex modes it is the mode of the real
- and imaginary parts. For other modes it is MODE itself. */
- #define GET_MODE_INNER(MODE) (mode_to_inner (MODE))
- /* Get the size in bytes or bits of the basic parts of an
- object of mode MODE. */
- #define GET_MODE_UNIT_SIZE(MODE) mode_to_unit_size (MODE)
- #define GET_MODE_UNIT_BITSIZE(MODE) \
- ((unsigned short) (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT))
- #define GET_MODE_UNIT_PRECISION(MODE) (mode_to_unit_precision (MODE))
- /* Get the number of units in an object of mode MODE. This is 2 for
- complex modes and the number of elements for vector modes. */
- #if ONLY_FIXED_SIZE_MODES
- #define GET_MODE_NUNITS(MODE) (mode_to_nunits (MODE).coeffs[0])
- #else
- ALWAYS_INLINE poly_uint16
- GET_MODE_NUNITS (machine_mode mode)
- {
- return mode_to_nunits (mode);
- }
- template<typename T>
- ALWAYS_INLINE typename if_poly<typename T::measurement_type>::type
- GET_MODE_NUNITS (const T &mode)
- {
- return mode_to_nunits (mode);
- }
- template<typename T>
- ALWAYS_INLINE typename if_nonpoly<typename T::measurement_type>::type
- GET_MODE_NUNITS (const T &mode)
- {
- return mode_to_nunits (mode).coeffs[0];
- }
- #endif
- /* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */
- template<typename T>
- ALWAYS_INLINE opt_mode<T>
- GET_MODE_WIDER_MODE (const T &m)
- {
- return typename opt_mode<T>::from_int (mode_wider[m]);
- }
- /* For scalars, this is a mode with twice the precision. For vectors,
- this is a mode with the same inner mode but with twice the elements. */
- template<typename T>
- ALWAYS_INLINE opt_mode<T>
- GET_MODE_2XWIDER_MODE (const T &m)
- {
- return typename opt_mode<T>::from_int (mode_2xwider[m]);
- }
- /* Get the complex mode from the component mode. */
- extern const unsigned char mode_complex[NUM_MACHINE_MODES];
- #define GET_MODE_COMPLEX_MODE(MODE) ((machine_mode) mode_complex[MODE])
- /* Represents a machine mode that must have a fixed size. The main
- use of this class is to represent the modes of objects that always
- have static storage duration, such as constant pool entries.
- (No current target supports the concept of variable-size static data.) */
- class fixed_size_mode
- {
- public:
- typedef mode_traits<fixed_size_mode>::from_int from_int;
- typedef unsigned short measurement_type;
- ALWAYS_INLINE fixed_size_mode () {}
- ALWAYS_INLINE fixed_size_mode (from_int m) : m_mode (machine_mode (m)) {}
- ALWAYS_INLINE fixed_size_mode (const scalar_mode &m) : m_mode (m) {}
- ALWAYS_INLINE fixed_size_mode (const scalar_int_mode &m) : m_mode (m) {}
- ALWAYS_INLINE fixed_size_mode (const scalar_float_mode &m) : m_mode (m) {}
- ALWAYS_INLINE fixed_size_mode (const scalar_mode_pod &m) : m_mode (m) {}
- ALWAYS_INLINE fixed_size_mode (const scalar_int_mode_pod &m) : m_mode (m) {}
- ALWAYS_INLINE fixed_size_mode (const complex_mode &m) : m_mode (m) {}
- ALWAYS_INLINE operator machine_mode () const { return m_mode; }
- static bool includes_p (machine_mode);
- protected:
- machine_mode m_mode;
- };
- /* Return true if MODE has a fixed size. */
- inline bool
- fixed_size_mode::includes_p (machine_mode mode)
- {
- return mode_to_bytes (mode).is_constant ();
- }
- /* Wrapper for mode arguments to target macros, so that if a target
- doesn't need polynomial-sized modes, its header file can continue
- to treat everything as fixed_size_mode. This should go away once
- macros are moved to target hooks. It shouldn't be used in other
- contexts. */
- #if NUM_POLY_INT_COEFFS == 1
- #define MACRO_MODE(MODE) (as_a <fixed_size_mode> (MODE))
- #else
- #define MACRO_MODE(MODE) (MODE)
- #endif
- extern opt_machine_mode mode_for_size (poly_uint64, enum mode_class, int);
- /* Return the machine mode to use for a MODE_INT of SIZE bits, if one
- exists. If LIMIT is nonzero, modes wider than MAX_FIXED_MODE_SIZE
- will not be used. */
- inline opt_scalar_int_mode
- int_mode_for_size (poly_uint64 size, int limit)
- {
- return dyn_cast <scalar_int_mode> (mode_for_size (size, MODE_INT, limit));
- }
- /* Return the machine mode to use for a MODE_FLOAT of SIZE bits, if one
- exists. */
- inline opt_scalar_float_mode
- float_mode_for_size (poly_uint64 size)
- {
- return dyn_cast <scalar_float_mode> (mode_for_size (size, MODE_FLOAT, 0));
- }
- /* Likewise for MODE_DECIMAL_FLOAT. */
- inline opt_scalar_float_mode
- decimal_float_mode_for_size (unsigned int size)
- {
- return dyn_cast <scalar_float_mode>
- (mode_for_size (size, MODE_DECIMAL_FLOAT, 0));
- }
- extern machine_mode smallest_mode_for_size (poly_uint64, enum mode_class);
- /* Find the narrowest integer mode that contains at least SIZE bits.
- Such a mode must exist. */
- inline scalar_int_mode
- smallest_int_mode_for_size (poly_uint64 size)
- {
- return as_a <scalar_int_mode> (smallest_mode_for_size (size, MODE_INT));
- }
- extern opt_scalar_int_mode int_mode_for_mode (machine_mode);
- extern opt_machine_mode bitwise_mode_for_mode (machine_mode);
- extern opt_machine_mode mode_for_vector (scalar_mode, poly_uint64);
- extern opt_machine_mode mode_for_int_vector (unsigned int, poly_uint64);
- /* Return the integer vector equivalent of MODE, if one exists. In other
- words, return the mode for an integer vector that has the same number
- of bits as MODE and the same number of elements as MODE, with the
- latter being 1 if MODE is scalar. The returned mode can be either
- an integer mode or a vector mode. */
- inline opt_machine_mode
- mode_for_int_vector (machine_mode mode)
- {
- return mode_for_int_vector (GET_MODE_UNIT_BITSIZE (mode),
- GET_MODE_NUNITS (mode));
- }
- /* A class for iterating through possible bitfield modes. */
- class bit_field_mode_iterator
- {
- public:
- bit_field_mode_iterator (HOST_WIDE_INT, HOST_WIDE_INT,
- poly_int64, poly_int64,
- unsigned int, bool);
- bool next_mode (scalar_int_mode *);
- bool prefer_smaller_modes ();
- private:
- opt_scalar_int_mode m_mode;
- /* We use signed values here because the bit position can be negative
- for invalid input such as gcc.dg/pr48335-8.c. */
- HOST_WIDE_INT m_bitsize;
- HOST_WIDE_INT m_bitpos;
- poly_int64 m_bitregion_start;
- poly_int64 m_bitregion_end;
- unsigned int m_align;
- bool m_volatilep;
- int m_count;
- };
- /* Find the best mode to use to access a bit field. */
- extern bool get_best_mode (int, int, poly_uint64, poly_uint64, unsigned int,
- unsigned HOST_WIDE_INT, bool, scalar_int_mode *);
- /* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT. */
- extern CONST_MODE_BASE_ALIGN unsigned short mode_base_align[NUM_MACHINE_MODES];
- extern unsigned get_mode_alignment (machine_mode);
- #define GET_MODE_ALIGNMENT(MODE) get_mode_alignment (MODE)
- /* For each class, get the narrowest mode in that class. */
- extern const unsigned char class_narrowest_mode[MAX_MODE_CLASS];
- #define GET_CLASS_NARROWEST_MODE(CLASS) \
- ((machine_mode) class_narrowest_mode[CLASS])
- /* The narrowest full integer mode available on the target. */
- #define NARROWEST_INT_MODE \
- (scalar_int_mode \
- (scalar_int_mode::from_int (class_narrowest_mode[MODE_INT])))
- /* Return the narrowest mode in T's class. */
- template<typename T>
- inline T
- get_narrowest_mode (T mode)
- {
- return typename mode_traits<T>::from_int
- (class_narrowest_mode[GET_MODE_CLASS (mode)]);
- }
- /* Define the integer modes whose sizes are BITS_PER_UNIT and BITS_PER_WORD
- and the mode whose class is Pmode and whose size is POINTER_SIZE. */
- extern scalar_int_mode byte_mode;
- extern scalar_int_mode word_mode;
- extern scalar_int_mode ptr_mode;
- /* Target-dependent machine mode initialization - in insn-modes.c. */
- extern void init_adjust_machine_modes (void);
- #define TRULY_NOOP_TRUNCATION_MODES_P(MODE1, MODE2) \
- (targetm.truly_noop_truncation (GET_MODE_PRECISION (MODE1), \
- GET_MODE_PRECISION (MODE2)))
- /* Return true if MODE is a scalar integer mode that fits in a
- HOST_WIDE_INT. */
- inline bool
- HWI_COMPUTABLE_MODE_P (machine_mode mode)
- {
- machine_mode mme = mode;
- return (SCALAR_INT_MODE_P (mme)
- && mode_to_precision (mme).coeffs[0] <= HOST_BITS_PER_WIDE_INT);
- }
- inline bool
- HWI_COMPUTABLE_MODE_P (scalar_int_mode mode)
- {
- return GET_MODE_PRECISION (mode) <= HOST_BITS_PER_WIDE_INT;
- }
- struct int_n_data_t {
- /* These parts are initailized by genmodes output */
- unsigned int bitsize;
- scalar_int_mode_pod m;
- /* RID_* is RID_INTN_BASE + index into this array */
- };
- /* This is also in tree.h. genmodes.c guarantees the're sorted from
- smallest bitsize to largest bitsize. */
- extern bool int_n_enabled_p[NUM_INT_N_ENTS];
- extern const int_n_data_t int_n_data[NUM_INT_N_ENTS];
- /* Return true if MODE has class MODE_INT, storing it as a scalar_int_mode
- in *INT_MODE if so. */
- template<typename T>
- inline bool
- is_int_mode (machine_mode mode, T *int_mode)
- {
- if (GET_MODE_CLASS (mode) == MODE_INT)
- {
- *int_mode = scalar_int_mode (scalar_int_mode::from_int (mode));
- return true;
- }
- return false;
- }
- /* Return true if MODE has class MODE_FLOAT, storing it as a
- scalar_float_mode in *FLOAT_MODE if so. */
- template<typename T>
- inline bool
- is_float_mode (machine_mode mode, T *float_mode)
- {
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
- *float_mode = scalar_float_mode (scalar_float_mode::from_int (mode));
- return true;
- }
- return false;
- }
- /* Return true if MODE has class MODE_COMPLEX_INT, storing it as
- a complex_mode in *CMODE if so. */
- template<typename T>
- inline bool
- is_complex_int_mode (machine_mode mode, T *cmode)
- {
- if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
- {
- *cmode = complex_mode (complex_mode::from_int (mode));
- return true;
- }
- return false;
- }
- /* Return true if MODE has class MODE_COMPLEX_FLOAT, storing it as
- a complex_mode in *CMODE if so. */
- template<typename T>
- inline bool
- is_complex_float_mode (machine_mode mode, T *cmode)
- {
- if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
- {
- *cmode = complex_mode (complex_mode::from_int (mode));
- return true;
- }
- return false;
- }
- /* Return true if MODE is a scalar integer mode with a precision
- smaller than LIMIT's precision. */
- inline bool
- is_narrower_int_mode (machine_mode mode, scalar_int_mode limit)
- {
- scalar_int_mode int_mode;
- return (is_a <scalar_int_mode> (mode, &int_mode)
- && GET_MODE_PRECISION (int_mode) < GET_MODE_PRECISION (limit));
- }
- namespace mode_iterator
- {
- /* Start mode iterator *ITER at the first mode in class MCLASS, if any. */
- template<typename T>
- inline void
- start (opt_mode<T> *iter, enum mode_class mclass)
- {
- if (GET_CLASS_NARROWEST_MODE (mclass) == E_VOIDmode)
- *iter = opt_mode<T> ();
- else
- *iter = as_a<T> (GET_CLASS_NARROWEST_MODE (mclass));
- }
- inline void
- start (machine_mode *iter, enum mode_class mclass)
- {
- *iter = GET_CLASS_NARROWEST_MODE (mclass);
- }
- /* Return true if mode iterator *ITER has not reached the end. */
- template<typename T>
- inline bool
- iterate_p (opt_mode<T> *iter)
- {
- return iter->exists ();
- }
- inline bool
- iterate_p (machine_mode *iter)
- {
- return *iter != E_VOIDmode;
- }
- /* Set mode iterator *ITER to the next widest mode in the same class,
- if any. */
- template<typename T>
- inline void
- get_wider (opt_mode<T> *iter)
- {
- *iter = GET_MODE_WIDER_MODE (iter->require ());
- }
- inline void
- get_wider (machine_mode *iter)
- {
- *iter = GET_MODE_WIDER_MODE (*iter).else_void ();
- }
- /* Set mode iterator *ITER to the next widest mode in the same class.
- Such a mode is known to exist. */
- template<typename T>
- inline void
- get_known_wider (T *iter)
- {
- *iter = GET_MODE_WIDER_MODE (*iter).require ();
- }
- /* Set mode iterator *ITER to the mode that is two times wider than the
- current one, if such a mode exists. */
- template<typename T>
- inline void
- get_2xwider (opt_mode<T> *iter)
- {
- *iter = GET_MODE_2XWIDER_MODE (iter->require ());
- }
- inline void
- get_2xwider (machine_mode *iter)
- {
- *iter = GET_MODE_2XWIDER_MODE (*iter).else_void ();
- }
- }
- /* Make ITERATOR iterate over all the modes in mode class CLASS,
- from narrowest to widest. */
- #define FOR_EACH_MODE_IN_CLASS(ITERATOR, CLASS) \
- for (mode_iterator::start (&(ITERATOR), CLASS); \
- mode_iterator::iterate_p (&(ITERATOR)); \
- mode_iterator::get_wider (&(ITERATOR)))
- /* Make ITERATOR iterate over all the modes in the range [START, END),
- in order of increasing width. */
- #define FOR_EACH_MODE(ITERATOR, START, END) \
- for ((ITERATOR) = (START); \
- (ITERATOR) != (END); \
- mode_iterator::get_known_wider (&(ITERATOR)))
- /* Make ITERATOR iterate over START and all wider modes in the same
- class, in order of increasing width. */
- #define FOR_EACH_MODE_FROM(ITERATOR, START) \
- for ((ITERATOR) = (START); \
- mode_iterator::iterate_p (&(ITERATOR)); \
- mode_iterator::get_wider (&(ITERATOR)))
- /* Make ITERATOR iterate over modes in the range [NARROWEST, END)
- in order of increasing width, where NARROWEST is the narrowest mode
- in END's class. */
- #define FOR_EACH_MODE_UNTIL(ITERATOR, END) \
- FOR_EACH_MODE (ITERATOR, get_narrowest_mode (END), END)
- /* Make ITERATOR iterate over modes in the same class as MODE, in order
- of increasing width. Start at the first mode wider than START,
- or don't iterate at all if there is no wider mode. */
- #define FOR_EACH_WIDER_MODE(ITERATOR, START) \
- for ((ITERATOR) = (START), mode_iterator::get_wider (&(ITERATOR)); \
- mode_iterator::iterate_p (&(ITERATOR)); \
- mode_iterator::get_wider (&(ITERATOR)))
- /* Make ITERATOR iterate over modes in the same class as MODE, in order
- of increasing width, and with each mode being twice the width of the
- previous mode. Start at the mode that is two times wider than START,
- or don't iterate at all if there is no such mode. */
- #define FOR_EACH_2XWIDER_MODE(ITERATOR, START) \
- for ((ITERATOR) = (START), mode_iterator::get_2xwider (&(ITERATOR)); \
- mode_iterator::iterate_p (&(ITERATOR)); \
- mode_iterator::get_2xwider (&(ITERATOR)))
- template<typename T>
- void
- gt_ggc_mx (pod_mode<T> *)
- {
- }
- template<typename T>
- void
- gt_pch_nx (pod_mode<T> *)
- {
- }
- template<typename T>
- void
- gt_pch_nx (pod_mode<T> *, void (*) (void *, void *), void *)
- {
- }
- #endif /* not HAVE_MACHINE_MODES */
|