[vm] Allow unaligned accesses by default in SIMARM64

ARMv8 ISA supports unaligned accesses (though a strict
alignment checking can be enabled).

Change-Id: I1f72d5f73934ba29b8436b5ed0f56a8dcd5a56ed
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121623
Auto-Submit: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Aart Bik <ajcbik@google.com>
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
This commit is contained in:
Vyacheslav Egorov
2019-10-15 08:50:52 +00:00
committed by commit-bot@chromium.org
parent 50f7ae9c5d
commit ba9d61ac96
2 changed files with 33 additions and 17 deletions
+29 -15
View File
@@ -31,6 +31,11 @@ DEFINE_FLAG(uint64_t,
ULLONG_MAX,
"Instruction address or instruction count to stop simulator at.");
DEFINE_FLAG(bool,
sim_allow_unaligned_accesses,
true,
"Allow unaligned accesses to Normal memory.");
// This macro provides a platform independent use of sscanf. The reason for
// SScanF not being implemented in a platform independent way through
// OS in the same way as SNPrint is that the Windows C Run-Time
@@ -999,9 +1004,10 @@ void Simulator::HandleIllegalAccess(uword addr, Instr* instr) {
FATAL("Cannot continue execution after illegal memory access.");
}
// The ARMv8 manual advises that an unaligned access may generate a fault,
// and if not, will likely take a number of additional cycles to execute,
// so let's just not generate any.
// ARMv8 supports unaligned memory accesses to normal memory without trapping
// for all instructions except Load-Exclusive/Store-Exclusive and
// Load-Acquire/Store-Release.
// See B2.4.2 "Alignment of data accesses" for more information.
void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) {
char buffer[128];
snprintf(buffer, sizeof(buffer), "unaligned %s at 0x%" Px ", pc=%p\n", msg,
@@ -1027,8 +1033,12 @@ bool Simulator::IsTracingExecution() const {
return icount_ > FLAG_trace_sim_after;
}
intptr_t Simulator::ReadX(uword addr, Instr* instr) {
if ((addr & 7) == 0) {
intptr_t Simulator::ReadX(uword addr,
Instr* instr,
bool must_be_aligned /* = false */) {
const bool allow_unaligned_access =
FLAG_sim_allow_unaligned_accesses && !must_be_aligned;
if (allow_unaligned_access || (addr & 7) == 0) {
intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
return *ptr;
}
@@ -1037,7 +1047,7 @@ intptr_t Simulator::ReadX(uword addr, Instr* instr) {
}
void Simulator::WriteX(uword addr, intptr_t value, Instr* instr) {
if ((addr & 7) == 0) {
if (FLAG_sim_allow_unaligned_accesses || (addr & 7) == 0) {
intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
*ptr = value;
return;
@@ -1045,8 +1055,12 @@ void Simulator::WriteX(uword addr, intptr_t value, Instr* instr) {
UnalignedAccess("write", addr, instr);
}
uint32_t Simulator::ReadWU(uword addr, Instr* instr) {
if ((addr & 3) == 0) {
uint32_t Simulator::ReadWU(uword addr,
Instr* instr,
bool must_be_aligned /* = false */) {
const bool allow_unaligned_access =
FLAG_sim_allow_unaligned_accesses && !must_be_aligned;
if (allow_unaligned_access || (addr & 3) == 0) {
uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
return *ptr;
}
@@ -1055,7 +1069,7 @@ uint32_t Simulator::ReadWU(uword addr, Instr* instr) {
}
int32_t Simulator::ReadW(uword addr, Instr* instr) {
if ((addr & 3) == 0) {
if (FLAG_sim_allow_unaligned_accesses || (addr & 3) == 0) {
int32_t* ptr = reinterpret_cast<int32_t*>(addr);
return *ptr;
}
@@ -1064,7 +1078,7 @@ int32_t Simulator::ReadW(uword addr, Instr* instr) {
}
void Simulator::WriteW(uword addr, uint32_t value, Instr* instr) {
if ((addr & 3) == 0) {
if (FLAG_sim_allow_unaligned_accesses || (addr & 3) == 0) {
uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
*ptr = value;
return;
@@ -1073,7 +1087,7 @@ void Simulator::WriteW(uword addr, uint32_t value, Instr* instr) {
}
uint16_t Simulator::ReadHU(uword addr, Instr* instr) {
if ((addr & 1) == 0) {
if (FLAG_sim_allow_unaligned_accesses || (addr & 1) == 0) {
uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
return *ptr;
}
@@ -1082,7 +1096,7 @@ uint16_t Simulator::ReadHU(uword addr, Instr* instr) {
}
int16_t Simulator::ReadH(uword addr, Instr* instr) {
if ((addr & 1) == 0) {
if (FLAG_sim_allow_unaligned_accesses || (addr & 1) == 0) {
int16_t* ptr = reinterpret_cast<int16_t*>(addr);
return *ptr;
}
@@ -1091,7 +1105,7 @@ int16_t Simulator::ReadH(uword addr, Instr* instr) {
}
void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) {
if ((addr & 1) == 0) {
if (FLAG_sim_allow_unaligned_accesses || (addr & 1) == 0) {
uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
*ptr = value;
return;
@@ -1121,13 +1135,13 @@ void Simulator::ClearExclusive() {
intptr_t Simulator::ReadExclusiveX(uword addr, Instr* instr) {
exclusive_access_addr_ = addr;
exclusive_access_value_ = ReadX(addr, instr);
exclusive_access_value_ = ReadX(addr, instr, /*must_be_aligned=*/true);
return exclusive_access_value_;
}
intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) {
exclusive_access_addr_ = addr;
exclusive_access_value_ = ReadWU(addr, instr);
exclusive_access_value_ = ReadWU(addr, instr, /*must_be_aligned=*/true);
return exclusive_access_value_;
}
+4 -2
View File
@@ -170,11 +170,13 @@ class Simulator {
inline int16_t ReadH(uword addr, Instr* instr);
inline void WriteH(uword addr, uint16_t value, Instr* instr);
inline uint32_t ReadWU(uword addr, Instr* instr);
inline uint32_t ReadWU(uword addr,
Instr* instr,
bool must_be_aligned = false);
inline int32_t ReadW(uword addr, Instr* instr);
inline void WriteW(uword addr, uint32_t value, Instr* instr);
inline intptr_t ReadX(uword addr, Instr* instr);
inline intptr_t ReadX(uword addr, Instr* instr, bool must_be_aligned = false);
inline void WriteX(uword addr, intptr_t value, Instr* instr);
// Synchronization primitives support.