From 8b20d3ab1d2487726f730d7a4f31701ad361f66a Mon Sep 17 00:00:00 2001 From: Alfred Huang Date: Wed, 27 Jan 2021 15:54:52 -0800 Subject: [PATCH 1/5] Added vararg prolog and epilog support --- src/mapleall/maple_be/include/be/becommon.h | 13 ++- .../include/cg/aarch64/aarch64_memlayout.h | 23 ++++- .../include/cg/aarch64/aarch64_proepilog.h | 3 +- src/mapleall/maple_be/include/cg/memlayout.h | 9 +- src/mapleall/maple_be/src/be/becommon.cpp | 10 +- src/mapleall/maple_be/src/be/lower.cpp | 2 + .../src/cg/aarch64/aarch64_memlayout.cpp | 64 ++++++++++++- .../src/cg/aarch64/aarch64_proepilog.cpp | 93 +++++++++++++++++-- src/mapleall/maple_ir/src/mir_module.cpp | 12 ++- 9 files changed, 211 insertions(+), 18 deletions(-) diff --git a/src/mapleall/maple_be/include/be/becommon.h b/src/mapleall/maple_be/include/be/becommon.h index ccfd4c59a4..10582def81 100644 --- a/src/mapleall/maple_be/include/be/becommon.h +++ b/src/mapleall/maple_be/include/be/becommon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -114,6 +114,16 @@ class BECommon { void AddElementToJClassLayout(MIRClassType &klass, JClassFieldInfo info); + bool HasFuncReturnType(MIRFunction &func) const { + return (funcReturnType.find(&func) != funcReturnType.end()); + } + + const TyIdx GetFuncReturnType(MIRFunction &func) const { + return (funcReturnType.at(&func)); + } + + void AddElementToFuncReturnType(MIRFunction &func, TyIdx tyIdx); + MIRType *BeGetOrCreatePointerType(const MIRType &pointedType); MIRType *BeGetOrCreateFunctionType(TyIdx tyIdx, const std::vector &vecTy, @@ -223,6 +233,7 @@ class BECommon { * Note: currently only for java class types. */ MapleUnorderedMap jClassLayoutTable; + MapleUnorderedMap funcReturnType; }; /* class BECommon */ } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_memlayout.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_memlayout.h index 0815ef20ed..09b37dbb61 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_memlayout.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_memlayout.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -163,19 +163,40 @@ class AArch64MemLayout : public MemLayout { return segLocals.GetSize(); } + void SetSizeOfGRSaveArea(int32 sz) { + segGrSaveArea.SetSize(sz); + } + + int32 GetSizeOfGRSaveArea() { + return segGrSaveArea.GetSize(); + } + + inline void SetSizeOfVRSaveArea(int32 sz) { + segVrSaveArea.SetSize(sz); + } + + int32 GetSizeOfVRSaveArea() { + return segVrSaveArea.GetSize(); + } + int32 GetSizeOfRefLocals() { return segRefLocals.GetSize(); } int32 GetRefLocBaseLoc() const; + int32 GetGRSaveAreaBaseLoc(); + int32 GetVRSaveAreaBaseLoc(); private: MemSegment segRefLocals = MemSegment(kMsRefLocals); /* callee saved register R19-R28 (10) */ MemSegment segSpillReg = MemSegment(kMsSpillReg); MemSegment segLocals = MemSegment(kMsLocals); /* these are accessed via Frame Pointer */ + MemSegment segGrSaveArea = MemSegment(kMsGrSaveArea); + MemSegment segVrSaveArea = MemSegment(kMsVrSaveArea); int32 fixStackSize = 0; void SetSegmentSize(AArch64SymbolAlloc &symbolAlloc, MemSegment &segment, uint32 typeIdx); + void LayoutVarargParams(); void LayoutFormalParams(); void LayoutActualParams(); void LayoutLocalVariales(std::vector &tempVar, std::vector &returnDelays); diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_proepilog.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_proepilog.h index cff964d499..9dc2108ad3 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_proepilog.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_proepilog.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -41,6 +41,7 @@ class AArch64GenProEpilog : public GenProEpilog { void AppendInstructionAllocateCallFrame(AArch64reg reg0, AArch64reg reg1, RegType rty); void AppendInstructionAllocateCallFrameDebug(AArch64reg reg0, AArch64reg reg1, RegType rty); void GeneratePushRegs(); + void GeneratePushUnnamedVarargRegs(); void AppendInstructionStackCheck(AArch64reg reg, RegType rty, int offset); void GenerateProlog(BB&); diff --git a/src/mapleall/maple_be/include/cg/memlayout.h b/src/mapleall/maple_be/include/cg/memlayout.h index 56d96e7d14..07ee562005 100644 --- a/src/mapleall/maple_be/include/cg/memlayout.h +++ b/src/mapleall/maple_be/include/cg/memlayout.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -47,6 +47,11 @@ enum MemSegmentKind : uint8 { * (or we may allocate them in caller-saved; may be this is better...) */ kMsArgsRegPassed, + /* + * GR/VR Save areas for unnamed arguments under vararg functions + */ + kMsGrSaveArea, + kMsVrSaveArea, /* local (auto) variables */ kMsRefLocals, kMsLocals, @@ -253,4 +258,4 @@ class MemLayout { }; } /* namespace maplebe */ -#endif /* MAPLEBE_INCLUDE_CG_MEMLAYOUT_H */ \ No newline at end of file +#endif /* MAPLEBE_INCLUDE_CG_MEMLAYOUT_H */ diff --git a/src/mapleall/maple_be/src/be/becommon.cpp b/src/mapleall/maple_be/src/be/becommon.cpp index 29c08e359c..48284ebc47 100644 --- a/src/mapleall/maple_be/src/be/becommon.cpp +++ b/src/mapleall/maple_be/src/be/becommon.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -30,7 +30,8 @@ BECommon::BECommon(MIRModule &mod) mirModule.GetMPAllocator().Adapter()), structFieldCountTable(GlobalTables::GetTypeTable().GetTypeTable().size(), 0, mirModule.GetMPAllocator().Adapter()), - jClassLayoutTable(mirModule.GetMPAllocator().Adapter()) { + jClassLayoutTable(mirModule.GetMPAllocator().Adapter()), + funcReturnType(mirModule.GetMPAllocator().Adapter()) { for (uint32 i = 1; i < GlobalTables::GetTypeTable().GetTypeTable().size(); ++i) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeTable()[i]; ComputeTypeSizesAligns(*ty); @@ -597,6 +598,11 @@ void BECommon::AddElementToJClassLayout(MIRClassType &klass, JClassFieldInfo inf layout.emplace_back(info); } +void BECommon::AddElementToFuncReturnType(MIRFunction &func, TyIdx tyIdx) { + TyIdx &ty = funcReturnType.at(&func); + ty = tyIdx; +} + MIRType *BECommon::BeGetOrCreatePointerType(const MIRType &pointedType) { MIRType *newType = GlobalTables::GetTypeTable().GetOrCreatePointerType(pointedType, PTY_a64); if (TyIsInSizeAlignTable(*newType)) { diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 087b3d9fee..5f67ba70a3 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -1240,6 +1240,8 @@ void CGLowerer::LowerEntry(MIRFunction &func) { formals.emplace_back(formal); } + beCommon.AddElementToFuncReturnType(func, func.GetReturnTyIdx()); + func.UpdateFuncTypeAndFormalsAndReturnType(formals, TyIdx(PTY_void), true); auto *funcType = func.GetMIRFuncType(); ASSERT(funcType != nullptr, "null ptr check"); 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 d293c8aa02..5f671aa475 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -103,6 +103,44 @@ void AArch64MemLayout::SetSegmentSize(AArch64SymbolAlloc &symbolAlloc, MemSegmen segment.SetSize(static_cast(RoundUp(static_cast(segment.GetSize()), kSizeOfPtr))); } +void AArch64MemLayout::LayoutVarargParams() { + uint32 nIntRegs = 0; + uint32 nFpRegs = 0; + ParmLocator parmlocator(be); + PLocInfo ploc; + MIRFunction *func = mirFunction; + if (be.GetMIRModule().IsCModule() && func->GetAttr(FUNCATTR_varargs)) { + for (uint32 i = 0; i < func->GetFormalCount(); i++) { + if (i == 0) { + if (be.HasFuncReturnType(*func)) { + TyIdx tidx = be.GetFuncReturnType(*func); + if (be.GetTypeSize(tidx.GetIdx()) <= 16) { + continue; + } + } + } + MIRType *ty = func->GetNthParamType(i); + parmlocator.LocateNextParm(*ty, ploc); + if (ploc.reg0 != kRinvalid) { + if (ploc.reg0 >= R0 && ploc.reg0 <= R7) { + nIntRegs++; + } else if (ploc.reg0 >= V0 && ploc.reg0 <= V7) { + nFpRegs++; + } + } + if (ploc.reg1 != kRinvalid) { + if (ploc.reg1 >= R0 && ploc.reg1 <= R7) { + nIntRegs++; + } else if (ploc.reg1 >= V0 && ploc.reg1 <= V7) { + nFpRegs++; + } + } + } + SetSizeOfGRSaveArea((k8BitSize - nIntRegs) * kSizeOfPtr); + SetSizeOfVRSaveArea((k8BitSize - nFpRegs) * kSizeOfPtr * 2); + } +} + void AArch64MemLayout::LayoutFormalParams() { ParmLocator parmLocator(be); PLocInfo ploc; @@ -257,6 +295,7 @@ void AArch64MemLayout::LayoutActualParams() { } void AArch64MemLayout::LayoutStackFrame() { + LayoutVarargParams(); LayoutFormalParams(); /* * We do need this as LDR/STR with immediate @@ -334,6 +373,13 @@ int32 AArch64MemLayout::StackFrameSize() { int32 total = segArgsRegPassed.GetSize() + static_cast(cgFunc)->SizeOfCalleeSaved() + GetSizeOfRefLocals() + locals().GetSize() + GetSizeOfSpillReg(); + if (GetSizeOfGRSaveArea() > 0) { + total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); + } + if (GetSizeOfVRSaveArea() > 0) { + total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + } + /* * if the function does not have VLA nor alloca, * we allocate space for arguments to stack-pass @@ -359,4 +405,20 @@ int32 AArch64MemLayout::GetRefLocBaseLoc() const { } return beforeSize + kSizeOfFplr; } + +int32 AArch64MemLayout::GetGRSaveAreaBaseLoc() { + int32 total = RealStackFrameSize() - + RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); + total -= SizeOfArgsToStackPass(); + return total; +} + +int32 AArch64MemLayout::GetVRSaveAreaBaseLoc() { + int32 total = RealStackFrameSize() - + RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment) - + RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + total -= SizeOfArgsToStackPass(); + return total; +} + } /* namespace maplebe */ 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 9d75ba6f48..269a49cd47 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -86,10 +86,21 @@ void AArch64GenProEpilog::GenStackGuard(BB &bb) { insn.SetDoNotRemove(true); cgFunc.GetCurBB()->AppendInsn(insn); + int vArea = 0; + if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + AArch64MemLayout *ml = static_cast(cgFunc.GetMemlayout()); + if (ml->GetSizeOfGRSaveArea() > 0) { + vArea += RoundUp(ml->GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); + } + if (ml->GetSizeOfVRSaveArea() > 0) { + vArea += RoundUp(ml->GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + } + } + int32 stkSize = static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - static_cast(cgFunc.GetMemlayout())->SizeOfArgsToStackPass(); - AArch64MemOperand *downStk = aarchCGFunc.GetMemoryPool()->New(RFP, stkSize - kOffset8MemPos, - kSizeOfPtr * kBitsPerByte); + static_cast(cgFunc.GetMemlayout())->SizeOfArgsToStackPass() - vArea; + AArch64MemOperand *downStk = aarchCGFunc.GetMemoryPool()->New(RFP, + stkSize - kOffset8MemPos - vArea, kSizeOfPtr * kBitsPerByte); if (downStk->GetMemVaryType() == kNotVary && aarchCGFunc.IsImmediateOffsetOutOfRange(*downStk, k64BitSize)) { downStk = &aarchCGFunc.SplitOffsetWithAddInstruction(*downStk, k64BitSize, R10); @@ -133,12 +144,23 @@ BB &AArch64GenProEpilog::GenStackGuardCheckInsn(BB &bb) { insn.SetDoNotRemove(true); cgFunc.GetCurBB()->AppendInsn(insn); + int vArea = 0; + if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + AArch64MemLayout *ml = static_cast(cgFunc.GetMemlayout()); + if (ml->GetSizeOfGRSaveArea() > 0) { + vArea += RoundUp(ml->GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); + } + if (ml->GetSizeOfVRSaveArea() > 0) { + vArea += RoundUp(ml->GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + } + } + AArch64RegOperand &checkOp = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(R10, kSizeOfPtr * kBitsPerByte, kRegTyInt); int32 stkSize = static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - static_cast(cgFunc.GetMemlayout())->SizeOfArgsToStackPass(); - AArch64MemOperand *downStk = aarchCGFunc.GetMemoryPool()->New(RFP, stkSize - kOffset8MemPos, - kSizeOfPtr * kBitsPerByte); + static_cast(cgFunc.GetMemlayout())->SizeOfArgsToStackPass() - vArea; + AArch64MemOperand *downStk = aarchCGFunc.GetMemoryPool()->New + (RFP, stkSize - kOffset8MemPos - vArea, kSizeOfPtr * kBitsPerByte); if (downStk->GetMemVaryType() == kNotVary && aarchCGFunc.IsImmediateOffsetOutOfRange(*downStk, k64BitSize)) { downStk = &aarchCGFunc.SplitOffsetWithAddInstruction(*static_cast(downStk), k64BitSize, R10); } @@ -550,6 +572,14 @@ void AArch64GenProEpilog::GeneratePushRegs() { (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - cgFunc.GetMemlayout()->SizeOfArgsToStackPass(); + if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + // GR/VR save areas are above the callee save area + AArch64MemLayout *ml = static_cast(cgFunc.GetMemlayout()); + int saveareasize = RoundUp(ml->GetSizeOfGRSaveArea(), kSizeOfPtr*2) + + RoundUp(ml->GetSizeOfVRSaveArea(), kSizeOfPtr*2); + offset -= saveareasize; + } + for (; it != regsToSave.end(); ++it) { AArch64reg reg = *it; CHECK_FATAL(reg != RFP, "stray RFP in callee_saved_list?"); @@ -585,6 +615,40 @@ void AArch64GenProEpilog::GeneratePushRegs() { aarchCGFunc.SetSplitBaseOffset(0); } +void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { + auto &aarchCGFunc = static_cast(cgFunc); + CG *currCG = cgFunc.GetCG(); + if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + AArch64MemLayout *memlayout = static_cast(cgFunc.GetMemlayout()); + uint32 dataSizeBits = kSizeOfPtr * kBitsPerByte; + int32 offset = memlayout->GetGRSaveAreaBaseLoc(); + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset += kSizeOfPtr; // End of area should be aligned. Hole between VR and GR area + } + int32 start_regno = 8 - (memlayout->GetSizeOfGRSaveArea() / kSizeOfPtr); + ASSERT(start_regno <= 8, "Incorrect starting GR regno for GR Save Area"); + for (uint32 i = start_regno + (uint32)R0; i < (uint32)R8; i++) { + Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset, dataSizeBits); + RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand((AArch64reg)i, 64, kRegTyInt); + Insn &inst = currCG->BuildInstruction( + aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, stackloc); + cgFunc.GetCurBB()->AppendInsn(inst); + offset += kSizeOfPtr; + } + offset = memlayout->GetVRSaveAreaBaseLoc(); + start_regno = 8 - (memlayout->GetSizeOfVRSaveArea() / (kSizeOfPtr * 2)); + ASSERT(start_regno <= 8, "Incorrect starting GR regno for VR Save Area"); + for (uint32 i = start_regno + (uint32)V0; i < (uint32)V8; i++) { + Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset, dataSizeBits); + RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand((AArch64reg)i, 64, kRegTyInt); + Insn &inst = currCG->BuildInstruction( + aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, stackloc); + cgFunc.GetCurBB()->AppendInsn(inst); + offset += (kSizeOfPtr * 2); + } + } +} + void AArch64GenProEpilog::AppendInstructionStackCheck(AArch64reg reg, RegType rty, int32 offset) { auto &aarchCGFunc = static_cast(cgFunc); CG *currCG = cgFunc.GetCG(); @@ -658,6 +722,7 @@ void AArch64GenProEpilog::GenerateProlog(BB &bb) { aarchCGFunc.CreateCfiRegOperand(RFP, k64BitSize))); } } + GeneratePushUnnamedVarargRegs(); if (currCG->DoCheckSOE()) { AppendInstructionStackCheck(R16, kRegTyInt, kSoeChckOffset); } @@ -676,6 +741,12 @@ void AArch64GenProEpilog::GenerateRet(BB &bb) { * Otherwise, return false, create the ret insn. */ bool AArch64GenProEpilog::TestPredsOfRetBB(const BB &exitBB) { + AArch64MemLayout *ml = static_cast(cgFunc.GetMemlayout()); + if (cgFunc.GetMirModule().IsCModule() && + (cgFunc.GetFunction().GetAttr(FUNCATTR_varargs) || + ml->GetSizeOfLocals() > 0 || cgFunc.HasVLAOrAlloca())) { + return false; + } for (auto tmpBB : exitBB.GetPreds()) { Insn *firstInsn = tmpBB->GetFirstInsn(); if ((firstInsn == nullptr || tmpBB->IsCommentBB()) && (!tmpBB->GetPreds().empty())) { @@ -884,6 +955,14 @@ void AArch64GenProEpilog::GeneratePopRegs() { (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - cgFunc.GetMemlayout()->SizeOfArgsToStackPass(); + if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + // GR/VR save areas are above the callee save area + AArch64MemLayout *ml = static_cast(cgFunc.GetMemlayout()); + int saveareasize = RoundUp(ml->GetSizeOfGRSaveArea(), kSizeOfPtr*2) + + RoundUp(ml->GetSizeOfVRSaveArea(), kSizeOfPtr*2); + offset -= saveareasize; + } + /* * We are using a cleared dummy block; so insertPoint cannot be ret; * see GenerateEpilog() diff --git a/src/mapleall/maple_ir/src/mir_module.cpp b/src/mapleall/maple_ir/src/mir_module.cpp index fb3f815f6f..4efa53ac49 100644 --- a/src/mapleall/maple_ir/src/mir_module.cpp +++ b/src/mapleall/maple_ir/src/mir_module.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -505,8 +505,14 @@ std::string MIRModule::GetFileNameAsPostfix() const { fileNameStr += GlobalTables::GetStrTable().GetStringFromStrIdx(GStrIdx(fileNameIdx)); } else { // option 2: src file name removing ext name. - ASSERT(fileNameStr.find_last_of('.') != fileNameStr.npos, "not found."); - fileNameStr += fileNameStr.substr(0, fileNameStr.find_last_of('.')); + if (GetSrcFileInfo().size() != 0) { + GStrIdx idx = GetSrcFileInfo()[0].first; + const std::string kStr = GlobalTables::GetStrTable().GetStringFromStrIdx(idx); + ASSERT(kStr.find_last_of('.') != kStr.npos, "not found ."); + fileNameStr += kStr.substr(0, kStr.find_last_of('.')); + } else { + ASSERT(0, "No fileinfo and no srcfileinfo in mpl file"); + } } for (char &c : fileNameStr) { if (!isalpha(c) && !isdigit(c) && c != '_' && c != '$') { -- Gitee From 95020e74eb347ff06e5895a431c220ad16688fc6 Mon Sep 17 00:00:00 2001 From: Alfred Huang Date: Wed, 27 Jan 2021 16:22:13 -0800 Subject: [PATCH 2/5] Fixed license date --- src/mapleall/maple_be/include/be/becommon.h | 2 +- src/mapleall/maple_be/include/cg/aarch64/aarch64_memlayout.h | 2 +- src/mapleall/maple_be/include/cg/aarch64/aarch64_proepilog.h | 2 +- src/mapleall/maple_be/include/cg/memlayout.h | 2 +- src/mapleall/maple_be/src/be/becommon.cpp | 2 +- src/mapleall/maple_be/src/be/lower.cpp | 2 +- src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp | 2 +- src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mapleall/maple_be/include/be/becommon.h b/src/mapleall/maple_be/include/be/becommon.h index 10582def81..954a35a0ef 100644 --- a/src/mapleall/maple_be/include/be/becommon.h +++ b/src/mapleall/maple_be/include/be/becommon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_memlayout.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_memlayout.h index 09b37dbb61..cb2f7b8838 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_memlayout.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_memlayout.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_proepilog.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_proepilog.h index 9dc2108ad3..fa9074fe17 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_proepilog.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_proepilog.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mapleall/maple_be/include/cg/memlayout.h b/src/mapleall/maple_be/include/cg/memlayout.h index 07ee562005..d37fc019b7 100644 --- a/src/mapleall/maple_be/include/cg/memlayout.h +++ b/src/mapleall/maple_be/include/cg/memlayout.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mapleall/maple_be/src/be/becommon.cpp b/src/mapleall/maple_be/src/be/becommon.cpp index 48284ebc47..89346028fe 100644 --- a/src/mapleall/maple_be/src/be/becommon.cpp +++ b/src/mapleall/maple_be/src/be/becommon.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 5f67ba70a3..78386ecbcd 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. 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 5f671aa475..2961ebca81 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. 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 269a49cd47..8f2ddb4a5b 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020 - 2021] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. -- Gitee From 9ef5551a824b4e41f93b6a6a0dfa8f2ddea573f0 Mon Sep 17 00:00:00 2001 From: Alfred Huang Date: Fri, 29 Jan 2021 15:01:34 -0800 Subject: [PATCH 3/5] Support of C vararg intrinsic function va_start --- .../include/cg/aarch64/aarch64_cgfunc.h | 4 +- .../src/cg/aarch64/aarch64_cgfunc.cpp | 90 +++++++++++++++++++ src/mapleall/maple_ir/include/intrinsic_c.def | 4 +- 3 files changed, 95 insertions(+), 3 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 0983475048..aaa39903bf 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -580,8 +580,10 @@ class AArch64CGFunc : public CGFunc { PrimType stype); bool GenerateCompareWithZeroInstruction(Opcode jmpOp, Opcode cmpOp, bool is64Bits, LabelOperand &targetOpnd, Operand &opnd0); + void GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize); void SelectMPLClinitCheck(IntrinsiccallNode&); void SelectMPLProfCounterInc(IntrinsiccallNode &intrnNode); + void SelectCVaStart(IntrinsiccallNode &intrnNode); /* Helper functions for translating complex Maple IR instructions/inrinsics */ void SelectDassign(StIdx stIdx, FieldID fieldId, PrimType rhsPType, Operand &opnd0); LabelIdx CreateLabeledBB(StmtNode &stmt); 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 00045a037f..79890ab1e8 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -6067,6 +6067,92 @@ void AArch64CGFunc::SelectMPLClinitCheck(IntrinsiccallNode &intrnNode) { } } +void AArch64CGFunc::GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize) { + // FPLR only pushed in regalloc() after intrin function + Operand &stkOpnd = GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); + + // __stack + AArch64ImmOperand *offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); // isvary reset StackFrameSize + AArch64ImmOperand *offsOpnd2 = &CreateImmOperand(stkSize, k64BitSize, false); + RegOperand &vReg = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, GetPrimTypeSize(PTY_a64))); + if (stkSize) { + SelectAdd(vReg, *offsOpnd, *offsOpnd2, PTY_a64); + SelectAdd(vReg, stkOpnd, vReg, PTY_a64); + } else { + SelectAdd(vReg, stkOpnd, *offsOpnd, PTY_a64); + } + AArch64OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); + MemOperand *strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, + offOpnd, static_cast(nullptr)); // mem operand in va_list struct (lhs) + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xstr, vReg, *strOpnd)); + + // __gr_top ; it's the same as __stack before the 1st va_arg + offOpnd = &GetOrCreateOfstOpnd(k8BitSize, k64BitSize); + strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, + offOpnd, static_cast(nullptr)); + SelectAdd(vReg, stkOpnd, *offsOpnd, PTY_a64); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xstr, vReg, *strOpnd)); + + // __vr_top + int32 grAreaSize = static_cast(GetMemlayout())->GetSizeOfGRSaveArea(); + offsOpnd2 = &CreateImmOperand(RoundUp(grAreaSize, kSizeOfPtr*2), k64BitSize, false); + SelectSub(vReg, *offsOpnd, *offsOpnd2, PTY_a64); // if 1st opnd is register => sub + SelectAdd(vReg, stkOpnd, vReg, PTY_a64); + offOpnd = &GetOrCreateOfstOpnd(k16BitSize, k64BitSize); + strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, + offOpnd, static_cast(nullptr)); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xstr, vReg, *strOpnd)); + + // __gr_offs + int32 offs = 0 - grAreaSize; + offsOpnd = &CreateImmOperand(offs, k32BitSize, false); + RegOperand *tmpReg = &CreateRegisterOperandOfType(PTY_i32); // offs value to be assigned (rhs) + SelectCopyImm(*tmpReg, *offsOpnd, PTY_i32); + offOpnd = &GetOrCreateOfstOpnd(3*kSizeOfPtr, k32BitSize); + strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k32BitSize, &opnd, nullptr, + offOpnd, static_cast(nullptr)); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_wstr, *tmpReg, *strOpnd)); + + // __vr_offs + offs = 0 - static_cast(GetMemlayout())->GetSizeOfVRSaveArea(); + offsOpnd = &CreateImmOperand(offs, k32BitSize, false); + tmpReg = &CreateRegisterOperandOfType(PTY_i32); + SelectCopyImm(*tmpReg, *offsOpnd, PTY_i32); + offOpnd = &GetOrCreateOfstOpnd(3*kSizeOfPtr+sizeof(int32), k32BitSize); + strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k32BitSize, &opnd, nullptr, + offOpnd, static_cast(nullptr)); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_wstr, *tmpReg, *strOpnd)); +} + +void AArch64CGFunc::SelectCVaStart(IntrinsiccallNode &intrnNode) { + ASSERT(intrnNode.NumOpnds() == 2, "must be 2 operands"); + // 2 operands, but only 1 needed. Don't need to emit code for second operand + + // va_list is a passed struct with an address, load its address + BaseNode *argExpr = intrnNode.Opnd(0); + Operand *opnd = HandleExpr(intrnNode, *argExpr); + RegOperand &opnd0 = LoadIntoRegister(*opnd, PTY_a64); // first argument of intrinsic + + // Find beginning of unnamed arg on stack. + // Ex. void foo(int i1, int i2, ... int i8, struct S r, struct S s, ...) + // where struct S has size 32, address of r and s are on stack but they are named. + ParmLocator parmLocator(GetBecommon()); + PLocInfo pLoc; + uint32 stkSize = 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 = pLoc.memOffset + pLoc.memSize; + } + } + stkSize = RoundUp(stkSize, kSizeOfPtr); + + GenCVaStartIntrin(opnd0, stkSize); + + return; +} + void AArch64CGFunc::SelectIntrinCall(IntrinsiccallNode &intrinsiccallNode) { MIRIntrinsicID intrinsic = intrinsiccallNode.GetIntrinsic(); @@ -6095,6 +6181,10 @@ void AArch64CGFunc::SelectIntrinCall(IntrinsiccallNode &intrinsiccallNode) { (intrinsic == INTRN_MPL_CLEANUP_NORETESCOBJS)) { return; } + if (intrinsic == INTRN_C_va_start) { + SelectCVaStart(intrinsiccallNode); + return; + } std::vector operands; /* Temporary. Deallocated on return. */ AArch64ListOperand *srcOpnds = memPool->New(*GetFuncScopeAllocator()); for (size_t i = 0; i < intrinsiccallNode.NumOpnds(); i++) { diff --git a/src/mapleall/maple_ir/include/intrinsic_c.def b/src/mapleall/maple_ir/include/intrinsic_c.def index 5c5b901689..1f0fd625d4 100644 --- a/src/mapleall/maple_ir/include/intrinsic_c.def +++ b/src/mapleall/maple_ir/include/intrinsic_c.def @@ -76,7 +76,7 @@ DEF_MIR_INTRINSIC(C_sinh,\ DEF_MIR_INTRINSIC(C_ffs,\ "ffs", INTRNISPURE, kArgTyI32, kArgTyI32) DEF_MIR_INTRINSIC(C_va_start,\ - "sinh"/*dummy*/, INTRNISPURE, kArgTyVoid, kArgTyPtr, kArgTyI32) + "sinh"/*dummy*/, INTRNISPURE | INTRNISSPECIAL, kArgTyVoid, kArgTyPtr, kArgTyI32) DEF_MIR_INTRINSIC(C_constant_p,\ "sinh"/*dummy*/, 0, kArgTyI32, kArgTyDynany) DEF_MIR_INTRINSIC(C_clz32,\ @@ -86,4 +86,4 @@ DEF_MIR_INTRINSIC(C_clz64,\ DEF_MIR_INTRINSIC(C_ctz32,\ "sinh"/*dummy*/, INTRNISPURE, kArgTyI32, kArgTyU32) DEF_MIR_INTRINSIC(C_ctz64,\ - "sinh"/*dummy*/, INTRNISPURE, kArgTyI32, kArgTyU64) \ No newline at end of file + "sinh"/*dummy*/, INTRNISPURE, kArgTyI32, kArgTyU64) -- Gitee From 7b7ada45206121895315c366680c99832485a8df Mon Sep 17 00:00:00 2001 From: Alfred Huang Date: Fri, 29 Jan 2021 15:20:48 -0800 Subject: [PATCH 4/5] Revert "Support of C vararg intrinsic function va_start" from "Support of C vararg prolog/epilog". They should be in different PRs. This reverts commit 9ef5551a824b4e41f93b6a6a0dfa8f2ddea573f0. --- .../include/cg/aarch64/aarch64_cgfunc.h | 4 +- .../src/cg/aarch64/aarch64_cgfunc.cpp | 90 ------------------- src/mapleall/maple_ir/include/intrinsic_c.def | 4 +- 3 files changed, 3 insertions(+), 95 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 aaa39903bf..0983475048 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -580,10 +580,8 @@ class AArch64CGFunc : public CGFunc { PrimType stype); bool GenerateCompareWithZeroInstruction(Opcode jmpOp, Opcode cmpOp, bool is64Bits, LabelOperand &targetOpnd, Operand &opnd0); - void GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize); void SelectMPLClinitCheck(IntrinsiccallNode&); void SelectMPLProfCounterInc(IntrinsiccallNode &intrnNode); - void SelectCVaStart(IntrinsiccallNode &intrnNode); /* Helper functions for translating complex Maple IR instructions/inrinsics */ void SelectDassign(StIdx stIdx, FieldID fieldId, PrimType rhsPType, Operand &opnd0); LabelIdx CreateLabeledBB(StmtNode &stmt); 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 79890ab1e8..00045a037f 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -6067,92 +6067,6 @@ void AArch64CGFunc::SelectMPLClinitCheck(IntrinsiccallNode &intrnNode) { } } -void AArch64CGFunc::GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize) { - // FPLR only pushed in regalloc() after intrin function - Operand &stkOpnd = GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - - // __stack - AArch64ImmOperand *offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); // isvary reset StackFrameSize - AArch64ImmOperand *offsOpnd2 = &CreateImmOperand(stkSize, k64BitSize, false); - RegOperand &vReg = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, GetPrimTypeSize(PTY_a64))); - if (stkSize) { - SelectAdd(vReg, *offsOpnd, *offsOpnd2, PTY_a64); - SelectAdd(vReg, stkOpnd, vReg, PTY_a64); - } else { - SelectAdd(vReg, stkOpnd, *offsOpnd, PTY_a64); - } - AArch64OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); - MemOperand *strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, - offOpnd, static_cast(nullptr)); // mem operand in va_list struct (lhs) - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xstr, vReg, *strOpnd)); - - // __gr_top ; it's the same as __stack before the 1st va_arg - offOpnd = &GetOrCreateOfstOpnd(k8BitSize, k64BitSize); - strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, - offOpnd, static_cast(nullptr)); - SelectAdd(vReg, stkOpnd, *offsOpnd, PTY_a64); - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xstr, vReg, *strOpnd)); - - // __vr_top - int32 grAreaSize = static_cast(GetMemlayout())->GetSizeOfGRSaveArea(); - offsOpnd2 = &CreateImmOperand(RoundUp(grAreaSize, kSizeOfPtr*2), k64BitSize, false); - SelectSub(vReg, *offsOpnd, *offsOpnd2, PTY_a64); // if 1st opnd is register => sub - SelectAdd(vReg, stkOpnd, vReg, PTY_a64); - offOpnd = &GetOrCreateOfstOpnd(k16BitSize, k64BitSize); - strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, - offOpnd, static_cast(nullptr)); - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xstr, vReg, *strOpnd)); - - // __gr_offs - int32 offs = 0 - grAreaSize; - offsOpnd = &CreateImmOperand(offs, k32BitSize, false); - RegOperand *tmpReg = &CreateRegisterOperandOfType(PTY_i32); // offs value to be assigned (rhs) - SelectCopyImm(*tmpReg, *offsOpnd, PTY_i32); - offOpnd = &GetOrCreateOfstOpnd(3*kSizeOfPtr, k32BitSize); - strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k32BitSize, &opnd, nullptr, - offOpnd, static_cast(nullptr)); - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_wstr, *tmpReg, *strOpnd)); - - // __vr_offs - offs = 0 - static_cast(GetMemlayout())->GetSizeOfVRSaveArea(); - offsOpnd = &CreateImmOperand(offs, k32BitSize, false); - tmpReg = &CreateRegisterOperandOfType(PTY_i32); - SelectCopyImm(*tmpReg, *offsOpnd, PTY_i32); - offOpnd = &GetOrCreateOfstOpnd(3*kSizeOfPtr+sizeof(int32), k32BitSize); - strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k32BitSize, &opnd, nullptr, - offOpnd, static_cast(nullptr)); - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_wstr, *tmpReg, *strOpnd)); -} - -void AArch64CGFunc::SelectCVaStart(IntrinsiccallNode &intrnNode) { - ASSERT(intrnNode.NumOpnds() == 2, "must be 2 operands"); - // 2 operands, but only 1 needed. Don't need to emit code for second operand - - // va_list is a passed struct with an address, load its address - BaseNode *argExpr = intrnNode.Opnd(0); - Operand *opnd = HandleExpr(intrnNode, *argExpr); - RegOperand &opnd0 = LoadIntoRegister(*opnd, PTY_a64); // first argument of intrinsic - - // Find beginning of unnamed arg on stack. - // Ex. void foo(int i1, int i2, ... int i8, struct S r, struct S s, ...) - // where struct S has size 32, address of r and s are on stack but they are named. - ParmLocator parmLocator(GetBecommon()); - PLocInfo pLoc; - uint32 stkSize = 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 = pLoc.memOffset + pLoc.memSize; - } - } - stkSize = RoundUp(stkSize, kSizeOfPtr); - - GenCVaStartIntrin(opnd0, stkSize); - - return; -} - void AArch64CGFunc::SelectIntrinCall(IntrinsiccallNode &intrinsiccallNode) { MIRIntrinsicID intrinsic = intrinsiccallNode.GetIntrinsic(); @@ -6181,10 +6095,6 @@ void AArch64CGFunc::SelectIntrinCall(IntrinsiccallNode &intrinsiccallNode) { (intrinsic == INTRN_MPL_CLEANUP_NORETESCOBJS)) { return; } - if (intrinsic == INTRN_C_va_start) { - SelectCVaStart(intrinsiccallNode); - return; - } std::vector operands; /* Temporary. Deallocated on return. */ AArch64ListOperand *srcOpnds = memPool->New(*GetFuncScopeAllocator()); for (size_t i = 0; i < intrinsiccallNode.NumOpnds(); i++) { diff --git a/src/mapleall/maple_ir/include/intrinsic_c.def b/src/mapleall/maple_ir/include/intrinsic_c.def index 1f0fd625d4..5c5b901689 100644 --- a/src/mapleall/maple_ir/include/intrinsic_c.def +++ b/src/mapleall/maple_ir/include/intrinsic_c.def @@ -76,7 +76,7 @@ DEF_MIR_INTRINSIC(C_sinh,\ DEF_MIR_INTRINSIC(C_ffs,\ "ffs", INTRNISPURE, kArgTyI32, kArgTyI32) DEF_MIR_INTRINSIC(C_va_start,\ - "sinh"/*dummy*/, INTRNISPURE | INTRNISSPECIAL, kArgTyVoid, kArgTyPtr, kArgTyI32) + "sinh"/*dummy*/, INTRNISPURE, kArgTyVoid, kArgTyPtr, kArgTyI32) DEF_MIR_INTRINSIC(C_constant_p,\ "sinh"/*dummy*/, 0, kArgTyI32, kArgTyDynany) DEF_MIR_INTRINSIC(C_clz32,\ @@ -86,4 +86,4 @@ DEF_MIR_INTRINSIC(C_clz64,\ DEF_MIR_INTRINSIC(C_ctz32,\ "sinh"/*dummy*/, INTRNISPURE, kArgTyI32, kArgTyU32) DEF_MIR_INTRINSIC(C_ctz64,\ - "sinh"/*dummy*/, INTRNISPURE, kArgTyI32, kArgTyU64) + "sinh"/*dummy*/, INTRNISPURE, kArgTyI32, kArgTyU64) \ No newline at end of file -- Gitee From 2279c1bde6dadf72a0771029d48bd231ca2cbecb Mon Sep 17 00:00:00 2001 From: Alfred Huang Date: Fri, 29 Jan 2021 16:18:03 -0800 Subject: [PATCH 5/5] Support C vararg intrinsic of va_start --- .../include/cg/aarch64/aarch64_cgfunc.h | 4 +- .../src/cg/aarch64/aarch64_cgfunc.cpp | 90 +++++++++++++++++++ src/mapleall/maple_ir/include/intrinsic_c.def | 4 +- 3 files changed, 95 insertions(+), 3 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 0983475048..aaa39903bf 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2020-2021] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. @@ -580,8 +580,10 @@ class AArch64CGFunc : public CGFunc { PrimType stype); bool GenerateCompareWithZeroInstruction(Opcode jmpOp, Opcode cmpOp, bool is64Bits, LabelOperand &targetOpnd, Operand &opnd0); + void GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize); void SelectMPLClinitCheck(IntrinsiccallNode&); void SelectMPLProfCounterInc(IntrinsiccallNode &intrnNode); + void SelectCVaStart(IntrinsiccallNode &intrnNode); /* Helper functions for translating complex Maple IR instructions/inrinsics */ void SelectDassign(StIdx stIdx, FieldID fieldId, PrimType rhsPType, Operand &opnd0); LabelIdx CreateLabeledBB(StmtNode &stmt); 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 00045a037f..79890ab1e8 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -6067,6 +6067,92 @@ void AArch64CGFunc::SelectMPLClinitCheck(IntrinsiccallNode &intrnNode) { } } +void AArch64CGFunc::GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize) { + // FPLR only pushed in regalloc() after intrin function + Operand &stkOpnd = GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); + + // __stack + AArch64ImmOperand *offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); // isvary reset StackFrameSize + AArch64ImmOperand *offsOpnd2 = &CreateImmOperand(stkSize, k64BitSize, false); + RegOperand &vReg = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, GetPrimTypeSize(PTY_a64))); + if (stkSize) { + SelectAdd(vReg, *offsOpnd, *offsOpnd2, PTY_a64); + SelectAdd(vReg, stkOpnd, vReg, PTY_a64); + } else { + SelectAdd(vReg, stkOpnd, *offsOpnd, PTY_a64); + } + AArch64OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); + MemOperand *strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, + offOpnd, static_cast(nullptr)); // mem operand in va_list struct (lhs) + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xstr, vReg, *strOpnd)); + + // __gr_top ; it's the same as __stack before the 1st va_arg + offOpnd = &GetOrCreateOfstOpnd(k8BitSize, k64BitSize); + strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, + offOpnd, static_cast(nullptr)); + SelectAdd(vReg, stkOpnd, *offsOpnd, PTY_a64); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xstr, vReg, *strOpnd)); + + // __vr_top + int32 grAreaSize = static_cast(GetMemlayout())->GetSizeOfGRSaveArea(); + offsOpnd2 = &CreateImmOperand(RoundUp(grAreaSize, kSizeOfPtr*2), k64BitSize, false); + SelectSub(vReg, *offsOpnd, *offsOpnd2, PTY_a64); // if 1st opnd is register => sub + SelectAdd(vReg, stkOpnd, vReg, PTY_a64); + offOpnd = &GetOrCreateOfstOpnd(k16BitSize, k64BitSize); + strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, + offOpnd, static_cast(nullptr)); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xstr, vReg, *strOpnd)); + + // __gr_offs + int32 offs = 0 - grAreaSize; + offsOpnd = &CreateImmOperand(offs, k32BitSize, false); + RegOperand *tmpReg = &CreateRegisterOperandOfType(PTY_i32); // offs value to be assigned (rhs) + SelectCopyImm(*tmpReg, *offsOpnd, PTY_i32); + offOpnd = &GetOrCreateOfstOpnd(3*kSizeOfPtr, k32BitSize); + strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k32BitSize, &opnd, nullptr, + offOpnd, static_cast(nullptr)); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_wstr, *tmpReg, *strOpnd)); + + // __vr_offs + offs = 0 - static_cast(GetMemlayout())->GetSizeOfVRSaveArea(); + offsOpnd = &CreateImmOperand(offs, k32BitSize, false); + tmpReg = &CreateRegisterOperandOfType(PTY_i32); + SelectCopyImm(*tmpReg, *offsOpnd, PTY_i32); + offOpnd = &GetOrCreateOfstOpnd(3*kSizeOfPtr+sizeof(int32), k32BitSize); + strOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, k32BitSize, &opnd, nullptr, + offOpnd, static_cast(nullptr)); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_wstr, *tmpReg, *strOpnd)); +} + +void AArch64CGFunc::SelectCVaStart(IntrinsiccallNode &intrnNode) { + ASSERT(intrnNode.NumOpnds() == 2, "must be 2 operands"); + // 2 operands, but only 1 needed. Don't need to emit code for second operand + + // va_list is a passed struct with an address, load its address + BaseNode *argExpr = intrnNode.Opnd(0); + Operand *opnd = HandleExpr(intrnNode, *argExpr); + RegOperand &opnd0 = LoadIntoRegister(*opnd, PTY_a64); // first argument of intrinsic + + // Find beginning of unnamed arg on stack. + // Ex. void foo(int i1, int i2, ... int i8, struct S r, struct S s, ...) + // where struct S has size 32, address of r and s are on stack but they are named. + ParmLocator parmLocator(GetBecommon()); + PLocInfo pLoc; + uint32 stkSize = 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 = pLoc.memOffset + pLoc.memSize; + } + } + stkSize = RoundUp(stkSize, kSizeOfPtr); + + GenCVaStartIntrin(opnd0, stkSize); + + return; +} + void AArch64CGFunc::SelectIntrinCall(IntrinsiccallNode &intrinsiccallNode) { MIRIntrinsicID intrinsic = intrinsiccallNode.GetIntrinsic(); @@ -6095,6 +6181,10 @@ void AArch64CGFunc::SelectIntrinCall(IntrinsiccallNode &intrinsiccallNode) { (intrinsic == INTRN_MPL_CLEANUP_NORETESCOBJS)) { return; } + if (intrinsic == INTRN_C_va_start) { + SelectCVaStart(intrinsiccallNode); + return; + } std::vector operands; /* Temporary. Deallocated on return. */ AArch64ListOperand *srcOpnds = memPool->New(*GetFuncScopeAllocator()); for (size_t i = 0; i < intrinsiccallNode.NumOpnds(); i++) { diff --git a/src/mapleall/maple_ir/include/intrinsic_c.def b/src/mapleall/maple_ir/include/intrinsic_c.def index 5c5b901689..1f0fd625d4 100644 --- a/src/mapleall/maple_ir/include/intrinsic_c.def +++ b/src/mapleall/maple_ir/include/intrinsic_c.def @@ -76,7 +76,7 @@ DEF_MIR_INTRINSIC(C_sinh,\ DEF_MIR_INTRINSIC(C_ffs,\ "ffs", INTRNISPURE, kArgTyI32, kArgTyI32) DEF_MIR_INTRINSIC(C_va_start,\ - "sinh"/*dummy*/, INTRNISPURE, kArgTyVoid, kArgTyPtr, kArgTyI32) + "sinh"/*dummy*/, INTRNISPURE | INTRNISSPECIAL, kArgTyVoid, kArgTyPtr, kArgTyI32) DEF_MIR_INTRINSIC(C_constant_p,\ "sinh"/*dummy*/, 0, kArgTyI32, kArgTyDynany) DEF_MIR_INTRINSIC(C_clz32,\ @@ -86,4 +86,4 @@ DEF_MIR_INTRINSIC(C_clz64,\ DEF_MIR_INTRINSIC(C_ctz32,\ "sinh"/*dummy*/, INTRNISPURE, kArgTyI32, kArgTyU32) DEF_MIR_INTRINSIC(C_ctz64,\ - "sinh"/*dummy*/, INTRNISPURE, kArgTyI32, kArgTyU64) \ No newline at end of file + "sinh"/*dummy*/, INTRNISPURE, kArgTyI32, kArgTyU64) -- Gitee