Thumb encoding: add test cases for  misaligned loads of the form
   LD Rt, [Rn +/- #imm12]  when Rn == PC
See #333145.  (dimitry@google.com)



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13958 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/none/tests/arm/v6intThumb.c b/none/tests/arm/v6intThumb.c
index 1015e0d..668c415 100644
--- a/none/tests/arm/v6intThumb.c
+++ b/none/tests/arm/v6intThumb.c
@@ -5,7 +5,7 @@
 
 #include <stdio.h>
 
-static int gen_cvin(cvin)
+static int gen_cvin(int cvin)
 {
   int r = ((cvin & 2) ? (1<<29) : 0) | ((cvin & 1) ? (1<<28) : 0);
   r |= (1 << 31) | (1 << 30);
@@ -218,6 +218,120 @@
 		); \
 }
 
+// Tests misaligned access via PC+$#imm
+#define TESTINSTPCMISALIGNED(instruction, RD, label, cvin) \
+{ \
+    unsigned int out; \
+    unsigned int cpsr; \
+    __asm__ volatile(\
+    ".align 4;" \
+    "msr cpsr_f, %2;" \
+    "mov " #RD ", #0;" \
+    ".align 2;" \
+    ".thumb;" \
+    ".syntax unified;" \
+    "nop;" \
+    instruction ";" \
+    "b .Lend" #label ";" \
+    ".align 4;" \
+    #label ": " \
+    ".word 0x8191881b;" \
+    ".word 0x18fe9c93;" \
+    ".word 0x00000000;" \
+    ".word 0x00000000;" \
+    ".Lend" #label ":" \
+    "mov %0, " #RD ";" \
+	"mrs %1,cpsr;" \
+  : "=&r" (out), "=&r" (cpsr) \
+  : "r" (gen_cvin(cvin)) \
+  ); \
+  printf("%s :: rd 0x%08x, cpsr 0x%08x %c%c%c%c\n", \
+        instruction, out, \
+		cpsr & 0xffff0000, \
+		((1<<31) & cpsr) ? 'N' : ' ', \
+		((1<<30) & cpsr) ? 'Z' : ' ', \
+		((1<<29) & cpsr) ? 'C' : ' ', \
+		((1<<28) & cpsr) ? 'V' : ' ' \
+		); \
+}
+
+// this one uses d0, s0 and s2 (hardcoded)
+#define TESTINSTPCMISALIGNED_DWORDOUT(instruction, label, cvin) \
+{ \
+    unsigned int out; \
+    unsigned int out2; \
+    unsigned int cpsr; \
+    __asm__ volatile(\
+    ".align 4;" \
+    "msr cpsr_f, %3;" \
+    ".align 2;" \
+    ".thumb;" \
+    ".syntax unified;" \
+    "nop;" \
+    instruction ";" \
+    "b .Lend" #label ";" \
+    ".align 4;" \
+    #label ": " \
+    ".word 0x8191881b;" \
+    ".word 0x18fe9c93;" \
+    ".word 0x00000000;" \
+    ".word 0x00000000;" \
+    ".Lend" #label ":" \
+    "vmov %0, s0;" \
+    "vmov %1, s1;" \
+	"mrs %2,cpsr;" \
+  : "=&r" (out), "=&r" (out2), "=&r" (cpsr) \
+  : "r" (gen_cvin(cvin)) \
+  ); \
+  printf("%s :: s0 0x%08x s1 0x%08x, cpsr 0x%08x %c%c%c%c\n", \
+        instruction, out, out2, \
+		cpsr & 0xffff0000, \
+		((1<<31) & cpsr) ? 'N' : ' ', \
+		((1<<30) & cpsr) ? 'Z' : ' ', \
+		((1<<29) & cpsr) ? 'C' : ' ', \
+		((1<<28) & cpsr) ? 'V' : ' ' \
+		); \
+}
+
+#define TESTINSTPCMISALIGNED_2OUT(instruction, RD, RD2, label, cvin) \
+{ \
+    unsigned int out; \
+    unsigned int out2; \
+    unsigned int cpsr; \
+    __asm__ volatile(\
+    ".align 4;" \
+    "msr cpsr_f, %3;" \
+    "mov " #RD ", #0;" \
+    "mov " #RD2 ", #0;" \
+    ".align 2;" \
+    ".thumb;" \
+    ".syntax unified;" \
+    "nop;" \
+    instruction ";" \
+    "b .Lend" #label ";" \
+    ".align 4;" \
+    #label ": " \
+    ".word 0x8191881b;" \
+    ".word 0x18fe9c93;" \
+    ".word 0x00000000;" \
+    ".word 0x00000000;" \
+    ".Lend" #label ":" \
+    "mov %0, " #RD ";" \
+    "mov %1, " #RD2 ";" \
+	"mrs %2,cpsr;" \
+  : "=&r" (out), "=&r" (out2), "=&r" (cpsr) \
+  : "r" (gen_cvin(cvin)) \
+  ); \
+  printf("%s :: rd 0x%08x rd2 0x%08x, cpsr 0x%08x %c%c%c%c\n", \
+        instruction, out, out2, \
+		cpsr & 0xffff0000, \
+		((1<<31) & cpsr) ? 'N' : ' ', \
+		((1<<30) & cpsr) ? 'Z' : ' ', \
+		((1<<29) & cpsr) ? 'C' : ' ', \
+		((1<<28) & cpsr) ? 'V' : ' ' \
+		); \
+}
+
 /* helpers */
 #define NOCARRY { int cv = 0; {
 #define TESTCARRY { int cv = 0; for (cv = 0; cv < 4; cv++) {
@@ -457,6 +571,30 @@
 	TESTINST2("asrs r0, r1, #18", 0x00010000, r0, r1, cv);
 	TESTCARRYEND
 
+    printf("literal access [PC+#imm]\n");
+    NOCARRY
+    // this should result in r1=0
+    TESTINSTPCMISALIGNED("adr.w r1, label_magic_adrw; and r1, r1, #0x3",
+                        r1, label_magic_adrw, cv);
+    // omitting LDC/LDC2
+    TESTINSTPCMISALIGNED("ldr r1, label_magic_ldr",
+                         r1, label_magic_ldr, cv);
+    TESTINSTPCMISALIGNED("ldrb r1, label_magic_ldrb",
+                         r1, label_magic_ldrb, cv);
+    TESTINSTPCMISALIGNED_2OUT("ldrd r0, r1, label_magic_ldrd",
+                              r0, r1, label_magic_ldrd, cv);
+    TESTINSTPCMISALIGNED("ldrh r1, label_magic_ldrh",
+                         r1, label_magic_ldrh, cv);
+    TESTINSTPCMISALIGNED("ldrsb r1, label_magic_ldrsb",
+                         r1, label_magic_ldrsb, cv);
+    TESTINSTPCMISALIGNED("ldrsh r1, label_magic_ldrsh",
+                         r1, label_magic_ldrsh, cv);
+    // omitting PLD/PLI
+    TESTINSTPCMISALIGNED_DWORDOUT("vldr d0, label_magic_vldr",
+                                  label_magic_vldr, cv);
+
+    TESTCARRYEND
+
 #if 0
 	printf("ROR\n");
 	TESTCARRY
diff --git a/none/tests/arm/v6intThumb.stdout.exp b/none/tests/arm/v6intThumb.stdout.exp
index 306176b..52404cf 100644
--- a/none/tests/arm/v6intThumb.stdout.exp
+++ b/none/tests/arm/v6intThumb.stdout.exp
@@ -17307,6 +17307,15 @@
 asrs r0, r1, #16 :: rd 0x00000001 rm 0x00010000, c:v-in 3, cpsr 0x10000000    V
 asrs r0, r1, #17 :: rd 0x00000000 rm 0x00010000, c:v-in 3, cpsr 0x70000000  ZCV
 asrs r0, r1, #18 :: rd 0x00000000 rm 0x00010000, c:v-in 3, cpsr 0x50000000  Z V
+literal access [PC+#imm]
+adr.w r1, label_magic_adrw; and r1, r1, #0x3 :: rd 0x00000000, cpsr 0xc0000000 NZ  
+ldr r1, label_magic_ldr :: rd 0x8191881b, cpsr 0xc0000000 NZ  
+ldrb r1, label_magic_ldrb :: rd 0x0000001b, cpsr 0xc0000000 NZ  
+ldrd r0, r1, label_magic_ldrd :: rd 0x8191881b rd2 0x18fe9c93, cpsr 0xc0000000 NZ  
+ldrh r1, label_magic_ldrh :: rd 0x0000881b, cpsr 0xc0000000 NZ  
+ldrsb r1, label_magic_ldrsb :: rd 0x0000001b, cpsr 0xc0000000 NZ  
+ldrsh r1, label_magic_ldrsh :: rd 0xffff881b, cpsr 0xc0000000 NZ  
+vldr d0, label_magic_vldr :: s0 0x8191881b s1 0x18fe9c93, cpsr 0xc0000000 NZ  
 MUL
 mul  r0, r1, r2 :: rd 0x00000000 rm 0x00000000, rn 0x00000000, c:v-in 0, cpsr 0xc0000000 NZ  
 mul  r0, r1, r2 :: rd 0x00000000 rm 0xffffffff, rn 0x00000000, c:v-in 0, cpsr 0xc0000000 NZ