Commit ca86a6f9 authored by Dusan Milosavljevic's avatar Dusan Milosavljevic

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}
parent ae9130eb
......@@ -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)
......
......@@ -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----------------
......
......@@ -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()));
}
......
......@@ -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.
......
......@@ -287,6 +287,7 @@ Instruction::Type Instruction::InstructionType() const {
switch (FunctionFieldRaw()) {
case INS:
case EXT:
case DEXT:
return kRegisterType;
default:
return kUnsupported;
......
......@@ -101,9 +101,8 @@ void Deoptimizer::SetPlatformCompiledStubRegisters(
ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_);
intptr_t handler = reinterpret_cast<intptr_t>(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);
}
......
......@@ -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();
}
......
This diff is collapsed.
......@@ -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<Object> code_object_;
......
......@@ -2088,7 +2088,8 @@ void Simulator::ConfigureTypeRegister(Instruction* instr,
*i64hilo = rs * rt;
break;
case MULTU:
*u64hilo = static_cast<uint64_t>(rs_u) * static_cast<uint64_t>(rt_u);
*u64hilo = static_cast<uint64_t>(rs_u & 0xffffffff) *
static_cast<uint64_t>(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<int32_t>((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<int64_t>((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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment