forked from OSchip/llvm-project
215 lines
7.0 KiB
C
215 lines
7.0 KiB
C
// REQUIRES: powerpc-registered-target
|
|
// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu \
|
|
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefixes=64BIT --check-prefix=BOTH
|
|
// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu \
|
|
// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s --check-prefixes=64BIT --check-prefix=BOTH
|
|
// RUN: %clang_cc1 -triple powerpc-unknown-aix \
|
|
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefixes=32BIT --check-prefix=BOTH
|
|
// RUN: %clang_cc1 -triple powerpc64-unknown-aix \
|
|
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefixes=64BIT --check-prefix=BOTH
|
|
|
|
// Will not be adding include files to avoid any dependencies on the system.
|
|
// Required for size_t. Usually found in stddef.h.
|
|
typedef __SIZE_TYPE__ size_t;
|
|
|
|
// 64BIT-LABEL: @testlabs(
|
|
// 64BIT-NEXT: entry:
|
|
// 64BIT-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8
|
|
// 64BIT-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8
|
|
// 64BIT-NEXT: [[TMP0:%.*]] = load i64, i64* [[A_ADDR]], align 8
|
|
// 64BIT-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[TMP0]]
|
|
// 64BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i64 [[TMP0]], 0
|
|
// 64BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i64 [[NEG]], i64 [[TMP0]]
|
|
// 64BIT-NEXT: ret i64 [[ABS]]
|
|
//
|
|
// 32BIT-LABEL: @testlabs(
|
|
// 32BIT-NEXT: entry:
|
|
// 32BIT-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
// 32BIT-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4
|
|
// 32BIT-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4
|
|
// 32BIT-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[TMP0]]
|
|
// 32BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i32 [[TMP0]], 0
|
|
// 32BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[TMP0]]
|
|
// 32BIT-NEXT: ret i32 [[ABS]]
|
|
//
|
|
signed long testlabs(signed long a) {
|
|
return __labs(a);
|
|
}
|
|
|
|
// 64BIT-LABEL: @testllabs(
|
|
// 64BIT-NEXT: entry:
|
|
// 64BIT-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8
|
|
// 64BIT-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8
|
|
// 64BIT-NEXT: [[TMP0:%.*]] = load i64, i64* [[A_ADDR]], align 8
|
|
// 64BIT-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[TMP0]]
|
|
// 64BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i64 [[TMP0]], 0
|
|
// 64BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i64 [[NEG]], i64 [[TMP0]]
|
|
// 64BIT-NEXT: ret i64 [[ABS]]
|
|
//
|
|
// 32BIT-LABEL: @testllabs(
|
|
// 32BIT-NEXT: entry:
|
|
// 32BIT-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8
|
|
// 32BIT-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8
|
|
// 32BIT-NEXT: [[TMP0:%.*]] = load i64, i64* [[A_ADDR]], align 8
|
|
// 32BIT-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[TMP0]]
|
|
// 32BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i64 [[TMP0]], 0
|
|
// 32BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i64 [[NEG]], i64 [[TMP0]]
|
|
// 32BIT-NEXT: ret i64 [[ABS]]
|
|
//
|
|
signed long long testllabs(signed long long a) {
|
|
return __llabs(a);
|
|
}
|
|
|
|
// 64BIT-LABEL: @testalloca(
|
|
// 64BIT: [[TMP1:%.*]] = alloca i8, i64
|
|
// 64BIT-NEXT: ret i8* [[TMP1]]
|
|
//
|
|
// 32BIT-LABEL: @testalloca(
|
|
// 32BIT: [[TMP1:%.*]] = alloca i8, i32
|
|
// 32BIT-NEXT: ret i8* [[TMP1]]
|
|
//
|
|
void *testalloca(size_t size) {
|
|
return __alloca(size);
|
|
}
|
|
|
|
// Note that bpermd is 64 bit only.
|
|
#ifdef __PPC64__
|
|
// 64BIT-LABEL: @testbpermd(
|
|
// 64BIT: [[TMP:%.*]] = call i64 @llvm.ppc.bpermd(i64 {{%.*}}, i64 {{%.*}})
|
|
// 64BIT-NEXT: ret i64 [[TMP]]
|
|
//
|
|
long long testbpermd(long long bit_selector, long long source) {
|
|
return __bpermd(bit_selector, source);
|
|
}
|
|
#endif
|
|
|
|
#ifdef __PPC64__
|
|
// 64BIT-LABEL: @testdivde(
|
|
// 64BIT: [[TMP2:%.*]] = call i64 @llvm.ppc.divde
|
|
// 64BIT-NEXT: ret i64 [[TMP2]]
|
|
long long testdivde(long long dividend, long long divisor) {
|
|
return __divde(dividend, divisor);
|
|
}
|
|
|
|
// 64BIT-LABEL: @testdivdeu(
|
|
// 64BIT: [[TMP2:%.*]] = call i64 @llvm.ppc.divdeu
|
|
// 64BIT-NEXT: ret i64 [[TMP2]]
|
|
unsigned long long testdivdeu(unsigned long long dividend, unsigned long long divisor) {
|
|
return __divdeu(dividend, divisor);
|
|
}
|
|
#endif
|
|
|
|
// 64BIT-LABEL: @testdivwe(
|
|
// 64BIT: [[TMP2:%.*]] = call i32 @llvm.ppc.divwe
|
|
// 64BIT-NEXT: ret i32 [[TMP2]]
|
|
//
|
|
// 32BIT-LABEL: @testdivwe(
|
|
// 32BIT: [[TMP2:%.*]] = call i32 @llvm.ppc.divwe
|
|
// 32BIT-NEXT: ret i32 [[TMP2]]
|
|
int testdivwe(int dividend, int divisor) {
|
|
return __divwe(dividend, divisor);
|
|
}
|
|
|
|
// 64BIT-LABEL: @testdivweu(
|
|
// 64BIT: [[TMP2:%.*]] = call i32 @llvm.ppc.divweu
|
|
// 64BIT-NEXT: ret i32 [[TMP2]]
|
|
//
|
|
// 32BIT-LABEL: @testdivweu(
|
|
// 32BIT: [[TMP2:%.*]] = call i32 @llvm.ppc.divweu
|
|
// 32BIT-NEXT: ret i32 [[TMP2]]
|
|
unsigned int testdivweu(unsigned int dividend, unsigned int divisor) {
|
|
return __divweu(dividend, divisor);
|
|
}
|
|
|
|
// BOTH-LABEL: @testfmadd(
|
|
// BOTH: [[TMP3:%.*]] = call double @llvm.fma.f64
|
|
// BOTH-NEXT: ret double [[TMP3]]
|
|
//
|
|
double testfmadd(double a, double b, double c) {
|
|
return __fmadd(a, b, c);
|
|
}
|
|
|
|
// BOTH-LABEL: @testfmadds(
|
|
// BOTH: [[TMP3:%.*]] = call float @llvm.fma.f32(
|
|
// BOTH-NEXT: ret float [[TMP3]]
|
|
//
|
|
float testfmadds(float a, float b, float c) {
|
|
return __fmadds(a, b, c);
|
|
}
|
|
|
|
// Required for bzero and bcopy. Usually in strings.h.
|
|
extern void bcopy(const void *__src, void *__dest, size_t __n);
|
|
extern void bzero(void *__s, size_t __n);
|
|
|
|
// 64BIT-LABEL: @testalignx(
|
|
// 64BIT: call void @llvm.assume(i1 true) [ "align"(i8* {{%.*}}, i64 16) ]
|
|
// 64BIT-NEXT: ret void
|
|
//
|
|
// 32BIT-LABEL: @testalignx(
|
|
// 32BIT: call void @llvm.assume(i1 true) [ "align"(i8* {{%.*}}, i32 16) ]
|
|
// 32BIT-NEXT: ret void
|
|
//
|
|
void testalignx(const void *pointer) {
|
|
__alignx(16, pointer);
|
|
}
|
|
|
|
// 64BIT-LABEL: @testbcopy(
|
|
// 64BIT: call void @bcopy(i8* {{%.*}}, i8* {{%.*}}, i64 {{%.*}})
|
|
// 64BIT-NEXT: ret void
|
|
//
|
|
// 32BIT-LABEL: @testbcopy(
|
|
// 32BIT: call void @bcopy(i8* {{%.*}}, i8* {{%.*}}, i32 {{%.*}})
|
|
// 32BIT-NEXT: ret void
|
|
//
|
|
void testbcopy(const void *src, void *dest, size_t n) {
|
|
__bcopy(src, dest, n);
|
|
}
|
|
|
|
// 64BIT-LABEL: @testbzero(
|
|
// 64BIT: call void @llvm.memset.p0i8.i64(i8* align 1 {{%.*}}, i8 0, i64 {{%.*}}, i1 false)
|
|
// 64BIT-NEXT: ret void
|
|
//
|
|
// 32BIT-LABEL: @testbzero(
|
|
// 32BIT: call void @llvm.memset.p0i8.i32(i8* align 1 {{%.*}}, i8 0, i32 {{%.*}}, i1 false)
|
|
// 32BIT-NEXT: ret void
|
|
//
|
|
void testbzero(void *s, size_t n) {
|
|
bzero(s, n);
|
|
}
|
|
|
|
// 64BIT-LABEL: @testdcbf(
|
|
// 64BIT: call void @llvm.ppc.dcbf(i8* {{%.*}})
|
|
// 64BIT-NEXT: ret void
|
|
//
|
|
// 32BIT-LABEL: @testdcbf(
|
|
// 32BIT: call void @llvm.ppc.dcbf(i8* {{%.*}})
|
|
// 32BIT-NEXT: ret void
|
|
//
|
|
void testdcbf(const void *addr) {
|
|
__dcbf(addr);
|
|
}
|
|
|
|
// BOTH-LABEL: @testreadflm(
|
|
// BOTH: [[TMP0:%.*]] = call double @llvm.ppc.readflm()
|
|
// BOTH-NEXT: ret double [[TMP0]]
|
|
//
|
|
double testreadflm(void) {
|
|
return __readflm();
|
|
}
|
|
|
|
// BOTH-LABEL: @testsetflm(
|
|
// BOTH: [[TMP1:%.*]] = call double @llvm.ppc.setflm(double {{%.*}})
|
|
// BOTH-NEXT: ret double [[TMP1]]
|
|
//
|
|
double testsetflm(double a) {
|
|
return __setflm(a);
|
|
}
|
|
|
|
// BOTH-LABEL: @testsetrnd(
|
|
// BOTH: [[TMP1:%.*]] = call double @llvm.ppc.setrnd(i32 {{%.*}})
|
|
// BOTH-NEXT: ret double [[TMP1]]
|
|
//
|
|
double testsetrnd(int mode) {
|
|
return __setrnd(mode);
|
|
}
|