diff options
Diffstat (limited to 'src/mips64/macro-assembler-mips64.cc')
-rw-r--r-- | src/mips64/macro-assembler-mips64.cc | 737 |
1 files changed, 232 insertions, 505 deletions
diff --git a/src/mips64/macro-assembler-mips64.cc b/src/mips64/macro-assembler-mips64.cc index a3ab4a88..849327e6 100644 --- a/src/mips64/macro-assembler-mips64.cc +++ b/src/mips64/macro-assembler-mips64.cc @@ -2212,19 +2212,49 @@ void MacroAssembler::Trunc_ul_s(FPURegister fd, Register rs, bind(&fail); } +void MacroAssembler::Madd_s(FPURegister fd, FPURegister fr, FPURegister fs, + FPURegister ft, FPURegister scratch) { + if (kArchVariant == kMips64r2) { + madd_s(fd, fr, fs, ft); + } else { + DCHECK(!fr.is(scratch) && !fs.is(scratch) && !ft.is(scratch)); + mul_s(scratch, fs, ft); + add_s(fd, fr, scratch); + } +} void MacroAssembler::Madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft, FPURegister scratch) { - if (0) { // TODO(plind): find reasonable arch-variant symbol names. + if (kArchVariant == kMips64r2) { madd_d(fd, fr, fs, ft); } else { - // Can not change source regs's value. DCHECK(!fr.is(scratch) && !fs.is(scratch) && !ft.is(scratch)); mul_d(scratch, fs, ft); add_d(fd, fr, scratch); } } +void MacroAssembler::Msub_s(FPURegister fd, FPURegister fr, FPURegister fs, + FPURegister ft, FPURegister scratch) { + if (kArchVariant == kMips64r2) { + msub_s(fd, fr, fs, ft); + } else { + DCHECK(!fr.is(scratch) && !fs.is(scratch) && !ft.is(scratch)); + mul_s(scratch, fs, ft); + sub_s(fd, scratch, fr); + } +} + +void MacroAssembler::Msub_d(FPURegister fd, FPURegister fr, FPURegister fs, + FPURegister ft, FPURegister scratch) { + if (kArchVariant == kMips64r2) { + msub_d(fd, fr, fs, ft); + } else { + DCHECK(!fr.is(scratch) && !fs.is(scratch) && !ft.is(scratch)); + mul_d(scratch, fs, ft); + sub_d(fd, scratch, fr); + } +} void MacroAssembler::BranchFCommon(SecondaryField sizeField, Label* target, Label* nan, Condition cond, FPURegister cmp1, @@ -2524,186 +2554,6 @@ void MacroAssembler::Movf(Register rd, Register rs, uint16_t cc) { movf(rd, rs, cc); } -#define __ masm-> - -static bool ZeroHelper_d(MacroAssembler* masm, MaxMinKind kind, FPURegister dst, - FPURegister src1, FPURegister src2, Label* equal) { - if (src1.is(src2)) { - __ Move(dst, src1); - return true; - } - - Label other, compare_not_equal; - FPURegister left, right; - if (kind == MaxMinKind::kMin) { - left = src1; - right = src2; - } else { - left = src2; - right = src1; - } - - __ BranchF64(&compare_not_equal, nullptr, ne, src1, src2); - // Left and right hand side are equal, check for -0 vs. +0. - __ dmfc1(t8, src1); - __ Branch(&other, eq, t8, Operand(0x8000000000000000)); - __ Move_d(dst, right); - __ Branch(equal); - __ bind(&other); - __ Move_d(dst, left); - __ Branch(equal); - __ bind(&compare_not_equal); - return false; -} - -static bool ZeroHelper_s(MacroAssembler* masm, MaxMinKind kind, FPURegister dst, - FPURegister src1, FPURegister src2, Label* equal) { - if (src1.is(src2)) { - __ Move(dst, src1); - return true; - } - - Label other, compare_not_equal; - FPURegister left, right; - if (kind == MaxMinKind::kMin) { - left = src1; - right = src2; - } else { - left = src2; - right = src1; - } - - __ BranchF32(&compare_not_equal, nullptr, ne, src1, src2); - // Left and right hand side are equal, check for -0 vs. +0. - __ FmoveLow(t8, src1); - __ dsll32(t8, t8, 0); - __ Branch(&other, eq, t8, Operand(0x8000000000000000)); - __ Move_s(dst, right); - __ Branch(equal); - __ bind(&other); - __ Move_s(dst, left); - __ Branch(equal); - __ bind(&compare_not_equal); - return false; -} - -#undef __ - -void MacroAssembler::MinNaNCheck_d(FPURegister dst, FPURegister src1, - FPURegister src2, Label* nan) { - if (nan) { - BranchF64(nullptr, nan, eq, src1, src2); - } - if (kArchVariant >= kMips64r6) { - min_d(dst, src1, src2); - } else { - Label skip; - if (!ZeroHelper_d(this, MaxMinKind::kMin, dst, src1, src2, &skip)) { - if (dst.is(src1)) { - BranchF64(&skip, nullptr, le, src1, src2); - Move_d(dst, src2); - } else if (dst.is(src2)) { - BranchF64(&skip, nullptr, ge, src1, src2); - Move_d(dst, src1); - } else { - Label right; - BranchF64(&right, nullptr, gt, src1, src2); - Move_d(dst, src1); - Branch(&skip); - bind(&right); - Move_d(dst, src2); - } - } - bind(&skip); - } -} - -void MacroAssembler::MaxNaNCheck_d(FPURegister dst, FPURegister src1, - FPURegister src2, Label* nan) { - if (nan) { - BranchF64(nullptr, nan, eq, src1, src2); - } - if (kArchVariant >= kMips64r6) { - max_d(dst, src1, src2); - } else { - Label skip; - if (!ZeroHelper_d(this, MaxMinKind::kMax, dst, src1, src2, &skip)) { - if (dst.is(src1)) { - BranchF64(&skip, nullptr, ge, src1, src2); - Move_d(dst, src2); - } else if (dst.is(src2)) { - BranchF64(&skip, nullptr, le, src1, src2); - Move_d(dst, src1); - } else { - Label right; - BranchF64(&right, nullptr, lt, src1, src2); - Move_d(dst, src1); - Branch(&skip); - bind(&right); - Move_d(dst, src2); - } - } - bind(&skip); - } -} - -void MacroAssembler::MinNaNCheck_s(FPURegister dst, FPURegister src1, - FPURegister src2, Label* nan) { - if (nan) { - BranchF32(nullptr, nan, eq, src1, src2); - } - if (kArchVariant >= kMips64r6) { - min_s(dst, src1, src2); - } else { - Label skip; - if (!ZeroHelper_s(this, MaxMinKind::kMin, dst, src1, src2, &skip)) { - if (dst.is(src1)) { - BranchF32(&skip, nullptr, le, src1, src2); - Move_s(dst, src2); - } else if (dst.is(src2)) { - BranchF32(&skip, nullptr, ge, src1, src2); - Move_s(dst, src1); - } else { - Label right; - BranchF32(&right, nullptr, gt, src1, src2); - Move_s(dst, src1); - Branch(&skip); - bind(&right); - Move_s(dst, src2); - } - } - bind(&skip); - } -} - -void MacroAssembler::MaxNaNCheck_s(FPURegister dst, FPURegister src1, - FPURegister src2, Label* nan) { - if (nan) { - BranchF32(nullptr, nan, eq, src1, src2); - } - if (kArchVariant >= kMips64r6) { - max_s(dst, src1, src2); - } else { - Label skip; - if (!ZeroHelper_s(this, MaxMinKind::kMax, dst, src1, src2, &skip)) { - if (dst.is(src1)) { - BranchF32(&skip, nullptr, ge, src1, src2); - Move_s(dst, src2); - } else if (dst.is(src2)) { - BranchF32(&skip, nullptr, le, src1, src2); - Move_s(dst, src1); - } else { - Label right; - BranchF32(&right, nullptr, lt, src1, src2); - Move_s(dst, src1); - Branch(&skip); - bind(&right); - Move_s(dst, src2); - } - } - bind(&skip); - } -} void MacroAssembler::Clz(Register rd, Register rs) { clz(rd, rs); @@ -4190,17 +4040,16 @@ void MacroAssembler::PopRegisterAsTwoSmis(Register dst, Register scratch) { or_(dst, dst, scratch); } - -void MacroAssembler::DebugBreak() { - PrepareCEntryArgs(0); - PrepareCEntryFunction( - ExternalReference(Runtime::kHandleDebuggerStatement, isolate())); - CEntryStub ces(isolate(), 1); - DCHECK(AllowThisStubCall(&ces)); - Call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT); +void MacroAssembler::MaybeDropFrames() { + // Check whether we need to drop frames to restart a function on the stack. + ExternalReference restart_fp = + ExternalReference::debug_restart_fp_address(isolate()); + li(a1, Operand(restart_fp)); + ld(a1, MemOperand(a1)); + Jump(isolate()->builtins()->FrameDropperTrampoline(), RelocInfo::CODE_TARGET, + ne, a1, Operand(zero_reg)); } - // --------------------------------------------------------------------------- // Exception handling. @@ -4472,111 +4321,6 @@ void MacroAssembler::FastAllocate(Register object_size, Register result, Daddu(result, result, Operand(kHeapObjectTag)); } -void MacroAssembler::AllocateTwoByteString(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. - DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); - dsll(scratch1, length, 1); // Length in bytes, not chars. - daddiu(scratch1, scratch1, - kObjectAlignmentMask + SeqTwoByteString::kHeaderSize); - And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); - - // Allocate two-byte string in new space. - Allocate(scratch1, result, scratch2, scratch3, gc_required, - NO_ALLOCATION_FLAGS); - - // Set the map, length and hash field. - InitializeNewString(result, - length, - Heap::kStringMapRootIndex, - scratch1, - scratch2); -} - - -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. - DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); - DCHECK(kCharSize == 1); - daddiu(scratch1, length, - kObjectAlignmentMask + SeqOneByteString::kHeaderSize); - And(scratch1, scratch1, Operand(~kObjectAlignmentMask)); - - // Allocate one-byte string in new space. - Allocate(scratch1, result, scratch2, scratch3, gc_required, - NO_ALLOCATION_FLAGS); - - // Set the map, length and hash field. - InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex, - scratch1, scratch2); -} - - -void MacroAssembler::AllocateTwoByteConsString(Register result, - Register length, - Register scratch1, - Register scratch2, - Label* gc_required) { - Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, - NO_ALLOCATION_FLAGS); - InitializeNewString(result, - length, - Heap::kConsStringMapRootIndex, - scratch1, - scratch2); -} - - -void MacroAssembler::AllocateOneByteConsString(Register result, Register length, - Register scratch1, - Register scratch2, - Label* gc_required) { - Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, - NO_ALLOCATION_FLAGS); - - InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex, - scratch1, scratch2); -} - - -void MacroAssembler::AllocateTwoByteSlicedString(Register result, - Register length, - Register scratch1, - Register scratch2, - Label* gc_required) { - Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, - NO_ALLOCATION_FLAGS); - - InitializeNewString(result, - length, - Heap::kSlicedStringMapRootIndex, - scratch1, - scratch2); -} - - -void MacroAssembler::AllocateOneByteSlicedString(Register result, - Register length, - Register scratch1, - Register scratch2, - Label* gc_required) { - Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, - NO_ALLOCATION_FLAGS); - - InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex, - scratch1, scratch2); -} - - void MacroAssembler::JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name) { STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); @@ -4657,76 +4401,6 @@ void MacroAssembler::InitializeFieldsWithFiller(Register current_address, Branch(&loop, ult, current_address, Operand(end_address)); } -void MacroAssembler::CheckFastObjectElements(Register map, - Register scratch, - Label* fail) { - STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); - STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); - STATIC_ASSERT(FAST_ELEMENTS == 2); - STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); - lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset)); - Branch(fail, ls, scratch, - Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); - Branch(fail, hi, scratch, - Operand(Map::kMaximumBitField2FastHoleyElementValue)); -} - - -void MacroAssembler::CheckFastSmiElements(Register map, - Register scratch, - Label* fail) { - STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); - STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); - lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset)); - Branch(fail, hi, scratch, - Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); -} - - -void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, - Register key_reg, - Register elements_reg, - Register scratch1, - Register scratch2, - Label* fail, - int elements_offset) { - DCHECK(!AreAliased(value_reg, key_reg, elements_reg, scratch1, scratch2)); - Label smi_value, done; - - // Handle smi values specially. - JumpIfSmi(value_reg, &smi_value); - - // Ensure that the object is a heap number. - CheckMap(value_reg, - scratch1, - Heap::kHeapNumberMapRootIndex, - fail, - DONT_DO_SMI_CHECK); - - // Double value, turn potential sNaN into qNan. - DoubleRegister double_result = f0; - DoubleRegister double_scratch = f2; - - ldc1(double_result, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); - Branch(USE_DELAY_SLOT, &done); // Canonicalization is one instruction. - FPUCanonicalizeNaN(double_result, double_result); - - bind(&smi_value); - // Untag and transfer. - dsrl32(scratch1, value_reg, 0); - mtc1(scratch1, double_scratch); - cvt_d_w(double_result, double_scratch); - - bind(&done); - Daddu(scratch1, elements_reg, - Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag - - elements_offset)); - dsra(scratch2, key_reg, 32 - kDoubleSizeLog2); - Daddu(scratch1, scratch1, scratch2); - // scratch1 is now effective address of the double element. - sdc1(double_result, MemOperand(scratch1, 0)); -} - void MacroAssembler::SubNanPreservePayloadAndSign_s(FPURegister fd, FPURegister fs, FPURegister ft) { @@ -5076,17 +4750,15 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, } } - -void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, - const ParameterCount& expected, - const ParameterCount& actual) { - Label skip_flooding; - ExternalReference last_step_action = - ExternalReference::debug_last_step_action_address(isolate()); - STATIC_ASSERT(StepFrame > StepIn); - li(t0, Operand(last_step_action)); +void MacroAssembler::CheckDebugHook(Register fun, Register new_target, + const ParameterCount& expected, + const ParameterCount& actual) { + Label skip_hook; + ExternalReference debug_hook_active = + ExternalReference::debug_hook_on_function_call_address(isolate()); + li(t0, Operand(debug_hook_active)); lb(t0, MemOperand(t0)); - Branch(&skip_flooding, lt, t0, Operand(StepIn)); + Branch(&skip_hook, eq, t0, Operand(zero_reg)); { FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); @@ -5103,7 +4775,7 @@ void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, } Push(fun); Push(fun); - CallRuntime(Runtime::kDebugPrepareStepInIfStepping); + CallRuntime(Runtime::kDebugOnFunctionCall); Pop(fun); if (new_target.is_valid()) { Pop(new_target); @@ -5117,7 +4789,7 @@ void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, SmiUntag(expected.reg()); } } - bind(&skip_flooding); + bind(&skip_hook); } @@ -5131,8 +4803,8 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, DCHECK(function.is(a1)); DCHECK_IMPLIES(new_target.is_valid(), new_target.is(a3)); - if (call_wrapper.NeedsDebugStepCheck()) { - FloodFunctionIfStepping(function, new_target, expected, actual); + if (call_wrapper.NeedsDebugHookCheck()) { + CheckDebugHook(function, new_target, expected, actual); } // Clear the new.target register if not given. @@ -5255,32 +4927,6 @@ void MacroAssembler::GetMapConstructor(Register result, Register map, bind(&done); } - -void MacroAssembler::TryGetFunctionPrototype(Register function, Register result, - Register scratch, Label* miss) { - // Get the prototype or initial map from the function. - ld(result, - FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); - - // If the prototype or initial map is the hole, don't return it and - // simply miss the cache instead. This will allow us to allocate a - // prototype object on-demand in the runtime system. - LoadRoot(t8, Heap::kTheHoleValueRootIndex); - Branch(miss, eq, result, Operand(t8)); - - // If the function does not have an initial map, we're done. - Label done; - GetObjectType(result, scratch, scratch); - Branch(&done, ne, scratch, Operand(MAP_TYPE)); - - // Get the prototype from the initial map. - ld(result, FieldMemOperand(result, Map::kPrototypeOffset)); - - // All done. - bind(&done); -} - - void MacroAssembler::GetObjectType(Register object, Register map, Register type_reg) { @@ -5958,27 +5604,6 @@ void MacroAssembler::LoadContext(Register dst, int context_chain_length) { } } - -void MacroAssembler::LoadTransitionedArrayMapConditional( - ElementsKind expected_kind, - ElementsKind transitioned_kind, - Register map_in_out, - Register scratch, - Label* no_map_match) { - DCHECK(IsFastElementsKind(expected_kind)); - DCHECK(IsFastElementsKind(transitioned_kind)); - - // Check that the function's map is the same as the expected cached map. - ld(scratch, NativeContextMemOperand()); - ld(at, ContextMemOperand(scratch, Context::ArrayMapIndex(expected_kind))); - Branch(no_map_match, ne, map_in_out, Operand(at)); - - // Use the transitioned cached map. - ld(map_in_out, - ContextMemOperand(scratch, Context::ArrayMapIndex(transitioned_kind))); -} - - void MacroAssembler::LoadNativeContextSlot(int index, Register dst) { ld(dst, NativeContextMemOperand()); ld(dst, ContextMemOperand(dst, index)); @@ -6001,7 +5626,7 @@ void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, } void MacroAssembler::StubPrologue(StackFrame::Type type) { - li(at, Operand(Smi::FromInt(type))); + li(at, Operand(StackFrame::TypeToMarker(type))); PushCommonFrame(at); } @@ -6016,7 +5641,7 @@ void MacroAssembler::Prologue(bool code_pre_aging) { Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); nop(Assembler::CODE_AGE_MARKER_NOP); // Load the stub address to t9 and call it, - // GetCodeAgeAndParity() extracts the stub address from this instruction. + // GetCodeAge() extracts the stub address from this instruction. li(t9, Operand(reinterpret_cast<uint64_t>(stub->instruction_start())), ADDRESS_LOAD); @@ -6032,10 +5657,10 @@ void MacroAssembler::Prologue(bool code_pre_aging) { } } -void MacroAssembler::EmitLoadTypeFeedbackVector(Register vector) { +void MacroAssembler::EmitLoadFeedbackVector(Register vector) { ld(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); - ld(vector, FieldMemOperand(vector, JSFunction::kLiteralsOffset)); - ld(vector, FieldMemOperand(vector, LiteralsArray::kFeedbackVectorOffset)); + ld(vector, FieldMemOperand(vector, JSFunction::kFeedbackVectorOffset)); + ld(vector, FieldMemOperand(vector, Cell::kValueOffset)); } @@ -6061,7 +5686,7 @@ void MacroAssembler::EnterFrame(StackFrame::Type type) { stack_offset -= kPointerSize; sd(fp, MemOperand(sp, stack_offset)); stack_offset -= kPointerSize; - li(t9, Operand(Smi::FromInt(type))); + li(t9, Operand(StackFrame::TypeToMarker(type))); sd(t9, MemOperand(sp, stack_offset)); if (type == StackFrame::INTERNAL) { DCHECK_EQ(stack_offset, kPointerSize); @@ -6118,7 +5743,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space, daddiu(sp, sp, -2 * kPointerSize - ExitFrameConstants::kFixedFrameSizeFromFp); sd(ra, MemOperand(sp, 4 * kPointerSize)); sd(fp, MemOperand(sp, 3 * kPointerSize)); - li(at, Operand(Smi::FromInt(frame_type))); + li(at, Operand(StackFrame::TypeToMarker(frame_type))); sd(at, MemOperand(sp, 2 * kPointerSize)); // Set up new frame pointer. daddiu(fp, sp, ExitFrameConstants::kFixedFrameSizeFromFp); @@ -6216,22 +5841,6 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, daddiu(sp, sp, 2 * kPointerSize); } - -void MacroAssembler::InitializeNewString(Register string, - Register length, - Heap::RootListIndex map_index, - Register scratch1, - Register scratch2) { - // dsll(scratch1, length, kSmiTagSize); - dsll32(scratch1, length, 0); - LoadRoot(scratch2, map_index); - sd(scratch1, FieldMemOperand(string, String::kLengthOffset)); - li(scratch1, Operand(String::kEmptyHashField)); - sd(scratch2, FieldMemOperand(string, HeapObject::kMapOffset)); - sw(scratch1, FieldMemOperand(string, String::kHashFieldOffset)); -} - - int MacroAssembler::ActivationFrameAlignment() { #if V8_HOST_ARCH_MIPS || V8_HOST_ARCH_MIPS64 // Running on the real platform. Use the alignment as mandated by the local @@ -6367,15 +5976,6 @@ void MacroAssembler::UntagAndJumpIfSmi(Register dst, SmiUntag(dst, src); } - -void MacroAssembler::UntagAndJumpIfNotSmi(Register dst, - Register src, - Label* non_smi_case) { - // DCHECK(!dst.is(src)); - JumpIfNotSmi(src, non_smi_case, at, USE_DELAY_SLOT); - SmiUntag(dst, src); -} - void MacroAssembler::JumpIfSmi(Register value, Label* smi_label, Register scratch, @@ -6580,6 +6180,179 @@ void MacroAssembler::JumpIfNotBothSequentialOneByteStrings(Register first, scratch2, failure); } +void MacroAssembler::Float32Max(FPURegister dst, FPURegister src1, + FPURegister src2, Label* out_of_line) { + if (src1.is(src2)) { + Move_s(dst, src1); + return; + } + + // Check if one of operands is NaN. + BranchF32(nullptr, out_of_line, eq, src1, src2); + + if (kArchVariant >= kMips64r6) { + max_s(dst, src1, src2); + } else { + Label return_left, return_right, done; + + BranchF32(&return_right, nullptr, lt, src1, src2); + BranchF32(&return_left, nullptr, lt, src2, src1); + + // Operands are equal, but check for +/-0. + mfc1(t8, src1); + dsll32(t8, t8, 0); + Branch(&return_left, eq, t8, Operand(zero_reg)); + Branch(&return_right); + + bind(&return_right); + if (!src2.is(dst)) { + Move_s(dst, src2); + } + Branch(&done); + + bind(&return_left); + if (!src1.is(dst)) { + Move_s(dst, src1); + } + + bind(&done); + } +} + +void MacroAssembler::Float32MaxOutOfLine(FPURegister dst, FPURegister src1, + FPURegister src2) { + add_s(dst, src1, src2); +} + +void MacroAssembler::Float32Min(FPURegister dst, FPURegister src1, + FPURegister src2, Label* out_of_line) { + if (src1.is(src2)) { + Move_s(dst, src1); + return; + } + + // Check if one of operands is NaN. + BranchF32(nullptr, out_of_line, eq, src1, src2); + + if (kArchVariant >= kMips64r6) { + min_s(dst, src1, src2); + } else { + Label return_left, return_right, done; + + BranchF32(&return_left, nullptr, lt, src1, src2); + BranchF32(&return_right, nullptr, lt, src2, src1); + + // Left equals right => check for -0. + mfc1(t8, src1); + dsll32(t8, t8, 0); + Branch(&return_right, eq, t8, Operand(zero_reg)); + Branch(&return_left); + + bind(&return_right); + if (!src2.is(dst)) { + Move_s(dst, src2); + } + Branch(&done); + + bind(&return_left); + if (!src1.is(dst)) { + Move_s(dst, src1); + } + + bind(&done); + } +} + +void MacroAssembler::Float32MinOutOfLine(FPURegister dst, FPURegister src1, + FPURegister src2) { + add_s(dst, src1, src2); +} + +void MacroAssembler::Float64Max(FPURegister dst, FPURegister src1, + FPURegister src2, Label* out_of_line) { + if (src1.is(src2)) { + Move_d(dst, src1); + return; + } + + // Check if one of operands is NaN. + BranchF64(nullptr, out_of_line, eq, src1, src2); + + if (kArchVariant >= kMips64r6) { + max_d(dst, src1, src2); + } else { + Label return_left, return_right, done; + + BranchF64(&return_right, nullptr, lt, src1, src2); + BranchF64(&return_left, nullptr, lt, src2, src1); + + // Left equals right => check for -0. + dmfc1(t8, src1); + Branch(&return_left, eq, t8, Operand(zero_reg)); + Branch(&return_right); + + bind(&return_right); + if (!src2.is(dst)) { + Move_d(dst, src2); + } + Branch(&done); + + bind(&return_left); + if (!src1.is(dst)) { + Move_d(dst, src1); + } + + bind(&done); + } +} + +void MacroAssembler::Float64MaxOutOfLine(FPURegister dst, FPURegister src1, + FPURegister src2) { + add_d(dst, src1, src2); +} + +void MacroAssembler::Float64Min(FPURegister dst, FPURegister src1, + FPURegister src2, Label* out_of_line) { + if (src1.is(src2)) { + Move_d(dst, src1); + return; + } + + // Check if one of operands is NaN. + BranchF64(nullptr, out_of_line, eq, src1, src2); + + if (kArchVariant >= kMips64r6) { + min_d(dst, src1, src2); + } else { + Label return_left, return_right, done; + + BranchF64(&return_left, nullptr, lt, src1, src2); + BranchF64(&return_right, nullptr, lt, src2, src1); + + // Left equals right => check for -0. + dmfc1(t8, src1); + Branch(&return_right, eq, t8, Operand(zero_reg)); + Branch(&return_left); + + bind(&return_right); + if (!src2.is(dst)) { + Move_d(dst, src2); + } + Branch(&done); + + bind(&return_left); + if (!src1.is(dst)) { + Move_d(dst, src1); + } + + bind(&done); + } +} + +void MacroAssembler::Float64MinOutOfLine(FPURegister dst, FPURegister src1, + FPURegister src2) { + add_d(dst, src1, src2); +} void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( Register first, Register second, Register scratch1, Register scratch2, @@ -6595,18 +6368,6 @@ void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( Branch(failure, ne, scratch2, Operand(kFlatOneByteStringTag)); } - -void MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte(Register type, - Register scratch, - Label* failure) { - const int kFlatOneByteStringMask = - kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; - const int kFlatOneByteStringTag = - kStringTag | kOneByteStringTag | kSeqStringTag; - And(scratch, type, Operand(kFlatOneByteStringMask)); - Branch(failure, ne, scratch, Operand(kFlatOneByteStringTag)); -} - static const int kRegisterPassedArguments = 8; int MacroAssembler::CalculateStackPassedWords(int num_reg_arguments, @@ -7042,40 +6803,6 @@ Register GetRegisterThatIsNotOneOf(Register reg1, return no_reg; } - -void MacroAssembler::JumpIfDictionaryInPrototypeChain( - Register object, - Register scratch0, - Register scratch1, - Label* found) { - DCHECK(!scratch1.is(scratch0)); - Factory* factory = isolate()->factory(); - Register current = scratch0; - Label loop_again, end; - - // Scratch contained elements pointer. - Move(current, object); - ld(current, FieldMemOperand(current, HeapObject::kMapOffset)); - ld(current, FieldMemOperand(current, Map::kPrototypeOffset)); - Branch(&end, eq, current, Operand(factory->null_value())); - - // Loop based on the map going up the prototype chain. - bind(&loop_again); - ld(current, FieldMemOperand(current, HeapObject::kMapOffset)); - lbu(scratch1, FieldMemOperand(current, Map::kInstanceTypeOffset)); - STATIC_ASSERT(JS_VALUE_TYPE < JS_OBJECT_TYPE); - STATIC_ASSERT(JS_PROXY_TYPE < JS_OBJECT_TYPE); - Branch(found, lo, scratch1, Operand(JS_OBJECT_TYPE)); - lb(scratch1, FieldMemOperand(current, Map::kBitField2Offset)); - DecodeField<Map::ElementsKindBits>(scratch1); - Branch(found, eq, scratch1, Operand(DICTIONARY_ELEMENTS)); - ld(current, FieldMemOperand(current, Map::kPrototypeOffset)); - Branch(&loop_again, ne, current, Operand(factory->null_value())); - - bind(&end); -} - - bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4, Register reg5, Register reg6, Register reg7, Register reg8, Register reg9, Register reg10) { |