mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
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:
parent
d79015d4a4
commit
fcbd1a76a2
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -184,6 +184,8 @@ enum LoadStoreOpCode {
|
||||
LDR_Register = 0xb8600800,
|
||||
LDRB_Register = 0x38600800,
|
||||
LDRH_Register = 0x78600800,
|
||||
LDUR_Offset = 0xb8400000,
|
||||
STUR_Offset = 0xb8000000,
|
||||
};
|
||||
|
||||
enum AddrMode {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -697,7 +697,7 @@ struct BuiltinFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
|
||||
}
|
||||
size_t GetNumArgs()
|
||||
{
|
||||
return numArgs;
|
||||
return numArgs & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
alignas(EAS) FrameType type;
|
||||
|
Loading…
Reference in New Issue
Block a user