diff options
Diffstat (limited to 'src/jit/vartype.h')
-rw-r--r-- | src/jit/vartype.h | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/src/jit/vartype.h b/src/jit/vartype.h new file mode 100644 index 0000000000..550aeb9c5b --- /dev/null +++ b/src/jit/vartype.h @@ -0,0 +1,285 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*****************************************************************************/ +#ifndef _VARTYPE_H_ +#define _VARTYPE_H_ +/*****************************************************************************/ +#include "error.h" + +enum var_types_classification +{ + VTF_ANY = 0x0000, + VTF_INT = 0x0001, + VTF_UNS = 0x0002, // type is unsigned + VTF_FLT = 0x0004, + VTF_GCR = 0x0008, // type is GC ref + VTF_BYR = 0x0010, // type is Byref + VTF_I = 0x0020, // is machine sized + VTF_S = 0x0040, // is a struct type +}; + +DECLARE_TYPED_ENUM(var_types, BYTE) +{ +#define DEF_TP(tn, nm, jitType, verType, sz, sze, asze, st, al, tf, howUsed) TYP_##tn, +#include "typelist.h" +#undef DEF_TP + + TYP_COUNT, + + TYP_lastIntrins = TYP_DOUBLE +} +END_DECLARE_TYPED_ENUM(var_types, BYTE) + +/***************************************************************************** + * C-style pointers are implemented as TYP_INT or TYP_LONG depending on the + * platform + */ + +#ifdef _TARGET_64BIT_ +#define TYP_I_IMPL TYP_LONG +#define TYP_U_IMPL TYP_ULONG +#define TYPE_REF_IIM TYPE_REF_LNG +#else +#define TYP_I_IMPL TYP_INT +#define TYP_U_IMPL TYP_UINT +#define TYPE_REF_IIM TYPE_REF_INT +#ifdef _PREFAST_ +// We silence this in the 32-bit build because for portability, we like to have asserts like this: +// assert(op2->gtType == TYP_INT || op2->gtType == TYP_I_IMPL); +// This is obviously redundant for 32-bit builds, but we don't want to have ifdefs and different +// asserts just for 64-bit builds, so for now just silence the assert +#pragma warning(disable : 6287) // warning 6287: the left and right sub-expressions are identical +#endif //_PREFAST_ +#endif + +/*****************************************************************************/ + +const extern BYTE varTypeClassification[TYP_COUNT]; + +// make any class with a TypeGet member also have a function TypeGet() that does the same thing +template <class T> +inline var_types TypeGet(T* t) +{ + return t->TypeGet(); +} + +// make a TypeGet function which is the identity function for var_types +// the point of this and the preceding template is now you can make template functions +// that work on var_types as well as any object that exposes a TypeGet method. +// such as all of these varTypeIs* functions +inline var_types TypeGet(var_types v) +{ + return v; +} + +#ifdef FEATURE_SIMD +template <class T> +inline bool varTypeIsSIMD(T vt) +{ + switch (TypeGet(vt)) + { + case TYP_SIMD8: + case TYP_SIMD12: + case TYP_SIMD16: +#ifdef FEATURE_AVX_SUPPORT + case TYP_SIMD32: +#endif // FEATURE_AVX_SUPPORT + return true; + default: + return false; + } +} +#else // FEATURE_SIMD + +// Always return false if FEATURE_SIMD is not enabled +template <class T> +inline bool varTypeIsSIMD(T vt) +{ + return false; +} +#endif // !FEATURE_SIMD + +template <class T> +inline bool varTypeIsIntegral(T vt) +{ + return ((varTypeClassification[TypeGet(vt)] & (VTF_INT)) != 0); +} + +template <class T> +inline bool varTypeIsIntegralOrI(T vt) +{ + return ((varTypeClassification[TypeGet(vt)] & (VTF_INT | VTF_I)) != 0); +} + +template <class T> +inline bool varTypeIsUnsigned(T vt) +{ + return ((varTypeClassification[TypeGet(vt)] & (VTF_UNS)) != 0); +} + +// If "vt" is an unsigned integral type, returns the corresponding signed integral type, otherwise +// return "vt". +inline var_types varTypeUnsignedToSigned(var_types vt) +{ + if (varTypeIsUnsigned(vt)) + { + switch (vt) + { + case TYP_BOOL: + case TYP_UBYTE: + return TYP_BYTE; + case TYP_USHORT: + case TYP_CHAR: + return TYP_SHORT; + case TYP_UINT: + return TYP_INT; + case TYP_ULONG: + return TYP_LONG; + default: + unreached(); + } + } + else + { + return vt; + } +} + +template <class T> +inline bool varTypeIsFloating(T vt) +{ + return ((varTypeClassification[TypeGet(vt)] & (VTF_FLT)) != 0); +} + +template <class T> +inline bool varTypeIsArithmetic(T vt) +{ + return ((varTypeClassification[TypeGet(vt)] & (VTF_INT | VTF_FLT)) != 0); +} + +template <class T> +inline unsigned varTypeGCtype(T vt) +{ + return (unsigned)(varTypeClassification[TypeGet(vt)] & (VTF_GCR | VTF_BYR)); +} + +template <class T> +inline bool varTypeIsGC(T vt) +{ + return (varTypeGCtype(vt) != 0); +} + +template <class T> +inline bool varTypeIsI(T vt) +{ + return ((varTypeClassification[TypeGet(vt)] & VTF_I) != 0); +} + +template <class T> +inline bool varTypeCanReg(T vt) +{ + return ((varTypeClassification[TypeGet(vt)] & (VTF_INT | VTF_I | VTF_FLT)) != 0); +} + +template <class T> +inline bool varTypeIsByte(T vt) +{ + return (TypeGet(vt) >= TYP_BOOL) && (TypeGet(vt) <= TYP_UBYTE); +} + +template <class T> +inline bool varTypeIsShort(T vt) +{ + return (TypeGet(vt) >= TYP_CHAR) && (TypeGet(vt) <= TYP_USHORT); +} + +template <class T> +inline bool varTypeIsSmall(T vt) +{ + return (TypeGet(vt) >= TYP_BOOL) && (TypeGet(vt) <= TYP_USHORT); +} + +template <class T> +inline bool varTypeIsSmallInt(T vt) +{ + return (TypeGet(vt) >= TYP_BYTE) && (TypeGet(vt) <= TYP_USHORT); +} + +template <class T> +inline bool varTypeIsIntOrI(T vt) +{ + return ((TypeGet(vt) == TYP_INT) +#ifdef _TARGET_64BIT_ + || (TypeGet(vt) == TYP_I_IMPL) +#endif // _TARGET_64BIT_ + ); +} + +template <class T> +inline bool genActualTypeIsIntOrI(T vt) +{ + return ((TypeGet(vt) >= TYP_BOOL) && (TypeGet(vt) <= TYP_U_IMPL)); +} + +template <class T> +inline bool varTypeIsLong(T vt) +{ + return (TypeGet(vt) >= TYP_LONG) && (TypeGet(vt) <= TYP_ULONG); +} + +template <class T> +inline bool varTypeIsMultiReg(T vt) +{ +#ifdef _TARGET_64BIT_ + return false; +#else + return (TypeGet(vt) == TYP_LONG); +#endif +} + +template <class T> +inline bool varTypeIsSingleReg(T vt) +{ + return !varTypeIsMultiReg(vt); +} + +template <class T> +inline bool varTypeIsComposite(T vt) +{ + return (!varTypeIsArithmetic(TypeGet(vt)) && TypeGet(vt) != TYP_VOID); +} + +// Is this type promotable? +// In general only structs are promotable. +// However, a SIMD type, e.g. TYP_SIMD may be handled as either a struct, OR a +// fully-promoted register type. +// On 32-bit systems longs are split into an upper and lower half, and they are +// handled as if they are structs with two integer fields. + +template <class T> +inline bool varTypeIsPromotable(T vt) +{ + return (varTypeIsStruct(vt) || (TypeGet(vt) == TYP_BLK) +#if !defined(_TARGET_64BIT_) + || varTypeIsLong(vt) +#endif // !defined(_TARGET_64BIT_) + ); +} + +template <class T> +inline bool varTypeIsStruct(T vt) +{ + return ((varTypeClassification[TypeGet(vt)] & VTF_S) != 0); +} + +template <class T> +inline bool varTypeIsEnregisterableStruct(T vt) +{ + return (TypeGet(vt) != TYP_STRUCT); +} + +/*****************************************************************************/ +#endif // _VARTYPE_H_ +/*****************************************************************************/ |