Revision 4bd4ee07 targetarm/neon_helper.c
b/targetarm/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 1bit 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