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 2cd9119cc2913803b30425edfa507849bed3a23d..c17eff53a72b7f7a7255e39346df61f6fe6e9b18 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, size_t argNo); void IntrinsifyGetAndAddInt(ListOperand &srcOpnds, PrimType pty); void IntrinsifyGetAndSetInt(ListOperand &srcOpnds, PrimType pty); @@ -128,7 +129,7 @@ class AArch64CGFunc : public CGFunc { MemOperand *FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx); uint32 LmbcFindTotalStkUsed(std::vector *paramList); uint32 LmbcTotalRegsUsed(); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, const Operand *src); + bool LmbcSmallAggForRet(const BaseNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, const Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; @@ -871,10 +872,11 @@ class AArch64CGFunc : public CGFunc { uint32 structSize, int32 copyOffset, int32 fromOffset); RegOperand *CreateCallStructParamCopyToStack(uint32 numMemOp, const MIRSymbol *sym, RegOperand *addrOpd, int32 copyOffset, int32 fromOffset, const CCLocInfo &ploc); + RegOperand *LoadIreadAddrForSamllAgg(BaseNode &iread); 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, @@ -883,12 +885,24 @@ 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 GenAggParmForDread(BaseNode &parent, ListOperand &srcOpnds, AArch64CallConvImpl &parmLocator, + int32 &structCopyOffset, size_t argNo); + void GenAggParmForIread(BaseNode &parent, ListOperand &srcOpnds, + AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, size_t argNo); + void GenAggParmForIreadoff(BaseNode &parent, ListOperand &srcOpnds, + AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, size_t argNo); + void GenAggParmForIreadfpoff(BaseNode &parent, ListOperand &srcOpnds, + AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, size_t argNo); + void SelectParmListForAggregate(BaseNode &parent, ListOperand &srcOpnds, + AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, size_t 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 GenLargeStructCopyForDread(BaseNode &argExpr, int32 &structCopyOffset); + void GenLargeStructCopyForIread(BaseNode &argExpr, int32 &structCopyOffset); + void GenLargeStructCopyForIreadfpoff(BaseNode &parent, BaseNode &argExpr, int32 &structCopyOffset, size_t argNo); + void GenLargeStructCopyForIreadoff(BaseNode &parent, BaseNode &argExpr, int32 &structCopyOffset, size_t argNo); + void SelectParmListPreprocessLargeStruct(BaseNode &parent, BaseNode &argExpr, int32 &structCopyOffset, size_t 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 1ad9ddb436fb71c437da5194f80177c5c477ebf4..d032068e34d16953de9be23155d9c8e3d383b800 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -1151,7 +1151,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 a0740131415b61788faa20a3f3d563aa77eb93d4..653df11a47df6d37d4a4c97b1b06148b8d4b9e6c 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, size_t 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 + 1UL)) { + 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 + 1UL)) { + 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) { @@ -2142,7 +2165,7 @@ MIRType *AArch64CGFunc::LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector(static_cast(src)->GetRegisterNumber()); @@ -2152,9 +2175,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 */ @@ -2173,7 +2196,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; @@ -2191,7 +2214,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); @@ -3167,9 +3190,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"); + (void)LmbcSmallAggForRet(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; } @@ -3221,36 +3255,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(static_cast(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 == static_cast(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(false, "Invalid ireadfpoff offset"); } else { if (primType == PTY_agg) { + /* agg return */ CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); result = LmbcStructReturnLoad(offset); } else { @@ -7483,12 +7494,32 @@ void AArch64CGFunc::SelectParmListDreadSmallAggregate(const MIRSymbol &sym, MIRT } } -void AArch64CGFunc::SelectParmListIreadSmallAggregate(const IreadNode &iread, MIRType &structType, +RegOperand *AArch64CGFunc::LoadIreadAddrForSamllAgg(BaseNode &iread) { + RegOperand *addrOpnd1 = nullptr; + 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); + } + CHECK_FATAL(addrOpnd1 != nullptr, "addrOpnd for iread cannot be null"); + return addrOpnd1; +} + +void AArch64CGFunc::SelectParmListIreadSmallAggregate(BaseNode &iread, MIRType &structType, ListOperand &srcOpnds, int32 offset, AArch64CallConvImpl &parmLocator) { - int32 symSize = static_cast(static_cast(GetBecommon().GetTypeSize(structType.GetTypeIndex().GetIdx()))); - RegOperand *addrOpnd0 = static_cast(HandleExpr(iread, *(iread.Opnd(0)))); - RegOperand *addrOpnd1 = &LoadIntoRegister(*addrOpnd0, iread.Opnd(0)->GetPrimType()); + int32 symSize = GetBecommon().GetTypeSize(structType.GetTypeIndex().GetIdx()); + RegOperand *addrOpnd1 = LoadIreadAddrForSamllAgg(iread); CCLocInfo ploc; parmLocator.LocateNextParm(structType, ploc); if (ploc.reg0 == 0) { @@ -7515,8 +7546,7 @@ void AArch64CGFunc::SelectParmListIreadSmallAggregate(const IreadNode &iread, MI break; } OfstOperand *offOpnd0 = &GetOrCreateOfstOpnd(static_cast(static_cast(offset)), k32BitSize); - MemOperand *mopnd = - &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, memSize, addrOpnd1, nullptr, offOpnd0, nullptr); + MemOperand *mopnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, memSize, addrOpnd1, nullptr, offOpnd0, nullptr); CreateCallStructParamPassByReg(ploc.reg0, *mopnd, srcOpnds, state); if (ploc.reg1 > 0) { OfstOperand *offOpnd1 = &GetOrCreateOfstOpnd((((ploc.fpSize > 0) ? ploc.fpSize : kSizeOfPtr) + @@ -7864,55 +7894,107 @@ void AArch64CGFunc::CreateCallStructMemcpyToParamReg(MIRType &structType, int32 } } -void AArch64CGFunc::SelectParmListForAggregate(BaseNode &argExpr, ListOperand &srcOpnds, - AArch64CallConvImpl &parmLocator, int32 &structCopyOffset) { - uint64 symSize; +void AArch64CGFunc::GenAggParmForDread(BaseNode &parent, ListOperand &srcOpnds, + AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, size_t argNo) { int32 rhsOffset = 0; - if (argExpr.GetOpCode() == OP_dread) { - DreadNode &dread = static_cast(argExpr); - MIRSymbol *sym = GetBecommon().GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(dread.GetStIdx()); - MIRType *ty = sym->GetType(); - if (dread.GetFieldID() != 0) { - MIRStructType *structty = static_cast(ty); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(structty->GetFieldTyIdx(dread.GetFieldID())); - rhsOffset = GetBecommon().GetFieldOffset(*structty, dread.GetFieldID()).first; - } - symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex().GetIdx()); - if (symSize <= k16ByteSize) { - SelectParmListDreadSmallAggregate(*sym, *ty, srcOpnds, rhsOffset, parmLocator, dread.GetFieldID()); - } else if (symSize > kParmMemcpySize) { - CreateCallStructMemcpyToParamReg(*ty, structCopyOffset, parmLocator, srcOpnds); - structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); - } else { - SelectParmListDreadLargeAggregate(*sym, *ty, srcOpnds, parmLocator, structCopyOffset, rhsOffset); + BaseNode &argExpr = *parent.Opnd(argNo); + DreadNode &dread = static_cast(argExpr); + MIRSymbol *sym = GetBecommon().GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(dread.GetStIdx()); + MIRType *ty = sym->GetType(); + if (dread.GetFieldID() != 0) { + MIRStructType *structty = static_cast(ty); + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(structty->GetFieldTyIdx(dread.GetFieldID())); + rhsOffset = GetBecommon().GetFieldOffset(*structty, dread.GetFieldID()).first; + } + uint64 symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex().GetIdx()); + if (symSize <= k16ByteSize) { + SelectParmListDreadSmallAggregate(*sym, *ty, srcOpnds, rhsOffset, parmLocator, dread.GetFieldID()); + } else if (symSize > kParmMemcpySize) { + CreateCallStructMemcpyToParamReg(*ty, structCopyOffset, parmLocator, srcOpnds); + structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); + } else { + SelectParmListDreadLargeAggregate(*sym, *ty, srcOpnds, parmLocator, structCopyOffset, rhsOffset); + } +} + +void AArch64CGFunc::GenAggParmForIread(BaseNode &parent, ListOperand &srcOpnds, + AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, size_t argNo) { + int32 rhsOffset = 0; + BaseNode &argExpr = *parent.Opnd(argNo); + IreadNode &iread = static_cast(argExpr); + MIRPtrType *pointerty = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread.GetTyIdx())); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerty->GetPointedTyIdx()); + if (iread.GetFieldID() != 0) { + MIRStructType *structty = static_cast(ty); + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(structty->GetFieldTyIdx(iread.GetFieldID())); + rhsOffset = GetBecommon().GetFieldOffset(*structty, iread.GetFieldID()).first; + } + uint64 symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex().GetIdx()); + if (symSize <= k16ByteSize) { + SelectParmListIreadSmallAggregate(iread, *ty, srcOpnds, rhsOffset, parmLocator); + } else if (symSize > kParmMemcpySize) { + RegOperand *ireadOpnd = static_cast(HandleExpr(iread, *(iread.Opnd(0)))); + if (rhsOffset > 0) { + RegOperand *addrOpnd = &LoadIntoRegister(*ireadOpnd, iread.Opnd(0)->GetPrimType()); + regno_t vRegNO = NewVReg(kRegTyInt, k8ByteSize); + RegOperand *result = &CreateVirtualRegisterOperand(vRegNO); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xaddrri12, *result, *addrOpnd, + CreateImmOperand(rhsOffset, k64BitSize, false))); } + CreateCallStructMemcpyToParamReg(*ty, structCopyOffset, parmLocator, srcOpnds); + structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); + } else { + SelectParmListIreadLargeAggregate(iread, *ty, srcOpnds, parmLocator, structCopyOffset, rhsOffset); + } +} + +void AArch64CGFunc::GenAggParmForIreadoff(BaseNode &parent, ListOperand &srcOpnds, + AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, size_t argNo) { + int32 rhsOffset = 0; + BaseNode &argExpr = *parent.Opnd(argNo); + IreadoffNode &iread = static_cast(argExpr); + MIRStructType *ty = GetLmbcStructArgType(parent, argNo); + if (ty == nullptr) { + return; + } + uint64 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)); + } +} + +void AArch64CGFunc::GenAggParmForIreadfpoff(BaseNode &parent, ListOperand &srcOpnds, + AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, size_t argNo) { + int32 rhsOffset = 0; + BaseNode &argExpr = *parent.Opnd(argNo); + IreadFPoffNode &iread = static_cast(argExpr); + MIRStructType *ty = GetLmbcStructArgType(parent, argNo); + if (ty == nullptr) { /* param < arg */ + return; + } + uint64 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)); + } +} + +void AArch64CGFunc::SelectParmListForAggregate(BaseNode &parent, ListOperand &srcOpnds, + AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, size_t argNo) { + BaseNode &argExpr = *parent.Opnd(argNo); + if (argExpr.GetOpCode() == OP_dread) { + GenAggParmForDread(parent, srcOpnds, parmLocator, structCopyOffset, argNo); } else if (argExpr.GetOpCode() == OP_iread) { - IreadNode &iread = static_cast(argExpr); - MIRPtrType *pointerty = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread.GetTyIdx())); - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerty->GetPointedTyIdx()); - if (iread.GetFieldID() != 0) { - MIRStructType *structty = static_cast(ty); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(structty->GetFieldTyIdx(iread.GetFieldID())); - rhsOffset = GetBecommon().GetFieldOffset(*structty, iread.GetFieldID()).first; - } - symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex().GetIdx()); - if (symSize <= k16ByteSize) { - SelectParmListIreadSmallAggregate(iread, *ty, srcOpnds, rhsOffset, parmLocator); - } else if (symSize > kParmMemcpySize) { - RegOperand *ireadOpnd = static_cast(HandleExpr(iread, *(iread.Opnd(0)))); - if (rhsOffset > 0) { - RegOperand *addrOpnd = &LoadIntoRegister(*ireadOpnd, iread.Opnd(0)->GetPrimType()); - regno_t vRegNO = NewVReg(kRegTyInt, k8ByteSize); - RegOperand *result = &CreateVirtualRegisterOperand(vRegNO); - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xaddrri12, *result, *addrOpnd, - CreateImmOperand(rhsOffset, k64BitSize, false))); - } - - CreateCallStructMemcpyToParamReg(*ty, structCopyOffset, parmLocator, srcOpnds); - structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); - } else { - SelectParmListIreadLargeAggregate(iread, *ty, srcOpnds, parmLocator, structCopyOffset, rhsOffset); - } + GenAggParmForIread(parent, srcOpnds, parmLocator, structCopyOffset, argNo); + } else if (argExpr.GetOpCode() == OP_ireadfpoff) { + GenAggParmForIreadfpoff(parent, srcOpnds, parmLocator, structCopyOffset, argNo); + } else if (argExpr.GetOpCode() == OP_ireadoff) { + GenAggParmForIreadoff(parent, srcOpnds, parmLocator, structCopyOffset, argNo); } else { CHECK_FATAL(false, "NYI"); } @@ -7956,53 +8038,91 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { return 0; } -void AArch64CGFunc::SelectParmListPreprocessLargeStruct(BaseNode &argExpr, int32 &structCopyOffset) { - uint64 symSize; +void AArch64CGFunc::GenLargeStructCopyForDread(BaseNode &argExpr, int32 &structCopyOffset) { + int32 rhsOffset = 0; + DreadNode &dread = static_cast(argExpr); + MIRSymbol *sym = GetBecommon().GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(dread.GetStIdx()); + MIRType *ty = sym->GetType(); + if (dread.GetFieldID() != 0) { + MIRStructType *structty = static_cast(ty); + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(structty->GetFieldTyIdx(dread.GetFieldID())); + rhsOffset = GetBecommon().GetFieldOffset(*structty, dread.GetFieldID()).first; + } + uint64 symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex().GetIdx()); + if (symSize > kParmMemcpySize) { + CreateCallStructParamMemcpy(sym, nullptr, static_cast(symSize), structCopyOffset, rhsOffset); + structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); + } else if (symSize > k16ByteSize) { + uint32 numMemOp = static_cast(RoundUp(symSize, kSizeOfPtr) / kSizeOfPtr); + structCopyOffset += static_cast(numMemOp * kSizeOfPtr); + } +} + +void AArch64CGFunc::GenLargeStructCopyForIread(BaseNode &argExpr, int32 &structCopyOffset) { int32 rhsOffset = 0; + IreadNode &iread = static_cast(argExpr); + MIRPtrType *pointerty = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread.GetTyIdx())); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerty->GetPointedTyIdx()); + if (iread.GetFieldID() != 0) { + MIRStructType *structty = static_cast(ty); + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(structty->GetFieldTyIdx(iread.GetFieldID())); + rhsOffset = GetBecommon().GetFieldOffset(*structty, iread.GetFieldID()).first; + } + uint64 symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex().GetIdx()); + if (symSize > kParmMemcpySize) { + RegOperand *ireadOpnd = static_cast(HandleExpr(iread, *(iread.Opnd(0)))); + RegOperand *addrOpnd = &LoadIntoRegister(*ireadOpnd, iread.Opnd(0)->GetPrimType()); + if (rhsOffset > 0) { + regno_t vRegNO = NewVReg(kRegTyInt, k8ByteSize); + RegOperand *result = &CreateVirtualRegisterOperand(vRegNO); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xaddrri12, *result, *addrOpnd, + CreateImmOperand(rhsOffset, k64BitSize, false))); + addrOpnd = result; + } + CreateCallStructParamMemcpy(nullptr, addrOpnd, static_cast(symSize), structCopyOffset, rhsOffset); + structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); + } else if (symSize > k16ByteSize) { + uint32 numMemOp = static_cast(RoundUp(symSize, kSizeOfPtr) / kSizeOfPtr); + structCopyOffset += static_cast(numMemOp * kSizeOfPtr); + } +} + +void AArch64CGFunc::GenLargeStructCopyForIreadfpoff(BaseNode &parent, BaseNode &argExpr, int32 &structCopyOffset, size_t argNo) { + IreadFPoffNode &ireadoff = static_cast(argExpr); + MIRStructType *ty = GetLmbcStructArgType(parent, argNo); + uint64 symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex()); + if (symSize > k16ByteSize) { /* 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)); + } +} + +void AArch64CGFunc::GenLargeStructCopyForIreadoff(BaseNode &parent, BaseNode &argExpr, int32 &structCopyOffset, size_t argNo) { + IreadoffNode &ireadoff = static_cast(argExpr); + MIRStructType *ty = GetLmbcStructArgType(parent, argNo); + uint64 symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex()); + if (symSize > k16ByteSize) { /* kParmMemcpySize */ + RegOperand *addrOpnd = static_cast( + HandleExpr(ireadoff, *(ireadoff.Opnd(0)))); + CreateCallStructParamMemcpy(nullptr, addrOpnd, static_cast(symSize), structCopyOffset, 0); + structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); + } +} + +void AArch64CGFunc::SelectParmListPreprocessLargeStruct(BaseNode &parent, BaseNode &argExpr, + int32 &structCopyOffset, size_t argNo) { if (argExpr.GetOpCode() == OP_dread) { - DreadNode &dread = static_cast(argExpr); - MIRSymbol *sym = GetBecommon().GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(dread.GetStIdx()); - MIRType *ty = sym->GetType(); - if (dread.GetFieldID() != 0) { - MIRStructType *structty = static_cast(ty); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(structty->GetFieldTyIdx(dread.GetFieldID())); - rhsOffset = GetBecommon().GetFieldOffset(*structty, dread.GetFieldID()).first; - } - symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex().GetIdx()); - if (symSize > kParmMemcpySize) { - CreateCallStructParamMemcpy(sym, nullptr, static_cast(symSize), structCopyOffset, rhsOffset); - structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); - } else if (symSize > k16ByteSize) { - uint32 numMemOp = static_cast(RoundUp(symSize, kSizeOfPtr) / kSizeOfPtr); - structCopyOffset += static_cast(numMemOp * kSizeOfPtr); - } + GenLargeStructCopyForDread(argExpr, structCopyOffset); } else if (argExpr.GetOpCode() == OP_iread) { - IreadNode &iread = static_cast(argExpr); - MIRPtrType *pointerty = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread.GetTyIdx())); - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerty->GetPointedTyIdx()); - if (iread.GetFieldID() != 0) { - MIRStructType *structty = static_cast(ty); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(structty->GetFieldTyIdx(iread.GetFieldID())); - rhsOffset = GetBecommon().GetFieldOffset(*structty, iread.GetFieldID()).first; - } - symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex().GetIdx()); - if (symSize > kParmMemcpySize) { - RegOperand *ireadOpnd = static_cast(HandleExpr(iread, *(iread.Opnd(0)))); - RegOperand *addrOpnd = &LoadIntoRegister(*ireadOpnd, iread.Opnd(0)->GetPrimType()); - if (rhsOffset > 0) { - regno_t vRegNO = NewVReg(kRegTyInt, k8ByteSize); - RegOperand *result = &CreateVirtualRegisterOperand(vRegNO); - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xaddrri12, *result, *addrOpnd, - CreateImmOperand(rhsOffset, k64BitSize, false))); - addrOpnd = result; - } - - CreateCallStructParamMemcpy(nullptr, addrOpnd, static_cast(symSize), structCopyOffset, rhsOffset); - structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); - } else if (symSize > k16ByteSize) { - uint32 numMemOp = static_cast(RoundUp(symSize, kSizeOfPtr) / kSizeOfPtr); - structCopyOffset += static_cast(numMemOp * kSizeOfPtr); - } + GenLargeStructCopyForIread(argExpr, structCopyOffset); + } else if (argExpr.GetOpCode() == OP_ireadfpoff) { + GenLargeStructCopyForIreadfpoff(parent, argExpr, structCopyOffset, argNo); + } else if (argExpr.GetOpCode() == OP_ireadoff) { + GenLargeStructCopyForIreadoff(parent, argExpr, structCopyOffset, argNo); } } @@ -8034,7 +8154,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 +8167,7 @@ void AArch64CGFunc::SelectParmListPreprocess(const StmtNode &naryNode, size_t st if (primType != PTY_agg) { continue; } - SelectParmListPreprocessLargeStruct(*argExpr, structCopyOffset); + SelectParmListPreprocessLargeStruct(naryNode, *argExpr, structCopyOffset, static_cast(i)); } } @@ -8148,7 +8268,7 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo } /* use alloca */ if (primType == PTY_agg) { - SelectParmListForAggregate(*argExpr, srcOpnds, parmLocator, structCopyOffset); + SelectParmListForAggregate(naryNode, srcOpnds, parmLocator, structCopyOffset, static_cast(i)); continue; } ty = GlobalTables::GetTypeTable().GetTypeTable()[static_cast(primType)]; @@ -9512,7 +9632,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; } @@ -9530,21 +9654,35 @@ int32 AArch64CGFunc::GetBaseOffset(const SymbolAlloc &symbolAlloc) { int32 offset = static_cast(symAlloc->GetOffset()); return offset; } else if (sgKind == kMsArgsRegPassed) { - int32 baseOffset = static_cast(symAlloc->GetOffset()) + - static_cast(memLayout->GetSizeOfLocals() + memLayout->GetSizeOfRefLocals()); + int32 baseOffset; + if (GetCG()->IsLmbc()) { + baseOffset = static_cast(symAlloc->GetOffset()) + memLayout->GetSizeOfRefLocals() + + memLayout->SizeOfArgsToStackPass(); /* SP relative */ + } else { + baseOffset = memLayout->GetSizeOfLocals() + static_cast(symAlloc->GetOffset()) + + memLayout->GetSizeOfRefLocals(); + } return baseOffset + sizeofFplr; } else if (sgKind == kMsRefLocals) { int32 baseOffset = static_cast(symAlloc->GetOffset()) + static_cast(memLayout->GetSizeOfLocals()); return baseOffset + sizeofFplr; } else if (sgKind == kMsLocals) { - int32 baseOffset = static_cast(symAlloc->GetOffset()); + 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 static_cast(symAlloc->GetOffset()) + static_cast(memLayout->SizeOfArgsToStackPass()); + baseOffset = static_cast(symAlloc->GetOffset()) + + memLayout->SizeOfArgsRegisterPassed() + memLayout->GetSizeOfRefLocals() + + memLayout->SizeOfArgsToStackPass(); + } else { + baseOffset = static_cast(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()); @@ -10208,19 +10346,13 @@ void AArch64CGFunc::SelectCVaStart(const IntrinsiccallNode &intrnNode) { AArch64CallConvImpl parmLocator(GetBecommon()); CCLocInfo pLoc; uint32 stkSize = 0; - uint32 inReg = 0; for (uint32 i = 0; i < GetFunction().GetFormalCount(); i++) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetFunction().GetNthParamTyIdx(i)); parmLocator.LocateNextParm(*ty, pLoc); if (pLoc.reg0 == kRinvalid) { /* on stack */ stkSize = static_cast(pLoc.memOffset + pLoc.memSize); - } else { - 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 bf2e20cbe480f14d58ecfbd05b42ab408144aee6..0a41eaab6bde81c60b9619e81931273b3673d9bf 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -29,7 +29,7 @@ uint32 AArch64MemLayout::ComputeStackSpaceRequirementForCall(StmtNode &stmt, in /* instantiate a parm locator */ AArch64CallConvImpl parmLocator(be); uint32 sizeOfArgsToStkPass = 0; - size_t i = 0; + uint32 i = 0; /* An indirect call's first operand is the invocation target */ if (isIcall) { ++i; @@ -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,12 @@ 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 +197,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 +250,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 +364,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 0a90fe2727e7f5d32a1ea9f35df0ddac6d211441..8a585112fcc4ddee05cd00b9542a73f938cfbbf0 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 fb390a972d7ace9273b69ef13efe2302b294aca7..76ba08d401097f28169a42dade035ca51543bc73 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,8 @@ 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); @@ -368,7 +369,6 @@ void AArch64GenProEpilog::GenStackGuard(BB &bb) { Insn &tmpInsn = currCG->BuildInstruction(mOp, stAddrOpnd, *downStk); tmpInsn.SetDoNotRemove(true); cgFunc.GetCurBB()->AppendInsn(tmpInsn); - bb.InsertAtBeginning(*aarchCGFunc.GetDummyBB()); aarchCGFunc.GetDummyBB()->SetIsProEpilog(false); cgFunc.SetCurBB(*formerCurBB); @@ -401,7 +401,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 +1117,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(); @@ -1255,19 +1254,26 @@ void AArch64GenProEpilog::GeneratePushRegs() { AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); int32 offset; + int32 tmp; if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - offset = static_cast((memLayout->RealStackFrameSize() - - aarchCGFunc.SizeOfCalleeSaved()) - memLayout->GetSizeOfLocals()); + tmp = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* FP/LR */ )); + offset = static_cast(tmp - 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 */ + tmp = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* FP/LR */ )); + offset = static_cast(tmp - memLayout->SizeOfArgsToStackPass()); } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { 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) + @@ -1312,6 +1318,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; @@ -1321,19 +1328,15 @@ 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; - } + 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 */ } - 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++) { @@ -1343,12 +1346,7 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 8U - (dataSizeBits >> 3); } } - Operand *stackLoc; - if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { - stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); - } else { - stackLoc = aarchCGFunc.GenLmbcFpMemOperand(static_cast(offset), size); - } + Operand *stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyInt); Insn &inst = @@ -1358,9 +1356,10 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { } if (!CGOptions::UseGeneralRegOnly()) { if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { - offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); /* SP reference */ } else { - offset = (UINT32_MAX - (memlayout->GetSizeOfVRSaveArea() + grSize)) + 1; + offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()) + + memlayout->SizeOfArgsToStackPass(); } startRegno = k8BitSize - (memlayout->GetSizeOfVRSaveArea() / (size * k2BitSize)); ASSERT(startRegno <= k8BitSize, "Incorrect starting GR regno for VR Save Area"); @@ -1371,12 +1370,7 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 16U - (dataSizeBits >> 3); } } - Operand *stackLoc; - if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { - stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); - } else { - stackLoc = aarchCGFunc.GenLmbcFpMemOperand(static_cast(offset), size); - } + Operand *stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyFloat); Insn &inst = @@ -1684,13 +1678,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 = (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc); + bool isLmbc = cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc; if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0 || isLmbc) { int32 lmbcOffset = 0; if (!isLmbc) { stackFrameSize -= argsToStkPassSize; } else { - lmbcOffset = argsToStkPassSize - (kDivide2 * k8ByteSizeInt); + lmbcOffset = argsToStkPassSize; } if (stackFrameSize > kStpLdpImm64UpperBound || isLmbc) { Operand *o2; @@ -1770,20 +1764,25 @@ void AArch64GenProEpilog::GeneratePopRegs() { AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); int32 offset; + int32 tmp; if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - offset = static_cast((memLayout->RealStackFrameSize() - - aarchCGFunc.SizeOfCalleeSaved()) - memLayout->GetSizeOfLocals()); + tmp = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* FP/LR */ )); + offset = static_cast(tmp - 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 */ - memLayout->SizeOfArgsToStackPass()); + tmp = static_cast(static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */ )); + offset = static_cast(tmp - memLayout->SizeOfArgsToStackPass()); } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { 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) +