diff options
author | Rodolph Perfetta <rodolph.perfetta@arm.com> | 2018-11-21 18:23:53 +0000 |
---|---|---|
committer | Jacob Bramley <jacob.bramley@arm.com> | 2018-11-21 18:32:11 +0000 |
commit | 7fcd70d4afa05749967d54658fd1894e246f993e (patch) | |
tree | d153e46765941f9f3572fb633a38f9c04326fbdc | |
parent | 311edf27319bc91cf89db268c32b589f68b2ea69 (diff) |
Fix the C++11 runtime calls test.
Fix two related bugs:
1. Some inputs caused undefined behaviour when truncated to int8_t or int16_t.
2. The tests didn't properly perform sign extension on their return values
before comparing with int32_t 'expected' values.
Also, update the simulator so that the tests would reliably fail without the
second fix.
Change-Id: If02f056d32d4515d55708804e2fb839a71d29e54
-rw-r--r-- | src/aarch64/simulator-aarch64.h | 11 | ||||
-rw-r--r-- | test/aarch64/test-assembler-aarch64.cc | 20 |
2 files changed, 22 insertions, 9 deletions
diff --git a/src/aarch64/simulator-aarch64.h b/src/aarch64/simulator-aarch64.h index 84c81d8e..075a6061 100644 --- a/src/aarch64/simulator-aarch64.h +++ b/src/aarch64/simulator-aarch64.h @@ -1291,7 +1291,16 @@ class Simulator : public DecoderVisitor { T value, RegLogMode log_mode = LogRegWrites) { if (operand.IsCPURegister()) { - WriteCPURegister<T>(operand.GetCPURegister(), value, log_mode); + // Outside SIMD, registers are 64-bit or a subset of a 64-bit register. If + // the width of the value to write is smaller than 64 bits, the unused + // bits may contain unrelated values that the code following this write + // needs to handle gracefully. + // Here we fill the unused bits with a predefined pattern to catch issues + // early. + VIXL_ASSERT(operand.GetCPURegister().GetSizeInBits() <= 64); + uint64_t raw = 0xdeadda1adeadda1a; + memcpy(&raw, &value, sizeof(value)); + WriteCPURegister(operand.GetCPURegister(), raw, log_mode); } else { VIXL_ASSERT(operand.IsMemOperand()); Memory::Write(ComputeMemOperandAddress(operand.GetMemOperand()), value); diff --git a/test/aarch64/test-assembler-aarch64.cc b/test/aarch64/test-assembler-aarch64.cc index fb53213c..0a57ade6 100644 --- a/test/aarch64/test-assembler-aarch64.cc +++ b/test/aarch64/test-assembler-aarch64.cc @@ -28781,21 +28781,25 @@ TEST(runtime_calls) { for (size_t i = 0; i < sizeof(test_values) / sizeof(test_values[0]); ++i) { Label pass_int8, pass_uint8, pass_int16, pass_uint16; int x = test_values[i]; - __ Mov(w0, static_cast<int8_t>(x)); + __ Mov(w0, x); __ CallRuntime(test_int8_t); - __ Cmp(w0, static_cast<int8_t>(x)); + __ Sxtb(w0, w0); + __ Cmp(w0, ExtractSignedBitfield32(7, 0, x)); __ Cinc(x24, x24, ne); - __ Mov(w0, static_cast<uint8_t>(x)); + __ Mov(w0, x); __ CallRuntime(test_uint8_t); - __ Cmp(w0, static_cast<uint8_t>(x)); + __ Uxtb(w0, w0); + __ Cmp(w0, ExtractUnsignedBitfield32(7, 0, x)); __ Cinc(x24, x24, ne); - __ Mov(w0, static_cast<int16_t>(x)); + __ Mov(w0, x); __ CallRuntime(test_int16_t); - __ Cmp(w0, static_cast<int16_t>(x)); + __ Sxth(w0, w0); + __ Cmp(w0, ExtractSignedBitfield32(15, 0, x)); __ Cinc(x24, x24, ne); - __ Mov(w0, static_cast<uint16_t>(x)); + __ Mov(w0, x); __ CallRuntime(test_uint16_t); - __ Cmp(w0, static_cast<uint16_t>(x)); + __ Uxth(w0, w0); + __ Cmp(w0, ExtractUnsignedBitfield32(15, 0, x)); __ Cinc(x24, x24, ne); } |