aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJacob Bramley <jacob.bramley@arm.com>2020-07-02 12:06:45 +0100
committerJacob Bramley <jacob.bramley@arm.com>2020-07-02 14:28:07 +0100
commitdfb93b5e6b8c3e0cb1b3ff05f1bf49084d159258 (patch)
tree5a00a2f25616662a2bbc92c52aca6730e0e2d7fe /src
parent8caa873b7a9209737ff26b18430f1d986ac3d356 (diff)
downloadvixl-dfb93b5e6b8c3e0cb1b3ff05f1bf49084d159258.tar.gz
Fix simulation of FTSMUL.
We tried to set the sign bit before multiplying, but this produced the wrong result when the input is already negative. Change-Id: I7b44070409ca265b1fae34792ebe43e5e53ce646
Diffstat (limited to 'src')
-rw-r--r--src/aarch64/logic-aarch64.cc13
1 files changed, 6 insertions, 7 deletions
diff --git a/src/aarch64/logic-aarch64.cc b/src/aarch64/logic-aarch64.cc
index 9684355a..48d97e8b 100644
--- a/src/aarch64/logic-aarch64.cc
+++ b/src/aarch64/logic-aarch64.cc
@@ -6280,18 +6280,17 @@ LogicVRegister Simulator::ftsmul(VectorFormat vform,
LogicVRegister dst,
const LogicVRegister& src1,
const LogicVRegister& src2) {
- SimVRegister neg_src1;
- mov(vform, neg_src1, src1);
+ SimVRegister maybe_neg_src1;
- // The bottom bit of src2 controls the sign of the result. Set the sign of
- // neg_src1 by shifting and inserting the bit into the top of src1.
- int lane_bits = LaneSizeInBitsFromFormat(vform);
- sli(vform, neg_src1, src2, lane_bits - 1);
+ // The bottom bit of src2 controls the sign of the result. Use it to
+ // conditionally invert the sign of one `fmul` operand.
+ shl(vform, maybe_neg_src1, src2, LaneSizeInBitsFromFormat(vform) - 1);
+ eor(vform, maybe_neg_src1, maybe_neg_src1, src1);
// Multiply src1 by the modified neg_src1, which is potentially its negation.
// In the case of NaNs, NaN * -NaN will return the first NaN intact, so src1,
// rather than neg_src1, must be the first source argument.
- fmul(vform, dst, src1, neg_src1);
+ fmul(vform, dst, src1, maybe_neg_src1);
return dst;
}