00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef __SYSDEPS_ENDIAN_H__
00033 #define __SYSDEPS_ENDIAN_H__
00034
00035 #include "SysDeps/host_type.h"
00036
00037 namespace Onikiri {
00038
00039 inline u8 ConvertEndian(u8 value)
00040 {
00041 return value;
00042 }
00043
00044
00045 #if defined(COMPILER_IS_MSVC)
00046 inline u16 ConvertEndian(u16 value)
00047 {
00048 return _byteswap_ushort(value);
00049 }
00050 inline u32 ConvertEndian(u32 value)
00051 {
00052 return _byteswap_ulong(value);
00053 }
00054 inline u64 ConvertEndian(u64 value)
00055 {
00056 return _byteswap_uint64(value);
00057 }
00058
00059 #define CONVERTENDIAN16_DEFINED
00060 #define CONVERTENDIAN32_DEFINED
00061 #define CONVERTENDIAN64_DEFINED
00062
00063 #elif defined(COMPILER_IS_GCC) // #if defined(COMPILER_IS_MSVC)
00064 #if defined(HOST_IS_X86_64) || defined(HOST_IS_X86)
00065 inline u16 ConvertEndian(u16 value)
00066 {
00067 __asm__("rorw $8, %0" : "=r" (value) : "0" (value));
00068 return value;
00069 }
00070
00071 inline u32 ConvertEndian(u32 value)
00072 {
00073 __asm__("bswap %0" : "=r" (value) : "0" (value));
00074 return value;
00075 }
00076
00077 #define CONVERTENDIAN16_DEFINED
00078 #define CONVERTENDIAN32_DEFINED
00079
00080 #if defined(HOST_IS_X86_64)
00081 inline u64 ConvertEndian(u64 value)
00082 {
00083 __asm__("bswap %0" : "=r" (value) : "0" (value));
00084 return value;
00085 }
00086 #define CONVERTENDIAN64_DEFINED
00087 #endif // #if defined(HOST_IS_X86_64)
00088
00089 #endif // #if defined(HOST_IS_X86_64) || defined(HOST_IS_X86)
00090 #endif // #elif defined(COMPILER_IS_GCC)
00091
00092
00093
00094
00095 #ifndef CONVERTENDIAN16_DEFINED
00096 inline u16 ConvertEndian(u16 value)
00097 {
00098 return
00099 ((value & 0x00ff) << 8)
00100 | (value >> 8);
00101 }
00102 #else
00103 # undef CONVERTENDIAN16_DEFINED
00104 #endif // #ifndef CONVERTENDIAN16_DEFINED
00105
00106 #ifndef CONVERTENDIAN32_DEFINED
00107 inline u32 ConvertEndian(u32 value)
00108 {
00109 return
00110 ((u32)ConvertEndian((u16)value) << 16)
00111 | (u32)ConvertEndian((u16)(value >> 16));
00112 }
00113 #else
00114 # undef CONVERTENDIAN32_DEFINED
00115 #endif // #ifndef CONVERTENDIAN32_DEFINED
00116
00117 #ifndef CONVERTENDIAN64_DEFINED
00118 inline u64 ConvertEndian(u64 value)
00119 {
00120 return
00121 ((u64)ConvertEndian((u32)value) << 32)
00122 | (u64)ConvertEndian((u32)(value >> 32));
00123 }
00124 #else
00125 # undef CONVERTENDIAN64_DEFINED
00126 #endif // #ifndef CONVERTENDIAN64_DEFINED
00127
00128
00129 inline s8 ConvertEndian(s8 value)
00130 {
00131 return (s8)ConvertEndian((u8)value);
00132 }
00133 inline s16 ConvertEndian(s16 value)
00134 {
00135 return (s16)ConvertEndian((u16)value);
00136 }
00137 inline s32 ConvertEndian(s32 value)
00138 {
00139 return (s32)ConvertEndian((u32)value);
00140 }
00141 inline s64 ConvertEndian(s64 value)
00142 {
00143 return (s64)ConvertEndian((u64)value);
00144 }
00145
00146
00147
00148
00149 #if defined(HOST_IS_LITTLE_ENDIAN)
00150 template <typename T>
00151 inline T EndianHostToLittle(T value)
00152 {
00153 return value;
00154 }
00155 template <typename T>
00156 inline T EndianHostToBig(T value)
00157 {
00158 return ConvertEndian(value);
00159 }
00160
00161 #elif defined(HOST_IS_BIG_ENDIAN)
00162 template <typename T>
00163 inline T EndianHostToLittle(T value)
00164 {
00165 return ConvertEndian(value);
00166 }
00167 template <typename T>
00168 inline T EndianHostToBig(T value)
00169 {
00170 return value;
00171 }
00172 #else
00173 # error "host endian is not specified"
00174 #endif
00175
00176
00177 template <typename T>
00178 inline T EndianLittleToHost(T value)
00179 {
00180 return EndianHostToLittle(value);
00181 }
00182 template <typename T>
00183 inline T EndianBigToHost(T value)
00184 {
00185 return EndianHostToBig(value);
00186 }
00187
00188
00189 template <typename T>
00190 inline T EndianSpecifiedToHost(T value, bool bigEndian)
00191 {
00192 if (bigEndian)
00193 return EndianBigToHost(value);
00194 else
00195 return EndianLittleToHost(value);
00196 }
00197 template <typename T>
00198 inline T EndianHostToSpecified(T value, bool bigEndian)
00199 {
00200 return EndianSpecifiedToHost(value, bigEndian);
00201 }
00202
00203
00204 template <typename T>
00205 inline void EndianSpecifiedToHostInPlace(T &value, bool bigEndian)
00206 {
00207 value = EndianSpecifiedToHost(value, bigEndian);
00208 }
00209 template <typename T>
00210 inline void EndianHostToSpecifiedInPlace(T &value, bool bigEndian)
00211 {
00212 value = EndianHostToSpecified(value, bigEndian);
00213 }
00214
00215 }
00216
00217 #endif