]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Comprehensive tests for bt{s,r,c,}{w,l,q} on amd64.
authorJulian Seward <jseward@acm.org>
Fri, 12 May 2006 19:50:44 +0000 (19:50 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 12 May 2006 19:50:44 +0000 (19:50 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5892

memcheck/tests/amd64/Makefile.am
memcheck/tests/amd64/bt_everything.c [new file with mode: 0644]
memcheck/tests/amd64/bt_everything.stderr.exp [new file with mode: 0644]
memcheck/tests/amd64/bt_everything.stdout.exp [new file with mode: 0644]
memcheck/tests/amd64/bt_everything.vgtest [new file with mode: 0644]

index a62b428ab86a4a07fdc7e8ba0c2861474cd2b3c3..716c9d6981df858e9d4e6029e0b0553484cf41ce 100644 (file)
@@ -8,10 +8,12 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        $(addsuffix .stderr.exp,$(INSN_TESTS)) \
        $(addsuffix .stdout.exp,$(INSN_TESTS)) \
        $(addsuffix .vgtest,$(INSN_TESTS)) \
+       bt_everything.stderr.exp bt_everything.stdout.exp \
+               bt_everything.vgtest \
        more_x87_fp.stderr.exp more_x87_fp.stdout.exp more_x87_fp.vgtest \
        sse_memory.stderr.exp sse_memory.stdout.exp sse_memory.vgtest
 
-check_PROGRAMS = more_x87_fp sse_memory
+check_PROGRAMS = bt_everything more_x87_fp sse_memory
 
 AM_CPPFLAGS = -I$(top_srcdir)/include
 AM_CFLAGS   = $(WERROR) -Winline -Wall -Wshadow -g -I$(top_srcdir)/include
diff --git a/memcheck/tests/amd64/bt_everything.c b/memcheck/tests/amd64/bt_everything.c
new file mode 100644 (file)
index 0000000..3c50181
--- /dev/null
@@ -0,0 +1,498 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+typedef unsigned long long int ULong;
+typedef unsigned int   UInt;
+typedef unsigned short UShort;
+typedef unsigned char  UChar;
+
+typedef signed int    Int;
+typedef signed short  Short;
+
+typedef signed long int  Word;
+
+/* ------------ MEM, Q ------------ */
+
+ULong btsq_mem ( char* base, Word bitno )
+{
+   UChar res;
+   __asm__ 
+   __volatile__("btsq\t%2, %0\n\t"
+                "setc\t%1" 
+                : "=m" (*base), "=q" (res)
+                : "r" (bitno));
+   /* Pretty meaningless to dereference base here, but that's what you
+      have to do to get a btsl insn which refers to memory starting at
+      base. */
+   return res;
+}
+
+ULong btrq_mem ( char* base, Word bitno )
+{
+   UChar res;
+   __asm__ 
+   __volatile__("btrq\t%2, %0\n\t"
+                "setc\t%1" 
+                : "=m" (*base), "=q" (res)
+                : "r" (bitno));
+   return res;
+}
+
+ULong btcq_mem ( char* base, Word bitno )
+{
+   UChar res;
+   __asm__ 
+   __volatile__("btcq\t%2, %0\n\t"
+                "setc\t%1" 
+                : "=m" (*base), "=q" (res)
+                : "r" (bitno));
+   return res;
+}
+
+ULong btq_mem ( char* base, Word bitno )
+{
+   UChar res;
+   __asm__ 
+   __volatile__("btq\t%2, %0\n\t"
+                "setc\t%1" 
+                : "=m" (*base), "=q" (res)
+                : "r" (bitno)
+                : "cc", "memory");
+   return res;
+}
+
+
+/* ------------ MEM, L ------------ */
+
+ULong btsl_mem ( char* base, Word bitno )
+{
+   UChar res;
+   __asm__ 
+   __volatile__("btsl\t%2, %0\n\t"
+                "setc\t%1" 
+                : "=m" (*base), "=q" (res)
+                : "r" ((Int)bitno));
+   /* Pretty meaningless to dereference base here, but that's what you
+      have to do to get a btsl insn which refers to memory starting at
+      base. */
+   return res;
+}
+
+ULong btrl_mem ( char* base, Word bitno )
+{
+   UChar res;
+   __asm__ 
+   __volatile__("btrl\t%2, %0\n\t"
+                "setc\t%1" 
+                : "=m" (*base), "=q" (res)
+                : "r" ((Int)bitno));
+   return res;
+}
+
+ULong btcl_mem ( char* base, Word bitno )
+{
+   UChar res;
+   __asm__ 
+   __volatile__("btcl\t%2, %0\n\t"
+                "setc\t%1" 
+                : "=m" (*base), "=q" (res)
+                : "r" ((Int)bitno));
+   return res;
+}
+
+ULong btl_mem ( char* base, Word bitno )
+{
+   UChar res;
+   __asm__ 
+   __volatile__("btl\t%2, %0\n\t"
+                "setc\t%1" 
+                : "=m" (*base), "=q" (res)
+                : "r" ((Int)bitno)
+                : "cc", "memory");
+   return res;
+}
+
+
+
+/* ------------ MEM, W ------------ */
+
+ULong btsw_mem ( char* base, Word bitno )
+{
+   UChar res;
+   __asm__ 
+   __volatile__("btsw\t%2, %0\n\t"
+                "setc\t%1" 
+                : "=m" (*base), "=q" (res)
+                : "r" ((Short)bitno));
+   /* Pretty meaningless to dereference base here, but that's what you
+      have to do to get a btsl insn which refers to memory starting at
+      base. */
+   return res;
+}
+
+ULong btrw_mem ( char* base, Word bitno )
+{
+   UChar res;
+   __asm__ 
+   __volatile__("btrw\t%2, %0\n\t"
+                "setc\t%1" 
+                : "=m" (*base), "=q" (res)
+                : "r" ((Short)bitno));
+   return res;
+}
+
+ULong btcw_mem ( char* base, Word bitno )
+{
+   UChar res;
+   __asm__ 
+   __volatile__("btcw\t%2, %0\n\t"
+                "setc\t%1" 
+                : "=m" (*base), "=q" (res)
+                : "r" ((Short)bitno));
+   return res;
+}
+
+ULong btw_mem ( char* base, Word bitno )
+{
+   UChar res;
+   __asm__ 
+   __volatile__("btw\t%2, %0\n\t"
+                "setc\t%1" 
+                : "=m" (*base), "=q" (res)
+                : "r" ((Short)bitno)
+                : "cc", "memory");
+   return res;
+}
+
+
+
+/* ------------ REG, Q ------------ */
+
+ULong btsq_reg ( ULong reg_in, Word bitno, 
+                        ULong* reg_out_p )
+{
+   UChar res;
+   ULong reg_out;
+   __asm__ 
+   __volatile__("movq\t%3, %%rax\n\t"
+                "btsq\t%2, %%rax\n\t"
+                "movq\t%%rax, %1\n\t"
+                "setc\t%0" 
+                : "=q" (res), "=r" (reg_out)
+                : "r" (bitno), "r" (reg_in)
+                : "cc", "eax");
+   *reg_out_p = reg_out;
+   return res;
+}
+
+
+ULong btrq_reg ( ULong reg_in, Word bitno, 
+                        ULong* reg_out_p )
+{
+   UChar res;
+   ULong reg_out;
+   __asm__ 
+   __volatile__("movq\t%3, %%rax\n\t"
+                "btrq\t%2, %%rax\n\t"
+                "movq\t%%rax, %1\n\t"
+                "setc\t%0" 
+                : "=q" (res), "=r" (reg_out)
+                : "r" (bitno), "r" (reg_in)
+                : "cc", "eax");
+   *reg_out_p = reg_out;
+   return res;
+}
+
+
+ULong btcq_reg ( ULong reg_in, Word bitno, 
+                        ULong* reg_out_p )
+{
+   UChar res;
+   ULong reg_out;
+   __asm__ 
+   __volatile__("movq\t%3, %%rax\n\t"
+                "btcq\t%2, %%rax\n\t"
+                "movq\t%%rax, %1\n\t"
+                "setc\t%0" 
+                : "=q" (res), "=r" (reg_out)
+                : "r" (bitno), "r" (reg_in)
+                : "cc", "eax");
+   *reg_out_p = reg_out;
+   return res;
+}
+
+
+ULong btq_reg ( ULong reg_in, Word bitno, 
+                       ULong* reg_out_p )
+{
+   UChar res;
+   ULong reg_out;
+   __asm__ 
+   __volatile__("movq\t%3, %%rax\n\t"
+                "btq\t%2, %%rax\n\t"
+                "movq\t%%rax, %1\n\t"
+                "setc\t%0" 
+                : "=q" (res), "=r" (reg_out)
+                : "r" (bitno), "r" (reg_in)
+                : "cc", "eax");
+   *reg_out_p = reg_out;
+   return res;
+}
+
+
+
+/* ------------ REG, L ------------ */
+
+ULong btsl_reg ( ULong reg_in, Word bitno, 
+                        ULong* reg_out_p )
+{
+   UChar res;
+   ULong reg_out;
+   __asm__ 
+   __volatile__("movq\t%3, %%rax\n\t"
+                "btsl\t%2, %%eax\n\t"
+                "movq\t%%rax, %1\n\t"
+                "setc\t%0" 
+                : "=q" (res), "=r" (reg_out)
+                : "r" ((Int)bitno), "r" (reg_in)
+                : "cc", "eax");
+   *reg_out_p = reg_out;
+   return res;
+}
+
+
+ULong btrl_reg ( ULong reg_in, Word bitno, 
+                        ULong* reg_out_p )
+{
+   UChar res;
+   ULong reg_out;
+   __asm__ 
+   __volatile__("movq\t%3, %%rax\n\t"
+                "btrl\t%2, %%eax\n\t"
+                "movq\t%%rax, %1\n\t"
+                "setc\t%0" 
+                : "=q" (res), "=r" (reg_out)
+                : "r" ((Int)bitno), "r" (reg_in)
+                : "cc", "eax");
+   *reg_out_p = reg_out;
+   return res;
+}
+
+
+ULong btcl_reg ( ULong reg_in, Word bitno, 
+                        ULong* reg_out_p )
+{
+   UChar res;
+   ULong reg_out;
+   __asm__ 
+   __volatile__("movq\t%3, %%rax\n\t"
+                "btcl\t%2, %%eax\n\t"
+                "movq\t%%rax, %1\n\t"
+                "setc\t%0" 
+                : "=q" (res), "=r" (reg_out)
+                : "r" ((Int)bitno), "r" (reg_in)
+                : "cc", "eax");
+   *reg_out_p = reg_out;
+   return res;
+}
+
+
+ULong btl_reg ( ULong reg_in, Word bitno, 
+                       ULong* reg_out_p )
+{
+   UChar res;
+   ULong reg_out;
+   __asm__ 
+   __volatile__("movq\t%3, %%rax\n\t"
+                "btl\t%2, %%eax\n\t"
+                "movq\t%%rax, %1\n\t"
+                "setc\t%0" 
+                : "=q" (res), "=r" (reg_out)
+                : "r" ((Int)bitno), "r" (reg_in)
+                : "cc", "eax");
+   *reg_out_p = reg_out;
+   return res;
+}
+
+
+
+/* ------------ REG, W ------------ */
+
+ULong btsw_reg ( ULong reg_in, Word bitno, 
+                        ULong* reg_out_p )
+{
+   UChar res;
+   ULong reg_out;
+   __asm__ 
+   __volatile__("movq\t%3, %%rax\n\t"
+                "btsw\t%2, %%ax\n\t"
+                "movq\t%%rax, %1\n\t"
+                "setc\t%0" 
+                : "=q" (res), "=r" (reg_out)
+                : "r" ((Short)bitno), "r" (reg_in)
+                : "cc", "eax");
+   *reg_out_p = reg_out;
+   return res;
+}
+
+
+ULong btrw_reg ( ULong reg_in, Word bitno, 
+                        ULong* reg_out_p )
+{
+   UChar res;
+   ULong reg_out;
+   __asm__ 
+   __volatile__("movq\t%3, %%rax\n\t"
+                "btrw\t%2, %%ax\n\t"
+                "movq\t%%rax, %1\n\t"
+                "setc\t%0" 
+                : "=q" (res), "=r" (reg_out)
+                : "r" ((Short)bitno), "r" (reg_in)
+                : "cc", "eax");
+   *reg_out_p = reg_out;
+   return res;
+}
+
+
+ULong btcw_reg ( ULong reg_in, Word bitno, 
+                        ULong* reg_out_p )
+{
+   UChar res;
+   ULong reg_out;
+   __asm__ 
+   __volatile__("movq\t%3, %%rax\n\t"
+                "btcw\t%2, %%ax\n\t"
+                "movq\t%%rax, %1\n\t"
+                "setc\t%0" 
+                : "=q" (res), "=r" (reg_out)
+                : "r" ((Short)bitno), "r" (reg_in)
+                : "cc", "eax");
+   *reg_out_p = reg_out;
+   return res;
+}
+
+
+ULong btw_reg ( ULong reg_in, Word bitno, 
+                       ULong* reg_out_p )
+{
+   UChar res;
+   ULong reg_out;
+   __asm__ 
+   __volatile__("movq\t%3, %%rax\n\t"
+                "btw\t%2, %%ax\n\t"
+                "movq\t%%rax, %1\n\t"
+                "setc\t%0" 
+                : "=q" (res), "=r" (reg_out)
+                : "r" ((Short)bitno), "r" (reg_in)
+                : "cc", "eax");
+   *reg_out_p = reg_out;
+   return res;
+}
+
+
+
+
+
+
+
+ULong rol1 ( ULong x )
+{
+  return (x << 1) | (x >> 63);
+}
+
+int main ( void )
+{
+   UInt   n, op;
+   ULong  carrydep, c, res;
+   UChar* block;
+   ULong  reg;
+   Word   bitoff;
+
+   /*------------------------ MEM-L -----------------------*/
+
+   carrydep = 0;
+   block = calloc(200,1);
+   block += 100;
+   /* Valid bit offsets are -800 .. 799 inclusive. */
+
+   for (n = 0; n < 10000; n++) {
+      bitoff = (random() % 1600) - 800;
+      op = random() % 12;
+      c = 2;
+      switch (op) {
+         case  0: c = btsl_mem(block, bitoff); break;
+         case  1: c = btrl_mem(block, bitoff); break;
+         case  2: c = btcl_mem(block, bitoff); break;
+         case  3: c =  btl_mem(block, bitoff); break;
+         case  4: c = btsq_mem(block, bitoff); break;
+         case  5: c = btrq_mem(block, bitoff); break;
+         case  6: c = btcq_mem(block, bitoff); break;
+         case  7: c =  btq_mem(block, bitoff); break;
+         case  8: c = btsw_mem(block, bitoff); break;
+         case  9: c = btrw_mem(block, bitoff); break;
+         case 10: c = btcw_mem(block, bitoff); break;
+         case 11: c =  btw_mem(block, bitoff); break;
+         default: assert(0);
+      }
+      assert(c == 0 || c == 1);
+      carrydep = c ? (rol1(carrydep) ^ bitoff) : carrydep;
+   }
+
+   /* Compute final result */
+   block -= 100;   
+   res = 0;
+   for (n = 0; n < 200; n++) {
+      UChar ch = block[n];
+      /* printf("%d ", (int)block[n]); */
+      res = rol1(res) ^ (UInt)ch;
+   }
+
+   printf("MEM-L: final res 0x%llx, carrydep 0x%llx\n", res, carrydep);
+
+   /*------------------------ REG-L -----------------------*/
+
+   carrydep = 0;
+   reg = 0;
+
+   for (n = 0; n < 1000; n++) {
+      bitoff = (random() % 100) - 50;
+      op = random() % 12;
+      c = 2;
+      switch (op) {
+         case  0: c = btsl_reg(reg, bitoff, &reg); break;
+         case  1: c = btrl_reg(reg, bitoff, &reg); break;
+         case  2: c = btcl_reg(reg, bitoff, &reg); break;
+         case  3: c =  btl_reg(reg, bitoff, &reg); break;
+         case  4: c = btsq_reg(reg, bitoff, &reg); break;
+         case  5: c = btrq_reg(reg, bitoff, &reg); break;
+         case  6: c = btcq_reg(reg, bitoff, &reg); break;
+         case  7: c =  btq_reg(reg, bitoff, &reg); break;
+         case  8: c = btsw_reg(reg, bitoff, &reg); break;
+         case  9: c = btrw_reg(reg, bitoff, &reg); break;
+         case 10: c = btcw_reg(reg, bitoff, &reg); break;
+         case 11: c =  btw_reg(reg, bitoff, &reg); break;
+         default: assert(0);
+      }
+      assert(c == 0 || c == 1);
+      carrydep = c ? (rol1(carrydep) ^ bitoff) : carrydep;
+   }
+
+   printf("REG-L: final res 0x%llx, carrydep 0x%llx\n", reg, carrydep);
+
+   block += 100;
+
+   /* Just try one of these at once; more than one can cause a
+      confusing merging of error messages. */
+   //btsl_mem(block, -800);  /* should not complain */
+   //btsl_mem(block, -801);  /* should complain */
+   //btsl_mem(block, 799);   /* should not complain */
+   //btsl_mem(block, 800);   /* should complain */
+
+   block -= 100;
+   free(block);
+
+   return 0;
+}
+
diff --git a/memcheck/tests/amd64/bt_everything.stderr.exp b/memcheck/tests/amd64/bt_everything.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/memcheck/tests/amd64/bt_everything.stdout.exp b/memcheck/tests/amd64/bt_everything.stdout.exp
new file mode 100644 (file)
index 0000000..f22a0a7
--- /dev/null
@@ -0,0 +1,2 @@
+MEM-L: final res 0xbb05dc8f69ba36dc, carrydep 0x818f336625f01277
+REG-L: final res 0xa15f293e, carrydep 0x6082b5e5befc6a40
diff --git a/memcheck/tests/amd64/bt_everything.vgtest b/memcheck/tests/amd64/bt_everything.vgtest
new file mode 100644 (file)
index 0000000..844c404
--- /dev/null
@@ -0,0 +1,2 @@
+prog: bt_everything
+vgopts: -q