BUILTIN(__builtin_ppc_dcbtt, "vv*", "")
BUILTIN(__builtin_ppc_mftbu, "Ui","")
BUILTIN(__builtin_ppc_mfmsr, "Ui", "")
+BUILTIN(__builtin_ppc_mfspr, "ULiIi", "")
+BUILTIN(__builtin_ppc_mtmsr, "vUi", "")
+BUILTIN(__builtin_ppc_mtspr, "vIiULi", "")
BUILTIN(__builtin_ppc_stfiw, "viC*d", "")
BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
Builder.defineMacro("__dcbtt", "__builtin_ppc_dcbtt");
Builder.defineMacro("__mftbu", "__builtin_ppc_mftbu");
Builder.defineMacro("__mfmsr", "__builtin_ppc_mfmsr");
+ Builder.defineMacro("__mtmsr", "__builtin_ppc_mtmsr");
+ Builder.defineMacro("__mfspr", "__builtin_ppc_mfspr");
+ Builder.defineMacro("__mtspr", "__builtin_ppc_mtspr");
}
/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
case PPC::BI__builtin_ppc_lharx:
case PPC::BI__builtin_ppc_lbarx:
return emitPPCLoadReserveIntrinsic(*this, BuiltinID, E);
+ case PPC::BI__builtin_ppc_mfspr: {
+ llvm::Type *RetType = CGM.getDataLayout().getTypeSizeInBits(VoidPtrTy) == 32
+ ? Int32Ty
+ : Int64Ty;
+ Function *F = CGM.getIntrinsic(Intrinsic::ppc_mfspr, RetType);
+ return Builder.CreateCall(F, Ops);
+ }
+ case PPC::BI__builtin_ppc_mtspr: {
+ llvm::Type *RetType = CGM.getDataLayout().getTypeSizeInBits(VoidPtrTy) == 32
+ ? Int32Ty
+ : Int64Ty;
+ Function *F = CGM.getIntrinsic(Intrinsic::ppc_mtspr, RetType);
+ return Builder.CreateCall(F, Ops);
+ }
case PPC::BI__builtin_ppc_popcntb: {
Value *ArgValue = EmitScalarExpr(E->getArg(0));
llvm::Type *ArgType = ArgValue->getType();
extern int ia, ib;
extern unsigned int ui;
extern unsigned long long ull;
+extern const int cia;
+extern unsigned long ula;
void test_trap(void) {
#ifdef __PPC64__
return __divdeu(dividend, divisor); //expected-error {{this builtin is only available on 64-bit targets}}
}
#endif
+
+unsigned long test_mfspr(void) {
+ return __mfspr(cia); //expected-error {{argument to '__builtin_ppc_mfspr' must be a constant integer}}
+}
+
+void test_mtspr(void) {
+ __mtspr(cia, ula); //expected-error {{argument to '__builtin_ppc_mtspr' must be a constant integer}}
+}
// RUN: %clang_cc1 -O2 -triple powerpc64le-unknown-unknown \
// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s
// RUN: %clang_cc1 -O2 -triple powerpc-unknown-aix \
-// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
+// RUN: -emit-llvm %s -o - -target-cpu pwr7 | \
+// RUN: FileCheck %s --check-prefix=CHECK-32BIT
// RUN: %clang_cc1 -O2 -triple powerpc64-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s
+extern unsigned long ula;
+
unsigned int test_mftbu(void) {
// CHECK-LABEL: @test_mftbu
// CHECK: %0 = tail call i32 @llvm.ppc.mftbu()
// CHECK: %0 = tail call i32 @llvm.ppc.mfmsr()
return __mfmsr();
}
+
+void test_mtmsr(void) {
+ // CHECK-LABEL: @test_mtmsr
+ // CHECK: tail call void @llvm.ppc.mtmsr(i32 %conv)
+ // CHECK-32BIT-LABEL: @test_mtmsr
+ // CHECK-32BIT: tail call void @llvm.ppc.mtmsr(i32 %0)
+ __mtmsr(ula);
+}
+
+unsigned long test_mfspr(void) {
+ // CHECK-LABEL: @test_mfspr
+ // CHECK: %0 = tail call i64 @llvm.ppc.mfspr.i64(i32 898)
+ return __mfspr(898);
+}
+
+void test_mtspr(void) {
+ // CHECK-LABEL: @test_mtspr
+ // CHECK: tail call void @llvm.ppc.mtspr.i64(i32 1, i64 %0)
+ __mtspr(1, ula);
+}
Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
def int_ppc_mfmsr : GCCBuiltin<"__builtin_ppc_mfmsr">,
Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
+ def int_ppc_mfspr
+ : Intrinsic<[llvm_anyint_ty], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
+ def int_ppc_mtmsr
+ : GCCBuiltin<"__builtin_ppc_mtmsr">, Intrinsic<[], [llvm_i32_ty], []>;
+ def int_ppc_mtspr
+ : Intrinsic<[], [llvm_i32_ty, llvm_anyint_ty], [ImmArg<ArgIndex<0>>]>;
def int_ppc_stfiw : GCCBuiltin<"__builtin_ppc_stfiw">,
Intrinsic<[], [llvm_ptr_ty, llvm_double_ty],
[IntrWriteMem]>;
// trapd
def : Pat<(int_ppc_trapd g8rc:$A),
(TDI 24, $A, 0)>;
+def : Pat<(i64 (int_ppc_mfspr timm:$SPR)),
+ (MFSPR8 $SPR)>;
+def : Pat<(int_ppc_mtspr timm:$SPR, g8rc:$RT),
+ (MTSPR8 $SPR, $RT)>;
def : Pat<(int_ppc_mfmsr), (MFMSR)>;
def : Pat<(int_ppc_mftbu), (MFTB 269)>;
+def : Pat<(i32 (int_ppc_mfspr timm:$SPR)),
+ (MFSPR $SPR)>;
+def : Pat<(int_ppc_mtspr timm:$SPR, gprc:$RT),
+ (MTSPR $SPR, $RT)>;
+def : Pat<(int_ppc_mtmsr gprc:$RS),
+ (MTMSR $RS, 0)>;
let Predicates = [IsISA2_07] in {
def : Pat<(int_ppc_sthcx ForceXForm:$dst, gprc:$A),
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN: -mcpu=pwr8 < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
+; RUN: -mcpu=pwr7 < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
+; RUN: -mcpu=pwr7 < %s | FileCheck %s --check-prefix=CHECK-AIX64
+
+declare i64 @llvm.ppc.mfspr.i64(i32 immarg)
+declare void @llvm.ppc.mtspr.i64(i32 immarg, i64)
+
+@ula = external local_unnamed_addr global i64, align 8
+
+define dso_local i64 @test_mfxer() {
+; CHECK-LABEL: test_mfxer:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mfxer 3
+; CHECK-NEXT: blr
+;
+; CHECK-AIX64-LABEL: test_mfxer:
+; CHECK-AIX64: # %bb.0: # %entry
+; CHECK-AIX64-NEXT: mfxer 3
+; CHECK-AIX64-NEXT: blr
+entry:
+ %0 = call i64 @llvm.ppc.mfspr.i64(i32 1)
+ ret i64 %0
+}
+
+define dso_local i64 @test_mflr() {
+; CHECK-LABEL: test_mflr:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mflr 3
+; CHECK-NEXT: blr
+;
+; CHECK-AIX64-LABEL: test_mflr:
+; CHECK-AIX64: # %bb.0: # %entry
+; CHECK-AIX64-NEXT: mfspr 3, 8
+; CHECK-AIX64-NEXT: blr
+entry:
+ %0 = call i64 @llvm.ppc.mfspr.i64(i32 8)
+ ret i64 %0
+}
+
+define dso_local i64 @test_mfctr() {
+; CHECK-LABEL: test_mfctr:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mfctr 3
+; CHECK-NEXT: blr
+;
+; CHECK-AIX64-LABEL: test_mfctr:
+; CHECK-AIX64: # %bb.0: # %entry
+; CHECK-AIX64-NEXT: mfspr 3, 9
+; CHECK-AIX64-NEXT: blr
+entry:
+ %0 = call i64 @llvm.ppc.mfspr.i64(i32 9)
+ ret i64 %0
+}
+
+define dso_local i64 @test_mfppr() {
+; CHECK-LABEL: test_mfppr:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mfspr 3, 896
+; CHECK-NEXT: blr
+;
+; CHECK-AIX64-LABEL: test_mfppr:
+; CHECK-AIX64: # %bb.0: # %entry
+; CHECK-AIX64-NEXT: mfspr 3, 896
+; CHECK-AIX64-NEXT: blr
+entry:
+ %0 = call i64 @llvm.ppc.mfspr.i64(i32 896)
+ ret i64 %0
+}
+
+define dso_local i64 @test_mfppr32() {
+; CHECK-LABEL: test_mfppr32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mfspr 3, 898
+; CHECK-NEXT: blr
+;
+; CHECK-AIX64-LABEL: test_mfppr32:
+; CHECK-AIX64: # %bb.0: # %entry
+; CHECK-AIX64-NEXT: mfspr 3, 898
+; CHECK-AIX64-NEXT: blr
+entry:
+ %0 = call i64 @llvm.ppc.mfspr.i64(i32 898)
+ ret i64 %0
+}
+
+define dso_local void @test_mtxer() {
+; CHECK-LABEL: test_mtxer:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: addis 3, 2, .LC0@toc@ha
+; CHECK-NEXT: ld 3, .LC0@toc@l(3)
+; CHECK-NEXT: ld 3, 0(3)
+; CHECK-NEXT: mtxer 3
+; CHECK-NEXT: blr
+;
+; CHECK-AIX64-LABEL: test_mtxer:
+; CHECK-AIX64: # %bb.0: # %entry
+; CHECK-AIX64-NEXT: ld 3, L..C0(2) # @ula
+; CHECK-AIX64-NEXT: ld 3, 0(3)
+; CHECK-AIX64-NEXT: mtxer 3
+; CHECK-AIX64-NEXT: blr
+entry:
+ %0 = load i64, i64* @ula, align 8
+ tail call void @llvm.ppc.mtspr.i64(i32 1, i64 %0)
+ ret void
+}
+
+define dso_local void @test_mtlr() {
+; CHECK-LABEL: test_mtlr:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: addis 3, 2, .LC0@toc@ha
+; CHECK-NEXT: ld 3, .LC0@toc@l(3)
+; CHECK-NEXT: ld 3, 0(3)
+; CHECK-NEXT: mtlr 3
+; CHECK-NEXT: blr
+;
+; CHECK-AIX64-LABEL: test_mtlr:
+; CHECK-AIX64: # %bb.0: # %entry
+; CHECK-AIX64-NEXT: ld 3, L..C0(2) # @ula
+; CHECK-AIX64-NEXT: ld 3, 0(3)
+; CHECK-AIX64-NEXT: mtspr 8, 3
+; CHECK-AIX64-NEXT: blr
+entry:
+ %0 = load i64, i64* @ula, align 8
+ tail call void @llvm.ppc.mtspr.i64(i32 8, i64 %0)
+ ret void
+}
+
+define dso_local void @test_mtctr() {
+; CHECK-LABEL: test_mtctr:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: addis 3, 2, .LC0@toc@ha
+; CHECK-NEXT: ld 3, .LC0@toc@l(3)
+; CHECK-NEXT: ld 3, 0(3)
+; CHECK-NEXT: mtctr 3
+; CHECK-NEXT: blr
+;
+; CHECK-AIX64-LABEL: test_mtctr:
+; CHECK-AIX64: # %bb.0: # %entry
+; CHECK-AIX64-NEXT: ld 3, L..C0(2) # @ula
+; CHECK-AIX64-NEXT: ld 3, 0(3)
+; CHECK-AIX64-NEXT: mtspr 9, 3
+; CHECK-AIX64-NEXT: blr
+entry:
+ %0 = load i64, i64* @ula, align 8
+ tail call void @llvm.ppc.mtspr.i64(i32 9, i64 %0)
+ ret void
+}
+
+define dso_local void @test_mtppr() {
+; CHECK-LABEL: test_mtppr:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: addis 3, 2, .LC0@toc@ha
+; CHECK-NEXT: ld 3, .LC0@toc@l(3)
+; CHECK-NEXT: ld 3, 0(3)
+; CHECK-NEXT: mtspr 896, 3
+; CHECK-NEXT: blr
+;
+; CHECK-AIX64-LABEL: test_mtppr:
+; CHECK-AIX64: # %bb.0: # %entry
+; CHECK-AIX64-NEXT: ld 3, L..C0(2) # @ula
+; CHECK-AIX64-NEXT: ld 3, 0(3)
+; CHECK-AIX64-NEXT: mtspr 896, 3
+; CHECK-AIX64-NEXT: blr
+entry:
+ %0 = load i64, i64* @ula, align 8
+ tail call void @llvm.ppc.mtspr.i64(i32 896, i64 %0)
+ ret void
+}
+
+define dso_local void @test_mtppr32() {
+; CHECK-LABEL: test_mtppr32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: addis 3, 2, .LC0@toc@ha
+; CHECK-NEXT: ld 3, .LC0@toc@l(3)
+; CHECK-NEXT: ld 3, 0(3)
+; CHECK-NEXT: mtspr 898, 3
+; CHECK-NEXT: blr
+;
+; CHECK-AIX64-LABEL: test_mtppr32:
+; CHECK-AIX64: # %bb.0: # %entry
+; CHECK-AIX64-NEXT: ld 3, L..C0(2) # @ula
+; CHECK-AIX64-NEXT: ld 3, 0(3)
+; CHECK-AIX64-NEXT: mtspr 898, 3
+; CHECK-AIX64-NEXT: blr
+entry:
+ %0 = load i64, i64* @ula, align 8
+ tail call void @llvm.ppc.mtspr.i64(i32 898, i64 %0)
+ ret void
+}
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
+; RUN: -mcpu=pwr7 < %s | FileCheck %s
+
+declare i32 @llvm.ppc.mfspr.i32(i32 immarg)
+declare void @llvm.ppc.mtspr.i32(i32 immarg, i32)
+
+@ula = external dso_local global i32, align 4
+
+define dso_local i32 @test_mfxer() {
+; CHECK-LABEL: test_mfxer:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mfxer 3
+; CHECK-NEXT: blr
+entry:
+ %0 = call i32 @llvm.ppc.mfspr.i32(i32 1)
+ ret i32 %0
+}
+
+define dso_local i32 @test_mflr() {
+; CHECK-LABEL: test_mflr:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mfspr 3, 8
+; CHECK-NEXT: blr
+entry:
+ %0 = call i32 @llvm.ppc.mfspr.i32(i32 8)
+ ret i32 %0
+}
+
+define dso_local i32 @test_mfctr() {
+; CHECK-LABEL: test_mfctr:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mfspr 3, 9
+; CHECK-NEXT: blr
+entry:
+ %0 = call i32 @llvm.ppc.mfspr.i32(i32 9)
+ ret i32 %0
+}
+
+define dso_local i32 @test_mfppr() {
+; CHECK-LABEL: test_mfppr:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mfspr 3, 896
+; CHECK-NEXT: blr
+entry:
+ %0 = call i32 @llvm.ppc.mfspr.i32(i32 896)
+ ret i32 %0
+}
+
+define dso_local i32 @test_mfppr32() {
+; CHECK-LABEL: test_mfppr32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mfspr 3, 898
+; CHECK-NEXT: blr
+entry:
+ %0 = call i32 @llvm.ppc.mfspr.i32(i32 898)
+ ret i32 %0
+}
+
+define dso_local void @test_mtxer() {
+; CHECK-LABEL: test_mtxer:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lwz 3, L..C0(2) # @ula
+; CHECK-NEXT: lwz 3, 0(3)
+; CHECK-NEXT: mtxer 3
+; CHECK-NEXT: blr
+entry:
+ %0 = load i32, i32* @ula, align 8
+ tail call void @llvm.ppc.mtspr.i32(i32 1, i32 %0)
+ ret void
+}
+
+define dso_local void @test_mtlr() {
+; CHECK-LABEL: test_mtlr:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lwz 3, L..C0(2) # @ula
+; CHECK-NEXT: lwz 3, 0(3)
+; CHECK-NEXT: mtspr 8, 3
+; CHECK-NEXT: blr
+entry:
+ %0 = load i32, i32* @ula, align 8
+ tail call void @llvm.ppc.mtspr.i32(i32 8, i32 %0)
+ ret void
+}
+
+define dso_local void @test_mtctr() {
+; CHECK-LABEL: test_mtctr:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lwz 3, L..C0(2) # @ula
+; CHECK-NEXT: lwz 3, 0(3)
+; CHECK-NEXT: mtspr 9, 3
+; CHECK-NEXT: blr
+entry:
+ %0 = load i32, i32* @ula, align 8
+ tail call void @llvm.ppc.mtspr.i32(i32 9, i32 %0)
+ ret void
+}
+
+define dso_local void @test_mtppr() {
+; CHECK-LABEL: test_mtppr:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lwz 3, L..C0(2) # @ula
+; CHECK-NEXT: lwz 3, 0(3)
+; CHECK-NEXT: mtspr 896, 3
+; CHECK-NEXT: blr
+entry:
+ %0 = load i32, i32* @ula, align 8
+ tail call void @llvm.ppc.mtspr.i32(i32 896, i32 %0)
+ ret void
+}
+
+define dso_local void @test_mtppr32() {
+; CHECK-LABEL: test_mtppr32:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: lwz 3, L..C0(2) # @ula
+; CHECK-NEXT: lwz 3, 0(3)
+; CHECK-NEXT: mtspr 898, 3
+; CHECK-NEXT: blr
+entry:
+ %0 = load i32, i32* @ula, align 8
+ tail call void @llvm.ppc.mtspr.i32(i32 898, i32 %0)
+ ret void
+}
; RUN: -mcpu=pwr8 < %s | FileCheck %s
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
; RUN: -mcpu=pwr7 < %s | FileCheck %s
-; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
-; RUN: -mcpu=pwr7 < %s | FileCheck %s --check-prefix=CHECK-32BIT
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
; RUN: -mcpu=pwr7 < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
+; RUN: -mcpu=pwr7 < %s | FileCheck %s --check-prefix=CHECK-32BIT
declare i32 @llvm.ppc.mftbu()
declare i32 @llvm.ppc.mfmsr()
+declare void @llvm.ppc.mtmsr(i32)
+
+@ula = external local_unnamed_addr global i64, align 8
define dso_local zeroext i32 @test_mftbu() {
; CHECK-LABEL: test_mftbu:
%conv = zext i32 %0 to i64
ret i64 %conv
}
+
+define dso_local void @test_mtmsr() {
+; CHECK-LABEL: test_mtmsr:
+; CHECK: mtmsr 3
+; CHECK-NEXT: blr
+;
+; CHECK-32BIT-LABEL: test_mtmsr:
+; CHECK-32BIT: # %bb.0: # %entry
+; CHECK-32BIT-NEXT: lwz 3, L..C0(2) # @ula
+; CHECK-32BIT-NEXT: lwz 3, 4(3)
+; CHECK-32BIT-NEXT: mtmsr 3, 0
+; CHECK-32BIT-NEXT: blr
+entry:
+ %0 = load i64, i64* @ula, align 8
+ %conv = trunc i64 %0 to i32
+ call void @llvm.ppc.mtmsr(i32 %conv)
+ ret void
+}