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