Revision 612d590e include/qemu/bswap.h

b/include/qemu/bswap.h
215 215
#define leul_to_cpu(v) (v)
216 216
#endif
217 217

  
218
#undef le_bswap
219
#undef be_bswap
220
#undef le_bswaps
221
#undef be_bswaps
222

  
223 218
/* len must be one of 1, 2, 4 */
224 219
static inline uint32_t qemu_bswap_len(uint32_t value, int len)
225 220
{
......
377 372
    memcpy(ptr, &v, sizeof(v));
378 373
}
379 374

  
380
/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
381
   kernel handles unaligned load/stores may give better results, but
382
   it is a system wide setting : bad */
383
#if defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
384

  
385
/* conservative code for little endian unaligned accesses */
386 375
static inline int lduw_le_p(const void *ptr)
387 376
{
388
#ifdef _ARCH_PPC
389
    int val;
390
    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
391
    return val;
392
#else
393
    const uint8_t *p = ptr;
394
    return p[0] | (p[1] << 8);
395
#endif
377
    return (uint16_t)le_bswap(lduw_p(ptr), 16);
396 378
}
397 379

  
398 380
static inline int ldsw_le_p(const void *ptr)
399 381
{
400
#ifdef _ARCH_PPC
401
    int val;
402
    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
403
    return (int16_t)val;
404
#else
405
    const uint8_t *p = ptr;
406
    return (int16_t)(p[0] | (p[1] << 8));
407
#endif
382
    return (int16_t)le_bswap(lduw_p(ptr), 16);
408 383
}
409 384

  
410 385
static inline int ldl_le_p(const void *ptr)
411 386
{
412
#ifdef _ARCH_PPC
413
    int val;
414
    __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
415
    return val;
416
#else
417
    const uint8_t *p = ptr;
418
    return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
419
#endif
387
    return le_bswap(ldl_p(ptr), 32);
420 388
}
421 389

  
422 390
static inline uint64_t ldq_le_p(const void *ptr)
423 391
{
424
    const uint8_t *p = ptr;
425
    uint32_t v1, v2;
426
    v1 = ldl_le_p(p);
427
    v2 = ldl_le_p(p + 4);
428
    return v1 | ((uint64_t)v2 << 32);
392
    return le_bswap(ldq_p(ptr), 64);
429 393
}
430 394

  
431 395
static inline void stw_le_p(void *ptr, int v)
432 396
{
433
#ifdef _ARCH_PPC
434
    __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
435
#else
436
    uint8_t *p = ptr;
437
    p[0] = v;
438
    p[1] = v >> 8;
439
#endif
397
    stw_p(ptr, le_bswap(v, 16));
440 398
}
441 399

  
442 400
static inline void stl_le_p(void *ptr, int v)
443 401
{
444
#ifdef _ARCH_PPC
445
    __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
446
#else
447
    uint8_t *p = ptr;
448
    p[0] = v;
449
    p[1] = v >> 8;
450
    p[2] = v >> 16;
451
    p[3] = v >> 24;
452
#endif
402
    stl_p(ptr, le_bswap(v, 32));
453 403
}
454 404

  
455 405
static inline void stq_le_p(void *ptr, uint64_t v)
456 406
{
457
    uint8_t *p = ptr;
458
    stl_le_p(p, (uint32_t)v);
459
    stl_le_p(p + 4, v >> 32);
407
    stq_p(ptr, le_bswap(v, 64));
460 408
}
461 409

  
462 410
/* float access */
463 411

  
464 412
static inline float32 ldfl_le_p(const void *ptr)
465 413
{
466
    union {
467
        float32 f;
468
        uint32_t i;
469
    } u;
470
    u.i = ldl_le_p(ptr);
414
    CPU_FloatU u;
415
    u.l = ldl_le_p(ptr);
471 416
    return u.f;
472 417
}
473 418

  
474 419
static inline void stfl_le_p(void *ptr, float32 v)
475 420
{
476
    union {
477
        float32 f;
478
        uint32_t i;
479
    } u;
421
    CPU_FloatU u;
480 422
    u.f = v;
481
    stl_le_p(ptr, u.i);
423
    stl_le_p(ptr, u.l);
482 424
}
483 425

  
484 426
static inline float64 ldfq_le_p(const void *ptr)
485 427
{
486 428
    CPU_DoubleU u;
487
    u.l.lower = ldl_le_p(ptr);
488
    u.l.upper = ldl_le_p(ptr + 4);
429
    u.ll = ldq_le_p(ptr);
489 430
    return u.d;
490 431
}
491 432

  
......
493 434
{
494 435
    CPU_DoubleU u;
495 436
    u.d = v;
496
    stl_le_p(ptr, u.l.lower);
497
    stl_le_p(ptr + 4, u.l.upper);
437
    stq_le_p(ptr, u.ll);
498 438
}
499 439

  
500
#else
501

  
502
static inline int lduw_le_p(const void *ptr)
503
{
504
    return *(uint16_t *)ptr;
505
}
506

  
507
static inline int ldsw_le_p(const void *ptr)
508
{
509
    return *(int16_t *)ptr;
510
}
511

  
512
static inline int ldl_le_p(const void *ptr)
513
{
514
    return *(uint32_t *)ptr;
515
}
516

  
517
static inline uint64_t ldq_le_p(const void *ptr)
518
{
519
    return *(uint64_t *)ptr;
520
}
521

  
522
static inline void stw_le_p(void *ptr, int v)
523
{
524
    *(uint16_t *)ptr = v;
525
}
526

  
527
static inline void stl_le_p(void *ptr, int v)
528
{
529
    *(uint32_t *)ptr = v;
530
}
531

  
532
static inline void stq_le_p(void *ptr, uint64_t v)
533
{
534
    *(uint64_t *)ptr = v;
535
}
536

  
537
/* float access */
538

  
539
static inline float32 ldfl_le_p(const void *ptr)
540
{
541
    return *(float32 *)ptr;
542
}
543

  
544
static inline float64 ldfq_le_p(const void *ptr)
545
{
546
    return *(float64 *)ptr;
547
}
548

  
549
static inline void stfl_le_p(void *ptr, float32 v)
550
{
551
    *(float32 *)ptr = v;
552
}
553

  
554
static inline void stfq_le_p(void *ptr, float64 v)
555
{
556
    *(float64 *)ptr = v;
557
}
558
#endif
559

  
560
#if !defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
561

  
562 440
static inline int lduw_be_p(const void *ptr)
563 441
{
564
#if defined(__i386__)
565
    int val;
566
    asm volatile ("movzwl %1, %0\n"
567
                  "xchgb %b0, %h0\n"
568
                  : "=q" (val)
569
                  : "m" (*(uint16_t *)ptr));
570
    return val;
571
#else
572
    const uint8_t *b = ptr;
573
    return ((b[0] << 8) | b[1]);
574
#endif
442
    return (uint16_t)be_bswap(lduw_p(ptr), 16);
575 443
}
576 444

  
577 445
static inline int ldsw_be_p(const void *ptr)
578 446
{
579
#if defined(__i386__)
580
    int val;
581
    asm volatile ("movzwl %1, %0\n"
582
                  "xchgb %b0, %h0\n"
583
                  : "=q" (val)
584
                  : "m" (*(uint16_t *)ptr));
585
    return (int16_t)val;
586
#else
587
    const uint8_t *b = ptr;
588
    return (int16_t)((b[0] << 8) | b[1]);
589
#endif
447
    return (int16_t)be_bswap(lduw_p(ptr), 16);
590 448
}
591 449

  
592 450
static inline int ldl_be_p(const void *ptr)
593 451
{
594
#if defined(__i386__) || defined(__x86_64__)
595
    int val;
596
    asm volatile ("movl %1, %0\n"
597
                  "bswap %0\n"
598
                  : "=r" (val)
599
                  : "m" (*(uint32_t *)ptr));
600
    return val;
601
#else
602
    const uint8_t *b = ptr;
603
    return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
604
#endif
452
    return be_bswap(ldl_p(ptr), 32);
605 453
}
606 454

  
607 455
static inline uint64_t ldq_be_p(const void *ptr)
608 456
{
609
    uint32_t a,b;
610
    a = ldl_be_p(ptr);
611
    b = ldl_be_p((uint8_t *)ptr + 4);
612
    return (((uint64_t)a<<32)|b);
457
    return be_bswap(ldq_p(ptr), 64);
613 458
}
614 459

  
615 460
static inline void stw_be_p(void *ptr, int v)
616 461
{
617
#if defined(__i386__)
618
    asm volatile ("xchgb %b0, %h0\n"
619
                  "movw %w0, %1\n"
620
                  : "=q" (v)
621
                  : "m" (*(uint16_t *)ptr), "0" (v));
622
#else
623
    uint8_t *d = (uint8_t *) ptr;
624
    d[0] = v >> 8;
625
    d[1] = v;
626
#endif
462
    stw_p(ptr, be_bswap(v, 16));
627 463
}
628 464

  
629 465
static inline void stl_be_p(void *ptr, int v)
630 466
{
631
#if defined(__i386__) || defined(__x86_64__)
632
    asm volatile ("bswap %0\n"
633
                  "movl %0, %1\n"
634
                  : "=r" (v)
635
                  : "m" (*(uint32_t *)ptr), "0" (v));
636
#else
637
    uint8_t *d = (uint8_t *) ptr;
638
    d[0] = v >> 24;
639
    d[1] = v >> 16;
640
    d[2] = v >> 8;
641
    d[3] = v;
642
#endif
467
    stl_p(ptr, be_bswap(v, 32));
643 468
}
644 469

  
645 470
static inline void stq_be_p(void *ptr, uint64_t v)
646 471
{
647
    stl_be_p(ptr, v >> 32);
648
    stl_be_p((uint8_t *)ptr + 4, v);
472
    stq_p(ptr, be_bswap(v, 64));
649 473
}
650 474

  
651 475
/* float access */
652 476

  
653 477
static inline float32 ldfl_be_p(const void *ptr)
654 478
{
655
    union {
656
        float32 f;
657
        uint32_t i;
658
    } u;
659
    u.i = ldl_be_p(ptr);
479
    CPU_FloatU u;
480
    u.l = ldl_be_p(ptr);
660 481
    return u.f;
661 482
}
662 483

  
663 484
static inline void stfl_be_p(void *ptr, float32 v)
664 485
{
665
    union {
666
        float32 f;
667
        uint32_t i;
668
    } u;
486
    CPU_FloatU u;
669 487
    u.f = v;
670
    stl_be_p(ptr, u.i);
488
    stl_be_p(ptr, u.l);
671 489
}
672 490

  
673 491
static inline float64 ldfq_be_p(const void *ptr)
674 492
{
675 493
    CPU_DoubleU u;
676
    u.l.upper = ldl_be_p(ptr);
677
    u.l.lower = ldl_be_p((uint8_t *)ptr + 4);
494
    u.ll = ldq_be_p(ptr);
678 495
    return u.d;
679 496
}
680 497

  
......
682 499
{
683 500
    CPU_DoubleU u;
684 501
    u.d = v;
685
    stl_be_p(ptr, u.l.upper);
686
    stl_be_p((uint8_t *)ptr + 4, u.l.lower);
687
}
688

  
689
#else
690

  
691
static inline int lduw_be_p(const void *ptr)
692
{
693
    return *(uint16_t *)ptr;
694
}
695

  
696
static inline int ldsw_be_p(const void *ptr)
697
{
698
    return *(int16_t *)ptr;
699
}
700

  
701
static inline int ldl_be_p(const void *ptr)
702
{
703
    return *(uint32_t *)ptr;
704
}
705

  
706
static inline uint64_t ldq_be_p(const void *ptr)
707
{
708
    return *(uint64_t *)ptr;
709
}
710

  
711
static inline void stw_be_p(void *ptr, int v)
712
{
713
    *(uint16_t *)ptr = v;
714
}
715

  
716
static inline void stl_be_p(void *ptr, int v)
717
{
718
    *(uint32_t *)ptr = v;
719
}
720

  
721
static inline void stq_be_p(void *ptr, uint64_t v)
722
{
723
    *(uint64_t *)ptr = v;
724
}
725

  
726
/* float access */
727

  
728
static inline float32 ldfl_be_p(const void *ptr)
729
{
730
    return *(float32 *)ptr;
731
}
732

  
733
static inline float64 ldfq_be_p(const void *ptr)
734
{
735
    return *(float64 *)ptr;
736
}
737

  
738
static inline void stfl_be_p(void *ptr, float32 v)
739
{
740
    *(float32 *)ptr = v;
741
}
742

  
743
static inline void stfq_be_p(void *ptr, float64 v)
744
{
745
    *(float64 *)ptr = v;
502
    stq_be_p(ptr, u.ll);
746 503
}
747 504

  
748
#endif
505
#undef le_bswap
506
#undef be_bswap
507
#undef le_bswaps
508
#undef be_bswaps
749 509

  
750 510
#endif /* BSWAP_H */

Also available in: Unified diff