1 #ifndef BSWAP_H 2 #define BSWAP_H 3 4 #include "fpu/softfloat.h" 5 6 #ifdef CONFIG_MACHINE_BSWAP_H 7 # include <sys/endian.h> 8 # include <machine/bswap.h> 9 #elif defined(__FreeBSD__) 10 # include <sys/endian.h> 11 #elif defined(CONFIG_BYTESWAP_H) 12 # include <byteswap.h> 13 14 static inline uint16_t bswap16(uint16_t x) 15 { 16 return bswap_16(x); 17 } 18 19 static inline uint32_t bswap32(uint32_t x) 20 { 21 return bswap_32(x); 22 } 23 24 static inline uint64_t bswap64(uint64_t x) 25 { 26 return bswap_64(x); 27 } 28 # else 29 static inline uint16_t bswap16(uint16_t x) 30 { 31 return (((x & 0x00ff) << 8) | 32 ((x & 0xff00) >> 8)); 33 } 34 35 static inline uint32_t bswap32(uint32_t x) 36 { 37 return (((x & 0x000000ffU) << 24) | 38 ((x & 0x0000ff00U) << 8) | 39 ((x & 0x00ff0000U) >> 8) | 40 ((x & 0xff000000U) >> 24)); 41 } 42 43 static inline uint64_t bswap64(uint64_t x) 44 { 45 return (((x & 0x00000000000000ffULL) << 56) | 46 ((x & 0x000000000000ff00ULL) << 40) | 47 ((x & 0x0000000000ff0000ULL) << 24) | 48 ((x & 0x00000000ff000000ULL) << 8) | 49 ((x & 0x000000ff00000000ULL) >> 8) | 50 ((x & 0x0000ff0000000000ULL) >> 24) | 51 ((x & 0x00ff000000000000ULL) >> 40) | 52 ((x & 0xff00000000000000ULL) >> 56)); 53 } 54 #endif /* ! CONFIG_MACHINE_BSWAP_H */ 55 56 static inline void bswap16s(uint16_t *s) 57 { 58 *s = bswap16(*s); 59 } 60 61 static inline void bswap32s(uint32_t *s) 62 { 63 *s = bswap32(*s); 64 } 65 66 static inline void bswap64s(uint64_t *s) 67 { 68 *s = bswap64(*s); 69 } 70 71 #if defined(HOST_WORDS_BIGENDIAN) 72 #define be_bswap(v, size) (v) 73 #define le_bswap(v, size) glue(bswap, size)(v) 74 #define be_bswaps(v, size) 75 #define le_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0) 76 #else 77 #define le_bswap(v, size) (v) 78 #define be_bswap(v, size) glue(bswap, size)(v) 79 #define le_bswaps(v, size) 80 #define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0) 81 #endif 82 83 /** 84 * Endianness conversion functions between host cpu and specified endianness. 85 * (We list the complete set of prototypes produced by the macros below 86 * to assist people who search the headers to find their definitions.) 87 * 88 * uint16_t le16_to_cpu(uint16_t v); 89 * uint32_t le32_to_cpu(uint32_t v); 90 * uint64_t le64_to_cpu(uint64_t v); 91 * uint16_t be16_to_cpu(uint16_t v); 92 * uint32_t be32_to_cpu(uint32_t v); 93 * uint64_t be64_to_cpu(uint64_t v); 94 * 95 * Convert the value @v from the specified format to the native 96 * endianness of the host CPU by byteswapping if necessary, and 97 * return the converted value. 98 * 99 * uint16_t cpu_to_le16(uint16_t v); 100 * uint32_t cpu_to_le32(uint32_t v); 101 * uint64_t cpu_to_le64(uint64_t v); 102 * uint16_t cpu_to_be16(uint16_t v); 103 * uint32_t cpu_to_be32(uint32_t v); 104 * uint64_t cpu_to_be64(uint64_t v); 105 * 106 * Convert the value @v from the native endianness of the host CPU to 107 * the specified format by byteswapping if necessary, and return 108 * the converted value. 109 * 110 * void le16_to_cpus(uint16_t *v); 111 * void le32_to_cpus(uint32_t *v); 112 * void le64_to_cpus(uint64_t *v); 113 * void be16_to_cpus(uint16_t *v); 114 * void be32_to_cpus(uint32_t *v); 115 * void be64_to_cpus(uint64_t *v); 116 * 117 * Do an in-place conversion of the value pointed to by @v from the 118 * specified format to the native endianness of the host CPU. 119 * 120 * void cpu_to_le16s(uint16_t *v); 121 * void cpu_to_le32s(uint32_t *v); 122 * void cpu_to_le64s(uint64_t *v); 123 * void cpu_to_be16s(uint16_t *v); 124 * void cpu_to_be32s(uint32_t *v); 125 * void cpu_to_be64s(uint64_t *v); 126 * 127 * Do an in-place conversion of the value pointed to by @v from the 128 * native endianness of the host CPU to the specified format. 129 * 130 * Both X_to_cpu() and cpu_to_X() perform the same operation; you 131 * should use whichever one is better documenting of the function your 132 * code is performing. 133 * 134 * Do not use these functions for conversion of values which are in guest 135 * memory, since the data may not be sufficiently aligned for the host CPU's 136 * load and store instructions. Instead you should use the ld*_p() and 137 * st*_p() functions, which perform loads and stores of data of any 138 * required size and endianness and handle possible misalignment. 139 */ 140 141 #define CPU_CONVERT(endian, size, type)\ 142 static inline type endian ## size ## _to_cpu(type v)\ 143 {\ 144 return glue(endian, _bswap)(v, size);\ 145 }\ 146 \ 147 static inline type cpu_to_ ## endian ## size(type v)\ 148 {\ 149 return glue(endian, _bswap)(v, size);\ 150 }\ 151 \ 152 static inline void endian ## size ## _to_cpus(type *p)\ 153 {\ 154 glue(endian, _bswaps)(p, size);\ 155 }\ 156 \ 157 static inline void cpu_to_ ## endian ## size ## s(type *p)\ 158 {\ 159 glue(endian, _bswaps)(p, size);\ 160 } 161 162 CPU_CONVERT(be, 16, uint16_t) 163 CPU_CONVERT(be, 32, uint32_t) 164 CPU_CONVERT(be, 64, uint64_t) 165 166 CPU_CONVERT(le, 16, uint16_t) 167 CPU_CONVERT(le, 32, uint32_t) 168 CPU_CONVERT(le, 64, uint64_t) 169 170 /* len must be one of 1, 2, 4 */ 171 static inline uint32_t qemu_bswap_len(uint32_t value, int len) 172 { 173 return bswap32(value) >> (32 - 8 * len); 174 } 175 176 /* 177 * Same as cpu_to_le{16,32}, except that gcc will figure the result is 178 * a compile-time constant if you pass in a constant. So this can be 179 * used to initialize static variables. 180 */ 181 #if defined(HOST_WORDS_BIGENDIAN) 182 # define const_le32(_x) \ 183 ((((_x) & 0x000000ffU) << 24) | \ 184 (((_x) & 0x0000ff00U) << 8) | \ 185 (((_x) & 0x00ff0000U) >> 8) | \ 186 (((_x) & 0xff000000U) >> 24)) 187 # define const_le16(_x) \ 188 ((((_x) & 0x00ff) << 8) | \ 189 (((_x) & 0xff00) >> 8)) 190 #else 191 # define const_le32(_x) (_x) 192 # define const_le16(_x) (_x) 193 #endif 194 195 /* Unions for reinterpreting between floats and integers. */ 196 197 typedef union { 198 float32 f; 199 uint32_t l; 200 } CPU_FloatU; 201 202 typedef union { 203 float64 d; 204 #if defined(HOST_WORDS_BIGENDIAN) 205 struct { 206 uint32_t upper; 207 uint32_t lower; 208 } l; 209 #else 210 struct { 211 uint32_t lower; 212 uint32_t upper; 213 } l; 214 #endif 215 uint64_t ll; 216 } CPU_DoubleU; 217 218 typedef union { 219 floatx80 d; 220 struct { 221 uint64_t lower; 222 uint16_t upper; 223 } l; 224 } CPU_LDoubleU; 225 226 typedef union { 227 float128 q; 228 #if defined(HOST_WORDS_BIGENDIAN) 229 struct { 230 uint32_t upmost; 231 uint32_t upper; 232 uint32_t lower; 233 uint32_t lowest; 234 } l; 235 struct { 236 uint64_t upper; 237 uint64_t lower; 238 } ll; 239 #else 240 struct { 241 uint32_t lowest; 242 uint32_t lower; 243 uint32_t upper; 244 uint32_t upmost; 245 } l; 246 struct { 247 uint64_t lower; 248 uint64_t upper; 249 } ll; 250 #endif 251 } CPU_QuadU; 252 253 /* unaligned/endian-independent pointer access */ 254 255 /* 256 * the generic syntax is: 257 * 258 * load: ld{type}{sign}{size}{endian}_p(ptr) 259 * 260 * store: st{type}{size}{endian}_p(ptr, val) 261 * 262 * Note there are small differences with the softmmu access API! 263 * 264 * type is: 265 * (empty): integer access 266 * f : float access 267 * 268 * sign is: 269 * (empty): for 32 or 64 bit sizes (including floats and doubles) 270 * u : unsigned 271 * s : signed 272 * 273 * size is: 274 * b: 8 bits 275 * w: 16 bits 276 * l: 32 bits 277 * q: 64 bits 278 * 279 * endian is: 280 * he : host endian 281 * be : big endian 282 * le : little endian 283 * te : target endian 284 * (except for byte accesses, which have no endian infix). 285 * 286 * The target endian accessors are obviously only available to source 287 * files which are built per-target; they are defined in cpu-all.h. 288 * 289 * In all cases these functions take a host pointer. 290 * For accessors that take a guest address rather than a 291 * host address, see the cpu_{ld,st}_* accessors defined in 292 * cpu_ldst.h. 293 */ 294 295 static inline int ldub_p(const void *ptr) 296 { 297 return *(uint8_t *)ptr; 298 } 299 300 static inline int ldsb_p(const void *ptr) 301 { 302 return *(int8_t *)ptr; 303 } 304 305 static inline void stb_p(void *ptr, uint8_t v) 306 { 307 *(uint8_t *)ptr = v; 308 } 309 310 /* Any compiler worth its salt will turn these memcpy into native unaligned 311 operations. Thus we don't need to play games with packed attributes, or 312 inline byte-by-byte stores. */ 313 314 static inline int lduw_he_p(const void *ptr) 315 { 316 uint16_t r; 317 memcpy(&r, ptr, sizeof(r)); 318 return r; 319 } 320 321 static inline int ldsw_he_p(const void *ptr) 322 { 323 int16_t r; 324 memcpy(&r, ptr, sizeof(r)); 325 return r; 326 } 327 328 static inline void stw_he_p(void *ptr, uint16_t v) 329 { 330 memcpy(ptr, &v, sizeof(v)); 331 } 332 333 static inline int ldl_he_p(const void *ptr) 334 { 335 int32_t r; 336 memcpy(&r, ptr, sizeof(r)); 337 return r; 338 } 339 340 static inline void stl_he_p(void *ptr, uint32_t v) 341 { 342 memcpy(ptr, &v, sizeof(v)); 343 } 344 345 static inline uint64_t ldq_he_p(const void *ptr) 346 { 347 uint64_t r; 348 memcpy(&r, ptr, sizeof(r)); 349 return r; 350 } 351 352 static inline void stq_he_p(void *ptr, uint64_t v) 353 { 354 memcpy(ptr, &v, sizeof(v)); 355 } 356 357 static inline int lduw_le_p(const void *ptr) 358 { 359 return (uint16_t)le_bswap(lduw_he_p(ptr), 16); 360 } 361 362 static inline int ldsw_le_p(const void *ptr) 363 { 364 return (int16_t)le_bswap(lduw_he_p(ptr), 16); 365 } 366 367 static inline int ldl_le_p(const void *ptr) 368 { 369 return le_bswap(ldl_he_p(ptr), 32); 370 } 371 372 static inline uint64_t ldq_le_p(const void *ptr) 373 { 374 return le_bswap(ldq_he_p(ptr), 64); 375 } 376 377 static inline void stw_le_p(void *ptr, uint16_t v) 378 { 379 stw_he_p(ptr, le_bswap(v, 16)); 380 } 381 382 static inline void stl_le_p(void *ptr, uint32_t v) 383 { 384 stl_he_p(ptr, le_bswap(v, 32)); 385 } 386 387 static inline void stq_le_p(void *ptr, uint64_t v) 388 { 389 stq_he_p(ptr, le_bswap(v, 64)); 390 } 391 392 /* float access */ 393 394 static inline float32 ldfl_le_p(const void *ptr) 395 { 396 CPU_FloatU u; 397 u.l = ldl_le_p(ptr); 398 return u.f; 399 } 400 401 static inline void stfl_le_p(void *ptr, float32 v) 402 { 403 CPU_FloatU u; 404 u.f = v; 405 stl_le_p(ptr, u.l); 406 } 407 408 static inline float64 ldfq_le_p(const void *ptr) 409 { 410 CPU_DoubleU u; 411 u.ll = ldq_le_p(ptr); 412 return u.d; 413 } 414 415 static inline void stfq_le_p(void *ptr, float64 v) 416 { 417 CPU_DoubleU u; 418 u.d = v; 419 stq_le_p(ptr, u.ll); 420 } 421 422 static inline int lduw_be_p(const void *ptr) 423 { 424 return (uint16_t)be_bswap(lduw_he_p(ptr), 16); 425 } 426 427 static inline int ldsw_be_p(const void *ptr) 428 { 429 return (int16_t)be_bswap(lduw_he_p(ptr), 16); 430 } 431 432 static inline int ldl_be_p(const void *ptr) 433 { 434 return be_bswap(ldl_he_p(ptr), 32); 435 } 436 437 static inline uint64_t ldq_be_p(const void *ptr) 438 { 439 return be_bswap(ldq_he_p(ptr), 64); 440 } 441 442 static inline void stw_be_p(void *ptr, uint16_t v) 443 { 444 stw_he_p(ptr, be_bswap(v, 16)); 445 } 446 447 static inline void stl_be_p(void *ptr, uint32_t v) 448 { 449 stl_he_p(ptr, be_bswap(v, 32)); 450 } 451 452 static inline void stq_be_p(void *ptr, uint64_t v) 453 { 454 stq_he_p(ptr, be_bswap(v, 64)); 455 } 456 457 /* float access */ 458 459 static inline float32 ldfl_be_p(const void *ptr) 460 { 461 CPU_FloatU u; 462 u.l = ldl_be_p(ptr); 463 return u.f; 464 } 465 466 static inline void stfl_be_p(void *ptr, float32 v) 467 { 468 CPU_FloatU u; 469 u.f = v; 470 stl_be_p(ptr, u.l); 471 } 472 473 static inline float64 ldfq_be_p(const void *ptr) 474 { 475 CPU_DoubleU u; 476 u.ll = ldq_be_p(ptr); 477 return u.d; 478 } 479 480 static inline void stfq_be_p(void *ptr, float64 v) 481 { 482 CPU_DoubleU u; 483 u.d = v; 484 stq_be_p(ptr, u.ll); 485 } 486 487 static inline unsigned long leul_to_cpu(unsigned long v) 488 { 489 #if HOST_LONG_BITS == 32 490 return le_bswap(v, 32); 491 #elif HOST_LONG_BITS == 64 492 return le_bswap(v, 64); 493 #else 494 # error Unknown sizeof long 495 #endif 496 } 497 498 #undef le_bswap 499 #undef be_bswap 500 #undef le_bswaps 501 #undef be_bswaps 502 503 #endif /* BSWAP_H */ 504