r216658 - arm_acle: Implement data processing intrinsics
Yi Kong
Yi.Kong at arm.com
Thu Aug 28 02:44:07 PDT 2014
Author: kongyi
Date: Thu Aug 28 04:44:07 2014
New Revision: 216658
URL: http://llvm.org/viewvc/llvm-project?rev=216658&view=rev
Log:
arm_acle: Implement data processing intrinsics
Summary:
ACLE 2.0 section 9.2 defines the following "miscellaneous data processing intrinsics": `__clz`, `__cls`, `__ror`, `__rev`, `__rev16`, `__revsh` and `__rbit`.
`__clz` has already been implemented in the arm_acle.h header file. The rest are not supported yet. This patch completes ACLE data processing intrinsics.
Reviewers: t.p.northover, rengolin
Reviewed By: rengolin
Subscribers: aemerson, mroth, llvm-commits
Differential Revision: http://reviews.llvm.org/D4983
Modified:
cfe/trunk/lib/Headers/arm_acle.h
cfe/trunk/test/CodeGen/arm_acle.c
Modified: cfe/trunk/lib/Headers/arm_acle.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/arm_acle.h?rev=216658&r1=216657&r2=216658&view=diff
==============================================================================
--- cfe/trunk/lib/Headers/arm_acle.h (original)
+++ cfe/trunk/lib/Headers/arm_acle.h Thu Aug 28 04:44:07 2014
@@ -108,6 +108,32 @@ static __inline__ void __attribute__((al
/* 9 DATA-PROCESSING INTRINSICS */
/* 9.2 Miscellaneous data-processing intrinsics */
+/* ROR */
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+ __ror(uint32_t x, uint32_t y) {
+ if (y == 0) return y;
+ if (y >= 32) y %= 32;
+ return (x >> y) | (x << (32 - y));
+}
+
+static __inline__ uint64_t __attribute__((always_inline, nodebug))
+ __rorll(uint64_t x, uint32_t y) {
+ if (y == 0) return y;
+ if (y >= 64) y %= 64;
+ return (x >> y) | (x << (64 - y));
+}
+
+static __inline__ unsigned long __attribute__((always_inline, nodebug))
+ __rorl(unsigned long x, uint32_t y) {
+#if __SIZEOF_LONG__ == 4
+ return __ror(x, y);
+#else
+ return __rorll(x, y);
+#endif
+}
+
+
+/* CLZ */
static __inline__ uint32_t __attribute__((always_inline, nodebug))
__clz(uint32_t t) {
return __builtin_clz(t);
@@ -123,6 +149,7 @@ static __inline__ uint64_t __attribute__
return __builtin_clzll(t);
}
+/* REV */
static __inline__ uint32_t __attribute__((always_inline, nodebug))
__rev(uint32_t t) {
return __builtin_bswap32(t);
@@ -142,6 +169,53 @@ static __inline__ uint64_t __attribute__
return __builtin_bswap64(t);
}
+/* REV16 */
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+ __rev16(uint32_t t) {
+ return __ror(__rev(t), 16);
+}
+
+static __inline__ unsigned long __attribute__((always_inline, nodebug))
+ __rev16l(unsigned long t) {
+ return __rorl(__revl(t), sizeof(long) / 2);
+}
+
+static __inline__ uint64_t __attribute__((always_inline, nodebug))
+ __rev16ll(uint64_t t) {
+ return __rorll(__revll(t), 32);
+}
+
+/* REVSH */
+static __inline__ int16_t __attribute__((always_inline, nodebug))
+ __revsh(int16_t t) {
+ return __builtin_bswap16(t);
+}
+
+/* RBIT */
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+ __rbit(uint32_t t) {
+ return __builtin_arm_rbit(t);
+}
+
+static __inline__ uint64_t __attribute__((always_inline, nodebug))
+ __rbitll(uint64_t t) {
+#if __ARM_32BIT_STATE
+ return (((uint64_t) __builtin_arm_rbit(t)) << 32) |
+ __builtin_arm_rbit(t >> 32);
+#else
+ return __builtin_arm_rbit64(t);
+#endif
+}
+
+static __inline__ unsigned long __attribute__((always_inline, nodebug))
+ __rbitl(unsigned long t) {
+#if __SIZEOF_LONG__ == 4
+ return __rbit(t);
+#else
+ return __rbitll(t);
+#endif
+}
+
/*
* 9.4 Saturating intrinsics
*
Modified: cfe/trunk/test/CodeGen/arm_acle.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm_acle.c?rev=216658&r1=216657&r2=216658&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/arm_acle.c (original)
+++ cfe/trunk/test/CodeGen/arm_acle.c Thu Aug 28 04:44:07 2014
@@ -119,23 +119,31 @@ void test_nop(void) {
/* 9 DATA-PROCESSING INTRINSICS */
/* 9.2 Miscellaneous data-processing intrinsics */
-// ARM-LABEL: test_rev
-// ARM: call i32 @llvm.bswap.i32(i32 %t)
-uint32_t test_rev(uint32_t t) {
- return __rev(t);
-}
-
-// ARM-LABEL: test_revl
-// AArch32: call i32 @llvm.bswap.i32(i32 %t)
-// AArch64: call i64 @llvm.bswap.i64(i64 %t)
-long test_revl(long t) {
- return __revl(t);
-}
-
-// ARM-LABEL: test_revll
-// ARM: call i64 @llvm.bswap.i64(i64 %t)
-uint64_t test_revll(uint64_t t) {
- return __revll(t);
+// ARM-LABEL: test_ror
+// ARM: lshr
+// ARM: sub
+// ARM: shl
+// ARM: or
+uint32_t test_ror(uint32_t x, uint32_t y) {
+ return __ror(x, y);
+}
+
+// ARM-LABEL: test_rorl
+// ARM: lshr
+// ARM: sub
+// ARM: shl
+// ARM: or
+unsigned long test_rorl(unsigned long x, uint32_t y) {
+ return __rorl(x, y);
+}
+
+// ARM-LABEL: test_rorll
+// ARM: lshr
+// ARM: sub
+// ARM: shl
+// ARM: or
+uint64_t test_rorll(uint64_t x, uint32_t y) {
+ return __rorll(x, y);
}
// ARM-LABEL: test_clz
@@ -157,6 +165,80 @@ uint64_t test_clzll(uint64_t t) {
return __clzll(t);
}
+// ARM-LABEL: test_rev
+// ARM: call i32 @llvm.bswap.i32(i32 %t)
+uint32_t test_rev(uint32_t t) {
+ return __rev(t);
+}
+
+// ARM-LABEL: test_revl
+// AArch32: call i32 @llvm.bswap.i32(i32 %t)
+// AArch64: call i64 @llvm.bswap.i64(i64 %t)
+long test_revl(long t) {
+ return __revl(t);
+}
+
+// ARM-LABEL: test_revll
+// ARM: call i64 @llvm.bswap.i64(i64 %t)
+uint64_t test_revll(uint64_t t) {
+ return __revll(t);
+}
+
+// ARM-LABEL: test_rev16
+// ARM: llvm.bswap
+// ARM: lshr
+// ARM: shl
+// ARM: or
+uint32_t test_rev16(uint32_t t) {
+ return __rev16(t);
+}
+
+// ARM-LABEL: test_rev16l
+// ARM: llvm.bswap
+// ARM: lshr
+// ARM: shl
+// ARM: or
+long test_rev16l(long t) {
+ return __rev16l(t);
+}
+
+// ARM-LABEL: test_rev16ll
+// ARM: llvm.bswap
+// ARM: lshr
+// ARM: shl
+// ARM: or
+uint64_t test_rev16ll(uint64_t t) {
+ return __rev16ll(t);
+}
+
+// ARM-LABEL: test_revsh
+// ARM: call i16 @llvm.bswap.i16(i16 %t)
+int16_t test_revsh(int16_t t) {
+ return __revsh(t);
+}
+
+// ARM-LABEL: test_rbit
+// AArch32: call i32 @llvm.arm.rbit
+// AArch64: call i32 @llvm.aarch64.rbit.i32
+uint32_t test_rbit(uint32_t t) {
+ return __rbit(t);
+}
+
+// ARM-LABEL: test_rbitl
+// AArch32: call i32 @llvm.arm.rbit
+// AArch64: call i64 @llvm.aarch64.rbit.i64
+long test_rbitl(long t) {
+ return __rbitl(t);
+}
+
+// ARM-LABEL: test_rbitll
+// AArch32: call i32 @llvm.arm.rbit
+// AArch32: call i32 @llvm.arm.rbit
+// AArch64: call i64 @llvm.aarch64.rbit.i64
+uint64_t test_rbitll(uint64_t t) {
+ return __rbitll(t);
+}
+
/* 9.4 Saturating intrinsics */
#ifdef __ARM_32BIT_STATE
More information about the cfe-commits
mailing list