| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_ARM64_INSTRUCTIONS_ARM64_H_ | 5 #ifndef V8_ARM64_INSTRUCTIONS_ARM64_H_ |
| 6 #define V8_ARM64_INSTRUCTIONS_ARM64_H_ | 6 #define V8_ARM64_INSTRUCTIONS_ARM64_H_ |
| 7 | 7 |
| 8 #include "src/arm64/constants-arm64.h" | 8 #include "src/arm64/constants-arm64.h" |
| 9 #include "src/arm64/utils-arm64.h" | 9 #include "src/arm64/utils-arm64.h" |
| 10 #include "src/globals.h" | 10 #include "src/globals.h" |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 | 114 |
| 115 int32_t SignedBits(int msb, int lsb) const { | 115 int32_t SignedBits(int msb, int lsb) const { |
| 116 int32_t bits = *(reinterpret_cast<const int32_t*>(this)); | 116 int32_t bits = *(reinterpret_cast<const int32_t*>(this)); |
| 117 return signed_bitextract_32(msb, lsb, bits); | 117 return signed_bitextract_32(msb, lsb, bits); |
| 118 } | 118 } |
| 119 | 119 |
| 120 Instr Mask(uint32_t mask) const { | 120 Instr Mask(uint32_t mask) const { |
| 121 return InstructionBits() & mask; | 121 return InstructionBits() & mask; |
| 122 } | 122 } |
| 123 | 123 |
| 124 V8_INLINE const Instruction* following(int count = 1) const { |
| 125 return InstructionAtOffset(count * static_cast<int>(kInstructionSize)); |
| 126 } |
| 127 |
| 124 V8_INLINE Instruction* following(int count = 1) { | 128 V8_INLINE Instruction* following(int count = 1) { |
| 125 return InstructionAtOffset(count * static_cast<int>(kInstructionSize)); | 129 return InstructionAtOffset(count * static_cast<int>(kInstructionSize)); |
| 126 } | 130 } |
| 127 | 131 |
| 132 V8_INLINE const Instruction* preceding(int count = 1) const { |
| 133 return following(-count); |
| 134 } |
| 135 |
| 128 V8_INLINE Instruction* preceding(int count = 1) { | 136 V8_INLINE Instruction* preceding(int count = 1) { |
| 129 return following(-count); | 137 return following(-count); |
| 130 } | 138 } |
| 131 | 139 |
| 132 #define DEFINE_GETTER(Name, HighBit, LowBit, Func) \ | 140 #define DEFINE_GETTER(Name, HighBit, LowBit, Func) \ |
| 133 int64_t Name() const { return Func(HighBit, LowBit); } | 141 int64_t Name() const { return Func(HighBit, LowBit); } |
| 134 INSTRUCTION_FIELDS_LIST(DEFINE_GETTER) | 142 INSTRUCTION_FIELDS_LIST(DEFINE_GETTER) |
| 135 #undef DEFINE_GETTER | 143 #undef DEFINE_GETTER |
| 136 | 144 |
| 137 // ImmPCRel is a compound field (not present in INSTRUCTION_FIELDS_LIST), | 145 // ImmPCRel is a compound field (not present in INSTRUCTION_FIELDS_LIST), |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 } | 190 } |
| 183 | 191 |
| 184 bool IsPCRelAddressing() const { | 192 bool IsPCRelAddressing() const { |
| 185 return Mask(PCRelAddressingFMask) == PCRelAddressingFixed; | 193 return Mask(PCRelAddressingFMask) == PCRelAddressingFixed; |
| 186 } | 194 } |
| 187 | 195 |
| 188 bool IsAdr() const { | 196 bool IsAdr() const { |
| 189 return Mask(PCRelAddressingMask) == ADR; | 197 return Mask(PCRelAddressingMask) == ADR; |
| 190 } | 198 } |
| 191 | 199 |
| 200 bool IsBrk() const { return Mask(ExceptionMask) == BRK; } |
| 201 |
| 202 bool IsUnresolvedInternalReference() const { |
| 203 // Unresolved internal references are encoded as two consecutive brk |
| 204 // instructions. |
| 205 return IsBrk() && following()->IsBrk(); |
| 206 } |
| 207 |
| 192 bool IsLogicalImmediate() const { | 208 bool IsLogicalImmediate() const { |
| 193 return Mask(LogicalImmediateFMask) == LogicalImmediateFixed; | 209 return Mask(LogicalImmediateFMask) == LogicalImmediateFixed; |
| 194 } | 210 } |
| 195 | 211 |
| 196 bool IsAddSubImmediate() const { | 212 bool IsAddSubImmediate() const { |
| 197 return Mask(AddSubImmediateFMask) == AddSubImmediateFixed; | 213 return Mask(AddSubImmediateFMask) == AddSubImmediateFixed; |
| 198 } | 214 } |
| 199 | 215 |
| 200 bool IsAddSubShifted() const { | 216 bool IsAddSubShifted() const { |
| 201 return Mask(AddSubShiftedFMask) == AddSubShiftedFixed; | 217 return Mask(AddSubShiftedFMask) == AddSubShiftedFixed; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 switch (BranchType()) { | 315 switch (BranchType()) { |
| 300 case CondBranchType: return ImmCondBranch(); | 316 case CondBranchType: return ImmCondBranch(); |
| 301 case UncondBranchType: return ImmUncondBranch(); | 317 case UncondBranchType: return ImmUncondBranch(); |
| 302 case CompareBranchType: return ImmCmpBranch(); | 318 case CompareBranchType: return ImmCmpBranch(); |
| 303 case TestBranchType: return ImmTestBranch(); | 319 case TestBranchType: return ImmTestBranch(); |
| 304 default: UNREACHABLE(); | 320 default: UNREACHABLE(); |
| 305 } | 321 } |
| 306 return 0; | 322 return 0; |
| 307 } | 323 } |
| 308 | 324 |
| 325 int ImmUnresolvedInternalReference() const { |
| 326 DCHECK(IsUnresolvedInternalReference()); |
| 327 // Unresolved references are encoded as two consecutive brk instructions. |
| 328 // The associated immediate is made of the two 16-bit payloads. |
| 329 int32_t high16 = ImmException(); |
| 330 int32_t low16 = following()->ImmException(); |
| 331 return (high16 << 16) | low16; |
| 332 } |
| 333 |
| 309 bool IsBranchAndLinkToRegister() const { | 334 bool IsBranchAndLinkToRegister() const { |
| 310 return Mask(UnconditionalBranchToRegisterMask) == BLR; | 335 return Mask(UnconditionalBranchToRegisterMask) == BLR; |
| 311 } | 336 } |
| 312 | 337 |
| 313 bool IsMovz() const { | 338 bool IsMovz() const { |
| 314 return (Mask(MoveWideImmediateMask) == MOVZ_x) || | 339 return (Mask(MoveWideImmediateMask) == MOVZ_x) || |
| 315 (Mask(MoveWideImmediateMask) == MOVZ_w); | 340 (Mask(MoveWideImmediateMask) == MOVZ_w); |
| 316 } | 341 } |
| 317 | 342 |
| 318 bool IsMovk() const { | 343 bool IsMovk() const { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 342 | 367 |
| 343 // Find the target of this instruction. 'this' may be a branch or a | 368 // Find the target of this instruction. 'this' may be a branch or a |
| 344 // PC-relative addressing instruction. | 369 // PC-relative addressing instruction. |
| 345 Instruction* ImmPCOffsetTarget(); | 370 Instruction* ImmPCOffsetTarget(); |
| 346 | 371 |
| 347 static bool IsValidImmPCOffset(ImmBranchType branch_type, int32_t offset); | 372 static bool IsValidImmPCOffset(ImmBranchType branch_type, int32_t offset); |
| 348 bool IsTargetInImmPCOffsetRange(Instruction* target); | 373 bool IsTargetInImmPCOffsetRange(Instruction* target); |
| 349 // Patch a PC-relative offset to refer to 'target'. 'this' may be a branch or | 374 // Patch a PC-relative offset to refer to 'target'. 'this' may be a branch or |
| 350 // a PC-relative addressing instruction. | 375 // a PC-relative addressing instruction. |
| 351 void SetImmPCOffsetTarget(Instruction* target); | 376 void SetImmPCOffsetTarget(Instruction* target); |
| 377 void SetUnresolvedInternalReferenceImmTarget(Instruction* target); |
| 352 // Patch a literal load instruction to load from 'source'. | 378 // Patch a literal load instruction to load from 'source'. |
| 353 void SetImmLLiteral(Instruction* source); | 379 void SetImmLLiteral(Instruction* source); |
| 354 | 380 |
| 355 uintptr_t LiteralAddress() { | 381 uintptr_t LiteralAddress() { |
| 356 int offset = ImmLLiteral() << kLoadLiteralScaleLog2; | 382 int offset = ImmLLiteral() << kLoadLiteralScaleLog2; |
| 357 return reinterpret_cast<uintptr_t>(this) + offset; | 383 return reinterpret_cast<uintptr_t>(this) + offset; |
| 358 } | 384 } |
| 359 | 385 |
| 360 enum CheckAlignment { NO_CHECK, CHECK_ALIGNMENT }; | 386 enum CheckAlignment { NO_CHECK, CHECK_ALIGNMENT }; |
| 361 | 387 |
| 388 V8_INLINE const Instruction* InstructionAtOffset( |
| 389 int64_t offset, CheckAlignment check = CHECK_ALIGNMENT) const { |
| 390 // The FUZZ_disasm test relies on no check being done. |
| 391 DCHECK(check == NO_CHECK || IsAligned(offset, kInstructionSize)); |
| 392 return this + offset; |
| 393 } |
| 394 |
| 362 V8_INLINE Instruction* InstructionAtOffset( | 395 V8_INLINE Instruction* InstructionAtOffset( |
| 363 int64_t offset, | 396 int64_t offset, CheckAlignment check = CHECK_ALIGNMENT) { |
| 364 CheckAlignment check = CHECK_ALIGNMENT) { | |
| 365 Address addr = reinterpret_cast<Address>(this) + offset; | |
| 366 // The FUZZ_disasm test relies on no check being done. | 397 // The FUZZ_disasm test relies on no check being done. |
| 367 DCHECK(check == NO_CHECK || IsAddressAligned(addr, kInstructionSize)); | 398 DCHECK(check == NO_CHECK || IsAligned(offset, kInstructionSize)); |
| 368 return Cast(addr); | 399 return this + offset; |
| 369 } | 400 } |
| 370 | 401 |
| 371 template<typename T> V8_INLINE static Instruction* Cast(T src) { | 402 template<typename T> V8_INLINE static Instruction* Cast(T src) { |
| 372 return reinterpret_cast<Instruction*>(src); | 403 return reinterpret_cast<Instruction*>(src); |
| 373 } | 404 } |
| 374 | 405 |
| 375 V8_INLINE ptrdiff_t DistanceTo(Instruction* target) { | 406 V8_INLINE ptrdiff_t DistanceTo(Instruction* target) { |
| 376 return reinterpret_cast<Address>(target) - reinterpret_cast<Address>(this); | 407 return reinterpret_cast<Address>(target) - reinterpret_cast<Address>(this); |
| 377 } | 408 } |
| 378 | 409 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 TRACE_ENABLE = 1 << 6, | 531 TRACE_ENABLE = 1 << 6, |
| 501 TRACE_DISABLE = 2 << 6, | 532 TRACE_DISABLE = 2 << 6, |
| 502 TRACE_OVERRIDE = 3 << 6 | 533 TRACE_OVERRIDE = 3 << 6 |
| 503 }; | 534 }; |
| 504 | 535 |
| 505 | 536 |
| 506 } } // namespace v8::internal | 537 } } // namespace v8::internal |
| 507 | 538 |
| 508 | 539 |
| 509 #endif // V8_ARM64_INSTRUCTIONS_ARM64_H_ | 540 #endif // V8_ARM64_INSTRUCTIONS_ARM64_H_ |
| OLD | NEW |