]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add test cases for ARMv8 insns: LDA, LDAB, LDAH, STL, STLB, STLH.
authorJulian Seward <jseward@acm.org>
Sun, 28 Aug 2016 16:17:12 +0000 (16:17 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 28 Aug 2016 16:17:12 +0000 (16:17 +0000)
Not connected to the build system yet.

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

none/tests/arm/v8memory.c [new file with mode: 0644]

diff --git a/none/tests/arm/v8memory.c b/none/tests/arm/v8memory.c
new file mode 100644 (file)
index 0000000..93e7050
--- /dev/null
@@ -0,0 +1,155 @@
+
+/*
+gcc -g -o v8memory_a -march=armv8-a -mfpu=crypto-neon-fp-armv8 \
+   none/tests/arm/v8memory.c -I. -Wall -marm
+
+gcc -g -o v8memory_t -march=armv8-a -mfpu=crypto-neon-fp-armv8 \
+   none/tests/arm/v8memory.c -I. -Wall -mthumb   
+*/
+
+#include <stdio.h>
+#include <malloc.h>  // memalign
+#include <string.h>  // memset
+#include "tests/malloc.h"
+#include <assert.h>
+
+typedef  unsigned char           UChar;
+typedef  unsigned short int      UShort;
+typedef  unsigned int            UInt;
+typedef  signed int              Int;
+typedef  unsigned char           UChar;
+typedef  signed long long int    Long;
+typedef  unsigned long long int  ULong;
+
+typedef  unsigned char           Bool;
+#define False ((Bool)0)
+#define True  ((Bool)1)
+
+static inline UChar randUChar ( void )
+{
+   static UInt seed = 90210; // Somewhere in Beverly Hills, allegedly.
+   seed = 1103515245 * seed + 12345;
+   return (seed >> 17) & 0xFF;
+}
+
+static UInt randUInt ( void )
+{
+   Int i;
+   UInt r = 0;
+   for (i = 0; i < 4; i++) {
+      r = (r << 8) | (UInt)(0xFF & randUChar());
+   }
+   return r;
+}
+
+static void show_block_xor ( UChar* block1, UChar* block2, Int n )
+{
+   Int i;
+   printf("  ");
+   for (i = 0; i < n; i++) {
+      if (i > 0 && 0 == (i & 15)) printf("\n  ");
+      if (0 == (i & 15)) printf("[%3d]  ", i);
+      UInt diff = 0xFF & (UInt)(block1[i] - block2[i]);
+      if (diff == 0)
+         printf(".. ");
+      else
+         printf("%02x ", diff);
+   }
+   printf("\n");
+}
+
+
+// INSN may mention the following regs as containing load/store data:
+//      r2 r3 r6 r9
+// INSN must mention the following reg as containing the EA: r10
+//
+// INSN can use r4 and r5 as scratch
+//
+// In: rand: memory area (128 bytes), r2, r3, r6, r9
+//       r10 pointing to middle of memory area
+//
+// Out: memory area, r2, r3, r6, r9, r10
+//
+// What is printed out: the XOR of the new and old versions of the
+// following:
+//    the memory area
+//    r2, r3 r6 r9 r10
+
+#define MEM_TEST(INSN) { \
+  int i; \
+  const int N = 128; \
+  UChar* area1 = memalign16(N); \
+  UChar* area2 = memalign16(N); \
+  for (i = 0; i < N; i++) area1[i] = area2[i] = randUChar(); \
+  UInt block1[5]; \
+  UInt block2[5]; \
+  /* 0:r2    1:r3    2:r6    3:r9    4:r10 */ \
+  for (i = 0; i < 5; i++) block1[i] = block2[i] = randUInt(); \
+  block1[4] = block2[4] = (UInt)(&area1[N/2]); \
+  __asm__ __volatile__( \
+    "ldr r2,  [%0, #0]  ; " \
+    "ldr r3,  [%0, #4]  ; " \
+    "ldr r6,  [%0, #8]  ; " \
+    "ldr r9,  [%0, #12] ; " \
+    "ldr r10, [%0, #16] ; " \
+    INSN " ; " \
+    "str r2,  [%0, #0]  ; " \
+    "str r3,  [%0, #4]  ; " \
+    "str r6,  [%0, #8]  ; " \
+    "str r9,  [%0, #12] ; " \
+    "str r10, [%0, #16] ; " \
+    : : "r"(&block1[0]) : "r2", "r3", "r4", "r5", "r6", "r9", "r10", \
+        "memory", "cc" \
+  ); \
+  printf("%s  with  r10 = middle_of_block\n", INSN); \
+  show_block_xor(&area1[0], &area2[0], N); \
+  printf("  %08x  r2  (xor, data intreg #1)\n", block1[0] ^ block2[0]); \
+  printf("  %08x  r3  (xor, data intreg #2)\n", block1[1] ^ block2[1]); \
+  printf("  %08x  r6  (xor, data intreg #3)\n", block1[2] ^ block2[2]); \
+  printf("  %08x  r9  (xor, data intreg #4)\n", block1[3] ^ block2[3]); \
+  printf("  %08x  r10 (xor, addr intreg #1)\n", block1[4] ^ block2[4]); \
+  printf("\n"); \
+  free(area1); free(area2); \
+  }
+
+
+int main ( void )
+{
+   ////////////////////////////////////////////////////////////////
+   printf("LDA{,B,H} (reg)\n\n");
+   MEM_TEST("lda  r6, [r10]")
+   MEM_TEST("ldab r9, [r10]")
+   MEM_TEST("ldah r3, [r10]")
+
+   ////////////////////////////////////////////////////////////////
+   printf("STL{,B,H} (reg)\n\n");
+   MEM_TEST("stl  r6, [r10]")
+   MEM_TEST("stlb r9, [r10]")
+   MEM_TEST("stlh r3, [r10]")
+#if 0
+   ////////////////////////////////////////////////////////////////
+   printf("LDAEX{,B,H,D} (reg)\n\n");
+   MEM_TEST("ldaex  r6, [r10]")
+   MEM_TEST("ldaexb r9, [r10]")
+   MEM_TEST("ldaexh r3, [r10]")
+   MEM_TEST("ldaexd r2, r3, [r10]")
+
+   ////////////////////////////////////////////////////////////////
+   printf("STLEX{,B,H,D} (reg) -- expected to fail\n\n");
+   MEM_TEST("clrex; stlex  r9, r6, [r10]")
+   MEM_TEST("clrex; stlexb r9, r6, [r10]")
+   MEM_TEST("clrex; stlexh r9, r3, [r10]")
+   MEM_TEST("clrex; stlexd r9, r2, r3, [r10]")
+
+   ////////////////////////////////////////////////////////////////
+   printf("STLEX{,B,H,D} (reg) -- expected to succeed\n\n");
+   MEM_TEST("ldrex  r2, [r10] ; stlex  r9, r6, [r10]")
+   MEM_TEST("ldrexb r2, [r10] ; stlexb r9, r6, [r10]")
+   MEM_TEST("ldrexh r2, [r10] ; stlexh r9, r3, [r10]")
+   MEM_TEST("mov r4, r2 ; mov r5, r3 ; " // preserve r2/r3 around the ldrexd
+            "ldrexd r2, r3, [r10] ; "
+            "mov r2, r4 ; mov r3, r5 ; "
+            "stlexd r9, r2, r3, [r10]")
+#endif
+   return 0;
+}