aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartyn Capewell <martyn.capewell@arm.com>2020-09-23 17:13:45 +0100
committerMartyn Capewell <martyn.capewell@arm.com>2020-10-20 09:52:57 +0000
commit6f755e6aa9aee82a1754a2f04cbcbc38a87e37d2 (patch)
treecd0f932430a2ecbf7688db4783683f5ed1b6cac0 /src
parentd02f4372eb1075c5ed09326dc61d2329cef031d3 (diff)
downloadvixl-6f755e6aa9aee82a1754a2f04cbcbc38a87e37d2.tar.gz
Fix undefined behaviour in Halve
The Halve function relied on shifting a signed value right. Replace with a well-defined bitfield extraction. Change-Id: I980d64ee92b68b5d4e213a2f338d810ec3999df7
Diffstat (limited to 'src')
-rw-r--r--src/aarch64/simulator-aarch64.h10
1 files changed, 6 insertions, 4 deletions
diff --git a/src/aarch64/simulator-aarch64.h b/src/aarch64/simulator-aarch64.h
index 1a89dff7..1e7d3079 100644
--- a/src/aarch64/simulator-aarch64.h
+++ b/src/aarch64/simulator-aarch64.h
@@ -736,13 +736,15 @@ class LogicVRegister {
for (int i = 0; i < LaneCountFromFormat(vform); i++) {
int64_t val = Int(vform, i);
SetRounding(i, (val & 1) == 1);
- val >>= 1;
- if (GetSignedSaturation(i) != kNotSaturated) {
+ val = ExtractSignedBitfield64(63, 1, val); // >>= 1
+ if (GetSignedSaturation(i) == kNotSaturated) {
+ SetInt(vform, i, val);
+ } else {
// If the operation causes signed saturation, the sign bit must be
// inverted.
- val ^= (MaxUintFromFormat(vform) >> 1) + 1;
+ uint64_t uval = static_cast<uint64_t>(val);
+ SetUint(vform, i, uval ^ ((MaxUintFromFormat(vform) >> 1) + 1));
}
- SetInt(vform, i, val);
}
return *this;
}