From 9ff0b5e1e995b571eb3fc81392f7c0f5ad484226 Mon Sep 17 00:00:00 2001 From: Alfred Huang Date: Thu, 7 Jul 2022 13:26:35 -0700 Subject: [PATCH 1/2] Merged in changes for new lmbc. --- .../include/cg/aarch64/aarch64_cgfunc.h | 14 +- src/mapleall/maple_be/include/cg/cgfunc.h | 2 +- .../src/cg/aarch64/aarch64_cgfunc.cpp | 243 ++++++++++-------- .../src/cg/aarch64/aarch64_memlayout.cpp | 32 +-- .../maple_be/src/cg/aarch64/aarch64_peep.cpp | 1 + .../src/cg/aarch64/aarch64_proepilog.cpp | 79 +++--- 6 files changed, 192 insertions(+), 179 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h index 63113da9e7..fa195c1b32 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -104,6 +104,7 @@ class AArch64CGFunc : public CGFunc { MIRType *LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList) const; RegOperand &GetOrCreateResOperand(const BaseNode &parent, PrimType primType); + MIRStructType *GetLmbcStructArgType(BaseNode &stmt, int32 argNo); void IntrinsifyGetAndAddInt(ListOperand &srcOpnds, PrimType pty); void IntrinsifyGetAndSetInt(ListOperand &srcOpnds, PrimType pty); @@ -128,8 +129,7 @@ class AArch64CGFunc : public CGFunc { MemOperand *FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx); uint32 LmbcFindTotalStkUsed(std::vector *paramList); uint32 LmbcTotalRegsUsed(); - void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, const Operand *src); + bool LmbcSmallAggForRet(BaseNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, const Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; @@ -875,7 +875,7 @@ class AArch64CGFunc : public CGFunc { void SelectParmListDreadSmallAggregate(const MIRSymbol &sym, MIRType &structType, ListOperand &srcOpnds, int32 offset, AArch64CallConvImpl &parmLocator, FieldID fieldID); - void SelectParmListIreadSmallAggregate(const IreadNode &iread, MIRType &structType, ListOperand &srcOpnds, + void SelectParmListIreadSmallAggregate(BaseNode &iread, MIRType &structType, ListOperand &srcOpnds, int32 offset, AArch64CallConvImpl &parmLocator); void SelectParmListDreadLargeAggregate(const MIRSymbol &sym, MIRType &structType, ListOperand &srcOpnds, @@ -884,12 +884,12 @@ class AArch64CGFunc : public CGFunc { AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, int32 fromOffset); void CreateCallStructMemcpyToParamReg(MIRType &structType, int32 structCopyOffset, AArch64CallConvImpl &parmLocator, ListOperand &srcOpnds); - void SelectParmListForAggregate(BaseNode &argExpr, ListOperand &srcOpnds, AArch64CallConvImpl &parmLocator, - int32 &structCopyOffset); + void SelectParmListForAggregate(BaseNode &parent, BaseNode &argExpr, ListOperand &srcOpnds, + AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, int32 argNo); size_t SelectParmListGetStructReturnSize(StmtNode &naryNode); bool MarkParmListCall(BaseNode &expr); - void SelectParmListPreprocessLargeStruct(BaseNode &argExpr, int32 &structCopyOffset); - void SelectParmListPreprocess(const StmtNode &naryNode, size_t start, std::set &specialArgs); + void SelectParmListPreprocessLargeStruct(BaseNode &parent, BaseNode &argExpr, int32 &structCopyOffset, int32 argNo); + void SelectParmListPreprocess(StmtNode &naryNode, size_t start, std::set &specialArgs); void SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bool isCallNative = false); Operand *SelectClearStackCallParam(const AddrofNode &expr, int64 &offsetValue); void SelectClearStackCallParmList(const StmtNode &naryNode, ListOperand &srcOpnds, diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index cace570fda..2b3fe3c4c7 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -1153,7 +1153,7 @@ class CGFunc { MapleMap vregsToPregsMap; uint32 totalInsns = 0; int32 structCopySize = 0; - int32 maxParamStackSize; + int32 maxParamStackSize = 0; static constexpr int kRegIncrStepLen = 80; /* reg number increate step length */ bool hasVLAOrAlloca = false; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp index 77a3a631a8..39a56d170e 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -160,6 +160,29 @@ bool IsBlkassignForPush(const BlkassignoffNode &bNode) { return spBased; } +MIRStructType *AArch64CGFunc::GetLmbcStructArgType(BaseNode &stmt, int32 argNo) { + MIRType *ty = nullptr; + if (stmt.GetOpCode() == OP_call) { + CallNode &callNode = static_cast(stmt); + MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode.GetPUIdx()); + if (callFunc->GetFormalCount() < (argNo + 1)) { + return nullptr; /* formals less than actuals */ + } + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(callFunc->GetFormalDefVec()[argNo].formalTyIdx); + } else if (stmt.GetOpCode() == OP_icallproto) { + argNo--; /* 1st opnd of icallproto is funcname, skip it relative to param list */ + IcallNode &icallproto = static_cast(stmt); + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallproto.GetRetTyIdx()); + MIRFuncType *fType = static_cast(type); + if (fType->GetParamTypeList().size() < (argNo + 1)) { + return nullptr; + } + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetNthParamType(argNo)); + } + CHECK_FATAL(ty && ty->IsStructType(), "lmbc agg arg error"); + return static_cast(ty); +} + RegOperand &AArch64CGFunc::GetOrCreateResOperand(const BaseNode &parent, PrimType primType) { RegOperand *resOpnd = nullptr; if (parent.GetOpCode() == OP_regassign) { @@ -2074,7 +2097,7 @@ MIRType *AArch64CGFunc::LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector(static_cast(src)->GetRegisterNumber()); @@ -2084,9 +2107,9 @@ bool AArch64CGFunc::LmbcSmallAggForRet(const BlkassignoffNode &bNode, const Oper /* This blkassignoff is for struct return? */ uint32 loadSize; uint32 numRegs = 0; - if (bNode.GetNext()->GetOpCode() == OP_return) { - MIRStructType *ty = static_cast( - GlobalTables::GetTypeTable().GetTypeFromTyIdx(func->GetFuncRetStructTyIdx())); + if (static_cast(bNode).GetNext()->GetOpCode() == OP_return) { + MIRStructType *ty = static_cast(func->GetReturnType()); + uint32 tySize = GetBecommon().GetTypeSize(ty->GetTypeIndex()); uint32 fpregs = FloatParamRegRequired(ty, size); if (fpregs > 0) { /* pure floating point in agg */ @@ -2105,7 +2128,7 @@ bool AArch64CGFunc::LmbcSmallAggForRet(const BlkassignoffNode &bNode, const Oper numRegs = 2; pTy = PTY_i64; size = k4ByteSize; - switch (bNode.blockSize) { + switch (tySize) { case 1: pTy = PTY_i8; break; @@ -2123,7 +2146,7 @@ bool AArch64CGFunc::LmbcSmallAggForRet(const BlkassignoffNode &bNode, const Oper MemOperand &mem = CreateMemOpnd(regno, 0, size * kBitsPerByte); RegOperand *res = &GetOrCreatePhysicalRegisterOperand(R0, loadSize, kRegTyInt); SelectCopy(*res, pTy, mem, pTy); - if (bNode.blockSize > static_cast(k8ByteSize)) { + if (tySize > static_cast(k8ByteSize)) { MemOperand &newMem = CreateMemOpnd(regno, k8ByteSize, size * kBitsPerByte); res = &GetOrCreatePhysicalRegisterOperand(R1, loadSize, kRegTyInt); SelectCopy(*res, pTy, newMem, pTy); @@ -3174,9 +3197,20 @@ Operand *AArch64CGFunc::SelectIreadoff(const BaseNode &parent, IreadoffNode &ire auto *baseAddr = ireadoff.Opnd(0); auto *result = &CreateRegisterOperandOfType(primType); auto *addrOpnd = HandleExpr(ireadoff, *baseAddr); - auto &memOpnd = CreateMemOpnd(LoadIntoRegister(*addrOpnd, PTY_a64), offset, bitSize); - auto mop = PickLdInsn(bitSize, primType); - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mop, *result, memOpnd)); + if (primType == PTY_agg && parent.GetOpCode() == OP_regassign) { + auto &memOpnd = CreateMemOpnd(LoadIntoRegister(*addrOpnd, PTY_a64), offset, bitSize); + auto mop = PickLdInsn(64, PTY_a64); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mop, *result, memOpnd)); + auto ®AssignNode = static_cast(parent); + PregIdx pIdx = regAssignNode.GetRegIdx(); + CHECK_FATAL(IsSpecialPseudoRegister(pIdx), "SelectIreadfpoff of agg"); + LmbcSmallAggForRet(const_cast(parent), addrOpnd); + // result not used + } else { + auto &memOpnd = CreateMemOpnd(LoadIntoRegister(*addrOpnd, PTY_a64), offset, bitSize); + auto mop = PickLdInsn(bitSize, primType); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mop, *result, memOpnd)); + } return result; } @@ -3228,35 +3262,13 @@ Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode int32 offset = ireadoff.GetOffset(); PrimType primType = ireadoff.GetPrimType(); uint32 bytelen = GetPrimTypeSize(primType); - uint32 bitlen = bytelen * kBitsPerByte; RegType regty = GetRegTyFromPrimTy(primType); RegOperand *result = nullptr; - if (offset >= 0) { - LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(static_cast(offset)); - ASSERT(info != nullptr, "info should not be nullptr"); - if (info->GetPrimType() == PTY_agg) { - if (info->IsOnStack()) { - result = GenLmbcParamLoad(info->GetOnStackOffset(), GetPrimTypeSize(PTY_a64), kRegTyInt, PTY_a64); - regno_t baseRegno = result->GetRegisterNumber(); - result = GenLmbcParamLoad(offset - static_cast(info->GetOffset()), - bytelen, regty, primType, static_cast(baseRegno)); - } else if (primType == PTY_agg) { - CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); - result = LmbcStructReturnLoad(offset); - } else { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); - } - } else { - CHECK_FATAL(primType == info->GetPrimType(), "Incorrect primtype"); - CHECK_FATAL(offset == info->GetOffset(), "Incorrect offset"); - if (info->GetRegNO() == 0 || !info->HasRegassign()) { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); - } else { - result = &GetOrCreatePhysicalRegisterOperand(static_cast(info->GetRegNO()), bitlen, regty); - } - } + if (offset > 0) { + CHECK_FATAL(0, "Invalid ireadfpoff offset"); } else { if (primType == PTY_agg) { + /* agg return */ CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); result = LmbcStructReturnLoad(offset); } else { @@ -7486,12 +7498,26 @@ void AArch64CGFunc::SelectParmListDreadSmallAggregate(const MIRSymbol &sym, MIRT } } -void AArch64CGFunc::SelectParmListIreadSmallAggregate(const IreadNode &iread, MIRType &structType, +void AArch64CGFunc::SelectParmListIreadSmallAggregate(BaseNode &iread, MIRType &structType, ListOperand &srcOpnds, int32 offset, AArch64CallConvImpl &parmLocator) { int32 symSize = GetBecommon().GetTypeSize(structType.GetTypeIndex().GetIdx()); - RegOperand *addrOpnd0 = static_cast(HandleExpr(iread, *(iread.Opnd(0)))); - RegOperand *addrOpnd1 = &LoadIntoRegister(*addrOpnd0, iread.Opnd(0)->GetPrimType()); + RegOperand *addrOpnd1; + if (iread.GetOpCode() == OP_iread) { + RegOperand *addrOpnd0 = static_cast(HandleExpr(iread, *(iread.Opnd(0)))); + addrOpnd1 = &LoadIntoRegister(*addrOpnd0, iread.Opnd(0)->GetPrimType()); + } else if (iread.GetOpCode() == OP_ireadfpoff) { + IreadFPoffNode &ireadoff = static_cast(iread); + RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); + RegOperand *addrOpnd0 = &CreateRegisterOperandOfType(PTY_a64); + ImmOperand &immOpnd = CreateImmOperand(ireadoff.GetOffset(), k32BitSize, true); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xaddrri12, *addrOpnd0, *rfp, immOpnd)); + addrOpnd1 = &LoadIntoRegister(*addrOpnd0, PTY_i64); + } else if (iread.GetOpCode() == OP_ireadoff) { + IreadoffNode &ireadoff = static_cast(iread); + RegOperand *addrOpnd0 = static_cast(HandleExpr(ireadoff, *(ireadoff.Opnd(0)))); + addrOpnd1 = &LoadIntoRegister(*addrOpnd0, PTY_i64); + } CCLocInfo ploc; parmLocator.LocateNextParm(structType, ploc); if (ploc.reg0 == 0) { @@ -7864,8 +7890,8 @@ void AArch64CGFunc::CreateCallStructMemcpyToParamReg(MIRType &structType, int32 } } -void AArch64CGFunc::SelectParmListForAggregate(BaseNode &argExpr, ListOperand &srcOpnds, - AArch64CallConvImpl &parmLocator, int32 &structCopyOffset) { +void AArch64CGFunc::SelectParmListForAggregate(BaseNode &parent, BaseNode &argExpr, ListOperand &srcOpnds, + AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, int32 argNo) { uint64 symSize; int32 rhsOffset = 0; if (argExpr.GetOpCode() == OP_dread) { @@ -7913,6 +7939,32 @@ void AArch64CGFunc::SelectParmListForAggregate(BaseNode &argExpr, ListOperand &s } else { SelectParmListIreadLargeAggregate(iread, *ty, srcOpnds, parmLocator, structCopyOffset, rhsOffset); } + } else if (argExpr.GetOpCode() == OP_ireadfpoff) { + IreadFPoffNode &iread = static_cast(argExpr); + MIRStructType *ty = GetLmbcStructArgType(parent, argNo); + if (ty == nullptr) { /* param < arg */ + return; + } + symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex().GetIdx()); + if (symSize <= k16ByteSize) { + SelectParmListIreadSmallAggregate(iread, *ty, srcOpnds, rhsOffset, parmLocator); + } else { + CreateCallStructMemcpyToParamReg(*ty, structCopyOffset, parmLocator, srcOpnds); + structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); + } + } else if (argExpr.GetOpCode() == OP_ireadoff) { + IreadoffNode &iread = static_cast(argExpr); + MIRStructType *ty = GetLmbcStructArgType(parent, argNo); + if (ty == nullptr) { + return; + } + symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex().GetIdx()); + if (symSize <= k16ByteSize) { + SelectParmListIreadSmallAggregate(iread, *ty, srcOpnds, rhsOffset, parmLocator); + } else { + CreateCallStructMemcpyToParamReg(*ty, structCopyOffset, parmLocator, srcOpnds); + structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); + } } else { CHECK_FATAL(false, "NYI"); } @@ -7956,7 +8008,7 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { return 0; } -void AArch64CGFunc::SelectParmListPreprocessLargeStruct(BaseNode &argExpr, int32 &structCopyOffset) { +void AArch64CGFunc::SelectParmListPreprocessLargeStruct(BaseNode &parent, BaseNode &argExpr, int32 &structCopyOffset, int32 argNo) { uint64 symSize; int32 rhsOffset = 0; if (argExpr.GetOpCode() == OP_dread) { @@ -8003,6 +8055,29 @@ void AArch64CGFunc::SelectParmListPreprocessLargeStruct(BaseNode &argExpr, int32 uint32 numMemOp = static_cast(RoundUp(symSize, kSizeOfPtr) / kSizeOfPtr); structCopyOffset += static_cast(numMemOp * kSizeOfPtr); } + } else if (argExpr.GetOpCode() == OP_ireadfpoff) { + IreadFPoffNode &ireadoff = static_cast(argExpr); + MIRStructType *ty = GetLmbcStructArgType(parent, argNo); + symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex()); + if (symSize > 16 /*kParmMemcpySize*/) { + RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); + RegOperand *addrOpnd = &CreateRegisterOperandOfType(PTY_a64); + ImmOperand &immOpnd = CreateImmOperand(ireadoff.GetOffset(), k32BitSize, true); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xaddrri12, *addrOpnd, *rfp, immOpnd)); + CreateCallStructParamMemcpy(nullptr, addrOpnd, static_cast(symSize), structCopyOffset, 0); + structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); + } + } else if (argExpr.GetOpCode() == OP_ireadoff) { + IreadoffNode &ireadoff = static_cast(argExpr); + MIRStructType *ty = GetLmbcStructArgType(parent, argNo); + symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex()); + if (symSize > 16 /*kParmMemcpySize*/) { + RegOperand *addrOpnd = static_cast( + HandleExpr(ireadoff, *(ireadoff.Opnd(0)))); + CreateCallStructParamMemcpy(nullptr, addrOpnd, + static_cast(symSize), structCopyOffset, 0); + structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); + } } } @@ -8034,7 +8109,7 @@ bool AArch64CGFunc::MarkParmListCall(BaseNode &expr) { return false; } -void AArch64CGFunc::SelectParmListPreprocess(const StmtNode &naryNode, size_t start, std::set &specialArgs) { +void AArch64CGFunc::SelectParmListPreprocess(StmtNode &naryNode, size_t start, std::set &specialArgs) { size_t i = start; int32 structCopyOffset = GetMaxParamStackSize() - GetStructCopySize(); for (; i < naryNode.NumOpnds(); ++i) { @@ -8047,7 +8122,7 @@ void AArch64CGFunc::SelectParmListPreprocess(const StmtNode &naryNode, size_t st if (primType != PTY_agg) { continue; } - SelectParmListPreprocessLargeStruct(*argExpr, structCopyOffset); + SelectParmListPreprocessLargeStruct(naryNode, *argExpr, structCopyOffset, i); } } @@ -8148,7 +8223,7 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo } /* use alloca */ if (primType == PTY_agg) { - SelectParmListForAggregate(*argExpr, srcOpnds, parmLocator, structCopyOffset); + SelectParmListForAggregate(naryNode, *argExpr, srcOpnds, parmLocator, structCopyOffset, i); continue; } ty = GlobalTables::GetTypeTable().GetTypeTable()[static_cast(primType)]; @@ -8560,56 +8635,6 @@ void AArch64CGFunc::IntrinsifyStringIndexOf(ListOperand &srcOpnds, const MIRSymb SetCurBB(*jointBB); } -/* Lmbc calls have no argument, they are all explicit iassignspoff or - blkassign. Info collected and to be emitted here */ -void AArch64CGFunc::LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn) { - if (GetLmbcArgInfo() == nullptr) { - return; /* no arg */ - } - CHECK_FATAL(GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc, "To be called for Lmbc model only"); - MapleVector &args = GetLmbcCallArgs(); - MapleVector &types = GetLmbcCallArgTypes(); - MapleVector &offsets = GetLmbcCallArgOffsets(); - MapleVector ®s = GetLmbcCallArgNumOfRegs(); - int iCnt = 0; - int fCnt = 0; - for (size_t i = isArgReturn ? 1 : 0; i < args.size(); i++) { - RegType ty = args[i]->GetRegisterType(); - PrimType pTy = types[i]; - AArch64reg reg; - if (args[i]->IsOfIntClass() && (iCnt + regs[i]) <= static_cast(k8ByteSize)) { - reg = static_cast(R0 + iCnt++); - RegOperand *res = &GetOrCreatePhysicalRegisterOperand( - reg, GetPrimTypeSize(pTy) * kBitsPerByte, ty); - SelectCopy(*res, pTy, *args[i], pTy); - srcOpnds->PushOpnd(*res); - } else if (!args[i]->IsOfIntClass() && (fCnt + regs[i]) <= static_cast(k8ByteSize)) { - reg = static_cast(V0 + fCnt++); - RegOperand *res = &GetOrCreatePhysicalRegisterOperand( - reg, GetPrimTypeSize(pTy) * kBitsPerByte, ty); - SelectCopy(*res, pTy, *args[i], pTy); - srcOpnds->PushOpnd(*res); - } else { - uint32 pSize = GetPrimTypeSize(pTy); - Operand &memOpd = CreateMemOpnd(RSP, offsets[i], pSize); - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(PickStInsn(pSize * kBitsPerByte, pTy), - *args[i], memOpd)); - } - } - /* Load x8 if 1st arg is for agg return */ - if (isArgReturn) { - AArch64reg reg = static_cast(R8); - RegOperand *res = &GetOrCreatePhysicalRegisterOperand(reg, - GetPrimTypeSize(PTY_a64) * kBitsPerByte, - kRegTyInt); - SelectCopy(*res, PTY_a64, *args[0], PTY_a64); - srcOpnds->PushOpnd(*res); - } - ResetLmbcArgInfo(); /* reset */ - ResetLmbcArgsInRegs(); - ResetLmbcTotalArgs(); -} - void AArch64CGFunc::SelectCall(CallNode &callNode) { MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode.GetPUIdx()); MIRSymbol *fsym = GetFunction().GetLocalOrGlobalSymbol(fn->GetStIdx(), false); @@ -8634,7 +8659,6 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { MIRType *ty = fn->GetReturnType(); SetLmbcCallReturnType(ty); } - LmbcSelectParmList(srcOpnds, largeStructRet); } bool callNative = false; if ((fsym->GetName() == "MCC_CallFastNative") || (fsym->GetName() == "MCC_CallFastNativeExt") || @@ -9565,7 +9589,11 @@ Operand *AArch64CGFunc::GetBaseReg(const AArch64SymbolAlloc &symAlloc) { } if (fsp == nullptr) { - fsp = &GetOrCreatePhysicalRegisterOperand(RFP, kSizeOfPtr * kBitsPerByte, kRegTyInt); + if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + fsp = &GetOrCreatePhysicalRegisterOperand(RSP, kSizeOfPtr * kBitsPerByte, kRegTyInt); + } else { + fsp = &GetOrCreatePhysicalRegisterOperand(RFP, kSizeOfPtr * kBitsPerByte, kRegTyInt); + } } return fsp; } @@ -9583,20 +9611,34 @@ int32 AArch64CGFunc::GetBaseOffset(const SymbolAlloc &symbolAlloc) { int32 offset = static_cast(symAlloc->GetOffset()); return offset; } else if (sgKind == kMsArgsRegPassed) { - int32 baseOffset = memLayout->GetSizeOfLocals() + symAlloc->GetOffset() + memLayout->GetSizeOfRefLocals(); + int32 baseOffset; + if (GetCG()->IsLmbc()) { + baseOffset = symAlloc->GetOffset() + memLayout->GetSizeOfRefLocals() + + memLayout->SizeOfArgsToStackPass(); /* SP relative */ + } else { + baseOffset = memLayout->GetSizeOfLocals() + symAlloc->GetOffset() + + memLayout->GetSizeOfRefLocals(); + } return baseOffset + sizeofFplr; } else if (sgKind == kMsRefLocals) { int32 baseOffset = symAlloc->GetOffset() + memLayout->GetSizeOfLocals(); return baseOffset + sizeofFplr; } else if (sgKind == kMsLocals) { + if (GetCG()->IsLmbc()) { + CHECK_FATAL(false, "invalid lmbc's locals"); + } int32 baseOffset = symAlloc->GetOffset(); return baseOffset + sizeofFplr; } else if (sgKind == kMsSpillReg) { + int32 baseOffset; if (GetCG()->IsLmbc()) { - return symAlloc->GetOffset() + memLayout->SizeOfArgsToStackPass(); + baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + + memLayout->GetSizeOfRefLocals() + + memLayout->SizeOfArgsToStackPass(); + } else { + baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + + memLayout->GetSizeOfLocals() + memLayout->GetSizeOfRefLocals(); } - int32 baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + memLayout->GetSizeOfLocals() + - memLayout->GetSizeOfRefLocals(); return baseOffset + sizeofFplr; } else if (sgKind == kMsArgsToStkPass) { /* this is for callers */ return static_cast(symAlloc->GetOffset()); @@ -10270,9 +10312,6 @@ void AArch64CGFunc::SelectCVaStart(const IntrinsiccallNode &intrnNode) { inReg++; } } - if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - stkSize += (inReg * k8ByteSize); - } if (CGOptions::IsArm64ilp32()) { stkSize = static_cast(RoundUp(stkSize, k8ByteSize)); } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 3cd486deb1..0cadfda6c1 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -58,7 +58,9 @@ uint32 AArch64MemLayout::ComputeStackSpaceRequirementForCall(StmtNode &stmt, in ty = GlobalTables::GetTypeTable().GetTypeTable()[static_cast(opnd->GetPrimType())]; } else { Opcode opndOpcode = opnd->GetOpCode(); - ASSERT(opndOpcode == OP_dread || opndOpcode == OP_iread, "opndOpcode should be OP_dread or OP_iread"); + if (be.GetMIRModule().GetFlavor() != kFlavorLmbc) { + ASSERT(opndOpcode == OP_dread || opndOpcode == OP_iread, "opndOpcode should be OP_dread or OP_iread"); + } if (opndOpcode == OP_dread) { DreadNode *dread = static_cast(opnd); MIRSymbol *sym = be.GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(dread->GetStIdx()); @@ -72,8 +74,7 @@ uint32 AArch64MemLayout::ComputeStackSpaceRequirementForCall(StmtNode &stmt, in ty = static_cast(ty)->GetFieldType(dread->GetFieldID()); } } - } else { - /* OP_iread */ + } else if (opndOpcode == OP_iread) { IreadNode *iread = static_cast(opnd); ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); ASSERT(ty->GetKind() == kTypePointer, "expect pointer"); @@ -87,6 +88,11 @@ uint32 AArch64MemLayout::ComputeStackSpaceRequirementForCall(StmtNode &stmt, in ty = static_cast(ty)->GetFieldType(iread->GetFieldID()); } } + } else if ((opndOpcode == OP_ireadfpoff || opndOpcode == OP_ireadoff || opndOpcode == OP_dreadoff) && opnd->GetPrimType() == PTY_agg) { + ty = static_cast(cgFunc)->GetLmbcStructArgType(stmt, i); + } + if (ty == nullptr) { /* type mismatch */ + continue; } } CCLocInfo ploc; @@ -190,18 +196,6 @@ void AArch64MemLayout::LayoutVarargParams() { } void AArch64MemLayout::LayoutFormalParams() { - bool isLmbc = (be.GetMIRModule().GetFlavor() == kFlavorLmbc); - if (isLmbc && mirFunction->GetFormalCount() == 0) { - /* - * lmbc : upformalsize - size of formals passed from caller's frame into current function - * framesize - total frame size of current function used by Maple IR - * outparmsize - portion of frame size of current function used by call parameters - */ - segArgsStkPassed.SetSize(mirFunction->GetOutParmSize()); - segArgsRegPassed.SetSize(mirFunction->GetOutParmSize()); - return; - } - AArch64CallConvImpl parmLocator(be); CCLocInfo ploc; for (size_t i = 0; i < mirFunction->GetFormalCount(); ++i) { @@ -255,8 +249,6 @@ void AArch64MemLayout::LayoutFormalParams() { segArgsRegPassed.SetSize(static_cast(RoundUp(segArgsRegPassed.GetSize(), align))); symLoc->SetOffset(segArgsRegPassed.GetSize()); segArgsRegPassed.SetSize(segArgsRegPassed.GetSize() + size); - } else if (isLmbc) { - segArgsRegPassed.SetSize(segArgsRegPassed.GetSize() + k8ByteSize); } } else { /* stack */ uint32 size; @@ -371,11 +363,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, symLoc->SetOffset(segRefLocals.GetSize()); segRefLocals.SetSize(segRefLocals.GetSize() + be.GetTypeSize(tyIdx)); } - if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { - segArgsToStkPass.SetSize(mirFunction->GetOutParmSize() + kDivide2 * k8ByteSize); - } else { - segArgsToStkPass.SetSize(FindLargestActualArea(structCopySize)); - } + segArgsToStkPass.SetSize(FindLargestActualArea(structCopySize)); maxParmStackSize = static_cast(segArgsToStkPass.GetSize()); if (Globals::GetInstance()->GetOptimLevel() == 0) { AssignSpillLocationsToPseudoRegisters(); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp index 37efee5dda..c5910d55c8 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp @@ -2515,6 +2515,7 @@ void EnhanceStrLdrAArch64::Run(BB &bb, Insn &insn) { auto &ofstOpnd = static_cast(prevInsn->GetOperand(kInsnThirdOpnd)); OfstOperand &offOpnd = static_cast(cgFunc).GetOrCreateOfstOpnd( static_cast(ofstOpnd.GetValue()), k32BitSize); + offOpnd.SetVary(ofstOpnd.GetVary()); auto *origOffOpnd = concreteMemOpnd.GetOffsetImmediate(); concreteMemOpnd.SetOffsetOperand(offOpnd); if (!static_cast(cgFunc).IsOperandImmValid(insn.GetMachineOpcode(), &memOpnd, kInsnSecondOpnd)) { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index c4d04bfefc..b3f5b0fb58 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -344,7 +344,9 @@ void AArch64GenProEpilog::GenStackGuard(BB &bb) { cgFunc.GetCurBB()->AppendInsn(insn); uint64 vArea = 0; - if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + if (cgFunc.GetMirModule().IsCModule() && + cgFunc.GetFunction().GetAttr(FUNCATTR_varargs) && + cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { AArch64MemLayout *ml = static_cast(cgFunc.GetMemlayout()); if (ml->GetSizeOfGRSaveArea() > 0) { vArea += RoundUp(ml->GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); @@ -401,7 +403,9 @@ BB &AArch64GenProEpilog::GenStackGuardCheckInsn(BB &bb) { cgFunc.GetCurBB()->AppendInsn(insn); uint64 vArea = 0; - if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + if (cgFunc.GetMirModule().IsCModule() && + cgFunc.GetFunction().GetAttr(FUNCATTR_varargs) && + cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { AArch64MemLayout *ml = static_cast(cgFunc.GetMemlayout()); if (ml->GetSizeOfGRSaveArea() > 0) { vArea += RoundUp(ml->GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); @@ -1115,9 +1119,6 @@ void AArch64GenProEpilog::AppendInstructionAllocateCallFrameDebug(AArch64reg reg ipoint = cgFunc.GetCurBB()->GetLastInsn(); cfiOffset = stackFrameSize; (void)InsertCFIDefCfaOffset(cfiOffset, *ipoint); - if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - argsToStkPassSize -= (kDivide2 * k8ByteSize); - } ipoint = &CreateAndAppendInstructionForAllocateCallFrame(argsToStkPassSize, reg0, reg1, rty); CHECK_FATAL(ipoint != nullptr, "ipoint should not be nullptr at this point"); cfiOffset = GetOffsetFromCFA(); @@ -1256,8 +1257,10 @@ void AArch64GenProEpilog::GeneratePushRegs() { AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); int32 offset; if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - offset = static_cast((memLayout->RealStackFrameSize() - - aarchCGFunc.SizeOfCalleeSaved()) - memLayout->GetSizeOfLocals()); + offset = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen)/* FP/LR */) - + memLayout->GetSizeOfLocals()); /* SizeOfArgsToStackPass not deducted since + AdjustmentStackPointer() is not called for lmbc */ } else { offset = static_cast((memLayout->RealStackFrameSize() - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen))) - memLayout->SizeOfArgsToStackPass()); /* for FP/LR */ @@ -1267,7 +1270,9 @@ void AArch64GenProEpilog::GeneratePushRegs() { offset -= kAarch64StackPtrAlignmentInt; } - if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + if (cgFunc.GetMirModule().IsCModule() && + cgFunc.GetFunction().GetAttr(FUNCATTR_varargs) && + cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { /* GR/VR save areas are above the callee save area */ AArch64MemLayout *ml = static_cast(cgFunc.GetMemlayout()); auto saveareasize = static_cast(RoundUp(ml->GetSizeOfGRSaveArea(), kSizeOfPtr * k2BitSize) + @@ -1321,34 +1326,20 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { size = kSizeOfPtr; } uint32 dataSizeBits = size * kBitsPerByte; - uint32 offset; - if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { - offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); /* SP reference */ - if ((memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) > 0) { - offset += size; /* End of area should be aligned. Hole between VR and GR area */ - } - } else { - offset = (UINT32_MAX - memlayout->GetSizeOfGRSaveArea()) + 1; /* FP reference */ - if ((memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) > 0) { - offset -= size; - } + uint32 offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); /* SP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset += size; /* End of area should be aligned. Hole between VR and GR area */ } - uint32 grSize = (UINT32_MAX - offset) + 1; - uint32 startRegno = k8BitSize - (memlayout->GetSizeOfGRSaveArea() / size); - ASSERT(startRegno <= k8BitSize, "Incorrect starting GR regno for GR Save Area"); - for (uint32 i = startRegno + static_cast(R0); i < static_cast(R8); i++) { + uint32 start_regno = k8BitSize - (memlayout->GetSizeOfGRSaveArea() / size); + ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for GR Save Area"); + for (uint32 i = start_regno + static_cast(R0); i < static_cast(R8); i++) { uint32 tmpOffset = 0; if (CGOptions::IsBigEndian()) { if ((dataSizeBits >> 3) < 8) { tmpOffset += 8U - (dataSizeBits >> 3); } } - Operand *stackLoc; - if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { - stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); - } else { - stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); - } + Operand *stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyInt); Insn &inst = @@ -1357,26 +1348,17 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { offset += size; } if (!CGOptions::UseGeneralRegOnly()) { - if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { - offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); - } else { - offset = (UINT32_MAX - (memlayout->GetSizeOfVRSaveArea() + grSize)) + 1; - } - startRegno = k8BitSize - (memlayout->GetSizeOfVRSaveArea() / (size * k2BitSize)); - ASSERT(startRegno <= k8BitSize, "Incorrect starting GR regno for VR Save Area"); - for (uint32 i = startRegno + static_cast(V0); i < static_cast(V8); i++) { + offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + start_regno = k8BitSize - (memlayout->GetSizeOfVRSaveArea() / (size * k2BitSize)); + ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for VR Save Area"); + for (uint32 i = start_regno + static_cast(V0); i < static_cast(V8); i++) { uint32 tmpOffset = 0; if (CGOptions::IsBigEndian()) { if ((dataSizeBits >> 3) < 16) { tmpOffset += 16U - (dataSizeBits >> 3); } } - Operand *stackLoc; - if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { - stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); - } else { - stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); - } + Operand *stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyFloat); Insn &inst = @@ -1695,7 +1677,7 @@ void AArch64GenProEpilog::AppendInstructionDeallocateCallFrameDebug(AArch64reg r * ldp/stp's imm should be within -512 and 504; * if ldp's imm > 504, we fall back to the ldp-add version */ - bool isLmbc = (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc); + bool isLmbc = false; if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0 || isLmbc) { int lmbcOffset = 0; if (!isLmbc) { @@ -1782,8 +1764,10 @@ void AArch64GenProEpilog::GeneratePopRegs() { AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); int32 offset; if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - offset = static_cast((memLayout->RealStackFrameSize() - - aarchCGFunc.SizeOfCalleeSaved()) - memLayout->GetSizeOfLocals()); + offset = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen)/* FP/LR */) - + memLayout->GetSizeOfLocals()); /* SizeOfArgsToStackPass not deducted since + AdjustmentStackPointer() is not called for lmbc */ } else { offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen))) - /* for FP/LR */ @@ -1794,7 +1778,8 @@ void AArch64GenProEpilog::GeneratePopRegs() { offset -= kAarch64StackPtrAlignmentInt; } - if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs) && + cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { /* GR/VR save areas are above the callee save area */ AArch64MemLayout *ml = static_cast(cgFunc.GetMemlayout()); auto saveareasize = static_cast(RoundUp(ml->GetSizeOfGRSaveArea(), kSizeOfPtr * k2BitSize) + -- Gitee From 0c46eaba1202401121674596c776a9edf88bd791 Mon Sep 17 00:00:00 2001 From: Alfred Huang Date: Mon, 11 Jul 2022 14:23:18 -0700 Subject: [PATCH 2/2] Added update for vararg's offsets of unnamed var and epilog's offsets. --- .../src/cg/aarch64/aarch64_proepilog.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index b3f5b0fb58..88b290c5c6 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -1317,6 +1317,7 @@ void AArch64GenProEpilog::GeneratePushRegs() { void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { auto &aarchCGFunc = static_cast(cgFunc); CG *currCG = cgFunc.GetCG(); + uint32 offset; if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { AArch64MemLayout *memlayout = static_cast(cgFunc.GetMemlayout()); uint8 size; @@ -1326,7 +1327,12 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { size = kSizeOfPtr; } uint32 dataSizeBits = size * kBitsPerByte; - uint32 offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); /* SP reference */ + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); /* SP reference */ + } else { + offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()) + + memlayout->SizeOfArgsToStackPass(); + } if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { offset += size; /* End of area should be aligned. Hole between VR and GR area */ } @@ -1348,7 +1354,12 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { offset += size; } if (!CGOptions::UseGeneralRegOnly()) { - offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); /* SP reference */ + } else { + offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()) + + memlayout->SizeOfArgsToStackPass(); + } start_regno = k8BitSize - (memlayout->GetSizeOfVRSaveArea() / (size * k2BitSize)); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for VR Save Area"); for (uint32 i = start_regno + static_cast(V0); i < static_cast(V8); i++) { @@ -1677,13 +1688,13 @@ void AArch64GenProEpilog::AppendInstructionDeallocateCallFrameDebug(AArch64reg r * ldp/stp's imm should be within -512 and 504; * if ldp's imm > 504, we fall back to the ldp-add version */ - bool isLmbc = false; + bool isLmbc = cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc; if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0 || isLmbc) { int lmbcOffset = 0; if (!isLmbc) { stackFrameSize -= argsToStkPassSize; } else { - lmbcOffset = argsToStkPassSize - (kDivide2 * k8ByteSize); + lmbcOffset = argsToStkPassSize; } if (stackFrameSize > kStpLdpImm64UpperBound || isLmbc) { Operand *o2; -- Gitee