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
9
10
11--*/
12
13#ifndef __PAL_ENDIAN_H__
14#define __PAL_ENDIAN_H__
15
16#ifdef __cplusplus
17extern "C++" {
18inline UINT16 SWAP16(UINT16 x)
19{
20 return (x >> 8) | (x << 8);
21}
22
23inline UINT32 SWAP32(UINT32 x)
24{
25 return (x >> 24) |
26 ((x >> 8) & 0x0000FF00L) |
27 ((x & 0x0000FF00L) << 8) |
28 (x << 24);
29}
30
31}
32#endif // __cplusplus
33
34#if BIGENDIAN
35#ifdef __cplusplus
36extern "C++" {
37inline UINT16 VAL16(UINT16 x)
38{
39 return SWAP16(x);
40}
41
42inline UINT32 VAL32(UINT32 x)
43{
44 return SWAP32(x);
45}
46
47inline UINT64 VAL64(UINT64 x)
48{
49 return ((UINT64)VAL32(x) << 32) | VAL32(x >> 32);
50}
51
52inline void SwapString(WCHAR *szString)
53{
54 unsigned i;
55 for (i = 0; szString[i] != L'\0'; i++)
56 {
57 szString[i] = VAL16(szString[i]);
58 }
59}
60
61inline void SwapStringLength(WCHAR *szString, ULONG StringLength)
62{
63 unsigned i;
64 for (i = 0; i < StringLength; i++)
65 {
66 szString[i] = VAL16(szString[i]);
67 }
68}
69
70inline void SwapGuid(GUID *pGuid)
71{
72 pGuid->Data1 = VAL32(pGuid->Data1);
73 pGuid->Data2 = VAL16(pGuid->Data2);
74 pGuid->Data3 = VAL16(pGuid->Data3);
75}
76};
77#else // __cplusplus
78/* C Version of VAL functionality. Swap functions omitted for lack of use in C code */
79#define VAL16(x) (((x) >> 8) | ((x) << 8))
80#define VAL32(y) (((y) >> 24) | (((y) >> 8) & 0x0000FF00L) | (((y) & 0x0000FF00L) << 8) | ((y) << 24))
81#define VAL64(z) (((UINT64)VAL32(z) << 32) | VAL32((z) >> 32))
82#endif // __cplusplus
83
84#else // !BIGENDIAN
85
86#define VAL16(x) x
87#define VAL32(x) x
88#define VAL64(x) x
89#define SwapString(x)
90#define SwapStringLength(x, y)
91#define SwapGuid(x)
92
93#endif // !BIGENDIAN
94
95#ifdef BIT64
96#define VALPTR(x) VAL64(x)
97#else
98#define VALPTR(x) VAL32(x)
99#endif
100
101#ifdef _ARM_
102#define LOG2_PTRSIZE 2
103#define ALIGN_ACCESS ((1<<LOG2_PTRSIZE)-1)
104#endif
105
106#if defined(ALIGN_ACCESS) && !defined(_MSC_VER)
107#ifdef __cplusplus
108extern "C++" {
109// Get Unaligned values from a potentially unaligned object
110inline UINT16 GET_UNALIGNED_16(const void *pObject)
111{
112 UINT16 temp;
113 memcpy(&temp, pObject, sizeof(temp));
114 return temp;
115}
116inline UINT32 GET_UNALIGNED_32(const void *pObject)
117{
118 UINT32 temp;
119 memcpy(&temp, pObject, sizeof(temp));
120 return temp;
121}
122inline UINT64 GET_UNALIGNED_64(const void *pObject)
123{
124 UINT64 temp;
125 memcpy(&temp, pObject, sizeof(temp));
126 return temp;
127}
128
129// Set Value on an potentially unaligned object
130inline void SET_UNALIGNED_16(void *pObject, UINT16 Value)
131{
132 memcpy(pObject, &Value, sizeof(UINT16));
133}
134inline void SET_UNALIGNED_32(void *pObject, UINT32 Value)
135{
136 memcpy(pObject, &Value, sizeof(UINT32));
137}
138inline void SET_UNALIGNED_64(void *pObject, UINT64 Value)
139{
140 memcpy(pObject, &Value, sizeof(UINT64));
141}
142}
143#endif // __cplusplus
144
145#else // defined(ALIGN_ACCESS) && !defined(_MSC_VER)
146
147// Get Unaligned values from a potentially unaligned object
148#define GET_UNALIGNED_16(_pObject) (*(UINT16 UNALIGNED *)(_pObject))
149#define GET_UNALIGNED_32(_pObject) (*(UINT32 UNALIGNED *)(_pObject))
150#define GET_UNALIGNED_64(_pObject) (*(UINT64 UNALIGNED *)(_pObject))
151
152// Set Value on an potentially unaligned object
153#define SET_UNALIGNED_16(_pObject, _Value) (*(UNALIGNED UINT16 *)(_pObject)) = (UINT16)(_Value)
154#define SET_UNALIGNED_32(_pObject, _Value) (*(UNALIGNED UINT32 *)(_pObject)) = (UINT32)(_Value)
155#define SET_UNALIGNED_64(_pObject, _Value) (*(UNALIGNED UINT64 *)(_pObject)) = (UINT64)(_Value)
156
157#endif // defined(ALIGN_ACCESS) && !defined(_MSC_VER)
158
159// Get Unaligned values from a potentially unaligned object and swap the value
160#define GET_UNALIGNED_VAL16(_pObject) VAL16(GET_UNALIGNED_16(_pObject))
161#define GET_UNALIGNED_VAL32(_pObject) VAL32(GET_UNALIGNED_32(_pObject))
162#define GET_UNALIGNED_VAL64(_pObject) VAL64(GET_UNALIGNED_64(_pObject))
163
164// Set a swap Value on an potentially unaligned object
165#define SET_UNALIGNED_VAL16(_pObject, _Value) SET_UNALIGNED_16(_pObject, VAL16((UINT16)_Value))
166#define SET_UNALIGNED_VAL32(_pObject, _Value) SET_UNALIGNED_32(_pObject, VAL32((UINT32)_Value))
167#define SET_UNALIGNED_VAL64(_pObject, _Value) SET_UNALIGNED_64(_pObject, VAL64((UINT64)_Value))
168
169#endif // __PAL_ENDIAN_H__
170