Re: [PATCH] tests/tcg: i386: extend BMI test

2022-08-25 Thread Richard Henderson

On 8/25/22 05:34, Paolo Bonzini wrote:

Cover all BMI1 and BMI2 instructions, both 32- and 64-bit.

Due to the use of inlines, the test now has to be compiled with -O2.

Signed-off-by: Paolo Bonzini 
---
  tests/tcg/i386/Makefile.target  |   1 +
  tests/tcg/i386/test-i386-bmi2.c | 169 ++--
  2 files changed, 162 insertions(+), 8 deletions(-)


Reviewed-by: Richard Henderson 


r~



[PATCH] tests/tcg: i386: extend BMI test

2022-08-25 Thread Paolo Bonzini
Cover all BMI1 and BMI2 instructions, both 32- and 64-bit.

Due to the use of inlines, the test now has to be compiled with -O2.

Signed-off-by: Paolo Bonzini 
---
 tests/tcg/i386/Makefile.target  |   1 +
 tests/tcg/i386/test-i386-bmi2.c | 169 ++--
 2 files changed, 162 insertions(+), 8 deletions(-)

diff --git a/tests/tcg/i386/Makefile.target b/tests/tcg/i386/Makefile.target
index 5614838ffc..646b4ac13e 100644
--- a/tests/tcg/i386/Makefile.target
+++ b/tests/tcg/i386/Makefile.target
@@ -18,6 +18,7 @@ test-i386-pcmpistri: CFLAGS += -msse4.2
 run-test-i386-pcmpistri: QEMU_OPTS += -cpu max
 run-plugin-test-i386-pcmpistri-%: QEMU_OPTS += -cpu max
 
+test-i386-bmi2: CFLAGS=-O2
 run-test-i386-bmi2: QEMU_OPTS += -cpu max
 run-plugin-test-i386-bmi2-%: QEMU_OPTS += -cpu max
 
diff --git a/tests/tcg/i386/test-i386-bmi2.c b/tests/tcg/i386/test-i386-bmi2.c
index 935a4d2a73..5fadf47510 100644
--- a/tests/tcg/i386/test-i386-bmi2.c
+++ b/tests/tcg/i386/test-i386-bmi2.c
@@ -1,6 +1,66 @@
 /* See if various BMI2 instructions give expected results */
 #include 
 #include 
+#include 
+
+#define insn1q(name, arg0) 
  \
+static inline uint64_t name##q(uint64_t arg0)  
  \
+{  
  \
+uint64_t result64; 
  \
+asm volatile (#name "q   %1, %0" : "=r"(result64) : "rm"(arg0));   
  \
+return result64;   
  \
+}
+
+#define insn1l(name, arg0) 
  \
+static inline uint32_t name##l(uint32_t arg0)  
  \
+{  
  \
+uint32_t result32; 
  \
+asm volatile (#name "l   %k1, %k0" : "=r"(result32) : "rm"(arg0)); 
  \
+return result32;   
  \
+}
+
+#define insn2q(name, arg0, c0, arg1, c1)   
  \
+static inline uint64_t name##q(uint64_t arg0, uint64_t arg1)   
  \
+{  
  \
+uint64_t result64; 
  \
+asm volatile (#name "q   %2, %1, %0" : "=r"(result64) : c0(arg0), 
c1(arg1)); \
+return result64;   
  \
+}
+
+#define insn2l(name, arg0, c0, arg1, c1)   
  \
+static inline uint32_t name##l(uint32_t arg0, uint32_t arg1)   
  \
+{  
  \
+uint32_t result32; 
  \
+asm volatile (#name "l   %k2, %k1, %k0" : "=r"(result32) : c0(arg0), 
c1(arg1));  \
+return result32;   
  \
+}
+
+#ifdef __x86_64
+insn2q(pext, src, "r", mask, "rm")
+insn2q(pdep, src, "r", mask, "rm")
+insn2q(andn, clear, "rm", val, "r")
+insn2q(bextr, range, "rm", val, "r")
+insn2q(bzhi, pos, "rm", val, "r")
+insn2q(rorx, val, "r", n, "i")
+insn2q(sarx, val, "rm", n, "r")
+insn2q(shlx, val, "rm", n, "r")
+insn2q(shrx, val, "rm", n, "r")
+insn1q(blsi, src)
+insn1q(blsmsk, src)
+insn1q(blsr, src)
+#endif
+insn2l(pext, src, "r", mask, "rm")
+insn2l(pdep, src, "r", mask, "rm")
+insn2l(andn, clear, "rm", val, "r")
+insn2l(bextr, range, "rm", val, "r")
+insn2l(bzhi, pos, "rm", val, "r")
+insn2l(rorx, val, "r", n, "i")
+insn2l(sarx, val, "rm", n, "r")
+insn2l(shlx, val, "rm", n, "r")
+insn2l(shrx, val, "rm", n, "r")
+insn1l(blsi, src)
+insn1l(blsmsk, src)
+insn1l(blsr, src)
 
 int main(int argc, char *argv[]) {
 uint64_t ehlo = 0x202020204f4c4845ull;
@@ -11,32 +71,125 @@ int main(int argc, char *argv[]) {
 uint64_t result64;
 
 /* 64 bits */
-asm volatile ("pextq   %2, %1, %0" : "=r"(result64) : "r"(ehlo), 
"m"(mask));
+result64 = andnq(mask, ehlo);
+assert(result64 == 0x002020204d4c4844);
+
+result64 = pextq(ehlo, mask);
 assert(result64 == 133);
 
-asm volatile ("pdepq   %2, %1, %0" : "=r"(result64) : "r"(result64), 
"m"(mask));
+result64 = pdepq(result64, mask);
 assert(result64 == (ehlo & mask));
 
-asm volatile ("pextq   %2, %1, %0" : "=r"(result64) : "r"(-1ull), 
"m"(mask));
+result64 = pextq(-1ull, mask);
 assert(result64 == 511); /* mask has 9 bits set */
 
-asm volatile ("pdepq   %2, %1, %0" : "=r"(result64) : "r"(-1ull), 
"m"(mask));
+result64 = pdepq(-1ull, mask);
 assert(result64 == mask);
+
+result64 = bextrq(mask, 0x3f00);
+