## Revision 4bd4ee07 target-arm/neon_helper.c

b/target-arm/neon_helper.c
558 558
```    }} while (0)
```
559 559
```NEON_VOP(rshl_s8, neon_s8, 4)
```
560 560
```NEON_VOP(rshl_s16, neon_s16, 2)
```
561
```NEON_VOP(rshl_s32, neon_s32, 1)
```
562 561
```#undef NEON_FN
```
563 562

563
```/* The addition of the rounding constant may overflow, so we use an
```
564
``` * intermediate 64 bits accumulator.  */
```
565
```uint32_t HELPER(neon_rshl_s32)(uint32_t valop, uint32_t shiftop)
```
566
```{
```
567
```    int32_t dest;
```
568
```    int32_t val = (int32_t)valop;
```
569
```    int8_t shift = (int8_t)shiftop;
```
570
```    if ((shift >= 32) || (shift <= -32)) {
```
571
```        dest = 0;
```
572
```    } else if (shift < 0) {
```
573
```        int64_t big_dest = ((int64_t)val + (1 << (-1 - shift)));
```
574
```        dest = big_dest >> -shift;
```
575
```    } else {
```
576
```        dest = val << shift;
```
577
```    }
```
578
```    return dest;
```
579
```}
```
580

581
```/* Handling addition overflow with 64 bits inputs values is more
```
582
``` * tricky than with 32 bits values.  */
```
564 583
```uint64_t HELPER(neon_rshl_s64)(uint64_t valop, uint64_t shiftop)
```
565 584
```{
```
566 585
```    int8_t shift = (int8_t)shiftop;
```
......
574 593
```        val++;
```
575 594
```        val >>= 1;
```
576 595
```    } else if (shift < 0) {
```
577
```        val = (val + ((int64_t)1 << (-1 - shift))) >> -shift;
```
596
```        val >>= (-shift - 1);
```
597
```        if (val == INT64_MAX) {
```
598
```            /* In this case, it means that the rounding constant is 1,
```
599
```             * and the addition would overflow. Return the actual
```
600
```             * result directly.  */
```
601
```            val = 0x4000000000000000LL;
```
602
```        } else {
```
603
```            val++;
```
604
```            val >>= 1;
```
605
```        }
```
578 606
```    } else {
```
579 607
```        val <<= shift;
```
580 608
```    }
```
......
596 624
```    }} while (0)
```
597 625
```NEON_VOP(rshl_u8, neon_u8, 4)
```
598 626
```NEON_VOP(rshl_u16, neon_u16, 2)
```
599
```NEON_VOP(rshl_u32, neon_u32, 1)
```
600 627
```#undef NEON_FN
```
601 628

629
```/* The addition of the rounding constant may overflow, so we use an
```
630
``` * intermediate 64 bits accumulator.  */
```
631
```uint32_t HELPER(neon_rshl_u32)(uint32_t val, uint32_t shiftop)
```
632
```{
```
633
```    uint32_t dest;
```
634
```    int8_t shift = (int8_t)shiftop;
```
635
```    if (shift >= 32 || shift < -32) {
```
636
```        dest = 0;
```
637
```    } else if (shift == -32) {
```
638
```        dest = val >> 31;
```
639
```    } else if (shift < 0) {
```
640
```        uint64_t big_dest = ((uint64_t)val + (1 << (-1 - shift)));
```
641
```        dest = big_dest >> -shift;
```
642
```    } else {
```
643
```        dest = val << shift;
```
644
```    }
```
645
```    return dest;
```
646
```}
```
647

648
```/* Handling addition overflow with 64 bits inputs values is more
```
649
``` * tricky than with 32 bits values.  */
```
602 650
```uint64_t HELPER(neon_rshl_u64)(uint64_t val, uint64_t shiftop)
```
603 651
```{
```
604 652
```    int8_t shift = (uint8_t)shiftop;
```
......
607 655
```    } else if (shift == -64) {
```
608 656
```        /* Rounding a 1-bit result just preserves that bit.  */
```
609 657
```        val >>= 63;
```
610
```    } if (shift < 0) {
```
611
```        val = (val + ((uint64_t)1 << (-1 - shift))) >> -shift;
```
612
```        val >>= -shift;
```
658
```    } else if (shift < 0) {
```
659
```        val >>= (-shift - 1);
```
660
```        if (val == UINT64_MAX) {
```
661
```            /* In this case, it means that the rounding constant is 1,
```
662
```             * and the addition would overflow. Return the actual
```
663
```             * result directly.  */
```
664
```            val = 0x8000000000000000ULL;
```
665
```        } else {
```
666
```            val++;
```
667
```            val >>= 1;
```
668
```        }
```
613 669
```    } else {
```
614 670
```        val <<= shift;
```
615 671
```    }
```
......
784 840
```    }} while (0)
```
785 841
```NEON_VOP_ENV(qrshl_u8, neon_u8, 4)
```
786 842
```NEON_VOP_ENV(qrshl_u16, neon_u16, 2)
```
787
```NEON_VOP_ENV(qrshl_u32, neon_u32, 1)
```
788 843
```#undef NEON_FN
```
789 844

845
```/* The addition of the rounding constant may overflow, so we use an
```
846
``` * intermediate 64 bits accumulator.  */
```
847
```uint32_t HELPER(neon_qrshl_u32)(CPUState *env, uint32_t val, uint32_t shiftop)
```
848
```{
```
849
```    uint32_t dest;
```
850
```    int8_t shift = (int8_t)shiftop;
```
851
```    if (shift < 0) {
```
852
```        uint64_t big_dest = ((uint64_t)val + (1 << (-1 - shift)));
```
853
```        dest = big_dest >> -shift;
```
854
```    } else {
```
855
```        dest = val << shift;
```
856
```        if ((dest >> shift) != val) {
```
857
```            SET_QC();
```
858
```            dest = ~0;
```
859
```        }
```
860
```    }
```
861
```    return dest;
```
862
```}
```
863

864
```/* Handling addition overflow with 64 bits inputs values is more
```
865
``` * tricky than with 32 bits values.  */
```
790 866
```uint64_t HELPER(neon_qrshl_u64)(CPUState *env, uint64_t val, uint64_t shiftop)
```
791 867
```{
```
792 868
```    int8_t shift = (int8_t)shiftop;
```
793 869
```    if (shift < 0) {
```
794
```        val = (val + (1 << (-1 - shift))) >> -shift;
```
870
```        val >>= (-shift - 1);
```
871
```        if (val == UINT64_MAX) {
```
872
```            /* In this case, it means that the rounding constant is 1,
```
873
```             * and the addition would overflow. Return the actual
```
874
```             * result directly.  */
```
875
```            val = 0x8000000000000000ULL;
```
876
```        } else {
```
877
```            val++;
```
878
```            val >>= 1;
```
879
```        }
```
795 880
```    } else { \
```
796 881
```        uint64_t tmp = val;
```
797 882
```        val <<= shift;
```
......
817 902
```    }} while (0)
```
818 903
```NEON_VOP_ENV(qrshl_s8, neon_s8, 4)
```
819 904
```NEON_VOP_ENV(qrshl_s16, neon_s16, 2)
```
820
```NEON_VOP_ENV(qrshl_s32, neon_s32, 1)
```
821 905
```#undef NEON_FN
```
822 906

907
```/* The addition of the rounding constant may overflow, so we use an
```
908
``` * intermediate 64 bits accumulator.  */
```
909
```uint32_t HELPER(neon_qrshl_s32)(CPUState *env, uint32_t valop, uint32_t shiftop)
```
910
```{
```
911
```    int32_t dest;
```
912
```    int32_t val = (int32_t)valop;
```
913
```    int8_t shift = (int8_t)shiftop;
```
914
```    if (shift < 0) {
```
915
```        int64_t big_dest = ((int64_t)val + (1 << (-1 - shift)));
```
916
```        dest = big_dest >> -shift;
```
917
```    } else {
```
918
```        dest = val << shift;
```
919
```        if ((dest >> shift) != val) {
```
920
```            SET_QC();
```
921
```            dest = (val >> 31) ^ ~SIGNBIT;
```
922
```        }
```
923
```    }
```
924
```    return dest;
```
925
```}
```
926

927
```/* Handling addition overflow with 64 bits inputs values is more
```
928
``` * tricky than with 32 bits values.  */
```
823 929
```uint64_t HELPER(neon_qrshl_s64)(CPUState *env, uint64_t valop, uint64_t shiftop)
```
824 930
```{
```
825 931
```    int8_t shift = (uint8_t)shiftop;
```
826 932
```    int64_t val = valop;
```
827 933

828 934
```    if (shift < 0) {
```
829
```        val = (val + (1 << (-1 - shift))) >> -shift;
```
935
```        val >>= (-shift - 1);
```
936
```        if (val == INT64_MAX) {
```
937
```            /* In this case, it means that the rounding constant is 1,
```
938
```             * and the addition would overflow. Return the actual
```
939
```             * result directly.  */
```
940
```            val = 0x4000000000000000ULL;
```
941
```        } else {
```
942
```            val++;
```
943
```            val >>= 1;
```
944
```        }
```
830 945
```    } else {
```
831
```        int64_t tmp = val;;
```
946
```        int64_t tmp = val;
```
832 947
```        val <<= shift;
```
833 948
```        if ((val >> shift) != tmp) {
```
834 949
```            SET_QC();
```
835
```            val = tmp >> 31;
```
950
```            val = (tmp >> 63) ^ ~SIGNBIT64;
```
836 951
```        }
```
837 952
```    }
```
838 953
```    return val;
```

Also available in: Unified diff