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. Currently they incorrectly offset the address by 3 and 4 bytes respectively.
Committed the attached patch as obvious.
From 14f27ee6c97c585018882ac8f1f5f2d64618ba66 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz <joze...@mittosystems.com> Date: Mon, 13 Apr 2020 10:28:01 +0100 Subject: [PATCH] MSP430: Fix memory offsets used by %C and %D asm output operand modifiers 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 <joze...@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 <joze...@mittosystems.com> * gcc.target/msp430/operand-modifiers.c: New test. --- gcc/ChangeLog | 5 ++++ gcc/config/msp430/msp430.c | 4 +-- gcc/testsuite/ChangeLog | 4 +++ .../gcc.target/msp430/operand-modifiers.c | 30 +++++++++++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/msp430/operand-modifiers.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f3a226cc711..c0ac32dccf6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2020-04-13 Jozef Lawrynowicz <joze...@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 <ubiz...@gmail.com> PR target/94494 diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index e0d2d732ade..96532740ac1 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1343b8bec06..b1f232ec0e6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2020-04-13 Jozef Lawrynowicz <joze...@mittosystems.com> + + * gcc.target/msp430/operand-modifiers.c: New test. + 2020-04-12 Thomas Koenig <tkoe...@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 index 00000000000..ad0a5310839 --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/operand-modifiers.c @@ -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; +} -- 2.17.1