Skip to content

Commit ba9d61a

Browse files
mralephcommit-bot@chromium.org
authored andcommitted
[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 <[email protected]> Reviewed-by: Aart Bik <[email protected]> Commit-Queue: Vyacheslav Egorov <[email protected]>
1 parent 50f7ae9 commit ba9d61a

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

runtime/vm/simulator_arm64.cc

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ DEFINE_FLAG(uint64_t,
3131
ULLONG_MAX,
3232
"Instruction address or instruction count to stop simulator at.");
3333

34+
DEFINE_FLAG(bool,
35+
sim_allow_unaligned_accesses,
36+
true,
37+
"Allow unaligned accesses to Normal memory.");
38+
3439
// This macro provides a platform independent use of sscanf. The reason for
3540
// SScanF not being implemented in a platform independent way through
3641
// 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) {
9991004
FATAL("Cannot continue execution after illegal memory access.");
10001005
}
10011006

1002-
// The ARMv8 manual advises that an unaligned access may generate a fault,
1003-
// and if not, will likely take a number of additional cycles to execute,
1004-
// so let's just not generate any.
1007+
// ARMv8 supports unaligned memory accesses to normal memory without trapping
1008+
// for all instructions except Load-Exclusive/Store-Exclusive and
1009+
// Load-Acquire/Store-Release.
1010+
// See B2.4.2 "Alignment of data accesses" for more information.
10051011
void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) {
10061012
char buffer[128];
10071013
snprintf(buffer, sizeof(buffer), "unaligned %s at 0x%" Px ", pc=%p\n", msg,
@@ -1027,8 +1033,12 @@ bool Simulator::IsTracingExecution() const {
10271033
return icount_ > FLAG_trace_sim_after;
10281034
}
10291035

1030-
intptr_t Simulator::ReadX(uword addr, Instr* instr) {
1031-
if ((addr & 7) == 0) {
1036+
intptr_t Simulator::ReadX(uword addr,
1037+
Instr* instr,
1038+
bool must_be_aligned /* = false */) {
1039+
const bool allow_unaligned_access =
1040+
FLAG_sim_allow_unaligned_accesses && !must_be_aligned;
1041+
if (allow_unaligned_access || (addr & 7) == 0) {
10321042
intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
10331043
return *ptr;
10341044
}
@@ -1037,16 +1047,20 @@ intptr_t Simulator::ReadX(uword addr, Instr* instr) {
10371047
}
10381048

10391049
void Simulator::WriteX(uword addr, intptr_t value, Instr* instr) {
1040-
if ((addr & 7) == 0) {
1050+
if (FLAG_sim_allow_unaligned_accesses || (addr & 7) == 0) {
10411051
intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
10421052
*ptr = value;
10431053
return;
10441054
}
10451055
UnalignedAccess("write", addr, instr);
10461056
}
10471057

1048-
uint32_t Simulator::ReadWU(uword addr, Instr* instr) {
1049-
if ((addr & 3) == 0) {
1058+
uint32_t Simulator::ReadWU(uword addr,
1059+
Instr* instr,
1060+
bool must_be_aligned /* = false */) {
1061+
const bool allow_unaligned_access =
1062+
FLAG_sim_allow_unaligned_accesses && !must_be_aligned;
1063+
if (allow_unaligned_access || (addr & 3) == 0) {
10501064
uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
10511065
return *ptr;
10521066
}
@@ -1055,7 +1069,7 @@ uint32_t Simulator::ReadWU(uword addr, Instr* instr) {
10551069
}
10561070

10571071
int32_t Simulator::ReadW(uword addr, Instr* instr) {
1058-
if ((addr & 3) == 0) {
1072+
if (FLAG_sim_allow_unaligned_accesses || (addr & 3) == 0) {
10591073
int32_t* ptr = reinterpret_cast<int32_t*>(addr);
10601074
return *ptr;
10611075
}
@@ -1064,7 +1078,7 @@ int32_t Simulator::ReadW(uword addr, Instr* instr) {
10641078
}
10651079

10661080
void Simulator::WriteW(uword addr, uint32_t value, Instr* instr) {
1067-
if ((addr & 3) == 0) {
1081+
if (FLAG_sim_allow_unaligned_accesses || (addr & 3) == 0) {
10681082
uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
10691083
*ptr = value;
10701084
return;
@@ -1073,7 +1087,7 @@ void Simulator::WriteW(uword addr, uint32_t value, Instr* instr) {
10731087
}
10741088

10751089
uint16_t Simulator::ReadHU(uword addr, Instr* instr) {
1076-
if ((addr & 1) == 0) {
1090+
if (FLAG_sim_allow_unaligned_accesses || (addr & 1) == 0) {
10771091
uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
10781092
return *ptr;
10791093
}
@@ -1082,7 +1096,7 @@ uint16_t Simulator::ReadHU(uword addr, Instr* instr) {
10821096
}
10831097

10841098
int16_t Simulator::ReadH(uword addr, Instr* instr) {
1085-
if ((addr & 1) == 0) {
1099+
if (FLAG_sim_allow_unaligned_accesses || (addr & 1) == 0) {
10861100
int16_t* ptr = reinterpret_cast<int16_t*>(addr);
10871101
return *ptr;
10881102
}
@@ -1091,7 +1105,7 @@ int16_t Simulator::ReadH(uword addr, Instr* instr) {
10911105
}
10921106

10931107
void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) {
1094-
if ((addr & 1) == 0) {
1108+
if (FLAG_sim_allow_unaligned_accesses || (addr & 1) == 0) {
10951109
uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
10961110
*ptr = value;
10971111
return;
@@ -1121,13 +1135,13 @@ void Simulator::ClearExclusive() {
11211135

11221136
intptr_t Simulator::ReadExclusiveX(uword addr, Instr* instr) {
11231137
exclusive_access_addr_ = addr;
1124-
exclusive_access_value_ = ReadX(addr, instr);
1138+
exclusive_access_value_ = ReadX(addr, instr, /*must_be_aligned=*/true);
11251139
return exclusive_access_value_;
11261140
}
11271141

11281142
intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) {
11291143
exclusive_access_addr_ = addr;
1130-
exclusive_access_value_ = ReadWU(addr, instr);
1144+
exclusive_access_value_ = ReadWU(addr, instr, /*must_be_aligned=*/true);
11311145
return exclusive_access_value_;
11321146
}
11331147

runtime/vm/simulator_arm64.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,13 @@ class Simulator {
170170
inline int16_t ReadH(uword addr, Instr* instr);
171171
inline void WriteH(uword addr, uint16_t value, Instr* instr);
172172

173-
inline uint32_t ReadWU(uword addr, Instr* instr);
173+
inline uint32_t ReadWU(uword addr,
174+
Instr* instr,
175+
bool must_be_aligned = false);
174176
inline int32_t ReadW(uword addr, Instr* instr);
175177
inline void WriteW(uword addr, uint32_t value, Instr* instr);
176178

177-
inline intptr_t ReadX(uword addr, Instr* instr);
179+
inline intptr_t ReadX(uword addr, Instr* instr, bool must_be_aligned = false);
178180
inline void WriteX(uword addr, intptr_t value, Instr* instr);
179181

180182
// Synchronization primitives support.

0 commit comments

Comments
 (0)