This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] MIPS/gas: Always treat "dla" and "la" as macros


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	},


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]