Deal with cross-bitness compilation warnings Pt.2 (#19781)
[platform/upstream/coreclr.git] / src / inc / stdmacros.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
7 //
8 // common.h - precompiled headers include for the COM+ Execution Engine
9 //
10
11 //
12 // Make sure _ASSERTE is defined before including this header file
13 // Other than that, please keep this header self-contained so that it can be included in
14 //  all dlls
15 //
16
17
18 #ifndef _stdmacros_h_
19 #define _stdmacros_h_
20
21 #include "specstrings.h"
22 #include "contract.h"
23
24 #ifndef _ASSERTE
25 #error Please define _ASSERTE before including StdMacros.h
26 #endif
27
28 #ifdef _DEBUG
29 #define     DEBUG_ARG(x)  , x
30 #define     DEBUG_ARG1(x)  x
31 #else
32 #define     DEBUG_ARG(x) 
33 #define     DEBUG_ARG1(x)
34 #endif
35
36 #ifdef DACCESS_COMPILE
37 #define     DAC_ARG(x)  , x
38 #else
39 #define     DAC_ARG(x) 
40 #endif
41
42
43 /********************************************/
44 /*         Portability macros               */
45 /********************************************/
46
47 #ifdef _TARGET_AMD64_
48 #define AMD64_FIRST_ARG(x)  x ,
49 #define AMD64_ARG(x)        , x
50 #define AMD64_ONLY(x)       x
51 #define NOT_AMD64(x)
52 #define NOT_AMD64_ARG(x)
53 #else
54 #define AMD64_FIRST_ARG(x)
55 #define AMD64_ARG(x)
56 #define AMD64_ONLY(x)
57 #define NOT_AMD64(x)        x
58 #define NOT_AMD64_ARG(x)    , x
59 #endif
60
61 #ifdef _TARGET_X86_
62 #define X86_FIRST_ARG(x)    x ,
63 #define X86_ARG(x)          , x
64 #define X86_ONLY(x)         x
65 #define NOT_X86(x)
66 #define NOT_X86_ARG(x)
67 #else
68 #define X86_FIRST_ARG(x)
69 #define X86_ARG(x)
70 #define X86_ONLY(x)
71 #define NOT_X86(x)          x
72 #define NOT_X86_ARG(x)      , x
73 #endif
74
75 #ifdef _WIN64
76 #define WIN64_ARG(x)  , x 
77 #define WIN64_ONLY(x) x 
78 #define NOT_WIN64(x)
79 #define NOT_WIN64_ARG(x)
80 #else
81 #define WIN64_ARG(x)
82 #define WIN64_ONLY(x) 
83 #define NOT_WIN64(x)    x
84 #define NOT_WIN64_ARG(x)    , x
85 #endif // _WIN64
86
87 #ifdef _TARGET_ARM_
88 #define ARM_FIRST_ARG(x)  x ,
89 #define ARM_ARG(x)        , x
90 #define ARM_ONLY(x)       x
91 #define NOT_ARM(x)
92 #define NOT_ARM_ARG(x)
93 #else
94 #define ARM_FIRST_ARG(x)
95 #define ARM_ARG(x)
96 #define ARM_ONLY(x)
97 #define NOT_ARM(x)        x
98 #define NOT_ARM_ARG(x)    , x
99 #endif
100
101 #ifdef _TARGET_ARM64_
102 #define ARM64_FIRST_ARG(x)  x ,
103 #define ARM64_ARG(x)        , x
104 #define ARM64_ONLY(x)       x
105 #define NOT_ARM64(x)
106 #define NOT_ARM64_ARG(x)
107 #else
108 #define ARM64_FIRST_ARG(x)
109 #define ARM64_ARG(x)
110 #define ARM64_ONLY(x)
111 #define NOT_ARM64(x)        x
112 #define NOT_ARM64_ARG(x)    , x
113 #endif
114
115 #ifdef _TARGET_64BIT_
116 #define LOG2_PTRSIZE 3
117 #else
118 #define LOG2_PTRSIZE 2
119 #endif
120
121 #ifdef _WIN64
122     #define INVALID_POINTER_CC 0xcccccccccccccccc
123     #define INVALID_POINTER_CD 0xcdcdcdcdcdcdcdcd
124     #define FMT_ADDR           " %08x`%08x "
125     #define LFMT_ADDR          W(" %08x`%08x ")
126     #define DBG_ADDR(ptr)      (((UINT_PTR) (ptr)) >> 32), (((UINT_PTR) (ptr)) & 0xffffffff)
127 #else // _WIN64
128     #define INVALID_POINTER_CC 0xcccccccc
129     #define INVALID_POINTER_CD 0xcdcdcdcd
130     #define FMT_ADDR           " %08x "
131     #define LFMT_ADDR          W(" %08x ")
132     #define DBG_ADDR(ptr)      ((UINT_PTR)(ptr))
133 #endif // _WIN64
134
135 #ifdef _TARGET_ARM_
136     #define ALIGN_ACCESS        ((1<<LOG2_PTRSIZE)-1)
137 #endif
138
139
140 #ifndef ALLOC_ALIGN_CONSTANT
141 #define ALLOC_ALIGN_CONSTANT (sizeof(void*)-1)
142 #endif
143
144
145 inline void *GetTopMemoryAddress(void)
146 {
147     WRAPPER_NO_CONTRACT;
148     
149     static void *result; // = NULL;
150     if( NULL == result )
151     {
152         SYSTEM_INFO sysInfo;
153         GetSystemInfo( &sysInfo );
154         result = sysInfo.lpMaximumApplicationAddress;
155     }
156     return result;
157 }
158 inline void *GetBotMemoryAddress(void)
159 {
160     WRAPPER_NO_CONTRACT;
161     
162     static void *result; // = NULL;
163     if( NULL == result )
164     {
165         SYSTEM_INFO sysInfo;
166         GetSystemInfo( &sysInfo );
167         result = sysInfo.lpMinimumApplicationAddress;
168     }
169     return result;
170 }
171
172 #define TOP_MEMORY (GetTopMemoryAddress())
173 #define BOT_MEMORY (GetBotMemoryAddress())
174
175
176 //
177 // This macro returns val rounded up as necessary to be a multiple of alignment; alignment must be a power of 2
178 //
179 inline size_t ALIGN_UP( size_t val, size_t alignment )
180 {
181     LIMITED_METHOD_DAC_CONTRACT;
182     
183     // alignment must be a power of 2 for this implementation to work (need modulo otherwise)
184     _ASSERTE( 0 == (alignment & (alignment - 1)) ); 
185     size_t result = (val + (alignment - 1)) & ~(alignment - 1);
186     _ASSERTE( result >= val );      // check for overflow
187     return result;
188 }
189 inline void* ALIGN_UP( void* val, size_t alignment )
190 {
191     WRAPPER_NO_CONTRACT;
192     
193     return (void*) ALIGN_UP( (size_t)val, alignment );
194 }
195 inline uint8_t* ALIGN_UP( uint8_t* val, size_t alignment )
196 {
197     WRAPPER_NO_CONTRACT;
198     
199     return (uint8_t*) ALIGN_UP( (size_t)val, alignment );
200 }
201
202 inline size_t ALIGN_DOWN( size_t val, size_t alignment )
203 {
204     LIMITED_METHOD_CONTRACT;
205     
206     // alignment must be a power of 2 for this implementation to work (need modulo otherwise)
207     _ASSERTE( 0 == (alignment & (alignment - 1)) );
208     size_t result = val & ~(alignment - 1);
209     return result;
210 }
211 inline void* ALIGN_DOWN( void* val, size_t alignment )
212 {
213     WRAPPER_NO_CONTRACT;
214     return (void*) ALIGN_DOWN( (size_t)val, alignment );
215 }
216 inline uint8_t* ALIGN_DOWN( uint8_t* val, size_t alignment )
217 {
218     WRAPPER_NO_CONTRACT;
219     return (uint8_t*) ALIGN_DOWN( (size_t)val, alignment );
220 }
221
222 inline BOOL IS_ALIGNED( size_t val, size_t alignment )
223 {
224     LIMITED_METHOD_CONTRACT;
225     SUPPORTS_DAC;
226     
227     // alignment must be a power of 2 for this implementation to work (need modulo otherwise)
228     _ASSERTE( 0 == (alignment & (alignment - 1)) ); 
229     return 0 == (val & (alignment - 1));
230 }
231 inline BOOL IS_ALIGNED( const void* val, size_t alignment )
232 {
233     WRAPPER_NO_CONTRACT;
234     return IS_ALIGNED( (size_t) val, alignment );
235 }
236
237 // Rounds a ULONG up to the nearest power of two number.
238 inline ULONG RoundUpToPower2(ULONG x) 
239 {
240     if (x == 0) return 1;
241
242     x = x - 1;
243     x = x | (x >> 1);
244     x = x | (x >> 2);
245     x = x | (x >> 4);
246     x = x | (x >> 8);
247     x = x | (x >> 16);
248     return x + 1;
249 }
250
251 #ifdef ALIGN_ACCESS
252
253 // NOTE: pSrc is evaluated three times!!!
254 #define MAYBE_UNALIGNED_READ(pSrc, bits)        (IS_ALIGNED((size_t)(pSrc), sizeof(UINT##bits)) ? \
255                                                     (*(UINT##bits*)      (pSrc)) : \
256                                                     (GET_UNALIGNED_##bits(pSrc)) )
257
258 #define MAYBE_UNALIGNED_WRITE(pDst, bits, expr) do { if (IS_ALIGNED((size_t)(pDst), sizeof(UINT##bits))) \
259                                                     *(UINT##bits*)(pDst) = (UINT##bits)(expr); else \
260                                                     SET_UNALIGNED_##bits(pDst, (UINT##bits)(expr)); } while (0)
261
262 // these are necessary for MAYBE_UNALIGNED_XXX to work with UINT_PTR
263 #define GET_UNALIGNED__PTR(x) GET_UNALIGNED_PTR(x)
264 #define SET_UNALIGNED__PTR(p,x) SET_UNALIGNED_PTR(p,x)
265
266 #else // ALIGN_ACCESS
267 #define MAYBE_UNALIGNED_READ(pSrc, bits)        (*(UINT##bits*)(pSrc))
268 #define MAYBE_UNALIGNED_WRITE(pDst, bits, expr) do { *(UINT##bits*)(pDst) = (UINT##bits)(expr); } while(0)
269 #endif // ALIGN_ACCESS
270
271 //
272 // define some useful macros for logging object
273 //
274
275 #define FMT_OBJECT  "object" FMT_ADDR
276 #define FMT_HANDLE  "handle" FMT_ADDR
277 #define FMT_CLASS   "%s"
278 #define FMT_REG     "r%d "
279 #define FMT_STK     "sp%s0x%02x "
280 #define FMT_PIPTR   "%s%s pointer "
281
282
283 #define DBG_GET_CLASS_NAME(pMT)        \
284         (((pMT) == NULL)  ? NULL : (pMT)->GetClass()->GetDebugClassName())
285
286 #define DBG_CLASS_NAME_MT(pMT)         \
287         (DBG_GET_CLASS_NAME(pMT) == NULL) ? "<null-class>" : DBG_GET_CLASS_NAME(pMT) 
288
289 #define DBG_GET_MT_FROM_OBJ(obj)       \
290         (MethodTable*)((size_t)((Object*) (obj))->GetGCSafeMethodTable()) 
291
292 #define DBG_CLASS_NAME_OBJ(obj)        \
293         ((obj) == NULL)  ? "null" : DBG_CLASS_NAME_MT(DBG_GET_MT_FROM_OBJ(obj)) 
294
295 #define DBG_CLASS_NAME_IPTR2(obj,iptr) \
296         ((iptr) != 0)    ? ""     : DBG_CLASS_NAME_MT(DBG_GET_MT_FROM_OBJ(obj))
297
298 #define DBG_CLASS_NAME_IPTR(obj,iptr)  \
299         ((obj)  == NULL) ? "null" : DBG_CLASS_NAME_IPTR2(obj,iptr)
300
301 #define DBG_STK(off)                   \
302         (off >= 0) ? "+" : "-",        \
303         (off >= 0) ? off : -off
304
305 #define DBG_PIN_NAME(pin)              \
306         (pin)  ? "pinned "  : ""
307
308 #define DBG_IPTR_NAME(iptr)            \
309         (iptr) ? "interior" : "base"
310
311 #define LOG_HANDLE_OBJECT_CLASS(str1, hnd, str2, obj)    \
312         str1 FMT_HANDLE str2 FMT_OBJECT FMT_CLASS "\n",  \
313         DBG_ADDR(hnd), DBG_ADDR(obj), DBG_CLASS_NAME_OBJ(obj)
314
315 #define LOG_OBJECT_CLASS(obj)                            \
316         FMT_OBJECT FMT_CLASS "\n",                       \
317         DBG_ADDR(obj), DBG_CLASS_NAME_OBJ(obj)
318
319 #define LOG_PIPTR_OBJECT_CLASS(obj, pin, iptr)           \
320         FMT_PIPTR FMT_ADDR FMT_CLASS "\n",               \
321         DBG_PIN_NAME(pin), DBG_IPTR_NAME(iptr),          \
322         DBG_ADDR(obj), DBG_CLASS_NAME_IPTR(obj,iptr)
323
324 #define LOG_HANDLE_OBJECT(str1, hnd, str2, obj)          \
325         str1 FMT_HANDLE str2 FMT_OBJECT "\n",            \
326         DBG_ADDR(hnd), DBG_ADDR(obj)
327
328 #define LOG_PIPTR_OBJECT(obj, pin, iptr)                 \
329         FMT_PIPTR FMT_ADDR "\n",                         \
330         DBG_PIN_NAME(pin), DBG_IPTR_NAME(iptr),          \
331         DBG_ADDR(obj)
332
333 #define UNIQUE_LABEL_DEF(a,x)           a##x
334 #define UNIQUE_LABEL_DEF_X(a,x)         UNIQUE_LABEL_DEF(a,x)
335 #ifdef _MSC_VER
336 #define UNIQUE_LABEL(a)                 UNIQUE_LABEL_DEF_X(_unique_label_##a##_, __COUNTER__)
337 #else
338 #define UNIQUE_LABEL(a)                 UNIQUE_LABEL_DEF_X(_unique_label_##a##_, __LINE__)
339 #endif
340
341
342 #ifndef _countof
343 #define _countof(_array) (sizeof(_array)/sizeof(_array[0]))
344 #endif
345
346
347 // This is temporary.  LKG should provide these macros and we should then 
348 // remove STRUNCATE and _TRUNCATE from here.
349
350 /* error codes */
351 #if !defined(STRUNCATE)
352 #define STRUNCATE       80
353 #endif
354
355 /* _TRUNCATE */
356 #if !defined(_TRUNCATE)
357 #define _TRUNCATE ((size_t)-1)
358 #endif
359
360 #endif //_stdmacros_h_