]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
This patch by adrian.sendroiu@freescale.com fixes the lrmw and stmw
authorCarl Love <cel@us.ibm.com>
Fri, 24 Jan 2014 16:44:08 +0000 (16:44 +0000)
committerCarl Love <cel@us.ibm.com>
Fri, 24 Jan 2014 16:44:08 +0000 (16:44 +0000)
instructions.

The patch also adds ppc32 and ppc64 test cases for the instructions.

The patch is a fix for bugzilla 329956 "valgrind crashes when lmw/stmw instructions are used on ppc64".

The VEX code commit is 2802

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13780

none/tests/ppc32/Makefile.am
none/tests/ppc32/ldst_multiple.c [new file with mode: 0644]
none/tests/ppc32/ldst_multiple.stderr.exp [new file with mode: 0644]
none/tests/ppc32/ldst_multiple.stdout.exp [new file with mode: 0644]
none/tests/ppc32/ldst_multiple.vgtest [new file with mode: 0644]
none/tests/ppc64/Makefile.am
none/tests/ppc64/ldst_multiple.c [new symlink]
none/tests/ppc64/ldst_multiple.stderr.exp [new file with mode: 0644]
none/tests/ppc64/ldst_multiple.stdout.exp [new file with mode: 0644]
none/tests/ppc64/ldst_multiple.vgtest [new file with mode: 0644]

index 4f581b6f0c3d6dc987601858223bb09ea3f50e8a..08486cdcc45a42437444e9a50feccb543f5c3b78 100644 (file)
@@ -43,7 +43,8 @@ EXTRA_DIST = \
        jm_int_isa_2_07.stderr.exp jm_int_isa_2_07.stdout.exp jm_int_isa_2_07.vgtest \
        test_isa_2_07_part2.stderr.exp test_isa_2_07_part2.stdout.exp test_isa_2_07_part2.vgtest \
        test_tm.stderr.exp test_tm.stdout.exp test_tm.vgtest \
-       test_touch_tm.stderr.exp test_touch_tm.stdout.exp test_touch_tm.vgtest
+       test_touch_tm.stderr.exp test_touch_tm.stdout.exp test_touch_tm.vgtest \
+       ldst_multiple.stderr.exp ldst_multiple.stdout.exp ldst_multiple.vgtest
 
 
 check_PROGRAMS = \
@@ -59,7 +60,8 @@ check_PROGRAMS = \
        test_isa_2_07_part1 \
        test_isa_2_07_part2 \
        test_tm \
-       test_touch_tm
+       test_touch_tm \
+       ldst_multiple
 
 AM_CFLAGS    += @FLAG_M32@
 AM_CXXFLAGS  += @FLAG_M32@
diff --git a/none/tests/ppc32/ldst_multiple.c b/none/tests/ppc32/ldst_multiple.c
new file mode 100644 (file)
index 0000000..6c610b9
--- /dev/null
@@ -0,0 +1,191 @@
+#include <stdio.h>
+#include <stdint.h>
+
+#ifndef __powerpc64__
+typedef uint32_t HWord_t;
+#else
+typedef uint64_t HWord_t;
+#endif
+
+typedef void (*test_func_t)();
+
+typedef struct test_table {
+   test_func_t func;
+   char *name;
+} test_table_t;
+
+static uint32_t values[] = {
+   0x6efbcfdf,
+   0xd16c2fd4,
+   0xf9dc1743,
+   0xa5aa0bd4,
+   0x6c8f0c14,
+   0x69a24188,
+   0x53b57f1b,
+};
+
+register HWord_t r27 asm("r27");
+register HWord_t r28 asm("r28");
+register HWord_t r29 asm("r29");
+register HWord_t r30 asm("r30");
+register HWord_t r31 asm("r31");
+
+register HWord_t r14 asm("r14");
+
+HWord_t temp[5];
+
+#ifdef __powerpc64__
+
+#define SAVE_REGS(addr)                       \
+   asm volatile(                              \
+   "   std   27, 0(%0)   \n"                   \
+   "   std   28, 8(%0)   \n"                   \
+   "   std   29, 16(%0)  \n"                   \
+   "   std   30, 24(%0)  \n"                   \
+   "   std   31, 32(%0)  \n"                   \
+   ::"b"(addr))
+
+#define RESTORE_REGS(addr)                    \
+   asm volatile(                              \
+   "   ld    27, 0(%0)   \n"                   \
+   "   ld    28, 8(%0)   \n"                   \
+   "   ld    29, 16(%0)  \n"                   \
+   "   ld    30, 24(%0)  \n"                   \
+   "   ld    31, 32(%0)  \n"                   \
+   ::"b"(addr))
+
+#else /* !__powerpc64__ */
+
+#define SAVE_REGS(addr)                       \
+   asm volatile(                              \
+   "   stw   27, 0(%0)   \n"                   \
+   "   stw   28, 4(%0)   \n"                   \
+   "   stw   29, 8(%0)   \n"                   \
+   "   stw   30, 12(%0)  \n"                   \
+   "   stw   31, 16(%0)  \n"                   \
+   ::"b"(addr))
+
+#define RESTORE_REGS(addr)                    \
+   asm volatile(                              \
+   "   lwz   27, 0(%0)   \n"                   \
+   "   lwz   28, 4(%0)   \n"                   \
+   "   lwz   29, 8(%0)   \n"                   \
+   "   lwz   30, 12(%0)  \n"                   \
+   "   lwz   31, 16(%0)  \n"                   \
+   ::"b"(addr))
+
+#endif /* __powerpc64__ */
+
+/*
+ * gcc is not happy if we modify r31 (the frame pointer) behind its back
+ * so we omit it
+ */
+static void __attribute__((optimize("-fomit-frame-pointer"))) test_lmw(void)
+{
+   r14 = (HWord_t)values;
+
+   /* save r27 - r31 */
+   SAVE_REGS(temp);
+
+   /* load r27 - r31 */
+   asm volatile(
+      "        lmw     %r27, 0(%r14)   \n");
+
+#ifdef __powerpc64__
+   printf("lmw => %016lx %016lx %016lx %016lx %016lx\n",
+#else
+   printf("lmw => %08x %08x %08x %08x %08x\n",
+#endif
+          r27, r28, r29, r30, r31);
+
+   /*
+    * test load multiple with nonzero immediate offset
+    * load the last two values into r30 - r31.
+    * r27 - r29 should remain the same
+    */
+   asm volatile(
+      "        lmw     %r30, 20(%r14)  \n");
+
+#ifdef __powerpc64__
+   printf("lmw => %016lx %016lx %016lx %016lx %016lx\n",
+#else
+   printf("lmw => %08x %08x %08x %08x %08x\n",
+#endif
+          r27, r28, r29, r30, r31);
+
+   /* restore r27 - r31 */
+   RESTORE_REGS(temp);
+}
+
+/*
+ * gcc is not happy if we modify r31 (the frame pointer) behind its back
+ * so we omit it
+ */
+static void __attribute__((optimize("-fomit-frame-pointer"))) test_stmw(void)
+{
+   uint32_t result[7] = { 0 };
+   int i;
+
+   SAVE_REGS(temp);
+
+#ifdef __powerpc64__
+   asm volatile(
+   "   lwz   27, 0(%0)   \n"                   \
+   "   lwz   28, 4(%0)   \n"                   \
+   "   lwz   29, 8(%0)   \n"                   \
+   "   lwz   30, 12(%0)  \n"                   \
+   "   lwz   31, 16(%0)  \n"                   \
+   ::"b"(values));
+#else
+   RESTORE_REGS(values);
+#endif
+
+   r14 = (HWord_t)&result;
+
+   /* store r27 - r31 */
+   asm volatile(
+      "        stmw    %r27, 0(%r14)   \n");
+
+   printf("stmw => ");
+   for (i = 0; i < sizeof(result) / sizeof(result[0]); i++)
+      printf("%08x ", result[i]);
+
+   printf("\n");
+
+   /*
+    * test store multiple with nonzero immediate offset
+    * store r30 - r31 into the last two places in the array
+    * the rest of the array should remain the same
+    */
+   asm volatile(
+      "        stmw    %r30, 20(%r14)  \n");
+
+   printf("stmw => ");
+   for (i = 0; i < sizeof(result) / sizeof(result[0]); i++)
+      printf("%08x ", result[i]);
+
+   printf("\n");
+
+   RESTORE_REGS(temp);
+}
+
+static test_table_t all_tests[] = {
+   { &test_lmw,
+     "Test Load Multiple instruction" },
+   { &test_stmw,
+     "Test Store Multiple instruction" },
+   { NULL, NULL },
+};
+
+int main(void)
+{
+   test_func_t func;
+   int i = 0;
+
+   while ((func = all_tests[i].func)) {
+      (*func)();
+      i++;
+   }
+
+   return 0;
+}
diff --git a/none/tests/ppc32/ldst_multiple.stderr.exp b/none/tests/ppc32/ldst_multiple.stderr.exp
new file mode 100644 (file)
index 0000000..139597f
--- /dev/null
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/ppc32/ldst_multiple.stdout.exp b/none/tests/ppc32/ldst_multiple.stdout.exp
new file mode 100644 (file)
index 0000000..f3579dc
--- /dev/null
@@ -0,0 +1,4 @@
+lmw => 6efbcfdf d16c2fd4 f9dc1743 a5aa0bd4 6c8f0c14
+lmw => 6efbcfdf d16c2fd4 f9dc1743 69a24188 53b57f1b
+stmw => 6efbcfdf d16c2fd4 f9dc1743 a5aa0bd4 6c8f0c14 00000000 00000000 
+stmw => 6efbcfdf d16c2fd4 f9dc1743 a5aa0bd4 6c8f0c14 a5aa0bd4 6c8f0c14 
diff --git a/none/tests/ppc32/ldst_multiple.vgtest b/none/tests/ppc32/ldst_multiple.vgtest
new file mode 100644 (file)
index 0000000..87e668e
--- /dev/null
@@ -0,0 +1 @@
+prog: ldst_multiple
index 93c6fe132249369d4c6c78c6d4eeeef7079434ab..fc43f081a228536b3498dc5a268bedcbc80e39bd 100644 (file)
@@ -31,7 +31,8 @@ EXTRA_DIST = \
        jm_int_isa_2_07.stderr.exp jm_int_isa_2_07.stdout.exp jm_int_isa_2_07.vgtest \
        test_isa_2_07_part2.stderr.exp test_isa_2_07_part2.stdout.exp test_isa_2_07_part2.vgtest \
        test_tm.stderr.exp test_tm.stdout.exp test_tm.vgtest \
-       test_touch_tm.stderr.exp test_touch_tm.stdout.exp test_touch_tm.vgtest
+       test_touch_tm.stderr.exp test_touch_tm.stdout.exp test_touch_tm.vgtest \
+       ldst_multiple.stderr.exp ldst_multiple.stdout.exp ldst_multiple.vgtest
 
 check_PROGRAMS = \
        allexec \
@@ -39,7 +40,7 @@ check_PROGRAMS = \
        power6_mf_gpr test_isa_2_06_part1 test_isa_2_06_part2 \
        test_isa_2_06_part3 test_dfp1 test_dfp2 test_dfp3 test_dfp4 \
        test_dfp5 test_isa_2_07_part1 test_isa_2_07_part2 \
-       test_tm test_touch_tm
+       test_tm test_touch_tm ldst_multiple
 
 AM_CFLAGS    += @FLAG_M64@
 AM_CXXFLAGS  += @FLAG_M64@
diff --git a/none/tests/ppc64/ldst_multiple.c b/none/tests/ppc64/ldst_multiple.c
new file mode 120000 (symlink)
index 0000000..d155824
--- /dev/null
@@ -0,0 +1 @@
+../ppc32/ldst_multiple.c
\ No newline at end of file
diff --git a/none/tests/ppc64/ldst_multiple.stderr.exp b/none/tests/ppc64/ldst_multiple.stderr.exp
new file mode 100644 (file)
index 0000000..139597f
--- /dev/null
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/ppc64/ldst_multiple.stdout.exp b/none/tests/ppc64/ldst_multiple.stdout.exp
new file mode 100644 (file)
index 0000000..31f923b
--- /dev/null
@@ -0,0 +1,4 @@
+lmw => 000000006efbcfdf 00000000d16c2fd4 00000000f9dc1743 00000000a5aa0bd4 000000006c8f0c14
+lmw => 000000006efbcfdf 00000000d16c2fd4 00000000f9dc1743 0000000069a24188 0000000053b57f1b
+stmw => 6efbcfdf d16c2fd4 f9dc1743 a5aa0bd4 6c8f0c14 00000000 00000000 
+stmw => 6efbcfdf d16c2fd4 f9dc1743 a5aa0bd4 6c8f0c14 a5aa0bd4 6c8f0c14 
diff --git a/none/tests/ppc64/ldst_multiple.vgtest b/none/tests/ppc64/ldst_multiple.vgtest
new file mode 100644 (file)
index 0000000..87e668e
--- /dev/null
@@ -0,0 +1 @@
+prog: ldst_multiple