| Index: runtime/vm/simulator_arm.cc
|
| ===================================================================
|
| --- runtime/vm/simulator_arm.cc (revision 20300)
|
| +++ runtime/vm/simulator_arm.cc (working copy)
|
| @@ -93,8 +93,14 @@
|
| explicit SimulatorDebugger(Simulator* sim);
|
| ~SimulatorDebugger();
|
|
|
| + // Enter interactive debugging, and attach to the simulator.
|
| + void Attach(Instr* instr, const char *message);
|
| +
|
| + // Enter interactive debugging if debugging is already attached to
|
| + // the simulator, and otherwise return immediately.
|
| void Stop(Instr* instr, const char* message);
|
| void Debug();
|
| +
|
| char* ReadLine(const char* prompt);
|
|
|
| private:
|
| @@ -129,6 +135,12 @@
|
| }
|
|
|
|
|
| +void SimulatorDebugger::Attach(Instr* instr, const char* message) {
|
| + sim_->set_debugger_attached(true);
|
| + Stop(instr, message);
|
| +}
|
| +
|
| +
|
| void SimulatorDebugger::Stop(Instr* instr, const char* message) {
|
| OS::Print("Simulator hit %s\n", message);
|
| Debug();
|
| @@ -293,7 +305,6 @@
|
| void SimulatorDebugger::Debug() {
|
| intptr_t last_pc = -1;
|
| bool done = false;
|
| - bool decoded = true;
|
|
|
| #define COMMAND_SIZE 63
|
| #define ARG_SIZE 255
|
| @@ -305,6 +316,12 @@
|
| char arg1[ARG_SIZE + 1];
|
| char arg2[ARG_SIZE + 1];
|
|
|
| + // If the simulator does not already have debugging attached, then return---
|
| + // we aren't in interactive mode.
|
| + if (!sim_->debugger_attached()) {
|
| + return;
|
| + }
|
| +
|
| // make sure to have a proper terminating character if reaching the limit
|
| cmd[COMMAND_SIZE] = 0;
|
| arg1[ARG_SIZE] = 0;
|
| @@ -317,7 +334,7 @@
|
| while (!done) {
|
| if (last_pc != sim_->get_pc()) {
|
| last_pc = sim_->get_pc();
|
| - decoded = Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize);
|
| + Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize);
|
| }
|
| char* line = ReadLine("sim> ");
|
| if (line == NULL) {
|
| @@ -353,20 +370,12 @@
|
| OS::Print("Quitting\n");
|
| OS::Exit(0);
|
| } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
|
| - if (decoded) {
|
| - sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
|
| - } else {
|
| - OS::Print("Instruction could not be decoded. Stepping disabled.\n");
|
| - }
|
| + sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
|
| } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
|
| - if (decoded) {
|
| - // Execute the one instruction we broke at with breakpoints disabled.
|
| - sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
|
| - // Leave the debugger shell.
|
| - done = true;
|
| - } else {
|
| - OS::Print("Instruction could not be decoded. Cannot continue.\n");
|
| - }
|
| + // Execute the one instruction we broke at with breakpoints disabled.
|
| + sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
|
| + // Leave the debugger shell.
|
| + done = true;
|
| } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
|
| if (args == 2) {
|
| uint32_t value;
|
| @@ -668,6 +677,8 @@
|
| fp_z_flag_ = false;
|
| fp_c_flag_ = false;
|
| fp_v_flag_ = false;
|
| +
|
| + debugger_attached_ = false;
|
| }
|
|
|
|
|
| @@ -845,6 +856,15 @@
|
| }
|
|
|
|
|
| +void Simulator::UnimplementedInstruction(Instr* instr) {
|
| + char buffer[64];
|
| + snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr);
|
| + SimulatorDebugger dbg(this);
|
| + dbg.Stop(instr, buffer);
|
| + FATAL("Cannot continue execution after unimplemented instruction.");
|
| +}
|
| +
|
| +
|
| int Simulator::ReadW(uword addr, Instr* instr) {
|
| static StatsCounter counter_read_w("Simulated word reads");
|
| counter_read_w.Increment();
|
| @@ -1086,8 +1106,7 @@
|
| if (instr->Bit(4) == 0) {
|
| // by immediate
|
| if ((shift == ROR) && (shift_amount == 0)) {
|
| - UNIMPLEMENTED();
|
| - return result;
|
| + UnimplementedInstruction(instr);
|
| } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
|
| shift_amount = 32;
|
| }
|
| @@ -1135,7 +1154,7 @@
|
| }
|
|
|
| case ROR: {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
|
|
| @@ -1207,7 +1226,7 @@
|
| }
|
|
|
| case ROR: {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
|
|
| @@ -1391,7 +1410,8 @@
|
| }
|
| case kBreakpointSvcCode: {
|
| SimulatorDebugger dbg(this);
|
| - dbg.Stop(instr, "breakpoint");
|
| + set_debugger_attached(true);
|
| + dbg.Attach(instr, "breakpoint");
|
| break;
|
| }
|
| case kStopMessageSvcCode: {
|
| @@ -1399,7 +1419,7 @@
|
| const char* message = *reinterpret_cast<const char**>(
|
| reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize);
|
| set_pc(get_pc() + Instr::kInstrSize);
|
| - dbg.Stop(instr, message);
|
| + dbg.Attach(instr, message);
|
| break;
|
| }
|
| case kWordSpillMarkerSvcCode: {
|
| @@ -1471,15 +1491,15 @@
|
| set_pc(get_pc() + Instr::kInstrSize);
|
| char buffer[32];
|
| snprintf(buffer, sizeof(buffer), "bkpt #0x%x", instr->BkptField());
|
| - dbg.Stop(instr, buffer);
|
| + dbg.Attach(instr, buffer);
|
| } else {
|
| // Format(instr, "smc'cond");
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| }
|
| break;
|
| }
|
| default: {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
| }
|
| @@ -1539,7 +1559,7 @@
|
| break;
|
| }
|
| default: {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
| }
|
| @@ -1569,7 +1589,7 @@
|
| break;
|
| }
|
| default: {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
| }
|
| @@ -1594,12 +1614,12 @@
|
| if ((instr->Bits(16, 4) == 0) && (instr->Bits(0, 8) == 0)) {
|
| // Format(instr, "nop'cond");
|
| } else {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| }
|
| break;
|
| }
|
| default: {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
| }
|
| @@ -1727,7 +1747,7 @@
|
| set_register(rd1, val_high);
|
| }
|
| } else {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| }
|
| }
|
| }
|
| @@ -1856,7 +1876,7 @@
|
| SetNZFlags(alu_out);
|
| SetCFlag(shifter_carry_out);
|
| } else {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| }
|
| break;
|
| }
|
| @@ -1869,7 +1889,7 @@
|
| SetNZFlags(alu_out);
|
| SetCFlag(shifter_carry_out);
|
| } else {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| }
|
| break;
|
| }
|
| @@ -1883,7 +1903,7 @@
|
| SetCFlag(!BorrowFrom(rn_val, shifter_operand));
|
| SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
|
| } else {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| }
|
| break;
|
| }
|
| @@ -1897,7 +1917,7 @@
|
| SetCFlag(CarryFrom(rn_val, shifter_operand));
|
| SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
|
| } else {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| }
|
| break;
|
| }
|
| @@ -2281,7 +2301,7 @@
|
| }
|
| }
|
| } else {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| }
|
| }
|
|
|
| @@ -2317,7 +2337,7 @@
|
| switch (instr->Bits(20, 4) & 0xb) {
|
| case 1: // vnmla, vnmls, vnmul
|
| default: {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
| case 0: { // vmla, vmls floating-point
|
| @@ -2419,7 +2439,7 @@
|
| break;
|
| }
|
| default: {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
| }
|
| @@ -2448,7 +2468,7 @@
|
| break;
|
| }
|
| default: {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
| }
|
| @@ -2457,7 +2477,7 @@
|
| case 4: // vcmp, vcmpe
|
| case 5: { // vcmp #0.0, vcmpe #0.0
|
| if (instr->Bit(7) == 1) { // vcmpe
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| } else {
|
| fp_n_flag_ = false;
|
| fp_z_flag_ = false;
|
| @@ -2560,7 +2580,7 @@
|
| // flags, because we do not use them.
|
| if (instr->Bit(7) == 0) {
|
| // We only support round-to-zero mode
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
| int32_t id_val = 0;
|
| @@ -2624,7 +2644,7 @@
|
| case 14: // vcvt between floating-point and fixed-point
|
| case 15: // vcvt between floating-point and fixed-point
|
| default: {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| break;
|
| }
|
| }
|
| @@ -2651,7 +2671,7 @@
|
| c_flag_ = fp_c_flag_;
|
| v_flag_ = fp_v_flag_;
|
| } else {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| }
|
| }
|
| } else if (instr->IsMrcIdIsar0()) {
|
| @@ -2663,7 +2683,7 @@
|
| set_register(rd, 0x00100010); // simulator has only bkpt and clz.
|
| }
|
| } else {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| }
|
| }
|
|
|
| @@ -2681,7 +2701,7 @@
|
| // Format(instr, "clrex");
|
| ClearExclusive();
|
| } else {
|
| - UNIMPLEMENTED();
|
| + UnimplementedInstruction(instr);
|
| }
|
| } else if (ConditionallyExecute(instr)) {
|
| switch (instr->TypeField()) {
|
| @@ -2715,7 +2735,8 @@
|
| break;
|
| }
|
| default: {
|
| - UNIMPLEMENTED();
|
| + // Type field is three bits.
|
| + UNREACHABLE();
|
| break;
|
| }
|
| }
|
| @@ -2756,7 +2777,7 @@
|
| counter_instructions.Increment();
|
| if (icount_ == FLAG_stop_sim_at) {
|
| SimulatorDebugger dbg(this);
|
| - dbg.Debug();
|
| + dbg.Attach(instr, "Instruction count reached");
|
| } else if (IsIllegalAddress(program_counter)) {
|
| HandleIllegalAccess(program_counter, instr);
|
| } else {
|
|
|