| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #define ARM64_DEFINE_FP_STATICS | 9 #define ARM64_DEFINE_FP_STATICS |
| 10 | 10 |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 | 184 |
| 185 int64_t Instruction::ImmPCOffset() { | 185 int64_t Instruction::ImmPCOffset() { |
| 186 int64_t offset; | 186 int64_t offset; |
| 187 if (IsPCRelAddressing()) { | 187 if (IsPCRelAddressing()) { |
| 188 // PC-relative addressing. Only ADR is supported. | 188 // PC-relative addressing. Only ADR is supported. |
| 189 offset = ImmPCRel(); | 189 offset = ImmPCRel(); |
| 190 } else if (BranchType() != UnknownBranchType) { | 190 } else if (BranchType() != UnknownBranchType) { |
| 191 // All PC-relative branches. | 191 // All PC-relative branches. |
| 192 // Relative branch offsets are instruction-size-aligned. | 192 // Relative branch offsets are instruction-size-aligned. |
| 193 offset = ImmBranch() << kInstructionSizeLog2; | 193 offset = ImmBranch() << kInstructionSizeLog2; |
| 194 } else if (IsUnresolvedInternalReference()) { |
| 195 // Internal references are always word-aligned. |
| 196 offset = ImmUnresolvedInternalReference() << kInstructionSizeLog2; |
| 194 } else { | 197 } else { |
| 195 // Load literal (offset from PC). | 198 // Load literal (offset from PC). |
| 196 DCHECK(IsLdrLiteral()); | 199 DCHECK(IsLdrLiteral()); |
| 197 // The offset is always shifted by 2 bits, even for loads to 64-bits | 200 // The offset is always shifted by 2 bits, even for loads to 64-bits |
| 198 // registers. | 201 // registers. |
| 199 offset = ImmLLiteral() << kInstructionSizeLog2; | 202 offset = ImmLLiteral() << kInstructionSizeLog2; |
| 200 } | 203 } |
| 201 return offset; | 204 return offset; |
| 202 } | 205 } |
| 203 | 206 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 216 bool Instruction::IsTargetInImmPCOffsetRange(Instruction* target) { | 219 bool Instruction::IsTargetInImmPCOffsetRange(Instruction* target) { |
| 217 return IsValidImmPCOffset(BranchType(), DistanceTo(target)); | 220 return IsValidImmPCOffset(BranchType(), DistanceTo(target)); |
| 218 } | 221 } |
| 219 | 222 |
| 220 | 223 |
| 221 void Instruction::SetImmPCOffsetTarget(Instruction* target) { | 224 void Instruction::SetImmPCOffsetTarget(Instruction* target) { |
| 222 if (IsPCRelAddressing()) { | 225 if (IsPCRelAddressing()) { |
| 223 SetPCRelImmTarget(target); | 226 SetPCRelImmTarget(target); |
| 224 } else if (BranchType() != UnknownBranchType) { | 227 } else if (BranchType() != UnknownBranchType) { |
| 225 SetBranchImmTarget(target); | 228 SetBranchImmTarget(target); |
| 229 } else if (IsUnresolvedInternalReference()) { |
| 230 SetUnresolvedInternalReferenceImmTarget(target); |
| 226 } else { | 231 } else { |
| 232 // Load literal (offset from PC). |
| 227 SetImmLLiteral(target); | 233 SetImmLLiteral(target); |
| 228 } | 234 } |
| 229 } | 235 } |
| 230 | 236 |
| 231 | 237 |
| 232 void Instruction::SetPCRelImmTarget(Instruction* target) { | 238 void Instruction::SetPCRelImmTarget(Instruction* target) { |
| 233 // ADRP is not supported, so 'this' must point to an ADR instruction. | 239 // ADRP is not supported, so 'this' must point to an ADR instruction. |
| 234 DCHECK(IsAdr()); | 240 DCHECK(IsAdr()); |
| 235 | 241 |
| 236 ptrdiff_t target_offset = DistanceTo(target); | 242 ptrdiff_t target_offset = DistanceTo(target); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 branch_imm = Assembler::ImmTestBranch(offset); | 277 branch_imm = Assembler::ImmTestBranch(offset); |
| 272 imm_mask = ImmTestBranch_mask; | 278 imm_mask = ImmTestBranch_mask; |
| 273 break; | 279 break; |
| 274 } | 280 } |
| 275 default: UNREACHABLE(); | 281 default: UNREACHABLE(); |
| 276 } | 282 } |
| 277 SetInstructionBits(Mask(~imm_mask) | branch_imm); | 283 SetInstructionBits(Mask(~imm_mask) | branch_imm); |
| 278 } | 284 } |
| 279 | 285 |
| 280 | 286 |
| 287 void Instruction::SetUnresolvedInternalReferenceImmTarget(Instruction* target) { |
| 288 DCHECK(IsUnresolvedInternalReference()); |
| 289 DCHECK(IsAligned(DistanceTo(target), kInstructionSize)); |
| 290 |
| 291 ptrdiff_t target_offset = DistanceTo(target) >> kInstructionSizeLog2; |
| 292 DCHECK(is_int32(target_offset)); |
| 293 uint32_t high16 = unsigned_bitextract_32(31, 16, target_offset); |
| 294 uint32_t low16 = unsigned_bitextract_32(15, 0, target_offset); |
| 295 |
| 296 PatchingAssembler patcher(this, 2); |
| 297 patcher.brk(high16); |
| 298 patcher.brk(low16); |
| 299 } |
| 300 |
| 301 |
| 281 void Instruction::SetImmLLiteral(Instruction* source) { | 302 void Instruction::SetImmLLiteral(Instruction* source) { |
| 303 DCHECK(IsLdrLiteral()); |
| 282 DCHECK(IsAligned(DistanceTo(source), kInstructionSize)); | 304 DCHECK(IsAligned(DistanceTo(source), kInstructionSize)); |
| 283 ptrdiff_t offset = DistanceTo(source) >> kLoadLiteralScaleLog2; | 305 ptrdiff_t offset = DistanceTo(source) >> kLoadLiteralScaleLog2; |
| 284 Instr imm = Assembler::ImmLLiteral(offset); | 306 Instr imm = Assembler::ImmLLiteral(offset); |
| 285 Instr mask = ImmLLiteral_mask; | 307 Instr mask = ImmLLiteral_mask; |
| 286 | 308 |
| 287 SetInstructionBits(Mask(~mask) | imm); | 309 SetInstructionBits(Mask(~mask) | imm); |
| 288 } | 310 } |
| 289 | 311 |
| 290 | 312 |
| 291 // TODO(jbramley): We can't put this inline in the class because things like | 313 // TODO(jbramley): We can't put this inline in the class because things like |
| (...skipping 16 matching lines...) Expand all Loading... |
| 308 uint64_t payload = ImmMoveWide(); | 330 uint64_t payload = ImmMoveWide(); |
| 309 // TODO(all): If we extend ::InlineData() to support bigger data, we need | 331 // TODO(all): If we extend ::InlineData() to support bigger data, we need |
| 310 // to update this method too. | 332 // to update this method too. |
| 311 return payload; | 333 return payload; |
| 312 } | 334 } |
| 313 | 335 |
| 314 | 336 |
| 315 } } // namespace v8::internal | 337 } } // namespace v8::internal |
| 316 | 338 |
| 317 #endif // V8_TARGET_ARCH_ARM64 | 339 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |