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