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

📄 simulator-arm.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
  uint32_t uright = static_cast<uint32_t>(right);  return (uright > uleft);}// Calculate V flag value for additions and subtractions.bool Simulator::OverflowFrom(int32_t alu_out,                             int32_t left, int32_t right, bool addition) {  bool overflow;  if (addition) {               // operands have the same sign    overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))               // and operands and result have different sign               && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));  } else {               // operands have different signs    overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))               // and first operand and result have different signs               && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));  }  return overflow;}// Addressing Mode 1 - Data-processing operands:// Get the value based on the shifter_operand with register.int32_t Simulator::GetShiftRm(Instr* instr, bool* carry_out) {  Shift shift = instr->ShiftField();  int shift_amount = instr->ShiftAmountField();  int32_t result = get_register(instr->RmField());  if (instr->Bit(4) == 0) {    // by immediate    if ((shift == ROR) && (shift_amount == 0)) {      UNIMPLEMENTED();      return result;    } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {      shift_amount = 32;    }    switch (shift) {      case ASR: {        if (shift_amount == 0) {          if (result < 0) {            result = 0xffffffff;            *carry_out = true;          } else {            result = 0;            *carry_out = false;          }        } else {          result >>= (shift_amount - 1);          *carry_out = (result & 1) == 1;          result >>= 1;        }        break;      }      case LSL: {        if (shift_amount == 0) {          *carry_out = c_flag_;        } else {          result <<= (shift_amount - 1);          *carry_out = (result < 0);          result <<= 1;        }        break;      }      case LSR: {        if (shift_amount == 0) {          result = 0;          *carry_out = c_flag_;        } else {          uint32_t uresult = static_cast<uint32_t>(result);          uresult >>= (shift_amount - 1);          *carry_out = (uresult & 1) == 1;          uresult >>= 1;          result = static_cast<int32_t>(uresult);        }        break;      }      case ROR: {        UNIMPLEMENTED();        break;      }      default: {        UNREACHABLE();        break;      }    }  } else {    // by register    int rs = instr->RsField();    shift_amount = get_register(rs) &0xff;    switch (shift) {      case ASR: {        if (shift_amount == 0) {          *carry_out = c_flag_;        } else if (shift_amount < 32) {          result >>= (shift_amount - 1);          *carry_out = (result & 1) == 1;          result >>= 1;        } else {          ASSERT(shift_amount >= 32);          if (result < 0) {            *carry_out = true;            result = 0xffffffff;          } else {            *carry_out = false;            result = 0;          }        }        break;      }      case LSL: {        if (shift_amount == 0) {          *carry_out = c_flag_;        } else if (shift_amount < 32) {          result <<= (shift_amount - 1);          *carry_out = (result < 0);          result <<= 1;        } else if (shift_amount == 32) {          *carry_out = (result & 1) == 1;          result = 0;        } else {          ASSERT(shift_amount > 32);          *carry_out = false;          result = 0;        }        break;      }      case LSR: {        if (shift_amount == 0) {          *carry_out = c_flag_;        } else if (shift_amount < 32) {          uint32_t uresult = static_cast<uint32_t>(result);          uresult >>= (shift_amount - 1);          *carry_out = (uresult & 1) == 1;          uresult >>= 1;          result = static_cast<int32_t>(uresult);        } else if (shift_amount == 32) {          *carry_out = (result < 0);          result = 0;        } else {          *carry_out = false;          result = 0;        }        break;      }      case ROR: {        UNIMPLEMENTED();        break;      }      default: {        UNREACHABLE();        break;      }    }  }  return result;}// Addressing Mode 1 - Data-processing operands:// Get the value based on the shifter_operand with immediate.int32_t Simulator::GetImm(Instr* instr, bool* carry_out) {  int rotate = instr->RotateField() * 2;  int immed8 = instr->Immed8Field();  int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));  *carry_out = (rotate == 0) ? c_flag_ : (imm < 0);  return imm;}static int count_bits(int bit_vector) {  int count = 0;  while (bit_vector != 0) {    if ((bit_vector & 1) != 0) {      count++;    }    bit_vector >>= 1;  }  return count;}// Addressing Mode 4 - Load and Store Multiplevoid Simulator::HandleRList(Instr* instr, bool load) {  int rn = instr->RnField();  int32_t rn_val = get_register(rn);  int rlist = instr->RlistField();  int num_regs = count_bits(rlist);  intptr_t start_address = 0;  intptr_t end_address = 0;  switch (instr->PUField()) {    case 0: {      // Print("da");      UNIMPLEMENTED();      break;    }    case 1: {      // Print("ia");      start_address = rn_val;      end_address = rn_val + (num_regs * 4) - 4;      rn_val = rn_val + (num_regs * 4);      break;    }    case 2: {      // Print("db");      start_address = rn_val - (num_regs * 4);      end_address = rn_val - 4;      rn_val = start_address;      break;    }    case 3: {      // Print("ib");      UNIMPLEMENTED();      break;    }    default: {      UNREACHABLE();      break;    }  }  if (instr->HasW()) {    set_register(rn, rn_val);  }  intptr_t* address = reinterpret_cast<intptr_t*>(start_address);  int reg = 0;  while (rlist != 0) {    if ((rlist & 1) != 0) {      if (load) {        set_register(reg, *address);      } else {        *address = get_register(reg);      }      address += 1;    }    reg++;    rlist >>= 1;  }  ASSERT(end_address == ((intptr_t)address) - 4);}// Calls into the V8 runtime are based on this very simple interface.// Note: To be able to return two values from some calls the code in runtime.cc// uses the ObjectPair which is essentially two 32-bit values stuffed into a// 64-bit value. With the code below we assume that all runtime calls return// 64 bits of result. If they don't, the r1 result register contains a bogus// value, which is fine because it is caller-saved.typedef int64_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1);// Software interrupt instructions are used by the simulator to call into the// C-based V8 runtime.void Simulator::SoftwareInterrupt(Instr* instr) {  switch (instr->SwiField()) {    case call_rt_r5: {      SimulatorRuntimeCall target =          reinterpret_cast<SimulatorRuntimeCall>(get_register(r5));      intptr_t arg0 = get_register(r0);      intptr_t arg1 = get_register(r1);      int64_t result = target(arg0, arg1);      int32_t lo_res = static_cast<int32_t>(result);      int32_t hi_res = static_cast<int32_t>(result >> 32);      set_register(r0, lo_res);      set_register(r1, hi_res);      set_pc(reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);      break;    }    case call_rt_r2: {      SimulatorRuntimeCall target =          reinterpret_cast<SimulatorRuntimeCall>(get_register(r2));      intptr_t arg0 = get_register(r0);      intptr_t arg1 = get_register(r1);      int64_t result = target(arg0, arg1);      int32_t lo_res = static_cast<int32_t>(result);      int32_t hi_res = static_cast<int32_t>(result >> 32);      set_register(r0, lo_res);      set_register(r1, hi_res);      set_pc(reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);      break;    }    case break_point: {      Debugger dbg(this);      dbg.Debug();      break;    }    default: {      UNREACHABLE();      break;    }  }}// Handle execution based on instruction types.// Instruction types 0 and 1 are both rolled into one function because they// only differ in the handling of the shifter_operand.void Simulator::DecodeType01(Instr* instr) {  int type = instr->TypeField();  if ((type == 0) && instr->IsSpecialType0()) {    // multiply instruction or extra loads and stores    if (instr->Bits(7, 4) == 9) {      if (instr->Bit(24) == 0) {        // multiply instructions        int rd = instr->RdField();        int rm = instr->RmField();        int rs = instr->RsField();        int32_t rs_val = get_register(rs);        int32_t rm_val = get_register(rm);        if (instr->Bit(23) == 0) {          if (instr->Bit(21) == 0) {            // Format(instr, "mul'cond's 'rd, 'rm, 'rs");            int32_t alu_out = rm_val * rs_val;            set_register(rd, alu_out);            if (instr->HasS()) {              SetNZFlags(alu_out);            }          } else {            Format(instr, "mla'cond's 'rd, 'rm, 'rs, 'rn");          }        } else {          // Format(instr, "'um'al'cond's 'rn, 'rd, 'rs, 'rm");          int rn = instr->RnField();          int32_t hi_res = 0;          int32_t lo_res = 0;          if (instr->Bit(22) == 0) {            // signed multiply            UNIMPLEMENTED();          } else {            // unsigned multiply            uint64_t left_op  = rm_val;            uint64_t right_op = rs_val;            uint64_t result = left_op * right_op;            hi_res = static_cast<int32_t>(result >> 32);            lo_res = static_cast<int32_t>(result & 0xffffffff);          }          set_register(rn, hi_res);          set_register(rd, lo_res);          if (instr->HasS()) {            UNIMPLEMENTED();          }        }      } else {        UNIMPLEMENTED();  // not used by V8      }    } else {      // extra load/store instructions      int rd = instr->RdField();      int rn = instr->RnField();      int32_t rn_val = get_register(rn);      int32_t addr = 0;      if (instr->Bit(22) == 0) {        int rm = instr->RmField();        int32_t rm_val = get_register(rm);        switch (instr->PUField()) {          case 0: {            // Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm");            ASSERT(!instr->HasW());            addr = rn_val;            rn_val -= rm_val;            set_register(rn, rn_val);            break;          }          case 1: {            // Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm");            ASSERT(!instr->HasW());            addr = rn_val;            rn_val += rm_val;            set_register(rn, rn_val);            break;          }          case 2: {            // Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w");            rn_val -= rm_val;            addr = rn_val;            if (instr->HasW()) {              set_register(rn, rn_val);            }            break;          }          case 3: {            // Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w");            rn_val += rm_val;            addr = rn_val;            if (instr->HasW()) {              set_register(rn, rn_val);            }            break;          }          default: {            // The PU field is a 2-bit field.            UNREACHABLE();            break;          }        }      } else {        int32_t imm_val = (instr->ImmedHField() << 4) | instr->ImmedLField();        switch (instr->PUField()) {          case 0: {            // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8");            ASSERT(!instr->HasW());            addr = rn_val;            rn_val -= imm_val;            set_register(rn, rn_val);            break;          }          case 1: {            // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8");            ASSERT(!instr->HasW());            addr = rn_val;            rn_val += imm_val;            set_register(rn, rn_val);            break;          }          case 2: {            // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w");            rn_val -= imm_val;            addr = rn_val;            if (instr->HasW()) {              set_register(rn, rn_val);            }            break;          }          case 3: {            // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w");            rn_val += imm_val;            addr = rn_val;            if (instr->HasW()) {              set_register(rn, rn_val);            }            break;          }          default: {            // The PU field is a 2-bit field.            UNREACHABLE();            break;          }        }      }      if (instr->HasH()) {        if (instr->HasSign()) {          int16_t* haddr = reinterpret_cast<int16_t*>(addr);          if (instr->HasL()) {            int16_t val = *haddr;            set_register(rd, val);          } else {            int16_t val = get_register(rd);            *haddr = val;          }        } else {          uint16_t* haddr = reinterpret_cast<uint16_t*>(addr);          if (instr->HasL()) {            uint16_t val = *haddr;            set_register(rd, val);          } else {            uint16_t val = get_register(rd);            *haddr = val;          }        }      } else {        // signed byte loads        ASSERT(instr->HasSign());        ASSERT(instr->HasL());        int8_t* baddr = reinterpret_cast<int8_t*>(addr);        int8_t val = *baddr;        set_register(rd, val);      }      return;    }  } else {    int rd = instr->RdField();    int rn = instr->RnField();    int32_t rn_val = get_register(rn);    int32_t shifter_operand = 0;    bool shifter_carry_out = 0;    if (type == 0) {      shifter_operand = GetShiftRm(instr, &shifter_carry_out);    } else {      ASSERT(instr->TypeField() == 1);      shifter_operand = GetImm(instr, &shifter_carry_out);    }    int32_t alu_out;    switch (instr->OpcodeField()) {      case AND: {        // Format(instr, "and'cond's 'rd, 'rn, 'shift_rm");        // Format(instr, "and'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);

⌨️ 快捷键说明

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