Index: clang/docs/LanguageExtensions.rst =================================================================== --- clang/docs/LanguageExtensions.rst +++ clang/docs/LanguageExtensions.rst @@ -2448,6 +2448,31 @@ than 3, it will only use the least significant two bits of the mode. Namely, ``__builtin_setrnd(102))`` is equal to ``__builtin_setrnd(2)``. +PowerPC cache builtins +^^^^^^^^^^^^^^^^^^^^^^ + +The PowerPC architecture specifies instructions implementing cache operations. +Clang provides builtins that give direct programmer access to these cache +instructions. + +Currently the following builtins are implemented in clang: + +``__builtin_dcbf`` copies the contents of a modified block from the data cache +to main memory and flushes the copy from the data cache. + +**Syntax**: + +.. code-block:: c + + void __dcbf(const void* addr); /* Data Cache Block Flush */ + +**Example of Use**: + +.. code-block:: c + + int a = 1; + __builtin_dcbf (&a); + Extensions for Static Analysis ============================== Index: clang/include/clang/Basic/BuiltinsPPC.def =================================================================== --- clang/include/clang/Basic/BuiltinsPPC.def +++ clang/include/clang/Basic/BuiltinsPPC.def @@ -478,6 +478,9 @@ // Set the floating point rounding mode BUILTIN(__builtin_setrnd, "di", "") +// Cache built-ins +BUILTIN(__builtin_dcbf, "vvC*", "") + // FIXME: Obviously incomplete. #undef BUILTIN Index: clang/test/CodeGen/builtins-ppc-cache.c =================================================================== --- /dev/null +++ clang/test/CodeGen/builtins-ppc-cache.c @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -emit-llvm \ +// RUN: -o - %s | FileCheck %s + +int A; +int B[5]; +float C; +float D[5]; +double E; +double F[5]; + +void func(int a, int b[], float c, float d[], double e, double f[]) { + __builtin_dcbf (&a); + // CHECK: @llvm.ppc.dcbf(i8* + + __builtin_dcbf (&A); + // CHECK: @llvm.ppc.dcbf(i8* + + __builtin_dcbf (&b[2]); + // CHECK: @llvm.ppc.dcbf(i8* + + __builtin_dcbf (&B[2]); + // CHECK: @llvm.ppc.dcbf(i8* + + __builtin_dcbf (&c); + // CHECK: @llvm.ppc.dcbf(i8* + + __builtin_dcbf (&C); + // CHECK: @llvm.ppc.dcbf(i8* + + __builtin_dcbf (&d[2]); + // CHECK: @llvm.ppc.dcbf(i8* + + __builtin_dcbf (&D[2]); + // CHECK: @llvm.ppc.dcbf(i8* + + __builtin_dcbf (&e); + // CHECK: @llvm.ppc.dcbf(i8* + + __builtin_dcbf (&E); + // CHECK: @llvm.ppc.dcbf(i8* + + __builtin_dcbf (&f[0]); + // CHECK: @llvm.ppc.dcbf(i8* + + __builtin_dcbf (&F[0]); + // CHECK: @llvm.ppc.dcbf(i8* +} Index: llvm/include/llvm/IR/IntrinsicsPowerPC.td =================================================================== --- llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -18,7 +18,8 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". // dcba/dcbf/dcbi/dcbst/dcbt/dcbz/dcbzl(PPC970) instructions. def int_ppc_dcba : Intrinsic<[], [llvm_ptr_ty], []>; - def int_ppc_dcbf : Intrinsic<[], [llvm_ptr_ty], []>; + def int_ppc_dcbf : GCCBuiltin<"__builtin_dcbf">, + Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbi : Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbst : Intrinsic<[], [llvm_ptr_ty], []>; def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty], Index: llvm/test/CodeGen/PowerPC/dcbf.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/dcbf.ll @@ -0,0 +1,15 @@ +; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu < %s \ +; RUN: -verify-machineinstrs -ppc-asm-full-reg-names \ +; RUN: -ppc-vsr-nums-as-vr | FileCheck %s + +; Function Attrs: nounwind +define void @dcbf_test(i8* %a) { +entry: + tail call void @llvm.ppc.dcbf(i8* %a) +; CHECK-LABEL: @dcbf_test +; CHECK: dcbf 0, r3 +; CHECK-NEXT: blr +ret void +} + +declare void @llvm.ppc.dcbf(i8*)