| Index: runtime/vm/simulator_arm64.cc
|
| diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
|
| index 99912dfa29c7793730771114aadda99ba69cde83..49f8635090c86d4e91bbf7efe7653b90a7571c06 100644
|
| --- a/runtime/vm/simulator_arm64.cc
|
| +++ b/runtime/vm/simulator_arm64.cc
|
| @@ -18,8 +18,8 @@
|
| #include "vm/disassembler.h"
|
| #include "vm/lockers.h"
|
| #include "vm/native_arguments.h"
|
| -#include "vm/stack_frame.h"
|
| #include "vm/os_thread.h"
|
| +#include "vm/stack_frame.h"
|
|
|
| namespace dart {
|
|
|
| @@ -32,14 +32,12 @@ DEFINE_FLAG(uint64_t,
|
| ULLONG_MAX,
|
| "Instruction address or instruction count to stop simulator at.");
|
|
|
| -
|
| // 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
|
| // Library does not provide vsscanf.
|
| #define SScanF sscanf // NOLINT
|
|
|
| -
|
| // SimulatorSetjmpBuffer are linked together, and the last created one
|
| // is referenced by the Simulator. When an exception is thrown, the exception
|
| // runtime looks at where to jump and finds the corresponding
|
| @@ -78,7 +76,6 @@ class SimulatorSetjmpBuffer {
|
| friend class Simulator;
|
| };
|
|
|
| -
|
| // The SimulatorDebugger class is used by the simulator while debugging
|
| // simulated ARM64 code.
|
| class SimulatorDebugger {
|
| @@ -119,21 +116,17 @@ class SimulatorDebugger {
|
| void RedoBreakpoints();
|
| };
|
|
|
| -
|
| SimulatorDebugger::SimulatorDebugger(Simulator* sim) {
|
| sim_ = sim;
|
| }
|
|
|
| -
|
| SimulatorDebugger::~SimulatorDebugger() {}
|
|
|
| -
|
| void SimulatorDebugger::Stop(Instr* instr, const char* message) {
|
| OS::Print("Simulator hit %s\n", message);
|
| Debug();
|
| }
|
|
|
| -
|
| static Register LookupCpuRegisterByName(const char* name) {
|
| static const char* kNames[] = {
|
| "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
| @@ -159,7 +152,6 @@ static Register LookupCpuRegisterByName(const char* name) {
|
| return kNoRegister;
|
| }
|
|
|
| -
|
| static VRegister LookupVRegisterByName(const char* name) {
|
| int reg_nr = -1;
|
| bool ok = SScanF(name, "v%d", ®_nr);
|
| @@ -169,7 +161,6 @@ static VRegister LookupVRegisterByName(const char* name) {
|
| return kNoVRegister;
|
| }
|
|
|
| -
|
| bool SimulatorDebugger::GetValue(char* desc, uint64_t* value) {
|
| Register reg = LookupCpuRegisterByName(desc);
|
| if (reg != kNoRegister) {
|
| @@ -201,7 +192,6 @@ bool SimulatorDebugger::GetValue(char* desc, uint64_t* value) {
|
| return retval;
|
| }
|
|
|
| -
|
| bool SimulatorDebugger::GetSValue(char* desc, uint32_t* value) {
|
| VRegister vreg = LookupVRegisterByName(desc);
|
| if (vreg != kNoVRegister) {
|
| @@ -221,7 +211,6 @@ bool SimulatorDebugger::GetSValue(char* desc, uint32_t* value) {
|
| return false;
|
| }
|
|
|
| -
|
| bool SimulatorDebugger::GetDValue(char* desc, uint64_t* value) {
|
| VRegister vreg = LookupVRegisterByName(desc);
|
| if (vreg != kNoVRegister) {
|
| @@ -241,7 +230,6 @@ bool SimulatorDebugger::GetDValue(char* desc, uint64_t* value) {
|
| return false;
|
| }
|
|
|
| -
|
| bool SimulatorDebugger::GetQValue(char* desc, simd_value_t* value) {
|
| VRegister vreg = LookupVRegisterByName(desc);
|
| if (vreg != kNoVRegister) {
|
| @@ -261,7 +249,6 @@ bool SimulatorDebugger::GetQValue(char* desc, simd_value_t* value) {
|
| return false;
|
| }
|
|
|
| -
|
| TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code,
|
| uword pc) {
|
| TokenPosition token_pos = TokenPosition::kNoSource;
|
| @@ -279,7 +266,6 @@ TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code,
|
| return token_pos;
|
| }
|
|
|
| -
|
| void SimulatorDebugger::PrintDartFrame(uword pc,
|
| uword fp,
|
| uword sp,
|
| @@ -301,7 +287,6 @@ void SimulatorDebugger::PrintDartFrame(uword pc,
|
| func_name.ToCString(), url.ToCString(), line, column);
|
| }
|
|
|
| -
|
| void SimulatorDebugger::PrintBacktrace() {
|
| StackFrameIterator frames(
|
| sim_->get_register(FP), sim_->get_register(SP), sim_->get_pc(),
|
| @@ -353,7 +338,6 @@ void SimulatorDebugger::PrintBacktrace() {
|
| }
|
| }
|
|
|
| -
|
| bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) {
|
| // Check if a breakpoint can be set. If not return without any side-effects.
|
| if (sim_->break_pc_ != NULL) {
|
| @@ -368,7 +352,6 @@ bool SimulatorDebugger::SetBreakpoint(Instr* breakpc) {
|
| return true;
|
| }
|
|
|
| -
|
| bool SimulatorDebugger::DeleteBreakpoint(Instr* breakpc) {
|
| if (sim_->break_pc_ != NULL) {
|
| sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
|
| @@ -379,21 +362,18 @@ bool SimulatorDebugger::DeleteBreakpoint(Instr* breakpc) {
|
| return true;
|
| }
|
|
|
| -
|
| void SimulatorDebugger::UndoBreakpoints() {
|
| if (sim_->break_pc_ != NULL) {
|
| sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
|
| }
|
| }
|
|
|
| -
|
| void SimulatorDebugger::RedoBreakpoints() {
|
| if (sim_->break_pc_ != NULL) {
|
| sim_->break_pc_->SetInstructionBits(Instr::kSimulatorBreakpointInstruction);
|
| }
|
| }
|
|
|
| -
|
| void SimulatorDebugger::Debug() {
|
| intptr_t last_pc = -1;
|
| bool done = false;
|
| @@ -668,7 +648,6 @@ void SimulatorDebugger::Debug() {
|
| #undef XSTR
|
| }
|
|
|
| -
|
| char* SimulatorDebugger::ReadLine(const char* prompt) {
|
| char* result = NULL;
|
| char line_buf[256];
|
| @@ -727,20 +706,17 @@ char* SimulatorDebugger::ReadLine(const char* prompt) {
|
| return result;
|
| }
|
|
|
| -
|
| // Synchronization primitives support.
|
| Mutex* Simulator::exclusive_access_lock_ = NULL;
|
| Simulator::AddressTag Simulator::exclusive_access_state_[kNumAddressTags] = {
|
| {NULL, 0}};
|
| int Simulator::next_address_tag_ = 0;
|
|
|
| -
|
| void Simulator::InitOnce() {
|
| // Setup exclusive access state lock.
|
| exclusive_access_lock_ = new Mutex();
|
| }
|
|
|
| -
|
| Simulator::Simulator() {
|
| // Setup simulator support first. Some of this information is needed to
|
| // setup the architecture state.
|
| @@ -782,7 +758,6 @@ Simulator::Simulator() {
|
| pc_ = kBadLR;
|
| }
|
|
|
| -
|
| Simulator::~Simulator() {
|
| delete[] stack_;
|
| Isolate* isolate = Isolate::Current();
|
| @@ -791,7 +766,6 @@ Simulator::~Simulator() {
|
| }
|
| }
|
|
|
| -
|
| // When the generated code calls an external reference we need to catch that in
|
| // the simulator. The external reference will be a function compiled for the
|
| // host architecture. We need to call that function instead of trying to
|
| @@ -867,10 +841,8 @@ class Redirection {
|
| static Redirection* list_;
|
| };
|
|
|
| -
|
| Redirection* Redirection::list_ = NULL;
|
|
|
| -
|
| uword Simulator::RedirectExternalReference(uword function,
|
| CallKind call_kind,
|
| int argument_count) {
|
| @@ -879,12 +851,10 @@ uword Simulator::RedirectExternalReference(uword function,
|
| return redirection->address_of_hlt_instruction();
|
| }
|
|
|
| -
|
| uword Simulator::FunctionForRedirect(uword redirect) {
|
| return Redirection::FunctionForRedirect(redirect);
|
| }
|
|
|
| -
|
| // Get the active Simulator for the current isolate.
|
| Simulator* Simulator::Current() {
|
| Simulator* simulator = Isolate::Current()->simulator();
|
| @@ -895,7 +865,6 @@ Simulator* Simulator::Current() {
|
| return simulator;
|
| }
|
|
|
| -
|
| // Sets the register in the architecture state.
|
| void Simulator::set_register(Instr* instr,
|
| Register reg,
|
| @@ -919,7 +888,6 @@ void Simulator::set_register(Instr* instr,
|
| }
|
| }
|
|
|
| -
|
| // Get the register from the architecture state.
|
| int64_t Simulator::get_register(Register reg, R31Type r31t) const {
|
| ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
|
| @@ -930,7 +898,6 @@ int64_t Simulator::get_register(Register reg, R31Type r31t) const {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::set_wregister(Register reg, int32_t value, R31Type r31t) {
|
| ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
|
| // When setting in W mode, clear the high bits.
|
| @@ -939,7 +906,6 @@ void Simulator::set_wregister(Register reg, int32_t value, R31Type r31t) {
|
| }
|
| }
|
|
|
| -
|
| // Get the register from the architecture state.
|
| int32_t Simulator::get_wregister(Register reg, R31Type r31t) const {
|
| ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters));
|
| @@ -950,49 +916,42 @@ int32_t Simulator::get_wregister(Register reg, R31Type r31t) const {
|
| }
|
| }
|
|
|
| -
|
| int32_t Simulator::get_vregisters(VRegister reg, int idx) const {
|
| ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
|
| ASSERT((idx >= 0) && (idx <= 3));
|
| return vregisters_[reg].bits.i32[idx];
|
| }
|
|
|
| -
|
| void Simulator::set_vregisters(VRegister reg, int idx, int32_t value) {
|
| ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
|
| ASSERT((idx >= 0) && (idx <= 3));
|
| vregisters_[reg].bits.i32[idx] = value;
|
| }
|
|
|
| -
|
| int64_t Simulator::get_vregisterd(VRegister reg, int idx) const {
|
| ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
|
| ASSERT((idx == 0) || (idx == 1));
|
| return vregisters_[reg].bits.i64[idx];
|
| }
|
|
|
| -
|
| void Simulator::set_vregisterd(VRegister reg, int idx, int64_t value) {
|
| ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
|
| ASSERT((idx == 0) || (idx == 1));
|
| vregisters_[reg].bits.i64[idx] = value;
|
| }
|
|
|
| -
|
| void Simulator::get_vregister(VRegister reg, simd_value_t* value) const {
|
| ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
|
| value->bits.i64[0] = vregisters_[reg].bits.i64[0];
|
| value->bits.i64[1] = vregisters_[reg].bits.i64[1];
|
| }
|
|
|
| -
|
| void Simulator::set_vregister(VRegister reg, const simd_value_t& value) {
|
| ASSERT((reg >= 0) && (reg < kNumberOfVRegisters));
|
| vregisters_[reg].bits.i64[0] = value.bits.i64[0];
|
| vregisters_[reg].bits.i64[1] = value.bits.i64[1];
|
| }
|
|
|
| -
|
| // Raw access to the PC register.
|
| void Simulator::set_pc(int64_t value) {
|
| pc_modified_ = true;
|
| @@ -1000,24 +959,22 @@ void Simulator::set_pc(int64_t value) {
|
| pc_ = value;
|
| }
|
|
|
| -
|
| // Raw access to the pc.
|
| int64_t Simulator::get_pc() const {
|
| return pc_;
|
| }
|
|
|
| -
|
| int64_t Simulator::get_last_pc() const {
|
| return last_pc_;
|
| }
|
|
|
| -
|
| void Simulator::HandleIllegalAccess(uword addr, Instr* instr) {
|
| uword fault_pc = get_pc();
|
| uword last_pc = get_last_pc();
|
| char buffer[128];
|
| - snprintf(buffer, sizeof(buffer), "illegal memory access at 0x%" Px
|
| - ", pc=0x%" Px ", last_pc=0x%" Px "\n",
|
| + snprintf(buffer, sizeof(buffer),
|
| + "illegal memory access at 0x%" Px ", pc=0x%" Px ", last_pc=0x%" Px
|
| + "\n",
|
| addr, fault_pc, last_pc);
|
| SimulatorDebugger dbg(this);
|
| dbg.Stop(instr, buffer);
|
| @@ -1025,7 +982,6 @@ 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.
|
| @@ -1040,7 +996,6 @@ void Simulator::UnalignedAccess(const char* msg, uword addr, Instr* instr) {
|
| FATAL("Cannot continue execution after unaligned access.");
|
| }
|
|
|
| -
|
| void Simulator::UnimplementedInstruction(Instr* instr) {
|
| char buffer[128];
|
| snprintf(buffer, sizeof(buffer),
|
| @@ -1051,7 +1006,6 @@ void Simulator::UnimplementedInstruction(Instr* instr) {
|
| FATAL("Cannot continue execution after unimplemented instruction.");
|
| }
|
|
|
| -
|
| // Returns the top of the stack area to enable checking for stack pointer
|
| // validity.
|
| uword Simulator::StackTop() const {
|
| @@ -1061,12 +1015,10 @@ uword Simulator::StackTop() const {
|
| (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer);
|
| }
|
|
|
| -
|
| bool Simulator::IsTracingExecution() const {
|
| return icount_ > FLAG_trace_sim_after;
|
| }
|
|
|
| -
|
| intptr_t Simulator::ReadX(uword addr, Instr* instr) {
|
| if ((addr & 7) == 0) {
|
| intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
|
| @@ -1076,7 +1028,6 @@ intptr_t Simulator::ReadX(uword addr, Instr* instr) {
|
| return 0;
|
| }
|
|
|
| -
|
| void Simulator::WriteX(uword addr, intptr_t value, Instr* instr) {
|
| if ((addr & 7) == 0) {
|
| intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
|
| @@ -1086,7 +1037,6 @@ 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* ptr = reinterpret_cast<uint32_t*>(addr);
|
| @@ -1096,7 +1046,6 @@ uint32_t Simulator::ReadWU(uword addr, Instr* instr) {
|
| return 0;
|
| }
|
|
|
| -
|
| int32_t Simulator::ReadW(uword addr, Instr* instr) {
|
| if ((addr & 3) == 0) {
|
| int32_t* ptr = reinterpret_cast<int32_t*>(addr);
|
| @@ -1106,7 +1055,6 @@ int32_t Simulator::ReadW(uword addr, Instr* instr) {
|
| return 0;
|
| }
|
|
|
| -
|
| void Simulator::WriteW(uword addr, uint32_t value, Instr* instr) {
|
| if ((addr & 3) == 0) {
|
| uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
|
| @@ -1116,7 +1064,6 @@ void Simulator::WriteW(uword addr, uint32_t value, Instr* instr) {
|
| UnalignedAccess("write single word", addr, instr);
|
| }
|
|
|
| -
|
| uint16_t Simulator::ReadHU(uword addr, Instr* instr) {
|
| if ((addr & 1) == 0) {
|
| uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
|
| @@ -1126,7 +1073,6 @@ uint16_t Simulator::ReadHU(uword addr, Instr* instr) {
|
| return 0;
|
| }
|
|
|
| -
|
| int16_t Simulator::ReadH(uword addr, Instr* instr) {
|
| if ((addr & 1) == 0) {
|
| int16_t* ptr = reinterpret_cast<int16_t*>(addr);
|
| @@ -1136,7 +1082,6 @@ int16_t Simulator::ReadH(uword addr, Instr* instr) {
|
| return 0;
|
| }
|
|
|
| -
|
| void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) {
|
| if ((addr & 1) == 0) {
|
| uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
|
| @@ -1146,25 +1091,21 @@ void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) {
|
| UnalignedAccess("halfword write", addr, instr);
|
| }
|
|
|
| -
|
| uint8_t Simulator::ReadBU(uword addr) {
|
| uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
|
| return *ptr;
|
| }
|
|
|
| -
|
| int8_t Simulator::ReadB(uword addr) {
|
| int8_t* ptr = reinterpret_cast<int8_t*>(addr);
|
| return *ptr;
|
| }
|
|
|
| -
|
| void Simulator::WriteB(uword addr, uint8_t value) {
|
| uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
|
| *ptr = value;
|
| }
|
|
|
| -
|
| // Synchronization primitives support.
|
| void Simulator::SetExclusiveAccess(uword addr) {
|
| Thread* thread = Thread::Current();
|
| @@ -1188,7 +1129,6 @@ void Simulator::SetExclusiveAccess(uword addr) {
|
| exclusive_access_state_[i].addr = addr;
|
| }
|
|
|
| -
|
| bool Simulator::HasExclusiveAccessAndOpen(uword addr) {
|
| Thread* thread = Thread::Current();
|
| ASSERT(thread != NULL);
|
| @@ -1210,28 +1150,24 @@ bool Simulator::HasExclusiveAccessAndOpen(uword addr) {
|
| return result;
|
| }
|
|
|
| -
|
| void Simulator::ClearExclusive() {
|
| MutexLocker ml(exclusive_access_lock_);
|
| // Remove the reservation for this thread.
|
| SetExclusiveAccess(0);
|
| }
|
|
|
| -
|
| intptr_t Simulator::ReadExclusiveX(uword addr, Instr* instr) {
|
| MutexLocker ml(exclusive_access_lock_);
|
| SetExclusiveAccess(addr);
|
| return ReadX(addr, instr);
|
| }
|
|
|
| -
|
| intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) {
|
| MutexLocker ml(exclusive_access_lock_);
|
| SetExclusiveAccess(addr);
|
| return ReadWU(addr, instr);
|
| }
|
|
|
| -
|
| intptr_t Simulator::WriteExclusiveX(uword addr, intptr_t value, Instr* instr) {
|
| MutexLocker ml(exclusive_access_lock_);
|
| bool write_allowed = HasExclusiveAccessAndOpen(addr);
|
| @@ -1242,7 +1178,6 @@ intptr_t Simulator::WriteExclusiveX(uword addr, intptr_t value, Instr* instr) {
|
| return 1; // Failure.
|
| }
|
|
|
| -
|
| intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) {
|
| MutexLocker ml(exclusive_access_lock_);
|
| bool write_allowed = HasExclusiveAccessAndOpen(addr);
|
| @@ -1253,7 +1188,6 @@ intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) {
|
| return 1; // Failure.
|
| }
|
|
|
| -
|
| uword Simulator::CompareExchange(uword* address,
|
| uword compare_value,
|
| uword new_value) {
|
| @@ -1273,7 +1207,6 @@ uword Simulator::CompareExchange(uword* address,
|
| return value;
|
| }
|
|
|
| -
|
| uint32_t Simulator::CompareExchangeUint32(uint32_t* address,
|
| uint32_t compare_value,
|
| uint32_t new_value) {
|
| @@ -1293,7 +1226,6 @@ uint32_t Simulator::CompareExchangeUint32(uint32_t* address,
|
| return value;
|
| }
|
|
|
| -
|
| // Unsupported instructions use Format to print an error and stop execution.
|
| void Simulator::Format(Instr* instr, const char* format) {
|
| OS::Print("Simulator found unsupported instruction:\n 0x%p: %s\n", instr,
|
| @@ -1301,14 +1233,12 @@ void Simulator::Format(Instr* instr, const char* format) {
|
| UNIMPLEMENTED();
|
| }
|
|
|
| -
|
| // Calculate and set the Negative and Zero flags.
|
| void Simulator::SetNZFlagsW(int32_t val) {
|
| n_flag_ = (val < 0);
|
| z_flag_ = (val == 0);
|
| }
|
|
|
| -
|
| // Calculate C flag value for additions (and subtractions with adjusted args).
|
| bool Simulator::CarryFromW(int32_t left, int32_t right, int32_t carry) {
|
| uint64_t uleft = static_cast<uint32_t>(left);
|
| @@ -1317,21 +1247,18 @@ bool Simulator::CarryFromW(int32_t left, int32_t right, int32_t carry) {
|
| return ((uleft + uright + ucarry) >> 32) != 0;
|
| }
|
|
|
| -
|
| // Calculate V flag value for additions (and subtractions with adjusted args).
|
| bool Simulator::OverflowFromW(int32_t left, int32_t right, int32_t carry) {
|
| int64_t result = static_cast<int64_t>(left) + right + carry;
|
| return (result >> 31) != (result >> 32);
|
| }
|
|
|
| -
|
| // Calculate and set the Negative and Zero flags.
|
| void Simulator::SetNZFlagsX(int64_t val) {
|
| n_flag_ = (val < 0);
|
| z_flag_ = (val == 0);
|
| }
|
|
|
| -
|
| // Calculate C flag value for additions and subtractions.
|
| bool Simulator::CarryFromX(int64_t alu_out,
|
| int64_t left,
|
| @@ -1344,7 +1271,6 @@ bool Simulator::CarryFromX(int64_t alu_out,
|
| }
|
| }
|
|
|
| -
|
| // Calculate V flag value for additions and subtractions.
|
| bool Simulator::OverflowFromX(int64_t alu_out,
|
| int64_t left,
|
| @@ -1357,19 +1283,16 @@ bool Simulator::OverflowFromX(int64_t alu_out,
|
| }
|
| }
|
|
|
| -
|
| // Set the Carry flag.
|
| void Simulator::SetCFlag(bool val) {
|
| c_flag_ = val;
|
| }
|
|
|
| -
|
| // Set the oVerflow flag.
|
| void Simulator::SetVFlag(bool val) {
|
| v_flag_ = val;
|
| }
|
|
|
| -
|
| void Simulator::DecodeMoveWide(Instr* instr) {
|
| const Register rd = instr->RdField();
|
| const int hw = instr->HWField();
|
| @@ -1413,7 +1336,6 @@ void Simulator::DecodeMoveWide(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeAddSubImm(Instr* instr) {
|
| const bool addition = (instr->Bit(30) == 0);
|
| // Format(instr, "addi'sf's 'rd, 'rn, 'imm12s");
|
| @@ -1450,7 +1372,6 @@ void Simulator::DecodeAddSubImm(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeLogicalImm(Instr* instr) {
|
| const int op = instr->Bits(29, 2);
|
| const bool set_flags = op == 3;
|
| @@ -1501,7 +1422,6 @@ void Simulator::DecodeLogicalImm(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodePCRel(Instr* instr) {
|
| const int op = instr->Bit(31);
|
| if (op == 0) {
|
| @@ -1517,7 +1437,6 @@ void Simulator::DecodePCRel(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeDPImmediate(Instr* instr) {
|
| if (instr->IsMoveWideOp()) {
|
| DecodeMoveWide(instr);
|
| @@ -1532,7 +1451,6 @@ void Simulator::DecodeDPImmediate(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeCompareAndBranch(Instr* instr) {
|
| const int op = instr->Bit(24);
|
| const Register rt = instr->RtField();
|
| @@ -1553,7 +1471,6 @@ void Simulator::DecodeCompareAndBranch(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| bool Simulator::ConditionallyExecute(Instr* instr) {
|
| Condition cond;
|
| if (instr->IsConditionalSelectOp()) {
|
| @@ -1598,7 +1515,6 @@ bool Simulator::ConditionallyExecute(Instr* instr) {
|
| return false;
|
| }
|
|
|
| -
|
| void Simulator::DecodeConditionalBranch(Instr* instr) {
|
| // Format(instr, "b'cond 'dest19");
|
| if ((instr->Bit(24) != 0) || (instr->Bit(4) != 0)) {
|
| @@ -1611,7 +1527,6 @@ void Simulator::DecodeConditionalBranch(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| // Calls into the Dart runtime are based on this interface.
|
| typedef void (*SimulatorRuntimeCall)(NativeArguments arguments);
|
|
|
| @@ -1639,7 +1554,6 @@ typedef double (*SimulatorLeafFloatRuntimeCall)(double d0,
|
| typedef void (*SimulatorBootstrapNativeCall)(NativeArguments* arguments);
|
| typedef void (*SimulatorNativeCall)(NativeArguments* arguments, uword target);
|
|
|
| -
|
| void Simulator::DoRedirectedCall(Instr* instr) {
|
| SimulatorSetjmpBuffer buffer(this);
|
| if (!setjmp(buffer.buffer_)) {
|
| @@ -1751,7 +1665,6 @@ void Simulator::DoRedirectedCall(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeExceptionGen(Instr* instr) {
|
| if ((instr->Bits(0, 2) == 1) && (instr->Bits(2, 3) == 0) &&
|
| (instr->Bits(21, 3) == 0)) {
|
| @@ -1790,7 +1703,6 @@ void Simulator::DecodeExceptionGen(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeSystem(Instr* instr) {
|
| if (instr->InstructionBits() == CLREX) {
|
| // Format(instr, "clrex");
|
| @@ -1811,7 +1723,6 @@ void Simulator::DecodeSystem(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeTestAndBranch(Instr* instr) {
|
| const int op = instr->Bit(24);
|
| const int bitpos = instr->Bits(19, 4) | (instr->Bit(31) << 5);
|
| @@ -1832,7 +1743,6 @@ void Simulator::DecodeTestAndBranch(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeUnconditionalBranch(Instr* instr) {
|
| const bool link = instr->Bit(31) == 1;
|
| const int64_t imm26 = instr->SImm26Field();
|
| @@ -1844,7 +1754,6 @@ void Simulator::DecodeUnconditionalBranch(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeUnconditionalBranchReg(Instr* instr) {
|
| if ((instr->Bits(0, 5) == 0) && (instr->Bits(10, 6) == 0) &&
|
| (instr->Bits(16, 5) == 0x1f)) {
|
| @@ -1881,7 +1790,6 @@ void Simulator::DecodeUnconditionalBranchReg(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeCompareBranch(Instr* instr) {
|
| if (instr->IsCompareAndBranchOp()) {
|
| DecodeCompareAndBranch(instr);
|
| @@ -1902,7 +1810,6 @@ void Simulator::DecodeCompareBranch(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeLoadStoreReg(Instr* instr) {
|
| // Calculate the address.
|
| const Register rn = instr->RnField();
|
| @@ -2096,7 +2003,6 @@ void Simulator::DecodeLoadStoreReg(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeLoadStoreRegPair(Instr* instr) {
|
| const int32_t opc = instr->Bits(23, 3);
|
| const Register rn = instr->RnField();
|
| @@ -2190,7 +2096,6 @@ void Simulator::DecodeLoadStoreRegPair(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeLoadRegLiteral(Instr* instr) {
|
| if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) ||
|
| (instr->Bits(24, 3) != 0)) {
|
| @@ -2211,7 +2116,6 @@ void Simulator::DecodeLoadRegLiteral(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeLoadStoreExclusive(Instr* instr) {
|
| if ((instr->Bit(23) != 0) || (instr->Bit(21) != 0) || (instr->Bit(15) != 0)) {
|
| UNIMPLEMENTED();
|
| @@ -2251,7 +2155,6 @@ void Simulator::DecodeLoadStoreExclusive(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeLoadStore(Instr* instr) {
|
| if (instr->IsLoadStoreRegOp()) {
|
| DecodeLoadStoreReg(instr);
|
| @@ -2266,7 +2169,6 @@ void Simulator::DecodeLoadStore(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| int64_t Simulator::ShiftOperand(uint8_t reg_size,
|
| int64_t value,
|
| Shift shift_type,
|
| @@ -2301,7 +2203,6 @@ int64_t Simulator::ShiftOperand(uint8_t reg_size,
|
| }
|
| }
|
|
|
| -
|
| int64_t Simulator::ExtendOperand(uint8_t reg_size,
|
| int64_t value,
|
| Extend extend_type,
|
| @@ -2336,7 +2237,6 @@ int64_t Simulator::ExtendOperand(uint8_t reg_size,
|
| return (value << amount) & mask;
|
| }
|
|
|
| -
|
| int64_t Simulator::DecodeShiftExtendOperand(Instr* instr) {
|
| const Register rm = instr->RmField();
|
| const int64_t rm_val = get_register(rm, R31IsZR);
|
| @@ -2355,7 +2255,6 @@ int64_t Simulator::DecodeShiftExtendOperand(Instr* instr) {
|
| return -1;
|
| }
|
|
|
| -
|
| void Simulator::DecodeAddSubShiftExt(Instr* instr) {
|
| // Format(instr, "add'sf's 'rd, 'rn, 'shift_op");
|
| // also, sub, cmp, etc.
|
| @@ -2392,7 +2291,6 @@ void Simulator::DecodeAddSubShiftExt(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeAddSubWithCarry(Instr* instr) {
|
| // Format(instr, "adc'sf's 'rd, 'rn, 'rm");
|
| // Format(instr, "sbc'sf's 'rd, 'rn, 'rm");
|
| @@ -2430,7 +2328,6 @@ void Simulator::DecodeAddSubWithCarry(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeLogicalShift(Instr* instr) {
|
| const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21);
|
| const Register rd = instr->RdField();
|
| @@ -2494,7 +2391,6 @@ void Simulator::DecodeLogicalShift(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| static int64_t divide64(int64_t top, int64_t bottom, bool signd) {
|
| // ARM64 does not trap on integer division by zero. The destination register
|
| // is instead set to 0.
|
| @@ -2517,7 +2413,6 @@ static int64_t divide64(int64_t top, int64_t bottom, bool signd) {
|
| }
|
| }
|
|
|
| -
|
| static int32_t divide32(int32_t top, int32_t bottom, bool signd) {
|
| // ARM64 does not trap on integer division by zero. The destination register
|
| // is instead set to 0.
|
| @@ -2540,7 +2435,6 @@ static int32_t divide32(int32_t top, int32_t bottom, bool signd) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeMiscDP1Source(Instr* instr) {
|
| if (instr->Bit(29) != 0) {
|
| UnimplementedInstruction(instr);
|
| @@ -2577,7 +2471,6 @@ void Simulator::DecodeMiscDP1Source(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeMiscDP2Source(Instr* instr) {
|
| if (instr->Bit(29) != 0) {
|
| UnimplementedInstruction(instr);
|
| @@ -2645,7 +2538,6 @@ void Simulator::DecodeMiscDP2Source(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeMiscDP3Source(Instr* instr) {
|
| const Register rd = instr->RdField();
|
| const Register rn = instr->RnField();
|
| @@ -2726,7 +2618,6 @@ void Simulator::DecodeMiscDP3Source(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeConditionalSelect(Instr* instr) {
|
| const Register rd = instr->RdField();
|
| const Register rn = instr->RnField();
|
| @@ -2774,7 +2665,6 @@ void Simulator::DecodeConditionalSelect(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeDPRegister(Instr* instr) {
|
| if (instr->IsAddSubShiftExtOp()) {
|
| DecodeAddSubShiftExt(instr);
|
| @@ -2795,7 +2685,6 @@ void Simulator::DecodeDPRegister(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeSIMDCopy(Instr* instr) {
|
| const int32_t Q = instr->Bit(30);
|
| const int32_t op = instr->Bit(29);
|
| @@ -2890,7 +2779,6 @@ void Simulator::DecodeSIMDCopy(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeSIMDThreeSame(Instr* instr) {
|
| const int Q = instr->Bit(30);
|
| const int U = instr->Bit(29);
|
| @@ -3047,7 +2935,6 @@ void Simulator::DecodeSIMDThreeSame(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| static float arm_reciprocal_sqrt_estimate(float a) {
|
| // From the ARM Architecture Reference Manual A2-87.
|
| if (isinf(a) || (fabs(a) >= exp2f(126)))
|
| @@ -3102,7 +2989,6 @@ static float arm_reciprocal_sqrt_estimate(float a) {
|
| return bit_cast<float, int32_t>(result_bits);
|
| }
|
|
|
| -
|
| static float arm_recip_estimate(float a) {
|
| // From the ARM Architecture Reference Manual A2-85.
|
| if (isinf(a) || (fabs(a) >= exp2f(126)))
|
| @@ -3139,7 +3025,6 @@ static float arm_recip_estimate(float a) {
|
| return bit_cast<float, int32_t>(result_bits);
|
| }
|
|
|
| -
|
| void Simulator::DecodeSIMDTwoReg(Instr* instr) {
|
| const int32_t Q = instr->Bit(30);
|
| const int32_t U = instr->Bit(29);
|
| @@ -3241,7 +3126,6 @@ void Simulator::DecodeSIMDTwoReg(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeDPSimd1(Instr* instr) {
|
| if (instr->IsSIMDCopyOp()) {
|
| DecodeSIMDCopy(instr);
|
| @@ -3254,7 +3138,6 @@ void Simulator::DecodeDPSimd1(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeFPImm(Instr* instr) {
|
| if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) ||
|
| (instr->Bits(5, 5) != 0)) {
|
| @@ -3274,7 +3157,6 @@ void Simulator::DecodeFPImm(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeFPIntCvt(Instr* instr) {
|
| const VRegister vd = instr->VdField();
|
| const VRegister vn = instr->VnField();
|
| @@ -3332,7 +3214,6 @@ void Simulator::DecodeFPIntCvt(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeFPOneSource(Instr* instr) {
|
| const int opc = instr->Bits(15, 6);
|
| const VRegister vd = instr->VdField();
|
| @@ -3387,7 +3268,6 @@ void Simulator::DecodeFPOneSource(Instr* instr) {
|
| set_vregisterd(vd, 1, 0);
|
| }
|
|
|
| -
|
| void Simulator::DecodeFPTwoSource(Instr* instr) {
|
| if (instr->Bits(22, 2) != 1) {
|
| UnimplementedInstruction(instr);
|
| @@ -3427,7 +3307,6 @@ void Simulator::DecodeFPTwoSource(Instr* instr) {
|
| set_vregisterd(vd, 1, 0);
|
| }
|
|
|
| -
|
| void Simulator::DecodeFPCompare(Instr* instr) {
|
| const VRegister vn = instr->VnField();
|
| const VRegister vm = instr->VmField();
|
| @@ -3468,7 +3347,6 @@ void Simulator::DecodeFPCompare(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeFP(Instr* instr) {
|
| if (instr->IsFPImmOp()) {
|
| DecodeFPImm(instr);
|
| @@ -3485,7 +3363,6 @@ void Simulator::DecodeFP(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::DecodeDPSimd2(Instr* instr) {
|
| if (instr->IsFPOp()) {
|
| DecodeFP(instr);
|
| @@ -3494,7 +3371,6 @@ void Simulator::DecodeDPSimd2(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| // Executes the current instruction.
|
| void Simulator::InstructionDecode(Instr* instr) {
|
| pc_modified_ = false;
|
| @@ -3530,7 +3406,6 @@ void Simulator::InstructionDecode(Instr* instr) {
|
| }
|
| }
|
|
|
| -
|
| void Simulator::Execute() {
|
| // Get the PC to simulate. Cannot use the accessor here as we need the
|
| // raw PC value and not the one used as input to arithmetic instructions.
|
| @@ -3571,7 +3446,6 @@ void Simulator::Execute() {
|
| }
|
| }
|
|
|
| -
|
| int64_t Simulator::Call(int64_t entry,
|
| int64_t parameter0,
|
| int64_t parameter1,
|
| @@ -3664,7 +3538,6 @@ int64_t Simulator::Call(int64_t entry,
|
| return return_value;
|
| }
|
|
|
| -
|
| void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) {
|
| // Walk over all setjmp buffers (simulated --> C++ transitions)
|
| // and try to find the setjmp associated with the simulated stack pointer.
|
|
|