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

📄 assembler-arm.h.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
// 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.// A light-weight ARM Assembler// Generates user mode instructions for the ARM architecture up to version 5#ifndef V8_ASSEMBLER_ARM_H_#define V8_ASSEMBLER_ARM_H_#include "assembler.h"namespace v8 { namespace internal {// CPU Registers.//// 1) We would prefer to use an enum, but enum values are assignment-// compatible with int, which has caused code-generation bugs.//// 2) We would prefer to use a class instead of a struct but we don't like// the register initialization to depend on the particular initialization// order (which appears to be different on OS X, Linux, and Windows for the// installed versions of C++ we tried). Using a struct permits C-style// "initialization". Also, the Register objects cannot be const as this// forces initialization stubs in MSVC, making us dependent on initialization// order.//// 3) By not using an enum, we are possibly preventing the compiler from// doing certain constant folds, which may significantly reduce the// code generated for some assembly instructions (because they boil down// to a few constants). If this is a problem, we could change the code// such that we use an enum in optimized mode, and the struct in debug// mode. This way we get the compile-time error checking in debug mode// and best performance in optimized code.//// Core registerstruct Register {  bool is_valid() const  { return 0 <= code_ && code_ < 16; }  bool is(Register reg) const  { return code_ == reg.code_; }  int code() const  {    ASSERT(is_valid());    return code_;  }  int bit() const  {    ASSERT(is_valid());    return 1 << code_;  }  // (unfortunately we can't make this private in a struct)  int code_;};extern Register no_reg;extern Register r0;extern Register r1;extern Register r2;extern Register r3;extern Register r4;extern Register r5;extern Register r6;extern Register r7;extern Register r8;extern Register r9;extern Register r10;extern Register fp;extern Register ip;extern Register sp;extern Register lr;extern Register pc;// Coprocessor registerstruct CRegister {  bool is_valid() const  { return 0 <= code_ && code_ < 16; }  bool is(CRegister creg) const  { return code_ == creg.code_; }  int code() const  {    ASSERT(is_valid());    return code_;  }  int bit() const  {    ASSERT(is_valid());    return 1 << code_;  }  // (unfortunately we can't make this private in a struct)  int code_;};extern CRegister no_creg;extern CRegister cr0;extern CRegister cr1;extern CRegister cr2;extern CRegister cr3;extern CRegister cr4;extern CRegister cr5;extern CRegister cr6;extern CRegister cr7;extern CRegister cr8;extern CRegister cr9;extern CRegister cr10;extern CRegister cr11;extern CRegister cr12;extern CRegister cr13;extern CRegister cr14;extern CRegister cr15;// Coprocessor numberenum Coprocessor {  p0  = 0,  p1  = 1,  p2  = 2,  p3  = 3,  p4  = 4,  p5  = 5,  p6  = 6,  p7  = 7,  p8  = 8,  p9  = 9,  p10 = 10,  p11 = 11,  p12 = 12,  p13 = 13,  p14 = 14,  p15 = 15};// Condition field in instructionsenum Condition {  eq =  0 << 28,  ne =  1 << 28,  cs =  2 << 28,  hs =  2 << 28,  cc =  3 << 28,  lo =  3 << 28,  mi =  4 << 28,  pl =  5 << 28,  vs =  6 << 28,  vc =  7 << 28,  hi =  8 << 28,  ls =  9 << 28,  ge = 10 << 28,  lt = 11 << 28,  gt = 12 << 28,  le = 13 << 28,  al = 14 << 28};// Returns the equivalent of !cc.INLINE(Condition NegateCondition(Condition cc));// Corresponds to transposing the operands of a comparison.inline Condition ReverseCondition(Condition cc) {  switch (cc) {    case lo:      return hi;    case hi:      return lo;    case hs:      return ls;    case ls:      return hs;    case lt:      return gt;    case gt:      return lt;    case ge:      return le;    case le:      return ge;    default:      return cc;  };}// The pc store offset may be 8 or 12 depending on the processor implementation.int PcStoreOffset();// -----------------------------------------------------------------------------// Addressing modes and instruction variants// Shifter operand shift operationenum ShiftOp {  LSL = 0 << 5,  LSR = 1 << 5,  ASR = 2 << 5,  ROR = 3 << 5,  RRX = -1};// Condition code updating modeenum SBit {  SetCC   = 1 << 20,  // set condition code  LeaveCC = 0 << 20   // leave condition code unchanged};// Status register selectionenum SRegister {  CPSR = 0 << 22,  SPSR = 1 << 22};// Status register fieldsenum SRegisterField {  CPSR_c = CPSR | 1 << 16,  CPSR_x = CPSR | 1 << 17,  CPSR_s = CPSR | 1 << 18,  CPSR_f = CPSR | 1 << 19,  SPSR_c = SPSR | 1 << 16,  SPSR_x = SPSR | 1 << 17,  SPSR_s = SPSR | 1 << 18,  SPSR_f = SPSR | 1 << 19};// Status register field mask (or'ed SRegisterField enum values)typedef uint32_t SRegisterFieldMask;// Memory operand addressing modeenum AddrMode {  // bit encoding P U W  Offset       = (8|4|0) << 21,  // offset (without writeback to base)  PreIndex     = (8|4|1) << 21,  // pre-indexed addressing with writeback  PostIndex    = (0|4|0) << 21,  // post-indexed addressing with writeback  NegOffset    = (8|0|0) << 21,  // negative offset (without writeback to base)  NegPreIndex  = (8|0|1) << 21,  // negative pre-indexed with writeback  NegPostIndex = (0|0|0) << 21   // negative post-indexed with writeback};// Load/store multiple addressing modeenum BlockAddrMode {  // bit encoding P U W  da           = (0|0|0) << 21,  // decrement after  ia           = (0|4|0) << 21,  // increment after  db           = (8|0|0) << 21,  // decrement before  ib           = (8|4|0) << 21,  // increment before  da_w         = (0|0|1) << 21,  // decrement after with writeback to base  ia_w         = (0|4|1) << 21,  // increment after with writeback to base  db_w         = (8|0|1) << 21,  // decrement before with writeback to base  ib_w         = (8|4|1) << 21   // increment before with writeback to base};// Coprocessor load/store operand sizeenum LFlag {  Long  = 1 << 22,  // long load/store coprocessor  Short = 0 << 22   // short load/store coprocessor};// -----------------------------------------------------------------------------// Machine instruction Operands// Class Operand represents a shifter operand in data processing instructionsclass Operand BASE_EMBEDDED { public:  // immediate  INLINE(explicit Operand(int32_t immediate,         RelocInfo::Mode rmode = RelocInfo::NONE));  INLINE(explicit Operand(const ExternalReference& f));  INLINE(explicit Operand(const char* s));  INLINE(explicit Operand(Object** opp));  INLINE(explicit Operand(Context** cpp));  explicit Operand(Handle<Object> handle);  INLINE(explicit Operand(Smi* value));  // rm  INLINE(explicit Operand(Register rm));  // rm <shift_op> shift_imm  explicit Operand(Register rm, ShiftOp shift_op, int shift_imm);  // rm <shift_op> rs  explicit Operand(Register rm, ShiftOp shift_op, Register rs);  // Return true if this is a register operand.  INLINE(bool is_reg() const);  Register rm() const { return rm_; } private:  Register rm_;  Register rs_;  ShiftOp shift_op_;  int shift_imm_;  // valid if rm_ != no_reg && rs_ == no_reg  int32_t imm32_;  // valid if rm_ == no_reg  RelocInfo::Mode rmode_;  friend class Assembler;};// Class MemOperand represents a memory operand in load and store instructionsclass MemOperand BASE_EMBEDDED { public:  // [rn +/- offset]      Offset/NegOffset  // [rn +/- offset]!     PreIndex/NegPreIndex  // [rn], +/- offset     PostIndex/NegPostIndex  // offset is any signed 32-bit value; offset is first loaded to register ip if  // it does not fit the addressing mode (12-bit unsigned and sign bit)  explicit MemOperand(Register rn, int32_t offset = 0, AddrMode am = Offset);  // [rn +/- rm]          Offset/NegOffset  // [rn +/- rm]!         PreIndex/NegPreIndex  // [rn], +/- rm         PostIndex/NegPostIndex  explicit MemOperand(Register rn, Register rm, AddrMode am = Offset);  // [rn +/- rm <shift_op> shift_imm]      Offset/NegOffset  // [rn +/- rm <shift_op> shift_imm]!     PreIndex/NegPreIndex  // [rn], +/- rm <shift_op> shift_imm     PostIndex/NegPostIndex  explicit MemOperand(Register rn, Register rm,                      ShiftOp shift_op, int shift_imm, AddrMode am = Offset); private:  Register rn_;  // base  Register rm_;  // register offset  int32_t offset_;  // valid if rm_ == no_reg  ShiftOp shift_op_;  int shift_imm_;  // valid if rm_ != no_reg && rs_ == no_reg  AddrMode am_;  // bits P, U, and W  friend class Assembler;};typedef int32_t Instr;class Assembler : public Malloced { public:  // Create an assembler. Instructions and relocation information are emitted  // into a buffer, with the instructions starting from the beginning and the  // relocation information starting from the end of the buffer. See CodeDesc  // for a detailed comment on the layout (globals.h).  //  // If the provided buffer is NULL, the assembler allocates and grows its own  // buffer, and buffer_size determines the initial buffer size. The buffer is  // owned by the assembler and deallocated upon destruction of the assembler.  //  // If the provided buffer is not NULL, the assembler uses the provided buffer  // for code generation and assumes its size to be buffer_size. If the buffer  // is too small, a fatal error occurs. No deallocation of the buffer is done  // upon destruction of the assembler.  Assembler(void* buffer, int buffer_size);  ~Assembler();  // GetCode emits any pending (non-emitted) code and fills the descriptor  // desc. GetCode() is idempotent; it returns the same result if no other  // Assembler functions are invoked inbetween GetCode() calls.  void GetCode(CodeDesc* desc);  // Label operations & relative jumps (PPUM Appendix D)

⌨️ 快捷键说明

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