summaryrefslogtreecommitdiff
path: root/src/jit/vartype.h
blob: db358dad77c762f2d93c71b76ae9176b7e8f024e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
// 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 _WIN64
#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_
/*****************************************************************************/