| Index: src/arm64/simulator-arm64.cc
|
| diff --git a/src/arm64/simulator-arm64.cc b/src/arm64/simulator-arm64.cc
|
| index 890ab3164665c6151fcda4ed129ab41c193aff58..28ca616957b016cb6a6ba57b8cd001cc4f6e0fde 100644
|
| --- a/src/arm64/simulator-arm64.cc
|
| +++ b/src/arm64/simulator-arm64.cc
|
| @@ -1952,6 +1952,61 @@ Simulator::TransactionSize Simulator::get_transaction_size(unsigned size) {
|
| return TransactionSize::None;
|
| }
|
|
|
| +void Simulator::VisitLoadStoreExclusive(Instruction* instr) {
|
| + unsigned rs = instr->Rs();
|
| + unsigned rt = instr->Rt();
|
| + unsigned rn = instr->Rn();
|
| + LoadStoreExclusiveOp op =
|
| + static_cast<LoadStoreExclusiveOp>(instr->Mask(LoadStoreExclusiveMask));
|
| + int32_t is_load = instr->LoadStoreXLoad();
|
| + unsigned access_size = 1 << instr->LoadStoreXSizeLog2();
|
| + uintptr_t address = LoadStoreAddress(rn, 0, AddrMode::Offset);
|
| + DCHECK_EQ(address % access_size, 0);
|
| + base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex);
|
| + if (is_load != 0) {
|
| + local_monitor_.NotifyLoadExcl(address, get_transaction_size(access_size));
|
| + global_monitor_.Pointer()->NotifyLoadExcl_Locked(
|
| + address, &global_monitor_processor_);
|
| + switch (op) {
|
| + case LDXRB:
|
| + set_wreg_no_log(rt, MemoryRead<uint8_t>(address));
|
| + break;
|
| + case LDXRH:
|
| + set_wreg_no_log(rt, MemoryRead<uint16_t>(address));
|
| + break;
|
| + case LDXR_w:
|
| + set_wreg_no_log(rt, MemoryRead<uint32_t>(address));
|
| + break;
|
| + default:
|
| + UNIMPLEMENTED();
|
| + }
|
| + LogRead(address, access_size, rt);
|
| + } else {
|
| + if (local_monitor_.NotifyStoreExcl(address,
|
| + get_transaction_size(access_size)) &&
|
| + global_monitor_.Pointer()->NotifyStoreExcl_Locked(
|
| + address, &global_monitor_processor_)) {
|
| + switch (op) {
|
| + case STXRB:
|
| + MemoryWrite<uint8_t>(address, wreg(rt));
|
| + break;
|
| + case STXRH:
|
| + MemoryWrite<uint16_t>(address, wreg(rt));
|
| + break;
|
| + case STXR_w:
|
| + MemoryWrite<uint32_t>(address, wreg(rt));
|
| + break;
|
| + default:
|
| + UNIMPLEMENTED();
|
| + }
|
| + LogWrite(address, access_size, rt);
|
| + set_wreg(rs, 0);
|
| + } else {
|
| + set_wreg(rs, 1);
|
| + }
|
| + }
|
| +}
|
| +
|
| void Simulator::VisitLoadStoreAcquireRelease(Instruction* instr) {
|
| unsigned rs = instr->Rs();
|
| unsigned rt = instr->Rt();
|
| @@ -1967,7 +2022,7 @@ void Simulator::VisitLoadStoreAcquireRelease(Instruction* instr) {
|
| DCHECK_EQ(is_pair, 0); // Pair unimplemented.
|
| unsigned access_size = 1 << instr->LoadStoreXSizeLog2();
|
| uintptr_t address = LoadStoreAddress(rn, 0, AddrMode::Offset);
|
| - DCHECK(address % access_size == 0);
|
| + DCHECK_EQ(address % access_size, 0);
|
| base::LockGuard<base::Mutex> lock_guard(&global_monitor_.Pointer()->mutex);
|
| if (is_load != 0) {
|
| local_monitor_.NotifyLoadExcl(address, get_transaction_size(access_size));
|
|
|