1 /* 2 * PROJECT: ReactOS SDK 3 * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 * PURPOSE: Unaligened access helper functions 5 * COPYRIGHT: Copyright 2024 Timo Kreuzer <timo.kreuzer@reactos.org> 6 */ 7 8 #pragma once 9 10 #ifdef __cplusplus 11 extern "C" { 12 #endif 13 14 #if defined(_M_IX86) || defined(_M_AMD64) 15 #define _UNALIGNED_ACCESS_ALLOWED 1 16 #else // defined(_M_IX86) || defined(_M_AMD64) 17 #define _UNALIGNED_ACCESS_ALLOWED 0 18 #endif // defined(_M_IX86) || defined(_M_AMD64) 19 20 #if _UNALIGNED_ACCESS_ALLOWED 21 22 __forceinline 23 unsigned short ReadUnalignedU16(const unsigned short * p)24ReadUnalignedU16(const unsigned short* p) 25 { 26 return *p; 27 } 28 29 __forceinline 30 unsigned long ReadUnalignedU32(const unsigned long * p)31ReadUnalignedU32(const unsigned long* p) 32 { 33 return *p; 34 } 35 36 __forceinline 37 unsigned long long ReadUnalignedU64(const unsigned long long * p)38ReadUnalignedU64(const unsigned long long* p) 39 { 40 return *p; 41 } 42 43 __forceinline 44 void WriteUnalignedU16(unsigned short * p,unsigned short val)45WriteUnalignedU16(unsigned short* p, unsigned short val) 46 { 47 *p = val; 48 } 49 50 __forceinline 51 void WriteUnalignedU32(unsigned long * p,unsigned long val)52WriteUnalignedU32(unsigned long* p, unsigned long val) 53 { 54 *p = val; 55 } 56 57 __forceinline 58 void WriteUnalignedU64(unsigned long long * p,unsigned long long val)59WriteUnalignedU64(unsigned long long* p, unsigned long long val) 60 { 61 *p = val; 62 } 63 64 #else // !UNALIGNED_ACCESS_ALLOWED 65 66 __forceinline 67 unsigned short 68 ReadUnalignedU16(const unsigned short* p) 69 { 70 unsigned char* p1 = (unsigned char*)p; 71 return (unsigned short)(p1[0] | (p1[1] << 8)); 72 } 73 74 __forceinline 75 unsigned long 76 ReadUnalignedU32(const unsigned long* p) 77 { 78 unsigned char* p1 = (unsigned char*)p; 79 return (((unsigned long)p1[0] << 0) | 80 ((unsigned long)p1[1] << 8) | 81 ((unsigned long)p1[2] << 16) | 82 ((unsigned long)p1[3] << 24)); 83 } 84 85 __forceinline 86 unsigned long long 87 ReadUnalignedU64(const unsigned long long* p) 88 { 89 unsigned char* p1 = (unsigned char*)p; 90 return (((unsigned long long)p1[0] << 0) | 91 ((unsigned long long)p1[1] << 8) | 92 ((unsigned long long)p1[2] << 16) | 93 ((unsigned long long)p1[3] << 24) | 94 ((unsigned long long)p1[4] << 32) | 95 ((unsigned long long)p1[5] << 40) | 96 ((unsigned long long)p1[6] << 48) | 97 ((unsigned long long)p1[7] << 56)); 98 } 99 100 __forceinline 101 void 102 WriteUnalignedU16(unsigned short* p, unsigned short val) 103 { 104 unsigned char* p1 = (unsigned char*)p; 105 p1[0] = (unsigned char)(val >> 0); 106 p1[1] = (unsigned char)(val >> 8); 107 } 108 109 __forceinline 110 void 111 WriteUnalignedU32(unsigned long* p, unsigned long val) 112 { 113 unsigned char* p1 = (unsigned char*)p; 114 p1[0] = (unsigned char)(val >> 0); 115 p1[1] = (unsigned char)(val >> 8); 116 p1[2] = (unsigned char)(val >> 16); 117 p1[3] = (unsigned char)(val >> 24); 118 } 119 120 __forceinline 121 void 122 WriteUnalignedU64(unsigned long long* p, unsigned long long val) 123 { 124 unsigned char* p1 = (unsigned char*)p; 125 p1[0] = (unsigned char)(val >> 0); 126 p1[1] = (unsigned char)(val >> 8); 127 p1[2] = (unsigned char)(val >> 16); 128 p1[3] = (unsigned char)(val >> 24); 129 p1[4] = (unsigned char)(val >> 32); 130 p1[5] = (unsigned char)(val >> 40); 131 p1[6] = (unsigned char)(val >> 48); 132 p1[7] = (unsigned char)(val >> 56); 133 } 134 135 #endif // !UNALIGNED_ACCESS_ALLOWED 136 137 #ifdef _WIN64 138 #define ReadUnalignedUlongPtr ReadUnalignedU64 139 #define WriteUnalignedUlongPtr WriteUnalignedU64 140 #else // _WIN64 141 #define ReadUnalignedUlongPtr ReadUnalignedU32 142 #define WriteUnalignedUlongPtr WriteUnalignedU32 143 #endif // _WIN64 144 145 #ifdef __cplusplus 146 } // extern "C" 147 #endif 148