This is the mail archive of the
mailing list for the binutils project.
[patch] MIPS64: A 32-bit address range fix
- From: "Maciej W. Rozycki" <macro at ds2 dot pg dot gda dot pl>
- To: binutils at sources dot redhat dot com
- Date: Thu, 4 Jul 2002 16:00:24 +0200 (MET DST)
- Subject: [patch] MIPS64: A 32-bit address range fix
- Organization: Technical University of Gdansk
There is an optimization in gas that generates only a single "lui" for
loading constant addresses for memory accesses that fit in the 32-bit
address range. For example:
ld $4, 0x12345678
lui $4, 0x1234
ld $4, 22136(a0)
There is a bug in the code: the address range is selected improperly.
For the following macro:
ld $4, 0x7fff8000
the following code is generated:
lui $4, 0x8000
ld $4, -32768(a0)
which is incorrect as it really implements:
ld $4, 0xffffffff7fff8000
The fix is to adjust the range so that bit 15 of the immediate used in
"lui" is the same as in the address to use. Here is an implementation.
2002-07-04 Maciej W. Rozycki <email@example.com>
* config/tc-mips.c (macro): Shift the 32-bit address range
accessible with a lone "lui" down by 32768.
OK to apply?
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+ e-mail: firstname.lastname@example.org, PGP key available +
diff -up --recursive --new-file binutils-2.12.90-20020702.macro/gas/config/tc-mips.c binutils-2.12.90-20020702/gas/config/tc-mips.c
--- binutils-2.12.90-20020702.macro/gas/config/tc-mips.c 2002-06-15 03:25:24.000000000 +0000
+++ binutils-2.12.90-20020702/gas/config/tc-mips.c 2002-07-02 21:35:55.000000000 +0000
@@ -5497,13 +5497,15 @@ macro (ip)
If we have 64-bit addresses, as an optimization, for
addresses which are 32-bit constants (e.g. kseg0/kseg1
addresses) we fall back to the 32-bit address generation
- mechanism since it is more efficient. This code should
+ mechanism since it is more efficient. Note that due to
+ the signed offset used by memory operations, the 32-bit
+ range is shifted down by 32768 here. This code should
probably attempt to generate 64-bit constants more
efficiently in general.
&& !(offset_expr.X_op == O_constant
- && IS_SEXT_32BIT_NUM (offset_expr.X_add_number)))
+ && IS_SEXT_32BIT_NUM (offset_expr.X_add_number + 0x8000)))
p = NULL;