RX: Incorrect output for displacement of subtruct expression
Commit Message
Assembling the following code results in incorrect displacement values:
1: mov.L 2f-1b[r0],r0
If you write a subtraction formula in the displacement field, the value
will simply be the result of the subtraction, which will not be the
expected value for word and longword sizes.
gas/
* config/rx-parse.y (displacement): use BFD_RELOC_RX_GPREL in subtract expression.
* testsuite/gas/rx/mov.sm: Add subtruct expression displacement.
* testsuite/gas/rx/mov.d: Likewise.
Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
gas/config/rx-parse.y | 35 ++++++++++++-----------------------
gas/testsuite/gas/rx/mov.d | 3 +++
gas/testsuite/gas/rx/mov.sm | 7 +++++++
3 files changed, 22 insertions(+), 23 deletions(-)
Comments
On Thu, 2024-12-26 at 12:53 +0900, Yoshinori Sato wrote:
> Assembling the following code results in incorrect displacement values:
> 1: mov.L 2f-1b[r0],r0
>
> If you write a subtraction formula in the displacement field, the value
> will simply be the result of the subtraction, which will not be the
> expected value for word and longword sizes.
>
> gas/
> * config/rx-parse.y (displacement): use BFD_RELOC_RX_GPREL in subtract expression.
> * testsuite/gas/rx/mov.sm: Add subtruct expression displacement.
> * testsuite/gas/rx/mov.d: Likewise.
>
Hi!
Wow .. how did you find this bug? I'm curious because I've been using an RX
system with GCC 8 and older binutils for several years.
Thanks for posting the patch!
Best regards,
Oleg Endo
On Thu, 26 Dec 2024 16:53:59 +0900,
Oleg Endo wrote:
>
>
> On Thu, 2024-12-26 at 12:53 +0900, Yoshinori Sato wrote:
> > Assembling the following code results in incorrect displacement values:
> > 1: mov.L 2f-1b[r0],r0
> >
> > If you write a subtraction formula in the displacement field, the value
> > will simply be the result of the subtraction, which will not be the
> > expected value for word and longword sizes.
> >
> > gas/
> > * config/rx-parse.y (displacement): use BFD_RELOC_RX_GPREL in subtract expression.
> > * testsuite/gas/rx/mov.sm: Add subtruct expression displacement.
> > * testsuite/gas/rx/mov.d: Likewise.
> >
>
> Hi!
>
> Wow .. how did you find this bug? I'm curious because I've been using an RX
> system with GCC 8 and older binutils for several years.
I am trying to get FDPIC support in RX.
gcc, which supports this FDPIC, generated the following code for a switch
statement:
1: mvfc pc, r3
shll #2, r14
add r3, r14
mov.L .L282 - 1b[r14], r14
1: bra r14
.balign 4
.L282:
.long .L284 - 1b
.long .L280 - 1b
.long .L280 - 1b
I investigated why this code wasn't working as expected and discovered that it
was due to this bug.
This kind of code is not output by the release version of gcc, and even when
written in assembler, it is not written in this way, so I don't think anyone
noticed the bug.
> Thanks for posting the patch!
>
> Best regards,
> Oleg Endo
>
On Fri, 2024-12-27 at 23:11 +0900, Yoshinori Sato wrote:
>
> I am trying to get FDPIC support in RX.
> gcc, which supports this FDPIC, generated the following code for a switch
> statement:
>
> 1: mvfc pc, r3
> shll #2, r14
> add r3, r14
> mov.L .L282 - 1b[r14], r14
>
> 1: bra r14
> .balign 4
> .L282:
> .long .L284 - 1b
> .long .L280 - 1b
> .long .L280 - 1b
>
> I investigated why this code wasn't working as expected and discovered that it
> was due to this bug.
> This kind of code is not output by the release version of gcc, and even when
> written in assembler, it is not written in this way, so I don't think anyone
> noticed the bug.
Very nice detective work. Thanks!
Best regards,
Oleg Endo
@@ -1934,32 +1934,21 @@ displacement (expressionS exp, int msize)
valueT val;
int vshift = 0;
- if (exp.X_op == O_symbol
- && exp.X_md)
+ if ((exp.X_op == O_symbol && exp.X_md == BFD_RELOC_GPREL16) ||
+ (exp.X_op == O_subtract))
{
- switch (exp.X_md)
+ switch (msize)
{
- case BFD_RELOC_GPREL16:
- switch (msize)
- {
- case BSIZE:
- exp.X_md = BFD_RELOC_RX_GPRELB;
- break;
- case WSIZE:
- exp.X_md = BFD_RELOC_RX_GPRELW;
- break;
- case LSIZE:
- exp.X_md = BFD_RELOC_RX_GPRELL;
- break;
- }
- O2 (exp);
- return 2;
+ case BSIZE:
+ exp.X_md = BFD_RELOC_RX_GPRELB;
+ break;
+ case WSIZE:
+ exp.X_md = BFD_RELOC_RX_GPRELW;
+ break;
+ case LSIZE:
+ exp.X_md = BFD_RELOC_RX_GPRELL;
+ break;
}
- }
-
- if (exp.X_op == O_subtract)
- {
- exp.X_md = BFD_RELOC_RX_DIFF;
O2 (exp);
return 2;
}
@@ -528,3 +528,6 @@ Disassembly of section .*:
[0-9a-f]+: fd 2e 0f mov.l \[-r0\], r15
[0-9a-f]+: fd 2e f0 mov.l \[-r15\], r0
[0-9a-f]+: fd 2e ff mov.l \[-r15\], r15
+ [0-9a-f]+: ce 00 04 00 mov.b 4\[r0\], r0
+ [0-9a-f]+: de 00 02 00 mov.w 4\[r0\], r0
+ [0-9a-f]+: ee 00 01 00 mov.l 4\[r0\], r0
@@ -31,3 +31,10 @@
mov{bwl} [{reg}+],{reg}
mov{bwl} {reg},[-{reg}]
mov{bwl} [-{reg}],{reg}
+
+1: mov.B 2f - 1b[r0], r0
+2:
+1: mov.W 2f - 1b[r0], r0
+2:
+1: mov.L 2f - 1b[r0], r0
+2: