Thumb encoding: add test case for assertion failure caused by
"ldr.w pc, [reg, #imm]".  See #333428.  (dimitry@google.com)



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13959 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/none/tests/arm/v6intThumb.c b/none/tests/arm/v6intThumb.c
index 668c415..811bbb3 100644
--- a/none/tests/arm/v6intThumb.c
+++ b/none/tests/arm/v6intThumb.c
@@ -342,6 +342,57 @@
 ///////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////
 
+__attribute__((noinline))
+void test_ldr_pc(void) {
+    // special case of ldr PC, [rN, +imm?]
+    printf("tests for instructions modifying pc (ldr pc, add pc)\n");
+    {    
+        unsigned int out; 
+        unsigned int cpsr;
+        unsigned char tmpbuff[512]; // we use tmpbuff+432
+        int cvin = 0; 
+
+        __asm__ volatile(
+            ".thumb;\n"
+            ".syntax unified                  ;\n"
+            "msr  cpsr_f, %3                  ;\n"
+            "mov  r9, %2                      ;\n"
+            "movw r2, #:lower16:.ldrwpclabel1 ;\n"
+            "movt r2, #:upper16:.ldrwpclabel1 ;\n"
+            "mov  r0, #1                      ;\n"
+            "orr  r2, r0                      ;\n" // set thumb bit to 1
+            "str  r2, [r9, +#432]             ;\n"
+            "bl   .ldrwpclabel_continue       ;\n"
+            ".align 4                         ;\n"
+            ".ldrwpclabel1:                   \n"
+            "mov  r1, #42                     ;\n" // expected output value
+            "bl   .ldrwpclabel_end            ;\n"
+            ".ldrwpclabel_continue:           \n"
+            "ldr.w pc, [r9, +#432]            ;\n"
+            "mov  r1, #0                      ;\n" // should never get here
+            ".ldrwpclabel_end:                \n"
+            "mov  %0, r1                      ;\n"
+            "mrs  %1, cpsr                    ;\n"
+            : "=r"(out), "=r"(cpsr)
+            : "r"(tmpbuff), "r"(gen_cvin(cvin))
+            : "r9", "r2", "r0", "r1", "cc", "memory"
+        );
+
+        // print
+        printf("ldr.w pc, [r9, +#432] :: r1 0x%08x c:v-in %d, "
+               "cpsr 0x%08x %c%c%c%c\n",        \
+            out, \
+            cvin, \
+            cpsr & 0xffff0000, \
+            ((1<<31) & cpsr) ? 'N' : ' ', \
+            ((1<<30) & cpsr) ? 'Z' : ' ', \
+            ((1<<29) & cpsr) ? 'C' : ' ', \
+            ((1<<28) & cpsr) ? 'V' : ' ' \
+            ); \
+
+    }    
+}
+
 static int old_main(void)
 {
 
@@ -595,6 +646,7 @@
 
     TESTCARRYEND
 
+    test_ldr_pc();
 #if 0
 	printf("ROR\n");
 	TESTCARRY
diff --git a/none/tests/arm/v6intThumb.stdout.exp b/none/tests/arm/v6intThumb.stdout.exp
index 52404cf..9169f88 100644
--- a/none/tests/arm/v6intThumb.stdout.exp
+++ b/none/tests/arm/v6intThumb.stdout.exp
@@ -17316,6 +17316,8 @@
 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  
+tests for instructions modifying pc (ldr pc, add pc)
+ldr.w pc, [r9, +#432] :: r1 0x0000002a c:v-in 0, 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