Commit 2ede7475 authored by Liu Yu's avatar Liu Yu Committed by V8 LUCI CQ

[loong64][mips][masm] Argument Count Consistency

Port commit 6bd44dfe
Port commit 89933af6
Port commit 255aaed9
Port commit 7511020b
Port commit aa259e30

Bug: v8:11112

Change-Id: Ia005a5da2d48505926a19a5d238b606826db1135
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3215372
Auto-Submit: Liu yu <liuyu@loongson.cn>
Reviewed-by: 's avatarPatrick Thier <pthier@chromium.org>
Commit-Queue: Patrick Thier <pthier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77338}
parent b4aa41d0
......@@ -349,7 +349,9 @@ declare_args() {
# enabled unconditionally.
v8_include_receiver_in_argc =
v8_current_cpu == "x86" || v8_current_cpu == "x64" ||
v8_current_cpu == "arm" || v8_current_cpu == "arm64"
v8_current_cpu == "arm" || v8_current_cpu == "arm64" ||
v8_current_cpu == "mips64el" || v8_current_cpu == "mipsel" ||
v8_current_cpu == "loong64"
}
# Derived defaults.
......
......@@ -483,8 +483,11 @@ void BaselineAssembler::EmitReturn(MacroAssembler* masm) {
__ masm()->LeaveFrame(StackFrame::BASELINE);
// Drop receiver + arguments.
__ masm()->Add_d(params_size, params_size, 1); // Include the receiver.
__ masm()->Alsl_d(sp, params_size, sp, kPointerSizeLog2);
__ masm()->DropArguments(params_size, TurboAssembler::kCountIsInteger,
kJSArgcIncludesReceiver
? TurboAssembler::kCountIncludesReceiver
: TurboAssembler::kCountExcludesReceiver);
__ masm()->Ret();
}
......
......@@ -499,8 +499,11 @@ void BaselineAssembler::EmitReturn(MacroAssembler* masm) {
__ masm()->LeaveFrame(StackFrame::BASELINE);
// Drop receiver + arguments.
__ masm()->Addu(params_size, params_size, 1); // Include the receiver.
__ masm()->Lsa(sp, sp, params_size, kPointerSizeLog2);
__ masm()->DropArguments(params_size, TurboAssembler::kCountIsInteger,
kJSArgcIncludesReceiver
? TurboAssembler::kCountIncludesReceiver
: TurboAssembler::kCountExcludesReceiver);
__ masm()->Ret();
}
......
......@@ -497,8 +497,11 @@ void BaselineAssembler::EmitReturn(MacroAssembler* masm) {
__ masm()->LeaveFrame(StackFrame::BASELINE);
// Drop receiver + arguments.
__ masm()->Daddu(params_size, params_size, 1); // Include the receiver.
__ masm()->Dlsa(sp, sp, params_size, kPointerSizeLog2);
__ masm()->DropArguments(params_size, TurboAssembler::kCountIsInteger,
kJSArgcIncludesReceiver
? TurboAssembler::kCountIncludesReceiver
: TurboAssembler::kCountExcludesReceiver);
__ masm()->Ret();
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -2808,6 +2808,46 @@ void TurboAssembler::StoreReturnAddressAndCall(Register target) {
DCHECK_EQ(kNumInstructionsToJump, InstructionsGeneratedSince(&find_ra));
}
void TurboAssembler::DropArguments(Register count, ArgumentsCountType type,
ArgumentsCountMode mode, Register scratch) {
switch (type) {
case kCountIsInteger: {
Alsl_d(sp, count, sp, kPointerSizeLog2);
break;
}
case kCountIsSmi: {
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
DCHECK_NE(scratch, no_reg);
SmiScale(scratch, count, kPointerSizeLog2);
Add_d(sp, sp, scratch);
break;
}
case kCountIsBytes: {
Add_d(sp, sp, count);
break;
}
}
if (mode == kCountExcludesReceiver) {
Add_d(sp, sp, kSystemPointerSize);
}
}
void TurboAssembler::DropArgumentsAndPushNewReceiver(Register argc,
Register receiver,
ArgumentsCountType type,
ArgumentsCountMode mode,
Register scratch) {
DCHECK(!AreAliased(argc, receiver));
if (mode == kCountExcludesReceiver) {
// Drop arguments without receiver and override old receiver.
DropArguments(argc, type, kCountIncludesReceiver, scratch);
St_d(receiver, MemOperand(sp, 0));
} else {
DropArguments(argc, type, mode, scratch);
Push(receiver);
}
}
void TurboAssembler::Ret(Condition cond, Register rj, const Operand& rk) {
Jump(ra, cond, rj, rk);
}
......@@ -2973,8 +3013,10 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
// If the expected parameter count is equal to the adaptor sentinel, no need
// to push undefined value as arguments.
Branch(&regular_invoke, eq, expected_parameter_count,
Operand(kDontAdaptArgumentsSentinel));
if (kDontAdaptArgumentsSentinel != 0) {
Branch(&regular_invoke, eq, expected_parameter_count,
Operand(kDontAdaptArgumentsSentinel));
}
// If overapplication or if the actual argument count is equal to the
// formal parameter count, no need to push extra undefined values.
......@@ -3001,7 +3043,11 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
Sub_d(t0, t0, Operand(1));
Add_d(src, src, Operand(kSystemPointerSize));
Add_d(dest, dest, Operand(kSystemPointerSize));
Branch(&copy, ge, t0, Operand(zero_reg));
if (kJSArgcIncludesReceiver) {
Branch(&copy, gt, t0, Operand(zero_reg));
} else {
Branch(&copy, ge, t0, Operand(zero_reg));
}
}
// Fill remaining expected arguments with undefined values.
......
......@@ -219,6 +219,15 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void Drop(int count, Condition cond = cc_always, Register reg = no_reg,
const Operand& op = Operand(no_reg));
enum ArgumentsCountMode { kCountIncludesReceiver, kCountExcludesReceiver };
enum ArgumentsCountType { kCountIsInteger, kCountIsSmi, kCountIsBytes };
void DropArguments(Register count, ArgumentsCountType type,
ArgumentsCountMode mode, Register scratch = no_reg);
void DropArgumentsAndPushNewReceiver(Register argc, Register receiver,
ArgumentsCountType type,
ArgumentsCountMode mode,
Register scratch = no_reg);
void Ld_d(Register rd, const MemOperand& rj);
void St_d(Register rd, const MemOperand& rj);
......@@ -420,6 +429,18 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void SmiUntag(Register reg) { SmiUntag(reg, reg); }
// Left-shifted from int32 equivalent of Smi.
void SmiScale(Register dst, Register src, int scale) {
if (SmiValuesAre32Bits()) {
// The int portion is upper 32-bits of 64-bit word.
srai_d(dst, src, kSmiShift - scale);
} else {
DCHECK(SmiValuesAre31Bits());
DCHECK_GE(scale, kSmiTagSize);
slli_w(dst, src, scale - kSmiTagSize);
}
}
// On LoongArch64, we should sign-extend 32-bit values.
void SmiToInt32(Register smi) {
if (FLAG_enable_slow_asserts) {
......@@ -989,18 +1010,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
void SmiTag(Register reg) { SmiTag(reg, reg); }
// Left-shifted from int32 equivalent of Smi.
void SmiScale(Register dst, Register src, int scale) {
if (SmiValuesAre32Bits()) {
// The int portion is upper 32-bits of 64-bit word.
srai_d(dst, src, kSmiShift - scale);
} else {
DCHECK(SmiValuesAre31Bits());
DCHECK_GE(scale, kSmiTagSize);
slli_w(dst, src, scale - kSmiTagSize);
}
}
// Test if the register contains a smi.
inline void SmiTst(Register value, Register scratch) {
And(scratch, value, Operand(kSmiTagMask));
......
......@@ -4074,6 +4074,43 @@ void TurboAssembler::BranchAndLinkLong(Label* L, BranchDelaySlot bdslot) {
}
}
void TurboAssembler::DropArguments(Register count, ArgumentsCountType type,
ArgumentsCountMode mode) {
switch (type) {
case kCountIsInteger: {
Lsa(sp, sp, count, kPointerSizeLog2);
break;
}
case kCountIsSmi: {
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
Lsa(sp, sp, count, kPointerSizeLog2 - kSmiTagSize, count);
break;
}
case kCountIsBytes: {
Addu(sp, sp, count);
break;
}
}
if (mode == kCountExcludesReceiver) {
Addu(sp, sp, kSystemPointerSize);
}
}
void TurboAssembler::DropArgumentsAndPushNewReceiver(Register argc,
Register receiver,
ArgumentsCountType type,
ArgumentsCountMode mode) {
DCHECK(!AreAliased(argc, receiver));
if (mode == kCountExcludesReceiver) {
// Drop arguments without receiver and override old receiver.
DropArguments(argc, type, kCountIncludesReceiver);
sw(receiver, MemOperand(sp));
} else {
DropArguments(argc, type, mode);
push(receiver);
}
}
void TurboAssembler::DropAndRet(int drop) {
int32_t drop_size = drop * kSystemPointerSize;
DCHECK(is_int31(drop_size));
......@@ -4340,8 +4377,10 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
// If the expected parameter count is equal to the adaptor sentinel, no need
// to push undefined value as arguments.
Branch(&regular_invoke, eq, expected_parameter_count,
Operand(kDontAdaptArgumentsSentinel));
if (kDontAdaptArgumentsSentinel != 0) {
Branch(&regular_invoke, eq, expected_parameter_count,
Operand(kDontAdaptArgumentsSentinel));
}
// If overapplication or if the actual argument count is equal to the
// formal parameter count, no need to push extra undefined values.
......@@ -4368,7 +4407,11 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
Subu(t0, t0, Operand(1));
Addu(src, src, Operand(kSystemPointerSize));
Addu(dest, dest, Operand(kSystemPointerSize));
Branch(&copy, ge, t0, Operand(zero_reg));
if (kJSArgcIncludesReceiver) {
Branch(&copy, gt, t0, Operand(zero_reg));
} else {
Branch(&copy, ge, t0, Operand(zero_reg));
}
}
// Fill remaining expected arguments with undefined values.
......
......@@ -257,6 +257,17 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void Drop(int count, Condition cond = cc_always, Register reg = no_reg,
const Operand& op = Operand(no_reg));
// We assume the size of the arguments is the pointer size.
// An optional mode argument is passed, which can indicate we need to
// explicitly add the receiver to the count.
enum ArgumentsCountMode { kCountIncludesReceiver, kCountExcludesReceiver };
enum ArgumentsCountType { kCountIsInteger, kCountIsSmi, kCountIsBytes };
void DropArguments(Register count, ArgumentsCountType type,
ArgumentsCountMode mode);
void DropArgumentsAndPushNewReceiver(Register argc, Register receiver,
ArgumentsCountType type,
ArgumentsCountMode mode);
// Trivial case of DropAndRet that utilizes the delay slot.
void DropAndRet(int drop);
......
......@@ -4593,6 +4593,46 @@ void TurboAssembler::BranchAndLinkLong(Label* L, BranchDelaySlot bdslot) {
}
}
void TurboAssembler::DropArguments(Register count, ArgumentsCountType type,
ArgumentsCountMode mode, Register scratch) {
switch (type) {
case kCountIsInteger: {
Dlsa(sp, sp, count, kPointerSizeLog2);
break;
}
case kCountIsSmi: {
STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
DCHECK_NE(scratch, no_reg);
SmiScale(scratch, count, kPointerSizeLog2);
Daddu(sp, sp, scratch);
break;
}
case kCountIsBytes: {
Daddu(sp, sp, count);
break;
}
}
if (mode == kCountExcludesReceiver) {
Daddu(sp, sp, kSystemPointerSize);
}
}
void TurboAssembler::DropArgumentsAndPushNewReceiver(Register argc,
Register receiver,
ArgumentsCountType type,
ArgumentsCountMode mode,
Register scratch) {
DCHECK(!AreAliased(argc, receiver));
if (mode == kCountExcludesReceiver) {
// Drop arguments without receiver and override old receiver.
DropArguments(argc, type, kCountIncludesReceiver, scratch);
Sd(receiver, MemOperand(sp));
} else {
DropArguments(argc, type, mode, scratch);
push(receiver);
}
}
void TurboAssembler::DropAndRet(int drop) {
int32_t drop_size = drop * kSystemPointerSize;
DCHECK(is_int31(drop_size));
......@@ -4862,8 +4902,10 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
// If the expected parameter count is equal to the adaptor sentinel, no need
// to push undefined value as arguments.
Branch(&regular_invoke, eq, expected_parameter_count,
Operand(kDontAdaptArgumentsSentinel));
if (kDontAdaptArgumentsSentinel != 0) {
Branch(&regular_invoke, eq, expected_parameter_count,
Operand(kDontAdaptArgumentsSentinel));
}
// If overapplication or if the actual argument count is equal to the
// formal parameter count, no need to push extra undefined values.
......@@ -4890,7 +4932,11 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
Dsubu(t0, t0, Operand(1));
Daddu(src, src, Operand(kSystemPointerSize));
Daddu(dest, dest, Operand(kSystemPointerSize));
Branch(&copy, ge, t0, Operand(zero_reg));
if (kJSArgcIncludesReceiver) {
Branch(&copy, gt, t0, Operand(zero_reg));
} else {
Branch(&copy, ge, t0, Operand(zero_reg));
}
}
// Fill remaining expected arguments with undefined values.
......
......@@ -280,6 +280,15 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void Drop(int count, Condition cond = cc_always, Register reg = no_reg,
const Operand& op = Operand(no_reg));
enum ArgumentsCountMode { kCountIncludesReceiver, kCountExcludesReceiver };
enum ArgumentsCountType { kCountIsInteger, kCountIsSmi, kCountIsBytes };
void DropArguments(Register count, ArgumentsCountType type,
ArgumentsCountMode mode, Register scratch = no_reg);
void DropArgumentsAndPushNewReceiver(Register argc, Register receiver,
ArgumentsCountType type,
ArgumentsCountMode mode,
Register scratch = no_reg);
// Trivial case of DropAndRet that utilizes the delay slot.
void DropAndRet(int drop);
......@@ -485,6 +494,18 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void SmiUntag(Register reg) { SmiUntag(reg, reg); }
// Left-shifted from int32 equivalent of Smi.
void SmiScale(Register dst, Register src, int scale) {
if (SmiValuesAre32Bits()) {
// The int portion is upper 32-bits of 64-bit word.
dsra(dst, src, kSmiShift - scale);
} else {
DCHECK(SmiValuesAre31Bits());
DCHECK_GE(scale, kSmiTagSize);
sll(dst, src, scale - kSmiTagSize);
}
}
// On MIPS64, we should sign-extend 32-bit values.
void SmiToInt32(Register smi) {
if (FLAG_enable_slow_asserts) {
......@@ -1175,18 +1196,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
void SmiTag(Register reg) { SmiTag(reg, reg); }
// Left-shifted from int32 equivalent of Smi.
void SmiScale(Register dst, Register src, int scale) {
if (SmiValuesAre32Bits()) {
// The int portion is upper 32-bits of 64-bit word.
dsra(dst, src, kSmiShift - scale);
} else {
DCHECK(SmiValuesAre31Bits());
DCHECK_GE(scale, kSmiTagSize);
sll(dst, src, scale - kSmiTagSize);
}
}
// Test if the register contains a smi.
inline void SmiTst(Register value, Register scratch) {
And(scratch, value, Operand(kSmiTagMask));
......
......@@ -2391,22 +2391,22 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
if (drop_jsargs) {
// We must pop all arguments from the stack (including the receiver). This
// number of arguments is given by max(1 + argc_reg, parameter_count).
__ Add_d(t0, t0, Operand(1)); // Also pop the receiver.
if (!kJSArgcIncludesReceiver) {
__ Add_d(t0, t0, Operand(1)); // Also pop the receiver.
}
if (parameter_slots > 1) {
__ li(t1, parameter_slots);
__ slt(t2, t0, t1);
__ Movn(t0, t1, t2);
}
__ slli_d(t0, t0, kSystemPointerSizeLog2);
__ add_d(sp, sp, t0);
__ Alsl_d(sp, t0, sp, kSystemPointerSizeLog2);
} else if (additional_pop_count->IsImmediate()) {
int additional_count = g.ToConstant(additional_pop_count).ToInt32();
__ Drop(parameter_slots + additional_count);
} else {
Register pop_reg = g.ToRegister(additional_pop_count);
__ Drop(parameter_slots);
__ slli_d(pop_reg, pop_reg, kSystemPointerSizeLog2);
__ add_d(sp, sp, pop_reg);
__ Alsl_d(sp, pop_reg, sp, kSystemPointerSizeLog2);
}
__ Ret();
}
......
......@@ -4142,14 +4142,15 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
if (drop_jsargs) {
// We must pop all arguments from the stack (including the receiver). This
// number of arguments is given by max(1 + argc_reg, parameter_slots).
__ Addu(t0, t0, Operand(1)); // Also pop the receiver.
if (!kJSArgcIncludesReceiver) {
__ Addu(t0, t0, Operand(1)); // Also pop the receiver.
}
if (parameter_slots > 1) {
__ li(kScratchReg, parameter_slots);
__ slt(kScratchReg2, t0, kScratchReg);
__ movn(t0, kScratchReg, kScratchReg2);
}
__ sll(t0, t0, kSystemPointerSizeLog2);
__ Addu(sp, sp, t0);
__ Lsa(sp, sp, t0, kSystemPointerSizeLog2, t0);
} else if (additional_pop_count->IsImmediate()) {
DCHECK_EQ(Constant::kInt32, g.ToConstant(additional_pop_count).type());
int additional_count = g.ToConstant(additional_pop_count).ToInt32();
......@@ -4157,8 +4158,7 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
} else {
Register pop_reg = g.ToRegister(additional_pop_count);
__ Drop(parameter_slots);
__ sll(pop_reg, pop_reg, kSystemPointerSizeLog2);
__ Addu(sp, sp, pop_reg);
__ Lsa(sp, sp, pop_reg, kSystemPointerSizeLog2, pop_reg);
}
__ Ret();
}
......
......@@ -4346,22 +4346,22 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
if (drop_jsargs) {
// We must pop all arguments from the stack (including the receiver). This
// number of arguments is given by max(1 + argc_reg, parameter_slots).
__ Daddu(t0, t0, Operand(1)); // Also pop the receiver.
if (!kJSArgcIncludesReceiver) {
__ Daddu(t0, t0, Operand(1)); // Also pop the receiver.
}
if (parameter_slots > 1) {
__ li(kScratchReg, parameter_slots);
__ slt(kScratchReg2, t0, kScratchReg);
__ movn(t0, kScratchReg, kScratchReg2);
}
__ dsll(t0, t0, kSystemPointerSizeLog2);
__ Daddu(sp, sp, t0);
__ Dlsa(sp, sp, t0, kSystemPointerSizeLog2);
} else if (additional_pop_count->IsImmediate()) {
int additional_count = g.ToConstant(additional_pop_count).ToInt32();
__ Drop(parameter_slots + additional_count);
} else {
Register pop_reg = g.ToRegister(additional_pop_count);
__ Drop(parameter_slots);
__ dsll(pop_reg, pop_reg, kSystemPointerSizeLog2);
__ Daddu(sp, sp, pop_reg);
__ Dlsa(sp, sp, pop_reg, kSystemPointerSizeLog2);
}
__ Ret();
}
......
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