Fix reading Time zone rules using Julian days (#17672)
[platform/upstream/coreclr.git] / src / jit / vartype.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 /*****************************************************************************/
6 #ifndef _VARTYPE_H_
7 #define _VARTYPE_H_
8 /*****************************************************************************/
9 #include "error.h"
10
11 enum var_types_classification
12 {
13     VTF_ANY = 0x0000,
14     VTF_INT = 0x0001,
15     VTF_UNS = 0x0002, // type is unsigned
16     VTF_FLT = 0x0004,
17     VTF_GCR = 0x0008, // type is GC ref
18     VTF_BYR = 0x0010, // type is Byref
19     VTF_I   = 0x0020, // is machine sized
20     VTF_S   = 0x0040, // is a struct type
21 };
22
23 enum var_types : BYTE
24 {
25 #define DEF_TP(tn, nm, jitType, verType, sz, sze, asze, st, al, tf, howUsed) TYP_##tn,
26 #include "typelist.h"
27 #undef DEF_TP
28
29     TYP_COUNT,
30
31     TYP_lastIntrins = TYP_DOUBLE
32 };
33
34 /*****************************************************************************
35  * C-style pointers are implemented as TYP_INT or TYP_LONG depending on the
36  * platform
37  */
38
39 #ifdef _TARGET_64BIT_
40 #define TYP_I_IMPL TYP_LONG
41 #define TYP_U_IMPL TYP_ULONG
42 #define TYPE_REF_IIM TYPE_REF_LNG
43 #else
44 #define TYP_I_IMPL TYP_INT
45 #define TYP_U_IMPL TYP_UINT
46 #define TYPE_REF_IIM TYPE_REF_INT
47 #ifdef _PREFAST_
48 // We silence this in the 32-bit build because for portability, we like to have asserts like this:
49 // assert(op2->gtType == TYP_INT || op2->gtType == TYP_I_IMPL);
50 // This is obviously redundant for 32-bit builds, but we don't want to have ifdefs and different
51 // asserts just for 64-bit builds, so for now just silence the assert
52 #pragma warning(disable : 6287) // warning 6287: the left and right sub-expressions are identical
53 #endif                          //_PREFAST_
54 #endif
55
56 /*****************************************************************************/
57
58 const extern BYTE varTypeClassification[TYP_COUNT];
59
60 // make any class with a TypeGet member also have a function TypeGet() that does the same thing
61 template <class T>
62 inline var_types TypeGet(T* t)
63 {
64     return t->TypeGet();
65 }
66
67 // make a TypeGet function which is the identity function for var_types
68 // the point of this and the preceding template is now you can make template functions
69 // that work on var_types as well as any object that exposes a TypeGet method.
70 // such as all of these varTypeIs* functions
71 inline var_types TypeGet(var_types v)
72 {
73     return v;
74 }
75
76 #ifdef FEATURE_SIMD
77 template <class T>
78 inline bool varTypeIsSIMD(T vt)
79 {
80     switch (TypeGet(vt))
81     {
82         case TYP_SIMD8:
83         case TYP_SIMD12:
84         case TYP_SIMD16:
85         case TYP_SIMD32:
86             return true;
87         default:
88             return false;
89     }
90 }
91 #else  // FEATURE_SIMD
92
93 // Always return false if FEATURE_SIMD is not enabled
94 template <class T>
95 inline bool varTypeIsSIMD(T vt)
96 {
97     return false;
98 }
99 #endif // !FEATURE_SIMD
100
101 template <class T>
102 inline bool varTypeIsIntegral(T vt)
103 {
104     return ((varTypeClassification[TypeGet(vt)] & (VTF_INT)) != 0);
105 }
106
107 template <class T>
108 inline bool varTypeIsIntegralOrI(T vt)
109 {
110     return ((varTypeClassification[TypeGet(vt)] & (VTF_INT | VTF_I)) != 0);
111 }
112
113 template <class T>
114 inline bool varTypeIsUnsigned(T vt)
115 {
116     return ((varTypeClassification[TypeGet(vt)] & (VTF_UNS)) != 0);
117 }
118
119 // If "vt" is an unsigned integral type, returns the corresponding signed integral type, otherwise
120 // return "vt".
121 inline var_types varTypeUnsignedToSigned(var_types vt)
122 {
123     if (varTypeIsUnsigned(vt))
124     {
125         switch (vt)
126         {
127             case TYP_BOOL:
128             case TYP_UBYTE:
129                 return TYP_BYTE;
130             case TYP_USHORT:
131                 return TYP_SHORT;
132             case TYP_UINT:
133                 return TYP_INT;
134             case TYP_ULONG:
135                 return TYP_LONG;
136             default:
137                 unreached();
138         }
139     }
140     else
141     {
142         return vt;
143     }
144 }
145
146 template <class T>
147 inline bool varTypeIsFloating(T vt)
148 {
149     return ((varTypeClassification[TypeGet(vt)] & (VTF_FLT)) != 0);
150 }
151
152 template <class T>
153 inline bool varTypeIsArithmetic(T vt)
154 {
155     return ((varTypeClassification[TypeGet(vt)] & (VTF_INT | VTF_FLT)) != 0);
156 }
157
158 template <class T>
159 inline unsigned varTypeGCtype(T vt)
160 {
161     return (unsigned)(varTypeClassification[TypeGet(vt)] & (VTF_GCR | VTF_BYR));
162 }
163
164 template <class T>
165 inline bool varTypeIsGC(T vt)
166 {
167     return (varTypeGCtype(vt) != 0);
168 }
169
170 template <class T>
171 inline bool varTypeIsI(T vt)
172 {
173     return ((varTypeClassification[TypeGet(vt)] & VTF_I) != 0);
174 }
175
176 template <class T>
177 inline bool varTypeCanReg(T vt)
178 {
179     return ((varTypeClassification[TypeGet(vt)] & (VTF_INT | VTF_I | VTF_FLT)) != 0);
180 }
181
182 template <class T>
183 inline bool varTypeIsByte(T vt)
184 {
185     return (TypeGet(vt) >= TYP_BOOL) && (TypeGet(vt) <= TYP_UBYTE);
186 }
187
188 template <class T>
189 inline bool varTypeIsShort(T vt)
190 {
191     return (TypeGet(vt) == TYP_SHORT) || (TypeGet(vt) == TYP_USHORT);
192 }
193
194 template <class T>
195 inline bool varTypeIsSmall(T vt)
196 {
197     return (TypeGet(vt) >= TYP_BOOL) && (TypeGet(vt) <= TYP_USHORT);
198 }
199
200 template <class T>
201 inline bool varTypeIsSmallInt(T vt)
202 {
203     return (TypeGet(vt) >= TYP_BYTE) && (TypeGet(vt) <= TYP_USHORT);
204 }
205
206 template <class T>
207 inline bool varTypeIsIntOrI(T vt)
208 {
209     return ((TypeGet(vt) == TYP_INT)
210 #ifdef _TARGET_64BIT_
211             || (TypeGet(vt) == TYP_I_IMPL)
212 #endif // _TARGET_64BIT_
213                 );
214 }
215
216 template <class T>
217 inline bool genActualTypeIsIntOrI(T vt)
218 {
219     return ((TypeGet(vt) >= TYP_BOOL) && (TypeGet(vt) <= TYP_U_IMPL));
220 }
221
222 template <class T>
223 inline bool varTypeIsLong(T vt)
224 {
225     return (TypeGet(vt) >= TYP_LONG) && (TypeGet(vt) <= TYP_ULONG);
226 }
227
228 template <class T>
229 inline bool varTypeIsMultiReg(T vt)
230 {
231 #ifdef _TARGET_64BIT_
232     return false;
233 #else
234     return (TypeGet(vt) == TYP_LONG);
235 #endif
236 }
237
238 template <class T>
239 inline bool varTypeIsSingleReg(T vt)
240 {
241     return !varTypeIsMultiReg(vt);
242 }
243
244 template <class T>
245 inline bool varTypeIsComposite(T vt)
246 {
247     return (!varTypeIsArithmetic(TypeGet(vt)) && TypeGet(vt) != TYP_VOID);
248 }
249
250 // Is this type promotable?
251 // In general only structs are promotable.
252 // However, a SIMD type, e.g. TYP_SIMD may be handled as either a struct, OR a
253 // fully-promoted register type.
254 // On 32-bit systems longs are split into an upper and lower half, and they are
255 // handled as if they are structs with two integer fields.
256
257 template <class T>
258 inline bool varTypeIsPromotable(T vt)
259 {
260     return (varTypeIsStruct(vt) || (TypeGet(vt) == TYP_BLK)
261 #if !defined(_TARGET_64BIT_)
262             || varTypeIsLong(vt)
263 #endif // !defined(_TARGET_64BIT_)
264                 );
265 }
266
267 template <class T>
268 inline bool varTypeIsStruct(T vt)
269 {
270     return ((varTypeClassification[TypeGet(vt)] & VTF_S) != 0);
271 }
272
273 template <class T>
274 inline bool varTypeIsEnregisterableStruct(T vt)
275 {
276     return (TypeGet(vt) != TYP_STRUCT);
277 }
278
279 /*****************************************************************************/
280 #endif // _VARTYPE_H_
281 /*****************************************************************************/