openMSX
vla.hh
Go to the documentation of this file.
1 #ifndef VLA_HH
2 #define VLA_HH
3 
4 // VLAs (Variable Length Array's) are part of C99, but not of C++98.
5 // Though gcc does support VLAs as an extension. For VC++ we have to emulate
6 // them via alloca.
7 
8 #ifndef _MSC_VER
9 
10 #define VLA(TYPE, NAME, LENGTH) \
11  TYPE NAME[(LENGTH)]
12 
13 #if defined __i386 || defined __x86_64
14 #define VLA_ALIGNED(TYPE, NAME, LENGTH, ALIGNMENT) \
15  TYPE NAME[(LENGTH)] __attribute__((__aligned__((ALIGNMENT))))
16 #else
17 // Except on x86/x86-64, GCC can align VLAs within a stack frame, but it makes
18 // no guarantees if the requested alignment is larger than the alignment of the
19 // stack frame itself.
20 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16660
21 #define VLA_ALIGNED(TYPE, NAME, LENGTH, ALIGNMENT) \
22  UNABLE_TO_GUARANTEE_VLA_ALIGNMENT_ON_THIS_ARCHITECTURE
23 #endif
24 
25 #else
26 
27 #define VLA(TYPE, NAME, LENGTH) \
28  auto NAME = static_cast<TYPE*>(_alloca(sizeof(TYPE) * (LENGTH)))
29 
30 // mfeingol: evil hack alert
31 #define VLA_ALIGNED(TYPE, NAME, LENGTH, ALIGNMENT) \
32  size_t cbAlign##NAME = (ALIGNMENT); \
33  void* palloc##NAME = _alloca(sizeof(TYPE) * (LENGTH) + cbAlign##NAME); \
34  palloc##NAME = (void*)((size_t(palloc##NAME) + cbAlign##NAME - 1UL) & ~(cbAlign##NAME - 1UL)); \
35  auto NAME = static_cast<TYPE*>(palloc##NAME); \
36 
37 #endif
38 
39 // Macro to align a buffer that might be used by SSE instructions.
40 // On platforms without SSE no (extra) alignment is performed.
41 #ifdef __SSE2__
42 #define VLA_SSE_ALIGNED(TYPE, NAME, LENGTH) VLA_ALIGNED(TYPE, NAME, LENGTH, 16)
43 #else
44 #define VLA_SSE_ALIGNED(TYPE, NAME, LENGTH) VLA(TYPE, NAME, LENGTH)
45 #endif
46 
47 #endif // VLA_HH