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