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 6a33ad07f8d203c962edcca519e499c25a41e862..e32a157273dbf5ca0a589a43dfead7f1bd1cd12b 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -122,6 +122,7 @@ class AArch64CGFunc : public CGFunc { void SelectIcall(IcallNode &icallNode, Operand &fptrOpnd) override; void SelectIntrinCall(IntrinsiccallNode &intrinsicCallNode) override; Operand *SelectIntrinsicOpWithOneParam(IntrinsicopNode &intrinopNode, std::string name) override; + Operand *SelectIntrinsicOpWithNParams(IntrinsicopNode &intrinopNode, PrimType retType, std::string &name) override; Operand *SelectCclz(IntrinsicopNode &intrinopNode) override; Operand *SelectCctz(IntrinsicopNode &intrinopNode) override; Operand *SelectCpopcount(IntrinsicopNode &intrinopNode) override; @@ -250,6 +251,8 @@ class AArch64CGFunc : public CGFunc { void SelectCopyImm(Operand &dest, PrimType dType, ImmOperand &src, PrimType sType); void SelectCopyImm(Operand &dest, ImmOperand &src, PrimType dtype); void SelectLibCall(const std::string&, std::vector&, PrimType, PrimType, bool is2ndRet = false); + void SelectLibCallNArg(const std::string &funcName, std::vector &opndVec, std::vector pt, + PrimType retPrimType, bool is2ndRet); bool IsRegRematCand(const RegOperand ®); void ClearRegRematInfo(const RegOperand ®); bool IsRegSameRematInfo(const RegOperand ®Dest, const RegOperand ®Src); diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 84018da3c323ec6df2c2f49a64dc0a427fa40e16..b3e20554e608d3e2ca79aba935f7d33858a278c0 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -184,6 +184,7 @@ class CGFunc { virtual void SelectIcall(IcallNode &icallNode, Operand &fptrOpnd) = 0; virtual void SelectIntrinCall(IntrinsiccallNode &intrinsiccallNode) = 0; virtual Operand *SelectIntrinsicOpWithOneParam(IntrinsicopNode &intrinopNode, std::string name) = 0; + virtual Operand *SelectIntrinsicOpWithNParams(IntrinsicopNode &intrinopNode, PrimType retType, std::string &name) = 0; virtual Operand *SelectCclz(IntrinsicopNode &intrinopNode) = 0; virtual Operand *SelectCctz(IntrinsicopNode &intrinopNode) = 0; virtual Operand *SelectCpopcount(IntrinsicopNode &intrinopNode) = 0; 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 a4aa80dcfaef41de023528d1f38cd7a85a25a3cb..dcdbc92deec7b7f84b760bc98574f68250970586 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -4788,6 +4788,31 @@ Operand *AArch64CGFunc::SelectIntrinsicOpWithOneParam(IntrinsicopNode &intrnNode return dst; } +Operand *AArch64CGFunc::SelectIntrinsicOpWithNParams(IntrinsicopNode &intrnNode, PrimType retType, std::string &name) { + MapleVector argNodes = intrnNode.GetNopnd(); + std::vector opndVec; + std::vector opndTypes; + RegOperand *retOpnd = &CreateRegisterOperandOfType(retType); + opndVec.push_back(retOpnd); + opndTypes.push_back(retType); + + for (BaseNode *argexpr : argNodes) { + PrimType ptype = argexpr->GetPrimType(); + Operand *opnd = HandleExpr(intrnNode, *argexpr); + if (opnd->IsMemoryAccessOperand()) { + RegOperand &ldDest = CreateRegisterOperandOfType(ptype); + Insn &insn = GetCG()->BuildInstruction(PickLdInsn(GetPrimTypeBitSize(ptype), ptype), ldDest, *opnd); + GetCurBB()->AppendInsn(insn); + opnd = &ldDest; + } + opndVec.push_back(opnd); + opndTypes.push_back(ptype); + } + SelectLibCallNArg(name, opndVec, opndTypes, retType, false); + + return retOpnd; +} + /* According to gcc.target/aarch64/ffs.c */ Operand *AArch64CGFunc::SelectAArch64ffs(Operand &argOpnd, PrimType argType) { RegOperand &destOpnd = LoadIntoRegister(argOpnd, argType); @@ -8280,6 +8305,17 @@ Operand &AArch64CGFunc::GetOrCreatevaryreg() { /* the first operand in opndvec is return opnd */ void AArch64CGFunc::SelectLibCall(const std::string &funcName, std::vector &opndVec, PrimType primType, PrimType retPrimType, bool is2ndRet) { + std::vector pt; + pt.push_back(retPrimType); + for (size_t i = 0; i < opndVec.size(); ++i) { + pt.push_back(primType); + } + SelectLibCallNArg(funcName, opndVec, pt, retPrimType, is2ndRet); + return; +} + +void AArch64CGFunc::SelectLibCallNArg(const std::string &funcName, std::vector &opndVec, + std::vector pt, PrimType retPrimType, bool is2ndRet) { std::string newName = funcName; // Check whether we have a maple version of libcall and we want to use it instead. if (!CGOptions::IsDuplicateAsmFileEmpty() && asmMap.find(funcName) != asmMap.end()) { @@ -8293,11 +8329,11 @@ void AArch64CGFunc::SelectLibCall(const std::string &funcName, std::vector vec; std::vector vecAt; for (size_t i = 1; i < opndVec.size(); ++i) { - vec.emplace_back(GlobalTables::GetTypeTable().GetTypeTable()[static_cast(primType)]->GetTypeIndex()); + vec.emplace_back(GlobalTables::GetTypeTable().GetTypeTable()[static_cast(pt[i])]->GetTypeIndex()); vecAt.emplace_back(TypeAttrs()); } - MIRType *retType = GlobalTables::GetTypeTable().GetTypeTable().at(static_cast(primType)); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeTable().at(static_cast(retPrimType)); st->SetTyIdx(GetBecommon().BeGetOrCreateFunctionType(retType->GetTypeIndex(), vec, vecAt)->GetTypeIndex()); if (GetCG()->GenerateVerboseCG()) { @@ -8307,22 +8343,22 @@ void AArch64CGFunc::SelectLibCall(const std::string &funcName, std::vectorNew(*GetFuncScopeAllocator()); for (size_t i = 1; i < opndVec.size(); ++i) { + ASSERT(pt[i] != PTY_void, "primType check"); MIRType *ty; - ty = GlobalTables::GetTypeTable().GetTypeTable()[static_cast(primType)]; + ty = GlobalTables::GetTypeTable().GetTypeTable()[static_cast(pt[i])]; Operand *stOpnd = opndVec[i]; if (stOpnd->GetKind() != Operand::kOpdRegister) { - stOpnd = &SelectCopy(*stOpnd, primType, primType); + stOpnd = &SelectCopy(*stOpnd, pt[i], pt[i]); } RegOperand *expRegOpnd = static_cast(stOpnd); parmLocator.LocateNextParm(*ty, ploc); if (ploc.reg0 != 0) { /* load to the register */ AArch64RegOperand &parmRegOpnd = GetOrCreatePhysicalRegisterOperand( - static_cast(ploc.reg0), expRegOpnd->GetSize(), GetRegTyFromPrimTy(primType)); - SelectCopy(parmRegOpnd, primType, *expRegOpnd, primType); + static_cast(ploc.reg0), expRegOpnd->GetSize(), GetRegTyFromPrimTy(pt[i])); + SelectCopy(parmRegOpnd, pt[i], *expRegOpnd, pt[i]); srcOpnds->PushOpnd(parmRegOpnd); } ASSERT(ploc.reg1 == 0, "SelectCall NYI");