forked from OSchip/llvm-project
[PowerPC] Implament Load and Reserve and Store Conditional Builtins
This patch implaments the load and reserve and store conditional builtins for the PowerPC target, in order to have feature parody with xlC on AIX. Differential revision: https://reviews.llvm.org/D105236
This commit is contained in:
parent
21106388eb
commit
7d10dd60ce
|
@ -55,6 +55,10 @@ BUILTIN(__builtin_ppc_fetch_and_or, "UiUiD*Ui", "")
|
|||
BUILTIN(__builtin_ppc_fetch_and_orlp, "ULiULiD*ULi", "")
|
||||
BUILTIN(__builtin_ppc_fetch_and_swap, "UiUiD*Ui", "")
|
||||
BUILTIN(__builtin_ppc_fetch_and_swaplp, "ULiULiD*ULi", "")
|
||||
BUILTIN(__builtin_ppc_ldarx, "LiLiD*", "")
|
||||
BUILTIN(__builtin_ppc_lwarx, "iiD*", "")
|
||||
BUILTIN(__builtin_ppc_stdcx, "iLiD*Li", "")
|
||||
BUILTIN(__builtin_ppc_stwcx, "iiD*i", "")
|
||||
|
||||
BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
|
||||
|
||||
|
|
|
@ -108,6 +108,10 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
|
|||
Builder.defineMacro("__fetch_and_orlp", "__builtin_ppc_fetch_and_orlp");
|
||||
Builder.defineMacro("__fetch_and_swap", "__builtin_ppc_fetch_and_swap");
|
||||
Builder.defineMacro("__fetch_and_swaplp", "__builtin_ppc_fetch_and_swaplp");
|
||||
Builder.defineMacro("__ldarx", "__builtin_ppc_ldarx");
|
||||
Builder.defineMacro("__lwarx", "__builtin_ppc_lwarx");
|
||||
Builder.defineMacro("__stdcx", "__builtin_ppc_stdcx");
|
||||
Builder.defineMacro("__stwcx", "__builtin_ppc_stwcx");
|
||||
}
|
||||
|
||||
/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
|
||||
|
|
|
@ -3265,6 +3265,8 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
|
|||
case PPC::BI__builtin_divde:
|
||||
case PPC::BI__builtin_divdeu:
|
||||
case PPC::BI__builtin_bpermd:
|
||||
case PPC::BI__builtin_ppc_ldarx:
|
||||
case PPC::BI__builtin_ppc_stdcx:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// RUN: not %clang_cc1 -triple=powerpc-unknown-aix -emit-llvm %s -o - 2>&1 |\
|
||||
// RUN: FileCheck %s --check-prefix=CHECK32-ERROR
|
||||
// RUN: %clang_cc1 -triple=powerpc64-unknown-aix -emit-llvm %s -o - | \
|
||||
// RUN: FileCheck %s --check-prefix=CHECK64
|
||||
// RUN: %clang_cc1 -triple=powerpc64le-unknown-unknown -emit-llvm %s \
|
||||
// RUN: -o - | FileCheck %s --check-prefix=CHECK64
|
||||
// RUN: %clang_cc1 -triple=powerpc64-unknown-unknown -emit-llvm %s \
|
||||
// RUN: -o - | FileCheck %s --check-prefix=CHECK64
|
||||
|
||||
long test_ldarx(volatile long* a) {
|
||||
// CHECK64-LABEL: @test_ldarx
|
||||
// CHECK64: %0 = load i64*, i64** %a.addr, align 8
|
||||
// CHECK64: %1 = bitcast i64* %0 to i8*
|
||||
// CHECK64: %2 = call i64 @llvm.ppc.ldarx(i8* %1)
|
||||
// CHECK32-ERROR: error: this builtin is only available on 64-bit targets
|
||||
return __ldarx(a);
|
||||
}
|
||||
|
||||
int test_stdcx(volatile long* addr, long val) {
|
||||
// CHECK64-LABEL: @test_stdcx
|
||||
// CHECK64: %0 = load i64*, i64** %addr.addr, align 8
|
||||
// CHECK64: %1 = bitcast i64* %0 to i8*
|
||||
// CHECK64: %2 = load i64, i64* %val.addr, align 8
|
||||
// CHECK64: %3 = call i32 @llvm.ppc.stdcx(i8* %1, i64 %2)
|
||||
// CHECK32-ERROR: error: this builtin is only available on 64-bit targets
|
||||
return __stdcx(addr, val);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// RUN: %clang_cc1 -triple=powerpc-unknown-aix -emit-llvm %s -o - | \
|
||||
// RUN: FileCheck %s
|
||||
// RUN: %clang_cc1 -triple=powerpc64-unknown-aix -emit-llvm %s -o - | \
|
||||
// RUN: FileCheck %s
|
||||
// RUN: %clang_cc1 -triple=powerpc64le-unknown-unknown -emit-llvm %s \
|
||||
// RUN: -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple=powerpc64-unknown-unknown -emit-llvm %s \
|
||||
// RUN: -o - | FileCheck %s
|
||||
|
||||
int test_lwarx(volatile int* a) {
|
||||
// CHECK: @test_lwarx
|
||||
// CHECK: %1 = bitcast i32* %0 to i8*
|
||||
// CHECK: %2 = call i32 @llvm.ppc.lwarx(i8* %1)
|
||||
return __lwarx(a);
|
||||
}
|
||||
int test_stwcx(volatile int* a, int val) {
|
||||
// CHECK: @test_stwcx
|
||||
// CHECK: %1 = bitcast i32* %0 to i8*
|
||||
// CHECK: %2 = load i32, i32* %val.addr, align 4
|
||||
// CHECK: %3 = call i32 @llvm.ppc.stwcx(i8* %1, i32 %2)
|
||||
return __stwcx(a, val);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
// REQUIRES: powerpc-registered-target
|
||||
// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -fsyntax-only \
|
||||
// RUN: -Wall -Werror -verify %s
|
||||
// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -fsyntax-only \
|
||||
// RUN: -Wall -Werror -verify %s
|
||||
// RUN: %clang_cc1 -triple powerpc64-unknown-aix -fsyntax-only \
|
||||
// RUN: -Wall -Werror -verify %s
|
||||
// RUN: %clang_cc1 -triple powerpc-unknown-aix -fsyntax-only \
|
||||
// RUN: -Wall -Werror -verify %s
|
||||
|
||||
long long lla, llb;
|
||||
int ia, ib;
|
||||
|
||||
void test_trap(void) {
|
||||
__tdw(lla, llb, 50); //expected-error {{argument value 50 is outside the valid range [0, 31]}}
|
||||
__tw(ia, ib, 50); //expected-error {{argument value 50 is outside the valid range [0, 31]}}
|
||||
}
|
|
@ -1523,5 +1523,15 @@ let TargetPrefix = "ppc" in {
|
|||
Intrinsic<[],[],[]>;
|
||||
def int_ppc_iospace_eieio : GCCBuiltin<"__builtin_ppc_iospace_eieio">,
|
||||
Intrinsic<[],[],[]>;
|
||||
def int_ppc_stdcx : GCCBuiltin<"__builtin_ppc_stdcx">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i64_ty],
|
||||
[IntrWriteMem]>;
|
||||
def int_ppc_stwcx : GCCBuiltin<"__builtin_ppc_stwcx">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty],
|
||||
[IntrWriteMem]>;
|
||||
def int_ppc_lwarx : GCCBuiltin<"__builtin_ppc_lwarx">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>;
|
||||
def int_ppc_ldarx : GCCBuiltin<"__builtin_ppc_ldarx">,
|
||||
Intrinsic<[llvm_i64_ty], [llvm_ptr_ty], [IntrNoMem]>;
|
||||
}
|
||||
|
||||
|
|
|
@ -1720,3 +1720,8 @@ def SLBIEG : XForm_26<31, 466, (outs), (ins gprc:$RS, gprc:$RB),
|
|||
def SLBSYNC : XForm_0<31, 338, (outs), (ins), "slbsync", IIC_SprSLBSYNC, []>;
|
||||
|
||||
} // IsISA3_0
|
||||
|
||||
def : Pat<(int_ppc_stdcx ForceXForm:$dst, g8rc:$A),
|
||||
(STDCX g8rc:$A, ForceXForm:$dst)>;
|
||||
def : Pat<(int_ppc_ldarx ForceXForm:$dst),
|
||||
(LDARX ForceXForm:$dst)>;
|
||||
|
|
|
@ -5411,3 +5411,8 @@ def DWBytes3210 {
|
|||
// swap the high word and low word.
|
||||
def : Pat<(i64 (bitreverse i64:$A)),
|
||||
(OR8 (RLDICR DWBytes7654.DWord, 32, 31), DWBytes3210.DWord)>;
|
||||
|
||||
def : Pat<(int_ppc_lwarx ForceXForm:$dst),
|
||||
(LWARX ForceXForm:$dst)>;
|
||||
def : Pat<(int_ppc_stwcx ForceXForm:$dst, gprc:$A),
|
||||
(STWCX gprc:$A, ForceXForm:$dst)>;
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
; 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 --check-prefix=CHECK
|
||||
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
|
||||
; RUN: -mcpu=pwr8 < %s | FileCheck %s --check-prefix=CHECK
|
||||
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
|
||||
; RUN: -mcpu=pwr8 < %s | FileCheck %s --check-prefix=CHECK
|
||||
|
||||
declare i64 @llvm.ppc.ldarx(i8*)
|
||||
define dso_local i64 @test_ldarx(i64* readnone %a) {
|
||||
; CHECK-LABEL: test_ldarx:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK-NEXT: ldarx 3, 0, 3
|
||||
; CHECK-NEXT: blr
|
||||
entry:
|
||||
%0 = bitcast i64* %a to i8*
|
||||
%1 = tail call i64 @llvm.ppc.ldarx(i8* %0)
|
||||
ret i64 %1
|
||||
}
|
||||
|
||||
declare i32 @llvm.ppc.stdcx(i8*, i64)
|
||||
define dso_local i64 @test(i64* %a, i64 %b) {
|
||||
; CHECK-LABEL: test:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK-NEXT: stdcx. 4, 0, 3
|
||||
; CHECK-NEXT: mfocrf 3, 128
|
||||
; CHECK-NEXT: srwi 3, 3, 28
|
||||
; CHECK-NEXT: extsw 3, 3
|
||||
; CHECK-NEXT: blr
|
||||
entry:
|
||||
%0 = bitcast i64* %a to i8*
|
||||
%1 = tail call i32 @llvm.ppc.stdcx(i8* %0, i64 %b)
|
||||
%conv = sext i32 %1 to i64
|
||||
ret i64 %conv
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
; 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 --check-prefix=CHECK-64
|
||||
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
|
||||
; RUN: -mcpu=pwr8 < %s | FileCheck %s --check-prefix=CHECK-64
|
||||
; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
|
||||
; RUN: -mcpu=pwr8 < %s | FileCheck %s --check-prefix=CHECK-32
|
||||
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
|
||||
; RUN: -mcpu=pwr8 < %s | FileCheck %s --check-prefix=CHECK-64
|
||||
|
||||
declare i32 @llvm.ppc.lwarx(i8*)
|
||||
define dso_local signext i32 @test_lwarx(i32* readnone %a) {
|
||||
; CHECK-64-LABEL: test_lwarx:
|
||||
; CHECK-64: # %bb.0: # %entry
|
||||
; CHECK-64-NEXT: lwarx 3, 0, 3
|
||||
; CHECK-64-NEXT: extsw 3, 3
|
||||
; CHECK-64-NEXT: blr
|
||||
;
|
||||
; CHECK-32-LABEL: test_lwarx:
|
||||
; CHECK-32: # %bb.0: # %entry
|
||||
; CHECK-32-NEXT: lwarx 3, 0, 3
|
||||
; CHECK-32-NEXT: blr
|
||||
entry:
|
||||
%0 = bitcast i32* %a to i8*
|
||||
%1 = tail call i32 @llvm.ppc.lwarx(i8* %0)
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
declare i32 @llvm.ppc.stwcx(i8*, i32)
|
||||
define dso_local signext i32 @test_stwcx(i32* %a, i32 signext %b) {
|
||||
; CHECK-64-LABEL: test_stwcx:
|
||||
; CHECK-64: # %bb.0: # %entry
|
||||
; CHECK-64-NEXT: stwcx. 4, 0, 3
|
||||
; CHECK-64-NEXT: mfocrf 3, 128
|
||||
; CHECK-64-NEXT: srwi 3, 3, 28
|
||||
; CHECK-64-NEXT: extsw 3, 3
|
||||
; CHECK-64-NEXT: blr
|
||||
;
|
||||
; CHECK-32-LABEL: test_stwcx:
|
||||
; CHECK-32: # %bb.0: # %entry
|
||||
; CHECK-32-NEXT: stwcx. 4, 0, 3
|
||||
; CHECK-32-NEXT: mfocrf 3, 128
|
||||
; CHECK-32-NEXT: srwi 3, 3, 28
|
||||
; CHECK-32-NEXT: blr
|
||||
entry:
|
||||
%0 = bitcast i32* %a to i8*
|
||||
%1 = tail call i32 @llvm.ppc.stwcx(i8* %0, i32 %b)
|
||||
ret i32 %1
|
||||
}
|
Loading…
Reference in New Issue