MSP430: Fix memory offsets used by %C and %D asm output operand modifiers
authorJozef Lawrynowicz <jozef.l@mittosystems.com>
Mon, 13 Apr 2020 09:28:01 +0000 (10:28 +0100)
committerJozef Lawrynowicz <jozef.l@mittosystems.com>
Mon, 13 Apr 2020 09:47:26 +0000 (10:47 +0100)
The %C and %D operand modifiers are supposed to access the 3rd and 4th
words of a 64-bit value, so for memory references they need to offset
the given address by 4 and 6 bytes respectively.

gcc/ChangeLog:

2020-04-13  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

* config/msp430/msp430.c (msp430_print_operand): Offset a %C memory
reference by 4 bytes, and %D memory reference by 6 bytes.

gcc/testsuite/ChangeLog:

2020-04-13  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

* gcc.target/msp430/operand-modifiers.c: New test.

gcc/ChangeLog
gcc/config/msp430/msp430.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/msp430/operand-modifiers.c [new file with mode: 0644]

index f3a226cc7119aded4dbe70f76de84ad7c87afe3c..c0ac32dccf6e11c7994d08272ddd509f492bfdc3 100644 (file)
@@ -1,3 +1,8 @@
+2020-04-13  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
+
+       * config/msp430/msp430.c (msp430_print_operand): Offset a %C memory
+       reference by 4 bytes, and %D memory reference by 6 bytes.
+
 2020-04-11  Uroš Bizjak  <ubizjak@gmail.com>
 
        PR target/94494
index e0d2d732adee466da7198af282831da950c41306..96532740ac15b031a1e42799f0b67396f1be83c0 100644 (file)
@@ -3492,7 +3492,7 @@ msp430_print_operand (FILE * file, rtx op, int letter)
       switch (GET_CODE (op))
        {
        case MEM:
-         op = adjust_address (op, Pmode, 3);
+         op = adjust_address (op, Pmode, 4);
          break;
        case REG:
          op = gen_rtx_REG (Pmode, REGNO (op) + 2);
@@ -3510,7 +3510,7 @@ msp430_print_operand (FILE * file, rtx op, int letter)
       switch (GET_CODE (op))
        {
        case MEM:
-         op = adjust_address (op, Pmode, 4);
+         op = adjust_address (op, Pmode, 6);
          break;
        case REG:
          op = gen_rtx_REG (Pmode, REGNO (op) + 3);
index 1343b8bec0672406ac159da9ab65b00f35456512..b1f232ec0e623556d10d1ea21f85053ee6bf959e 100644 (file)
@@ -1,3 +1,7 @@
+2020-04-13  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
+
+       * gcc.target/msp430/operand-modifiers.c: New test.
+
 2020-04-12  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/94091
diff --git a/gcc/testsuite/gcc.target/msp430/operand-modifiers.c b/gcc/testsuite/gcc.target/msp430/operand-modifiers.c
new file mode 100644 (file)
index 0000000..ad0a531
--- /dev/null
@@ -0,0 +1,30 @@
+volatile unsigned long si = 0x89abcdef;
+volatile unsigned long long di = 0xfedcba9876543210;
+
+unsigned int a, b, c, d;
+
+int
+main (void)
+{
+  /* Check that %A and %B extract the low and high words of a 32-bit value,
+     respectively.  */
+  __asm__("mov %A1, %0\n" : "=m" (a) : "m" (si));
+  __asm__("mov %B1, %0\n" : "=m" (b) : "m" (si));
+  if (a != ((unsigned)si)
+      || b != ((unsigned)(si >> 16)))
+    return 1;
+
+  /* Check that %A, %B, %C and %D extract the 1st, 2nd, 3rd and 4th words of a
+     64-bit value, respectively.  */
+  __asm__("mov %A1, %0\n" : "=m" (a) : "m" (di));
+  __asm__("mov %B1, %0\n" : "=m" (b) : "m" (di));
+  __asm__("mov %C1, %0\n" : "=m" (c) : "m" (di));
+  __asm__("mov %D1, %0\n" : "=m" (d) : "m" (di));
+  if (a != ((unsigned)di)
+      || b != ((unsigned)(di >> 16))
+      || c != ((unsigned)(di >> 32))
+      || d != ((unsigned)(di >> 48)))
+    return 1;
+
+  return 0;
+}