This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[patch] MIPS/gas: Always treat "dla" and "la" as macros
- From: "Maciej W. Rozycki" <macro at ds2 dot pg dot gda dot pl>
- To: binutils at sources dot redhat dot com
- Date: Thu, 8 Aug 2002 18:51:31 +0200 (MET DST)
- Subject: [patch] MIPS/gas: Always treat "dla" and "la" as macros
- Organization: Technical University of Gdansk
- Reply-to: "Maciej W. Rozycki" <macro at ds2 dot pg dot gda dot pl>
Hello,
The "dla" and "la" keywords are usually treated as macros. As part of
their expansion there is a consistency check performed and under certain
conditions a warning is emitted and the generated code adjusted
appropriately if using the default expansion for these macros would lead
to an address being cropped. There is a single exception for these
keywords. If their source operand can be expressed as a valid machine
code address expression (i.e. a register base plus a 16-bit signed
immediate offset) these keywords are treated as aliases for the "daddiu"
and "addiu" instructions and do not undergo the usual macro handling. As
a result address size mismatches do not get reported.
E.g.:
$ cat dla.s
la $2, label
la $3, -256($2)
$ mips64el-linux-as -64 -o dla.o dla.s
dla.s: Assembler messages:
dla.s:1: Warning: la used to load 64-bit address
$ mips64el-linux-objdump -Sr dla.o
dla.o: file format elf64-tradlittlemips
Disassembly of section .text:
0000000000000000 <.text>:
0: 3c020000 lui v0,0x0
0: R_MIPS_HIGHEST label
4: 3c010000 lui at,0x0
4: R_MIPS_HI16 label
8: 64420000 daddiu v0,v0,0
8: R_MIPS_HIGHER label
c: 64210000 daddiu at,at,0
c: R_MIPS_LO16 label
10: 0002103c dsll32 v0,v0,0x0
14: 0041102c daddu v0,v0,at
18: 2443ff00 addiu v1,v0,-256
1c: 00000000 nop
As a result, $3 doesn't always contain $3 - 256; as a matter of fact, MIPS
defines the result of an "addiu" performed on a register that does not
contain a proper sign-extended 32-bit value as unpredictable (similarly to
most 32-bit operations).
Following is a patch that removes the special case. With it applied, I
get:
$ mips64el-linux-as -64 -o dla.o dla.s
dla.s: Assembler messages:
dla.s:1: Warning: la used to load 64-bit address
dla.s:2: Warning: la used to load 64-bit address
$ mips64el-linux-objdump -Sr dla.o
dla.o: file format elf64-tradlittlemips
Disassembly of section .text:
0000000000000000 <.text>:
0: 3c020000 lui v0,0x0
0: R_MIPS_HIGHEST label
4: 3c010000 lui at,0x0
4: R_MIPS_HI16 label
8: 64420000 daddiu v0,v0,0
8: R_MIPS_HIGHER label
c: 64210000 daddiu at,at,0
c: R_MIPS_LO16 label
10: 0002103c dsll32 v0,v0,0x0
14: 0041102c dadd v0,v0,at
18: 6443ff00 daddiu v1,v0,-256
1c: 00000000 nop
gas:
2002-08-08 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
* config/tc-mips.c (macro): Handle a register plus a 16-bit
immediate offset in "dla" and "la" expansions.
gas/testsuite:
2002-08-08 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
* gas/mips/empic.d: Treat "addiu" and "daddiu" as equivalent when
$0 is source.
opcodes:
2002-08-08 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
* mips-opc.c (mips_builtin_opcodes): Remove "dla" and "la" as
aliases to "daddiu" and "addiu".
No other test failures and no gcc problems (with ~2.95.4) as it selects
between "dla" and "la" as appropriate. Since I consider it a bug fix, I'd
like to see it in 2.13.1 as well. OK to apply?
Maciej
--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +
binutils-2.12.91-20020805-mips-dla_la-macro
diff -up --recursive --new-file binutils-2.12.91-20020805.macro/gas/config/tc-mips.c binutils-2.12.91-20020805/gas/config/tc-mips.c
--- binutils-2.12.91-20020805.macro/gas/config/tc-mips.c 2002-08-03 01:25:28.000000000 +0000
+++ binutils-2.12.91-20020805/gas/config/tc-mips.c 2002-08-05 19:47:30.000000000 +0000
@@ -4462,6 +4462,16 @@ macro (ip)
if (! dbl && HAVE_64BIT_OBJECTS)
as_warn (_("la used to load 64-bit address"));
+ if (offset_expr.X_op == O_constant
+ && offset_expr.X_add_number >= -0x8000
+ && offset_expr.X_add_number < 0x8000)
+ {
+ macro_build ((char *) NULL, &icnt, &offset_expr,
+ (dbl || HAVE_64BIT_ADDRESSES) ? "daddiu" : "addiu",
+ "t,r,j", treg, sreg, (int) BFD_RELOC_LO16);
+ return;
+ }
+
if (treg == breg)
{
tempreg = AT;
diff -up --recursive --new-file binutils-2.12.91-20020805.macro/gas/testsuite/gas/mips/empic.d binutils-2.12.91-20020805/gas/testsuite/gas/mips/empic.d
--- binutils-2.12.91-20020805.macro/gas/testsuite/gas/mips/empic.d 2002-04-22 21:14:41.000000000 +0000
+++ binutils-2.12.91-20020805/gas/testsuite/gas/mips/empic.d 2002-08-05 19:35:10.000000000 +0000
@@ -118,7 +118,7 @@ Contents of section \.text:
0010 00000000 1000ffff 00000000 0411003f .*
0020 00000000 04110000 00000000 10000041 .*
0030 00000000 10000000 00000000 3c030000 .*
- 0040 [26]463000c 3c030000 [26]4630114 2403ffd0 .*
+ 0040 [26]463000c 3c030000 [26]4630114 [26]403ffd0 .*
0050 00000000 00000100 00000004 00000028 .*
0060 0000012c ffffffd0 00000000 00000000 .*
0070 00000000 00000100 00000000 00000004 .*
diff -up --recursive --new-file binutils-2.12.91-20020805.macro/opcodes/mips-opc.c binutils-2.12.91-20020805/opcodes/mips-opc.c
--- binutils-2.12.91-20020805.macro/opcodes/mips-opc.c 2002-07-09 14:21:40.000000000 +0000
+++ binutils-2.12.91-20020805/opcodes/mips-opc.c 2002-08-04 22:00:09.000000000 +0000
@@ -480,7 +480,6 @@ const struct mips_opcode mips_builtin_op
{"divu", "z,t", 0x0000001b, 0xffe0ffff, RD_s|RD_t|WR_HILO, I1 },
{"divu", "d,v,t", 0, (int) M_DIVU_3, INSN_MACRO, I1 },
{"divu", "d,v,I", 0, (int) M_DIVU_3I, INSN_MACRO, I1 },
-{"dla", "t,o(b)", 0x64000000, 0xfc000000, WR_t|RD_s, I3 }, /* daddiu */
{"dla", "t,A(b)", 0, (int) M_DLA_AB, INSN_MACRO, I3 },
{"dli", "t,j", 0x24000000, 0xffe00000, WR_t, I3 }, /* addiu */
{"dli", "t,i", 0x34000000, 0xffe00000, WR_t, I3 }, /* ori */
@@ -572,7 +571,6 @@ const struct mips_opcode mips_builtin_op
will match first). */
{"jal", "a", 0x0c000000, 0xfc000000, UBD|WR_31, I1 },
{"jalx", "a", 0x74000000, 0xfc000000, UBD|WR_31, I16 },
-{"la", "t,o(b)", 0x24000000, 0xfc000000, WR_t|RD_s, I1 }, /* addiu */
{"la", "t,A(b)", 0, (int) M_LA_AB, INSN_MACRO, I1 },
{"lb", "t,o(b)", 0x80000000, 0xfc000000, LDD|RD_b|WR_t, I1 },
{"lb", "t,A(b)", 0, (int) M_LB_AB, INSN_MACRO, I1 },