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