[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:
committed by
commit-bot@chromium.org
parent
50f7ae9c5d
commit
ba9d61ac96
@@ -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_;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user