diff options
author | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-03-31 03:46:33 +0000 |
---|---|---|
committer | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-03-31 03:46:33 +0000 |
commit | 6ddbc6e4cfbfa0937fdebd8aa7b518d8b7fd118b (patch) | |
tree | f1a5af853e58f91106f2eb90338cc795ae036fa2 /target-arm/op_helper.c | |
parent | 3670669ce25ef337a6e5e99b7a97b83997c06721 (diff) |
ARM TCG conversion 7/16.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4144 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-arm/op_helper.c')
-rw-r--r-- | target-arm/op_helper.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 1b90f58296..2d3abfd79b 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -369,3 +369,70 @@ uint32_t HELPER(sub_usaturate)(uint32_t a, uint32_t b) return res; } +/* Signed saturation. */ +static inline uint32_t do_ssat(int32_t val, int shift) +{ + int32_t top; + uint32_t mask; + + shift = PARAM1; + top = val >> shift; + mask = (1u << shift) - 1; + if (top > 0) { + env->QF = 1; + return mask; + } else if (top < -1) { + env->QF = 1; + return ~mask; + } + return val; +} + +/* Unsigned saturation. */ +static inline uint32_t do_usat(int32_t val, int shift) +{ + uint32_t max; + + shift = PARAM1; + max = (1u << shift) - 1; + if (val < 0) { + env->QF = 1; + return 0; + } else if (val > max) { + env->QF = 1; + return max; + } + return val; +} + +/* Signed saturate. */ +uint32_t HELPER(ssat)(uint32_t x, uint32_t shift) +{ + return do_ssat(x, shift); +} + +/* Dual halfword signed saturate. */ +uint32_t HELPER(ssat16)(uint32_t x, uint32_t shift) +{ + uint32_t res; + + res = (uint16_t)do_ssat((int16_t)x, shift); + res |= do_ssat(((int32_t)x) >> 16, shift) << 16; + return res; +} + +/* Unsigned saturate. */ +uint32_t HELPER(usat)(uint32_t x, uint32_t shift) +{ + return do_usat(x, shift); +} + +/* Dual halfword unsigned saturate. */ +uint32_t HELPER(usat16)(uint32_t x, uint32_t shift) +{ + uint32_t res; + + res = (uint16_t)do_usat((int16_t)x, shift); + res |= do_usat(((int32_t)x) >> 16, shift) << 16; + return res; +} |