Fix rsp frame on arm64

1. get 32bits of argc
2. add ldur&stur to support signed offset
Issue:https://gitee.com/openharmony/ark_js_runtime/issues/I5ASTO?from=project-issue

Signed-off-by: zhangyukun <zhangyukun8@huawei.com>
Change-Id: Id4a6bad2977611939ef5fbece5ae5a862cab6e34
This commit is contained in:
zhangyukun 2022-06-06 11:08:31 +08:00
parent d79015d4a4
commit fcbd1a76a2
6 changed files with 56 additions and 19 deletions

View File

@ -335,6 +335,30 @@ void AssemblerAarch64::Str(const Register &rt, const MemoryOperand &operand)
UNREACHABLE();
}
void AssemblerAarch64::Ldur(const Register &rt, const MemoryOperand &operand)
{
bool regX = !rt.IsW();
uint32_t op = LDUR_Offset;
ASSERT(operand.IsImmediateOffset());
uint64_t imm = static_cast<uint64_t>(operand.GetImmediate().Value());
// 30: 30bit indicate the size of LDUR Reg
uint32_t instructionCode = (regX << 30) | op | LoadAndStoreImm(imm, true)
| Rn(operand.GetRegBase().GetId()) | Rt(rt.GetId());
EmitU32(instructionCode);
}
void AssemblerAarch64::Stur(const Register &rt, const MemoryOperand &operand)
{
bool regX = !rt.IsW();
uint32_t op = STUR_Offset;
ASSERT(operand.IsImmediateOffset());
uint64_t imm = static_cast<uint64_t>(operand.GetImmediate().Value());
// 30: 30bit indicate the size of LDUR Reg
uint32_t instructionCode = (regX << 30) | op | LoadAndStoreImm(imm, true)
| Rn(operand.GetRegBase().GetId()) | Rt(rt.GetId());
EmitU32(instructionCode);
}
void AssemblerAarch64::Mov(const Register &rd, const Immediate &imm)
{
ASSERT_PRINT(!rd.IsSp(), "sp can't load immediate, please use add instruction");

View File

@ -291,6 +291,8 @@ public:
void Ldrh(const Register &rt, const MemoryOperand &operand);
void Ldrb(const Register &rt, const MemoryOperand &operand);
void Str(const Register &rt, const MemoryOperand &operand);
void Ldur(const Register &rt, const MemoryOperand &operand);
void Stur(const Register &rt, const MemoryOperand &operand);
void Mov(const Register &rd, const Immediate &imm);
void Mov(const Register &rd, const Register &rm);
void Movz(const Register &rd, uint64_t imm, int shift);

View File

@ -184,6 +184,8 @@ enum LoadStoreOpCode {
LDR_Register = 0xb8600800,
LDRB_Register = 0x38600800,
LDRH_Register = 0x78600800,
LDUR_Offset = 0xb8400000,
STUR_Offset = 0xb8000000,
};
enum AddrMode {

View File

@ -185,7 +185,9 @@ HWTEST_F_L0(AssemblerAarch64Test, LdrStr)
"00000014:38408fe1 \tldrb\tw1, [sp, #8]!\n"
"00000018:394023e1 \tldrb\tw1, [sp, #8]\n"
"0000001c:78408fe1 \tldrh\tw1, [sp, #8]!\n"
"00000020:794013e1 \tldrh\tw1, [sp, #8]\n");
"00000020:794013e1 \tldrh\tw1, [sp, #8]\n"
"00000024:f85f83e1 \tldur\tx1, [sp, #-8]\n"
"00000028:f81f83e3 \tstur\tx3, [sp, #-8]\n");
AssemblerAarch64 masm(chunk_);
__ Str(Register(X1), MemoryOperand(Register(SP), 8, POSTINDEX));
@ -197,6 +199,8 @@ HWTEST_F_L0(AssemblerAarch64Test, LdrStr)
__ Ldrb(Register(X1).W(), MemoryOperand(Register(SP), 8, OFFSET));
__ Ldrh(Register(X1).W(), MemoryOperand(Register(SP), 8, PREINDEX));
__ Ldrh(Register(X1).W(), MemoryOperand(Register(SP), 8, OFFSET));
__ Ldur(Register(X1), MemoryOperand(Register(SP), -8, OFFSET));
__ Stur(Register(X3), MemoryOperand(Register(SP), -8, OFFSET));
std::ostringstream oss;
DisassembleChunk("aarch64-unknown-linux-gnu", &masm, oss);
ASSERT_EQ(oss.str(), expectResult);

View File

@ -785,11 +785,11 @@ void AssemblerStubs::JSCallCommonEntry(ExtendedAssembler *assembler, JSCallMode
auto jumpSize = kungfu::AssemblerModule::GetJumpSizeFromJSCallMode(mode);
[[maybe_unused]] TempRegister1Scope scope1(assembler);
Register temp = __ TempRegister1();
[[maybe_unused]] TempRegister2Scope scope2(assembler);
Register frameStateRegister = __ TempRegister2();
__ Mov(temp, Immediate(static_cast<int>(jumpSize)));
__ Sub(frameStateRegister, Register(FP), Immediate(AsmInterpretedFrame::GetSize(false)));
__ Str(temp, MemoryOperand(frameStateRegister, AsmInterpretedFrame::GetCallSizeOffset(false)));
int64_t offset = static_cast<int64_t>(AsmInterpretedFrame::GetCallSizeOffset(false))
- static_cast<int64_t>(AsmInterpretedFrame::GetSize(false));
ASSERT(offset < 0);
__ Stur(temp, MemoryOperand(Register(FP), offset));
}
Register declaredNumArgsRegister = __ AvailableRegister2();
@ -815,7 +815,7 @@ void AssemblerStubs::JSCallCommonEntry(ExtendedAssembler *assembler, JSCallMode
// GHC calling convention
// Input1: for callarg0/1/2/3 Input2: for callrange
// X19 - glue // X19 - glue
// FP - sp // FP - sp
// FP - sp // FP - sp
// X20 - callTarget // X20 - callTarget
// X21 - method // X21 - method
// X22 - callField // X22 - callField
@ -997,7 +997,7 @@ void AssemblerStubs::CallIThisRangeNoExtraEntry(ExtendedAssembler *assembler)
__ Bind(&pushCallThis);
{
Register thisRegister = __ AvailableRegister2();
__ Ldr(thisRegister, MemoryOperand(argvRegister, -8)); // 8: this is just before the argv list
__ Ldur(thisRegister, MemoryOperand(argvRegister, -8)); // 8: this is just before the argv list
PushCallThis(assembler, thisRegister, false);
}
}
@ -1201,11 +1201,15 @@ void AssemblerStubs::ResumeRspAndDispatch(ExtendedAssembler *assembler)
Register opcode(X6, W);
Register bcStub(X7);
Register frameStateRegister(X16);
__ Sub(frameStateRegister, sp, Immediate(AsmInterpretedFrame::GetSize(false)));
__ Ldr(Register(SP), MemoryOperand(frameStateRegister, AsmInterpretedFrame::GetFpOffset(false))); // resume rsp
__ Ldr(sp, MemoryOperand(frameStateRegister, AsmInterpretedFrame::GetBaseOffset(false))); // update sp
int64_t fpOffset = static_cast<int64_t>(AsmInterpretedFrame::GetFpOffset(false))
- static_cast<int64_t>(AsmInterpretedFrame::GetSize(false));
int64_t spOffset = static_cast<int64_t>(AsmInterpretedFrame::GetBaseOffset(false))
- static_cast<int64_t>(AsmInterpretedFrame::GetSize(false));
ASSERT(fpOffset < 0);
ASSERT(spOffset < 0);
__ Ldur(Register(SP), MemoryOperand(sp, fpOffset)); // resume rsp
__ Ldur(sp, MemoryOperand(sp, spOffset)); // update sp
__ Add(pc, pc, Operand(jumpSize, LSL, 0));
__ Ldrb(opcode, MemoryOperand(pc, 0));
@ -1222,10 +1226,10 @@ void AssemblerStubs::ResumeRspAndReturn([[maybe_unused]] ExtendedAssembler *asse
[[maybe_unused]] TempRegister1Scope scope1(assembler);
Register fpRegister = __ TempRegister1();
[[maybe_unused]] TempRegister2Scope scope2(assembler);
Register frameStateRegister = __ TempRegister2();
__ Sub(frameStateRegister, Register(FP), Immediate(AsmInterpretedFrame::GetSize(false)));
__ Ldr(fpRegister, MemoryOperand(frameStateRegister, AsmInterpretedFrame::GetFpOffset(false)));
int64_t offset = static_cast<int64_t>(AsmInterpretedFrame::GetFpOffset(false))
- static_cast<int64_t>(AsmInterpretedFrame::GetSize(false));
ASSERT(offset < 0);
__ Ldur(fpRegister, MemoryOperand(Register(FP), offset));
__ Mov(sp, fpRegister);
// return
@ -1372,7 +1376,7 @@ void AssemblerStubs::CallIThisRangeEntry(ExtendedAssembler *assembler)
}
__ Bind(&pushCallThis);
Register thisRegister = __ AvailableRegister2();
__ Ldr(thisRegister, MemoryOperand(argvRegister, -8)); // 8: this is just before the argv list
__ Ldur(thisRegister, MemoryOperand(argvRegister, -8)); // 8: this is just before the argv list
PushCallThis(assembler, thisRegister, false);
}
@ -1600,6 +1604,7 @@ void AssemblerStubs::ConstructEcmaRuntimeCallInfo(ExtendedAssembler *assembler,
Register sp(SP);
__ Sub(sp, sp, Immediate(sizeof(EcmaRuntimeCallInfo)));
__ Str(thread, MemoryOperand(sp, EcmaRuntimeCallInfo::GetThreadOffset()));
__ And(numArgs, numArgs, LogicalImmediate::Create(0x00000000FFFFFFFF, RegXSize));
__ Str(numArgs, MemoryOperand(sp, EcmaRuntimeCallInfo::GetNumArgsOffset()));
__ Str(stackArgs, MemoryOperand(sp, EcmaRuntimeCallInfo::GetStackArgsOffset()));
}
@ -1705,8 +1710,8 @@ void AssemblerStubs::CallNativeEntry(ExtendedAssembler *assembler)
__ Ldr(nativeCode, MemoryOperand(method, JSMethod::GetBytecodeArrayOffset(false)));
CallNativeInternal(assembler, glue, argc, argv, nativeCode);
// 40: skip function
__ Add(sp, sp, Immediate(40));
// 32: skip function
__ Add(sp, sp, Immediate(32));
__ Ret();
}

View File

@ -697,7 +697,7 @@ struct BuiltinFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
}
size_t GetNumArgs()
{
return numArgs;
return numArgs & 0xFFFFFFFF;
}
alignas(EAS) FrameType type;