@@ -2089,10 +2089,10 @@ static inline unsigned pcmpxstrx(CPUX86State *env, Reg *d, Reg *s,
res = (2 << upper) - 1;
break;
}
- for (j = valids - validd; j >= 0; j--) {
+ for (j = valids == upper ? valids : valids - validd; j >= 0; j--) {
res <<= 1;
v = 1;
- for (i = validd; i >= 0; i--) {
+ for (i = MIN(valids - j, validd); i >= 0; i--) {
v &= (pcmp_val(s, ctrl, i + j) == pcmp_val(d, ctrl, i));
}
res |= v;
@@ -10,6 +10,9 @@ ALL_X86_TESTS=$(I386_SRCS:.c=)
SKIP_I386_TESTS=test-i386-ssse3
X86_64_TESTS:=$(filter test-i386-ssse3, $(ALL_X86_TESTS))
+test-i386-pcmpistri: CFLAGS += -msse4.2
+test-i386-pcmpistri: QEMU_OPTS += -cpu max
+
#
# hello-i386 is a barebones app
#
new file mode 100644
@@ -0,0 +1,33 @@
+/* Test pcmpistri instruction. */
+
+#include <nmmintrin.h>
+#include <stdio.h>
+
+union u {
+ __m128i x;
+ unsigned char uc[16];
+};
+
+union u s0 = { .uc = { 0 } };
+union u s1 = { .uc = "abcdefghijklmnop" };
+union u s2 = { .uc = "bcdefghijklmnopa" };
+union u s3 = { .uc = "bcdefghijklmnab" };
+
+int
+main(void)
+{
+ int ret = 0;
+ if (_mm_cmpistri(s0.x, s0.x, 0x4c) != 15) {
+ printf("FAIL: pcmpistri test 1\n");
+ ret = 1;
+ }
+ if (_mm_cmpistri(s1.x, s2.x, 0x4c) != 15) {
+ printf("FAIL: pcmpistri test 2\n");
+ ret = 1;
+ }
+ if ("%d\n", _mm_cmpistri(s1.x, s3.x, 0x4c) != 16) {
+ printf("FAIL: pcmpistri test 3\n");
+ ret = 1;
+ }
+ return ret;
+}