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 IsBreakPoint()240 bool IsBreakPoint() { 241 return IsBkpt(); 242 } 243 244 // Get the raw instruction bits. InstructionBits()245 inline int32_t InstructionBits() const { 246 return *reinterpret_cast<const int32_t*>(this); 247 } 248 249 // Set the raw instruction bits to value. SetInstructionBits(int32_t 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. Bit(int nr)255 inline int Bit(int nr) const { 256 return (InstructionBits() >> nr) & 1; 257 } 258 259 // Read a bit field out of the instruction bits. Bits(int shift,int count)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 ConditionField()268 inline Condition ConditionField() const { 269 return static_cast<Condition>(Bits(kConditionShift, kConditionBits)); 270 } TypeField()271 inline int TypeField() const { return Bits(kTypeShift, kTypeBits); } 272 RnField()273 inline Register RnField() const { return static_cast<Register>( 274 Bits(kRnShift, kRnBits)); } RdField()275 inline Register RdField() const { return static_cast<Register>( 276 Bits(kRdShift, kRdBits)); } 277 278 // Fields used in Data processing instructions OpcodeField()279 inline Opcode OpcodeField() const { 280 return static_cast<Opcode>(Bits(kOpcodeShift, kOpcodeBits)); 281 } SField()282 inline int SField() const { return Bits(kSShift, kSBits); } 283 // with register RmField()284 inline Register RmField() const { 285 return static_cast<Register>(Bits(kRmShift, kRmBits)); 286 } ShiftField()287 inline Shift ShiftField() const { return static_cast<Shift>( 288 Bits(kShiftShift, kShiftBits)); } RegShiftField()289 inline int RegShiftField() const { return Bit(4); } RsField()290 inline Register RsField() const { 291 return static_cast<Register>(Bits(kRsShift, kRsBits)); 292 } ShiftAmountField()293 inline int ShiftAmountField() const { return Bits(kShiftImmShift, 294 kShiftImmBits); } 295 // with immediate RotateField()296 inline int RotateField() const { return Bits(kRotateShift, kRotateBits); } Immed8Field()297 inline int Immed8Field() const { return Bits(kImmed8Shift, kImmed8Bits); } 298 299 // Fields used in Load/Store instructions PUField()300 inline int PUField() const { return Bits(23, 2); } BField()301 inline int BField() const { return Bit(22); } WField()302 inline int WField() const { return Bit(21); } LField()303 inline int LField() const { return Bit(20); } 304 // with register uses same fields as Data processing instructions above 305 // with immediate Offset12Field()306 inline int Offset12Field() const { return Bits(kOffset12Shift, 307 kOffset12Bits); } 308 // multiple RlistField()309 inline int RlistField() const { return Bits(0, 16); } 310 // extra loads and stores SignField()311 inline int SignField() const { return Bit(6); } HField()312 inline int HField() const { return Bit(5); } ImmedHField()313 inline int ImmedHField() const { return Bits(8, 4); } ImmedLField()314 inline int ImmedLField() const { return Bits(0, 4); } 315 316 // Fields used in Branch instructions LinkField()317 inline int LinkField() const { return Bits(kLinkShift, kLinkBits); } SImmed24Field()318 inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); } 319 320 // Fields used in Supervisor Call instructions SvcField()321 inline uint32_t SvcField() const { return Bits(0, 24); } 322 323 // Field used in Breakpoint instruction BkptField()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 MovwField()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 ImmFloatField()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 ImmDoubleField()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". IsDataProcessing()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. IsMiscellaneous()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 } IsMultiplyOrSyncPrimitive()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. IsSvc()372 inline bool IsSvc() const { 373 return ((InstructionBits() & 0xff000000) == 0xef000000); 374 } 375 376 // Test for Breakpoint instruction. IsBkpt()377 inline bool IsBkpt() const { 378 return ((InstructionBits() & 0xfff000f0) == 0xe1200070); 379 } 380 381 // VFP register fields. SnField()382 inline SRegister SnField() const { 383 return static_cast<SRegister>((Bits(kRnShift, kRnBits) << 1) + Bit(7)); 384 } SdField()385 inline SRegister SdField() const { 386 return static_cast<SRegister>((Bits(kRdShift, kRdBits) << 1) + Bit(22)); 387 } SmField()388 inline SRegister SmField() const { 389 return static_cast<SRegister>((Bits(kRmShift, kRmBits) << 1) + Bit(5)); 390 } DnField()391 inline DRegister DnField() const { 392 return static_cast<DRegister>(Bits(kRnShift, kRnBits) + (Bit(7) << 4)); 393 } DdField()394 inline DRegister DdField() const { 395 return static_cast<DRegister>(Bits(kRdShift, kRdBits) + (Bit(22) << 4)); 396 } DmField()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. IsVFPDataProcessingOrSingleTransfer()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. IsVFPDoubleTransfer()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. IsVFPLoadStore()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. HasS()426 inline bool HasS() const { return SField() == 1; } HasB()427 inline bool HasB() const { return BField() == 1; } HasW()428 inline bool HasW() const { return WField() == 1; } HasL()429 inline bool HasL() const { return LField() == 1; } HasSign()430 inline bool HasSign() const { return SignField() == 1; } HasH()431 inline bool HasH() const { return HField() == 1; } HasLink()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. At(uword pc)438 static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); } Next()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