Fix tcg/i386 bug vs sari_vec.

Fix tcg-runtime-gvec.c vs i386 without avx.
 -----BEGIN PGP SIGNATURE-----
 
 iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAl5xHcYdHHJpY2hhcmQu
 aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/jcQf/aF2+3UeRCfk/Iu1s
 ClM6Gpo7z2sDSZwt8oDgxlhmvoA6j2V5Oa33rB9A5bcglV+WE1BEx6vBrMcP2RQx
 2555p8DxkvY4ePFTX+E6IFQxLT8XcS+ttByvakLsfElKK6xflOjJKQOzml/MOL0Y
 GfMsjhreUKq/DPkZ9wyinlQp+Oq4yFNwuUWxAi19S2parB/xpJenVaIeMQGXyR/n
 kPvFG/42nr8JkMiZReeVUcJ9bcdLx1tSKt4fLUsU8MLdUKoq2qV6cm2r4UEyVIAi
 NBQc5MpQcO7Bb1yw88bcprjAXfr/JRnlpzWjgAUTYWdhQRDBspUK0qV2fHT9X7cZ
 ghyf3Q==
 =vaWE
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20200317' into staging

Fix tcg/i386 bug vs sari_vec.
Fix tcg-runtime-gvec.c vs i386 without avx.

# gpg: Signature made Tue 17 Mar 2020 18:58:14 GMT
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* remotes/rth/tags/pull-tcg-20200317:
  tcg: Remove tcg-runtime-gvec.c DO_CMP0
  tcg: Tidy tcg-runtime-gvec.c DUP*
  tcg: Tidy tcg-runtime-gvec.c types
  tcg: Remove CONFIG_VECTOR16
  tcg/i386: Bound shift count expanding sari_vec

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-03-18 22:15:59 +00:00
commit 0a4833b3b4
3 changed files with 122 additions and 241 deletions

View File

@ -24,48 +24,6 @@
#include "tcg/tcg-gvec-desc.h" #include "tcg/tcg-gvec-desc.h"
/* Virtually all hosts support 16-byte vectors. Those that don't can emulate
* them via GCC's generic vector extension. This turns out to be simpler and
* more reliable than getting the compiler to autovectorize.
*
* In tcg-op-gvec.c, we asserted that both the size and alignment of the data
* are multiples of 16.
*
* When the compiler does not support all of the operations we require, the
* loops are written so that we can always fall back on the base types.
*/
#ifdef CONFIG_VECTOR16
typedef uint8_t vec8 __attribute__((vector_size(16)));
typedef uint16_t vec16 __attribute__((vector_size(16)));
typedef uint32_t vec32 __attribute__((vector_size(16)));
typedef uint64_t vec64 __attribute__((vector_size(16)));
typedef int8_t svec8 __attribute__((vector_size(16)));
typedef int16_t svec16 __attribute__((vector_size(16)));
typedef int32_t svec32 __attribute__((vector_size(16)));
typedef int64_t svec64 __attribute__((vector_size(16)));
#define DUP16(X) { X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X }
#define DUP8(X) { X, X, X, X, X, X, X, X }
#define DUP4(X) { X, X, X, X }
#define DUP2(X) { X, X }
#else
typedef uint8_t vec8;
typedef uint16_t vec16;
typedef uint32_t vec32;
typedef uint64_t vec64;
typedef int8_t svec8;
typedef int16_t svec16;
typedef int32_t svec32;
typedef int64_t svec64;
#define DUP16(X) X
#define DUP8(X) X
#define DUP4(X) X
#define DUP2(X) X
#endif /* CONFIG_VECTOR16 */
static inline void clear_high(void *d, intptr_t oprsz, uint32_t desc) static inline void clear_high(void *d, intptr_t oprsz, uint32_t desc)
{ {
intptr_t maxsz = simd_maxsz(desc); intptr_t maxsz = simd_maxsz(desc);
@ -83,8 +41,8 @@ void HELPER(gvec_add8)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec8)) { for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
*(vec8 *)(d + i) = *(vec8 *)(a + i) + *(vec8 *)(b + i); *(uint8_t *)(d + i) = *(uint8_t *)(a + i) + *(uint8_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -94,8 +52,8 @@ void HELPER(gvec_add16)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec16)) { for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
*(vec16 *)(d + i) = *(vec16 *)(a + i) + *(vec16 *)(b + i); *(uint16_t *)(d + i) = *(uint16_t *)(a + i) + *(uint16_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -105,8 +63,8 @@ void HELPER(gvec_add32)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec32)) { for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
*(vec32 *)(d + i) = *(vec32 *)(a + i) + *(vec32 *)(b + i); *(uint32_t *)(d + i) = *(uint32_t *)(a + i) + *(uint32_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -116,8 +74,8 @@ void HELPER(gvec_add64)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) + *(vec64 *)(b + i); *(uint64_t *)(d + i) = *(uint64_t *)(a + i) + *(uint64_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -125,11 +83,10 @@ void HELPER(gvec_add64)(void *d, void *a, void *b, uint32_t desc)
void HELPER(gvec_adds8)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_adds8)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec8 vecb = (vec8)DUP16(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec8)) { for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
*(vec8 *)(d + i) = *(vec8 *)(a + i) + vecb; *(uint8_t *)(d + i) = *(uint8_t *)(a + i) + (uint8_t)b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -137,11 +94,10 @@ void HELPER(gvec_adds8)(void *d, void *a, uint64_t b, uint32_t desc)
void HELPER(gvec_adds16)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_adds16)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec16 vecb = (vec16)DUP8(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec16)) { for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
*(vec16 *)(d + i) = *(vec16 *)(a + i) + vecb; *(uint16_t *)(d + i) = *(uint16_t *)(a + i) + (uint16_t)b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -149,11 +105,10 @@ void HELPER(gvec_adds16)(void *d, void *a, uint64_t b, uint32_t desc)
void HELPER(gvec_adds32)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_adds32)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec32 vecb = (vec32)DUP4(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec32)) { for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
*(vec32 *)(d + i) = *(vec32 *)(a + i) + vecb; *(uint32_t *)(d + i) = *(uint32_t *)(a + i) + (uint32_t)b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -161,11 +116,10 @@ void HELPER(gvec_adds32)(void *d, void *a, uint64_t b, uint32_t desc)
void HELPER(gvec_adds64)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_adds64)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec64 vecb = (vec64)DUP2(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) + vecb; *(uint64_t *)(d + i) = *(uint64_t *)(a + i) + b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -175,8 +129,8 @@ void HELPER(gvec_sub8)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec8)) { for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
*(vec8 *)(d + i) = *(vec8 *)(a + i) - *(vec8 *)(b + i); *(uint8_t *)(d + i) = *(uint8_t *)(a + i) - *(uint8_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -186,8 +140,8 @@ void HELPER(gvec_sub16)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec16)) { for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
*(vec16 *)(d + i) = *(vec16 *)(a + i) - *(vec16 *)(b + i); *(uint16_t *)(d + i) = *(uint16_t *)(a + i) - *(uint16_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -197,8 +151,8 @@ void HELPER(gvec_sub32)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec32)) { for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
*(vec32 *)(d + i) = *(vec32 *)(a + i) - *(vec32 *)(b + i); *(uint32_t *)(d + i) = *(uint32_t *)(a + i) - *(uint32_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -208,8 +162,8 @@ void HELPER(gvec_sub64)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) - *(vec64 *)(b + i); *(uint64_t *)(d + i) = *(uint64_t *)(a + i) - *(uint64_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -217,11 +171,10 @@ void HELPER(gvec_sub64)(void *d, void *a, void *b, uint32_t desc)
void HELPER(gvec_subs8)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_subs8)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec8 vecb = (vec8)DUP16(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec8)) { for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
*(vec8 *)(d + i) = *(vec8 *)(a + i) - vecb; *(uint8_t *)(d + i) = *(uint8_t *)(a + i) - (uint8_t)b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -229,11 +182,10 @@ void HELPER(gvec_subs8)(void *d, void *a, uint64_t b, uint32_t desc)
void HELPER(gvec_subs16)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_subs16)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec16 vecb = (vec16)DUP8(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec16)) { for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
*(vec16 *)(d + i) = *(vec16 *)(a + i) - vecb; *(uint16_t *)(d + i) = *(uint16_t *)(a + i) - (uint16_t)b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -241,11 +193,10 @@ void HELPER(gvec_subs16)(void *d, void *a, uint64_t b, uint32_t desc)
void HELPER(gvec_subs32)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_subs32)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec32 vecb = (vec32)DUP4(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec32)) { for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
*(vec32 *)(d + i) = *(vec32 *)(a + i) - vecb; *(uint32_t *)(d + i) = *(uint32_t *)(a + i) - (uint32_t)b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -253,11 +204,10 @@ void HELPER(gvec_subs32)(void *d, void *a, uint64_t b, uint32_t desc)
void HELPER(gvec_subs64)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_subs64)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec64 vecb = (vec64)DUP2(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) - vecb; *(uint64_t *)(d + i) = *(uint64_t *)(a + i) - b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -267,8 +217,8 @@ void HELPER(gvec_mul8)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec8)) { for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
*(vec8 *)(d + i) = *(vec8 *)(a + i) * *(vec8 *)(b + i); *(uint8_t *)(d + i) = *(uint8_t *)(a + i) * *(uint8_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -278,8 +228,8 @@ void HELPER(gvec_mul16)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec16)) { for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
*(vec16 *)(d + i) = *(vec16 *)(a + i) * *(vec16 *)(b + i); *(uint16_t *)(d + i) = *(uint16_t *)(a + i) * *(uint16_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -289,8 +239,8 @@ void HELPER(gvec_mul32)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec32)) { for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
*(vec32 *)(d + i) = *(vec32 *)(a + i) * *(vec32 *)(b + i); *(uint32_t *)(d + i) = *(uint32_t *)(a + i) * *(uint32_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -300,8 +250,8 @@ void HELPER(gvec_mul64)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) * *(vec64 *)(b + i); *(uint64_t *)(d + i) = *(uint64_t *)(a + i) * *(uint64_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -309,11 +259,10 @@ void HELPER(gvec_mul64)(void *d, void *a, void *b, uint32_t desc)
void HELPER(gvec_muls8)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_muls8)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec8 vecb = (vec8)DUP16(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec8)) { for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
*(vec8 *)(d + i) = *(vec8 *)(a + i) * vecb; *(uint8_t *)(d + i) = *(uint8_t *)(a + i) * (uint8_t)b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -321,11 +270,10 @@ void HELPER(gvec_muls8)(void *d, void *a, uint64_t b, uint32_t desc)
void HELPER(gvec_muls16)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_muls16)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec16 vecb = (vec16)DUP8(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec16)) { for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
*(vec16 *)(d + i) = *(vec16 *)(a + i) * vecb; *(uint16_t *)(d + i) = *(uint16_t *)(a + i) * (uint16_t)b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -333,11 +281,10 @@ void HELPER(gvec_muls16)(void *d, void *a, uint64_t b, uint32_t desc)
void HELPER(gvec_muls32)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_muls32)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec32 vecb = (vec32)DUP4(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec32)) { for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
*(vec32 *)(d + i) = *(vec32 *)(a + i) * vecb; *(uint32_t *)(d + i) = *(uint32_t *)(a + i) * (uint32_t)b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -345,11 +292,10 @@ void HELPER(gvec_muls32)(void *d, void *a, uint64_t b, uint32_t desc)
void HELPER(gvec_muls64)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_muls64)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec64 vecb = (vec64)DUP2(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) * vecb; *(uint64_t *)(d + i) = *(uint64_t *)(a + i) * b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -359,8 +305,8 @@ void HELPER(gvec_neg8)(void *d, void *a, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec8)) { for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
*(vec8 *)(d + i) = -*(vec8 *)(a + i); *(uint8_t *)(d + i) = -*(uint8_t *)(a + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -370,8 +316,8 @@ void HELPER(gvec_neg16)(void *d, void *a, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec16)) { for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
*(vec16 *)(d + i) = -*(vec16 *)(a + i); *(uint16_t *)(d + i) = -*(uint16_t *)(a + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -381,8 +327,8 @@ void HELPER(gvec_neg32)(void *d, void *a, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec32)) { for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
*(vec32 *)(d + i) = -*(vec32 *)(a + i); *(uint32_t *)(d + i) = -*(uint32_t *)(a + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -392,8 +338,8 @@ void HELPER(gvec_neg64)(void *d, void *a, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = -*(vec64 *)(a + i); *(uint64_t *)(d + i) = -*(uint64_t *)(a + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -499,8 +445,8 @@ void HELPER(gvec_not)(void *d, void *a, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = ~*(vec64 *)(a + i); *(uint64_t *)(d + i) = ~*(uint64_t *)(a + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -510,8 +456,8 @@ void HELPER(gvec_and)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) & *(vec64 *)(b + i); *(uint64_t *)(d + i) = *(uint64_t *)(a + i) & *(uint64_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -521,8 +467,8 @@ void HELPER(gvec_or)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) | *(vec64 *)(b + i); *(uint64_t *)(d + i) = *(uint64_t *)(a + i) | *(uint64_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -532,8 +478,8 @@ void HELPER(gvec_xor)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) ^ *(vec64 *)(b + i); *(uint64_t *)(d + i) = *(uint64_t *)(a + i) ^ *(uint64_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -543,8 +489,8 @@ void HELPER(gvec_andc)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) &~ *(vec64 *)(b + i); *(uint64_t *)(d + i) = *(uint64_t *)(a + i) &~ *(uint64_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -554,8 +500,8 @@ void HELPER(gvec_orc)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) |~ *(vec64 *)(b + i); *(uint64_t *)(d + i) = *(uint64_t *)(a + i) |~ *(uint64_t *)(b + i);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -565,8 +511,8 @@ void HELPER(gvec_nand)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = ~(*(vec64 *)(a + i) & *(vec64 *)(b + i)); *(uint64_t *)(d + i) = ~(*(uint64_t *)(a + i) & *(uint64_t *)(b + i));
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -576,8 +522,8 @@ void HELPER(gvec_nor)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = ~(*(vec64 *)(a + i) | *(vec64 *)(b + i)); *(uint64_t *)(d + i) = ~(*(uint64_t *)(a + i) | *(uint64_t *)(b + i));
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -587,8 +533,8 @@ void HELPER(gvec_eqv)(void *d, void *a, void *b, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = ~(*(vec64 *)(a + i) ^ *(vec64 *)(b + i)); *(uint64_t *)(d + i) = ~(*(uint64_t *)(a + i) ^ *(uint64_t *)(b + i));
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -596,11 +542,10 @@ void HELPER(gvec_eqv)(void *d, void *a, void *b, uint32_t desc)
void HELPER(gvec_ands)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_ands)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec64 vecb = (vec64)DUP2(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) & vecb; *(uint64_t *)(d + i) = *(uint64_t *)(a + i) & b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -608,11 +553,10 @@ void HELPER(gvec_ands)(void *d, void *a, uint64_t b, uint32_t desc)
void HELPER(gvec_xors)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_xors)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec64 vecb = (vec64)DUP2(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) ^ vecb; *(uint64_t *)(d + i) = *(uint64_t *)(a + i) ^ b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -620,11 +564,10 @@ void HELPER(gvec_xors)(void *d, void *a, uint64_t b, uint32_t desc)
void HELPER(gvec_ors)(void *d, void *a, uint64_t b, uint32_t desc) void HELPER(gvec_ors)(void *d, void *a, uint64_t b, uint32_t desc)
{ {
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
vec64 vecb = (vec64)DUP2(b);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) | vecb; *(uint64_t *)(d + i) = *(uint64_t *)(a + i) | b;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -635,8 +578,8 @@ void HELPER(gvec_shl8i)(void *d, void *a, uint32_t desc)
int shift = simd_data(desc); int shift = simd_data(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec8)) { for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
*(vec8 *)(d + i) = *(vec8 *)(a + i) << shift; *(uint8_t *)(d + i) = *(uint8_t *)(a + i) << shift;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -647,8 +590,8 @@ void HELPER(gvec_shl16i)(void *d, void *a, uint32_t desc)
int shift = simd_data(desc); int shift = simd_data(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec16)) { for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
*(vec16 *)(d + i) = *(vec16 *)(a + i) << shift; *(uint16_t *)(d + i) = *(uint16_t *)(a + i) << shift;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -659,8 +602,8 @@ void HELPER(gvec_shl32i)(void *d, void *a, uint32_t desc)
int shift = simd_data(desc); int shift = simd_data(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec32)) { for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
*(vec32 *)(d + i) = *(vec32 *)(a + i) << shift; *(uint32_t *)(d + i) = *(uint32_t *)(a + i) << shift;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -671,8 +614,8 @@ void HELPER(gvec_shl64i)(void *d, void *a, uint32_t desc)
int shift = simd_data(desc); int shift = simd_data(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) << shift; *(uint64_t *)(d + i) = *(uint64_t *)(a + i) << shift;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -683,8 +626,8 @@ void HELPER(gvec_shr8i)(void *d, void *a, uint32_t desc)
int shift = simd_data(desc); int shift = simd_data(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec8)) { for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
*(vec8 *)(d + i) = *(vec8 *)(a + i) >> shift; *(uint8_t *)(d + i) = *(uint8_t *)(a + i) >> shift;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -695,8 +638,8 @@ void HELPER(gvec_shr16i)(void *d, void *a, uint32_t desc)
int shift = simd_data(desc); int shift = simd_data(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec16)) { for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
*(vec16 *)(d + i) = *(vec16 *)(a + i) >> shift; *(uint16_t *)(d + i) = *(uint16_t *)(a + i) >> shift;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -707,8 +650,8 @@ void HELPER(gvec_shr32i)(void *d, void *a, uint32_t desc)
int shift = simd_data(desc); int shift = simd_data(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec32)) { for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
*(vec32 *)(d + i) = *(vec32 *)(a + i) >> shift; *(uint32_t *)(d + i) = *(uint32_t *)(a + i) >> shift;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -719,8 +662,8 @@ void HELPER(gvec_shr64i)(void *d, void *a, uint32_t desc)
int shift = simd_data(desc); int shift = simd_data(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(vec64 *)(d + i) = *(vec64 *)(a + i) >> shift; *(uint64_t *)(d + i) = *(uint64_t *)(a + i) >> shift;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -731,8 +674,8 @@ void HELPER(gvec_sar8i)(void *d, void *a, uint32_t desc)
int shift = simd_data(desc); int shift = simd_data(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec8)) { for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
*(svec8 *)(d + i) = *(svec8 *)(a + i) >> shift; *(int8_t *)(d + i) = *(int8_t *)(a + i) >> shift;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -743,8 +686,8 @@ void HELPER(gvec_sar16i)(void *d, void *a, uint32_t desc)
int shift = simd_data(desc); int shift = simd_data(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec16)) { for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
*(svec16 *)(d + i) = *(svec16 *)(a + i) >> shift; *(int16_t *)(d + i) = *(int16_t *)(a + i) >> shift;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -755,8 +698,8 @@ void HELPER(gvec_sar32i)(void *d, void *a, uint32_t desc)
int shift = simd_data(desc); int shift = simd_data(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec32)) { for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
*(svec32 *)(d + i) = *(svec32 *)(a + i) >> shift; *(int32_t *)(d + i) = *(int32_t *)(a + i) >> shift;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -767,8 +710,8 @@ void HELPER(gvec_sar64i)(void *d, void *a, uint32_t desc)
int shift = simd_data(desc); int shift = simd_data(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
*(svec64 *)(d + i) = *(svec64 *)(a + i) >> shift; *(int64_t *)(d + i) = *(int64_t *)(a + i) >> shift;
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
@ -917,39 +860,30 @@ void HELPER(gvec_sar64v)(void *d, void *a, void *b, uint32_t desc)
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
/* If vectors are enabled, the compiler fills in -1 for true.
Otherwise, we must take care of this by hand. */
#ifdef CONFIG_VECTOR16
# define DO_CMP0(X) X
#else
# define DO_CMP0(X) -(X)
#endif
#define DO_CMP1(NAME, TYPE, OP) \ #define DO_CMP1(NAME, TYPE, OP) \
void HELPER(NAME)(void *d, void *a, void *b, uint32_t desc) \ void HELPER(NAME)(void *d, void *a, void *b, uint32_t desc) \
{ \ { \
intptr_t oprsz = simd_oprsz(desc); \ intptr_t oprsz = simd_oprsz(desc); \
intptr_t i; \ intptr_t i; \
for (i = 0; i < oprsz; i += sizeof(TYPE)) { \ for (i = 0; i < oprsz; i += sizeof(TYPE)) { \
*(TYPE *)(d + i) = DO_CMP0(*(TYPE *)(a + i) OP *(TYPE *)(b + i)); \ *(TYPE *)(d + i) = -(*(TYPE *)(a + i) OP *(TYPE *)(b + i)); \
} \ } \
clear_high(d, oprsz, desc); \ clear_high(d, oprsz, desc); \
} }
#define DO_CMP2(SZ) \ #define DO_CMP2(SZ) \
DO_CMP1(gvec_eq##SZ, vec##SZ, ==) \ DO_CMP1(gvec_eq##SZ, uint##SZ##_t, ==) \
DO_CMP1(gvec_ne##SZ, vec##SZ, !=) \ DO_CMP1(gvec_ne##SZ, uint##SZ##_t, !=) \
DO_CMP1(gvec_lt##SZ, svec##SZ, <) \ DO_CMP1(gvec_lt##SZ, int##SZ##_t, <) \
DO_CMP1(gvec_le##SZ, svec##SZ, <=) \ DO_CMP1(gvec_le##SZ, int##SZ##_t, <=) \
DO_CMP1(gvec_ltu##SZ, vec##SZ, <) \ DO_CMP1(gvec_ltu##SZ, uint##SZ##_t, <) \
DO_CMP1(gvec_leu##SZ, vec##SZ, <=) DO_CMP1(gvec_leu##SZ, uint##SZ##_t, <=)
DO_CMP2(8) DO_CMP2(8)
DO_CMP2(16) DO_CMP2(16)
DO_CMP2(32) DO_CMP2(32)
DO_CMP2(64) DO_CMP2(64)
#undef DO_CMP0
#undef DO_CMP1 #undef DO_CMP1
#undef DO_CMP2 #undef DO_CMP2
@ -1450,11 +1384,11 @@ void HELPER(gvec_bitsel)(void *d, void *a, void *b, void *c, uint32_t desc)
intptr_t oprsz = simd_oprsz(desc); intptr_t oprsz = simd_oprsz(desc);
intptr_t i; intptr_t i;
for (i = 0; i < oprsz; i += sizeof(vec64)) { for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
vec64 aa = *(vec64 *)(a + i); uint64_t aa = *(uint64_t *)(a + i);
vec64 bb = *(vec64 *)(b + i); uint64_t bb = *(uint64_t *)(b + i);
vec64 cc = *(vec64 *)(c + i); uint64_t cc = *(uint64_t *)(c + i);
*(vec64 *)(d + i) = (bb & aa) | (cc & ~aa); *(uint64_t *)(d + i) = (bb & aa) | (cc & ~aa);
} }
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }

56
configure vendored
View File

@ -5764,58 +5764,6 @@ if test "$plugins" = "yes" &&
"for this purpose. You can't build with --static." "for this purpose. You can't build with --static."
fi fi
########################################
# See if 16-byte vector operations are supported.
# Even without a vector unit the compiler may expand these.
# There is a bug in old GCC for PPC that crashes here.
# Unfortunately it's the system compiler for Centos 7.
cat > $TMPC << EOF
typedef unsigned char U1 __attribute__((vector_size(16)));
typedef unsigned short U2 __attribute__((vector_size(16)));
typedef unsigned int U4 __attribute__((vector_size(16)));
typedef unsigned long long U8 __attribute__((vector_size(16)));
typedef signed char S1 __attribute__((vector_size(16)));
typedef signed short S2 __attribute__((vector_size(16)));
typedef signed int S4 __attribute__((vector_size(16)));
typedef signed long long S8 __attribute__((vector_size(16)));
static U1 a1, b1;
static U2 a2, b2;
static U4 a4, b4;
static U8 a8, b8;
static S1 c1;
static S2 c2;
static S4 c4;
static S8 c8;
static int i;
void helper(void *d, void *a, int shift, int i);
void helper(void *d, void *a, int shift, int i)
{
*(U1 *)(d + i) = *(U1 *)(a + i) << shift;
*(U2 *)(d + i) = *(U2 *)(a + i) << shift;
*(U4 *)(d + i) = *(U4 *)(a + i) << shift;
*(U8 *)(d + i) = *(U8 *)(a + i) << shift;
}
int main(void)
{
a1 += b1; a2 += b2; a4 += b4; a8 += b8;
a1 -= b1; a2 -= b2; a4 -= b4; a8 -= b8;
a1 *= b1; a2 *= b2; a4 *= b4; a8 *= b8;
a1 &= b1; a2 &= b2; a4 &= b4; a8 &= b8;
a1 |= b1; a2 |= b2; a4 |= b4; a8 |= b8;
a1 ^= b1; a2 ^= b2; a4 ^= b4; a8 ^= b8;
a1 <<= i; a2 <<= i; a4 <<= i; a8 <<= i;
a1 >>= i; a2 >>= i; a4 >>= i; a8 >>= i;
c1 >>= i; c2 >>= i; c4 >>= i; c8 >>= i;
return 0;
}
EOF
vector16=no
if compile_prog "" "" ; then
vector16=yes
fi
######################################## ########################################
# See if __attribute__((alias)) is supported. # See if __attribute__((alias)) is supported.
# This false for Xcode 9, but has been remedied for Xcode 10. # This false for Xcode 9, but has been remedied for Xcode 10.
@ -7446,10 +7394,6 @@ if test "$atomic64" = "yes" ; then
echo "CONFIG_ATOMIC64=y" >> $config_host_mak echo "CONFIG_ATOMIC64=y" >> $config_host_mak
fi fi
if test "$vector16" = "yes" ; then
echo "CONFIG_VECTOR16=y" >> $config_host_mak
fi
if test "$attralias" = "yes" ; then if test "$attralias" = "yes" ; then
echo "CONFIG_ATTRIBUTE_ALIAS=y" >> $config_host_mak echo "CONFIG_ATTRIBUTE_ALIAS=y" >> $config_host_mak
fi fi

View File

@ -3391,12 +3391,15 @@ static void expand_vec_sari(TCGType type, unsigned vece,
case MO_64: case MO_64:
if (imm <= 32) { if (imm <= 32) {
/* We can emulate a small sign extend by performing an arithmetic /*
* We can emulate a small sign extend by performing an arithmetic
* 32-bit shift and overwriting the high half of a 64-bit logical * 32-bit shift and overwriting the high half of a 64-bit logical
* shift (note that the ISA says shift of 32 is valid). * shift. Note that the ISA says shift of 32 is valid, but TCG
* does not, so we have to bound the smaller shift -- we get the
* same result in the high half either way.
*/ */
t1 = tcg_temp_new_vec(type); t1 = tcg_temp_new_vec(type);
tcg_gen_sari_vec(MO_32, t1, v1, imm); tcg_gen_sari_vec(MO_32, t1, v1, MIN(imm, 31));
tcg_gen_shri_vec(MO_64, v0, v1, imm); tcg_gen_shri_vec(MO_64, v0, v1, imm);
vec_gen_4(INDEX_op_x86_blend_vec, type, MO_32, vec_gen_4(INDEX_op_x86_blend_vec, type, MO_32,
tcgv_vec_arg(v0), tcgv_vec_arg(v0), tcgv_vec_arg(v0), tcgv_vec_arg(v0),