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 |