This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: SH @(expr,pc) fix-ups broken
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: Hans-Peter Nilsson <hp at bitrange dot com>
- Cc: <binutils at sources dot redhat dot com>, dj at redhat dot com
- Date: 01 Feb 2002 23:39:02 -0200
- Subject: Re: SH @(expr,pc) fix-ups broken
- Organization: GCC Team, Red Hat
- References: <Pine.BSF.4.30.0201312006430.1774-100000@dair.pair.com><ork7tx1nnj.fsf@livre.redhat.lsd.ic.unicamp.br>
On Feb 1, 2002, Alexandre Oliva <aoliva@redhat.com> wrote:
>>> IMO, the `-4' should be taken out
>> Yeah. But I suggest you doublecheck with Joern.
> I wonder if he still reads this list. Well, I'll see if I can get him
> to have a look into it.
I still haven't got a reply from Jörn, but I managed to extract a
confession from DJ :-) He had apparently misunderstood some piece of
doc on which he based his patch, and the implementation had made the
same mistake or so. Here's a patch that implements the idea I had
delineated earlier. Tested on athlon-pc-linux-gnu-x-sh-elf. Ok to
install?
Index: opcodes/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* sh-opc.h (sh_arg_type): Added A_DISP_PC_ABS.
Index: opcodes/sh-opc.h
===================================================================
RCS file: /cvs/src/src/opcodes/sh-opc.h,v
retrieving revision 1.12
diff -u -p -r1.12 sh-opc.h
--- opcodes/sh-opc.h 2001/10/09 12:25:22 1.12
+++ opcodes/sh-opc.h 2002/02/02 01:35:15
@@ -76,6 +76,7 @@ typedef enum {
A_DISP_GBR,
A_PC,
A_DISP_PC,
+ A_DISP_PC_ABS,
A_DISP_REG_M,
A_DISP_REG_N,
A_GBR,
Index: gas/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* config/tc-sh.c (parse_at): Set arg type of @(expr,pc) to
A_DISP_PC only if it's an integral constant, and to
A_DISP_PC_ABS otherwise.
(get_specific): Accept A_DISP_PC_ABS where A_DISP_PC is
expected.
(build_Mytes): Mark PCRELIMM fix-ups as pc-relative only if
the operand type is not A_DISP_PC_ABS.
Index: gas/testsuite/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* gas/testsuite/gas/sh/pcrel.d: New test.
* gas/testsuite/gas/sh/pcrel.s: Sources for new test.
* gas/testsuite/gas/sh/basic.exp: Run it.
Index: gas/config/tc-sh.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-sh.c,v
retrieving revision 1.53
diff -u -p -r1.53 tc-sh.c
--- gas/config/tc-sh.c 2002/01/30 18:25:30 1.53
+++ gas/config/tc-sh.c 2002/02/02 01:35:20
@@ -981,13 +981,10 @@ parse_at (src, op)
}
else if (mode == A_PC)
{
- /* Turn a plain @(4,pc) into @(.+4,pc). */
- if (op->immediate.X_op == O_constant)
- {
- op->immediate.X_add_symbol = dot();
- op->immediate.X_op = O_symbol;
- }
- op->type = A_DISP_PC;
+ op->type = A_DISP_PC_ABS;
+ /* Such operands don't get corrected for PC==.+4, so
+ make the correction here. */
+ op->immediate.X_add_number -= 4;
}
else
{
@@ -1169,11 +1166,14 @@ get_specific (opcode, operands)
switch (arg)
{
+ case A_DISP_PC:
+ if (user->type == A_DISP_PC_ABS)
+ break;
+ /* Fall through. */
case A_IMM:
case A_BDISP12:
case A_BDISP8:
case A_DISP_GBR:
- case A_DISP_PC:
case A_MACH:
case A_PR:
case A_MACL:
@@ -1603,10 +1603,12 @@ build_Mytes (opcode, operand)
insert (output + low_byte, BFD_RELOC_SH_IMM8, 0, operand + 1);
break;
case PCRELIMM_8BY4:
- insert (output, BFD_RELOC_SH_PCRELIMM8BY4, 1, operand);
+ insert (output, BFD_RELOC_SH_PCRELIMM8BY4,
+ operand->type != A_DISP_PC_ABS, operand);
break;
case PCRELIMM_8BY2:
- insert (output, BFD_RELOC_SH_PCRELIMM8BY2, 1, operand);
+ insert (output, BFD_RELOC_SH_PCRELIMM8BY2,
+ operand->type != A_DISP_PC_ABS, operand);
break;
case REPEAT:
output = insert_loop_bounds (output, operand);
Index: gas/testsuite/gas/sh/basic.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/sh/basic.exp,v
retrieving revision 1.3
diff -u -p -r1.3 basic.exp
--- gas/testsuite/gas/sh/basic.exp 2001/11/02 17:07:52 1.3
+++ gas/testsuite/gas/sh/basic.exp 2002/02/02 01:35:20
@@ -1,4 +1,4 @@
-# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+# Copyright (C) 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -90,4 +90,6 @@ if [istarget sh*-*-*] then {
do_fp
# Test DSP instructions
run_dump_test "dsp"
+
+ run_dump_test "pcrel"
}
Index: gas/testsuite/gas/sh/pcrel.d
===================================================================
RCS file: pcrel.d
diff -N pcrel.d
--- /dev/null Tue May 5 13:32:27 1998
+++ gas/testsuite/gas/sh/pcrel.d Fri Feb 1 17:35:20 2002
@@ -0,0 +1,21 @@
+#as: -big
+#objdump: -d
+#name: PC-relative loads
+
+.*: file format .*sh.*
+
+Disassembly of section .text:
+
+00000000 <code>:
+ 0: d1 03 mov\.l 10 <litpool>,r1 ! 0xfffffff0
+ 2: d1 03 mov\.l 10 <litpool>,r1 ! 0xfffffff0
+ 4: c7 02 mova 10 <litpool>,r0
+ 6: 61 02 mov\.l @r0,r1
+ 8: d1 01 mov\.l 10 <litpool>,r1 ! 0xfffffff0
+ a: 01 03 bsrf r1
+ c: 00 09 nop
+ e: 00 09 nop
+
+00000010 <litpool>:
+ 10: ff ff \.word 0xffff
+ 12: ff f0 \.word 0xfff0
Index: gas/testsuite/gas/sh/pcrel.s
===================================================================
RCS file: pcrel.s
diff -N pcrel.s
--- /dev/null Tue May 5 13:32:27 1998
+++ gas/testsuite/gas/sh/pcrel.s Fri Feb 1 17:35:20 2002
@@ -0,0 +1,14 @@
+ .text
+
+ .p2align 2
+code:
+ mov.l litpool, r1
+ mov.l @(14,pc), r1
+ mova @(litpool-.,pc), r0
+ mov.l @r0,r1
+ mov.l @(litpool-.,pc), r1
+ bsrf r1
+ nop
+ nop
+litpool:
+ .long code - .
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist Professional serial bug killer