This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
mips [PATCH RFA]: fix ulh, ulhu, ulw, and uld macro expansions.
- From: cgd at broadcom dot com
- To: binutils at sources dot redhat dot com
- Date: 31 Mar 2003 17:41:22 -0800
- Subject: 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
...