r216658 - arm_acle: Implement data processing intrinsics

Pasi Parviainen pasi.parviainen at iki.fi
Thu Aug 28 08:14:19 PDT 2014


On 28.8.2014 12:44, Yi Kong wrote:
> 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));
> +}
> +

These ror implementations are flawed. __ror(x, 0) and __rorll(x, 0) 
return always zero, I would expect the result to be x. Also if the 
rotate count is multiple of 32 (for __ror) or 64 (for __rorll), left 
shifts will result to undefined behavior.

Pasi

> +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
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>




More information about the cfe-commits mailing list