OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_CONSTANTS_ARM_H_ | 5 #ifndef VM_CONSTANTS_ARM_H_ |
6 #define VM_CONSTANTS_ARM_H_ | 6 #define VM_CONSTANTS_ARM_H_ |
7 | 7 |
8 namespace dart { | 8 namespace dart { |
9 | 9 |
10 // We support both VFPv3-D16 and VFPv3-D32 profiles, but currently only one at | 10 // We support both VFPv3-D16 and VFPv3-D32 profiles, but currently only one at |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 const int kNumberOfFpuRegisters = kNumberOfDRegisters; | 131 const int kNumberOfFpuRegisters = kNumberOfDRegisters; |
132 | 132 |
133 | 133 |
134 // Register aliases. | 134 // Register aliases. |
135 const Register TMP = kNoRegister; // No scratch register used by assembler. | 135 const Register TMP = kNoRegister; // No scratch register used by assembler. |
136 const Register CTX = R9; // Caches current context in generated code. | 136 const Register CTX = R9; // Caches current context in generated code. |
137 const Register SPREG = SP; | 137 const Register SPREG = SP; |
138 const Register FPREG = FP; | 138 const Register FPREG = FP; |
139 | 139 |
140 | 140 |
| 141 // Exception object is passed in this register to the catch handlers when an |
| 142 // exception is thrown. |
| 143 const Register kExceptionObjectReg = R0; // Unimplemented. |
| 144 |
| 145 |
141 // Values for the condition field as defined in section A3.2. | 146 // Values for the condition field as defined in section A3.2. |
142 enum Condition { | 147 enum Condition { |
143 kNoCondition = -1, | 148 kNoCondition = -1, |
144 EQ = 0, // equal | 149 EQ = 0, // equal |
145 NE = 1, // not equal | 150 NE = 1, // not equal |
146 CS = 2, // carry set/unsigned higher or same | 151 CS = 2, // carry set/unsigned higher or same |
147 CC = 3, // carry clear/unsigned lower | 152 CC = 3, // carry clear/unsigned lower |
148 MI = 4, // minus/negative | 153 MI = 4, // minus/negative |
149 PL = 5, // plus/positive or zero | 154 PL = 5, // plus/positive or zero |
150 VS = 6, // overflow | 155 VS = 6, // overflow |
151 VC = 7, // no overflow | 156 VC = 7, // no overflow |
152 HI = 8, // unsigned higher | 157 HI = 8, // unsigned higher |
153 LS = 9, // unsigned lower or same | 158 LS = 9, // unsigned lower or same |
154 GE = 10, // signed greater than or equal | 159 GE = 10, // signed greater than or equal |
155 LT = 11, // signed less than | 160 LT = 11, // signed less than |
156 GT = 12, // signed greater than | 161 GT = 12, // signed greater than |
157 LE = 13, // signed less than or equal | 162 LE = 13, // signed less than or equal |
158 AL = 14, // always (unconditional) | 163 AL = 14, // always (unconditional) |
159 kSpecialCondition = 15, // special condition (refer to section A3.2.1) | 164 kSpecialCondition = 15, // special condition (refer to section A3.2.1) |
160 kMaxCondition = 16, | 165 kMaxCondition = 16, |
161 }; | 166 }; |
162 | 167 |
| 168 |
| 169 // Opcodes for Data-processing instructions (instructions with a type 0 and 1) |
| 170 // as defined in section A3.4 |
| 171 enum Opcode { |
| 172 kNoOperand = -1, |
| 173 AND = 0, // Logical AND |
| 174 EOR = 1, // Logical Exclusive OR |
| 175 SUB = 2, // Subtract |
| 176 RSB = 3, // Reverse Subtract |
| 177 ADD = 4, // Add |
| 178 ADC = 5, // Add with Carry |
| 179 SBC = 6, // Subtract with Carry |
| 180 RSC = 7, // Reverse Subtract with Carry |
| 181 TST = 8, // Test |
| 182 TEQ = 9, // Test Equivalence |
| 183 CMP = 10, // Compare |
| 184 CMN = 11, // Compare Negated |
| 185 ORR = 12, // Logical (inclusive) OR |
| 186 MOV = 13, // Move |
| 187 BIC = 14, // Bit Clear |
| 188 MVN = 15, // Move Not |
| 189 kMaxOperand = 16 |
| 190 }; |
| 191 |
| 192 |
| 193 // Shifter types for Data-processing operands as defined in section A5.1.2. |
| 194 enum Shift { |
| 195 kNoShift = -1, |
| 196 LSL = 0, // Logical shift left |
| 197 LSR = 1, // Logical shift right |
| 198 ASR = 2, // Arithmetic shift right |
| 199 ROR = 3, // Rotate right |
| 200 kMaxShift = 4 |
| 201 }; |
| 202 |
| 203 |
| 204 // Special Supervisor Call 24-bit codes used in the presence of the ARM |
| 205 // simulator for redirection, breakpoints, stop messages, and spill markers. |
| 206 // See /usr/include/asm/unistd.h |
| 207 const uint32_t kRedirectionSvcCode = 0x90001f; // unused syscall, was sys_stty |
| 208 const uint32_t kBreakpointSvcCode = 0x900020; // unused syscall, was sys_gtty |
| 209 const uint32_t kStopMessageSvcCode = 0x9f0001; // __ARM_NR_breakpoint |
| 210 const uint32_t kSpillMarkerSvcBase = 0x9f0100; // unused ARM private syscall |
| 211 const uint32_t kWordSpillMarkerSvcCode = kSpillMarkerSvcBase + 1; |
| 212 const uint32_t kDWordSpillMarkerSvcCode = kSpillMarkerSvcBase + 2; |
| 213 |
| 214 |
| 215 // Constants used for the decoding or encoding of the individual fields of |
| 216 // instructions. Based on the "Figure 3-1 ARM instruction set summary". |
| 217 enum InstructionFields { |
| 218 kConditionShift = 28, |
| 219 kConditionBits = 4, |
| 220 kTypeShift = 25, |
| 221 kTypeBits = 3, |
| 222 kLinkShift = 24, |
| 223 kLinkBits = 1, |
| 224 kUShift = 23, |
| 225 kUBits = 1, |
| 226 kOpcodeShift = 21, |
| 227 kOpcodeBits = 4, |
| 228 kSShift = 20, |
| 229 kSBits = 1, |
| 230 kRnShift = 16, |
| 231 kRnBits = 4, |
| 232 kRdShift = 12, |
| 233 kRdBits = 4, |
| 234 kRsShift = 8, |
| 235 kRsBits = 4, |
| 236 kRmShift = 0, |
| 237 kRmBits = 4, |
| 238 |
| 239 // Immediate instruction fields encoding. |
| 240 kRotateShift = 8, |
| 241 kRotateBits = 4, |
| 242 kImmed8Shift = 0, |
| 243 kImmed8Bits = 8, |
| 244 |
| 245 // Shift instruction register fields encodings. |
| 246 kShiftImmShift = 7, |
| 247 kShiftRegisterShift = 8, |
| 248 kShiftImmBits = 5, |
| 249 kShiftShift = 5, |
| 250 kShiftBits = 2, |
| 251 |
| 252 // Load/store instruction offset field encoding. |
| 253 kOffset12Shift = 0, |
| 254 kOffset12Bits = 12, |
| 255 kOffset12Mask = 0x00000fff, |
| 256 |
| 257 // Mul instruction register fields encodings. |
| 258 kMulRdShift = 16, |
| 259 kMulRdBits = 4, |
| 260 kMulRnShift = 12, |
| 261 kMulRnBits = 4, |
| 262 |
| 263 kBranchOffsetMask = 0x00ffffff |
| 264 }; |
| 265 |
| 266 |
| 267 // The class Instr enables access to individual fields defined in the ARM |
| 268 // architecture instruction set encoding as described in figure A3-1. |
| 269 // |
| 270 // Example: Test whether the instruction at ptr sets the condition code bits. |
| 271 // |
| 272 // bool InstructionSetsConditionCodes(byte* ptr) { |
| 273 // Instr* instr = Instr::At(ptr); |
| 274 // int type = instr->TypeField(); |
| 275 // return ((type == 0) || (type == 1)) && instr->HasS(); |
| 276 // } |
| 277 // |
| 278 class Instr { |
| 279 public: |
| 280 enum { |
| 281 kInstrSize = 4, |
| 282 kInstrSizeLog2 = 2, |
| 283 kPCReadOffset = 8 |
| 284 }; |
| 285 |
| 286 static const int kBreakPointInstructionSize = kInstrSize; |
| 287 bool IsBreakPoint() { |
| 288 return IsBkpt(); |
| 289 } |
| 290 |
| 291 // Get the raw instruction bits. |
| 292 inline int32_t InstructionBits() const { |
| 293 return *reinterpret_cast<const int32_t*>(this); |
| 294 } |
| 295 |
| 296 // Set the raw instruction bits to value. |
| 297 inline void SetInstructionBits(int32_t value) { |
| 298 *reinterpret_cast<int32_t*>(this) = value; |
| 299 } |
| 300 |
| 301 // Read one particular bit out of the instruction bits. |
| 302 inline int Bit(int nr) const { |
| 303 return (InstructionBits() >> nr) & 1; |
| 304 } |
| 305 |
| 306 // Read a bit field out of the instruction bits. |
| 307 inline int Bits(int shift, int count) const { |
| 308 return (InstructionBits() >> shift) & ((1 << count) - 1); |
| 309 } |
| 310 |
| 311 |
| 312 // Accessors for the different named fields used in the ARM encoding. |
| 313 // The naming of these accessor corresponds to figure A3-1. |
| 314 // Generally applicable fields |
| 315 inline Condition ConditionField() const { |
| 316 return static_cast<Condition>(Bits(kConditionShift, kConditionBits)); |
| 317 } |
| 318 inline int TypeField() const { return Bits(kTypeShift, kTypeBits); } |
| 319 |
| 320 inline Register RnField() const { return static_cast<Register>( |
| 321 Bits(kRnShift, kRnBits)); } |
| 322 inline Register RdField() const { return static_cast<Register>( |
| 323 Bits(kRdShift, kRdBits)); } |
| 324 |
| 325 // Fields used in Data processing instructions |
| 326 inline Opcode OpcodeField() const { |
| 327 return static_cast<Opcode>(Bits(kOpcodeShift, kOpcodeBits)); |
| 328 } |
| 329 inline int SField() const { return Bits(kSShift, kSBits); } |
| 330 // with register |
| 331 inline Register RmField() const { |
| 332 return static_cast<Register>(Bits(kRmShift, kRmBits)); |
| 333 } |
| 334 inline Shift ShiftField() const { return static_cast<Shift>( |
| 335 Bits(kShiftShift, kShiftBits)); } |
| 336 inline int RegShiftField() const { return Bit(4); } |
| 337 inline Register RsField() const { |
| 338 return static_cast<Register>(Bits(kRsShift, kRsBits)); |
| 339 } |
| 340 inline int ShiftAmountField() const { return Bits(kShiftImmShift, |
| 341 kShiftImmBits); } |
| 342 // with immediate |
| 343 inline int RotateField() const { return Bits(kRotateShift, kRotateBits); } |
| 344 inline int Immed8Field() const { return Bits(kImmed8Shift, kImmed8Bits); } |
| 345 |
| 346 // Fields used in Load/Store instructions |
| 347 inline int PUField() const { return Bits(23, 2); } |
| 348 inline int BField() const { return Bit(22); } |
| 349 inline int WField() const { return Bit(21); } |
| 350 inline int LField() const { return Bit(20); } |
| 351 // with register uses same fields as Data processing instructions above |
| 352 // with immediate |
| 353 inline int Offset12Field() const { return Bits(kOffset12Shift, |
| 354 kOffset12Bits); } |
| 355 // multiple |
| 356 inline int RlistField() const { return Bits(0, 16); } |
| 357 // extra loads and stores |
| 358 inline int SignField() const { return Bit(6); } |
| 359 inline int HField() const { return Bit(5); } |
| 360 inline int ImmedHField() const { return Bits(8, 4); } |
| 361 inline int ImmedLField() const { return Bits(0, 4); } |
| 362 |
| 363 // Fields used in Branch instructions |
| 364 inline int LinkField() const { return Bits(kLinkShift, kLinkBits); } |
| 365 inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); } |
| 366 |
| 367 // Fields used in Supervisor Call instructions |
| 368 inline uint32_t SvcField() const { return Bits(0, 24); } |
| 369 |
| 370 // Field used in Breakpoint instruction |
| 371 inline uint16_t BkptField() const { |
| 372 return ((Bits(8, 12) << 4) | Bits(0, 4)); |
| 373 } |
| 374 |
| 375 // Field used in 16-bit immediate move instructions |
| 376 inline uint16_t MovwField() const { |
| 377 return ((Bits(16, 4) << 12) | Bits(0, 12)); |
| 378 } |
| 379 |
| 380 // Field used in VFP float immediate move instruction |
| 381 inline float ImmFloatField() const { |
| 382 uint32_t imm32 = (Bit(19) << 31) | (((1 << 5) - Bit(18)) << 25) | |
| 383 (Bits(16, 2) << 23) | (Bits(0, 4) << 19); |
| 384 return bit_cast<float, uint32_t>(imm32); |
| 385 } |
| 386 |
| 387 // Field used in VFP double immediate move instruction |
| 388 inline double ImmDoubleField() const { |
| 389 uint64_t imm64 = (Bit(19)*(1LL << 63)) | (((1LL << 8) - Bit(18)) << 54) | |
| 390 (Bits(16, 2)*(1LL << 52)) | (Bits(0, 4)*(1LL << 48)); |
| 391 return bit_cast<double, uint64_t>(imm64); |
| 392 } |
| 393 |
| 394 // Test for data processing instructions of type 0 or 1. |
| 395 // See "ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition", |
| 396 // section A5.1 "ARM instruction set encoding". |
| 397 inline bool IsDataProcessing() const { |
| 398 ASSERT(ConditionField() != kSpecialCondition); |
| 399 ASSERT(Bits(26, 2) == 0); // Type 0 or 1. |
| 400 return ((Bits(20, 5) & 0x19) != 0x10) && |
| 401 ((Bit(25) == 1) || // Data processing immediate. |
| 402 (Bit(4) == 0) || // Data processing register. |
| 403 (Bit(7) == 0)); // Data processing register-shifted register. |
| 404 } |
| 405 |
| 406 // Tests for special encodings of type 0 instructions (extra loads and stores, |
| 407 // as well as multiplications, synchronization primitives, and miscellaneous). |
| 408 // Can only be called for a type 0 or 1 instruction. |
| 409 inline bool IsMiscellaneous() const { |
| 410 ASSERT(Bits(26, 2) == 0); // Type 0 or 1. |
| 411 return ((Bit(25) == 0) && ((Bits(20, 5) & 0x19) == 0x10) && (Bit(7) == 0)); |
| 412 } |
| 413 inline bool IsMultiplyOrSyncPrimitive() const { |
| 414 ASSERT(Bits(26, 2) == 0); // Type 0 or 1. |
| 415 return ((Bit(25) == 0) && (Bits(4, 4) == 9)); |
| 416 } |
| 417 |
| 418 // Test for Supervisor Call instruction. |
| 419 inline bool IsSvc() const { |
| 420 return ((InstructionBits() & 0xff000000) == 0xef000000); |
| 421 } |
| 422 |
| 423 // Test for Breakpoint instruction. |
| 424 inline bool IsBkpt() const { |
| 425 return ((InstructionBits() & 0xfff000f0) == 0xe1200070); |
| 426 } |
| 427 |
| 428 // VFP register fields. |
| 429 inline SRegister SnField() const { |
| 430 return static_cast<SRegister>((Bits(kRnShift, kRnBits) << 1) + Bit(7)); |
| 431 } |
| 432 inline SRegister SdField() const { |
| 433 return static_cast<SRegister>((Bits(kRdShift, kRdBits) << 1) + Bit(22)); |
| 434 } |
| 435 inline SRegister SmField() const { |
| 436 return static_cast<SRegister>((Bits(kRmShift, kRmBits) << 1) + Bit(5)); |
| 437 } |
| 438 inline DRegister DnField() const { |
| 439 return static_cast<DRegister>(Bits(kRnShift, kRnBits) + (Bit(7) << 4)); |
| 440 } |
| 441 inline DRegister DdField() const { |
| 442 return static_cast<DRegister>(Bits(kRdShift, kRdBits) + (Bit(22) << 4)); |
| 443 } |
| 444 inline DRegister DmField() const { |
| 445 return static_cast<DRegister>(Bits(kRmShift, kRmBits) + (Bit(5) << 4)); |
| 446 } |
| 447 |
| 448 // Test for VFP data processing or single transfer instructions of type 7. |
| 449 inline bool IsVFPDataProcessingOrSingleTransfer() const { |
| 450 ASSERT(ConditionField() != kSpecialCondition); |
| 451 ASSERT(TypeField() == 7); |
| 452 return ((Bit(24) == 0) && (Bits(9, 3) == 5)); |
| 453 // Bit(4) == 0: Data Processing |
| 454 // Bit(4) == 1: 8, 16, or 32-bit Transfer between ARM Core and VFP |
| 455 } |
| 456 |
| 457 // Test for VFP 64-bit transfer instructions of type 6. |
| 458 inline bool IsVFPDoubleTransfer() const { |
| 459 ASSERT(ConditionField() != kSpecialCondition); |
| 460 ASSERT(TypeField() == 6); |
| 461 return ((Bits(21, 4) == 2) && (Bits(9, 3) == 5) && |
| 462 ((Bits(4, 4) & 0xd) == 1)); |
| 463 } |
| 464 |
| 465 // Test for VFP load and store instructions of type 6. |
| 466 inline bool IsVFPLoadStore() const { |
| 467 ASSERT(ConditionField() != kSpecialCondition); |
| 468 ASSERT(TypeField() == 6); |
| 469 return ((Bits(20, 5) & 0x12) == 0x10) && (Bits(9, 3) == 5); |
| 470 } |
| 471 |
| 472 // Special accessors that test for existence of a value. |
| 473 inline bool HasS() const { return SField() == 1; } |
| 474 inline bool HasB() const { return BField() == 1; } |
| 475 inline bool HasW() const { return WField() == 1; } |
| 476 inline bool HasL() const { return LField() == 1; } |
| 477 inline bool HasSign() const { return SignField() == 1; } |
| 478 inline bool HasH() const { return HField() == 1; } |
| 479 inline bool HasLink() const { return LinkField() == 1; } |
| 480 |
| 481 // Instructions are read out of a code stream. The only way to get a |
| 482 // reference to an instruction is to convert a pointer. There is no way |
| 483 // to allocate or create instances of class Instr. |
| 484 // Use the At(pc) function to create references to Instr. |
| 485 static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); } |
| 486 Instr* Next() { return this + kInstrSize; } |
| 487 |
| 488 private: |
| 489 DISALLOW_ALLOCATION(); |
| 490 DISALLOW_IMPLICIT_CONSTRUCTORS(Instr); |
| 491 }; |
| 492 |
163 } // namespace dart | 493 } // namespace dart |
164 | 494 |
165 #endif // VM_CONSTANTS_ARM_H_ | 495 #endif // VM_CONSTANTS_ARM_H_ |
OLD | NEW |