Index: lib/Headers/arm_acle.h =================================================================== --- lib/Headers/arm_acle.h +++ lib/Headers/arm_acle.h @@ -96,6 +96,23 @@ /* 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) { + return (x >> y) | (x << 32 - y); +} + +static __inline__ unsigned long __attribute__((always_inline, nodebug)) + __rorl(unsigned long x, uint32_t y) { + return (x >> y) | (x << (sizeof(unsigned long) * 8 - y)); +} + +static __inline__ uint64_t __attribute__((always_inline, nodebug)) + __rorll(uint64_t x, uint32_t y) { + return (x >> y) | (x << 64 - y); +} + +/* CLZ */ static __inline__ uint32_t __attribute__((always_inline, nodebug)) __clz(uint32_t t) { return __builtin_clz(t); @@ -111,6 +128,23 @@ return __builtin_clzll(t); } +/* CLS */ +static __inline__ uint32_t __attribute__((always_inline, nodebug)) + __cls(uint32_t t) { + return __clz(((t ^ ((int32_t)t >> 31)) << 1) + 1); +} + +static __inline__ unsigned long __attribute__((always_inline, nodebug)) + __clsl(unsigned long t) { + return __clzl(((t ^ ((long)t >> (sizeof(unsigned long) * 8 - 1))) << 1) + 1); +} + +static __inline__ uint64_t __attribute__((always_inline, nodebug)) + __clsll(uint64_t t) { + return __clzll(((t ^ ((int64_t)t >> 63)) << 1) + 1); +} + +/* REV */ static __inline__ uint32_t __attribute__((always_inline, nodebug)) __rev(uint32_t t) { return __builtin_bswap32(t); @@ -130,6 +164,53 @@ 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 * Index: test/CodeGen/arm_acle.c =================================================================== --- test/CodeGen/arm_acle.c +++ test/CodeGen/arm_acle.c @@ -101,23 +101,31 @@ /* 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 @@ -139,6 +147,107 @@ return __clzll(t); } +// ARM-LABEL: test_cls +// ARM: ashr {{[i64,i32]}} +// ARM-NEXT: xor {{[i64,i32]}} +// ARM-NEXT: shl {{[i64,i32]}} +// ARM-NEXT: or {{[i64,i32]}} +uint32_t test_cls(uint32_t t) { + return __cls(t); +} + +// ARM-LABEL: test_clsl +// ARM: ashr {{[i64,i32]}} +// ARM-NEXT: xor {{[i64,i32]}} +// ARM-NEXT: shl {{[i64,i32]}} +// ARM-NEXT: or {{[i64,i32]}} +long test_clsl(long t) { + return __clsl(t); +} + +// ARM-LABEL: test_clsll +// ARM: ashr {{[i64,i32]}} +// ARM-NEXT: xor {{[i64,i32]}} +// ARM-NEXT: shl {{[i64,i32]}} +// ARM-NEXT: or {{[i64,i32]}} +uint64_t test_clsll(uint64_t t) { + return __clsll(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