diff options
Diffstat (limited to 'deps/v8/src/x64/macro-assembler-x64.cc')
-rw-r--r-- | deps/v8/src/x64/macro-assembler-x64.cc | 183 |
1 files changed, 71 insertions, 112 deletions
diff --git a/deps/v8/src/x64/macro-assembler-x64.cc b/deps/v8/src/x64/macro-assembler-x64.cc index 7a37fb3e3a..5033303402 100644 --- a/deps/v8/src/x64/macro-assembler-x64.cc +++ b/deps/v8/src/x64/macro-assembler-x64.cc @@ -6,6 +6,8 @@ #if V8_TARGET_ARCH_X64 +#include "src/base/bits.h" +#include "src/base/division-by-constant.h" #include "src/bootstrapper.h" #include "src/codegen.h" #include "src/cpu-profiler.h" @@ -235,8 +237,7 @@ void MacroAssembler::RememberedSetHelper(Register object, // For debug tests. DCHECK(and_then == kFallThroughAtEnd); j(equal, &done, Label::kNear); } - StoreBufferOverflowStub store_buffer_overflow = - StoreBufferOverflowStub(isolate(), save_fp); + StoreBufferOverflowStub store_buffer_overflow(isolate(), save_fp); CallStub(&store_buffer_overflow); if (and_then == kReturnAtEnd) { ret(0); @@ -545,7 +546,7 @@ void MacroAssembler::CheckStackAlignment() { int frame_alignment = base::OS::ActivationFrameAlignment(); int frame_alignment_mask = frame_alignment - 1; if (frame_alignment > kPointerSize) { - DCHECK(IsPowerOf2(frame_alignment)); + DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); Label alignment_as_expected; testp(rsp, Immediate(frame_alignment_mask)); j(zero, &alignment_as_expected, Label::kNear); @@ -2610,13 +2611,9 @@ void MacroAssembler::JumpIfNotString(Register object, } -void MacroAssembler::JumpIfNotBothSequentialAsciiStrings( - Register first_object, - Register second_object, - Register scratch1, - Register scratch2, - Label* on_fail, - Label::Distance near_jump) { +void MacroAssembler::JumpIfNotBothSequentialOneByteStrings( + Register first_object, Register second_object, Register scratch1, + Register scratch2, Label* on_fail, Label::Distance near_jump) { // Check that both objects are not smis. Condition either_smi = CheckEitherSmi(first_object, second_object); j(either_smi, on_fail, near_jump); @@ -2627,67 +2624,62 @@ void MacroAssembler::JumpIfNotBothSequentialAsciiStrings( movzxbl(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset)); movzxbl(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset)); - // Check that both are flat ASCII strings. + // Check that both are flat one-byte strings. DCHECK(kNotStringTag != 0); - const int kFlatAsciiStringMask = + const int kFlatOneByteStringMask = kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; - const int kFlatAsciiStringTag = + const int kFlatOneByteStringTag = kStringTag | kOneByteStringTag | kSeqStringTag; - andl(scratch1, Immediate(kFlatAsciiStringMask)); - andl(scratch2, Immediate(kFlatAsciiStringMask)); + andl(scratch1, Immediate(kFlatOneByteStringMask)); + andl(scratch2, Immediate(kFlatOneByteStringMask)); // Interleave the bits to check both scratch1 and scratch2 in one test. - DCHECK_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3)); + DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << 3)); leap(scratch1, Operand(scratch1, scratch2, times_8, 0)); cmpl(scratch1, - Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3))); + Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << 3))); j(not_equal, on_fail, near_jump); } -void MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii( - Register instance_type, - Register scratch, - Label* failure, +void MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte( + Register instance_type, Register scratch, Label* failure, Label::Distance near_jump) { if (!scratch.is(instance_type)) { movl(scratch, instance_type); } - const int kFlatAsciiStringMask = + const int kFlatOneByteStringMask = kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; - andl(scratch, Immediate(kFlatAsciiStringMask)); + andl(scratch, Immediate(kFlatOneByteStringMask)); cmpl(scratch, Immediate(kStringTag | kSeqStringTag | kOneByteStringTag)); j(not_equal, failure, near_jump); } -void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialAscii( - Register first_object_instance_type, - Register second_object_instance_type, - Register scratch1, - Register scratch2, - Label* on_fail, +void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( + Register first_object_instance_type, Register second_object_instance_type, + Register scratch1, Register scratch2, Label* on_fail, Label::Distance near_jump) { // Load instance type for both strings. movp(scratch1, first_object_instance_type); movp(scratch2, second_object_instance_type); - // Check that both are flat ASCII strings. + // Check that both are flat one-byte strings. DCHECK(kNotStringTag != 0); - const int kFlatAsciiStringMask = + const int kFlatOneByteStringMask = kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; - const int kFlatAsciiStringTag = + const int kFlatOneByteStringTag = kStringTag | kOneByteStringTag | kSeqStringTag; - andl(scratch1, Immediate(kFlatAsciiStringMask)); - andl(scratch2, Immediate(kFlatAsciiStringMask)); + andl(scratch1, Immediate(kFlatOneByteStringMask)); + andl(scratch2, Immediate(kFlatOneByteStringMask)); // Interleave the bits to check both scratch1 and scratch2 in one test. - DCHECK_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3)); + DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << 3)); leap(scratch1, Operand(scratch1, scratch2, times_8, 0)); cmpl(scratch1, - Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3))); + Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << 3))); j(not_equal, on_fail, near_jump); } @@ -2709,16 +2701,16 @@ static void JumpIfNotUniqueNameHelper(MacroAssembler* masm, } -void MacroAssembler::JumpIfNotUniqueName(Operand operand, - Label* not_unique_name, - Label::Distance distance) { +void MacroAssembler::JumpIfNotUniqueNameInstanceType(Operand operand, + Label* not_unique_name, + Label::Distance distance) { JumpIfNotUniqueNameHelper<Operand>(this, operand, not_unique_name, distance); } -void MacroAssembler::JumpIfNotUniqueName(Register reg, - Label* not_unique_name, - Label::Distance distance) { +void MacroAssembler::JumpIfNotUniqueNameInstanceType(Register reg, + Label* not_unique_name, + Label::Distance distance) { JumpIfNotUniqueNameHelper<Register>(this, reg, not_unique_name, distance); } @@ -3394,8 +3386,9 @@ void MacroAssembler::StoreNumberToDoubleElements( bind(&is_nan); // Convert all NaNs to the same canonical NaN value when they are stored in // the double array. - Set(kScratchRegister, BitCast<uint64_t>( - FixedDoubleArray::canonical_not_the_hole_nan_as_double())); + Set(kScratchRegister, + bit_cast<uint64_t>( + FixedDoubleArray::canonical_not_the_hole_nan_as_double())); movq(xmm_scratch, kScratchRegister); jmp(&have_double_value, Label::kNear); @@ -3524,17 +3517,16 @@ void MacroAssembler::TruncateDoubleToI(Register result_reg, } -void MacroAssembler::DoubleToI(Register result_reg, - XMMRegister input_reg, +void MacroAssembler::DoubleToI(Register result_reg, XMMRegister input_reg, XMMRegister scratch, MinusZeroMode minus_zero_mode, - Label* conversion_failed, - Label::Distance dst) { + Label* lost_precision, Label* is_nan, + Label* minus_zero, Label::Distance dst) { cvttsd2si(result_reg, input_reg); Cvtlsi2sd(xmm0, result_reg); ucomisd(xmm0, input_reg); - j(not_equal, conversion_failed, dst); - j(parity_even, conversion_failed, dst); // NaN. + j(not_equal, lost_precision, dst); + j(parity_even, is_nan, dst); // NaN. if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { Label done; // The integer converted back is equal to the original. We @@ -3544,47 +3536,14 @@ void MacroAssembler::DoubleToI(Register result_reg, movmskpd(result_reg, input_reg); // Bit 0 contains the sign of the double in input_reg. // If input was positive, we are ok and return 0, otherwise - // jump to conversion_failed. + // jump to minus_zero. andl(result_reg, Immediate(1)); - j(not_zero, conversion_failed, dst); + j(not_zero, minus_zero, dst); bind(&done); } } -void MacroAssembler::TaggedToI(Register result_reg, - Register input_reg, - XMMRegister temp, - MinusZeroMode minus_zero_mode, - Label* lost_precision, - Label::Distance dst) { - Label done; - DCHECK(!temp.is(xmm0)); - - // Heap number map check. - CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), - Heap::kHeapNumberMapRootIndex); - j(not_equal, lost_precision, dst); - - movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); - cvttsd2si(result_reg, xmm0); - Cvtlsi2sd(temp, result_reg); - ucomisd(xmm0, temp); - RecordComment("Deferred TaggedToI: lost precision"); - j(not_equal, lost_precision, dst); - RecordComment("Deferred TaggedToI: NaN"); - j(parity_even, lost_precision, dst); // NaN. - if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { - testl(result_reg, result_reg); - j(not_zero, &done, Label::kNear); - movmskpd(result_reg, xmm0); - andl(result_reg, Immediate(1)); - j(not_zero, lost_precision, dst); - } - bind(&done); -} - - void MacroAssembler::LoadInstanceDescriptors(Register map, Register descriptors) { movp(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); @@ -4102,7 +4061,7 @@ void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, // Get the required frame alignment for the OS. const int kFrameAlignment = base::OS::ActivationFrameAlignment(); if (kFrameAlignment > 0) { - DCHECK(IsPowerOf2(kFrameAlignment)); + DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); DCHECK(is_int8(kFrameAlignment)); andp(rsp, Immediate(-kFrameAlignment)); } @@ -4650,12 +4609,10 @@ void MacroAssembler::AllocateTwoByteString(Register result, } -void MacroAssembler::AllocateAsciiString(Register result, - Register length, - Register scratch1, - Register scratch2, - Register scratch3, - Label* gc_required) { +void MacroAssembler::AllocateOneByteString(Register result, Register length, + Register scratch1, Register scratch2, + Register scratch3, + Label* gc_required) { // Calculate the number of bytes needed for the characters in the string while // observing object alignment. const int kHeaderAlignment = SeqOneByteString::kHeaderSize & @@ -4668,7 +4625,7 @@ void MacroAssembler::AllocateAsciiString(Register result, subp(scratch1, Immediate(kHeaderAlignment)); } - // Allocate ASCII string in new space. + // Allocate one-byte string in new space. Allocate(SeqOneByteString::kHeaderSize, times_1, scratch1, @@ -4679,7 +4636,7 @@ void MacroAssembler::AllocateAsciiString(Register result, TAG_OBJECT); // Set the map, length and hash field. - LoadRoot(kScratchRegister, Heap::kAsciiStringMapRootIndex); + LoadRoot(kScratchRegister, Heap::kOneByteStringMapRootIndex); movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); Integer32ToSmi(scratch1, length); movp(FieldOperand(result, String::kLengthOffset), scratch1); @@ -4702,10 +4659,10 @@ void MacroAssembler::AllocateTwoByteConsString(Register result, } -void MacroAssembler::AllocateAsciiConsString(Register result, - Register scratch1, - Register scratch2, - Label* gc_required) { +void MacroAssembler::AllocateOneByteConsString(Register result, + Register scratch1, + Register scratch2, + Label* gc_required) { Allocate(ConsString::kSize, result, scratch1, @@ -4714,7 +4671,7 @@ void MacroAssembler::AllocateAsciiConsString(Register result, TAG_OBJECT); // Set the map. The other fields are left uninitialized. - LoadRoot(kScratchRegister, Heap::kConsAsciiStringMapRootIndex); + LoadRoot(kScratchRegister, Heap::kConsOneByteStringMapRootIndex); movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); } @@ -4733,16 +4690,16 @@ void MacroAssembler::AllocateTwoByteSlicedString(Register result, } -void MacroAssembler::AllocateAsciiSlicedString(Register result, - Register scratch1, - Register scratch2, - Label* gc_required) { +void MacroAssembler::AllocateOneByteSlicedString(Register result, + Register scratch1, + Register scratch2, + Label* gc_required) { // Allocate heap number in new space. Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, TAG_OBJECT); // Set the map. The other fields are left uninitialized. - LoadRoot(kScratchRegister, Heap::kSlicedAsciiStringMapRootIndex); + LoadRoot(kScratchRegister, Heap::kSlicedOneByteStringMapRootIndex); movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); } @@ -4991,7 +4948,7 @@ void MacroAssembler::PrepareCallCFunction(int num_arguments) { // Make stack end at alignment and allocate space for arguments and old rsp. movp(kScratchRegister, rsp); - DCHECK(IsPowerOf2(frame_alignment)); + DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); int argument_slots_on_stack = ArgumentStackSlotsForCFunctionCall(num_arguments); subp(rsp, Immediate((argument_slots_on_stack + 1) * kRegisterSize)); @@ -5251,12 +5208,12 @@ void MacroAssembler::EnsureNotWhite( jmp(&is_data_object, Label::kNear); bind(¬_external); - // Sequential string, either ASCII or UC16. + // Sequential string, either Latin1 or UC16. DCHECK(kOneByteStringTag == 0x04); andp(length, Immediate(kStringEncodingMask)); xorp(length, Immediate(kStringEncodingMask)); addp(length, Immediate(0x04)); - // Value now either 4 (if ASCII) or 8 (if UC16), i.e. char-size shifted by 2. + // Value now either 4 (if Latin1) or 8 (if UC16), i.e. char-size shifted by 2. imulp(length, FieldOperand(value, String::kLengthOffset)); shrp(length, Immediate(2 + kSmiTagSize + kSmiShiftSize)); addp(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask)); @@ -5368,12 +5325,14 @@ void MacroAssembler::JumpIfDictionaryInPrototypeChain( void MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) { DCHECK(!dividend.is(rax)); DCHECK(!dividend.is(rdx)); - MultiplierAndShift ms(divisor); - movl(rax, Immediate(ms.multiplier())); + base::MagicNumbersForDivision<uint32_t> mag = + base::SignedDivisionByConstant(static_cast<uint32_t>(divisor)); + movl(rax, Immediate(mag.multiplier)); imull(dividend); - if (divisor > 0 && ms.multiplier() < 0) addl(rdx, dividend); - if (divisor < 0 && ms.multiplier() > 0) subl(rdx, dividend); - if (ms.shift() > 0) sarl(rdx, Immediate(ms.shift())); + bool neg = (mag.multiplier & (static_cast<uint32_t>(1) << 31)) != 0; + if (divisor > 0 && neg) addl(rdx, dividend); + if (divisor < 0 && !neg && mag.multiplier > 0) subl(rdx, dividend); + if (mag.shift > 0) sarl(rdx, Immediate(mag.shift)); movl(rax, dividend); shrl(rax, Immediate(31)); addl(rdx, rax); |