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 |