| 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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 3646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3657 } else if (if_all_clear == fall_through) { | 3657 } else if (if_all_clear == fall_through) { |
| 3658 TestAndBranchIfAnySet(reg, bit_pattern, if_any_set); | 3658 TestAndBranchIfAnySet(reg, bit_pattern, if_any_set); |
| 3659 } else if (if_any_set == fall_through) { | 3659 } else if (if_any_set == fall_through) { |
| 3660 TestAndBranchIfAllClear(reg, bit_pattern, if_all_clear); | 3660 TestAndBranchIfAllClear(reg, bit_pattern, if_all_clear); |
| 3661 } else { | 3661 } else { |
| 3662 TestAndBranchIfAnySet(reg, bit_pattern, if_any_set); | 3662 TestAndBranchIfAnySet(reg, bit_pattern, if_any_set); |
| 3663 B(if_all_clear); | 3663 B(if_all_clear); |
| 3664 } | 3664 } |
| 3665 } | 3665 } |
| 3666 | 3666 |
| 3667 void MacroAssembler::CheckFastObjectElements(Register map, | |
| 3668 Register scratch, | |
| 3669 Label* fail) { | |
| 3670 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | |
| 3671 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | |
| 3672 STATIC_ASSERT(FAST_ELEMENTS == 2); | |
| 3673 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | |
| 3674 Ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset)); | |
| 3675 Cmp(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); | |
| 3676 // If cond==ls, set cond=hi, otherwise compare. | |
| 3677 Ccmp(scratch, | |
| 3678 Operand(Map::kMaximumBitField2FastHoleyElementValue), CFlag, hi); | |
| 3679 B(hi, fail); | |
| 3680 } | |
| 3681 | |
| 3682 | |
| 3683 // Note: The ARM version of this clobbers elements_reg, but this version does | |
| 3684 // not. Some uses of this in ARM64 assume that elements_reg will be preserved. | |
| 3685 void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, | |
| 3686 Register key_reg, | |
| 3687 Register elements_reg, | |
| 3688 Register scratch1, | |
| 3689 FPRegister fpscratch1, | |
| 3690 Label* fail, | |
| 3691 int elements_offset) { | |
| 3692 DCHECK(!AreAliased(value_reg, key_reg, elements_reg, scratch1)); | |
| 3693 Label store_num; | |
| 3694 | |
| 3695 // Speculatively convert the smi to a double - all smis can be exactly | |
| 3696 // represented as a double. | |
| 3697 SmiUntagToDouble(fpscratch1, value_reg, kSpeculativeUntag); | |
| 3698 | |
| 3699 // If value_reg is a smi, we're done. | |
| 3700 JumpIfSmi(value_reg, &store_num); | |
| 3701 | |
| 3702 // Ensure that the object is a heap number. | |
| 3703 JumpIfNotHeapNumber(value_reg, fail); | |
| 3704 | |
| 3705 Ldr(fpscratch1, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); | |
| 3706 | |
| 3707 // Canonicalize NaNs. | |
| 3708 CanonicalizeNaN(fpscratch1); | |
| 3709 | |
| 3710 // Store the result. | |
| 3711 Bind(&store_num); | |
| 3712 Add(scratch1, elements_reg, | |
| 3713 Operand::UntagSmiAndScale(key_reg, kDoubleSizeLog2)); | |
| 3714 Str(fpscratch1, | |
| 3715 FieldMemOperand(scratch1, | |
| 3716 FixedDoubleArray::kHeaderSize - elements_offset)); | |
| 3717 } | |
| 3718 | |
| 3719 | |
| 3720 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) { | 3667 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) { |
| 3721 return has_frame_ || !stub->SometimesSetsUpAFrame(); | 3668 return has_frame_ || !stub->SometimesSetsUpAFrame(); |
| 3722 } | 3669 } |
| 3723 | 3670 |
| 3724 void MacroAssembler::EmitSeqStringSetCharCheck( | 3671 void MacroAssembler::EmitSeqStringSetCharCheck( |
| 3725 Register string, | 3672 Register string, |
| 3726 Register index, | 3673 Register index, |
| 3727 SeqStringSetCharCheckIndexType index_type, | 3674 SeqStringSetCharCheckIndexType index_type, |
| 3728 Register scratch, | 3675 Register scratch, |
| 3729 uint32_t encoding_mask) { | 3676 uint32_t encoding_mask) { |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4269 | 4216 |
| 4270 | 4217 |
| 4271 void MacroAssembler::JumpIfBlack(Register object, | 4218 void MacroAssembler::JumpIfBlack(Register object, |
| 4272 Register scratch0, | 4219 Register scratch0, |
| 4273 Register scratch1, | 4220 Register scratch1, |
| 4274 Label* on_black) { | 4221 Label* on_black) { |
| 4275 DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); | 4222 DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); |
| 4276 HasColor(object, scratch0, scratch1, on_black, 1, 1); // kBlackBitPattern. | 4223 HasColor(object, scratch0, scratch1, on_black, 1, 1); // kBlackBitPattern. |
| 4277 } | 4224 } |
| 4278 | 4225 |
| 4279 | |
| 4280 void MacroAssembler::JumpIfDictionaryInPrototypeChain( | |
| 4281 Register object, | |
| 4282 Register scratch0, | |
| 4283 Register scratch1, | |
| 4284 Label* found) { | |
| 4285 DCHECK(!AreAliased(object, scratch0, scratch1)); | |
| 4286 Register current = scratch0; | |
| 4287 Label loop_again, end; | |
| 4288 | |
| 4289 // Scratch contains elements pointer. | |
| 4290 Mov(current, object); | |
| 4291 Ldr(current, FieldMemOperand(current, HeapObject::kMapOffset)); | |
| 4292 Ldr(current, FieldMemOperand(current, Map::kPrototypeOffset)); | |
| 4293 CompareAndBranch(current, Heap::kNullValueRootIndex, eq, &end); | |
| 4294 | |
| 4295 // Loop based on the map going up the prototype chain. | |
| 4296 Bind(&loop_again); | |
| 4297 Ldr(current, FieldMemOperand(current, HeapObject::kMapOffset)); | |
| 4298 STATIC_ASSERT(JS_PROXY_TYPE < JS_OBJECT_TYPE); | |
| 4299 STATIC_ASSERT(JS_VALUE_TYPE < JS_OBJECT_TYPE); | |
| 4300 CompareInstanceType(current, scratch1, JS_OBJECT_TYPE); | |
| 4301 B(lo, found); | |
| 4302 Ldrb(scratch1, FieldMemOperand(current, Map::kBitField2Offset)); | |
| 4303 DecodeField<Map::ElementsKindBits>(scratch1); | |
| 4304 CompareAndBranch(scratch1, DICTIONARY_ELEMENTS, eq, found); | |
| 4305 Ldr(current, FieldMemOperand(current, Map::kPrototypeOffset)); | |
| 4306 CompareAndBranch(current, Heap::kNullValueRootIndex, ne, &loop_again); | |
| 4307 | |
| 4308 Bind(&end); | |
| 4309 } | |
| 4310 | |
| 4311 | |
| 4312 void MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch, | 4226 void MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch, |
| 4313 Register shift_scratch, Register load_scratch, | 4227 Register shift_scratch, Register load_scratch, |
| 4314 Register length_scratch, | 4228 Register length_scratch, |
| 4315 Label* value_is_white) { | 4229 Label* value_is_white) { |
| 4316 DCHECK(!AreAliased( | 4230 DCHECK(!AreAliased( |
| 4317 value, bitmap_scratch, shift_scratch, load_scratch, length_scratch)); | 4231 value, bitmap_scratch, shift_scratch, load_scratch, length_scratch)); |
| 4318 | 4232 |
| 4319 // These bit sequences are backwards. The first character in the string | 4233 // These bit sequences are backwards. The first character in the string |
| 4320 // represents the least significant bit. | 4234 // represents the least significant bit. |
| 4321 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); | 4235 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4464 BlockPoolsScope scope(this); | 4378 BlockPoolsScope scope(this); |
| 4465 Bind(&msg_address); | 4379 Bind(&msg_address); |
| 4466 EmitStringData(GetBailoutReason(reason)); | 4380 EmitStringData(GetBailoutReason(reason)); |
| 4467 } | 4381 } |
| 4468 } | 4382 } |
| 4469 | 4383 |
| 4470 SetStackPointer(old_stack_pointer); | 4384 SetStackPointer(old_stack_pointer); |
| 4471 TmpList()->set_list(old_tmp_list); | 4385 TmpList()->set_list(old_tmp_list); |
| 4472 } | 4386 } |
| 4473 | 4387 |
| 4474 | |
| 4475 void MacroAssembler::LoadTransitionedArrayMapConditional( | |
| 4476 ElementsKind expected_kind, | |
| 4477 ElementsKind transitioned_kind, | |
| 4478 Register map_in_out, | |
| 4479 Register scratch1, | |
| 4480 Register scratch2, | |
| 4481 Label* no_map_match) { | |
| 4482 DCHECK(IsFastElementsKind(expected_kind)); | |
| 4483 DCHECK(IsFastElementsKind(transitioned_kind)); | |
| 4484 | |
| 4485 // Check that the function's map is the same as the expected cached map. | |
| 4486 Ldr(scratch1, NativeContextMemOperand()); | |
| 4487 Ldr(scratch2, | |
| 4488 ContextMemOperand(scratch1, Context::ArrayMapIndex(expected_kind))); | |
| 4489 Cmp(map_in_out, scratch2); | |
| 4490 B(ne, no_map_match); | |
| 4491 | |
| 4492 // Use the transitioned cached map. | |
| 4493 Ldr(map_in_out, | |
| 4494 ContextMemOperand(scratch1, Context::ArrayMapIndex(transitioned_kind))); | |
| 4495 } | |
| 4496 | |
| 4497 | |
| 4498 void MacroAssembler::LoadNativeContextSlot(int index, Register dst) { | 4388 void MacroAssembler::LoadNativeContextSlot(int index, Register dst) { |
| 4499 Ldr(dst, NativeContextMemOperand()); | 4389 Ldr(dst, NativeContextMemOperand()); |
| 4500 Ldr(dst, ContextMemOperand(dst, index)); | 4390 Ldr(dst, ContextMemOperand(dst, index)); |
| 4501 } | 4391 } |
| 4502 | 4392 |
| 4503 | 4393 |
| 4504 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, | 4394 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, |
| 4505 Register map, | 4395 Register map, |
| 4506 Register scratch) { | 4396 Register scratch) { |
| 4507 // Load the initial map. The global functions all have initial maps. | 4397 // Load the initial map. The global functions all have initial maps. |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4934 } | 4824 } |
| 4935 | 4825 |
| 4936 | 4826 |
| 4937 #undef __ | 4827 #undef __ |
| 4938 | 4828 |
| 4939 | 4829 |
| 4940 } // namespace internal | 4830 } // namespace internal |
| 4941 } // namespace v8 | 4831 } // namespace v8 |
| 4942 | 4832 |
| 4943 #endif // V8_TARGET_ARCH_ARM64 | 4833 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |