diff --git a/src/hir2mpl/ast_input/clang/include/ast_expr.h b/src/hir2mpl/ast_input/clang/include/ast_expr.h index 51b08b0536faf969815c76ffbdc926bd332908d4..58a6bdcac6500ee5b1e1967278e9f27587e5a07a 100644 --- a/src/hir2mpl/ast_input/clang/include/ast_expr.h +++ b/src/hir2mpl/ast_input/clang/include/ast_expr.h @@ -1176,7 +1176,16 @@ class ASTCallExpr : public ASTExpr { UniqueFEIRExpr EMIT_BUILTIIN_FUNC(RotateRight16); UniqueFEIRExpr EMIT_BUILTIIN_FUNC(RotateRight32); UniqueFEIRExpr EMIT_BUILTIIN_FUNC(RotateRight64); - + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Strcpy); + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Strncpy); + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Strchr); + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Strlen); + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Strcmp); + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Strncmp); + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Memcpy); + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Memcmp); + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Memmove); + UniqueFEIRExpr EMIT_BUILTIIN_FUNC(Memset); UniqueFEIRExpr EMIT_BUILTIIN_FUNC(SyncAddAndFetch8); UniqueFEIRExpr EMIT_BUILTIIN_FUNC(SyncAddAndFetch4); UniqueFEIRExpr EMIT_BUILTIIN_FUNC(SyncAddAndFetch2); diff --git a/src/hir2mpl/ast_input/clang/include/builtin_func_emit.def b/src/hir2mpl/ast_input/clang/include/builtin_func_emit.def index 1b4efe5299d793b87aa3a9fd3fcc82b927877245..3dc3ef036a893f90ce7314d3e59e9056eaebd0aa 100644 --- a/src/hir2mpl/ast_input/clang/include/builtin_func_emit.def +++ b/src/hir2mpl/ast_input/clang/include/builtin_func_emit.def @@ -128,4 +128,25 @@ BUILTIN_FUNC_EMIT("__sync_lock_test_and_set_4", &ASTCallExpr::EmitBuiltinSyncLoc BUILTIN_FUNC_EMIT("__sync_lock_release_8", &ASTCallExpr::EmitBuiltinSyncLockRelease8) BUILTIN_FUNC_EMIT("__sync_lock_release_4", &ASTCallExpr::EmitBuiltinSyncLockRelease4) BUILTIN_FUNC_EMIT("__builtin_return_address", &ASTCallExpr::EmitBuiltinReturnAddress) -BUILTIN_FUNC_EMIT("__builtin_extract_return_addr", &ASTCallExpr::EmitBuiltinExtractReturnAddr) \ No newline at end of file +BUILTIN_FUNC_EMIT("__builtin_extract_return_addr", &ASTCallExpr::EmitBuiltinExtractReturnAddr) + +BUILTIN_FUNC_EMIT("__builtin_strcpy", &ASTCallExpr::EmitBuiltinStrcpy) +BUILTIN_FUNC_EMIT("strcpy", &ASTCallExpr::EmitBuiltinStrcpy) +BUILTIN_FUNC_EMIT("__builtin_strncpy", &ASTCallExpr::EmitBuiltinStrncpy) +BUILTIN_FUNC_EMIT("strncpy", &ASTCallExpr::EmitBuiltinStrncpy) +//BUILTIN_FUNC_EMIT("__builtin_strchr", &ASTCallExpr::EmitBuiltinStrchr) +//BUILTIN_FUNC_EMIT("strchr", &ASTCallExpr::EmitBuiltinStrchr) +BUILTIN_FUNC_EMIT("__builtin_memcmp", &ASTCallExpr::EmitBuiltinMemcmp) +BUILTIN_FUNC_EMIT("memcmp", &ASTCallExpr::EmitBuiltinMemcmp) +BUILTIN_FUNC_EMIT("__builtin_memcpy", &ASTCallExpr::EmitBuiltinMemcpy) +//BUILTIN_FUNC_EMIT("memcpy", &ASTCallExpr::EmitBuiltinMemcpy) +BUILTIN_FUNC_EMIT("__builtin_memset", &ASTCallExpr::EmitBuiltinMemset) +BUILTIN_FUNC_EMIT("memset", &ASTCallExpr::EmitBuiltinMemset) +BUILTIN_FUNC_EMIT("__builtin_strlen", &ASTCallExpr::EmitBuiltinStrlen) +BUILTIN_FUNC_EMIT("strlen", &ASTCallExpr::EmitBuiltinStrlen) +BUILTIN_FUNC_EMIT("__builtin_strcmp", &ASTCallExpr::EmitBuiltinStrcmp) +BUILTIN_FUNC_EMIT("strcmp", &ASTCallExpr::EmitBuiltinStrcmp) +BUILTIN_FUNC_EMIT("__builtin_strncmp", &ASTCallExpr::EmitBuiltinStrncmp) +//BUILTIN_FUNC_EMIT("strncmp", &ASTCallExpr::EmitBuiltinStrncmp) +BUILTIN_FUNC_EMIT("__builtin_memmove", &ASTCallExpr::EmitBuiltinMemmove) +BUILTIN_FUNC_EMIT("memmove", &ASTCallExpr::EmitBuiltinMemmove) \ No newline at end of file diff --git a/src/hir2mpl/ast_input/clang/src/ast_parser_builting_func.cpp b/src/hir2mpl/ast_input/clang/src/ast_parser_builting_func.cpp index 0ad44fa41379ba4136dbfcbb9f97aac02de39673..580f6ab67ab1166d8cba897d1d05f9f0b6a850f2 100644 --- a/src/hir2mpl/ast_input/clang/src/ast_parser_builting_func.cpp +++ b/src/hir2mpl/ast_input/clang/src/ast_parser_builting_func.cpp @@ -423,6 +423,41 @@ UniqueFEIRExpr ASTCallExpr::EmitBuiltinExtractReturnAddr(std::list &stmts) const { + return CreateIntrinsicopForC(stmts, INTRN_C_strcpy); +} +UniqueFEIRExpr ASTCallExpr::EmitBuiltinStrncpy(std::list &stmts) const { + return CreateIntrinsicopForC(stmts, INTRN_C_strncpy); +} + +UniqueFEIRExpr ASTCallExpr::EmitBuiltinMemcpy(std::list &stmts) const { + return CreateIntrinsicopForC(stmts, INTRN_C_memcpy); +} + +UniqueFEIRExpr ASTCallExpr::EmitBuiltinMemset(std::list &stmts) const { + return CreateIntrinsicopForC(stmts, INTRN_C_memset); +} + +UniqueFEIRExpr ASTCallExpr::EmitBuiltinMemcmp(std::list &stmts) const { + return CreateIntrinsicopForC(stmts, INTRN_C_memcmp); +} + +UniqueFEIRExpr ASTCallExpr::EmitBuiltinStrlen(std::list &stmts) const { + return CreateIntrinsicopForC(stmts, INTRN_C_strlen); +} + +UniqueFEIRExpr ASTCallExpr::EmitBuiltinStrcmp(std::list &stmts) const { + return CreateIntrinsicopForC(stmts, INTRN_C_strcmp); +} + +UniqueFEIRExpr ASTCallExpr::EmitBuiltinStrncmp(std::list &stmts) const { + return CreateIntrinsicopForC(stmts, INTRN_C_strncmp); +} + +UniqueFEIRExpr ASTCallExpr::EmitBuiltinMemmove(std::list &stmts) const { + return CreateIntrinsicopForC(stmts, INTRN_C_memmove); +} + UniqueFEIRExpr ASTCallExpr::EmitBuiltinAlloca(std::list &stmts) const { auto arg = args[0]->Emit2FEExpr(stmts); CHECK_NULL_FATAL(mirType); 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 475d9df31249122991ceaa2329fde553694de532..239fe2f510217a2ac09621658df1add1222eb215 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -119,6 +119,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; @@ -247,6 +248,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(RegOperand ®); bool IsRegSameRematInfo(RegOperand ®Dest, RegOperand ®Src); void ReplaceOpndInInsn(RegOperand ®Dest, RegOperand ®Src, Insn &insn) override; diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index d665bcadb58e21063da71455502fe90bc0df24ff..ec7e614fa1bdba276cdf7267658b3d52530c8e48 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -183,6 +183,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/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 2442510c694d38368410a3aed55976666fb8cb16..fb610bdd843a2e036a2cd1e92ac8f69d63371833 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -3638,6 +3638,15 @@ bool CGLowerer::IsIntrinsicOpHandledAtLowerLevel(MIRIntrinsicID intrinsic) { case INTRN_C___sync_lock_release_4: case INTRN_C__builtin_return_address: case INTRN_C__builtin_extract_return_addr: + case INTRN_C_strcpy: + case INTRN_C_strncpy: + case INTRN_C_memcmp: + case INTRN_C_memcpy: + case INTRN_C_memset: + case INTRN_C_strlen: + case INTRN_C_strcmp: + case INTRN_C_strncmp: + case INTRN_C_memmove: return true; #endif default: 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 8e81a29470011881a2716f6384f9cf1249d75503..4e4ad3c22fa88b5a68586a068e9bbe7e00650fe8 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1534,7 +1534,14 @@ void AArch64CGFunc::SelectAggDassign(DassignNode &stmt) { opndVec.push_back(PrepareMemcpyParamOpnd(lhsSize)); /* param 2 */ - SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); + std::vector opndTypes; + + opndTypes.push_back(maple::PTY_a64); + opndTypes.push_back(maple::PTY_a64); + opndTypes.push_back(maple::PTY_a64); + opndTypes.push_back(maple::PTY_u64); + + SelectLibCallNArg("memcpy", opndVec, opndTypes, PTY_a64, false); return; } @@ -1654,8 +1661,14 @@ void AArch64CGFunc::SelectAggDassign(DassignNode &stmt) { opndVec.push_back(PrepareMemcpyParamOpnd(rhsOffset, *addrOpnd)); /* param 1 */ opndVec.push_back(PrepareMemcpyParamOpnd(lhsSize)); /* param 2 */ + std::vector opndTypes; + + opndTypes.push_back(maple::PTY_a64); + opndTypes.push_back(maple::PTY_a64); + opndTypes.push_back(maple::PTY_a64); + opndTypes.push_back(maple::PTY_u64); - SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); + SelectLibCallNArg("memcpy", opndVec, opndTypes, PTY_a64, false); return; } @@ -2031,7 +2044,14 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { opndVec.push_back(PrepareMemcpyParamOpnd(lhsSize)); /* param 2 */ - SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); + std::vector opndTypes; + + opndTypes.push_back(maple::PTY_a64); + opndTypes.push_back(maple::PTY_a64); + opndTypes.push_back(maple::PTY_a64); + opndTypes.push_back(maple::PTY_u64); + + SelectLibCallNArg("memcpy", opndVec, opndTypes, PTY_a64, false); return; } @@ -2167,7 +2187,14 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { opndVec.push_back(PrepareMemcpyParamOpnd(lhsSize)); /* param 2 */ - SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); + std::vector opndTypes; + + opndTypes.push_back(maple::PTY_a64); + opndTypes.push_back(maple::PTY_a64); + opndTypes.push_back(maple::PTY_a64); + opndTypes.push_back(maple::PTY_u64); + + SelectLibCallNArg("memcpy", opndVec, opndTypes, PTY_a64, false); return; } @@ -4756,6 +4783,36 @@ Operand *AArch64CGFunc::SelectIntrinsicOpWithOneParam(IntrinsicopNode &intrnNode return dst; } +Operand *AArch64CGFunc::SelectIntrinsicOpWithNParams(IntrinsicopNode &intrnNode, PrimType retType, std::string name) { + MapleVector argNodes = intrnNode.GetNopnd(); + //FATAL(argNodes.size() > 0, "Faild to process intrinsic with zero params by NParams func"); + + 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); @@ -8135,6 +8192,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) { MIRSymbol *st = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal); st->SetNameStrIdx(funcName); st->SetStorageClass(kScExtern); @@ -8143,11 +8211,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()) { @@ -8157,22 +8225,22 @@ void AArch64CGFunc::SelectLibCall(const std::string &funcName, std::vectorNew(*GetFuncScopeAllocator()); for (size_t i = 1; i < opndVec.size(); ++i) { 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(ploc.reg0, expRegOpnd->GetSize(), GetRegTyFromPrimTy(primType)); - SelectCopy(parmRegOpnd, primType, *expRegOpnd, primType); + GetOrCreatePhysicalRegisterOperand(ploc.reg0, expRegOpnd->GetSize(), GetRegTyFromPrimTy(pt[i])); + SelectCopy(parmRegOpnd, pt[i], *expRegOpnd, pt[i]); srcOpnds->PushOpnd(parmRegOpnd); } ASSERT(ploc.reg1 == 0, "SelectCall NYI"); diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index eb470d03156d4e4fe218c1c1c3a501c6fa75d7a7..1c142a849b6e4b13b0e7b5d61ecf509d6bd45b6b 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -611,6 +611,25 @@ Operand *HandleIntrinOp(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc) case INTRN_C_ffs: return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "ffs"); + case INTRN_C_strcpy: + return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_a64, "strcpy"); + case INTRN_C_strncpy: + return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_a64, "strncpy"); + case INTRN_C_memcmp: + return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_i32, "memcmp"); + case INTRN_C_memcpy: + return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_a64, "memcpy"); + case INTRN_C_memset: + return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_a64, "memset"); + case INTRN_C_strlen: + return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_a64, "strlen"); + case INTRN_C_strcmp: + return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_i32, "strcmp"); + case INTRN_C_strncmp: + return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_i32, "strncmp"); + case INTRN_C_memmove: + return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_a64, "memmove"); + case INTRN_C_clz32: case INTRN_C_clz64: return cgFunc.SelectCclz(intrinsicopNode);