⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simulator-arm.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
        }        break;      }      case EOR: {        // Format(instr, "eor'cond's 'rd, 'rn, 'shift_rm");        // Format(instr, "eor'cond's 'rd, 'rn, 'imm");        alu_out = rn_val ^ shifter_operand;        set_register(rd, alu_out);        if (instr->HasS()) {          SetNZFlags(alu_out);          SetCFlag(shifter_carry_out);        }        break;      }      case SUB: {        // Format(instr, "sub'cond's 'rd, 'rn, 'shift_rm");        // Format(instr, "sub'cond's 'rd, 'rn, 'imm");        alu_out = rn_val - shifter_operand;        set_register(rd, alu_out);        if (instr->HasS()) {          SetNZFlags(alu_out);          SetCFlag(!BorrowFrom(rn_val, shifter_operand));          SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));        }        break;      }      case RSB: {        // Format(instr, "rsb'cond's 'rd, 'rn, 'shift_rm");        // Format(instr, "rsb'cond's 'rd, 'rn, 'imm");        alu_out = shifter_operand - rn_val;        set_register(rd, alu_out);        if (instr->HasS()) {          SetNZFlags(alu_out);          SetCFlag(!BorrowFrom(shifter_operand, rn_val));          SetVFlag(OverflowFrom(alu_out, shifter_operand, rn_val, false));        }        break;      }      case ADD: {        // Format(instr, "add'cond's 'rd, 'rn, 'shift_rm");        // Format(instr, "add'cond's 'rd, 'rn, 'imm");        alu_out = rn_val + shifter_operand;        set_register(rd, alu_out);        if (instr->HasS()) {          SetNZFlags(alu_out);          SetCFlag(CarryFrom(rn_val, shifter_operand));          SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));        }        break;      }      case ADC: {        Format(instr, "adc'cond's 'rd, 'rn, 'shift_rm");        Format(instr, "adc'cond's 'rd, 'rn, 'imm");        break;      }      case SBC: {        Format(instr, "sbc'cond's 'rd, 'rn, 'shift_rm");        Format(instr, "sbc'cond's 'rd, 'rn, 'imm");        break;      }      case RSC: {        Format(instr, "rsc'cond's 'rd, 'rn, 'shift_rm");        Format(instr, "rsc'cond's 'rd, 'rn, 'imm");        break;      }      case TST: {        if (instr->HasS()) {          // Format(instr, "tst'cond 'rn, 'shift_rm");          // Format(instr, "tst'cond 'rn, 'imm");          alu_out = rn_val & shifter_operand;          SetNZFlags(alu_out);          SetCFlag(shifter_carry_out);        } else {          UNIMPLEMENTED();        }        break;      }      case TEQ: {        if (instr->HasS()) {          // Format(instr, "teq'cond 'rn, 'shift_rm");          // Format(instr, "teq'cond 'rn, 'imm");          alu_out = rn_val ^ shifter_operand;          SetNZFlags(alu_out);          SetCFlag(shifter_carry_out);        } else {          UNIMPLEMENTED();        }        break;      }      case CMP: {        if (instr->HasS()) {          // Format(instr, "cmp'cond 'rn, 'shift_rm");          // Format(instr, "cmp'cond 'rn, 'imm");          alu_out = rn_val - shifter_operand;          SetNZFlags(alu_out);          SetCFlag(!BorrowFrom(rn_val, shifter_operand));          SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));        } else {          UNIMPLEMENTED();        }        break;      }      case CMN: {        if (instr->HasS()) {          Format(instr, "cmn'cond 'rn, 'shift_rm");          Format(instr, "cmn'cond 'rn, 'imm");        } else {          UNIMPLEMENTED();        }        break;      }      case ORR: {        // Format(instr, "orr'cond's 'rd, 'rn, 'shift_rm");        // Format(instr, "orr'cond's 'rd, 'rn, 'imm");        alu_out = rn_val | shifter_operand;        set_register(rd, alu_out);        if (instr->HasS()) {          SetNZFlags(alu_out);          SetCFlag(shifter_carry_out);        }        break;      }      case MOV: {        // Format(instr, "mov'cond's 'rd, 'shift_rm");        // Format(instr, "mov'cond's 'rd, 'imm");        alu_out = shifter_operand;        set_register(rd, alu_out);        if (instr->HasS()) {          SetNZFlags(alu_out);          SetCFlag(shifter_carry_out);        }        break;      }      case BIC: {        // Format(instr, "bic'cond's 'rd, 'rn, 'shift_rm");        // Format(instr, "bic'cond's 'rd, 'rn, 'imm");        alu_out = rn_val & ~shifter_operand;        set_register(rd, alu_out);        if (instr->HasS()) {          SetNZFlags(alu_out);          SetCFlag(shifter_carry_out);        }        break;      }      case MVN: {        // Format(instr, "mvn'cond's 'rd, 'shift_rm");        // Format(instr, "mvn'cond's 'rd, 'imm");        alu_out = ~shifter_operand;        set_register(rd, alu_out);        if (instr->HasS()) {          SetNZFlags(alu_out);          SetCFlag(shifter_carry_out);        }        break;      }      default: {        UNREACHABLE();        break;      }    }  }}void Simulator::DecodeType2(Instr* instr) {  int rd = instr->RdField();  int rn = instr->RnField();  int32_t rn_val = get_register(rn);  int32_t im_val = instr->Offset12Field();  int32_t addr = 0;  switch (instr->PUField()) {    case 0: {      // Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");      ASSERT(!instr->HasW());      addr = rn_val;      rn_val -= im_val;      set_register(rn, rn_val);      break;    }    case 1: {      // Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");      ASSERT(!instr->HasW());      addr = rn_val;      rn_val += im_val;      set_register(rn, rn_val);      break;    }    case 2: {      // Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w");      rn_val -= im_val;      addr = rn_val;      if (instr->HasW()) {        set_register(rn, rn_val);      }      break;    }    case 3: {      // Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w");      rn_val += im_val;      addr = rn_val;      if (instr->HasW()) {        set_register(rn, rn_val);      }      break;    }    default: {      UNREACHABLE();      break;    }  }  if (instr->HasB()) {    byte* baddr = reinterpret_cast<byte*>(addr);    if (instr->HasL()) {      byte val = *baddr;      set_register(rd, val);    } else {      byte val = get_register(rd);      *baddr = val;    }  } else {    intptr_t* iaddr = reinterpret_cast<intptr_t*>(addr);    if (instr->HasL()) {      set_register(rd, *iaddr);    } else {      *iaddr = get_register(rd);    }  }}void Simulator::DecodeType3(Instr* instr) {  int rd = instr->RdField();  int rn = instr->RnField();  int32_t rn_val = get_register(rn);  bool shifter_carry_out = 0;  int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out);  int32_t addr = 0;  switch (instr->PUField()) {    case 0: {      ASSERT(!instr->HasW());      Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");      break;    }    case 1: {      ASSERT(!instr->HasW());      Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");      break;    }    case 2: {      // Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");      addr = rn_val - shifter_operand;      if (instr->HasW()) {        set_register(rn, addr);      }      break;    }    case 3: {      // Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w");      addr = rn_val + shifter_operand;      if (instr->HasW()) {        set_register(rn, addr);      }      break;    }    default: {      UNREACHABLE();      break;    }  }  if (instr->HasB()) {    UNIMPLEMENTED();  } else {    intptr_t* iaddr = reinterpret_cast<intptr_t*>(addr);    if (instr->HasL()) {      set_register(rd, *iaddr);    } else {      *iaddr = get_register(rd);    }  }}void Simulator::DecodeType4(Instr* instr) {  ASSERT(instr->Bit(22) == 0);  // only allowed to be set in privileged mode  if (instr->HasL()) {    // Format(instr, "ldm'cond'pu 'rn'w, 'rlist");    HandleRList(instr, true);  } else {    // Format(instr, "stm'cond'pu 'rn'w, 'rlist");    HandleRList(instr, false);  }}void Simulator::DecodeType5(Instr* instr) {  // Format(instr, "b'l'cond 'target");  int off = (instr->SImmed24Field() << 2) + 8;  intptr_t pc = get_pc();  if (instr->HasLink()) {    set_register(lr, pc + Instr::kInstrSize);  }  set_pc(pc+off);}void Simulator::DecodeType6(Instr* instr) {  UNIMPLEMENTED();}void Simulator::DecodeType7(Instr* instr) {  if (instr->Bit(24) == 1) {    // Format(instr, "swi 'swi");    SoftwareInterrupt(instr);  } else {    UNIMPLEMENTED();  }}// Executes the current instruction.void Simulator::InstructionDecode(Instr* instr) {  pc_modified_ = false;  if (instr->ConditionField() == special_condition) {    Debugger dbg(this);    dbg.Stop(instr);    return;  }  if (::v8::internal::FLAG_trace_sim) {    disasm::Disassembler dasm;    // use a reasonably large buffer    v8::internal::EmbeddedVector<char, 256> buffer;    dasm.InstructionDecode(buffer,                           reinterpret_cast<byte*>(instr));    PrintF("  0x%x  %s\n", instr, buffer.start());  }  if (ConditionallyExecute(instr)) {    switch (instr->TypeField()) {      case 0:      case 1: {        DecodeType01(instr);        break;      }      case 2: {        DecodeType2(instr);        break;      }      case 3: {        DecodeType3(instr);        break;      }      case 4: {        DecodeType4(instr);        break;      }      case 5: {        DecodeType5(instr);        break;      }      case 6: {        DecodeType6(instr);        break;      }      case 7: {        DecodeType7(instr);        break;      }      default: {        UNIMPLEMENTED();        break;      }    }  }  if (!pc_modified_) {    set_register(pc, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);  }}//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.  int program_counter = get_pc();  if (::v8::internal::FLAG_stop_sim_at == 0) {    // Fast version of the dispatch loop without checking whether the simulator    // should be stopping at a particular executed instruction.    while (program_counter != end_sim_pc) {      Instr* instr = reinterpret_cast<Instr*>(program_counter);      icount_++;      InstructionDecode(instr);      program_counter = get_pc();    }  } else {    // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when    // we reach the particular instuction count.    while (program_counter != end_sim_pc) {      Instr* instr = reinterpret_cast<Instr*>(program_counter);      icount_++;      if (icount_ == ::v8::internal::FLAG_stop_sim_at) {        Debugger dbg(this);        dbg.Debug();      } else {        InstructionDecode(instr);      }      program_counter = get_pc();    }  }}Object* Simulator::call(int32_t entry, int32_t p0, int32_t p1, int32_t p2,                           int32_t p3, int32_t p4) {  // Setup parameters  set_register(r0, p0);  set_register(r1, p1);  set_register(r2, p2);  set_register(r3, p3);  intptr_t* stack_pointer = reinterpret_cast<intptr_t*>(get_register(sp));  *(--stack_pointer) = p4;  set_register(sp, reinterpret_cast<int32_t>(stack_pointer));  // Prepare to execute the code at entry  set_register(pc, entry);  // Put down marker for end of simulation. The simulator will stop simulation  // when the PC reaches this value. By saving the "end simulation" value into  // the LR the simulation stops when returning to this call point.  set_register(lr, end_sim_pc);  // Remember the values of callee-saved registers.  // The code below assumes that r9 is not used as sb (static base) in  // simulator code and therefore is regarded as a callee-saved register.  int32_t r4_val = get_register(r4);  int32_t r5_val = get_register(r5);  int32_t r6_val = get_register(r6);  int32_t r7_val = get_register(r7);  int32_t r8_val = get_register(r8);  int32_t r9_val = get_register(r9);  int32_t r10_val = get_register(r10);  int32_t r11_val = get_register(r11);  // Setup the callee-saved registers with a known value. To be able to check  // that they are preserved properly across JS execution.  int32_t callee_saved_value = icount_;  set_register(r4, callee_saved_value);  set_register(r5, callee_saved_value);  set_register(r6, callee_saved_value);  set_register(r7, callee_saved_value);  set_register(r8, callee_saved_value);  set_register(r9, callee_saved_value);  set_register(r10, callee_saved_value);  set_register(r11, callee_saved_value);  // Start the simulation  execute();  // Check that the callee-saved registers have been preserved.  CHECK_EQ(get_register(r4), callee_saved_value);  CHECK_EQ(get_register(r5), callee_saved_value);  CHECK_EQ(get_register(r6), callee_saved_value);  CHECK_EQ(get_register(r7), callee_saved_value);  CHECK_EQ(get_register(r8), callee_saved_value);  CHECK_EQ(get_register(r9), callee_saved_value);  CHECK_EQ(get_register(r10), callee_saved_value);  CHECK_EQ(get_register(r11), callee_saved_value);  // Restore callee-saved registers with the original value.  set_register(r4, r4_val);  set_register(r5, r5_val);  set_register(r6, r6_val);  set_register(r7, r7_val);  set_register(r8, r8_val);  set_register(r9, r9_val);  set_register(r10, r10_val);  set_register(r11, r11_val);  int result = get_register(r0);  return reinterpret_cast<Object*>(result);}} }  // namespace assembler::arm#endif  // !defined(__arm__)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -