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. InstructionBits()209 inline instr_t InstructionBits() const { 210 return *reinterpret_cast<const instr_t*>(this); 211 } 212 213 // Set the raw instruction bits to value. SetInstructionBits(instr_t 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. Bit(int nr)219 inline int Bit(int nr) const { 220 return (InstructionBits() >> nr) & 1; 221 } 222 223 // Read a bit field out of the instruction bits. Bits(int hi,int lo)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 ConditionField()232 inline Condition ConditionField() const { 233 return static_cast<Condition>(Bits(31, 28)); 234 } TypeField()235 inline int TypeField() const { return Bits(27, 25); } 236 RnField()237 inline int RnField() const { return Bits(19, 16); } RdField()238 inline int RdField() const { return Bits(15, 12); } 239 CoprocessorField()240 inline int CoprocessorField() const { return Bits(11, 8); } 241 // Support for VFP. 242 // Vn(19-16) | Vd(15-12) | Vm(3-0) VnField()243 inline int VnField() const { return Bits(19, 16); } VmField()244 inline int VmField() const { return Bits(3, 0); } VdField()245 inline int VdField() const { return Bits(15, 12); } NField()246 inline int NField() const { return Bit(7); } MField()247 inline int MField() const { return Bit(5); } DField()248 inline int DField() const { return Bit(22); } RtField()249 inline int RtField() const { return Bits(15, 12); } PField()250 inline int PField() const { return Bit(24); } UField()251 inline int UField() const { return Bit(23); } 252 253 // Fields used in Data processing instructions OpcodeField()254 inline Opcode OpcodeField() const { 255 return static_cast<Opcode>(Bits(24, 21)); 256 } SField()257 inline int SField() const { return Bit(20); } 258 // with register RmField()259 inline int RmField() const { return Bits(3, 0); } ShiftField()260 inline Shift ShiftField() const { return static_cast<Shift>(Bits(6, 5)); } RegShiftField()261 inline int RegShiftField() const { return Bit(4); } RsField()262 inline int RsField() const { return Bits(11, 8); } ShiftAmountField()263 inline int ShiftAmountField() const { return Bits(11, 7); } 264 // with immediate RotateField()265 inline int RotateField() const { return Bits(11, 8); } Immed8Field()266 inline int Immed8Field() const { return Bits(7, 0); } 267 268 // Fields used in Load/Store instructions PUField()269 inline int PUField() const { return Bits(24, 23); } BField()270 inline int BField() const { return Bit(22); } WField()271 inline int WField() const { return Bit(21); } LField()272 inline int LField() const { return Bit(20); } 273 // with register uses same fields as Data processing instructions above 274 // with immediate Offset12Field()275 inline int Offset12Field() const { return Bits(11, 0); } 276 // multiple RlistField()277 inline int RlistField() const { return Bits(15, 0); } 278 // extra loads and stores SignField()279 inline int SignField() const { return Bit(6); } HField()280 inline int HField() const { return Bit(5); } ImmedHField()281 inline int ImmedHField() const { return Bits(11, 8); } ImmedLField()282 inline int ImmedLField() const { return Bits(3, 0); } 283 284 // Fields used in Branch instructions LinkField()285 inline int LinkField() const { return Bit(24); } SImmed24Field()286 inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); } 287 288 // Fields used in Software interrupt instructions SwiField()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). IsSpecialType0()295 inline bool IsSpecialType0() const { return (Bit(7) == 1) && (Bit(4) == 1); } 296 297 // Special accessors that test for existence of a value. HasS()298 inline bool HasS() const { return SField() == 1; } HasB()299 inline bool HasB() const { return BField() == 1; } HasW()300 inline bool HasW() const { return WField() == 1; } HasL()301 inline bool HasL() const { return LField() == 1; } HasU()302 inline bool HasU() const { return UField() == 1; } HasSign()303 inline bool HasSign() const { return SignField() == 1; } HasH()304 inline bool HasH() const { return HField() == 1; } HasLink()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. At(byte * pc)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