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

📄 assembler-arm.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
void Assembler::swi(uint32_t imm24, Condition cond) {  ASSERT(is_uint24(imm24));  emit(cond | 15*B24 | imm24);}// Coprocessor instructionsvoid Assembler::cdp(Coprocessor coproc,                    int opcode_1,                    CRegister crd,                    CRegister crn,                    CRegister crm,                    int opcode_2,                    Condition cond) {  ASSERT(is_uint4(opcode_1) && is_uint3(opcode_2));  emit(cond | B27 | B26 | B25 | (opcode_1 & 15)*B20 | crn.code()*B16 |       crd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | crm.code());}void Assembler::cdp2(Coprocessor coproc,                     int opcode_1,                     CRegister crd,                     CRegister crn,                     CRegister crm,                     int opcode_2) {  // v5 and above  cdp(coproc, opcode_1, crd, crn, crm, opcode_2, static_cast<Condition>(nv));}void Assembler::mcr(Coprocessor coproc,                    int opcode_1,                    Register rd,                    CRegister crn,                    CRegister crm,                    int opcode_2,                    Condition cond) {  ASSERT(is_uint3(opcode_1) && is_uint3(opcode_2));  emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | crn.code()*B16 |       rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());}void Assembler::mcr2(Coprocessor coproc,                     int opcode_1,                     Register rd,                     CRegister crn,                     CRegister crm,                     int opcode_2) {  // v5 and above  mcr(coproc, opcode_1, rd, crn, crm, opcode_2, static_cast<Condition>(nv));}void Assembler::mrc(Coprocessor coproc,                    int opcode_1,                    Register rd,                    CRegister crn,                    CRegister crm,                    int opcode_2,                    Condition cond) {  ASSERT(is_uint3(opcode_1) && is_uint3(opcode_2));  emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | L | crn.code()*B16 |       rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code());}void Assembler::mrc2(Coprocessor coproc,                     int opcode_1,                     Register rd,                     CRegister crn,                     CRegister crm,                     int opcode_2) {  // v5 and above  mrc(coproc, opcode_1, rd, crn, crm, opcode_2, static_cast<Condition>(nv));}void Assembler::ldc(Coprocessor coproc,                    CRegister crd,                    const MemOperand& src,                    LFlag l,                    Condition cond) {  addrmod5(cond | B27 | B26 | l | L | coproc*B8, crd, src);}void Assembler::ldc(Coprocessor coproc,                    CRegister crd,                    Register rn,                    int option,                    LFlag l,                    Condition cond) {  // unindexed addressing  ASSERT(is_uint8(option));  emit(cond | B27 | B26 | U | l | L | rn.code()*B16 | crd.code()*B12 |       coproc*B8 | (option & 255));}void Assembler::ldc2(Coprocessor coproc,                     CRegister crd,                     const MemOperand& src,                     LFlag l) {  // v5 and above  ldc(coproc, crd, src, l, static_cast<Condition>(nv));}void Assembler::ldc2(Coprocessor coproc,                     CRegister crd,                     Register rn,                     int option,                     LFlag l) {  // v5 and above  ldc(coproc, crd, rn, option, l, static_cast<Condition>(nv));}void Assembler::stc(Coprocessor coproc,                    CRegister crd,                    const MemOperand& dst,                    LFlag l,                    Condition cond) {  addrmod5(cond | B27 | B26 | l | coproc*B8, crd, dst);}void Assembler::stc(Coprocessor coproc,                    CRegister crd,                    Register rn,                    int option,                    LFlag l,                    Condition cond) {  // unindexed addressing  ASSERT(is_uint8(option));  emit(cond | B27 | B26 | U | l | rn.code()*B16 | crd.code()*B12 |       coproc*B8 | (option & 255));}void Assembler::stc2(Coprocessor                     coproc, CRegister crd,                     const MemOperand& dst,                     LFlag l) {  // v5 and above  stc(coproc, crd, dst, l, static_cast<Condition>(nv));}void Assembler::stc2(Coprocessor coproc,                     CRegister crd,                     Register rn,                     int option,                     LFlag l) {  // v5 and above  stc(coproc, crd, rn, option, l, static_cast<Condition>(nv));}// Pseudo instructionsvoid Assembler::lea(Register dst,                    const MemOperand& x,                    SBit s,                    Condition cond) {  int am = x.am_;  if (!x.rm_.is_valid()) {    // immediate offset    if ((am & P) == 0)  // post indexing      mov(dst, Operand(x.rn_), s, cond);    else if ((am & U) == 0)  // negative indexing      sub(dst, x.rn_, Operand(x.offset_), s, cond);    else      add(dst, x.rn_, Operand(x.offset_), s, cond);  } else {    // Register offset (shift_imm_ and shift_op_ are 0) or scaled    // register offset the constructors make sure than both shift_imm_    // and shift_op_ are initialized.    ASSERT(!x.rm_.is(pc));    if ((am & P) == 0)  // post indexing      mov(dst, Operand(x.rn_), s, cond);    else if ((am & U) == 0)  // negative indexing      sub(dst, x.rn_, Operand(x.rm_, x.shift_op_, x.shift_imm_), s, cond);    else      add(dst, x.rn_, Operand(x.rm_, x.shift_op_, x.shift_imm_), s, cond);  }}// Debuggingvoid Assembler::RecordComment(const char* msg) {  if (FLAG_debug_code) {    CheckBuffer();    RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));  }}void Assembler::RecordPosition(int pos) {  if (pos == RelocInfo::kNoPosition) return;  ASSERT(pos >= 0);  if (pos == last_position_) return;  CheckBuffer();  RecordRelocInfo(RelocInfo::POSITION, pos);  last_position_ = pos;  last_position_is_statement_ = false;}void Assembler::RecordStatementPosition(int pos) {  if (pos == last_position_) return;  CheckBuffer();  RecordRelocInfo(RelocInfo::STATEMENT_POSITION, pos);  last_position_ = pos;  last_position_is_statement_ = true;}void Assembler::GrowBuffer() {  if (!own_buffer_) FATAL("external code buffer is too small");  // compute new buffer size  CodeDesc desc;  // the new buffer  if (buffer_size_ < 4*KB) {    desc.buffer_size = 4*KB;  } else if (buffer_size_ < 1*MB) {    desc.buffer_size = 2*buffer_size_;  } else {    desc.buffer_size = buffer_size_ + 1*MB;  }  CHECK_GT(desc.buffer_size, 0);  // no overflow  // setup new buffer  desc.buffer = NewArray<byte>(desc.buffer_size);  desc.instr_size = pc_offset();  desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();  // copy the data  int pc_delta = desc.buffer - buffer_;  int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);  memmove(desc.buffer, buffer_, desc.instr_size);  memmove(reloc_info_writer.pos() + rc_delta,          reloc_info_writer.pos(), desc.reloc_size);  // switch buffers  DeleteArray(buffer_);  buffer_ = desc.buffer;  buffer_size_ = desc.buffer_size;  pc_ += pc_delta;  reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,                               reloc_info_writer.last_pc() + pc_delta);  // none of our relocation types are pc relative pointing outside the code  // buffer nor pc absolute pointing inside the code buffer, so there is no need  // to relocate any emitted relocation entries  // relocate pending relocation entries  for (int i = 0; i < num_prinfo_; i++) {    RelocInfo& rinfo = prinfo_[i];    ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&           rinfo.rmode() != RelocInfo::POSITION);    rinfo.set_pc(rinfo.pc() + pc_delta);  }}void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {  RelocInfo rinfo(pc_, rmode, data);  // we do not try to reuse pool constants  if (rmode >= RelocInfo::COMMENT && rmode <= RelocInfo::STATEMENT_POSITION) {    // adjust code for new modes    ASSERT(RelocInfo::IsComment(rmode) || RelocInfo::IsPosition(rmode));    // these modes do not need an entry in the constant pool  } else {    ASSERT(num_prinfo_ < kMaxNumPRInfo);    prinfo_[num_prinfo_++] = rinfo;    // Make sure the constant pool is not emitted in place of the next    // instruction for which we just recorded relocation info    BlockConstPoolBefore(pc_offset() + kInstrSize);  }  if (rinfo.rmode() != RelocInfo::NONE) {    // Don't record external references unless the heap will be serialized.    if (rmode == RelocInfo::EXTERNAL_REFERENCE &&        !Serializer::enabled() &&        !FLAG_debug_code) {      return;    }    ASSERT(buffer_space() >= kMaxRelocSize);  // too late to grow buffer here    reloc_info_writer.Write(&rinfo);  }}void Assembler::CheckConstPool(bool force_emit, bool require_jump) {  // Calculate the offset of the next check. It will be overwritten  // when a const pool is generated or when const pools are being  // blocked for a specific range.  next_buffer_check_ = pc_offset() + kCheckConstInterval;  // There is nothing to do if there are no pending relocation info entries  if (num_prinfo_ == 0) return;  // We emit a constant pool at regular intervals of about kDistBetweenPools  // or when requested by parameter force_emit (e.g. after each function).  // We prefer not to emit a jump unless the max distance is reached or if we  // are running low on slots, which can happen if a lot of constants are being  // emitted (e.g. --debug-code and many static references).  int dist = pc_offset() - last_const_pool_end_;  if (!force_emit && dist < kMaxDistBetweenPools &&      (require_jump || dist < kDistBetweenPools) &&      // TODO(1236125): Cleanup the "magic" number below. We know that      // the code generation will test every kCheckConstIntervalInst.      // Thus we are safe as long as we generate less than 7 constant      // entries per instruction.      (num_prinfo_ < (kMaxNumPRInfo - (7 * kCheckConstIntervalInst)))) {    return;  }  // If we did not return by now, we need to emit the constant pool soon.  // However, some small sequences of instructions must not be broken up by the  // insertion of a constant pool; such sequences are protected by setting  // no_const_pool_before_, which is checked here. Also, recursive calls to  // CheckConstPool are blocked by no_const_pool_before_.  if (pc_offset() < no_const_pool_before_) {    // Emission is currently blocked; make sure we try again as soon as possible    next_buffer_check_ = no_const_pool_before_;    // Something is wrong if emission is forced and blocked at the same time    ASSERT(!force_emit);    return;  }  int jump_instr = require_jump ? kInstrSize : 0;  // Check that the code buffer is large enough before emitting the constant  // pool and relocation information (include the jump over the pool and the  // constant pool marker).  int max_needed_space =      jump_instr + kInstrSize + num_prinfo_*(kInstrSize + kMaxRelocSize);  while (buffer_space() <= (max_needed_space + kGap)) GrowBuffer();  // Block recursive calls to CheckConstPool  BlockConstPoolBefore(pc_offset() + jump_instr + kInstrSize +                       num_prinfo_*kInstrSize);  // Don't bother to check for the emit calls below.  next_buffer_check_ = no_const_pool_before_;  // Emit jump over constant pool if necessary  Label after_pool;  if (require_jump) b(&after_pool);  RecordComment("[ Constant Pool");  // Put down constant pool marker  // "Undefined instruction" as specified by A3.1 Instruction set encoding  emit(0x03000000 | num_prinfo_);  // Emit constant pool entries  for (int i = 0; i < num_prinfo_; i++) {    RelocInfo& rinfo = prinfo_[i];    ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&           rinfo.rmode() != RelocInfo::POSITION &&           rinfo.rmode() != RelocInfo::STATEMENT_POSITION);    Instr instr = instr_at(rinfo.pc());    // Instruction to patch must be a ldr/str [pc, #offset]    // P and U set, B and W clear, Rn == pc, offset12 still 0    ASSERT((instr & (7*B25 | P | U | B | W | 15*B16 | Off12Mask)) ==           (2*B25 | P | U | pc.code()*B16));    int delta = pc_ - rinfo.pc() - 8;    ASSERT(delta >= -4);  // instr could be ldr pc, [pc, #-4] followed by targ32    if (delta < 0) {      instr &= ~U;      delta = -delta;    }    ASSERT(is_uint12(delta));    instr_at_put(rinfo.pc(), instr + delta);    emit(rinfo.data());  }  num_prinfo_ = 0;  last_const_pool_end_ = pc_offset();  RecordComment("]");  if (after_pool.is_linked()) {    bind(&after_pool);  }  // Since a constant pool was just emitted, move the check offset forward by  // the standard interval.  next_buffer_check_ = pc_offset() + kCheckConstInterval;}} }  // namespace v8::internal

⌨️ 快捷键说明

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