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

📄 assembler-arm.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
// Copyright (c) 1994-2006 Sun Microsystems Inc.// All Rights Reserved.//// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions// are met://// - Redistributions of source code must retain the above copyright notice,// this list of conditions and the following disclaimer.//// - Redistribution in binary form must reproduce the above copyright// notice, this list of conditions and the following disclaimer in the// documentation and/or other materials provided with the// distribution.//// - Neither the name of Sun Microsystems or the names of contributors may// be used to endorse or promote products derived from this software without// specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED// OF THE POSSIBILITY OF SUCH DAMAGE.// The original source code covered by the above license above has been modified// significantly by Google Inc.// Copyright 2006-2008 the V8 project authors. All rights reserved.#include "v8.h"#include "assembler-arm-inl.h"#include "serialize.h"namespace v8 { namespace internal {// -----------------------------------------------------------------------------// Implementation of Register and CRegisterRegister no_reg = { -1 };Register r0  = {  0 };Register r1  = {  1 };Register r2  = {  2 };Register r3  = {  3 };Register r4  = {  4 };Register r5  = {  5 };Register r6  = {  6 };Register r7  = {  7 };Register r8  = {  8 };Register r9  = {  9 };Register r10 = { 10 };Register fp  = { 11 };Register ip  = { 12 };Register sp  = { 13 };Register lr  = { 14 };Register pc  = { 15 };CRegister no_creg = { -1 };CRegister cr0  = {  0 };CRegister cr1  = {  1 };CRegister cr2  = {  2 };CRegister cr3  = {  3 };CRegister cr4  = {  4 };CRegister cr5  = {  5 };CRegister cr6  = {  6 };CRegister cr7  = {  7 };CRegister cr8  = {  8 };CRegister cr9  = {  9 };CRegister cr10 = { 10 };CRegister cr11 = { 11 };CRegister cr12 = { 12 };CRegister cr13 = { 13 };CRegister cr14 = { 14 };CRegister cr15 = { 15 };// In order to determine the pc store offset, we execute a small code sequence.// See ARM Architecture Reference Manual section A-2.4.3// Note that 'str pc, [sp]' and 'stmia sp, {pc}' were using different offsets// under the QEMU emulator (now fixed), so we are careful to test the actual// instruction we are interested in (stmia).int PcStoreOffset() {#if !defined(__arm__)  // Building an ARM emulator based target. The emulator is wired for 8 byte  // pc offsets as is the default in the spec.  static int pc_store_offset = 8;#elif defined(__arm__) && !defined(__thumb__)  // __arm__ may be defined in thumb mode.  static int pc_store_offset = -1;  asm volatile(    "sub sp, sp, #4  \n\t"    "sub r1, pc, #4  \n\t"    "stmia sp, {pc}  \n\t"    "ldr r0, [sp]    \n\t"    "add sp, sp, #4  \n\t"    "sub %0, r0, r1  \n\t"    : "=r" (pc_store_offset) : : "r0", "r1", "memory");#elif defined(__thumb__)  static int pc_store_offset = -1;  asm volatile(  "@   Enter ARM Mode  \n\t"      "adr r2, 1f      \n\t"      "bx  r2          \n\t"      ".ALIGN 4        \n\t"      ".ARM            \n"  "1:  sub sp, sp, #4  \n\t"      "sub r1, pc, #4  \n\t"      "stmia sp, {pc}  \n\t"      "ldr r0, [sp]    \n\t"      "add sp, sp, #4  \n\t"      "sub %0, r0, r1  \n"  "@   Enter THUMB Mode\n\t"      "adr r2, 2f+1    \n\t"      "bx  r2          \n\t"      ".THUMB          \n"  "2:                  \n\t"      : "=r" (pc_store_offset) : : "r0", "r1", "r2", "memory");#else#error unsupported architecture#endif  ASSERT(pc_store_offset == 8 || pc_store_offset == 12);  return pc_store_offset;}// -----------------------------------------------------------------------------// Implementation of RelocInfoconst int RelocInfo::kApplyMask = 0;void RelocInfo::patch_code(byte* instructions, int instruction_count) {  // Patch the code at the current address with the supplied instructions.  UNIMPLEMENTED();}// Patch the code at the current PC with a call to the target address.// Additional guard int3 instructions can be added if required.void RelocInfo::patch_code_with_call(Address target, int guard_bytes) {  // Patch the code at the current address with a call to the target.  UNIMPLEMENTED();}// -----------------------------------------------------------------------------// Implementation of Operand and MemOperand// See assembler-arm-inl.h for inlined constructorsOperand::Operand(Handle<Object> handle) {  rm_ = no_reg;  // Verify all Objects referred by code are NOT in new space.  Object* obj = *handle;  ASSERT(!Heap::InNewSpace(obj));  if (obj->IsHeapObject()) {    imm32_ = reinterpret_cast<intptr_t>(handle.location());    rmode_ = RelocInfo::EMBEDDED_OBJECT;  } else {    // no relocation needed    imm32_ =  reinterpret_cast<intptr_t>(obj);    rmode_ = RelocInfo::NONE;  }}Operand::Operand(Register rm, ShiftOp shift_op, int shift_imm) {  ASSERT(is_uint5(shift_imm));  ASSERT(shift_op != ROR || shift_imm != 0);  // use RRX if you mean it  rm_ = rm;  rs_ = no_reg;  shift_op_ = shift_op;  shift_imm_ = shift_imm & 31;  if (shift_op == RRX) {    // encoded as ROR with shift_imm == 0    ASSERT(shift_imm == 0);    shift_op_ = ROR;    shift_imm_ = 0;  }}Operand::Operand(Register rm, ShiftOp shift_op, Register rs) {  ASSERT(shift_op != RRX);  rm_ = rm;  rs_ = no_reg;  shift_op_ = shift_op;  rs_ = rs;}MemOperand::MemOperand(Register rn, int32_t offset, AddrMode am) {  rn_ = rn;  rm_ = no_reg;  offset_ = offset;  am_ = am;}MemOperand::MemOperand(Register rn, Register rm, AddrMode am) {  rn_ = rn;  rm_ = rm;  shift_op_ = LSL;  shift_imm_ = 0;  am_ = am;}MemOperand::MemOperand(Register rn, Register rm,                       ShiftOp shift_op, int shift_imm, AddrMode am) {  ASSERT(is_uint5(shift_imm));  rn_ = rn;  rm_ = rm;  shift_op_ = shift_op;  shift_imm_ = shift_imm & 31;  am_ = am;}// -----------------------------------------------------------------------------// Implementation of Assembler// Instruction encoding bitsenum {  H   = 1 << 5,   // halfword (or byte)  S6  = 1 << 6,   // signed (or unsigned)  L   = 1 << 20,  // load (or store)  S   = 1 << 20,  // set condition code (or leave unchanged)  W   = 1 << 21,  // writeback base register (or leave unchanged)  A   = 1 << 21,  // accumulate in multiply instruction (or not)  B   = 1 << 22,  // unsigned byte (or word)  N   = 1 << 22,  // long (or short)  U   = 1 << 23,  // positive (or negative) offset/index  P   = 1 << 24,  // offset/pre-indexed addressing (or post-indexed addressing)  I   = 1 << 25,  // immediate shifter operand (or not)  B4  = 1 << 4,  B5  = 1 << 5,  B7  = 1 << 7,  B8  = 1 << 8,  B12 = 1 << 12,  B16 = 1 << 16,  B20 = 1 << 20,  B21 = 1 << 21,  B22 = 1 << 22,  B23 = 1 << 23,  B24 = 1 << 24,  B25 = 1 << 25,  B26 = 1 << 26,  B27 = 1 << 27,  // Instruction bit masks  RdMask     = 15 << 12,  // in str instruction  CondMask   = 15 << 28,  OpCodeMask = 15 << 21,  // in data-processing instructions  Imm24Mask  = (1 << 24) - 1,  Off12Mask  = (1 << 12) - 1,  // Reserved condition  nv = 15 << 28};// add(sp, sp, 4) instruction (aka Pop())static const Instr kPopInstruction =    al | 4 * B21 | 4 | LeaveCC | I | sp.code() * B16 | sp.code() * B12;// str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))// register r is not encoded.static const Instr kPushRegPattern =    al | B26 | 4 | NegPreIndex | sp.code() * B16;// ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r))// register r is not encoded.static const Instr kPopRegPattern =    al | B26 | L | 4 | PostIndex | sp.code() * B16;// spare_buffer_static const int kMinimalBufferSize = 4*KB;static byte* spare_buffer_ = NULL;Assembler::Assembler(void* buffer, int buffer_size) {  if (buffer == NULL) {    // do our own buffer management    if (buffer_size <= kMinimalBufferSize) {      buffer_size = kMinimalBufferSize;      if (spare_buffer_ != NULL) {        buffer = spare_buffer_;        spare_buffer_ = NULL;      }    }    if (buffer == NULL) {      buffer_ = NewArray<byte>(buffer_size);    } else {      buffer_ = static_cast<byte*>(buffer);    }    buffer_size_ = buffer_size;    own_buffer_ = true;  } else {    // use externally provided buffer instead    ASSERT(buffer_size > 0);    buffer_ = static_cast<byte*>(buffer);    buffer_size_ = buffer_size;    own_buffer_ = false;  }  // setup buffer pointers  ASSERT(buffer_ != NULL);  pc_ = buffer_;  reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);  num_prinfo_ = 0;  next_buffer_check_ = 0;  no_const_pool_before_ = 0;  last_const_pool_end_ = 0;  last_bound_pos_ = 0;  last_position_ = RelocInfo::kNoPosition;  last_position_is_statement_ = false;}Assembler::~Assembler() {  if (own_buffer_) {    if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) {      spare_buffer_ = buffer_;    } else {      DeleteArray(buffer_);    }  }}void Assembler::GetCode(CodeDesc* desc) {  // finalize code  if (unbound_label_.is_linked())    bind_to(&unbound_label_, binding_pos_);  // emit constant pool if necessary  CheckConstPool(true, false);  ASSERT(num_prinfo_ == 0);  // setup desc  desc->buffer = buffer_;  desc->buffer_size = buffer_size_;  desc->instr_size = pc_offset();  desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();}void Assembler::Align(int m) {  ASSERT(m >= 4 && IsPowerOf2(m));  while ((pc_offset() & (m - 1)) != 0) {    nop();  }}// Labels refer to positions in the (to be) generated code.// There are bound, linked, and unused labels.//// Bound labels refer to known positions in the already// generated code. pos() is the position the label refers to.//// Linked labels refer to unknown positions in the code// to be generated; pos() is the position of the last// instruction using the label.// The link chain is terminated by a negative code position (must be aligned)const int kEndOfChain = -4;int Assembler::target_at(int pos)  {  Instr instr = instr_at(pos);  ASSERT((instr & 7*B25) == 5*B25);  // b, bl, or blx imm24  int imm26 = ((instr & Imm24Mask) << 8) >> 6;  if ((instr & CondMask) == nv && (instr & B24) != 0)    // blx uses bit 24 to encode bit 2 of imm26    imm26 += 2;  return pos + 8 + imm26;}

⌨️ 快捷键说明

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