Home | History | Annotate | Download | only in arm
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_COMPILER_UTILS_ARM_CONSTANTS_ARM_H_
     18 #define ART_COMPILER_UTILS_ARM_CONSTANTS_ARM_H_
     19 
     20 #include <stdint.h>
     21 
     22 #include <iosfwd>
     23 
     24 #include "arch/arm/registers_arm.h"
     25 #include "base/casts.h"
     26 #include "base/logging.h"
     27 #include "globals.h"
     28 
     29 namespace art {
     30 namespace arm {
     31 
     32 // Defines constants and accessor classes to assemble, disassemble and
     33 // simulate ARM instructions.
     34 //
     35 // Section references in the code refer to the "ARM Architecture Reference
     36 // Manual" from July 2005 (available at http://www.arm.com/miscPDFs/14128.pdf)
     37 //
     38 // Constants for specific fields are defined in their respective named enums.
     39 // General constants are in an anonymous enum in class Instr.
     40 
     41 
     42 // We support both VFPv3-D16 and VFPv3-D32 profiles, but currently only one at
     43 // a time, so that compile time optimizations can be applied.
     44 // Warning: VFPv3-D32 is untested.
     45 #define VFPv3_D16
     46 #if defined(VFPv3_D16) == defined(VFPv3_D32)
     47 #error "Exactly one of VFPv3_D16 or VFPv3_D32 can be defined at a time."
     48 #endif
     49 
     50 
     51 enum ScaleFactor {
     52   TIMES_1 = 0,
     53   TIMES_2 = 1,
     54   TIMES_4 = 2,
     55   TIMES_8 = 3
     56 };
     57 
     58 // Values for double-precision floating point registers.
     59 enum DRegister {
     60   D0  =  0,
     61   D1  =  1,
     62   D2  =  2,
     63   D3  =  3,
     64   D4  =  4,
     65   D5  =  5,
     66   D6  =  6,
     67   D7  =  7,
     68   D8  =  8,
     69   D9  =  9,
     70   D10 = 10,
     71   D11 = 11,
     72   D12 = 12,
     73   D13 = 13,
     74   D14 = 14,
     75   D15 = 15,
     76 #ifdef VFPv3_D16
     77   kNumberOfDRegisters = 16,
     78 #else
     79   D16 = 16,
     80   D17 = 17,
     81   D18 = 18,
     82   D19 = 19,
     83   D20 = 20,
     84   D21 = 21,
     85   D22 = 22,
     86   D23 = 23,
     87   D24 = 24,
     88   D25 = 25,
     89   D26 = 26,
     90   D27 = 27,
     91   D28 = 28,
     92   D29 = 29,
     93   D30 = 30,
     94   D31 = 31,
     95   kNumberOfDRegisters = 32,
     96 #endif
     97   kNumberOfOverlappingDRegisters = 16,
     98   kNoDRegister = -1,
     99 };
    100 std::ostream& operator<<(std::ostream& os, const DRegister& rhs);
    101 
    102 
    103 // Values for the condition field as defined in section A3.2.
    104 enum Condition {
    105   kNoCondition = -1,
    106   EQ =  0,  // equal
    107   NE =  1,  // not equal
    108   CS =  2,  // carry set/unsigned higher or same
    109   CC =  3,  // carry clear/unsigned lower
    110   MI =  4,  // minus/negative
    111   PL =  5,  // plus/positive or zero
    112   VS =  6,  // overflow
    113   VC =  7,  // no overflow
    114   HI =  8,  // unsigned higher
    115   LS =  9,  // unsigned lower or same
    116   GE = 10,  // signed greater than or equal
    117   LT = 11,  // signed less than
    118   GT = 12,  // signed greater than
    119   LE = 13,  // signed less than or equal
    120   AL = 14,  // always (unconditional)
    121   kSpecialCondition = 15,  // special condition (refer to section A3.2.1)
    122   kMaxCondition = 16,
    123 };
    124 std::ostream& operator<<(std::ostream& os, const Condition& rhs);
    125 
    126 
    127 // Opcodes for Data-processing instructions (instructions with a type 0 and 1)
    128 // as defined in section A3.4
    129 enum Opcode {
    130   kNoOperand = -1,
    131   AND =  0,  // Logical AND
    132   EOR =  1,  // Logical Exclusive OR
    133   SUB =  2,  // Subtract
    134   RSB =  3,  // Reverse Subtract
    135   ADD =  4,  // Add
    136   ADC =  5,  // Add with Carry
    137   SBC =  6,  // Subtract with Carry
    138   RSC =  7,  // Reverse Subtract with Carry
    139   TST =  8,  // Test
    140   TEQ =  9,  // Test Equivalence
    141   CMP = 10,  // Compare
    142   CMN = 11,  // Compare Negated
    143   ORR = 12,  // Logical (inclusive) OR
    144   MOV = 13,  // Move
    145   BIC = 14,  // Bit Clear
    146   MVN = 15,  // Move Not
    147   kMaxOperand = 16
    148 };
    149 
    150 
    151 // Shifter types for Data-processing operands as defined in section A5.1.2.
    152 enum Shift {
    153   kNoShift = -1,
    154   LSL = 0,  // Logical shift left
    155   LSR = 1,  // Logical shift right
    156   ASR = 2,  // Arithmetic shift right
    157   ROR = 3,  // Rotate right
    158   kMaxShift = 4
    159 };
    160 
    161 
    162 // Constants used for the decoding or encoding of the individual fields of
    163 // instructions. Based on the "Figure 3-1 ARM instruction set summary".
    164 enum InstructionFields {
    165   kConditionShift = 28,
    166   kConditionBits = 4,
    167   kTypeShift = 25,
    168   kTypeBits = 3,
    169   kLinkShift = 24,
    170   kLinkBits = 1,
    171   kUShift = 23,
    172   kUBits = 1,
    173   kOpcodeShift = 21,
    174   kOpcodeBits = 4,
    175   kSShift = 20,
    176   kSBits = 1,
    177   kRnShift = 16,
    178   kRnBits = 4,
    179   kRdShift = 12,
    180   kRdBits = 4,
    181   kRsShift = 8,
    182   kRsBits = 4,
    183   kRmShift = 0,
    184   kRmBits = 4,
    185 
    186   // Immediate instruction fields encoding.
    187   kRotateShift = 8,
    188   kRotateBits = 4,
    189   kImmed8Shift = 0,
    190   kImmed8Bits = 8,
    191 
    192   // Shift instruction register fields encodings.
    193   kShiftImmShift = 7,
    194   kShiftRegisterShift = 8,
    195   kShiftImmBits = 5,
    196   kShiftShift = 5,
    197   kShiftBits = 2,
    198 
    199   // Load/store instruction offset field encoding.
    200   kOffset12Shift = 0,
    201   kOffset12Bits = 12,
    202   kOffset12Mask = 0x00000fff,
    203 
    204   // Mul instruction register fields encodings.
    205   kMulRdShift = 16,
    206   kMulRdBits = 4,
    207   kMulRnShift = 12,
    208   kMulRnBits = 4,
    209 
    210   kBranchOffsetMask = 0x00ffffff
    211 };
    212 
    213 
    214 // Size (in bytes) of registers.
    215 const int kRegisterSize = 4;
    216 
    217 // List of registers used in load/store multiple.
    218 typedef uint16_t RegList;
    219 
    220 // The class Instr enables access to individual fields defined in the ARM
    221 // architecture instruction set encoding as described in figure A3-1.
    222 //
    223 // Example: Test whether the instruction at ptr does set the condition code
    224 // bits.
    225 //
    226 // bool InstructionSetsConditionCodes(byte* ptr) {
    227 //   Instr* instr = Instr::At(ptr);
    228 //   int type = instr->TypeField();
    229 //   return ((type == 0) || (type == 1)) && instr->HasS();
    230 // }
    231 //
    232 class Instr {
    233  public:
    234   enum {
    235     kInstrSize = 4,
    236     kInstrSizeLog2 = 2,
    237     kPCReadOffset = 8
    238   };
    239 
    240   bool IsBreakPoint() {
    241     return IsBkpt();
    242   }
    243 
    244   // Get the raw instruction bits.
    245   inline int32_t InstructionBits() const {
    246     return *reinterpret_cast<const int32_t*>(this);
    247   }
    248 
    249   // Set the raw instruction bits to value.
    250   inline void SetInstructionBits(int32_t value) {
    251     *reinterpret_cast<int32_t*>(this) = value;
    252   }
    253 
    254   // Read one particular bit out of the instruction bits.
    255   inline int Bit(int nr) const {
    256     return (InstructionBits() >> nr) & 1;
    257   }
    258 
    259   // Read a bit field out of the instruction bits.
    260   inline int Bits(int shift, int count) const {
    261     return (InstructionBits() >> shift) & ((1 << count) - 1);
    262   }
    263 
    264 
    265   // Accessors for the different named fields used in the ARM encoding.
    266   // The naming of these accessor corresponds to figure A3-1.
    267   // Generally applicable fields
    268   inline Condition ConditionField() const {
    269     return static_cast<Condition>(Bits(kConditionShift, kConditionBits));
    270   }
    271   inline int TypeField() const { return Bits(kTypeShift, kTypeBits); }
    272 
    273   inline Register RnField() const { return static_cast<Register>(
    274                                         Bits(kRnShift, kRnBits)); }
    275   inline Register RdField() const { return static_cast<Register>(
    276                                         Bits(kRdShift, kRdBits)); }
    277 
    278   // Fields used in Data processing instructions
    279   inline Opcode OpcodeField() const {
    280     return static_cast<Opcode>(Bits(kOpcodeShift, kOpcodeBits));
    281   }
    282   inline int SField() const { return Bits(kSShift, kSBits); }
    283   // with register
    284   inline Register RmField() const {
    285     return static_cast<Register>(Bits(kRmShift, kRmBits));
    286   }
    287   inline Shift ShiftField() const { return static_cast<Shift>(
    288                                         Bits(kShiftShift, kShiftBits)); }
    289   inline int RegShiftField() const { return Bit(4); }
    290   inline Register RsField() const {
    291     return static_cast<Register>(Bits(kRsShift, kRsBits));
    292   }
    293   inline int ShiftAmountField() const { return Bits(kShiftImmShift,
    294                                                     kShiftImmBits); }
    295   // with immediate
    296   inline int RotateField() const { return Bits(kRotateShift, kRotateBits); }
    297   inline int Immed8Field() const { return Bits(kImmed8Shift, kImmed8Bits); }
    298 
    299   // Fields used in Load/Store instructions
    300   inline int PUField() const { return Bits(23, 2); }
    301   inline int  BField() const { return Bit(22); }
    302   inline int  WField() const { return Bit(21); }
    303   inline int  LField() const { return Bit(20); }
    304   // with register uses same fields as Data processing instructions above
    305   // with immediate
    306   inline int Offset12Field() const { return Bits(kOffset12Shift,
    307                                                  kOffset12Bits); }
    308   // multiple
    309   inline int RlistField() const { return Bits(0, 16); }
    310   // extra loads and stores
    311   inline int SignField() const { return Bit(6); }
    312   inline int HField() const { return Bit(5); }
    313   inline int ImmedHField() const { return Bits(8, 4); }
    314   inline int ImmedLField() const { return Bits(0, 4); }
    315 
    316   // Fields used in Branch instructions
    317   inline int LinkField() const { return Bits(kLinkShift, kLinkBits); }
    318   inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); }
    319 
    320   // Fields used in Supervisor Call instructions
    321   inline uint32_t SvcField() const { return Bits(0, 24); }
    322 
    323   // Field used in Breakpoint instruction
    324   inline uint16_t BkptField() const {
    325     return ((Bits(8, 12) << 4) | Bits(0, 4));
    326   }
    327 
    328   // Field used in 16-bit immediate move instructions
    329   inline uint16_t MovwField() const {
    330     return ((Bits(16, 4) << 12) | Bits(0, 12));
    331   }
    332 
    333   // Field used in VFP float immediate move instruction
    334   inline float ImmFloatField() const {
    335     uint32_t imm32 = (Bit(19) << 31) | (((1 << 5) - Bit(18)) << 25) |
    336                      (Bits(16, 2) << 23) | (Bits(0, 4) << 19);
    337     return bit_cast<float, uint32_t>(imm32);
    338   }
    339 
    340   // Field used in VFP double immediate move instruction
    341   inline double ImmDoubleField() const {
    342     uint64_t imm64 = (Bit(19)*(1LL << 63)) | (((1LL << 8) - Bit(18)) << 54) |
    343                      (Bits(16, 2)*(1LL << 52)) | (Bits(0, 4)*(1LL << 48));
    344     return bit_cast<double, uint64_t>(imm64);
    345   }
    346 
    347   // Test for data processing instructions of type 0 or 1.
    348   // See "ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition",
    349   // section A5.1 "ARM instruction set encoding".
    350   inline bool IsDataProcessing() const {
    351     CHECK_NE(ConditionField(), kSpecialCondition);
    352     CHECK_EQ(Bits(26, 2), 0);  // Type 0 or 1.
    353     return ((Bits(20, 5) & 0x19) != 0x10) &&
    354       ((Bit(25) == 1) ||  // Data processing immediate.
    355        (Bit(4) == 0) ||  // Data processing register.
    356        (Bit(7) == 0));  // Data processing register-shifted register.
    357   }
    358 
    359   // Tests for special encodings of type 0 instructions (extra loads and stores,
    360   // as well as multiplications, synchronization primitives, and miscellaneous).
    361   // Can only be called for a type 0 or 1 instruction.
    362   inline bool IsMiscellaneous() const {
    363     CHECK_EQ(Bits(26, 2), 0);  // Type 0 or 1.
    364     return ((Bit(25) == 0) && ((Bits(20, 5) & 0x19) == 0x10) && (Bit(7) == 0));
    365   }
    366   inline bool IsMultiplyOrSyncPrimitive() const {
    367     CHECK_EQ(Bits(26, 2), 0);  // Type 0 or 1.
    368     return ((Bit(25) == 0) && (Bits(4, 4) == 9));
    369   }
    370 
    371   // Test for Supervisor Call instruction.
    372   inline bool IsSvc() const {
    373     return ((InstructionBits() & 0xff000000) == 0xef000000);
    374   }
    375 
    376   // Test for Breakpoint instruction.
    377   inline bool IsBkpt() const {
    378     return ((InstructionBits() & 0xfff000f0) == 0xe1200070);
    379   }
    380 
    381   // VFP register fields.
    382   inline SRegister SnField() const {
    383     return static_cast<SRegister>((Bits(kRnShift, kRnBits) << 1) + Bit(7));
    384   }
    385   inline SRegister SdField() const {
    386     return static_cast<SRegister>((Bits(kRdShift, kRdBits) << 1) + Bit(22));
    387   }
    388   inline SRegister SmField() const {
    389     return static_cast<SRegister>((Bits(kRmShift, kRmBits) << 1) + Bit(5));
    390   }
    391   inline DRegister DnField() const {
    392     return static_cast<DRegister>(Bits(kRnShift, kRnBits) + (Bit(7) << 4));
    393   }
    394   inline DRegister DdField() const {
    395     return static_cast<DRegister>(Bits(kRdShift, kRdBits) + (Bit(22) << 4));
    396   }
    397   inline DRegister DmField() const {
    398     return static_cast<DRegister>(Bits(kRmShift, kRmBits) + (Bit(5) << 4));
    399   }
    400 
    401   // Test for VFP data processing or single transfer instructions of type 7.
    402   inline bool IsVFPDataProcessingOrSingleTransfer() const {
    403     CHECK_NE(ConditionField(), kSpecialCondition);
    404     CHECK_EQ(TypeField(), 7);
    405     return ((Bit(24) == 0) && (Bits(9, 3) == 5));
    406     // Bit(4) == 0: Data Processing
    407     // Bit(4) == 1: 8, 16, or 32-bit Transfer between ARM Core and VFP
    408   }
    409 
    410   // Test for VFP 64-bit transfer instructions of type 6.
    411   inline bool IsVFPDoubleTransfer() const {
    412     CHECK_NE(ConditionField(), kSpecialCondition);
    413     CHECK_EQ(TypeField(), 6);
    414     return ((Bits(21, 4) == 2) && (Bits(9, 3) == 5) &&
    415             ((Bits(4, 4) & 0xd) == 1));
    416   }
    417 
    418   // Test for VFP load and store instructions of type 6.
    419   inline bool IsVFPLoadStore() const {
    420     CHECK_NE(ConditionField(), kSpecialCondition);
    421     CHECK_EQ(TypeField(), 6);
    422     return ((Bits(20, 5) & 0x12) == 0x10) && (Bits(9, 3) == 5);
    423   }
    424 
    425   // Special accessors that test for existence of a value.
    426   inline bool HasS() const { return SField() == 1; }
    427   inline bool HasB() const { return BField() == 1; }
    428   inline bool HasW() const { return WField() == 1; }
    429   inline bool HasL() const { return LField() == 1; }
    430   inline bool HasSign() const { return SignField() == 1; }
    431   inline bool HasH() const { return HField() == 1; }
    432   inline bool HasLink() const { return LinkField() == 1; }
    433 
    434   // Instructions are read out of a code stream. The only way to get a
    435   // reference to an instruction is to convert a pointer. There is no way
    436   // to allocate or create instances of class Instr.
    437   // Use the At(pc) function to create references to Instr.
    438   static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
    439   Instr* Next() { return this + kInstrSize; }
    440 
    441  private:
    442   // We need to prevent the creation of instances of class Instr.
    443   DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
    444 };
    445 
    446 }  // namespace arm
    447 }  // namespace art
    448 
    449 #endif  // ART_COMPILER_UTILS_ARM_CONSTANTS_ARM_H_
    450