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