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