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(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 * For cases where the size to be used is not fixed at compile time, 295 * there are 296 * stn_{endian}_p(ptr, sz, val) 297 * which stores @val to @ptr as an @endian-order number @sz bytes in size 298 * and 299 * ldn_{endian}_p(ptr, sz) 300 * which loads @sz bytes from @ptr as an unsigned @endian-order number 301 * and returns it in a uint64_t. 302 */ 303 304 static inline int ldub_p(const void *ptr) 305 { 306 return *(uint8_t *)ptr; 307 } 308 309 static inline int ldsb_p(const void *ptr) 310 { 311 return *(int8_t *)ptr; 312 } 313 314 static inline void stb_p(void *ptr, uint8_t v) 315 { 316 *(uint8_t *)ptr = v; 317 } 318 319 /* 320 * Any compiler worth its salt will turn these memcpy into native unaligned 321 * operations. Thus we don't need to play games with packed attributes, or 322 * inline byte-by-byte stores. 323 * Some compilation environments (eg some fortify-source implementations) 324 * may intercept memcpy() in a way that defeats the compiler optimization, 325 * though, so we use __builtin_memcpy() to give ourselves the best chance 326 * of good performance. 327 */ 328 329 static inline int lduw_he_p(const void *ptr) 330 { 331 uint16_t r; 332 __builtin_memcpy(&r, ptr, sizeof(r)); 333 return r; 334 } 335 336 static inline int ldsw_he_p(const void *ptr) 337 { 338 int16_t r; 339 __builtin_memcpy(&r, ptr, sizeof(r)); 340 return r; 341 } 342 343 static inline void stw_he_p(void *ptr, uint16_t v) 344 { 345 __builtin_memcpy(ptr, &v, sizeof(v)); 346 } 347 348 static inline int ldl_he_p(const void *ptr) 349 { 350 int32_t r; 351 __builtin_memcpy(&r, ptr, sizeof(r)); 352 return r; 353 } 354 355 static inline void stl_he_p(void *ptr, uint32_t v) 356 { 357 __builtin_memcpy(ptr, &v, sizeof(v)); 358 } 359 360 static inline uint64_t ldq_he_p(const void *ptr) 361 { 362 uint64_t r; 363 __builtin_memcpy(&r, ptr, sizeof(r)); 364 return r; 365 } 366 367 static inline void stq_he_p(void *ptr, uint64_t v) 368 { 369 __builtin_memcpy(ptr, &v, sizeof(v)); 370 } 371 372 static inline int lduw_le_p(const void *ptr) 373 { 374 return (uint16_t)le_bswap(lduw_he_p(ptr), 16); 375 } 376 377 static inline int ldsw_le_p(const void *ptr) 378 { 379 return (int16_t)le_bswap(lduw_he_p(ptr), 16); 380 } 381 382 static inline int ldl_le_p(const void *ptr) 383 { 384 return le_bswap(ldl_he_p(ptr), 32); 385 } 386 387 static inline uint64_t ldq_le_p(const void *ptr) 388 { 389 return le_bswap(ldq_he_p(ptr), 64); 390 } 391 392 static inline void stw_le_p(void *ptr, uint16_t v) 393 { 394 stw_he_p(ptr, le_bswap(v, 16)); 395 } 396 397 static inline void stl_le_p(void *ptr, uint32_t v) 398 { 399 stl_he_p(ptr, le_bswap(v, 32)); 400 } 401 402 static inline void stq_le_p(void *ptr, uint64_t v) 403 { 404 stq_he_p(ptr, le_bswap(v, 64)); 405 } 406 407 /* float access */ 408 409 static inline float32 ldfl_le_p(const void *ptr) 410 { 411 CPU_FloatU u; 412 u.l = ldl_le_p(ptr); 413 return u.f; 414 } 415 416 static inline void stfl_le_p(void *ptr, float32 v) 417 { 418 CPU_FloatU u; 419 u.f = v; 420 stl_le_p(ptr, u.l); 421 } 422 423 static inline float64 ldfq_le_p(const void *ptr) 424 { 425 CPU_DoubleU u; 426 u.ll = ldq_le_p(ptr); 427 return u.d; 428 } 429 430 static inline void stfq_le_p(void *ptr, float64 v) 431 { 432 CPU_DoubleU u; 433 u.d = v; 434 stq_le_p(ptr, u.ll); 435 } 436 437 static inline int lduw_be_p(const void *ptr) 438 { 439 return (uint16_t)be_bswap(lduw_he_p(ptr), 16); 440 } 441 442 static inline int ldsw_be_p(const void *ptr) 443 { 444 return (int16_t)be_bswap(lduw_he_p(ptr), 16); 445 } 446 447 static inline int ldl_be_p(const void *ptr) 448 { 449 return be_bswap(ldl_he_p(ptr), 32); 450 } 451 452 static inline uint64_t ldq_be_p(const void *ptr) 453 { 454 return be_bswap(ldq_he_p(ptr), 64); 455 } 456 457 static inline void stw_be_p(void *ptr, uint16_t v) 458 { 459 stw_he_p(ptr, be_bswap(v, 16)); 460 } 461 462 static inline void stl_be_p(void *ptr, uint32_t v) 463 { 464 stl_he_p(ptr, be_bswap(v, 32)); 465 } 466 467 static inline void stq_be_p(void *ptr, uint64_t v) 468 { 469 stq_he_p(ptr, be_bswap(v, 64)); 470 } 471 472 /* float access */ 473 474 static inline float32 ldfl_be_p(const void *ptr) 475 { 476 CPU_FloatU u; 477 u.l = ldl_be_p(ptr); 478 return u.f; 479 } 480 481 static inline void stfl_be_p(void *ptr, float32 v) 482 { 483 CPU_FloatU u; 484 u.f = v; 485 stl_be_p(ptr, u.l); 486 } 487 488 static inline float64 ldfq_be_p(const void *ptr) 489 { 490 CPU_DoubleU u; 491 u.ll = ldq_be_p(ptr); 492 return u.d; 493 } 494 495 static inline void stfq_be_p(void *ptr, float64 v) 496 { 497 CPU_DoubleU u; 498 u.d = v; 499 stq_be_p(ptr, u.ll); 500 } 501 502 static inline unsigned long leul_to_cpu(unsigned long v) 503 { 504 #if HOST_LONG_BITS == 32 505 return le_bswap(v, 32); 506 #elif HOST_LONG_BITS == 64 507 return le_bswap(v, 64); 508 #else 509 # error Unknown sizeof long 510 #endif 511 } 512 513 /* Store v to p as a sz byte value in host order */ 514 #define DO_STN_LDN_P(END) \ 515 static inline void stn_## END ## _p(void *ptr, int sz, uint64_t v) \ 516 { \ 517 switch (sz) { \ 518 case 1: \ 519 stb_p(ptr, v); \ 520 break; \ 521 case 2: \ 522 stw_ ## END ## _p(ptr, v); \ 523 break; \ 524 case 4: \ 525 stl_ ## END ## _p(ptr, v); \ 526 break; \ 527 case 8: \ 528 stq_ ## END ## _p(ptr, v); \ 529 break; \ 530 default: \ 531 g_assert_not_reached(); \ 532 } \ 533 } \ 534 static inline uint64_t ldn_## END ## _p(const void *ptr, int sz) \ 535 { \ 536 switch (sz) { \ 537 case 1: \ 538 return ldub_p(ptr); \ 539 case 2: \ 540 return lduw_ ## END ## _p(ptr); \ 541 case 4: \ 542 return (uint32_t)ldl_ ## END ## _p(ptr); \ 543 case 8: \ 544 return ldq_ ## END ## _p(ptr); \ 545 default: \ 546 g_assert_not_reached(); \ 547 } \ 548 } 549 550 DO_STN_LDN_P(he) 551 DO_STN_LDN_P(le) 552 DO_STN_LDN_P(be) 553 554 #undef DO_STN_LDN_P 555 556 #undef le_bswap 557 #undef be_bswap 558 #undef le_bswaps 559 #undef be_bswaps 560 561 #endif /* BSWAP_H */ 562