From ca86a6f942e6ca05e3e06e53d3cf461632cee88a Mon Sep 17 00:00:00 2001 From: Dusan Milosavljevic Date: Wed, 19 Nov 2014 17:08:23 +0100 Subject: [PATCH] MIPS64: Prepare additonal code for turbofan landing. TEST= BUG= R=paul.lind@imgtec.com Review URL: https://codereview.chromium.org/735033002 Cr-Commit-Position: refs/heads/master@{#25425} --- src/mips64/assembler-mips64.cc | 8 + src/mips64/assembler-mips64.h | 1 + src/mips64/builtins-mips64.cc | 6 +- src/mips64/code-stubs-mips64.cc | 43 ++-- src/mips64/constants-mips64.cc | 1 + src/mips64/deoptimizer-mips64.cc | 5 +- src/mips64/disasm-mips64.cc | 4 + src/mips64/macro-assembler-mips64.cc | 309 +++++++++++++++++++++++---- src/mips64/macro-assembler-mips64.h | 24 ++- src/mips64/simulator-mips64.cc | 26 ++- 10 files changed, 349 insertions(+), 78 deletions(-) diff --git a/src/mips64/assembler-mips64.cc b/src/mips64/assembler-mips64.cc index 5d51e6354..b8f582131 100644 --- a/src/mips64/assembler-mips64.cc +++ b/src/mips64/assembler-mips64.cc @@ -2192,6 +2192,14 @@ void Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) { } +void Assembler::dext_(Register rt, Register rs, uint16_t pos, uint16_t size) { + // Should be called via MacroAssembler::Ext. + // Dext instr has 'rt' field as dest, and two uint5: msb, lsb. + DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6); + GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, DEXT); +} + + void Assembler::pref(int32_t hint, const MemOperand& rs) { DCHECK(is_uint5(hint) && is_uint16(rs.offset_)); Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift) diff --git a/src/mips64/assembler-mips64.h b/src/mips64/assembler-mips64.h index b296d5175..5ca2f3ad0 100644 --- a/src/mips64/assembler-mips64.h +++ b/src/mips64/assembler-mips64.h @@ -886,6 +886,7 @@ class Assembler : public AssemblerBase { void clz(Register rd, Register rs); void ins_(Register rt, Register rs, uint16_t pos, uint16_t size); void ext_(Register rt, Register rs, uint16_t pos, uint16_t size); + void dext_(Register rt, Register rs, uint16_t pos, uint16_t size); // --------Coprocessor-instructions---------------- diff --git a/src/mips64/builtins-mips64.cc b/src/mips64/builtins-mips64.cc index f4bd386ea..8f36797c8 100644 --- a/src/mips64/builtins-mips64.cc +++ b/src/mips64/builtins-mips64.cc @@ -44,11 +44,9 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, DCHECK(extra_args == NO_EXTRA_ARGUMENTS); } - // JumpToExternalReference expects s0 to contain the number of arguments + // JumpToExternalReference expects a0 to contain the number of arguments // including the receiver and the extra arguments. - __ Daddu(s0, a0, num_extra_args + 1); - __ dsll(s1, s0, kPointerSizeLog2); - __ Dsubu(s1, s1, kPointerSize); + __ Daddu(a0, a0, num_extra_args + 1); __ JumpToExternalReference(ExternalReference(id, masm->isolate())); } diff --git a/src/mips64/code-stubs-mips64.cc b/src/mips64/code-stubs-mips64.cc index 481fb8c91..19ad81221 100644 --- a/src/mips64/code-stubs-mips64.cc +++ b/src/mips64/code-stubs-mips64.cc @@ -1033,22 +1033,18 @@ void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { void CEntryStub::Generate(MacroAssembler* masm) { // Called from JavaScript; parameters are on stack as if calling JS function - // s0: number of arguments including receiver - // s1: size of arguments excluding receiver - // s2: pointer to builtin function + // a0: number of arguments including receiver + // a1: pointer to builtin function // fp: frame pointer (restored after C call) // sp: stack pointer (restored as callee's sp after C call) // cp: current context (C callee-saved) ProfileEntryHookStub::MaybeCallEntryHook(masm); - // NOTE: s0-s2 hold the arguments of this function instead of a0-a2. - // The reason for this is that these arguments would need to be saved anyway - // so it's faster to set them up directly. - // See MacroAssembler::PrepareCEntryArgs and PrepareCEntryFunction. - // Compute the argv pointer in a callee-saved register. + __ dsll(s1, a0, kPointerSizeLog2); __ Daddu(s1, sp, s1); + __ Dsubu(s1, s1, kPointerSize); // Enter the exit frame that transitions from JavaScript to C++. FrameScope scope(masm, StackFrame::MANUAL); @@ -1060,7 +1056,8 @@ void CEntryStub::Generate(MacroAssembler* masm) { // Prepare arguments for C routine. // a0 = argc - __ mov(a0, s0); + __ mov(s0, a0); + __ mov(s2, a1); // a1 = argv (set in the delay slot after find_ra below). // We are calling compiled C/C++ code. a0 and a1 hold our two arguments. We @@ -1383,8 +1380,6 @@ void LoadIndexedStringStub::Generate(MacroAssembler* masm) { void InstanceofStub::Generate(MacroAssembler* masm) { // Call site inlining and patching implies arguments in registers. DCHECK(HasArgsInRegisters() || !HasCallSiteInlineCheck()); - // ReturnTrueFalse is only implemented for inlined call sites. - DCHECK(!ReturnTrueFalseObject() || HasCallSiteInlineCheck()); // Fixed register usage throughout the stub: const Register object = a0; // Object (lhs). @@ -1409,7 +1404,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) { // If there is a call site cache don't look in the global cache, but do the // real lookup and update the call site cache. - if (!HasCallSiteInlineCheck()) { + if (!HasCallSiteInlineCheck() && !ReturnTrueFalseObject()) { Label miss; __ LoadRoot(at, Heap::kInstanceofCacheFunctionRootIndex); __ Branch(&miss, ne, function, Operand(at)); @@ -1468,6 +1463,9 @@ void InstanceofStub::Generate(MacroAssembler* masm) { if (!HasCallSiteInlineCheck()) { __ mov(v0, zero_reg); __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex); + if (ReturnTrueFalseObject()) { + __ LoadRoot(v0, Heap::kTrueValueRootIndex); + } } else { // Patch the call site to return true. __ LoadRoot(v0, Heap::kTrueValueRootIndex); @@ -1486,6 +1484,9 @@ void InstanceofStub::Generate(MacroAssembler* masm) { if (!HasCallSiteInlineCheck()) { __ li(v0, Operand(Smi::FromInt(1))); __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex); + if (ReturnTrueFalseObject()) { + __ LoadRoot(v0, Heap::kFalseValueRootIndex); + } } else { // Patch the call site to return false. __ LoadRoot(v0, Heap::kFalseValueRootIndex); @@ -1511,19 +1512,31 @@ void InstanceofStub::Generate(MacroAssembler* masm) { // Null is not instance of anything. __ Branch(&object_not_null, ne, object, Operand(isolate()->factory()->null_value())); - __ li(v0, Operand(Smi::FromInt(1))); + if (ReturnTrueFalseObject()) { + __ LoadRoot(v0, Heap::kFalseValueRootIndex); + } else { + __ li(v0, Operand(Smi::FromInt(1))); + } __ DropAndRet(HasArgsInRegisters() ? 0 : 2); __ bind(&object_not_null); // Smi values are not instances of anything. __ JumpIfNotSmi(object, &object_not_null_or_smi); - __ li(v0, Operand(Smi::FromInt(1))); + if (ReturnTrueFalseObject()) { + __ LoadRoot(v0, Heap::kFalseValueRootIndex); + } else { + __ li(v0, Operand(Smi::FromInt(1))); + } __ DropAndRet(HasArgsInRegisters() ? 0 : 2); __ bind(&object_not_null_or_smi); // String values are not instances of anything. __ IsObjectJSStringType(object, scratch, &slow); - __ li(v0, Operand(Smi::FromInt(1))); + if (ReturnTrueFalseObject()) { + __ LoadRoot(v0, Heap::kFalseValueRootIndex); + } else { + __ li(v0, Operand(Smi::FromInt(1))); + } __ DropAndRet(HasArgsInRegisters() ? 0 : 2); // Slow-case. Tail call builtin. diff --git a/src/mips64/constants-mips64.cc b/src/mips64/constants-mips64.cc index dfd62430c..dd34c57bf 100644 --- a/src/mips64/constants-mips64.cc +++ b/src/mips64/constants-mips64.cc @@ -287,6 +287,7 @@ Instruction::Type Instruction::InstructionType() const { switch (FunctionFieldRaw()) { case INS: case EXT: + case DEXT: return kRegisterType; default: return kUnsupported; diff --git a/src/mips64/deoptimizer-mips64.cc b/src/mips64/deoptimizer-mips64.cc index 2550b765b..f903f4656 100644 --- a/src/mips64/deoptimizer-mips64.cc +++ b/src/mips64/deoptimizer-mips64.cc @@ -101,9 +101,8 @@ void Deoptimizer::SetPlatformCompiledStubRegisters( ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_); intptr_t handler = reinterpret_cast(xref.address()); int params = descriptor->GetHandlerParameterCount(); - output_frame->SetRegister(s0.code(), params); - output_frame->SetRegister(s1.code(), (params - 1) * kPointerSize); - output_frame->SetRegister(s2.code(), handler); + output_frame->SetRegister(a0.code(), params); + output_frame->SetRegister(a1.code(), handler); } diff --git a/src/mips64/disasm-mips64.cc b/src/mips64/disasm-mips64.cc index d47950fd0..3f0642db2 100644 --- a/src/mips64/disasm-mips64.cc +++ b/src/mips64/disasm-mips64.cc @@ -963,6 +963,10 @@ int Decoder::DecodeTypeRegister(Instruction* instr) { Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); break; } + case DEXT: { + Format(instr, "dext 'rt, 'rs, 'sa, 'ss1"); + break; + } default: UNREACHABLE(); } diff --git a/src/mips64/macro-assembler-mips64.cc b/src/mips64/macro-assembler-mips64.cc index 45b190b53..8f0ae0908 100644 --- a/src/mips64/macro-assembler-mips64.cc +++ b/src/mips64/macro-assembler-mips64.cc @@ -22,7 +22,8 @@ namespace internal { MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) : Assembler(arg_isolate, buffer, size), generating_stub_(false), - has_frame_(false) { + has_frame_(false), + has_double_zero_reg_set_(false) { if (isolate() != NULL) { code_object_ = Handle(isolate()->heap()->undefined_value(), isolate()); @@ -712,6 +713,28 @@ void MacroAssembler::Mulh(Register rd, Register rs, const Operand& rt) { } +void MacroAssembler::Mulhu(Register rd, Register rs, const Operand& rt) { + if (rt.is_reg()) { + if (kArchVariant != kMips64r6) { + multu(rs, rt.rm()); + mfhi(rd); + } else { + muhu(rd, rs, rt.rm()); + } + } else { + // li handles the relocation. + DCHECK(!rs.is(at)); + li(at, rt); + if (kArchVariant != kMips64r6) { + multu(rs, at); + mfhi(rd); + } else { + muhu(rd, rs, at); + } + } +} + + void MacroAssembler::Dmul(Register rd, Register rs, const Operand& rt) { if (rt.is_reg()) { if (kArchVariant == kMips64r6) { @@ -816,6 +839,72 @@ void MacroAssembler::Div(Register rs, const Operand& rt) { } +void MacroAssembler::Div(Register res, Register rs, const Operand& rt) { + if (rt.is_reg()) { + if (kArchVariant != kMips64r6) { + div(rs, rt.rm()); + mflo(res); + } else { + div(res, rs, rt.rm()); + } + } else { + // li handles the relocation. + DCHECK(!rs.is(at)); + li(at, rt); + if (kArchVariant != kMips64r6) { + div(rs, at); + mflo(res); + } else { + div(res, rs, at); + } + } +} + + +void MacroAssembler::Mod(Register rd, Register rs, const Operand& rt) { + if (rt.is_reg()) { + if (kArchVariant != kMips64r6) { + div(rs, rt.rm()); + mfhi(rd); + } else { + mod(rd, rs, rt.rm()); + } + } else { + // li handles the relocation. + DCHECK(!rs.is(at)); + li(at, rt); + if (kArchVariant != kMips64r6) { + div(rs, at); + mfhi(rd); + } else { + mod(rd, rs, at); + } + } +} + + +void MacroAssembler::Modu(Register rd, Register rs, const Operand& rt) { + if (rt.is_reg()) { + if (kArchVariant != kMips64r6) { + divu(rs, rt.rm()); + mfhi(rd); + } else { + modu(rd, rs, rt.rm()); + } + } else { + // li handles the relocation. + DCHECK(!rs.is(at)); + li(at, rt); + if (kArchVariant != kMips64r6) { + divu(rs, at); + mfhi(rd); + } else { + modu(rd, rs, at); + } + } +} + + void MacroAssembler::Ddiv(Register rs, const Operand& rt) { if (rt.is_reg()) { ddiv(rs, rt.rm()); @@ -865,6 +954,28 @@ void MacroAssembler::Divu(Register rs, const Operand& rt) { } +void MacroAssembler::Divu(Register res, Register rs, const Operand& rt) { + if (rt.is_reg()) { + if (kArchVariant != kMips64r6) { + divu(rs, rt.rm()); + mflo(res); + } else { + divu(res, rs, rt.rm()); + } + } else { + // li handles the relocation. + DCHECK(!rs.is(at)); + li(at, rt); + if (kArchVariant != kMips64r6) { + divu(rs, at); + mflo(res); + } else { + divu(res, rs, at); + } + } +} + + void MacroAssembler::Ddivu(Register rs, const Operand& rt) { if (rt.is_reg()) { ddivu(rs, rt.rm()); @@ -877,6 +988,28 @@ void MacroAssembler::Ddivu(Register rs, const Operand& rt) { } +void MacroAssembler::Ddivu(Register res, Register rs, const Operand& rt) { + if (rt.is_reg()) { + if (kArchVariant != kMips64r6) { + ddivu(rs, rt.rm()); + mflo(res); + } else { + ddivu(res, rs, rt.rm()); + } + } else { + // li handles the relocation. + DCHECK(!rs.is(at)); + li(at, rt); + if (kArchVariant != kMips64r6) { + ddivu(rs, at); + mflo(res); + } else { + ddivu(res, rs, at); + } + } +} + + void MacroAssembler::Dmod(Register rd, Register rs, const Operand& rt) { if (kArchVariant != kMips64r6) { if (rt.is_reg()) { @@ -902,6 +1035,31 @@ void MacroAssembler::Dmod(Register rd, Register rs, const Operand& rt) { } +void MacroAssembler::Dmodu(Register rd, Register rs, const Operand& rt) { + if (kArchVariant != kMips64r6) { + if (rt.is_reg()) { + ddivu(rs, rt.rm()); + mfhi(rd); + } else { + // li handles the relocation. + DCHECK(!rs.is(at)); + li(at, rt); + ddivu(rs, at); + mfhi(rd); + } + } else { + if (rt.is_reg()) { + dmodu(rd, rs, rt.rm()); + } else { + // li handles the relocation. + DCHECK(!rs.is(at)); + li(at, rt); + dmodu(rd, rs, at); + } + } +} + + void MacroAssembler::And(Register rd, Register rs, const Operand& rt) { if (rt.is_reg()) { and_(rd, rs, rt.rm()); @@ -1004,27 +1162,10 @@ void MacroAssembler::Sltu(Register rd, Register rs, const Operand& rt) { void MacroAssembler::Ror(Register rd, Register rs, const Operand& rt) { - if (kArchVariant == kMips64r2) { - if (rt.is_reg()) { - rotrv(rd, rs, rt.rm()); - } else { - rotr(rd, rs, rt.imm64_); - } + if (rt.is_reg()) { + rotrv(rd, rs, rt.rm()); } else { - if (rt.is_reg()) { - subu(at, zero_reg, rt.rm()); - sllv(at, rs, at); - srlv(rd, rs, rt.rm()); - or_(rd, rd, at); - } else { - if (rt.imm64_ == 0) { - srl(rd, rs, 0); - } else { - srl(at, rs, rt.imm64_); - sll(rd, rs, (0x20 - rt.imm64_) & 0x1f); - or_(rd, rd, at); - } - } + rotr(rd, rs, rt.imm64_); } } @@ -1282,6 +1423,14 @@ void MacroAssembler::Ext(Register rt, } +void MacroAssembler::Dext(Register rt, Register rs, uint16_t pos, + uint16_t size) { + DCHECK(pos < 32); + DCHECK(pos + size < 33); + dext_(rt, rs, pos, size); +} + + void MacroAssembler::Ins(Register rt, Register rs, uint16_t pos, @@ -1573,10 +1722,9 @@ void MacroAssembler::Move(FPURegister dst, double imm) { static const DoubleRepresentation zero(0.0); DoubleRepresentation value_rep(imm); // Handle special values first. - bool force_load = dst.is(kDoubleRegZero); - if (value_rep == zero && !force_load) { + if (value_rep == zero && has_double_zero_reg_set_) { mov_d(dst, kDoubleRegZero); - } else if (value_rep == minus_zero && !force_load) { + } else if (value_rep == minus_zero && has_double_zero_reg_set_) { neg_d(dst, kDoubleRegZero); } else { uint32_t lo, hi; @@ -1597,6 +1745,7 @@ void MacroAssembler::Move(FPURegister dst, double imm) { } else { mthc1(zero_reg, dst); } + if (dst.is(kDoubleRegZero)) has_double_zero_reg_set_ = true; } } @@ -2001,18 +2150,26 @@ void MacroAssembler::BranchShort(int16_t offset, Condition cond, Register rs, b(offset); break; case eq: - // We don't want any other register but scratch clobbered. - DCHECK(!scratch.is(rs)); - r2 = scratch; - li(r2, rt); - beq(rs, r2, offset); + if (rt.imm64_ == 0) { + beq(rs, zero_reg, offset); + } else { + // We don't want any other register but scratch clobbered. + DCHECK(!scratch.is(rs)); + r2 = scratch; + li(r2, rt); + beq(rs, r2, offset); + } break; case ne: - // We don't want any other register but scratch clobbered. - DCHECK(!scratch.is(rs)); - r2 = scratch; - li(r2, rt); - bne(rs, r2, offset); + if (rt.imm64_ == 0) { + bne(rs, zero_reg, offset); + } else { + // We don't want any other register but scratch clobbered. + DCHECK(!scratch.is(rs)); + r2 = scratch; + li(r2, rt); + bne(rs, r2, offset); + } break; // Signed comparison. case greater: @@ -2254,18 +2411,28 @@ void MacroAssembler::BranchShort(Label* L, Condition cond, Register rs, b(offset); break; case eq: - DCHECK(!scratch.is(rs)); - r2 = scratch; - li(r2, rt); - offset = shifted_branch_offset(L, false); - beq(rs, r2, offset); + if (rt.imm64_ == 0) { + offset = shifted_branch_offset(L, false); + beq(rs, zero_reg, offset); + } else { + DCHECK(!scratch.is(rs)); + r2 = scratch; + li(r2, rt); + offset = shifted_branch_offset(L, false); + beq(rs, r2, offset); + } break; case ne: - DCHECK(!scratch.is(rs)); - r2 = scratch; - li(r2, rt); - offset = shifted_branch_offset(L, false); - bne(rs, r2, offset); + if (rt.imm64_ == 0) { + offset = shifted_branch_offset(L, false); + bne(rs, zero_reg, offset); + } else { + DCHECK(!scratch.is(rs)); + r2 = scratch; + li(r2, rt); + offset = shifted_branch_offset(L, false); + bne(rs, r2, offset); + } break; // Signed comparison. case greater: @@ -4368,6 +4535,33 @@ void MacroAssembler::SmiToDoubleFPURegister(Register smi, } +void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left, + const Operand& right, + Register overflow_dst, + Register scratch) { + if (right.is_reg()) { + AdduAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); + } else { + if (dst.is(left)) { + mov(scratch, left); // Preserve left. + daddiu(dst, left, right.immediate()); // Left is overwritten. + xor_(scratch, dst, scratch); // Original left. + // Load right since xori takes uint16 as immediate. + daddiu(t9, zero_reg, right.immediate()); + xor_(overflow_dst, dst, t9); + and_(overflow_dst, overflow_dst, scratch); + } else { + daddiu(dst, left, right.immediate()); + xor_(overflow_dst, dst, left); + // Load right since xori takes uint16 as immediate. + daddiu(t9, zero_reg, right.immediate()); + xor_(scratch, dst, t9); + and_(overflow_dst, scratch, overflow_dst); + } + } +} + + void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left, Register right, @@ -4410,6 +4604,33 @@ void MacroAssembler::AdduAndCheckForOverflow(Register dst, } +void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left, + const Operand& right, + Register overflow_dst, + Register scratch) { + if (right.is_reg()) { + SubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); + } else { + if (dst.is(left)) { + mov(scratch, left); // Preserve left. + daddiu(dst, left, -(right.immediate())); // Left is overwritten. + xor_(overflow_dst, dst, scratch); // scratch is original left. + // Load right since xori takes uint16 as immediate. + daddiu(t9, zero_reg, right.immediate()); + xor_(scratch, scratch, t9); // scratch is original left. + and_(overflow_dst, scratch, overflow_dst); + } else { + daddiu(dst, left, -(right.immediate())); + xor_(overflow_dst, dst, left); + // Load right since xori takes uint16 as immediate. + daddiu(t9, zero_reg, right.immediate()); + xor_(scratch, left, t9); + and_(overflow_dst, scratch, overflow_dst); + } + } +} + + void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left, Register right, diff --git a/src/mips64/macro-assembler-mips64.h b/src/mips64/macro-assembler-mips64.h index 4ef3e532f..95d6c785f 100644 --- a/src/mips64/macro-assembler-mips64.h +++ b/src/mips64/macro-assembler-mips64.h @@ -599,12 +599,19 @@ class MacroAssembler: public Assembler { DEFINE_INSTRUCTION(Addu); DEFINE_INSTRUCTION(Daddu); + DEFINE_INSTRUCTION(Div); + DEFINE_INSTRUCTION(Divu); + DEFINE_INSTRUCTION(Ddivu); + DEFINE_INSTRUCTION(Mod); + DEFINE_INSTRUCTION(Modu); DEFINE_INSTRUCTION(Ddiv); DEFINE_INSTRUCTION(Subu); DEFINE_INSTRUCTION(Dsubu); DEFINE_INSTRUCTION(Dmod); + DEFINE_INSTRUCTION(Dmodu); DEFINE_INSTRUCTION(Mul); DEFINE_INSTRUCTION(Mulh); + DEFINE_INSTRUCTION(Mulhu); DEFINE_INSTRUCTION(Dmul); DEFINE_INSTRUCTION(Dmulh); DEFINE_INSTRUCTION2(Mult); @@ -758,6 +765,7 @@ class MacroAssembler: public Assembler { // MIPS64 R2 instruction macro. void Ins(Register rt, Register rs, uint16_t pos, uint16_t size); void Ext(Register rt, Register rs, uint16_t pos, uint16_t size); + void Dext(Register rt, Register rs, uint16_t pos, uint16_t size); // --------------------------------------------------------------------------- // FPU macros. These do not handle special cases like NaN or +- inf. @@ -1168,12 +1176,20 @@ class MacroAssembler: public Assembler { Register overflow_dst, Register scratch = at); + void AdduAndCheckForOverflow(Register dst, Register left, + const Operand& right, Register overflow_dst, + Register scratch = at); + void SubuAndCheckForOverflow(Register dst, Register left, Register right, Register overflow_dst, Register scratch = at); + void SubuAndCheckForOverflow(Register dst, Register left, + const Operand& right, Register overflow_dst, + Register scratch = at); + void BranchOnOverflow(Label* label, Register overflow_check, BranchDelaySlot bd = PROTECT) { @@ -1198,13 +1214,10 @@ class MacroAssembler: public Assembler { // Runtime calls. // See comments at the beginning of CEntryStub::Generate. - inline void PrepareCEntryArgs(int num_args) { - li(s0, num_args); - li(s1, (num_args - 1) * kPointerSize); - } + inline void PrepareCEntryArgs(int num_args) { li(a0, num_args); } inline void PrepareCEntryFunction(const ExternalReference& ref) { - li(s2, Operand(ref)); + li(a1, Operand(ref)); } #define COND_ARGS Condition cond = al, Register rs = zero_reg, \ @@ -1720,6 +1733,7 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT bool generating_stub_; bool has_frame_; + bool has_double_zero_reg_set_; // This handle will be patched with the code object on installation. Handle code_object_; diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc index 00396656e..3351ac179 100644 --- a/src/mips64/simulator-mips64.cc +++ b/src/mips64/simulator-mips64.cc @@ -2088,7 +2088,8 @@ void Simulator::ConfigureTypeRegister(Instruction* instr, *i64hilo = rs * rt; break; case MULTU: - *u64hilo = static_cast(rs_u) * static_cast(rt_u); + *u64hilo = static_cast(rs_u & 0xffffffff) * + static_cast(rt_u & 0xffffffff); break; case DMULT: // DMULT == D_MUL_MUH. if (kArchVariant != kMips64r6) { @@ -2230,7 +2231,7 @@ void Simulator::ConfigureTypeRegister(Instruction* instr, // Interpret sa field as 5-bit lsb of insert. uint16_t lsb = sa; uint16_t size = msb - lsb + 1; - uint32_t mask = (1 << size) - 1; + uint64_t mask = (1ULL << size) - 1; *alu_out = (rt_u & ~(mask << lsb)) | ((rs_u & mask) << lsb); break; } @@ -2240,8 +2241,18 @@ void Simulator::ConfigureTypeRegister(Instruction* instr, // Interpret sa field as 5-bit lsb of extract. uint16_t lsb = sa; uint16_t size = msb + 1; - uint32_t mask = (1 << size) - 1; - *alu_out = (rs_u & (mask << lsb)) >> lsb; + uint64_t mask = (1ULL << size) - 1; + *alu_out = static_cast((rs_u & (mask << lsb)) >> lsb); + break; + } + case DEXT: { // Mips32r2 instruction. + // Interpret rd field as 5-bit msb of extract. + uint16_t msb = rd_reg; + // Interpret sa field as 5-bit lsb of extract. + uint16_t lsb = sa; + uint16_t size = msb + 1; + uint64_t mask = (1ULL << size) - 1; + *alu_out = static_cast((rs_u & (mask << lsb)) >> lsb); break; } default: @@ -2783,7 +2794,8 @@ void Simulator::DecodeTypeRegister(Instruction* instr) { TraceRegWr(alu_out); break; case EXT: - // Ext instr leaves result in Rt, rather than Rd. + case DEXT: + // Dext/Ext instr leaves result in Rt, rather than Rd. set_register(rt_reg, alu_out); TraceRegWr(alu_out); break; @@ -2815,9 +2827,9 @@ void Simulator::DecodeTypeImmediate(Instruction* instr) { int64_t ft = get_fpu_register(ft_reg); // Zero extended immediate. - uint32_t oe_imm16 = 0xffff & imm16; + uint64_t oe_imm16 = 0xffff & imm16; // Sign extended immediate. - int32_t se_imm16 = imm16; + int64_t se_imm16 = imm16; // Get current pc. int64_t current_pc = get_pc(); -- 2.34.1