Home | History | Annotate | Download | only in arm
      1 // Copyright 2010 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_ARM_CONSTANTS_ARM_H_
     29 #define V8_ARM_CONSTANTS_ARM_H_
     30 
     31 // The simulator emulates the EABI so we define the USE_ARM_EABI macro if we
     32 // are not running on real ARM hardware.  One reason for this is that the
     33 // old ABI uses fp registers in the calling convention and the simulator does
     34 // not simulate fp registers or coroutine instructions.
     35 #if defined(__ARM_EABI__) || !defined(__arm__)
     36 # define USE_ARM_EABI 1
     37 #endif
     38 
     39 // This means that interwork-compatible jump instructions are generated.  We
     40 // want to generate them on the simulator too so it makes snapshots that can
     41 // be used on real hardware.
     42 #if defined(__THUMB_INTERWORK__) || !defined(__arm__)
     43 # define USE_THUMB_INTERWORK 1
     44 #endif
     45 
     46 #if defined(__ARM_ARCH_7A__) || \
     47     defined(__ARM_ARCH_7R__) || \
     48     defined(__ARM_ARCH_7__)
     49 # define CAN_USE_ARMV7_INSTRUCTIONS 1
     50 #endif
     51 
     52 #if defined(__ARM_ARCH_6__) ||   \
     53     defined(__ARM_ARCH_6J__) ||  \
     54     defined(__ARM_ARCH_6K__) ||  \
     55     defined(__ARM_ARCH_6Z__) ||  \
     56     defined(__ARM_ARCH_6ZK__) || \
     57     defined(__ARM_ARCH_6T2__) || \
     58     defined(CAN_USE_ARMV7_INSTRUCTIONS)
     59 # define CAN_USE_ARMV6_INSTRUCTIONS 1
     60 #endif
     61 
     62 #if defined(__ARM_ARCH_5T__)            || \
     63     defined(__ARM_ARCH_5TE__)           || \
     64     defined(CAN_USE_ARMV6_INSTRUCTIONS)
     65 # define CAN_USE_ARMV5_INSTRUCTIONS 1
     66 # define CAN_USE_THUMB_INSTRUCTIONS 1
     67 #endif
     68 
     69 // Simulator should support ARM5 instructions.
     70 #if !defined(__arm__)
     71 # define CAN_USE_ARMV5_INSTRUCTIONS 1
     72 # define CAN_USE_THUMB_INSTRUCTIONS 1
     73 #endif
     74 
     75 namespace assembler {
     76 namespace arm {
     77 
     78 // Number of registers in normal ARM mode.
     79 static const int kNumRegisters = 16;
     80 
     81 // VFP support.
     82 static const int kNumVFPRegisters = 48;
     83 
     84 // PC is register 15.
     85 static const int kPCRegister = 15;
     86 static const int kNoRegister = -1;
     87 
     88 // Defines constants and accessor classes to assemble, disassemble and
     89 // simulate ARM instructions.
     90 //
     91 // Section references in the code refer to the "ARM Architecture Reference
     92 // Manual" from July 2005 (available at http://www.arm.com/miscPDFs/14128.pdf)
     93 //
     94 // Constants for specific fields are defined in their respective named enums.
     95 // General constants are in an anonymous enum in class Instr.
     96 
     97 typedef unsigned char byte;
     98 
     99 // Values for the condition field as defined in section A3.2
    100 enum Condition {
    101   no_condition = -1,
    102   EQ =  0,  // equal
    103   NE =  1,  // not equal
    104   CS =  2,  // carry set/unsigned higher or same
    105   CC =  3,  // carry clear/unsigned lower
    106   MI =  4,  // minus/negative
    107   PL =  5,  // plus/positive or zero
    108   VS =  6,  // overflow
    109   VC =  7,  // no overflow
    110   HI =  8,  // unsigned higher
    111   LS =  9,  // unsigned lower or same
    112   GE = 10,  // signed greater than or equal
    113   LT = 11,  // signed less than
    114   GT = 12,  // signed greater than
    115   LE = 13,  // signed less than or equal
    116   AL = 14,  // always (unconditional)
    117   special_condition = 15,  // special condition (refer to section A3.2.1)
    118   max_condition = 16
    119 };
    120 
    121 
    122 // Opcodes for Data-processing instructions (instructions with a type 0 and 1)
    123 // as defined in section A3.4
    124 enum Opcode {
    125   no_operand = -1,
    126   AND =  0,  // Logical AND
    127   EOR =  1,  // Logical Exclusive OR
    128   SUB =  2,  // Subtract
    129   RSB =  3,  // Reverse Subtract
    130   ADD =  4,  // Add
    131   ADC =  5,  // Add with Carry
    132   SBC =  6,  // Subtract with Carry
    133   RSC =  7,  // Reverse Subtract with Carry
    134   TST =  8,  // Test
    135   TEQ =  9,  // Test Equivalence
    136   CMP = 10,  // Compare
    137   CMN = 11,  // Compare Negated
    138   ORR = 12,  // Logical (inclusive) OR
    139   MOV = 13,  // Move
    140   BIC = 14,  // Bit Clear
    141   MVN = 15,  // Move Not
    142   max_operand = 16
    143 };
    144 
    145 
    146 // Some special instructions encoded as a TEQ with S=0 (bit 20).
    147 enum Opcode9Bits {
    148   BX   =  1,
    149   BXJ  =  2,
    150   BLX  =  3,
    151   BKPT =  7
    152 };
    153 
    154 
    155 // Some special instructions encoded as a CMN with S=0 (bit 20).
    156 enum Opcode11Bits {
    157   CLZ  =  1
    158 };
    159 
    160 
    161 // S
    162 
    163 
    164 // Shifter types for Data-processing operands as defined in section A5.1.2.
    165 enum Shift {
    166   no_shift = -1,
    167   LSL = 0,  // Logical shift left
    168   LSR = 1,  // Logical shift right
    169   ASR = 2,  // Arithmetic shift right
    170   ROR = 3,  // Rotate right
    171   max_shift = 4
    172 };
    173 
    174 
    175 // Special Software Interrupt codes when used in the presence of the ARM
    176 // simulator.
    177 enum SoftwareInterruptCodes {
    178   // transition to C code
    179   call_rt_redirected = 0x10,
    180   // break point
    181   break_point = 0x20
    182 };
    183 
    184 
    185 typedef int32_t instr_t;
    186 
    187 
    188 // The class Instr enables access to individual fields defined in the ARM
    189 // architecture instruction set encoding as described in figure A3-1.
    190 //
    191 // Example: Test whether the instruction at ptr does set the condition code
    192 // bits.
    193 //
    194 // bool InstructionSetsConditionCodes(byte* ptr) {
    195 //   Instr* instr = Instr::At(ptr);
    196 //   int type = instr->TypeField();
    197 //   return ((type == 0) || (type == 1)) && instr->HasS();
    198 // }
    199 //
    200 class Instr {
    201  public:
    202   enum {
    203     kInstrSize = 4,
    204     kInstrSizeLog2 = 2,
    205     kPCReadOffset = 8
    206   };
    207 
    208   // Get the raw instruction bits.
    209   inline instr_t InstructionBits() const {
    210     return *reinterpret_cast<const instr_t*>(this);
    211   }
    212 
    213   // Set the raw instruction bits to value.
    214   inline void SetInstructionBits(instr_t value) {
    215     *reinterpret_cast<instr_t*>(this) = value;
    216   }
    217 
    218   // Read one particular bit out of the instruction bits.
    219   inline int Bit(int nr) const {
    220     return (InstructionBits() >> nr) & 1;
    221   }
    222 
    223   // Read a bit field out of the instruction bits.
    224   inline int Bits(int hi, int lo) const {
    225     return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
    226   }
    227 
    228 
    229   // Accessors for the different named fields used in the ARM encoding.
    230   // The naming of these accessor corresponds to figure A3-1.
    231   // Generally applicable fields
    232   inline Condition ConditionField() const {
    233     return static_cast<Condition>(Bits(31, 28));
    234   }
    235   inline int TypeField() const { return Bits(27, 25); }
    236 
    237   inline int RnField() const { return Bits(19, 16); }
    238   inline int RdField() const { return Bits(15, 12); }
    239 
    240   inline int CoprocessorField() const { return Bits(11, 8); }
    241   // Support for VFP.
    242   // Vn(19-16) | Vd(15-12) |  Vm(3-0)
    243   inline int VnField() const { return Bits(19, 16); }
    244   inline int VmField() const { return Bits(3, 0); }
    245   inline int VdField() const { return Bits(15, 12); }
    246   inline int NField() const { return Bit(7); }
    247   inline int MField() const { return Bit(5); }
    248   inline int DField() const { return Bit(22); }
    249   inline int RtField() const { return Bits(15, 12); }
    250   inline int PField() const { return Bit(24); }
    251   inline int UField() const { return Bit(23); }
    252 
    253   // Fields used in Data processing instructions
    254   inline Opcode OpcodeField() const {
    255     return static_cast<Opcode>(Bits(24, 21));
    256   }
    257   inline int SField() const { return Bit(20); }
    258     // with register
    259   inline int RmField() const { return Bits(3, 0); }
    260   inline Shift ShiftField() const { return static_cast<Shift>(Bits(6, 5)); }
    261   inline int RegShiftField() const { return Bit(4); }
    262   inline int RsField() const { return Bits(11, 8); }
    263   inline int ShiftAmountField() const { return Bits(11, 7); }
    264     // with immediate
    265   inline int RotateField() const { return Bits(11, 8); }
    266   inline int Immed8Field() const { return Bits(7, 0); }
    267 
    268   // Fields used in Load/Store instructions
    269   inline int PUField() const { return Bits(24, 23); }
    270   inline int  BField() const { return Bit(22); }
    271   inline int  WField() const { return Bit(21); }
    272   inline int  LField() const { return Bit(20); }
    273     // with register uses same fields as Data processing instructions above
    274     // with immediate
    275   inline int Offset12Field() const { return Bits(11, 0); }
    276     // multiple
    277   inline int RlistField() const { return Bits(15, 0); }
    278     // extra loads and stores
    279   inline int SignField() const { return Bit(6); }
    280   inline int HField() const { return Bit(5); }
    281   inline int ImmedHField() const { return Bits(11, 8); }
    282   inline int ImmedLField() const { return Bits(3, 0); }
    283 
    284   // Fields used in Branch instructions
    285   inline int LinkField() const { return Bit(24); }
    286   inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); }
    287 
    288   // Fields used in Software interrupt instructions
    289   inline SoftwareInterruptCodes SwiField() const {
    290     return static_cast<SoftwareInterruptCodes>(Bits(23, 0));
    291   }
    292 
    293   // Test for special encodings of type 0 instructions (extra loads and stores,
    294   // as well as multiplications).
    295   inline bool IsSpecialType0() const { return (Bit(7) == 1) && (Bit(4) == 1); }
    296 
    297   // Special accessors that test for existence of a value.
    298   inline bool HasS()    const { return SField() == 1; }
    299   inline bool HasB()    const { return BField() == 1; }
    300   inline bool HasW()    const { return WField() == 1; }
    301   inline bool HasL()    const { return LField() == 1; }
    302   inline bool HasU()    const { return UField() == 1; }
    303   inline bool HasSign() const { return SignField() == 1; }
    304   inline bool HasH()    const { return HField() == 1; }
    305   inline bool HasLink() const { return LinkField() == 1; }
    306 
    307   // Instructions are read of out a code stream. The only way to get a
    308   // reference to an instruction is to convert a pointer. There is no way
    309   // to allocate or create instances of class Instr.
    310   // Use the At(pc) function to create references to Instr.
    311   static Instr* At(byte* pc) { return reinterpret_cast<Instr*>(pc); }
    312 
    313  private:
    314   // We need to prevent the creation of instances of class Instr.
    315   DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
    316 };
    317 
    318 
    319 // Helper functions for converting between register numbers and names.
    320 class Registers {
    321  public:
    322   // Return the name of the register.
    323   static const char* Name(int reg);
    324 
    325   // Lookup the register number for the name provided.
    326   static int Number(const char* name);
    327 
    328   struct RegisterAlias {
    329     int reg;
    330     const char* name;
    331   };
    332 
    333  private:
    334   static const char* names_[kNumRegisters];
    335   static const RegisterAlias aliases_[];
    336 };
    337 
    338 // Helper functions for converting between VFP register numbers and names.
    339 class VFPRegisters {
    340  public:
    341   // Return the name of the register.
    342   static const char* Name(int reg);
    343 
    344  private:
    345   static const char* names_[kNumVFPRegisters];
    346 };
    347 
    348 
    349 } }  // namespace assembler::arm
    350 
    351 #endif  // V8_ARM_CONSTANTS_ARM_H_
    352