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]

mips [PATCH RFA]: fix ulh, ulhu, ulw, and uld macro expansions.


The ulh, ulhu, ulw, and uld (M_ULH, M_ULHU, etc., not the _A versions)
macro expansions were broken in the case where source and destinations
registers were the same.  (This was noticed by a customer of ours.)

They'd actually work OK in the r3000 (load delay slot) case (somewhat
ironic for uld 8-), but would clobber the source reg before it was
used the second time if src and destination were the same register on
processors w/ GPR interlocks.

for M_ULH and M_ULU this was simple enough to fix.  (just switch which
reg is loaded first, $at or the destination.)

for M_ULW and M_ULD it's a little bit harder (if src == dest, must
load into $at then move).

The following are the patches which implement the changes, and some
more complete test cases of these macros (and the cases in which they
should issue "macro used $at" warnings).

This code and the modified ulh.d test works fine as of 2003-03-26
00:00GMT sources.  In current binutils sources many of the existing
MIPS tests that do load/store are broken ("eric knows already" 8-).
In the current binutils, the new tests are still fine, and the changed
sources work as expected, but the modified ulh.d test is broken
(because of the unrelated changes).


tested via make && make check of binutils, for mips-elf, mips-linux,
mipsisa64-elf, and mipsisa64el-elf.


chris
--
[ gas/ChangeLog ]
2003-03-31  Chris Demetriou  <cgd at broadcom dot com>

	* config/tc-mips.c (macro2): Adjust implementation of
	M_ULH, M_ULHU, M_ULW, and M_ULD so that they work properly
	in the case where the source and destination registers
	are the same.

[ gas/testsuite/ChangeLog ]
2003-03-31  Chris Demetriou  <cgd at broadcom dot com>

	* gas/mips/ulh.d: Adjust for ulh and ulhu macro assembly changes.

	* gas/mips/mips.exp: Define new "gpr_ilocks" architecture
	property, and add it to mips2 (and later) chips and r3900.
	* gas/mips/uld2.s: New test source file.
	* gas/mips/ulh2.s: Likewise.
	* gas/mips/ulw2.s: Likewise.
	* gas/mips/uld2.l: New test stderr listing.
	* gas/mips/ulh2.l: Likewise.
	* gas/mips/ulw2.l: Likewise.
	* gas/mips/uld2-eb.d: New test.
	* gas/mips/uld2-el.d: Likewise.
	* gas/mips/ulh2-eb.d: Likewise.
	* gas/mips/ulh2-el.d: Likewise.
	* gas/mips/ulw2-eb-ilocks.d: Likewise.
	* gas/mips/ulw2-eb.d: Likewise.
	* gas/mips/ulw2-el-ilocks.d: Likewise.
	* gas/mips/ulw2-el.d: Likewise.
	* gas/mips/mips.exp: Run new tests for appropriate architectures.


Index: config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.198
diff -u -p -r1.198 tc-mips.c
--- config/tc-mips.c	26 Mar 2003 23:32:06 -0000	1.198
+++ config/tc-mips.c	1 Apr 2003 01:34:50 -0000
@@ -7554,19 +7554,18 @@ macro2 (ip)
     ulh:
       if (offset_expr.X_add_number >= 0x7fff)
 	as_bad (_("operand overflow"));
-      /* avoid load delay */
       if (! target_big_endian)
 	++offset_expr.X_add_number;
-      macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,
+      macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", AT,
 		   (int) BFD_RELOC_LO16, breg);
       if (! target_big_endian)
 	--offset_expr.X_add_number;
       else
 	++offset_expr.X_add_number;
-      macro_build ((char *) NULL, &icnt, &offset_expr, "lbu", "t,o(b)", AT,
+      macro_build ((char *) NULL, &icnt, &offset_expr, "lbu", "t,o(b)", treg,
 		   (int) BFD_RELOC_LO16, breg);
       macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "sll", "d,w,<",
-		   treg, treg, 8);
+		   AT, AT, 8);
       macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "or", "d,v,t",
 		   treg, treg, AT);
       break;
@@ -7583,17 +7582,29 @@ macro2 (ip)
     ulw:
       if (offset_expr.X_add_number >= 0x8000 - off)
 	as_bad (_("operand overflow"));
+      if (treg != breg)
+	tempreg = treg;
+      else
+	tempreg = AT;
       if (! target_big_endian)
 	offset_expr.X_add_number += off;
-      macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,
+      macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", tempreg,
 		   (int) BFD_RELOC_LO16, breg);
       if (! target_big_endian)
 	offset_expr.X_add_number -= off;
       else
 	offset_expr.X_add_number += off;
-      macro_build ((char *) NULL, &icnt, &offset_expr, s2, "t,o(b)", treg,
+      macro_build ((char *) NULL, &icnt, &offset_expr, s2, "t,o(b)", tempreg,
 		   (int) BFD_RELOC_LO16, breg);
-      return;
+
+      /* If necessary, move the result in tempreg the final destination.  */
+      if (treg == tempreg)
+        return;
+      /* Protect second load's delay slot.  */
+      if (!gpr_interlocks)
+	macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");
+      move_register (&icnt, treg, tempreg);
+      break;
 
     case M_ULD_A:
       s = "ldl";
Index: testsuite/gas/mips/mips.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips.exp,v
retrieving revision 1.64
diff -u -p -r1.64 mips.exp
--- testsuite/gas/mips/mips.exp	12 Mar 2003 23:05:31 -0000	1.64
+++ testsuite/gas/mips/mips.exp	1 Apr 2003 01:34:50 -0000
@@ -55,6 +55,10 @@
 #		The architecture includes the instructions defined
 #		by that MIPS ISA.
 #
+#	gpr_ilocks
+#		The architecture interlocks GPRs accesses.  (That is,
+#		there are no load delay slots.)
+#
 #	mips3d	The architecture includes the MIPS-3D ASE.
 #
 #	ror	The architecture includes hardware rotate instructions.
@@ -332,7 +336,7 @@ proc run_list_test_arches { name opts ar
 # to any architecture.
 mips_arch_create mips1 	32	{}	{} \
 			{ -march=mips1 -mtune=mips1 } { -mmips:3000 }
-mips_arch_create mips2 	32	mips1	{} \
+mips_arch_create mips2 	32	mips1	{ gpr_ilocks } \
 		        { -march=mips2 -mtune=mips2 } { -mmips:6000 }
 mips_arch_create mips3 	64	mips2	{} \
 			{ -march=mips3 -mtune=mips3 } { -mmips:4000 }
@@ -352,7 +356,7 @@ mips_arch_create mips64	64	mips5	{ mips3
 			{ mipsisa64-*-* mipsisa64el-*-* }
 mips_arch_create r3000 	32	mips1	{} \
 			{ -march=r3000 -mtune=r3000 } { -mmips:3000 }
-mips_arch_create r3900 	32	mips1	{} \
+mips_arch_create r3900 	32	mips1	{ gpr_ilocks } \
 			{ -march=r3900 -mtune=r3900 } { -mmips:3900 } \
 			{ mipstx39-*-* mipstx39el-*-* }
 mips_arch_create r4000 	64	mips3	{} \
@@ -492,6 +496,8 @@ if { [istarget mips*-*-*] } then {
     if !$aout { run_dump_test "sb" }
     run_dump_test "trunc"
     if !$aout { run_dump_test "ulh" }
+    run_dump_test_arches "ulh2-eb"	[mips_arch_list_matching mips1]
+    run_dump_test_arches "ulh2-el"	[mips_arch_list_matching mips1]
     if $elf { run_dump_test "ulh-svr4pic" }
     if $elf { run_dump_test "ulh-xgot" }
     if $ecoff { run_dump_test "ulh-empic" }
@@ -502,6 +508,14 @@ if { [istarget mips*-*-*] } then {
 	run_dump_test "usw"
 	run_dump_test "usd"
     }
+    run_dump_test_arches "ulw2-eb"	[mips_arch_list_matching !gpr_ilocks]
+    run_dump_test_arches "ulw2-eb-ilocks" [mips_arch_list_matching gpr_ilocks]
+    run_dump_test_arches "ulw2-el"	[mips_arch_list_matching !gpr_ilocks]
+    run_dump_test_arches "ulw2-el-ilocks" [mips_arch_list_matching gpr_ilocks]
+
+    run_dump_test_arches "uld2-eb" [mips_arch_list_matching mips3]
+    run_dump_test_arches "uld2-el" [mips_arch_list_matching mips3]
+
     # The mips16 test can only be run on ELF, because only ELF
     # supports the necessary mips16 reloc.
     if { $elf && !$no_mips16 } {
Index: testsuite/gas/mips/ulh.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/ulh.d,v
retrieving revision 1.2
diff -u -p -r1.2 ulh.d
--- testsuite/gas/mips/ulh.d	15 May 2001 12:11:13 -0000	1.2
+++ testsuite/gas/mips/ulh.d	1 Apr 2003 01:34:51 -0000
@@ -7,22 +7,22 @@
 .*: +file format .*mips.*
 
 Disassembly of section .text:
-0+0000 <[^>]*> lb	a0,[01]\(zero\)
-0+0004 <[^>]*> lbu	at,[01]\(zero\)
-0+0008 <[^>]*> sll	a0,a0,0x8
+0+0000 <[^>]*> lb	at,[01]\(zero\)
+0+0004 <[^>]*> lbu	a0,[01]\(zero\)
+0+0008 <[^>]*> sll	at,at,0x8
 0+000c <[^>]*> or	a0,a0,at
-0+0010 <[^>]*> lb	a0,[12]\(zero\)
-0+0014 <[^>]*> lbu	at,[12]\(zero\)
-0+0018 <[^>]*> sll	a0,a0,0x8
+0+0010 <[^>]*> lb	at,[12]\(zero\)
+0+0014 <[^>]*> lbu	a0,[12]\(zero\)
+0+0018 <[^>]*> sll	at,at,0x8
 0+001c <[^>]*> or	a0,a0,at
 0+0020 <[^>]*> li	at,0x8000
 0+0024 <[^>]*> lb	a0,[01]\(at\)
 0+0028 <[^>]*> lbu	at,[01]\(at\)
 0+002c <[^>]*> sll	a0,a0,0x8
 0+0030 <[^>]*> or	a0,a0,at
-0+0034 <[^>]*> lb	a0,-3276[78]\(zero\)
-0+0038 <[^>]*> lbu	at,-3276[78]\(zero\)
-0+003c <[^>]*> sll	a0,a0,0x8
+0+0034 <[^>]*> lb	at,-3276[78]\(zero\)
+0+0038 <[^>]*> lbu	a0,-3276[78]\(zero\)
+0+003c <[^>]*> sll	at,at,0x8
 0+0040 <[^>]*> or	a0,a0,at
 0+0044 <[^>]*> lui	at,0x1
 0+0048 <[^>]*> lb	a0,[01]\(at\)
@@ -35,13 +35,13 @@ Disassembly of section .text:
 0+0064 <[^>]*> lbu	at,[01]\(at\)
 0+0068 <[^>]*> sll	a0,a0,0x8
 0+006c <[^>]*> or	a0,a0,at
-0+0070 <[^>]*> lb	a0,[01]\(a1\)
-0+0074 <[^>]*> lbu	at,[01]\(a1\)
-0+0078 <[^>]*> sll	a0,a0,0x8
+0+0070 <[^>]*> lb	at,[01]\(a1\)
+0+0074 <[^>]*> lbu	a0,[01]\(a1\)
+0+0078 <[^>]*> sll	at,at,0x8
 0+007c <[^>]*> or	a0,a0,at
-0+0080 <[^>]*> lb	a0,[12]\(a1\)
-0+0084 <[^>]*> lbu	at,[12]\(a1\)
-0+0088 <[^>]*> sll	a0,a0,0x8
+0+0080 <[^>]*> lb	at,[12]\(a1\)
+0+0084 <[^>]*> lbu	a0,[12]\(a1\)
+0+0088 <[^>]*> sll	at,at,0x8
 0+008c <[^>]*> or	a0,a0,at
 0+0090 <[^>]*> lui	at,[-0-9x]+
 [ 	]*90: [A-Z0-9_]*HI[A-Z0-9_]*	.data.*
@@ -367,8 +367,8 @@ Disassembly of section .text:
 0+045c <[^>]*> lbu	at,[01]\(at\)
 0+0460 <[^>]*> sll	a0,a0,0x8
 0+0464 <[^>]*> or	a0,a0,at
-0+0468 <[^>]*> lbu	a0,[01]\(zero\)
-0+046c <[^>]*> lbu	at,[01]\(zero\)
-0+0470 <[^>]*> sll	a0,a0,0x8
+0+0468 <[^>]*> lbu	at,[01]\(zero\)
+0+046c <[^>]*> lbu	a0,[01]\(zero\)
+0+0470 <[^>]*> sll	at,at,0x8
 0+0474 <[^>]*> or	a0,a0,at
 	...


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