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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 } | 86 } |
87 return result; | 87 return result; |
88 } | 88 } |
89 | 89 |
90 | 90 |
91 // Logical immediates can't encode zero, so a return value of zero is used to | 91 // Logical immediates can't encode zero, so a return value of zero is used to |
92 // indicate a failure case. Specifically, where the constraints on imm_s are not | 92 // indicate a failure case. Specifically, where the constraints on imm_s are not |
93 // met. | 93 // met. |
94 uint64_t Instruction::ImmLogical() { | 94 uint64_t Instruction::ImmLogical() { |
95 unsigned reg_size = SixtyFourBits() ? kXRegSizeInBits : kWRegSizeInBits; | 95 unsigned reg_size = SixtyFourBits() ? kXRegSizeInBits : kWRegSizeInBits; |
96 int64_t n = BitN(); | 96 int32_t n = BitN(); |
97 int64_t imm_s = ImmSetBits(); | 97 int32_t imm_s = ImmSetBits(); |
98 int64_t imm_r = ImmRotate(); | 98 int32_t imm_r = ImmRotate(); |
99 | 99 |
100 // An integer is constructed from the n, imm_s and imm_r bits according to | 100 // An integer is constructed from the n, imm_s and imm_r bits according to |
101 // the following table: | 101 // the following table: |
102 // | 102 // |
103 // N imms immr size S R | 103 // N imms immr size S R |
104 // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr) | 104 // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr) |
105 // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr) | 105 // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr) |
106 // 0 10ssss xxrrrr 16 UInt(ssss) UInt(rrrr) | 106 // 0 10ssss xxrrrr 16 UInt(ssss) UInt(rrrr) |
107 // 0 110sss xxxrrr 8 UInt(sss) UInt(rrr) | 107 // 0 110sss xxxrrr 8 UInt(sss) UInt(rrr) |
108 // 0 1110ss xxxxrr 4 UInt(ss) UInt(rr) | 108 // 0 1110ss xxxxrr 4 UInt(ss) UInt(rr) |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 return offset; | 204 return offset; |
205 } | 205 } |
206 | 206 |
207 | 207 |
208 Instruction* Instruction::ImmPCOffsetTarget() { | 208 Instruction* Instruction::ImmPCOffsetTarget() { |
209 return InstructionAtOffset(ImmPCOffset()); | 209 return InstructionAtOffset(ImmPCOffset()); |
210 } | 210 } |
211 | 211 |
212 | 212 |
213 bool Instruction::IsValidImmPCOffset(ImmBranchType branch_type, | 213 bool Instruction::IsValidImmPCOffset(ImmBranchType branch_type, |
214 int32_t offset) { | 214 ptrdiff_t offset) { |
215 return is_intn(offset, ImmBranchRangeBitwidth(branch_type)); | 215 return is_intn(offset, ImmBranchRangeBitwidth(branch_type)); |
216 } | 216 } |
217 | 217 |
218 | 218 |
219 bool Instruction::IsTargetInImmPCOffsetRange(Instruction* target) { | 219 bool Instruction::IsTargetInImmPCOffsetRange(Instruction* target) { |
220 return IsValidImmPCOffset(BranchType(), DistanceTo(target)); | 220 return IsValidImmPCOffset(BranchType(), DistanceTo(target)); |
221 } | 221 } |
222 | 222 |
223 | 223 |
224 void Instruction::SetImmPCOffsetTarget(Instruction* target) { | 224 void Instruction::SetImmPCOffsetTarget(Instruction* target) { |
(...skipping 10 matching lines...) Expand all Loading... |
235 } | 235 } |
236 | 236 |
237 | 237 |
238 void Instruction::SetPCRelImmTarget(Instruction* target) { | 238 void Instruction::SetPCRelImmTarget(Instruction* target) { |
239 // 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. |
240 DCHECK(IsAdr()); | 240 DCHECK(IsAdr()); |
241 | 241 |
242 ptrdiff_t target_offset = DistanceTo(target); | 242 ptrdiff_t target_offset = DistanceTo(target); |
243 Instr imm; | 243 Instr imm; |
244 if (Instruction::IsValidPCRelOffset(target_offset)) { | 244 if (Instruction::IsValidPCRelOffset(target_offset)) { |
245 imm = Assembler::ImmPCRelAddress(target_offset); | 245 imm = Assembler::ImmPCRelAddress(static_cast<int>(target_offset)); |
246 SetInstructionBits(Mask(~ImmPCRel_mask) | imm); | 246 SetInstructionBits(Mask(~ImmPCRel_mask) | imm); |
247 } else { | 247 } else { |
248 PatchingAssembler patcher(this, | 248 PatchingAssembler patcher(this, |
249 PatchingAssembler::kAdrFarPatchableNInstrs); | 249 PatchingAssembler::kAdrFarPatchableNInstrs); |
250 patcher.PatchAdrFar(target_offset); | 250 patcher.PatchAdrFar(target_offset); |
251 } | 251 } |
252 } | 252 } |
253 | 253 |
254 | 254 |
255 void Instruction::SetBranchImmTarget(Instruction* target) { | 255 void Instruction::SetBranchImmTarget(Instruction* target) { |
256 DCHECK(IsAligned(DistanceTo(target), kInstructionSize)); | 256 DCHECK(IsAligned(DistanceTo(target), kInstructionSize)); |
| 257 DCHECK(IsValidImmPCOffset(BranchType(), |
| 258 DistanceTo(target) >> kInstructionSizeLog2)); |
| 259 int offset = static_cast<int>(DistanceTo(target) >> kInstructionSizeLog2); |
257 Instr branch_imm = 0; | 260 Instr branch_imm = 0; |
258 uint32_t imm_mask = 0; | 261 uint32_t imm_mask = 0; |
259 ptrdiff_t offset = DistanceTo(target) >> kInstructionSizeLog2; | |
260 switch (BranchType()) { | 262 switch (BranchType()) { |
261 case CondBranchType: { | 263 case CondBranchType: { |
262 branch_imm = Assembler::ImmCondBranch(offset); | 264 branch_imm = Assembler::ImmCondBranch(offset); |
263 imm_mask = ImmCondBranch_mask; | 265 imm_mask = ImmCondBranch_mask; |
264 break; | 266 break; |
265 } | 267 } |
266 case UncondBranchType: { | 268 case UncondBranchType: { |
267 branch_imm = Assembler::ImmUncondBranch(offset); | 269 branch_imm = Assembler::ImmUncondBranch(offset); |
268 imm_mask = ImmUncondBranch_mask; | 270 imm_mask = ImmUncondBranch_mask; |
269 break; | 271 break; |
(...skipping 10 matching lines...) Expand all Loading... |
280 } | 282 } |
281 default: UNREACHABLE(); | 283 default: UNREACHABLE(); |
282 } | 284 } |
283 SetInstructionBits(Mask(~imm_mask) | branch_imm); | 285 SetInstructionBits(Mask(~imm_mask) | branch_imm); |
284 } | 286 } |
285 | 287 |
286 | 288 |
287 void Instruction::SetUnresolvedInternalReferenceImmTarget(Instruction* target) { | 289 void Instruction::SetUnresolvedInternalReferenceImmTarget(Instruction* target) { |
288 DCHECK(IsUnresolvedInternalReference()); | 290 DCHECK(IsUnresolvedInternalReference()); |
289 DCHECK(IsAligned(DistanceTo(target), kInstructionSize)); | 291 DCHECK(IsAligned(DistanceTo(target), kInstructionSize)); |
290 | 292 DCHECK(is_int32(DistanceTo(target) >> kInstructionSizeLog2)); |
291 ptrdiff_t target_offset = DistanceTo(target) >> kInstructionSizeLog2; | 293 int32_t target_offset = |
292 DCHECK(is_int32(target_offset)); | 294 static_cast<int32_t>(DistanceTo(target) >> kInstructionSizeLog2); |
293 uint32_t high16 = unsigned_bitextract_32(31, 16, target_offset); | 295 uint32_t high16 = unsigned_bitextract_32(31, 16, target_offset); |
294 uint32_t low16 = unsigned_bitextract_32(15, 0, target_offset); | 296 uint32_t low16 = unsigned_bitextract_32(15, 0, target_offset); |
295 | 297 |
296 PatchingAssembler patcher(this, 2); | 298 PatchingAssembler patcher(this, 2); |
297 patcher.brk(high16); | 299 patcher.brk(high16); |
298 patcher.brk(low16); | 300 patcher.brk(low16); |
299 } | 301 } |
300 | 302 |
301 | 303 |
302 void Instruction::SetImmLLiteral(Instruction* source) { | 304 void Instruction::SetImmLLiteral(Instruction* source) { |
303 DCHECK(IsLdrLiteral()); | 305 DCHECK(IsLdrLiteral()); |
304 DCHECK(IsAligned(DistanceTo(source), kInstructionSize)); | 306 DCHECK(IsAligned(DistanceTo(source), kInstructionSize)); |
305 ptrdiff_t offset = DistanceTo(source) >> kLoadLiteralScaleLog2; | 307 DCHECK(Assembler::IsImmLLiteral(DistanceTo(source))); |
306 Instr imm = Assembler::ImmLLiteral(offset); | 308 Instr imm = Assembler::ImmLLiteral( |
| 309 static_cast<int>(DistanceTo(source) >> kLoadLiteralScaleLog2)); |
307 Instr mask = ImmLLiteral_mask; | 310 Instr mask = ImmLLiteral_mask; |
308 | 311 |
309 SetInstructionBits(Mask(~mask) | imm); | 312 SetInstructionBits(Mask(~mask) | imm); |
310 } | 313 } |
311 | 314 |
312 | 315 |
313 // TODO(jbramley): We can't put this inline in the class because things like | 316 // TODO(jbramley): We can't put this inline in the class because things like |
314 // xzr and Register are not defined in that header. Consider adding | 317 // xzr and Register are not defined in that header. Consider adding |
315 // instructions-arm64-inl.h to work around this. | 318 // instructions-arm64-inl.h to work around this. |
316 bool InstructionSequence::IsInlineData() const { | 319 bool InstructionSequence::IsInlineData() const { |
(...skipping 13 matching lines...) Expand all Loading... |
330 uint64_t payload = ImmMoveWide(); | 333 uint64_t payload = ImmMoveWide(); |
331 // TODO(all): If we extend ::InlineData() to support bigger data, we need | 334 // TODO(all): If we extend ::InlineData() to support bigger data, we need |
332 // to update this method too. | 335 // to update this method too. |
333 return payload; | 336 return payload; |
334 } | 337 } |
335 | 338 |
336 | 339 |
337 } } // namespace v8::internal | 340 } } // namespace v8::internal |
338 | 341 |
339 #endif // V8_TARGET_ARCH_ARM64 | 342 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |