aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodolph Perfetta <rodolph.perfetta@arm.com>2018-11-21 18:23:53 +0000
committerJacob Bramley <jacob.bramley@arm.com>2018-11-21 18:32:11 +0000
commit7fcd70d4afa05749967d54658fd1894e246f993e (patch)
treed153e46765941f9f3572fb633a38f9c04326fbdc
parent311edf27319bc91cf89db268c32b589f68b2ea69 (diff)
downloadvixl-master.tar.gz
Fix the C++11 runtime calls test.HEADmaster
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.h11
-rw-r--r--test/aarch64/test-assembler-aarch64.cc20
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);
}