diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -25,6 +25,22 @@ # define BUILTIN(ID, TYPES, ATTRS) #endif +BUILTIN(__popcntb, "ULiULi", "") +BUILTIN(__eieio, "v", "") +BUILTIN(__iospace_eieio, "v", "") +BUILTIN(__isync, "v", "") +BUILTIN(__lwsync, "v", "") +BUILTIN(__iospace_lwsync, "v", "") +BUILTIN(__sync, "v", "") +BUILTIN(__iospace_sync, "v", "") +BUILTIN(__dcbfl, "vvC*", "") +BUILTIN(__dcbflp, "vvC*", "") +BUILTIN(__dcbst, "vvC*", "") +BUILTIN(__dcbt, "vv*", "") +BUILTIN(__dcbtst, "vv*", "") +BUILTIN(__dcbz, "vv*", "") +BUILTIN(__icbt, "vv*", "") + BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n") // This is just a placeholder, the types and attributes are wrong. diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td --- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -20,34 +20,53 @@ def int_ppc_dcba : Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbf : GCCBuiltin<"__builtin_dcbf">, Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; - def int_ppc_dcbfl : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; - def int_ppc_dcbflp : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; + def int_ppc_dcbfl : GCCBuiltin<"__dcbfl">, + Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; + def int_ppc_dcbflp : GCCBuiltin<"__dcbflp">, + Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; def int_ppc_dcbfps : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; def int_ppc_dcbstps : Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly]>; def int_ppc_dcbi : Intrinsic<[], [llvm_ptr_ty], []>; - def int_ppc_dcbst : Intrinsic<[], [llvm_ptr_ty], []>; - def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty], + def int_ppc_dcbst : GCCBuiltin<"__dcbst">, + Intrinsic<[], [llvm_ptr_ty], []>; + def int_ppc_dcbt : GCCBuiltin<"__dcbt">, + Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly, NoCapture>]>; - def int_ppc_dcbtst: Intrinsic<[], [llvm_ptr_ty], + def int_ppc_dcbtst : GCCBuiltin<"__dcbtst">, + Intrinsic<[], [llvm_ptr_ty], [IntrArgMemOnly, NoCapture>]>; def int_ppc_dcbt_with_hint: Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrArgMemOnly, NoCapture>, ImmArg>]>; def int_ppc_dcbtst_with_hint: Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrArgMemOnly, NoCapture>, ImmArg>]>; - def int_ppc_dcbz : Intrinsic<[], [llvm_ptr_ty], []>; + def int_ppc_dcbz : GCCBuiltin<"__dcbz">, + Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbzl : Intrinsic<[], [llvm_ptr_ty], []>; + def int_ppc_icbt : GCCBuiltin<"__icbt">, + Intrinsic<[], [llvm_ptr_ty], []>; // Population Count in each Byte. - def int_ppc_popcntb : Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>; + def int_ppc_popcntb : GCCBuiltin<"__popcntb">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>; // sync instruction (i.e. sync 0, a.k.a hwsync) - def int_ppc_sync : Intrinsic<[], [], []>; + def int_ppc_sync : GCCBuiltin<"__sync">, + Intrinsic<[], [], []>; + def int_ppc_iospace_sync : GCCBuiltin<"__iospace_sync">, + Intrinsic<[], [], []>; // isync instruction - def int_ppc_isync : Intrinsic<[], [], []>; + def int_ppc_isync : GCCBuiltin<"__isync">, + Intrinsic<[], [], []>; // lwsync is sync 1 - def int_ppc_lwsync : Intrinsic<[], [], []>; + def int_ppc_lwsync : GCCBuiltin<"__lwsync">, + Intrinsic<[], [], []>; + def int_ppc_iospace_lwsync : GCCBuiltin<"__iospace_lwsync">, + Intrinsic<[], [], []>; // eieio instruction - def int_ppc_eieio : Intrinsic<[],[],[]>; + def int_ppc_eieio : GCCBuiltin<"__eieio">, + Intrinsic<[],[],[]>; + def int_ppc_iospace_eieio : GCCBuiltin<"__iospace_eieio">, + Intrinsic<[],[],[]>; // Get content from current FPSCR register def int_ppc_readflm : GCCBuiltin<"__builtin_readflm">, diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -1351,6 +1351,16 @@ // Now process the instruction normally. break; } + case PPC::PseudoEIEIO: + case PPC::PseudoIOSPACEEIEIO: + EmitToStreamer( + *OutStreamer, + MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0)); + EmitToStreamer( + *OutStreamer, + MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::EnforceIEIO)); + break; } LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -2044,6 +2044,8 @@ (DCBTST 0, xoaddr:$dst)>; def : Pat<(int_ppc_dcbf xoaddr:$dst), (DCBF 0, xoaddr:$dst)>; +def : Pat<(int_ppc_icbt xoaddr:$dst), + (ICBT 0, xoaddr:$dst)>; def : Pat<(prefetch xoaddr:$dst, (i32 0), imm, (i32 1)), (DCBT 0, xoaddr:$dst)>; // data prefetch for loads @@ -2565,11 +2567,21 @@ def EnforceIEIO : XForm_24_eieio<31, 854, (outs), (ins), "eieio", IIC_LdStLoad, []>; +def PseudoEIEIO : PPCEmitTimePseudo<(outs), (ins), "#PPCEIEIO", + [(int_ppc_eieio)]>; +def PseudoIOSPACEEIEIO : PPCEmitTimePseudo<(outs), (ins), "#PPCIOSPACEEIEIO", + [(int_ppc_iospace_eieio)]>; + def : Pat<(int_ppc_sync), (SYNC 0)>, Requires<[HasSYNC]>; +def : Pat<(int_ppc_iospace_sync), (SYNC 0)>, Requires<[HasSYNC]>; def : Pat<(int_ppc_lwsync), (SYNC 1)>, Requires<[HasSYNC]>; +def : Pat<(int_ppc_iospace_lwsync), (SYNC 1)>, Requires<[HasSYNC]>; def : Pat<(int_ppc_sync), (MSYNC)>, Requires<[HasOnlyMSYNC]>; +def : Pat<(int_ppc_iospace_sync), (MSYNC)>, Requires<[HasOnlyMSYNC]>; def : Pat<(int_ppc_lwsync), (MSYNC)>, Requires<[HasOnlyMSYNC]>; +def : Pat<(int_ppc_iospace_lwsync), (MSYNC)>, Requires<[HasOnlyMSYNC]>; def : Pat<(int_ppc_eieio), (EnforceIEIO)>; +def : Pat<(int_ppc_iospace_eieio), (EnforceIEIO)>; //===----------------------------------------------------------------------===// // PPC32 Arithmetic Instructions. diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat.ll @@ -0,0 +1,67 @@ +; RUN: llc < %s | FileCheck %s + +define dso_local void @test_builtin_ppc_eieio() #0 { +; CHECK-LABEL: test_builtin_ppc_eieio + +entry: + call void @llvm.ppc.eieio() +; CHECK: ori 2, 2, 0 +; CHECK-NEXT: ori 2, 2, 0 +; CHECK-NEXT: eieio + + ret void +} + +declare void @llvm.ppc.eieio() #2 + +define dso_local void @test_builtin_ppc_iospace_eieio() #0 { +; CHECK-LABEL: test_builtin_ppc_iospace_eieio + +entry: + call void @llvm.ppc.iospace.eieio() +; CHECK: ori 2, 2, 0 +; CHECK-NEXT: ori 2, 2, 0 +; CHECK-NEXT: eieio + + ret void +} + +declare void @llvm.ppc.iospace.eieio() #2 + +define dso_local void @test_builtin_ppc_iospace_lwsync() #0 { +; CHECK-LABEL: test_builtin_ppc_iospace_lwsync + +entry: + call void @llvm.ppc.iospace.lwsync() +; CHECK: lwsync + + ret void +} + +declare void @llvm.ppc.iospace.lwsync() #2 + +define dso_local void @test_builtin_ppc_iospace_sync() #0 { +; CHECK-LABEL: test_builtin_ppc_iospace_sync + +entry: + call void @llvm.ppc.iospace.sync() +; CHECK: sync + + ret void +} + +declare void @llvm.ppc.iospace.sync() #2 + +define dso_local void @test_builtin_ppc_icbt() #0 { +; CHECK-LABEL: test_builtin_ppc_icbt + +entry: + %a = alloca i8*, align 8 + %0 = load i8*, i8** %a, align 8 + call void @llvm.ppc.icbt(i8* %0) +; CHECK: icbt 0, 0, 3 + + ret void +} + +declare void @llvm.ppc.icbt(i8*) #2