diff options
author | Bill Schmidt <wschmidt@linux.vnet.ibm.com> | 2014-06-06 14:45:06 +0000 |
---|---|---|
committer | Bill Schmidt <wschmidt@linux.vnet.ibm.com> | 2014-06-06 14:45:06 +0000 |
commit | 7c0114f6e373497855844a063e9c2d9c4966da58 (patch) | |
tree | 90c90552593c65e7ad788480466c0cd34a348b78 | |
parent | 4aedff8995d3e0788fd2e84079e5b19fcdf899c5 (diff) | |
download | bcm5719-llvm-7c0114f6e373497855844a063e9c2d9c4966da58.tar.gz bcm5719-llvm-7c0114f6e373497855844a063e9c2d9c4966da58.zip |
[PPC64LE] Implement little-endian semantics for vec_mul[eo]
The PowerPC vector-multiply-even and vector-multiply-odd instructions
are defined architecturally with a big-endian bias, in that the vector
element numbering is assumed to be "left to right" regardless of
whether the processor is in big-endian or little-endian mode. This
definition is unnatural for little-endian code generation.
To facilitate ease of porting, the vec_mule and vec_mulo interfacs are
designed to use natural element ordering, so that elements are
numbered according to little-endian design principles when code is
generated for a little-endian target. The desired semantics can be
achieved by using the opposite instruction for little-endian mode.
That is, when a call to vec_mule appears in the code, a
vector-multiply-odd is generated, and when a call to vec_mulo appears
in the code, a vector-multiply-even is generated.
The correctness of this code is tested by the new mult-even-odd.c test
added in a previous patch. I plan to later make the existing ppc32
Altivec compile-time tests work for ppc64 and ppc64le as well.
llvm-svn: 210337
-rw-r--r-- | clang/lib/Headers/altivec.h | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h index 252d3fbba6d..9995415c010 100644 --- a/clang/lib/Headers/altivec.h +++ b/clang/lib/Headers/altivec.h @@ -3488,30 +3488,49 @@ vec_mtvscr(vector float __a) __builtin_altivec_mtvscr((vector int)__a); } +/* The vmulos* and vmules* instructions have a big endian bias, so + we must reverse the meaning of "even" and "odd" for little endian. */ + /* vec_mule */ static vector short __ATTRS_o_ai vec_mule(vector signed char __a, vector signed char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulosb(__a, __b); +#else return __builtin_altivec_vmulesb(__a, __b); +#endif } static vector unsigned short __ATTRS_o_ai vec_mule(vector unsigned char __a, vector unsigned char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuloub(__a, __b); +#else return __builtin_altivec_vmuleub(__a, __b); +#endif } static vector int __ATTRS_o_ai vec_mule(vector short __a, vector short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulosh(__a, __b); +#else return __builtin_altivec_vmulesh(__a, __b); +#endif } static vector unsigned int __ATTRS_o_ai vec_mule(vector unsigned short __a, vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulouh(__a, __b); +#else return __builtin_altivec_vmuleuh(__a, __b); +#endif } /* vec_vmulesb */ @@ -3519,7 +3538,11 @@ vec_mule(vector unsigned short __a, vector unsigned short __b) static vector short __attribute__((__always_inline__)) vec_vmulesb(vector signed char __a, vector signed char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulosb(__a, __b); +#else return __builtin_altivec_vmulesb(__a, __b); +#endif } /* vec_vmuleub */ @@ -3527,7 +3550,11 @@ vec_vmulesb(vector signed char __a, vector signed char __b) static vector unsigned short __attribute__((__always_inline__)) vec_vmuleub(vector unsigned char __a, vector unsigned char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuloub(__a, __b); +#else return __builtin_altivec_vmuleub(__a, __b); +#endif } /* vec_vmulesh */ @@ -3535,7 +3562,11 @@ vec_vmuleub(vector unsigned char __a, vector unsigned char __b) static vector int __attribute__((__always_inline__)) vec_vmulesh(vector short __a, vector short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulosh(__a, __b); +#else return __builtin_altivec_vmulesh(__a, __b); +#endif } /* vec_vmuleuh */ @@ -3543,7 +3574,11 @@ vec_vmulesh(vector short __a, vector short __b) static vector unsigned int __attribute__((__always_inline__)) vec_vmuleuh(vector unsigned short __a, vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulouh(__a, __b); +#else return __builtin_altivec_vmuleuh(__a, __b); +#endif } /* vec_mulo */ @@ -3551,25 +3586,41 @@ vec_vmuleuh(vector unsigned short __a, vector unsigned short __b) static vector short __ATTRS_o_ai vec_mulo(vector signed char __a, vector signed char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulesb(__a, __b); +#else return __builtin_altivec_vmulosb(__a, __b); +#endif } static vector unsigned short __ATTRS_o_ai vec_mulo(vector unsigned char __a, vector unsigned char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuleub(__a, __b); +#else return __builtin_altivec_vmuloub(__a, __b); +#endif } static vector int __ATTRS_o_ai vec_mulo(vector short __a, vector short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulesh(__a, __b); +#else return __builtin_altivec_vmulosh(__a, __b); +#endif } static vector unsigned int __ATTRS_o_ai vec_mulo(vector unsigned short __a, vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuleuh(__a, __b); +#else return __builtin_altivec_vmulouh(__a, __b); +#endif } /* vec_vmulosb */ @@ -3577,7 +3628,11 @@ vec_mulo(vector unsigned short __a, vector unsigned short __b) static vector short __attribute__((__always_inline__)) vec_vmulosb(vector signed char __a, vector signed char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulesb(__a, __b); +#else return __builtin_altivec_vmulosb(__a, __b); +#endif } /* vec_vmuloub */ @@ -3585,7 +3640,11 @@ vec_vmulosb(vector signed char __a, vector signed char __b) static vector unsigned short __attribute__((__always_inline__)) vec_vmuloub(vector unsigned char __a, vector unsigned char __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuleub(__a, __b); +#else return __builtin_altivec_vmuloub(__a, __b); +#endif } /* vec_vmulosh */ @@ -3593,7 +3652,11 @@ vec_vmuloub(vector unsigned char __a, vector unsigned char __b) static vector int __attribute__((__always_inline__)) vec_vmulosh(vector short __a, vector short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmulesh(__a, __b); +#else return __builtin_altivec_vmulosh(__a, __b); +#endif } /* vec_vmulouh */ @@ -3601,7 +3664,11 @@ vec_vmulosh(vector short __a, vector short __b) static vector unsigned int __attribute__((__always_inline__)) vec_vmulouh(vector unsigned short __a, vector unsigned short __b) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vmuleuh(__a, __b); +#else return __builtin_altivec_vmulouh(__a, __b); +#endif } /* vec_nmsub */ |