00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <stdlib.h>
00029
00030 #include "v8.h"
00031
00032 #include "disasm.h"
00033 #include "constants-arm.h"
00034 #include "simulator-arm.h"
00035
00036 #if !defined(__arm__)
00037
00038
00039 namespace assembler { namespace arm {
00040
00041 using ::v8::internal::Object;
00042 using ::v8::internal::PrintF;
00043 using ::v8::internal::OS;
00044 using ::v8::internal::ReadLine;
00045 using ::v8::internal::DeleteArray;
00046
00047
00048
00049
00050
00051 #ifdef WIN32
00052 #define SScanF sscanf_s
00053 #else
00054 #define SScanF sscanf // NOLINT
00055 #endif
00056
00057
00058
00059 class Debugger {
00060 public:
00061 explicit Debugger(Simulator* sim);
00062 ~Debugger();
00063
00064 void Stop(Instr* instr);
00065 void Debug();
00066
00067 private:
00068 static const instr_t kBreakpointInstr =
00069 ((AL << 28) | (7 << 25) | (1 << 24) | break_point);
00070 static const instr_t kNopInstr =
00071 ((AL << 28) | (13 << 21));
00072
00073 Simulator* sim_;
00074
00075 bool GetValue(char* desc, int32_t* value);
00076
00077
00078 bool SetBreakpoint(Instr* breakpc);
00079 bool DeleteBreakpoint(Instr* breakpc);
00080
00081
00082
00083 void UndoBreakpoints();
00084 void RedoBreakpoints();
00085 };
00086
00087
00088 Debugger::Debugger(Simulator* sim) {
00089 sim_ = sim;
00090 }
00091
00092
00093 Debugger::~Debugger() {
00094 }
00095
00096
00097 void Debugger::Stop(Instr* instr) {
00098 const char* str = (const char*)(instr->InstructionBits() & 0x0fffffff);
00099 PrintF("Simulator hit %s\n", str);
00100 sim_->set_pc(sim_->get_pc() + Instr::kInstrSize);
00101 Debug();
00102 }
00103
00104
00105 static const char* reg_names[] = { "r0", "r1", "r2", "r3",
00106 "r4", "r5", "r6", "r7",
00107 "r8", "r9", "r10", "r11",
00108 "r12", "r13", "r14", "r15",
00109 "pc", "lr", "sp", "ip",
00110 "fp", "sl", ""};
00111
00112 static int reg_nums[] = { 0, 1, 2, 3,
00113 4, 5, 6, 7,
00114 8, 9, 10, 11,
00115 12, 13, 14, 15,
00116 15, 14, 13, 12,
00117 11, 10};
00118
00119
00120 static int RegNameToRegNum(char* name) {
00121 int reg = 0;
00122 while (*reg_names[reg] != 0) {
00123 if (strcmp(reg_names[reg], name) == 0) {
00124 return reg_nums[reg];
00125 }
00126 reg++;
00127 }
00128 return -1;
00129 }
00130
00131
00132 bool Debugger::GetValue(char* desc, int32_t* value) {
00133 int regnum = RegNameToRegNum(desc);
00134 if (regnum >= 0) {
00135 if (regnum == 15) {
00136 *value = sim_->get_pc();
00137 } else {
00138 *value = sim_->get_register(regnum);
00139 }
00140 return true;
00141 } else {
00142 return SScanF(desc, "%i", value) == 1;
00143 }
00144 return false;
00145 }
00146
00147
00148 bool Debugger::SetBreakpoint(Instr* breakpc) {
00149
00150 if (sim_->break_pc_ != NULL) {
00151 return false;
00152 }
00153
00154
00155 sim_->break_pc_ = breakpc;
00156 sim_->break_instr_ = breakpc->InstructionBits();
00157
00158
00159 return true;
00160 }
00161
00162
00163 bool Debugger::DeleteBreakpoint(Instr* breakpc) {
00164 if (sim_->break_pc_ != NULL) {
00165 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
00166 }
00167
00168 sim_->break_pc_ = NULL;
00169 sim_->break_instr_ = 0;
00170 return true;
00171 }
00172
00173
00174 void Debugger::UndoBreakpoints() {
00175 if (sim_->break_pc_ != NULL) {
00176 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
00177 }
00178 }
00179
00180
00181 void Debugger::RedoBreakpoints() {
00182 if (sim_->break_pc_ != NULL) {
00183 sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
00184 }
00185 }
00186
00187
00188 void Debugger::Debug() {
00189 intptr_t last_pc = -1;
00190 bool done = false;
00191
00192 #define COMMAND_SIZE 63
00193 #define ARG_SIZE 255
00194
00195 #define STR(a) #a
00196 #define XSTR(a) STR(a)
00197
00198 char cmd[COMMAND_SIZE + 1];
00199 char arg1[ARG_SIZE + 1];
00200 char arg2[ARG_SIZE + 1];
00201
00202
00203 cmd[COMMAND_SIZE] = 0;
00204 arg1[ARG_SIZE] = 0;
00205 arg2[ARG_SIZE] = 0;
00206
00207
00208
00209 UndoBreakpoints();
00210
00211 while (!done) {
00212 if (last_pc != sim_->get_pc()) {
00213 disasm::Disassembler dasm;
00214
00215 v8::internal::EmbeddedVector<char, 256> buffer;
00216 dasm.InstructionDecode(buffer,
00217 reinterpret_cast<byte*>(sim_->get_pc()));
00218 PrintF(" 0x%x %s\n", sim_->get_pc(), buffer.start());
00219 last_pc = sim_->get_pc();
00220 }
00221 char* line = ReadLine("sim> ");
00222 if (line == NULL) {
00223 break;
00224 } else {
00225
00226
00227 int args = SScanF(line,
00228 "%" XSTR(COMMAND_SIZE) "s "
00229 "%" XSTR(ARG_SIZE) "s "
00230 "%" XSTR(ARG_SIZE) "s",
00231 cmd, arg1, arg2);
00232 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
00233 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
00234 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
00235
00236 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
00237
00238 done = true;
00239 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
00240 if (args == 2) {
00241 int32_t value;
00242 if (GetValue(arg1, &value)) {
00243 PrintF("%s: %d 0x%x\n", arg1, value, value);
00244 } else {
00245 PrintF("%s unrecognized\n", arg1);
00246 }
00247 } else {
00248 PrintF("print value\n");
00249 }
00250 } else if ((strcmp(cmd, "po") == 0)
00251 || (strcmp(cmd, "printobject") == 0)) {
00252 if (args == 2) {
00253 int32_t value;
00254 if (GetValue(arg1, &value)) {
00255 Object* obj = reinterpret_cast<Object*>(value);
00256 USE(obj);
00257 PrintF("%s: \n", arg1);
00258 #if defined(DEBUG)
00259 obj->PrintLn();
00260 #endif // defined(DEBUG)
00261 } else {
00262 PrintF("%s unrecognized\n", arg1);
00263 }
00264 } else {
00265 PrintF("printobject value\n");
00266 }
00267 } else if (strcmp(cmd, "disasm") == 0) {
00268 disasm::Disassembler dasm;
00269
00270 v8::internal::EmbeddedVector<char, 256> buffer;
00271
00272 byte* cur = NULL;
00273 byte* end = NULL;
00274
00275 if (args == 1) {
00276 cur = reinterpret_cast<byte*>(sim_->get_pc());
00277 end = cur + (10 * Instr::kInstrSize);
00278 } else if (args == 2) {
00279 int32_t value;
00280 if (GetValue(arg1, &value)) {
00281 cur = reinterpret_cast<byte*>(value);
00282
00283 end = cur + (10 * Instr::kInstrSize);
00284 }
00285 } else {
00286 int32_t value1;
00287 int32_t value2;
00288 if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
00289 cur = reinterpret_cast<byte*>(value1);
00290 end = cur + (value2 * Instr::kInstrSize);
00291 }
00292 }
00293
00294 while (cur < end) {
00295 dasm.InstructionDecode(buffer, cur);
00296 PrintF(" 0x%x %s\n", cur, buffer.start());
00297 cur += Instr::kInstrSize;
00298 }
00299 } else if (strcmp(cmd, "gdb") == 0) {
00300 PrintF("relinquishing control to gdb\n");
00301 v8::internal::OS::DebugBreak();
00302 PrintF("regaining control from gdb\n");
00303 } else if (strcmp(cmd, "break") == 0) {
00304 if (args == 2) {
00305 int32_t value;
00306 if (GetValue(arg1, &value)) {
00307 if (!SetBreakpoint(reinterpret_cast<Instr*>(value))) {
00308 PrintF("setting breakpoint failed\n");
00309 }
00310 } else {
00311 PrintF("%s unrecognized\n", arg1);
00312 }
00313 } else {
00314 PrintF("break addr\n");
00315 }
00316 } else if (strcmp(cmd, "del") == 0) {
00317 if (!DeleteBreakpoint(NULL)) {
00318 PrintF("deleting breakpoint failed\n");
00319 }
00320 } else if (strcmp(cmd, "flags") == 0) {
00321 PrintF("N flag: %d; ", sim_->n_flag_);
00322 PrintF("Z flag: %d; ", sim_->z_flag_);
00323 PrintF("C flag: %d; ", sim_->c_flag_);
00324 PrintF("V flag: %d\n", sim_->v_flag_);
00325 } else if (strcmp(cmd, "unstop") == 0) {
00326 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize;
00327 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
00328 if (stop_instr->ConditionField() == special_condition) {
00329 stop_instr->SetInstructionBits(kNopInstr);
00330 } else {
00331 PrintF("Not at debugger stop.");
00332 }
00333 } else {
00334 PrintF("Unknown command: %s\n", cmd);
00335 }
00336 }
00337 DeleteArray(line);
00338 }
00339
00340
00341
00342 RedoBreakpoints();
00343
00344 #undef COMMAND_SIZE
00345 #undef ARG_SIZE
00346
00347 #undef STR
00348 #undef XSTR
00349 }
00350
00351
00352 Simulator::Simulator() {
00353
00354
00355 size_t stack_size = 1 * 1024*1024;
00356 stack_ = reinterpret_cast<char*>(malloc(stack_size));
00357 pc_modified_ = false;
00358 icount_ = 0;
00359 break_pc_ = NULL;
00360 break_instr_ = 0;
00361
00362
00363
00364 for (int i = 0; i < num_registers; i++) {
00365 registers_[i] = 0;
00366 }
00367 n_flag_ = false;
00368 z_flag_ = false;
00369 c_flag_ = false;
00370 v_flag_ = false;
00371
00372
00373
00374
00375 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size - 64;
00376
00377
00378 registers_[pc] = bad_lr;
00379 registers_[lr] = bad_lr;
00380 }
00381
00382
00383
00384
00385
00386 static Simulator* the_sim = NULL;
00387
00388
00389
00390
00391 Simulator* Simulator::current() {
00392 if (the_sim == NULL) {
00393 the_sim = new Simulator();
00394 }
00395 return the_sim;
00396 }
00397
00398
00399
00400
00401 void Simulator::set_register(int reg, int32_t value) {
00402 ASSERT((reg >= 0) && (reg < num_registers));
00403 if (reg == pc) {
00404 pc_modified_ = true;
00405 }
00406 registers_[reg] = value;
00407 }
00408
00409
00410
00411
00412 int32_t Simulator::get_register(int reg) const {
00413 ASSERT((reg >= 0) && (reg < num_registers));
00414 return registers_[reg] + ((reg == pc) ? Instr::kPCReadOffset : 0);
00415 }
00416
00417
00418
00419 void Simulator::set_pc(int32_t value) {
00420 pc_modified_ = true;
00421 registers_[pc] = value;
00422 }
00423
00424
00425
00426 int32_t Simulator::get_pc() const {
00427 return registers_[pc];
00428 }
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 int Simulator::ReadW(int32_t addr, Instr* instr) {
00440 if ((addr & 3) == 0) {
00441 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
00442 return *ptr;
00443 }
00444 PrintF("Unaligned read at %x\n", addr);
00445 UNIMPLEMENTED();
00446 return 0;
00447 }
00448
00449
00450 void Simulator::WriteW(int32_t addr, int value, Instr* instr) {
00451 if ((addr & 3) == 0) {
00452 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
00453 *ptr = value;
00454 return;
00455 }
00456 PrintF("Unaligned write at %x, pc=%p\n", addr, instr);
00457 UNIMPLEMENTED();
00458 }
00459
00460
00461 uint16_t Simulator::ReadHU(int32_t addr, Instr* instr) {
00462 if ((addr & 1) == 0) {
00463 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
00464 return *ptr;
00465 }
00466 PrintF("Unaligned read at %x, pc=%p\n", addr, instr);
00467 UNIMPLEMENTED();
00468 return 0;
00469 }
00470
00471
00472 int16_t Simulator::ReadH(int32_t addr, Instr* instr) {
00473 if ((addr & 1) == 0) {
00474 int16_t* ptr = reinterpret_cast<int16_t*>(addr);
00475 return *ptr;
00476 }
00477 PrintF("Unaligned read at %x\n", addr);
00478 UNIMPLEMENTED();
00479 return 0;
00480 }
00481
00482
00483 void Simulator::WriteH(int32_t addr, uint16_t value, Instr* instr) {
00484 if ((addr & 1) == 0) {
00485 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
00486 *ptr = value;
00487 return;
00488 }
00489 PrintF("Unaligned write at %x, pc=%p\n", addr, instr);
00490 UNIMPLEMENTED();
00491 }
00492
00493
00494 void Simulator::WriteH(int32_t addr, int16_t value, Instr* instr) {
00495 if ((addr & 1) == 0) {
00496 int16_t* ptr = reinterpret_cast<int16_t*>(addr);
00497 *ptr = value;
00498 return;
00499 }
00500 PrintF("Unaligned write at %x, pc=%p\n", addr, instr);
00501 UNIMPLEMENTED();
00502 }
00503
00504
00505 uint8_t Simulator::ReadBU(int32_t addr) {
00506 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
00507 return *ptr;
00508 }
00509
00510
00511 int8_t Simulator::ReadB(int32_t addr) {
00512 int8_t* ptr = reinterpret_cast<int8_t*>(addr);
00513 return *ptr;
00514 }
00515
00516
00517 void Simulator::WriteB(int32_t addr, uint8_t value) {
00518 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
00519 *ptr = value;
00520 }
00521
00522
00523 void Simulator::WriteB(int32_t addr, int8_t value) {
00524 int8_t* ptr = reinterpret_cast<int8_t*>(addr);
00525 *ptr = value;
00526 }
00527
00528
00529
00530 uintptr_t Simulator::StackLimit() const {
00531
00532
00533 return reinterpret_cast<uintptr_t>(stack_) + 256;
00534 }
00535
00536
00537
00538 void Simulator::Format(Instr* instr, const char* format) {
00539 PrintF("Simulator found unsupported instruction:\n 0x%x: %s\n",
00540 instr, format);
00541 UNIMPLEMENTED();
00542 }
00543
00544
00545
00546
00547 bool Simulator::ConditionallyExecute(Instr* instr) {
00548 switch (instr->ConditionField()) {
00549 case EQ: return z_flag_;
00550 case NE: return !z_flag_;
00551 case CS: return c_flag_;
00552 case CC: return !c_flag_;
00553 case MI: return n_flag_;
00554 case PL: return !n_flag_;
00555 case VS: return v_flag_;
00556 case VC: return !v_flag_;
00557 case HI: return c_flag_ && !z_flag_;
00558 case LS: return !c_flag_ || z_flag_;
00559 case GE: return n_flag_ == v_flag_;
00560 case LT: return n_flag_ != v_flag_;
00561 case GT: return !z_flag_ && (n_flag_ == v_flag_);
00562 case LE: return z_flag_ || (n_flag_ != v_flag_);
00563 case AL: return true;
00564 default: UNREACHABLE();
00565 }
00566 return false;
00567 }
00568
00569
00570
00571 void Simulator::SetNZFlags(int32_t val) {
00572 n_flag_ = (val < 0);
00573 z_flag_ = (val == 0);
00574 }
00575
00576
00577
00578 void Simulator::SetCFlag(bool val) {
00579 c_flag_ = val;
00580 }
00581
00582
00583
00584 void Simulator::SetVFlag(bool val) {
00585 v_flag_ = val;
00586 }
00587
00588
00589
00590 bool Simulator::CarryFrom(int32_t left, int32_t right) {
00591 uint32_t uleft = static_cast<uint32_t>(left);
00592 uint32_t uright = static_cast<uint32_t>(right);
00593 uint32_t urest = 0xffffffffU - uleft;
00594
00595 return (uright > urest);
00596 }
00597
00598
00599
00600 bool Simulator::BorrowFrom(int32_t left, int32_t right) {
00601 uint32_t uleft = static_cast<uint32_t>(left);
00602 uint32_t uright = static_cast<uint32_t>(right);
00603
00604 return (uright > uleft);
00605 }
00606
00607
00608
00609 bool Simulator::OverflowFrom(int32_t alu_out,
00610 int32_t left, int32_t right, bool addition) {
00611 bool overflow;
00612 if (addition) {
00613
00614 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
00615
00616 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
00617 } else {
00618
00619 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
00620
00621 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
00622 }
00623 return overflow;
00624 }
00625
00626
00627
00628
00629 int32_t Simulator::GetShiftRm(Instr* instr, bool* carry_out) {
00630 Shift shift = instr->ShiftField();
00631 int shift_amount = instr->ShiftAmountField();
00632 int32_t result = get_register(instr->RmField());
00633 if (instr->Bit(4) == 0) {
00634
00635 if ((shift == ROR) && (shift_amount == 0)) {
00636 UNIMPLEMENTED();
00637 return result;
00638 } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
00639 shift_amount = 32;
00640 }
00641 switch (shift) {
00642 case ASR: {
00643 if (shift_amount == 0) {
00644 if (result < 0) {
00645 result = 0xffffffff;
00646 *carry_out = true;
00647 } else {
00648 result = 0;
00649 *carry_out = false;
00650 }
00651 } else {
00652 result >>= (shift_amount - 1);
00653 *carry_out = (result & 1) == 1;
00654 result >>= 1;
00655 }
00656 break;
00657 }
00658
00659 case LSL: {
00660 if (shift_amount == 0) {
00661 *carry_out = c_flag_;
00662 } else {
00663 result <<= (shift_amount - 1);
00664 *carry_out = (result < 0);
00665 result <<= 1;
00666 }
00667 break;
00668 }
00669
00670 case LSR: {
00671 if (shift_amount == 0) {
00672 result = 0;
00673 *carry_out = c_flag_;
00674 } else {
00675 uint32_t uresult = static_cast<uint32_t>(result);
00676 uresult >>= (shift_amount - 1);
00677 *carry_out = (uresult & 1) == 1;
00678 uresult >>= 1;
00679 result = static_cast<int32_t>(uresult);
00680 }
00681 break;
00682 }
00683
00684 case ROR: {
00685 UNIMPLEMENTED();
00686 break;
00687 }
00688
00689 default: {
00690 UNREACHABLE();
00691 break;
00692 }
00693 }
00694 } else {
00695
00696 int rs = instr->RsField();
00697 shift_amount = get_register(rs) &0xff;
00698 switch (shift) {
00699 case ASR: {
00700 if (shift_amount == 0) {
00701 *carry_out = c_flag_;
00702 } else if (shift_amount < 32) {
00703 result >>= (shift_amount - 1);
00704 *carry_out = (result & 1) == 1;
00705 result >>= 1;
00706 } else {
00707 ASSERT(shift_amount >= 32);
00708 if (result < 0) {
00709 *carry_out = true;
00710 result = 0xffffffff;
00711 } else {
00712 *carry_out = false;
00713 result = 0;
00714 }
00715 }
00716 break;
00717 }
00718
00719 case LSL: {
00720 if (shift_amount == 0) {
00721 *carry_out = c_flag_;
00722 } else if (shift_amount < 32) {
00723 result <<= (shift_amount - 1);
00724 *carry_out = (result < 0);
00725 result <<= 1;
00726 } else if (shift_amount == 32) {
00727 *carry_out = (result & 1) == 1;
00728 result = 0;
00729 } else {
00730 ASSERT(shift_amount > 32);
00731 *carry_out = false;
00732 result = 0;
00733 }
00734 break;
00735 }
00736
00737 case LSR: {
00738 if (shift_amount == 0) {
00739 *carry_out = c_flag_;
00740 } else if (shift_amount < 32) {
00741 uint32_t uresult = static_cast<uint32_t>(result);
00742 uresult >>= (shift_amount - 1);
00743 *carry_out = (uresult & 1) == 1;
00744 uresult >>= 1;
00745 result = static_cast<int32_t>(uresult);
00746 } else if (shift_amount == 32) {
00747 *carry_out = (result < 0);
00748 result = 0;
00749 } else {
00750 *carry_out = false;
00751 result = 0;
00752 }
00753 break;
00754 }
00755
00756 case ROR: {
00757 UNIMPLEMENTED();
00758 break;
00759 }
00760
00761 default: {
00762 UNREACHABLE();
00763 break;
00764 }
00765 }
00766 }
00767 return result;
00768 }
00769
00770
00771
00772
00773 int32_t Simulator::GetImm(Instr* instr, bool* carry_out) {
00774 int rotate = instr->RotateField() * 2;
00775 int immed8 = instr->Immed8Field();
00776 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
00777 *carry_out = (rotate == 0) ? c_flag_ : (imm < 0);
00778 return imm;
00779 }
00780
00781
00782 static int count_bits(int bit_vector) {
00783 int count = 0;
00784 while (bit_vector != 0) {
00785 if ((bit_vector & 1) != 0) {
00786 count++;
00787 }
00788 bit_vector >>= 1;
00789 }
00790 return count;
00791 }
00792
00793
00794
00795 void Simulator::HandleRList(Instr* instr, bool load) {
00796 int rn = instr->RnField();
00797 int32_t rn_val = get_register(rn);
00798 int rlist = instr->RlistField();
00799 int num_regs = count_bits(rlist);
00800
00801 intptr_t start_address = 0;
00802 intptr_t end_address = 0;
00803 switch (instr->PUField()) {
00804 case 0: {
00805
00806 UNIMPLEMENTED();
00807 break;
00808 }
00809 case 1: {
00810
00811 start_address = rn_val;
00812 end_address = rn_val + (num_regs * 4) - 4;
00813 rn_val = rn_val + (num_regs * 4);
00814 break;
00815 }
00816 case 2: {
00817
00818 start_address = rn_val - (num_regs * 4);
00819 end_address = rn_val - 4;
00820 rn_val = start_address;
00821 break;
00822 }
00823 case 3: {
00824
00825 UNIMPLEMENTED();
00826 break;
00827 }
00828 default: {
00829 UNREACHABLE();
00830 break;
00831 }
00832 }
00833 if (instr->HasW()) {
00834 set_register(rn, rn_val);
00835 }
00836 intptr_t* address = reinterpret_cast<intptr_t*>(start_address);
00837 int reg = 0;
00838 while (rlist != 0) {
00839 if ((rlist & 1) != 0) {
00840 if (load) {
00841 set_register(reg, *address);
00842 } else {
00843 *address = get_register(reg);
00844 }
00845 address += 1;
00846 }
00847 reg++;
00848 rlist >>= 1;
00849 }
00850 ASSERT(end_address == ((intptr_t)address) - 4);
00851 }
00852
00853
00854
00855
00856
00857
00858
00859
00860 typedef int64_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1);
00861
00862
00863
00864
00865 void Simulator::SoftwareInterrupt(Instr* instr) {
00866 switch (instr->SwiField()) {
00867 case call_rt_r5: {
00868 SimulatorRuntimeCall target =
00869 reinterpret_cast<SimulatorRuntimeCall>(get_register(r5));
00870 intptr_t arg0 = get_register(r0);
00871 intptr_t arg1 = get_register(r1);
00872 int64_t result = target(arg0, arg1);
00873 int32_t lo_res = static_cast<int32_t>(result);
00874 int32_t hi_res = static_cast<int32_t>(result >> 32);
00875 set_register(r0, lo_res);
00876 set_register(r1, hi_res);
00877 set_pc(reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
00878 break;
00879 }
00880 case call_rt_r2: {
00881 SimulatorRuntimeCall target =
00882 reinterpret_cast<SimulatorRuntimeCall>(get_register(r2));
00883 intptr_t arg0 = get_register(r0);
00884 intptr_t arg1 = get_register(r1);
00885 int64_t result = target(arg0, arg1);
00886 int32_t lo_res = static_cast<int32_t>(result);
00887 int32_t hi_res = static_cast<int32_t>(result >> 32);
00888 set_register(r0, lo_res);
00889 set_register(r1, hi_res);
00890 set_pc(reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
00891 break;
00892 }
00893 case break_point: {
00894 Debugger dbg(this);
00895 dbg.Debug();
00896 break;
00897 }
00898 default: {
00899 UNREACHABLE();
00900 break;
00901 }
00902 }
00903 }
00904
00905
00906
00907
00908
00909
00910 void Simulator::DecodeType01(Instr* instr) {
00911 int type = instr->TypeField();
00912 if ((type == 0) && instr->IsSpecialType0()) {
00913
00914 if (instr->Bits(7, 4) == 9) {
00915 if (instr->Bit(24) == 0) {
00916
00917 int rd = instr->RdField();
00918 int rm = instr->RmField();
00919 int rs = instr->RsField();
00920 int32_t rs_val = get_register(rs);
00921 int32_t rm_val = get_register(rm);
00922 if (instr->Bit(23) == 0) {
00923 if (instr->Bit(21) == 0) {
00924
00925 int32_t alu_out = rm_val * rs_val;
00926 set_register(rd, alu_out);
00927 if (instr->HasS()) {
00928 SetNZFlags(alu_out);
00929 }
00930 } else {
00931 Format(instr, "mla'cond's 'rd, 'rm, 'rs, 'rn");
00932 }
00933 } else {
00934
00935 int rn = instr->RnField();
00936 int32_t hi_res = 0;
00937 int32_t lo_res = 0;
00938 if (instr->Bit(22) == 0) {
00939
00940 UNIMPLEMENTED();
00941 } else {
00942
00943 uint64_t left_op = rm_val;
00944 uint64_t right_op = rs_val;
00945 uint64_t result = left_op * right_op;
00946 hi_res = static_cast<int32_t>(result >> 32);
00947 lo_res = static_cast<int32_t>(result & 0xffffffff);
00948 }
00949 set_register(rn, hi_res);
00950 set_register(rd, lo_res);
00951 if (instr->HasS()) {
00952 UNIMPLEMENTED();
00953 }
00954 }
00955 } else {
00956 UNIMPLEMENTED();
00957 }
00958 } else {
00959
00960 int rd = instr->RdField();
00961 int rn = instr->RnField();
00962 int32_t rn_val = get_register(rn);
00963 int32_t addr = 0;
00964 if (instr->Bit(22) == 0) {
00965 int rm = instr->RmField();
00966 int32_t rm_val = get_register(rm);
00967 switch (instr->PUField()) {
00968 case 0: {
00969
00970 ASSERT(!instr->HasW());
00971 addr = rn_val;
00972 rn_val -= rm_val;
00973 set_register(rn, rn_val);
00974 break;
00975 }
00976 case 1: {
00977
00978 ASSERT(!instr->HasW());
00979 addr = rn_val;
00980 rn_val += rm_val;
00981 set_register(rn, rn_val);
00982 break;
00983 }
00984 case 2: {
00985
00986 rn_val -= rm_val;
00987 addr = rn_val;
00988 if (instr->HasW()) {
00989 set_register(rn, rn_val);
00990 }
00991 break;
00992 }
00993 case 3: {
00994
00995 rn_val += rm_val;
00996 addr = rn_val;
00997 if (instr->HasW()) {
00998 set_register(rn, rn_val);
00999 }
01000 break;
01001 }
01002 default: {
01003
01004 UNREACHABLE();
01005 break;
01006 }
01007 }
01008 } else {
01009 int32_t imm_val = (instr->ImmedHField() << 4) | instr->ImmedLField();
01010 switch (instr->PUField()) {
01011 case 0: {
01012
01013 ASSERT(!instr->HasW());
01014 addr = rn_val;
01015 rn_val -= imm_val;
01016 set_register(rn, rn_val);
01017 break;
01018 }
01019 case 1: {
01020
01021 ASSERT(!instr->HasW());
01022 addr = rn_val;
01023 rn_val += imm_val;
01024 set_register(rn, rn_val);
01025 break;
01026 }
01027 case 2: {
01028
01029 rn_val -= imm_val;
01030 addr = rn_val;
01031 if (instr->HasW()) {
01032 set_register(rn, rn_val);
01033 }
01034 break;
01035 }
01036 case 3: {
01037
01038 rn_val += imm_val;
01039 addr = rn_val;
01040 if (instr->HasW()) {
01041 set_register(rn, rn_val);
01042 }
01043 break;
01044 }
01045 default: {
01046
01047 UNREACHABLE();
01048 break;
01049 }
01050 }
01051 }
01052 if (instr->HasH()) {
01053 if (instr->HasSign()) {
01054 if (instr->HasL()) {
01055 int16_t val = ReadH(addr, instr);
01056 set_register(rd, val);
01057 } else {
01058 int16_t val = get_register(rd);
01059 WriteH(addr, val, instr);
01060 }
01061 } else {
01062 if (instr->HasL()) {
01063 uint16_t val = ReadHU(addr, instr);
01064 set_register(rd, val);
01065 } else {
01066 uint16_t val = get_register(rd);
01067 WriteH(addr, val, instr);
01068 }
01069 }
01070 } else {
01071
01072 ASSERT(instr->HasSign());
01073 ASSERT(instr->HasL());
01074 int8_t val = ReadB(addr);
01075 set_register(rd, val);
01076 }
01077 return;
01078 }
01079 } else {
01080 int rd = instr->RdField();
01081 int rn = instr->RnField();
01082 int32_t rn_val = get_register(rn);
01083 int32_t shifter_operand = 0;
01084 bool shifter_carry_out = 0;
01085 if (type == 0) {
01086 shifter_operand = GetShiftRm(instr, &shifter_carry_out);
01087 } else {
01088 ASSERT(instr->TypeField() == 1);
01089 shifter_operand = GetImm(instr, &shifter_carry_out);
01090 }
01091 int32_t alu_out;
01092
01093 switch (instr->OpcodeField()) {
01094 case AND: {
01095
01096
01097 alu_out = rn_val & shifter_operand;
01098 set_register(rd, alu_out);
01099 if (instr->HasS()) {
01100 SetNZFlags(alu_out);
01101 SetCFlag(shifter_carry_out);
01102 }
01103 break;
01104 }
01105
01106 case EOR: {
01107
01108
01109 alu_out = rn_val ^ shifter_operand;
01110 set_register(rd, alu_out);
01111 if (instr->HasS()) {
01112 SetNZFlags(alu_out);
01113 SetCFlag(shifter_carry_out);
01114 }
01115 break;
01116 }
01117
01118 case SUB: {
01119
01120
01121 alu_out = rn_val - shifter_operand;
01122 set_register(rd, alu_out);
01123 if (instr->HasS()) {
01124 SetNZFlags(alu_out);
01125 SetCFlag(!BorrowFrom(rn_val, shifter_operand));
01126 SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
01127 }
01128 break;
01129 }
01130
01131 case RSB: {
01132
01133
01134 alu_out = shifter_operand - rn_val;
01135 set_register(rd, alu_out);
01136 if (instr->HasS()) {
01137 SetNZFlags(alu_out);
01138 SetCFlag(!BorrowFrom(shifter_operand, rn_val));
01139 SetVFlag(OverflowFrom(alu_out, shifter_operand, rn_val, false));
01140 }
01141 break;
01142 }
01143
01144 case ADD: {
01145
01146
01147 alu_out = rn_val + shifter_operand;
01148 set_register(rd, alu_out);
01149 if (instr->HasS()) {
01150 SetNZFlags(alu_out);
01151 SetCFlag(CarryFrom(rn_val, shifter_operand));
01152 SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
01153 }
01154 break;
01155 }
01156
01157 case ADC: {
01158 Format(instr, "adc'cond's 'rd, 'rn, 'shift_rm");
01159 Format(instr, "adc'cond's 'rd, 'rn, 'imm");
01160 break;
01161 }
01162
01163 case SBC: {
01164 Format(instr, "sbc'cond's 'rd, 'rn, 'shift_rm");
01165 Format(instr, "sbc'cond's 'rd, 'rn, 'imm");
01166 break;
01167 }
01168
01169 case RSC: {
01170 Format(instr, "rsc'cond's 'rd, 'rn, 'shift_rm");
01171 Format(instr, "rsc'cond's 'rd, 'rn, 'imm");
01172 break;
01173 }
01174
01175 case TST: {
01176 if (instr->HasS()) {
01177
01178
01179 alu_out = rn_val & shifter_operand;
01180 SetNZFlags(alu_out);
01181 SetCFlag(shifter_carry_out);
01182 } else {
01183 UNIMPLEMENTED();
01184 }
01185 break;
01186 }
01187
01188 case TEQ: {
01189 if (instr->HasS()) {
01190
01191
01192 alu_out = rn_val ^ shifter_operand;
01193 SetNZFlags(alu_out);
01194 SetCFlag(shifter_carry_out);
01195 } else {
01196 UNIMPLEMENTED();
01197 }
01198 break;
01199 }
01200
01201 case CMP: {
01202 if (instr->HasS()) {
01203
01204
01205 alu_out = rn_val - shifter_operand;
01206 SetNZFlags(alu_out);
01207 SetCFlag(!BorrowFrom(rn_val, shifter_operand));
01208 SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
01209 } else {
01210 UNIMPLEMENTED();
01211 }
01212 break;
01213 }
01214
01215 case CMN: {
01216 if (instr->HasS()) {
01217 Format(instr, "cmn'cond 'rn, 'shift_rm");
01218 Format(instr, "cmn'cond 'rn, 'imm");
01219 } else {
01220 UNIMPLEMENTED();
01221 }
01222 break;
01223 }
01224
01225 case ORR: {
01226
01227
01228 alu_out = rn_val | shifter_operand;
01229 set_register(rd, alu_out);
01230 if (instr->HasS()) {
01231 SetNZFlags(alu_out);
01232 SetCFlag(shifter_carry_out);
01233 }
01234 break;
01235 }
01236
01237 case MOV: {
01238
01239
01240 alu_out = shifter_operand;
01241 set_register(rd, alu_out);
01242 if (instr->HasS()) {
01243 SetNZFlags(alu_out);
01244 SetCFlag(shifter_carry_out);
01245 }
01246 break;
01247 }
01248
01249 case BIC: {
01250
01251
01252 alu_out = rn_val & ~shifter_operand;
01253 set_register(rd, alu_out);
01254 if (instr->HasS()) {
01255 SetNZFlags(alu_out);
01256 SetCFlag(shifter_carry_out);
01257 }
01258 break;
01259 }
01260
01261 case MVN: {
01262
01263
01264 alu_out = ~shifter_operand;
01265 set_register(rd, alu_out);
01266 if (instr->HasS()) {
01267 SetNZFlags(alu_out);
01268 SetCFlag(shifter_carry_out);
01269 }
01270 break;
01271 }
01272
01273 default: {
01274 UNREACHABLE();
01275 break;
01276 }
01277 }
01278 }
01279 }
01280
01281
01282 void Simulator::DecodeType2(Instr* instr) {
01283 int rd = instr->RdField();
01284 int rn = instr->RnField();
01285 int32_t rn_val = get_register(rn);
01286 int32_t im_val = instr->Offset12Field();
01287 int32_t addr = 0;
01288 switch (instr->PUField()) {
01289 case 0: {
01290
01291 ASSERT(!instr->HasW());
01292 addr = rn_val;
01293 rn_val -= im_val;
01294 set_register(rn, rn_val);
01295 break;
01296 }
01297 case 1: {
01298
01299 ASSERT(!instr->HasW());
01300 addr = rn_val;
01301 rn_val += im_val;
01302 set_register(rn, rn_val);
01303 break;
01304 }
01305 case 2: {
01306
01307 rn_val -= im_val;
01308 addr = rn_val;
01309 if (instr->HasW()) {
01310 set_register(rn, rn_val);
01311 }
01312 break;
01313 }
01314 case 3: {
01315
01316 rn_val += im_val;
01317 addr = rn_val;
01318 if (instr->HasW()) {
01319 set_register(rn, rn_val);
01320 }
01321 break;
01322 }
01323 default: {
01324 UNREACHABLE();
01325 break;
01326 }
01327 }
01328 if (instr->HasB()) {
01329 if (instr->HasL()) {
01330 byte val = ReadBU(addr);
01331 set_register(rd, val);
01332 } else {
01333 byte val = get_register(rd);
01334 WriteB(addr, val);
01335 }
01336 } else {
01337 if (instr->HasL()) {
01338 set_register(rd, ReadW(addr, instr));
01339 } else {
01340 WriteW(addr, get_register(rd), instr);
01341 }
01342 }
01343 }
01344
01345
01346 void Simulator::DecodeType3(Instr* instr) {
01347 int rd = instr->RdField();
01348 int rn = instr->RnField();
01349 int32_t rn_val = get_register(rn);
01350 bool shifter_carry_out = 0;
01351 int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out);
01352 int32_t addr = 0;
01353 switch (instr->PUField()) {
01354 case 0: {
01355 ASSERT(!instr->HasW());
01356 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
01357 break;
01358 }
01359 case 1: {
01360 ASSERT(!instr->HasW());
01361 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
01362 break;
01363 }
01364 case 2: {
01365
01366 addr = rn_val - shifter_operand;
01367 if (instr->HasW()) {
01368 set_register(rn, addr);
01369 }
01370 break;
01371 }
01372 case 3: {
01373
01374 addr = rn_val + shifter_operand;
01375 if (instr->HasW()) {
01376 set_register(rn, addr);
01377 }
01378 break;
01379 }
01380 default: {
01381 UNREACHABLE();
01382 break;
01383 }
01384 }
01385 if (instr->HasB()) {
01386 UNIMPLEMENTED();
01387 } else {
01388 if (instr->HasL()) {
01389 set_register(rd, ReadW(addr, instr));
01390 } else {
01391 WriteW(addr, get_register(rd), instr);
01392 }
01393 }
01394 }
01395
01396
01397 void Simulator::DecodeType4(Instr* instr) {
01398 ASSERT(instr->Bit(22) == 0);
01399 if (instr->HasL()) {
01400
01401 HandleRList(instr, true);
01402 } else {
01403
01404 HandleRList(instr, false);
01405 }
01406 }
01407
01408
01409 void Simulator::DecodeType5(Instr* instr) {
01410
01411 int off = (instr->SImmed24Field() << 2) + 8;
01412 intptr_t pc = get_pc();
01413 if (instr->HasLink()) {
01414 set_register(lr, pc + Instr::kInstrSize);
01415 }
01416 set_pc(pc+off);
01417 }
01418
01419
01420 void Simulator::DecodeType6(Instr* instr) {
01421 UNIMPLEMENTED();
01422 }
01423
01424
01425 void Simulator::DecodeType7(Instr* instr) {
01426 if (instr->Bit(24) == 1) {
01427
01428 SoftwareInterrupt(instr);
01429 } else {
01430 UNIMPLEMENTED();
01431 }
01432 }
01433
01434
01435
01436 void Simulator::InstructionDecode(Instr* instr) {
01437 pc_modified_ = false;
01438 if (instr->ConditionField() == special_condition) {
01439 Debugger dbg(this);
01440 dbg.Stop(instr);
01441 return;
01442 }
01443 if (::v8::internal::FLAG_trace_sim) {
01444 disasm::Disassembler dasm;
01445
01446 v8::internal::EmbeddedVector<char, 256> buffer;
01447 dasm.InstructionDecode(buffer,
01448 reinterpret_cast<byte*>(instr));
01449 PrintF(" 0x%x %s\n", instr, buffer.start());
01450 }
01451 if (ConditionallyExecute(instr)) {
01452 switch (instr->TypeField()) {
01453 case 0:
01454 case 1: {
01455 DecodeType01(instr);
01456 break;
01457 }
01458 case 2: {
01459 DecodeType2(instr);
01460 break;
01461 }
01462 case 3: {
01463 DecodeType3(instr);
01464 break;
01465 }
01466 case 4: {
01467 DecodeType4(instr);
01468 break;
01469 }
01470 case 5: {
01471 DecodeType5(instr);
01472 break;
01473 }
01474 case 6: {
01475 DecodeType6(instr);
01476 break;
01477 }
01478 case 7: {
01479 DecodeType7(instr);
01480 break;
01481 }
01482 default: {
01483 UNIMPLEMENTED();
01484 break;
01485 }
01486 }
01487 }
01488 if (!pc_modified_) {
01489 set_register(pc, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
01490 }
01491 }
01492
01493
01494
01495 void Simulator::execute() {
01496
01497
01498 int program_counter = get_pc();
01499
01500 if (::v8::internal::FLAG_stop_sim_at == 0) {
01501
01502
01503 while (program_counter != end_sim_pc) {
01504 Instr* instr = reinterpret_cast<Instr*>(program_counter);
01505 icount_++;
01506 InstructionDecode(instr);
01507 program_counter = get_pc();
01508 }
01509 } else {
01510
01511
01512 while (program_counter != end_sim_pc) {
01513 Instr* instr = reinterpret_cast<Instr*>(program_counter);
01514 icount_++;
01515 if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
01516 Debugger dbg(this);
01517 dbg.Debug();
01518 } else {
01519 InstructionDecode(instr);
01520 }
01521 program_counter = get_pc();
01522 }
01523 }
01524 }
01525
01526
01527 Object* Simulator::call(int32_t entry, int32_t p0, int32_t p1, int32_t p2,
01528 int32_t p3, int32_t p4) {
01529
01530 set_register(r0, p0);
01531 set_register(r1, p1);
01532 set_register(r2, p2);
01533 set_register(r3, p3);
01534 intptr_t* stack_pointer = reinterpret_cast<intptr_t*>(get_register(sp));
01535 *(--stack_pointer) = p4;
01536 set_register(sp, reinterpret_cast<int32_t>(stack_pointer));
01537
01538
01539 set_register(pc, entry);
01540
01541
01542
01543 set_register(lr, end_sim_pc);
01544
01545
01546
01547
01548 int32_t r4_val = get_register(r4);
01549 int32_t r5_val = get_register(r5);
01550 int32_t r6_val = get_register(r6);
01551 int32_t r7_val = get_register(r7);
01552 int32_t r8_val = get_register(r8);
01553 int32_t r9_val = get_register(r9);
01554 int32_t r10_val = get_register(r10);
01555 int32_t r11_val = get_register(r11);
01556
01557
01558
01559 int32_t callee_saved_value = icount_;
01560 set_register(r4, callee_saved_value);
01561 set_register(r5, callee_saved_value);
01562 set_register(r6, callee_saved_value);
01563 set_register(r7, callee_saved_value);
01564 set_register(r8, callee_saved_value);
01565 set_register(r9, callee_saved_value);
01566 set_register(r10, callee_saved_value);
01567 set_register(r11, callee_saved_value);
01568
01569
01570 execute();
01571
01572
01573 CHECK_EQ(get_register(r4), callee_saved_value);
01574 CHECK_EQ(get_register(r5), callee_saved_value);
01575 CHECK_EQ(get_register(r6), callee_saved_value);
01576 CHECK_EQ(get_register(r7), callee_saved_value);
01577 CHECK_EQ(get_register(r8), callee_saved_value);
01578 CHECK_EQ(get_register(r9), callee_saved_value);
01579 CHECK_EQ(get_register(r10), callee_saved_value);
01580 CHECK_EQ(get_register(r11), callee_saved_value);
01581
01582
01583 set_register(r4, r4_val);
01584 set_register(r5, r5_val);
01585 set_register(r6, r6_val);
01586 set_register(r7, r7_val);
01587 set_register(r8, r8_val);
01588 set_register(r9, r9_val);
01589 set_register(r10, r10_val);
01590 set_register(r11, r11_val);
01591
01592 int result = get_register(r0);
01593 return reinterpret_cast<Object*>(result);
01594 }
01595
01596 } }
01597
01598 #endif // !defined(__arm__)