public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] MIPS gas: Fix macro expansions for .set noat
@ 2005-02-16 23:51 Thiemo Seufer
  2005-02-17  0:25 ` Maciej W. Rozycki
  0 siblings, 1 reply; 13+ messages in thread
From: Thiemo Seufer @ 2005-02-16 23:51 UTC (permalink / raw)
  To: binutils

Hello All,

In some cases, MIPS gas uses the $at register even if .set noat is in
effect. The appended patch fixes this. Tested on mips-linux and
committed.


Thiemo


2005-02-16  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>

	/gas/ChangeLog
	* config/tc-mips.c (load_address): Fix formatting.
	(macro): Don't use AT if .set noat is in effect. Fix formatting.
	Catch macros which are unexpandable without AT. Remove duplicate
	zeroing of used_at.
	(macro2): Remove duplicate zeroing of used_at.


Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.281
diff -u -p -r1.281 tc-mips.c
--- gas/config/tc-mips.c	15 Feb 2005 19:57:52 -0000	1.281
+++ gas/config/tc-mips.c	16 Feb 2005 15:32:45 -0000
@@ -3877,7 +3877,7 @@ load_address (int reg, expressionS *ep, 
 	     It used not to be possible with the original relaxation code,
 	     but it could be done now.  */
 
-	  if (*used_at == 0 && ! mips_opts.noat)
+	  if (*used_at == 0 && !mips_opts.noat)
 	    {
 	      macro_build (ep, "lui", "t,u", reg, BFD_RELOC_MIPS_HIGHEST);
 	      macro_build (ep, "lui", "t,u", AT, BFD_RELOC_HI16_S);
@@ -4907,7 +4907,7 @@ macro (struct mips_cl_insn *ip)
 	  return;
 	}
 
-      if (treg == breg)
+      if (!mips_opts.noat && (treg == breg))
 	{
 	  tempreg = AT;
 	  used_at = 1;
@@ -4915,7 +4915,6 @@ macro (struct mips_cl_insn *ip)
       else
 	{
 	  tempreg = treg;
-	  used_at = 0;
 	}
 
       if (offset_expr.X_op != O_symbol
@@ -4963,7 +4962,7 @@ macro (struct mips_cl_insn *ip)
 		 these macros.  It used not to be possible with the
 		 original relaxation code, but it could be done now.  */
 
-	      if (used_at == 0 && ! mips_opts.noat)
+	      if (used_at == 0 && !mips_opts.noat)
 		{
 		  macro_build (&offset_expr, "lui", "t,u",
 			       tempreg, BFD_RELOC_MIPS_HIGHEST);
@@ -5484,7 +5483,7 @@ macro (struct mips_cl_insn *ip)
 	  macro_build (NULL, s, "d,v,t", treg, tempreg, breg);
 	}
 
-      if (! used_at)
+      if (!used_at)
 	return;
 
       break;
@@ -5762,11 +5761,19 @@ macro (struct mips_cl_insn *ip)
     case M_LWU_AB:
       s = "lwu";
     ld:
-      if (breg == treg || coproc || lr)
+      /* XXX Why don't we try to use AT for all expansions? */
+      if (!mips_opts.noat && (breg == treg || coproc || lr))
 	{
 	  tempreg = AT;
 	  used_at = 1;
 	}
+      else if (breg == treg
+	       && (offset_expr.X_op != O_constant
+		   || (offset_expr.X_add_number > 0x7fff
+		       || offset_expr.X_add_number < -0x8000)))
+	{
+	  as_bad(_("load expansion needs $at register"));
+	}
       else
 	{
 	  tempreg = treg;
@@ -5840,8 +5847,23 @@ macro (struct mips_cl_insn *ip)
     case M_SDR_AB:
       s = "sdr";
     st:
-      tempreg = AT;
-      used_at = 1;
+      if (!mips_opts.noat)
+	{
+	  tempreg = AT;
+	  used_at = 1;
+	}
+      else if (breg == treg
+	       && (offset_expr.X_op != O_constant
+		   || (offset_expr.X_add_number > 0x7fff
+		       || offset_expr.X_add_number < -0x8000)))
+	{
+	  as_bad(_("store expansion needs $at register"));
+	}
+      else
+	{
+	  tempreg = treg;
+	  used_at = 0;
+	}
     ld_st:
       /* Itbl support may require additional care here.  */
       if (mask == M_LWC1_AB
@@ -5973,7 +5995,7 @@ macro (struct mips_cl_insn *ip)
 		 these macros.  It used not to be possible with the
 		 original relaxation code, but it could be done now.  */
 
-	      if (used_at == 0 && ! mips_opts.noat)
+	      if (used_at == 0 && !mips_opts.noat)
 		{
 		  macro_build (&offset_expr, "lui", "t,u", tempreg,
 			       BFD_RELOC_MIPS_HIGHEST);
@@ -6006,6 +6028,9 @@ macro (struct mips_cl_insn *ip)
 			       BFD_RELOC_LO16, tempreg);
 		}
 
+	      if (used_at)
+		break;
+
 	      return;
 	    }
 
@@ -6022,7 +6047,6 @@ macro (struct mips_cl_insn *ip)
 		  macro_build (&offset_expr, s, fmt, treg, BFD_RELOC_GPREL16,
 			       mips_gp_register);
 		  relax_switch ();
-		  used_at = 0;
 		}
 	      macro_build_lui (&offset_expr, tempreg);
 	      macro_build (&offset_expr, s, fmt, treg,
@@ -6086,7 +6110,7 @@ macro (struct mips_cl_insn *ip)
 	      macro_build (&offset_expr, s, fmt, treg,
 			   BFD_RELOC_MIPS_GOT_OFST, tempreg);
 
-	      if (! used_at)
+	      if (!used_at)
 		return;
 
 	      break;
@@ -6200,7 +6224,7 @@ macro (struct mips_cl_insn *ip)
       else
 	abort ();
 
-      if (! used_at)
+      if (!used_at)
 	return;
 
       break;
@@ -6504,7 +6528,6 @@ macro (struct mips_cl_insn *ip)
 	      if (breg == 0)
 		{
 		  tempreg = mips_gp_register;
-		  used_at = 0;
 		}
 	      else
 		{
@@ -6690,7 +6713,7 @@ macro (struct mips_cl_insn *ip)
       else
 	abort ();
 
-      if (! used_at)
+      if (!used_at)
 	return;
 
       break;
@@ -6897,7 +6920,6 @@ macro2 (struct mips_cl_insn *ip)
 	  else
 	    {
 	      tempreg = dreg;
-	      used_at = 0;
 	    }
 	  macro_build (NULL, "dnegu", "d,w", tempreg, treg);
 	  macro_build (NULL, "drorv", "d,t,s", dreg, sreg, tempreg);
@@ -6922,7 +6944,6 @@ macro2 (struct mips_cl_insn *ip)
 	  else
 	    {
 	      tempreg = dreg;
-	      used_at = 0;
 	    }
 	  macro_build (NULL, "negu", "d,w", tempreg, treg);
 	  macro_build (NULL, "rorv", "d,t,s", dreg, sreg, tempreg);
@@ -7113,7 +7134,6 @@ macro2 (struct mips_cl_insn *ip)
 	  && imm_expr.X_add_number < 0x10000)
 	{
 	  macro_build (&imm_expr, "xori", "t,r,i", dreg, sreg, BFD_RELOC_LO16);
-	  used_at = 0;
 	}
       else if (imm_expr.X_op == O_constant
 	       && imm_expr.X_add_number > -0x8000
@@ -7122,7 +7142,6 @@ macro2 (struct mips_cl_insn *ip)
 	  imm_expr.X_add_number = -imm_expr.X_add_number;
 	  macro_build (&imm_expr, HAVE_32BIT_GPRS ? "addiu" : "daddiu",
 		       "t,r,j", dreg, sreg, BFD_RELOC_LO16);
-	  used_at = 0;
 	}
       else
 	{
@@ -7153,7 +7172,6 @@ macro2 (struct mips_cl_insn *ip)
 	{
 	  macro_build (&imm_expr, mask == M_SGE_I ? "slti" : "sltiu", "t,r,j",
 		       dreg, sreg, BFD_RELOC_LO16);
-	  used_at = 0;
 	}
       else
 	{
@@ -7263,7 +7281,6 @@ macro2 (struct mips_cl_insn *ip)
 	  && imm_expr.X_add_number < 0x10000)
 	{
 	  macro_build (&imm_expr, "xori", "t,r,i", dreg, sreg, BFD_RELOC_LO16);
-	  used_at = 0;
 	}
       else if (imm_expr.X_op == O_constant
 	       && imm_expr.X_add_number > -0x8000
@@ -7272,7 +7289,6 @@ macro2 (struct mips_cl_insn *ip)
 	  imm_expr.X_add_number = -imm_expr.X_add_number;
 	  macro_build (&imm_expr, HAVE_32BIT_GPRS ? "addiu" : "daddiu",
 		       "t,r,j", dreg, sreg, BFD_RELOC_LO16);
-	  used_at = 0;
 	}
       else
 	{

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] MIPS gas: Fix macro expansions for .set noat
  2005-02-16 23:51 [PATCH] MIPS gas: Fix macro expansions for .set noat Thiemo Seufer
@ 2005-02-17  0:25 ` Maciej W. Rozycki
  2005-02-17  1:31   ` Maciej W. Rozycki
  0 siblings, 1 reply; 13+ messages in thread
From: Maciej W. Rozycki @ 2005-02-17  0:25 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

On Wed, 16 Feb 2005, Thiemo Seufer wrote:

> @@ -5762,11 +5761,19 @@ macro (struct mips_cl_insn *ip)
>      case M_LWU_AB:
>        s = "lwu";
>      ld:
> -      if (breg == treg || coproc || lr)
> +      /* XXX Why don't we try to use AT for all expansions? */

 Because we don't have to and it helps in cases like:

	.set	noat
	ld	k0,foo

> +      if (!mips_opts.noat && (breg == treg || coproc || lr))
>  	{
>  	  tempreg = AT;
>  	  used_at = 1;
>  	}
> +      else if (breg == treg
> +	       && (offset_expr.X_op != O_constant
> +		   || (offset_expr.X_add_number > 0x7fff
> +		       || offset_expr.X_add_number < -0x8000)))
> +	{
> +	  as_bad(_("load expansion needs $at register"));
> +	}
>        else
>  	{
>  	  tempreg = treg;

 This looks broken -- you can only use treg as a scratch pad if it's a 
GPR.

> @@ -5840,8 +5847,23 @@ macro (struct mips_cl_insn *ip)
>      case M_SDR_AB:
>        s = "sdr";
>      st:
> -      tempreg = AT;
> -      used_at = 1;
> +      if (!mips_opts.noat)
> +	{
> +	  tempreg = AT;
> +	  used_at = 1;
> +	}
> +      else if (breg == treg
> +	       && (offset_expr.X_op != O_constant
> +		   || (offset_expr.X_add_number > 0x7fff
> +		       || offset_expr.X_add_number < -0x8000)))
> +	{
> +	  as_bad(_("store expansion needs $at register"));
> +	}
> +      else
> +	{
> +	  tempreg = treg;
> +	  used_at = 0;
> +	}
>      ld_st:
>        /* Itbl support may require additional care here.  */
>        if (mask == M_LWC1_AB

 This is yet more broken -- treg can never be used, because it contains 
the value to be stored!  And of course it's not expected to get trashed 
anyway.

  Maciej

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] MIPS gas: Fix macro expansions for .set noat
  2005-02-17  0:25 ` Maciej W. Rozycki
@ 2005-02-17  1:31   ` Maciej W. Rozycki
  2005-02-17  1:34     ` Thiemo Seufer
  0 siblings, 1 reply; 13+ messages in thread
From: Maciej W. Rozycki @ 2005-02-17  1:31 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

Thiemo,

 More comments about that change -- as I understand our policy wrt $at 
being used with ".set noat" in effect is to go for it regardless and only 
issue a warning (that can be converted to an error with --fatal-warnings).  
Therefore we shouldn't use as_bad() in this case.  Moreover, the situation 
is actually already handled in general -- see the bottom exit point from 
macro() -- so we should really only track down the failing execution path 
within that function and check whether its epilogue correctly executes a 
functional equivalent of this code:

if (used_at)
	break;
else
	return;

  Maciej

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] MIPS gas: Fix macro expansions for .set noat
  2005-02-17  1:31   ` Maciej W. Rozycki
@ 2005-02-17  1:34     ` Thiemo Seufer
  2005-02-17  2:02       ` Maciej W. Rozycki
  0 siblings, 1 reply; 13+ messages in thread
From: Thiemo Seufer @ 2005-02-17  1:34 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: binutils

Maciej W. Rozycki wrote:
> Thiemo,
> 
>  More comments about that change -- as I understand our policy wrt $at 
> being used with ".set noat" in effect is to go for it regardless and only 
> issue a warning (that can be converted to an error with --fatal-warnings).  
> Therefore we shouldn't use as_bad() in this case.

IMHO it should be an error if the result can't work at all. I don't
see a case where overwriting the base register before its use could
be the programmers intention.

> Moreover, the situation 
> is actually already handled in general -- see the bottom exit point from 
> macro() -- so we should really only track down the failing execution path 
> within that function and check whether its epilogue correctly executes a 
> functional equivalent of this code:
> 
> if (used_at)
> 	break;
> else
> 	return;

This causes "used $at in .set noat" warnings. That's a rather confusing
message, given that no use of $at was specified in the source.


Thiemo

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] MIPS gas: Fix macro expansions for .set noat
  2005-02-17  1:34     ` Thiemo Seufer
@ 2005-02-17  2:02       ` Maciej W. Rozycki
  2005-02-17  7:10         ` Thiemo Seufer
  0 siblings, 1 reply; 13+ messages in thread
From: Maciej W. Rozycki @ 2005-02-17  2:02 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

On Wed, 16 Feb 2005, Thiemo Seufer wrote:

> >  More comments about that change -- as I understand our policy wrt $at 
> > being used with ".set noat" in effect is to go for it regardless and only 
> > issue a warning (that can be converted to an error with --fatal-warnings).  
> > Therefore we shouldn't use as_bad() in this case.
> 
> IMHO it should be an error if the result can't work at all. I don't
> see a case where overwriting the base register before its use could
> be the programmers intention.

 I do agree it's of questionable use and I proposed changing it a few 
years ago, but I got a response as I expressed above.  Then if it's to be 
done, it should be done consistently for all cases -- replacing respective 
as_warn() calls with as_bad() ones should be the right way.

 Note that the Alpha port has always treated using $at with ".set noat" in 
effect as an error.

> > Moreover, the situation 
> > is actually already handled in general -- see the bottom exit point from 
> > macro() -- so we should really only track down the failing execution path 
> > within that function and check whether its epilogue correctly executes a 
> > functional equivalent of this code:
> > 
> > if (used_at)
> > 	break;
> > else
> > 	return;
> 
> This causes "used $at in .set noat" warnings. That's a rather confusing
> message, given that no use of $at was specified in the source.

 It's actually 'Macro used $at after ".set noat"' and I think it's 
perfectly clear.

  Maciej

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] MIPS gas: Fix macro expansions for .set noat
  2005-02-17  2:02       ` Maciej W. Rozycki
@ 2005-02-17  7:10         ` Thiemo Seufer
  2005-02-17 13:53           ` Eric Christopher
  0 siblings, 1 reply; 13+ messages in thread
From: Thiemo Seufer @ 2005-02-17  7:10 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: binutils

Maciej W. Rozycki wrote:
> On Wed, 16 Feb 2005, Thiemo Seufer wrote:
> 
> > >  More comments about that change -- as I understand our policy wrt $at 
> > > being used with ".set noat" in effect is to go for it regardless and only 
> > > issue a warning (that can be converted to an error with --fatal-warnings).  
> > > Therefore we shouldn't use as_bad() in this case.
> > 
> > IMHO it should be an error if the result can't work at all. I don't
> > see a case where overwriting the base register before its use could
> > be the programmers intention.
> 
>  I do agree it's of questionable use and I proposed changing it a few 
> years ago, but I got a response as I expressed above.  Then if it's to be 
> done, it should be done consistently for all cases -- replacing respective 
> as_warn() calls with as_bad() ones should be the right way.

Hm, OTOH it could simply be sloppy coding, and falling over it
is not necessarily the right thing to do. I plan to commit the
appended patch, it partially reverts the earlier change.

Comments?


Thiemo


2005-02-16  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>

	/gas/ChangeLog
	* config/tc-mips.c (macro): Don't fail but warn on $at uses
	after .set noat, it may only be sloppy coding.  Don't try to
	avoid $at use by sacrificing the target register before it is
	stored, it won't work.

	/gas/testsuite/ChangeLog
	* gas/mips/noat-1.s, gas/mips/noat-1.d, gas/mips/noat-2.s,
	gas/mips/noat2.l, gas/mips/noat-3.s, gas/mips/noat-3.l,
	gas/mips/noat-4.s, gas/mips/noat-4.l, gas/mips/noat-5.s,
	gas/mips/noat-5.l, gas/mips/noat-6.s, gas/mips/noat-6.l,
	gas/mips/noat-7.s, gas/mips/noat-7.l: New files, testcases for
	.set noat and macro expansion.
	* gas/mips/mips.exp: Run new testcases.


Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.282
diff -u -p -r1.282 tc-mips.c
--- gas/config/tc-mips.c	16 Feb 2005 15:49:13 -0000	1.282
+++ gas/config/tc-mips.c	16 Feb 2005 23:26:33 -0000
@@ -5761,23 +5761,14 @@ macro (struct mips_cl_insn *ip)
     case M_LWU_AB:
       s = "lwu";
     ld:
-      /* XXX Why don't we try to use AT for all expansions? */
-      if (!mips_opts.noat && (breg == treg || coproc || lr))
+      if (breg == treg || coproc || lr)
 	{
 	  tempreg = AT;
 	  used_at = 1;
 	}
-      else if (breg == treg
-	       && (offset_expr.X_op != O_constant
-		   || (offset_expr.X_add_number > 0x7fff
-		       || offset_expr.X_add_number < -0x8000)))
-	{
-	  as_bad(_("load expansion needs $at register"));
-	}
       else
 	{
 	  tempreg = treg;
-	  used_at = 0;
 	}
       goto ld_st;
     case M_SB_AB:
@@ -5847,23 +5838,8 @@ macro (struct mips_cl_insn *ip)
     case M_SDR_AB:
       s = "sdr";
     st:
-      if (!mips_opts.noat)
-	{
-	  tempreg = AT;
-	  used_at = 1;
-	}
-      else if (breg == treg
-	       && (offset_expr.X_op != O_constant
-		   || (offset_expr.X_add_number > 0x7fff
-		       || offset_expr.X_add_number < -0x8000)))
-	{
-	  as_bad(_("store expansion needs $at register"));
-	}
-      else
-	{
-	  tempreg = treg;
-	  used_at = 0;
-	}
+      tempreg = AT;
+      used_at = 1;
     ld_st:
       /* Itbl support may require additional care here.  */
       if (mask == M_LWC1_AB
Index: gas/testsuite/gas/mips/mips.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips.exp,v
retrieving revision 1.98
diff -u -p -r1.98 mips.exp
--- gas/testsuite/gas/mips/mips.exp	15 Feb 2005 19:57:53 -0000	1.98
+++ gas/testsuite/gas/mips/mips.exp	16 Feb 2005 23:26:35 -0000
@@ -738,4 +738,12 @@ if { [istarget mips*-*-*] } then {
 	run_dump_test "macro-warn-1-n32"
 	run_dump_test "macro-warn-2-n32"
     }
+
+    run_dump_test "noat-1"
+    run_list_test "noat-2" ""
+    run_list_test "noat-3" ""
+    run_list_test "noat-4" ""
+    run_list_test "noat-5" ""
+    run_list_test "noat-6" ""
+    run_list_test "noat-7" ""
 }
Index: gas/testsuite/gas/mips/noat-1.d
===================================================================
RCS file: gas/testsuite/gas/mips/noat-1.d
diff -N gas/testsuite/gas/mips/noat-1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-1.d	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,15 @@
+#as: -32
+#objdump: -dr
+
+.*: +file format .*mips
+
+Disassembly of section \.text:
+
+00000000 <\.text>:
+   0:	8f7b7fff 	lw	k1,32767\(k1\)
+   4:	00000000 	nop
+   8:	8f7b8000 	lw	k1,-32768\(k1\)
+   c:	00000000 	nop
+  10:	af7b7fff 	sw	k1,32767\(k1\)
+  14:	af7b8000 	sw	k1,-32768\(k1\)
+	\.\.\.
Index: gas/testsuite/gas/mips/noat-1.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-1.s
diff -N gas/testsuite/gas/mips/noat-1.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-1.s	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,7 @@
+	.set noat
+	lw $27, 0x7fff($27)
+	lw $27, -0x8000($27)
+	sw $27, 0x7fff($27)
+	sw $27, -0x8000($27)
+
+	.space 8
Index: gas/testsuite/gas/mips/noat-2.l
===================================================================
RCS file: gas/testsuite/gas/mips/noat-2.l
diff -N gas/testsuite/gas/mips/noat-2.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-2.l	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,2 @@
+.*\.s: Assembler messages:
+.*\.s:2: Warning: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/noat-2.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-2.s
diff -N gas/testsuite/gas/mips/noat-2.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-2.s	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,4 @@
+	.set noat
+	lw $27, 0x8000($27)
+
+	.space 8
Index: gas/testsuite/gas/mips/noat-3.l
===================================================================
RCS file: gas/testsuite/gas/mips/noat-3.l
diff -N gas/testsuite/gas/mips/noat-3.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-3.l	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,2 @@
+.*\.s: Assembler messages:
+.*\.s:2: Warning: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/noat-3.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-3.s
diff -N gas/testsuite/gas/mips/noat-3.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-3.s	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,4 @@
+	.set noat
+	lw $27, -0x8001($27)
+
+	.space 8
Index: gas/testsuite/gas/mips/noat-4.l
===================================================================
RCS file: gas/testsuite/gas/mips/noat-4.l
diff -N gas/testsuite/gas/mips/noat-4.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-4.l	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,2 @@
+.*\.s: Assembler messages:
+.*\.s:2: Warning: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/noat-4.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-4.s
diff -N gas/testsuite/gas/mips/noat-4.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-4.s	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,4 @@
+	.set noat
+	lw $27, symbol($27)
+
+	.space 8
Index: gas/testsuite/gas/mips/noat-5.l
===================================================================
RCS file: gas/testsuite/gas/mips/noat-5.l
diff -N gas/testsuite/gas/mips/noat-5.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-5.l	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,2 @@
+.*\.s: Assembler messages:
+.*\.s:2: Warning: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/noat-5.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-5.s
diff -N gas/testsuite/gas/mips/noat-5.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-5.s	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,4 @@
+	.set noat
+	sw $27, 0x8000($27)
+
+	.space 8
Index: gas/testsuite/gas/mips/noat-6.l
===================================================================
RCS file: gas/testsuite/gas/mips/noat-6.l
diff -N gas/testsuite/gas/mips/noat-6.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-6.l	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,2 @@
+.*\.s: Assembler messages:
+.*\.s:2: Warning: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/noat-6.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-6.s
diff -N gas/testsuite/gas/mips/noat-6.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-6.s	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,4 @@
+	.set noat
+	sw $27, -0x8001($27)
+
+	.space 8
Index: gas/testsuite/gas/mips/noat-7.l
===================================================================
RCS file: gas/testsuite/gas/mips/noat-7.l
diff -N gas/testsuite/gas/mips/noat-7.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-7.l	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,2 @@
+.*\.s: Assembler messages:
+.*\.s:2: Warning: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/noat-7.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-7.s
diff -N gas/testsuite/gas/mips/noat-7.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-7.s	16 Feb 2005 23:26:35 -0000
@@ -0,0 +1,4 @@
+	.set noat
+	sw $27, symbol($27)
+
+	.space 8

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] MIPS gas: Fix macro expansions for .set noat
  2005-02-17  7:10         ` Thiemo Seufer
@ 2005-02-17 13:53           ` Eric Christopher
  2005-02-17 20:50             ` Maciej W. Rozycki
  0 siblings, 1 reply; 13+ messages in thread
From: Eric Christopher @ 2005-02-17 13:53 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Maciej W. Rozycki, binutils


> Hm, OTOH it could simply be sloppy coding, and falling over it
> is not necessarily the right thing to do. I plan to commit the
> appended patch, it partially reverts the earlier change.
> 
> Comments?
> 
> 
> Thiemo
> 
> 
> 2005-02-16  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>
> 
> 	/gas/ChangeLog
> 	* config/tc-mips.c (macro): Don't fail but warn on $at uses
> 	after .set noat, it may only be sloppy coding.  Don't try to
> 	avoid $at use by sacrificing the target register before it is
> 	stored, it won't work.

Actually I disagree. If the user used .set noat and has sloppy coding we
should fall over like we would for .set nomacro or such.

-eric

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] MIPS gas: Fix macro expansions for .set noat
  2005-02-17 13:53           ` Eric Christopher
@ 2005-02-17 20:50             ` Maciej W. Rozycki
  2005-02-17 21:33               ` Thiemo Seufer
  0 siblings, 1 reply; 13+ messages in thread
From: Maciej W. Rozycki @ 2005-02-17 20:50 UTC (permalink / raw)
  To: Eric Christopher; +Cc: Thiemo Seufer, binutils

On Wed, 16 Feb 2005, Eric Christopher wrote:

> > 2005-02-16  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>
> > 
> > 	/gas/ChangeLog
> > 	* config/tc-mips.c (macro): Don't fail but warn on $at uses
> > 	after .set noat, it may only be sloppy coding.  Don't try to
> > 	avoid $at use by sacrificing the target register before it is
> > 	stored, it won't work.
> 
> Actually I disagree. If the user used .set noat and has sloppy coding we
> should fall over like we would for .set nomacro or such.

 What exactly do you mean?

$ cat nomacro.S
	.set	noreorder
	.set	nomacro
	la	$2,foo($3)
$ gcc -c nomacro.S
nomacro.S: Assembler messages:
nomacro.S:3: Warning: Macro instruction expanded into multiple instructions
$ objdump -Sr nomacro.o

nomacro.o:     file format elf32-tradbigmips

Disassembly of section .text:

00000000 <.text>:
   0:	8f820000 	lw	v0,0(gp)
			0: R_MIPS_GOT16	foo
   4:	00000000 	nop
   8:	00431021 	addu	v0,v0,v1
   c:	00000000 	nop

It's always been like this and when I complained once, asking for making 
it an error I was told a warning was The Right Way and it was not going to 
be changed, sigh...

 If the rules have changed now, then I am happy about it as I've never 
seen any benefit from the current behavior.  But then the update should be 
consistent and make all "set noat" and ".set nomacro" violations trigger 
the same action.

  Maciej

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] MIPS gas: Fix macro expansions for .set noat
  2005-02-17 20:50             ` Maciej W. Rozycki
@ 2005-02-17 21:33               ` Thiemo Seufer
  2005-02-18  0:21                 ` Maciej W. Rozycki
                                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Thiemo Seufer @ 2005-02-17 21:33 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Eric Christopher, binutils

Maciej W. Rozycki wrote:
> On Wed, 16 Feb 2005, Eric Christopher wrote:
> 
> > > 2005-02-16  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>
> > > 
> > > 	/gas/ChangeLog
> > > 	* config/tc-mips.c (macro): Don't fail but warn on $at uses
> > > 	after .set noat, it may only be sloppy coding.  Don't try to
> > > 	avoid $at use by sacrificing the target register before it is
> > > 	stored, it won't work.
> > 
> > Actually I disagree. If the user used .set noat and has sloppy coding we
> > should fall over like we would for .set nomacro or such.
> 
>  What exactly do you mean?
> 
> $ cat nomacro.S
> 	.set	noreorder
> 	.set	nomacro
> 	la	$2,foo($3)
> $ gcc -c nomacro.S
> nomacro.S: Assembler messages:
> nomacro.S:3: Warning: Macro instruction expanded into multiple instructions

Ok, this patch converts $at uses in .set noat from warnings to errors.
I haven't changed the .set nomacro behaviour yet, partially because
this patch is already big enough, and partially because nomacro isn't
fully equivalent to noat. Nomacro probably shouldn't fail if the number
of instructions stays the same.


Thiemo


2005-02-17  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>

	/gas/ChangeLog
	* config/tc-mips.c (macro_build_ldst_constoffset): Fail on $at
	uses after .set noat.
	(load_address): Likewise.
	(macro): Likewise. Don't try to avoid $at use by sacrificing
	the target register before it is stored, it won't work.

	/gas/testsuite/ChangeLog
	* gas/mips/noat-1.s, gas/mips/noat-1.d, gas/mips/noat-2.s,
	gas/mips/noat2.l, gas/mips/noat-3.s, gas/mips/noat-3.l,
	gas/mips/noat-4.s, gas/mips/noat-4.l, gas/mips/noat-5.s,
	gas/mips/noat-5.l, gas/mips/noat-6.s, gas/mips/noat-6.l,
	gas/mips/noat-7.s, gas/mips/noat-7.l: New files, testcases for
	.set noat in macro expansions.
	* gas/mips/mips.exp: Run new testcases.
	* gas/mips/rol-hw.d, gas/mips/rol-hw.l, gas/mips/rol.d,
	gas/mips/rol.l, gas/mips/rol.s, gas/mips/rol64-hw.d,
	gas/mips/rol64-hw.l, gas/mips/rol64.d, gas/mips/rol64.l,
	gas/mips/rol64.s, gas/mips/uld2-eb.d, gas/mips/uld2-el.d,
	gas/mips/uld2.l, gas/mips/uld2.s, gas/mips/ulh2-eb.d,
	gas/mips/ulh2-el.d, gas/mips/ulh2.l, gas/mips/ulh2.s,
	gas/mips/ulw2-eb-ilocks.d, gas/mips/ulw2-eb.d,
	gas/mips/ulw2-el-ilocks.d, gas/mips/ulw2-el.d, gas/mips/ulw2.l,
	gas/mips/ulw2.s: Don't try to test .set noat.


Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.282
diff -u -p -r1.282 tc-mips.c
--- gas/config/tc-mips.c	16 Feb 2005 15:49:13 -0000	1.282
+++ gas/config/tc-mips.c	17 Feb 2005 17:03:51 -0000
@@ -3463,7 +3463,7 @@ macro_build_ldst_constoffset (expression
       macro_build (ep, op, "t,o(b)", treg, BFD_RELOC_LO16, AT);
 
       if (mips_opts.noat)
-	as_warn (_("Macro used $at after \".set noat\""));
+	as_bad (_("Macro used $at after \".set noat\""));
     }
 }
 
@@ -4062,6 +4062,9 @@ load_address (int reg, expressionS *ep, 
     }
   else
     abort ();
+
+  if (mips_opts.noat && *used_at == 1)
+    as_bad (_("Macro used $at after \".set noat\""));
 }
 
 /* Move the contents of register SOURCE into register DEST.  */
@@ -4223,7 +4226,7 @@ macro (struct mips_cl_insn *ip)
       macro_build (NULL, dbl ? "dsub" : "sub", "d,v,t", dreg, 0, sreg);
 
       --mips_opts.noreorder;
-      return;
+      break;
 
     case M_ADD_I:
       s = "addi";
@@ -4248,8 +4251,9 @@ macro (struct mips_cl_insn *ip)
 	  && imm_expr.X_add_number < 0x8000)
 	{
 	  macro_build (&imm_expr, s, "t,r,j", treg, sreg, BFD_RELOC_LO16);
-	  return;
+	  break;
 	}
+      used_at = 1;
       load_register (AT, &imm_expr, dbl);
       macro_build (NULL, s2, "d,v,t", treg, sreg, AT);
       break;
@@ -4282,9 +4286,10 @@ macro (struct mips_cl_insn *ip)
 			   treg, sreg, BFD_RELOC_LO16);
 	      macro_build (NULL, "nor", "d,v,t", treg, treg, 0);
 	    }
-	  return;
+	  break;
 	}
 
+      used_at = 1;
       load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
       macro_build (NULL, s2, "d,v,t", treg, sreg, AT);
       break;
@@ -4306,8 +4311,9 @@ macro (struct mips_cl_insn *ip)
       if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
 	{
 	  macro_build (&offset_expr, s, "s,t,p", sreg, 0);
-	  return;
+	  break;
 	}
+      used_at = 1;
       load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
       macro_build (&offset_expr, s, "s,t,p", sreg, AT);
       break;
@@ -4318,13 +4324,14 @@ macro (struct mips_cl_insn *ip)
       if (treg == 0)
 	{
 	  macro_build (&offset_expr, likely ? "bgezl" : "bgez", "s,p", sreg);
-	  return;
+	  break;
 	}
       if (sreg == 0)
 	{
 	  macro_build (&offset_expr, likely ? "blezl" : "blez", "s,p", treg);
-	  return;
+	  break;
 	}
+      used_at = 1;
       macro_build (NULL, "slt", "d,v,t", AT, sreg, treg);
       macro_build (&offset_expr, likely ? "beql" : "beq", "s,t,p", AT, 0);
       break;
@@ -4351,7 +4358,7 @@ macro (struct mips_cl_insn *ip)
 	    macro_build (NULL, "nop", "", 0);
 	  else
 	    macro_build (&offset_expr, "bnel", "s,t,p", 0, 0);
-	  return;
+	  break;
 	}
       if (imm_expr.X_op != O_constant)
 	as_bad (_("Unsupported large constant"));
@@ -4364,12 +4371,12 @@ macro (struct mips_cl_insn *ip)
       if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
 	{
 	  macro_build (&offset_expr, likely ? "bgezl" : "bgez", "s,p", sreg);
-	  return;
+	  break;
 	}
       if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
 	{
 	  macro_build (&offset_expr, likely ? "bgtzl" : "bgtz", "s,p", sreg);
-	  return;
+	  break;
 	}
       maxnum = 0x7fffffff;
       if (HAVE_64BIT_GPRS && sizeof (maxnum) > 4)
@@ -4388,8 +4395,9 @@ macro (struct mips_cl_insn *ip)
 	  /* result is always true */
 	  as_warn (_("Branch %s is always true"), ip->insn_mo->name);
 	  macro_build (&offset_expr, "b", "p");
-	  return;
+	  break;
 	}
+      used_at = 1;
       set_at (sreg, 0);
       macro_build (&offset_expr, likely ? "beql" : "beq", "s,t,p", AT, 0);
       break;
@@ -4403,8 +4411,9 @@ macro (struct mips_cl_insn *ip)
 	{
 	  macro_build (&offset_expr, likely ? "beql" : "beq",
 		       "s,t,p", 0, treg);
-	  return;
+	  break;
 	}
+      used_at = 1;
       macro_build (NULL, "sltu", "d,v,t", AT, sreg, treg);
       macro_build (&offset_expr, likely ? "beql" : "beq", "s,t,p", AT, 0);
       break;
@@ -4431,8 +4440,9 @@ macro (struct mips_cl_insn *ip)
 	{
 	  macro_build (&offset_expr, likely ? "bnel" : "bne",
 		       "s,t,p", sreg, 0);
-	  return;
+	  break;
 	}
+      used_at = 1;
       set_at (sreg, 1);
       macro_build (&offset_expr, likely ? "beql" : "beq", "s,t,p", AT, 0);
       break;
@@ -4443,13 +4453,14 @@ macro (struct mips_cl_insn *ip)
       if (treg == 0)
 	{
 	  macro_build (&offset_expr, likely ? "bgtzl" : "bgtz", "s,p", sreg);
-	  return;
+	  break;
 	}
       if (sreg == 0)
 	{
 	  macro_build (&offset_expr, likely ? "bltzl" : "bltz", "s,p", treg);
-	  return;
+	  break;
 	}
+      used_at = 1;
       macro_build (NULL, "slt", "d,v,t", AT, treg, sreg);
       macro_build (&offset_expr, likely ? "bnel" : "bne", "s,t,p", AT, 0);
       break;
@@ -4461,10 +4472,11 @@ macro (struct mips_cl_insn *ip)
 	{
 	  macro_build (&offset_expr, likely ? "bnel" : "bne",
 		       "s,t,p", sreg, 0);
-	  return;
+	  break;
 	}
       if (sreg == 0)
 	goto do_false;
+      used_at = 1;
       macro_build (NULL, "sltu", "d,v,t", AT, treg, sreg);
       macro_build (&offset_expr, likely ? "bnel" : "bne", "s,t,p", AT, 0);
       break;
@@ -4475,13 +4487,14 @@ macro (struct mips_cl_insn *ip)
       if (treg == 0)
 	{
 	  macro_build (&offset_expr, likely ? "blezl" : "blez", "s,p", sreg);
-	  return;
+	  break;
 	}
       if (sreg == 0)
 	{
 	  macro_build (&offset_expr, likely ? "bgezl" : "bgez", "s,p", treg);
-	  return;
+	  break;
 	}
+      used_at = 1;
       macro_build (NULL, "slt", "d,v,t", AT, treg, sreg);
       macro_build (&offset_expr, likely ? "beql" : "beq", "s,t,p", AT, 0);
       break;
@@ -4512,13 +4525,14 @@ macro (struct mips_cl_insn *ip)
       if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
 	{
 	  macro_build (&offset_expr, likely ? "bltzl" : "bltz", "s,p", sreg);
-	  return;
+	  break;
 	}
       if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
 	{
 	  macro_build (&offset_expr, likely ? "blezl" : "blez", "s,p", sreg);
-	  return;
+	  break;
 	}
+      used_at = 1;
       set_at (sreg, 0);
       macro_build (&offset_expr, likely ? "bnel" : "bne", "s,t,p", AT, 0);
       break;
@@ -4530,10 +4544,11 @@ macro (struct mips_cl_insn *ip)
 	{
 	  macro_build (&offset_expr, likely ? "beql" : "beq",
 		       "s,t,p", sreg, 0);
-	  return;
+	  break;
 	}
       if (sreg == 0)
 	goto do_true;
+      used_at = 1;
       macro_build (NULL, "sltu", "d,v,t", AT, treg, sreg);
       macro_build (&offset_expr, likely ? "beql" : "beq", "s,t,p", AT, 0);
       break;
@@ -4560,8 +4575,9 @@ macro (struct mips_cl_insn *ip)
 	{
 	  macro_build (&offset_expr, likely ? "beql" : "beq",
 		       "s,t,p", sreg, 0);
-	  return;
+	  break;
 	}
+      used_at = 1;
       set_at (sreg, 1);
       macro_build (&offset_expr, likely ? "bnel" : "bne", "s,t,p", AT, 0);
       break;
@@ -4572,13 +4588,14 @@ macro (struct mips_cl_insn *ip)
       if (treg == 0)
 	{
 	  macro_build (&offset_expr, likely ? "bltzl" : "bltz", "s,p", sreg);
-	  return;
+	  break;
 	}
       if (sreg == 0)
 	{
 	  macro_build (&offset_expr, likely ? "bgtzl" : "bgtz", "s,p", treg);
-	  return;
+	  break;
 	}
+      used_at = 1;
       macro_build (NULL, "slt", "d,v,t", AT, sreg, treg);
       macro_build (&offset_expr, likely ? "bnel" : "bne", "s,t,p", AT, 0);
       break;
@@ -4592,8 +4609,9 @@ macro (struct mips_cl_insn *ip)
 	{
 	  macro_build (&offset_expr, likely ? "bnel" : "bne",
 		       "s,t,p", 0, treg);
-	  return;
+	  break;
 	}
+      used_at = 1;
       macro_build (NULL, "sltu", "d,v,t", AT, sreg, treg);
       macro_build (&offset_expr, likely ? "bnel" : "bne", "s,t,p", AT, 0);
       break;
@@ -4644,7 +4662,7 @@ macro (struct mips_cl_insn *ip)
 	  }
 	macro_build ((expressionS *) NULL, s, fmt, treg, sreg, pos, size - 1);
       }
-      return;
+      break;
 
     case M_DINS:
       {
@@ -4693,7 +4711,7 @@ macro (struct mips_cl_insn *ip)
 	macro_build ((expressionS *) NULL, s, fmt, treg, sreg, pos,
 		     pos + size - 1);
       }
-      return;
+      break;
 
     case M_DDIV_3:
       dbl = 1;
@@ -4712,7 +4730,7 @@ macro (struct mips_cl_insn *ip)
 	    macro_build (NULL, "teq", "s,t,q", 0, 0, 7);
 	  else
 	    macro_build (NULL, "break", "c", 7);
-	  return;
+	  break;
 	}
 
       mips_emit_delays (TRUE);
@@ -4731,6 +4749,7 @@ macro (struct mips_cl_insn *ip)
 	  macro_build (NULL, "break", "c", 7);
 	}
       expr1.X_add_number = -1;
+      used_at = 1;
       load_register (AT, &expr1, dbl);
       expr1.X_add_number = mips_trap ? (dbl ? 12 : 8) : (dbl ? 20 : 16);
       macro_build (&expr1, "bne", "s,t,p", treg, AT);
@@ -4810,7 +4829,7 @@ macro (struct mips_cl_insn *ip)
 	    macro_build (NULL, "teq", "s,t,q", 0, 0, 7);
 	  else
 	    macro_build (NULL, "break", "c", 7);
-	  return;
+	  break;
 	}
       if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
 	{
@@ -4818,7 +4837,7 @@ macro (struct mips_cl_insn *ip)
 	    move_register (dreg, sreg);
 	  else
 	    move_register (dreg, 0);
-	  return;
+	  break;
 	}
       if (imm_expr.X_op == O_constant
 	  && imm_expr.X_add_number == -1
@@ -4830,9 +4849,10 @@ macro (struct mips_cl_insn *ip)
 	    }
 	  else
 	    move_register (dreg, 0);
-	  return;
+	  break;
 	}
 
+      used_at = 1;
       load_register (AT, &imm_expr, dbl);
       macro_build (NULL, s, "z,s,t", sreg, AT);
       macro_build (NULL, s2, "d", dreg);
@@ -4877,7 +4897,7 @@ macro (struct mips_cl_insn *ip)
 	  macro_build (NULL, "break", "c", 7);
 	}
       macro_build (NULL, s2, "d", dreg);
-      return;
+      break;
 
     case M_DLCA_AB:
       dbl = 1;
@@ -4904,7 +4924,7 @@ macro (struct mips_cl_insn *ip)
 	  macro_build (&offset_expr,
 		       (dbl || HAVE_64BIT_ADDRESSES) ? "daddiu" : "addiu",
 		       "t,r,j", treg, sreg, BFD_RELOC_LO16);
-	  return;
+	  break;
 	}
 
       if (!mips_opts.noat && (treg == breg))
@@ -5358,6 +5378,7 @@ macro (struct mips_cl_insn *ip)
 			   AT, AT, BFD_RELOC_LO16);
 	      macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
 			   tempreg, tempreg, AT);
+	      used_at = 1;
 	    }
 	  relax_end ();
 	}
@@ -5482,10 +5503,6 @@ macro (struct mips_cl_insn *ip)
 
 	  macro_build (NULL, s, "d,v,t", treg, tempreg, breg);
 	}
-
-      if (!used_at)
-	return;
-
       break;
 
     case M_J_A:
@@ -5496,7 +5513,7 @@ macro (struct mips_cl_insn *ip)
 	macro_build (&offset_expr, "j", "a");
       else
 	macro_build (&offset_expr, "b", "p");
-      return;
+      break;
 
       /* The jal instructions must be handled as macros because when
 	 generating PIC code they expand to multi-instruction
@@ -5542,7 +5559,7 @@ macro (struct mips_cl_insn *ip)
       else
 	abort ();
 
-      return;
+      break;
 
     case M_JAL_A:
       if (mips_pic == NO_PIC)
@@ -5679,7 +5696,7 @@ macro (struct mips_cl_insn *ip)
       else
 	abort ();
 
-      return;
+      break;
 
     case M_LB_AB:
       s = "lb";
@@ -5728,7 +5745,7 @@ macro (struct mips_cl_insn *ip)
       if (mips_opts.arch == CPU_R4650)
 	{
 	  as_bad (_("opcode not supported on this processor"));
-	  return;
+	  break;
 	}
       s = "ldc1";
       /* Itbl support may require additional care here.  */
@@ -5761,23 +5778,14 @@ macro (struct mips_cl_insn *ip)
     case M_LWU_AB:
       s = "lwu";
     ld:
-      /* XXX Why don't we try to use AT for all expansions? */
-      if (!mips_opts.noat && (breg == treg || coproc || lr))
+      if (breg == treg || coproc || lr)
 	{
 	  tempreg = AT;
 	  used_at = 1;
 	}
-      else if (breg == treg
-	       && (offset_expr.X_op != O_constant
-		   || (offset_expr.X_add_number > 0x7fff
-		       || offset_expr.X_add_number < -0x8000)))
-	{
-	  as_bad(_("load expansion needs $at register"));
-	}
       else
 	{
 	  tempreg = treg;
-	  used_at = 0;
 	}
       goto ld_st;
     case M_SB_AB:
@@ -5825,7 +5833,7 @@ macro (struct mips_cl_insn *ip)
       if (mips_opts.arch == CPU_R4650)
 	{
 	  as_bad (_("opcode not supported on this processor"));
-	  return;
+	  break;
 	}
       s = "sdc1";
       coproc = 1;
@@ -5847,23 +5855,8 @@ macro (struct mips_cl_insn *ip)
     case M_SDR_AB:
       s = "sdr";
     st:
-      if (!mips_opts.noat)
-	{
-	  tempreg = AT;
-	  used_at = 1;
-	}
-      else if (breg == treg
-	       && (offset_expr.X_op != O_constant
-		   || (offset_expr.X_add_number > 0x7fff
-		       || offset_expr.X_add_number < -0x8000)))
-	{
-	  as_bad(_("store expansion needs $at register"));
-	}
-      else
-	{
-	  tempreg = treg;
-	  used_at = 0;
-	}
+      tempreg = AT;
+      used_at = 1;
     ld_st:
       /* Itbl support may require additional care here.  */
       if (mask == M_LWC1_AB
@@ -6027,11 +6020,7 @@ macro (struct mips_cl_insn *ip)
 		  macro_build (&offset_expr, s, fmt, treg,
 			       BFD_RELOC_LO16, tempreg);
 		}
-
-	      if (used_at)
-		break;
-
-	      return;
+	      break;
 	    }
 
 	  if (offset_expr.X_op == O_constant
@@ -6109,10 +6098,6 @@ macro (struct mips_cl_insn *ip)
 			     tempreg, tempreg, breg);
 	      macro_build (&offset_expr, s, fmt, treg,
 			   BFD_RELOC_MIPS_GOT_OFST, tempreg);
-
-	      if (!used_at)
-		return;
-
 	      break;
 	    }
 	  expr1.X_add_number = offset_expr.X_add_number;
@@ -6224,23 +6209,21 @@ macro (struct mips_cl_insn *ip)
       else
 	abort ();
 
-      if (!used_at)
-	return;
-
       break;
 
     case M_LI:
     case M_LI_S:
       load_register (treg, &imm_expr, 0);
-      return;
+      break;
 
     case M_DLI:
       load_register (treg, &imm_expr, 1);
-      return;
+      break;
 
     case M_LI_SS:
       if (imm_expr.X_op == O_constant)
 	{
+	  used_at = 1;
 	  load_register (AT, &imm_expr, 0);
 	  macro_build (NULL, "mtc1", "t,G", AT, treg);
 	  break;
@@ -6254,7 +6237,7 @@ macro (struct mips_cl_insn *ip)
 		  && offset_expr.X_add_number == 0);
 	  macro_build (&offset_expr, "lwc1", "T,o(b)", treg,
 		       BFD_RELOC_MIPS_LITERAL, mips_gp_register);
-	  return;
+	  break;
 	}
 
     case M_LI_D:
@@ -6294,7 +6277,7 @@ macro (struct mips_cl_insn *ip)
 		    }
 		}
 	    }
-	  return;
+	  break;
 	}
 
       /* We know that sym is in the .rdata section.  First we get the
@@ -6302,20 +6285,26 @@ macro (struct mips_cl_insn *ip)
       if (mips_pic == NO_PIC)
 	{
 	  macro_build_lui (&offset_expr, AT);
+	  used_at = 1;
 	}
       else if (mips_pic == SVR4_PIC)
 	{
 	  macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", AT,
 		       BFD_RELOC_MIPS_GOT16, mips_gp_register);
+	  used_at = 1;
 	}
       else
 	abort ();
 
       /* Now we load the register(s).  */
       if (HAVE_64BIT_GPRS)
-	macro_build (&offset_expr, "ld", "t,o(b)", treg, BFD_RELOC_LO16, AT);
+	{
+	  used_at = 1;
+	  macro_build (&offset_expr, "ld", "t,o(b)", treg, BFD_RELOC_LO16, AT);
+	}
       else
 	{
+	  used_at = 1;
 	  macro_build (&offset_expr, "lw", "t,o(b)", treg, BFD_RELOC_LO16, AT);
 	  if (treg != RA)
 	    {
@@ -6336,6 +6325,7 @@ macro (struct mips_cl_insn *ip)
          OFFSET_EXPR.  */
       if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)
 	{
+	  used_at = 1;
 	  load_register (AT, &imm_expr, HAVE_64BIT_FPRS);
 	  if (HAVE_64BIT_FPRS)
 	    {
@@ -6366,7 +6356,7 @@ macro (struct mips_cl_insn *ip)
 	    {
 	      macro_build (&offset_expr, "ldc1", "T,o(b)", treg,
 			   BFD_RELOC_MIPS_LITERAL, mips_gp_register);
-	      return;
+	      break;
 	    }
 	  breg = mips_gp_register;
 	  r = BFD_RELOC_MIPS_LITERAL;
@@ -6375,6 +6365,7 @@ macro (struct mips_cl_insn *ip)
       else
 	{
 	  assert (strcmp (s, RDATA_SECTION_NAME) == 0);
+	  used_at = 1;
 	  if (mips_pic == SVR4_PIC)
 	    macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", AT,
 			 BFD_RELOC_MIPS_GOT16, mips_gp_register);
@@ -6399,7 +6390,7 @@ macro (struct mips_cl_insn *ip)
       if (mips_opts.arch == CPU_R4650)
 	{
 	  as_bad (_("opcode not supported on this processor"));
-	  return;
+	  break;
 	}
       /* Even on a big endian machine $fn comes before $fn+1.  We have
 	 to adjust when loading from memory.  */
@@ -6413,9 +6404,6 @@ macro (struct mips_cl_insn *ip)
       offset_expr.X_add_number += 4;
       macro_build (&offset_expr, "lwc1", "T,o(b)",
 		   target_big_endian ? treg : treg + 1, r, breg);
-
-      if (breg != AT)
-	return;
       break;
 
     case M_L_DAB:
@@ -6433,7 +6421,7 @@ macro (struct mips_cl_insn *ip)
       if (mips_opts.arch == CPU_R4650)
 	{
 	  as_bad (_("opcode not supported on this processor"));
-	  return;
+	  break;
 	}
       /* Itbl support may require additional care here.  */
       coproc = 1;
@@ -6451,7 +6439,7 @@ macro (struct mips_cl_insn *ip)
       if (mips_opts.arch == CPU_R4650)
 	{
 	  as_bad (_("opcode not supported on this processor"));
-	  return;
+	  break;
 	}
 
       if (mips_opts.isa != ISA_MIPS1)
@@ -6574,6 +6562,7 @@ macro (struct mips_cl_insn *ip)
 		  offset_expr.X_op = O_constant;
 		}
 	    }
+	  used_at = 1;
 	  macro_build_lui (&offset_expr, AT);
 	  if (breg != 0)
 	    macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, breg, AT);
@@ -6713,9 +6702,6 @@ macro (struct mips_cl_insn *ip)
       else
 	abort ();
 
-      if (!used_at)
-	return;
-
       break;
 
     case M_LD_OB:
@@ -6728,7 +6714,7 @@ macro (struct mips_cl_insn *ip)
       macro_build (&offset_expr, s, "t,o(b)", treg, BFD_RELOC_LO16, breg);
       offset_expr.X_add_number += 4;
       macro_build (&offset_expr, s, "t,o(b)", treg + 1, BFD_RELOC_LO16, breg);
-      return;
+      break;
 
    /* New code added to support COPZ instructions.
       This code builds table entries out of the macros in mip_opcodes.
@@ -6762,11 +6748,11 @@ macro (struct mips_cl_insn *ip)
       /* For now we just do C (same as Cz).  The parameter will be
          stored in insn_opcode by mips_ip.  */
       macro_build (NULL, s, "C", ip->insn_opcode);
-      return;
+      break;
 
     case M_MOVE:
       move_register (dreg, sreg);
-      return;
+      break;
 
 #ifdef LOSING_COMPILER
     default:
@@ -6785,13 +6771,13 @@ macro (struct mips_cl_insn *ip)
 	  s2 = "cop3";
 	  coproc = ITBL_DECODE_PNUM (immed_expr);;
 	  macro_build (&immed_expr, s, "C");
-	  return;
+	  break;
 	}
       macro2 (ip);
-      return;
+      break;
     }
-  if (mips_opts.noat)
-    as_warn (_("Macro used $at after \".set noat\""));
+  if (mips_opts.noat && used_at)
+    as_bad (_("Macro used $at after \".set noat\""));
 }
 
 static void
@@ -6833,7 +6819,7 @@ macro2 (struct mips_cl_insn *ip)
     case M_MUL:
       macro_build (NULL, dbl ? "dmultu" : "multu", "s,t", sreg, treg);
       macro_build (NULL, "mflo", "d", dreg);
-      return;
+      break;
 
     case M_DMUL_I:
       dbl = 1;
@@ -6841,6 +6827,7 @@ macro2 (struct mips_cl_insn *ip)
       /* The MIPS assembler some times generates shifts and adds.  I'm
 	 not trying to be that fancy. GCC should do this for us
 	 anyway.  */
+      used_at = 1;
       load_register (AT, &imm_expr, dbl);
       macro_build (NULL, dbl ? "dmult" : "mult", "s,t", sreg, AT);
       macro_build (NULL, "mflo", "d", dreg);
@@ -6859,6 +6846,7 @@ macro2 (struct mips_cl_insn *ip)
       mips_emit_delays (TRUE);
       ++mips_opts.noreorder;
       mips_any_noreorder = 1;
+      used_at = 1;
       if (imm)
 	load_register (AT, &imm_expr, dbl);
       macro_build (NULL, dbl ? "dmult" : "mult", "s,t", sreg, imm ? AT : treg);
@@ -6891,6 +6879,7 @@ macro2 (struct mips_cl_insn *ip)
       mips_emit_delays (TRUE);
       ++mips_opts.noreorder;
       mips_any_noreorder = 1;
+      used_at = 1;
       if (imm)
 	load_register (AT, &imm_expr, dbl);
       macro_build (NULL, dbl ? "dmultu" : "multu", "s,t",
@@ -6923,10 +6912,9 @@ macro2 (struct mips_cl_insn *ip)
 	    }
 	  macro_build (NULL, "dnegu", "d,w", tempreg, treg);
 	  macro_build (NULL, "drorv", "d,t,s", dreg, sreg, tempreg);
-	  if (used_at)
-	    break;
-	  return;
+	  break;
 	}
+      used_at = 1;
       macro_build (NULL, "dsubu", "d,v,t", AT, 0, treg);
       macro_build (NULL, "dsrlv", "d,t,s", AT, sreg, AT);
       macro_build (NULL, "dsllv", "d,t,s", dreg, sreg, treg);
@@ -6947,10 +6935,9 @@ macro2 (struct mips_cl_insn *ip)
 	    }
 	  macro_build (NULL, "negu", "d,w", tempreg, treg);
 	  macro_build (NULL, "rorv", "d,t,s", dreg, sreg, tempreg);
-	  if (used_at)
-	    break;
-	  return;
+	  break;
 	}
+      used_at = 1;
       macro_build (NULL, "subu", "d,v,t", AT, 0, treg);
       macro_build (NULL, "srlv", "d,t,s", AT, sreg, AT);
       macro_build (NULL, "sllv", "d,t,s", dreg, sreg, treg);
@@ -6972,16 +6959,17 @@ macro2 (struct mips_cl_insn *ip)
 	      macro_build (NULL, "dror32", "d,w,<", dreg, sreg, rot - 32);
 	    else
 	      macro_build (NULL, "dror", "d,w,<", dreg, sreg, rot);
-	    return;
+	    break;
 	  }
 	if (rot == 0)
 	  {
 	    macro_build (NULL, "dsrl", "d,w,<", dreg, sreg, 0);
-	    return;
+	    break;
 	  }
 	l = (rot < 0x20) ? "dsll" : "dsll32";
 	r = ((0x40 - rot) < 0x20) ? "dsrl" : "dsrl32";
 	rot &= 0x1f;
+	used_at = 1;
 	macro_build (NULL, l, "d,w,<", AT, sreg, rot);
 	macro_build (NULL, r, "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
 	macro_build (NULL, "or", "d,v,t", dreg, dreg, AT);
@@ -6998,13 +6986,14 @@ macro2 (struct mips_cl_insn *ip)
 	if (ISA_HAS_ROR (mips_opts.isa) || CPU_HAS_ROR (mips_opts.arch))
 	  {
 	    macro_build (NULL, "ror", "d,w,<", dreg, sreg, (32 - rot) & 0x1f);
-	    return;
+	    break;
 	  }
 	if (rot == 0)
 	  {
 	    macro_build (NULL, "srl", "d,w,<", dreg, sreg, 0);
-	    return;
+	    break;
 	  }
+	used_at = 1;
 	macro_build (NULL, "sll", "d,w,<", AT, sreg, rot);
 	macro_build (NULL, "srl", "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
 	macro_build (NULL, "or", "d,v,t", dreg, dreg, AT);
@@ -7015,8 +7004,9 @@ macro2 (struct mips_cl_insn *ip)
       if (ISA_HAS_DROR (mips_opts.isa) || CPU_HAS_DROR (mips_opts.arch))
 	{
 	  macro_build (NULL, "drorv", "d,t,s", dreg, sreg, treg);
-	  return;
+	  break;
 	}
+      used_at = 1;
       macro_build (NULL, "dsubu", "d,v,t", AT, 0, treg);
       macro_build (NULL, "dsllv", "d,t,s", AT, sreg, AT);
       macro_build (NULL, "dsrlv", "d,t,s", dreg, sreg, treg);
@@ -7027,8 +7017,9 @@ macro2 (struct mips_cl_insn *ip)
       if (ISA_HAS_ROR (mips_opts.isa) || CPU_HAS_ROR (mips_opts.arch))
 	{
 	  macro_build (NULL, "rorv", "d,t,s", dreg, sreg, treg);
-	  return;
+	  break;
 	}
+      used_at = 1;
       macro_build (NULL, "subu", "d,v,t", AT, 0, treg);
       macro_build (NULL, "sllv", "d,t,s", AT, sreg, AT);
       macro_build (NULL, "srlv", "d,t,s", dreg, sreg, treg);
@@ -7049,16 +7040,17 @@ macro2 (struct mips_cl_insn *ip)
 	      macro_build (NULL, "dror32", "d,w,<", dreg, sreg, rot - 32);
 	    else
 	      macro_build (NULL, "dror", "d,w,<", dreg, sreg, rot);
-	    return;
+	    break;
 	  }
 	if (rot == 0)
 	  {
 	    macro_build (NULL, "dsrl", "d,w,<", dreg, sreg, 0);
-	    return;
+	    break;
 	  }
 	r = (rot < 0x20) ? "dsrl" : "dsrl32";
 	l = ((0x40 - rot) < 0x20) ? "dsll" : "dsll32";
 	rot &= 0x1f;
+	used_at = 1;
 	macro_build (NULL, r, "d,w,<", AT, sreg, rot);
 	macro_build (NULL, l, "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
 	macro_build (NULL, "or", "d,v,t", dreg, dreg, AT);
@@ -7075,13 +7067,14 @@ macro2 (struct mips_cl_insn *ip)
 	if (ISA_HAS_ROR (mips_opts.isa) || CPU_HAS_ROR (mips_opts.arch))
 	  {
 	    macro_build (NULL, "ror", "d,w,<", dreg, sreg, rot);
-	    return;
+	    break;
 	  }
 	if (rot == 0)
 	  {
 	    macro_build (NULL, "srl", "d,w,<", dreg, sreg, 0);
-	    return;
+	    break;
 	  }
+	used_at = 1;
 	macro_build (NULL, "srl", "d,w,<", AT, sreg, rot);
 	macro_build (NULL, "sll", "d,w,<", dreg, sreg, (0x20 - rot) & 0x1f);
 	macro_build (NULL, "or", "d,v,t", dreg, dreg, AT);
@@ -7092,7 +7085,7 @@ macro2 (struct mips_cl_insn *ip)
       if (mips_opts.arch == CPU_R4650)
 	{
 	  as_bad (_("opcode not supported on this processor"));
-	  return;
+	  break;
 	}
       assert (mips_opts.isa == ISA_MIPS1);
       /* Even on a big endian machine $fn comes before $fn+1.  We have
@@ -7102,7 +7095,7 @@ macro2 (struct mips_cl_insn *ip)
       offset_expr.X_add_number += 4;
       macro_build (&offset_expr, "swc1", "T,o(b)",
 		   target_big_endian ? treg : treg + 1, BFD_RELOC_LO16, breg);
-      return;
+      break;
 
     case M_SEQ:
       if (sreg == 0)
@@ -7114,20 +7107,20 @@ macro2 (struct mips_cl_insn *ip)
 	  macro_build (NULL, "xor", "d,v,t", dreg, sreg, treg);
 	  macro_build (&expr1, "sltiu", "t,r,j", dreg, dreg, BFD_RELOC_LO16);
 	}
-      return;
+      break;
 
     case M_SEQ_I:
       if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
 	{
 	  macro_build (&expr1, "sltiu", "t,r,j", dreg, sreg, BFD_RELOC_LO16);
-	  return;
+	  break;
 	}
       if (sreg == 0)
 	{
 	  as_warn (_("Instruction %s: result is always false"),
 		   ip->insn_mo->name);
 	  move_register (dreg, 0);
-	  return;
+	  break;
 	}
       if (imm_expr.X_op == O_constant
 	  && imm_expr.X_add_number >= 0
@@ -7150,9 +7143,7 @@ macro2 (struct mips_cl_insn *ip)
 	  used_at = 1;
 	}
       macro_build (&expr1, "sltiu", "t,r,j", dreg, dreg, BFD_RELOC_LO16);
-      if (used_at)
-	break;
-      return;
+      break;
 
     case M_SGE:		/* sreg >= treg <==> not (sreg < treg) */
       s = "slt";
@@ -7162,7 +7153,7 @@ macro2 (struct mips_cl_insn *ip)
     sge:
       macro_build (NULL, s, "d,v,t", dreg, sreg, treg);
       macro_build (&expr1, "xori", "t,r,i", dreg, dreg, BFD_RELOC_LO16);
-      return;
+      break;
 
     case M_SGE_I:		/* sreg >= I <==> not (sreg < I) */
     case M_SGEU_I:
@@ -7181,9 +7172,7 @@ macro2 (struct mips_cl_insn *ip)
 	  used_at = 1;
 	}
       macro_build (&expr1, "xori", "t,r,i", dreg, dreg, BFD_RELOC_LO16);
-      if (used_at)
-	break;
-      return;
+      break;
 
     case M_SGT:		/* sreg > treg  <==>  treg < sreg */
       s = "slt";
@@ -7192,7 +7181,7 @@ macro2 (struct mips_cl_insn *ip)
       s = "sltu";
     sgt:
       macro_build (NULL, s, "d,v,t", dreg, treg, sreg);
-      return;
+      break;
 
     case M_SGT_I:		/* sreg > I  <==>  I < sreg */
       s = "slt";
@@ -7200,6 +7189,7 @@ macro2 (struct mips_cl_insn *ip)
     case M_SGTU_I:
       s = "sltu";
     sgti:
+      used_at = 1;
       load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
       macro_build (NULL, s, "d,v,t", dreg, AT, sreg);
       break;
@@ -7212,7 +7202,7 @@ macro2 (struct mips_cl_insn *ip)
     sle:
       macro_build (NULL, s, "d,v,t", dreg, treg, sreg);
       macro_build (&expr1, "xori", "t,r,i", dreg, dreg, BFD_RELOC_LO16);
-      return;
+      break;
 
     case M_SLE_I:	/* sreg <= I <==> I >= sreg <==> not (I < sreg) */
       s = "slt";
@@ -7220,6 +7210,7 @@ macro2 (struct mips_cl_insn *ip)
     case M_SLEU_I:
       s = "sltu";
     slei:
+      used_at = 1;
       load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
       macro_build (NULL, s, "d,v,t", dreg, AT, sreg);
       macro_build (&expr1, "xori", "t,r,i", dreg, dreg, BFD_RELOC_LO16);
@@ -7231,8 +7222,9 @@ macro2 (struct mips_cl_insn *ip)
 	  && imm_expr.X_add_number < 0x8000)
 	{
 	  macro_build (&imm_expr, "slti", "t,r,j", dreg, sreg, BFD_RELOC_LO16);
-	  return;
+	  break;
 	}
+      used_at = 1;
       load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
       macro_build (NULL, "slt", "d,v,t", dreg, sreg, AT);
       break;
@@ -7244,8 +7236,9 @@ macro2 (struct mips_cl_insn *ip)
 	{
 	  macro_build (&imm_expr, "sltiu", "t,r,j", dreg, sreg,
 		       BFD_RELOC_LO16);
-	  return;
+	  break;
 	}
+      used_at = 1;
       load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
       macro_build (NULL, "sltu", "d,v,t", dreg, sreg, AT);
       break;
@@ -7260,13 +7253,13 @@ macro2 (struct mips_cl_insn *ip)
 	  macro_build (NULL, "xor", "d,v,t", dreg, sreg, treg);
 	  macro_build (NULL, "sltu", "d,v,t", dreg, 0, dreg);
 	}
-      return;
+      break;
 
     case M_SNE_I:
       if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
 	{
 	  macro_build (NULL, "sltu", "d,v,t", dreg, 0, sreg);
-	  return;
+	  break;
 	}
       if (sreg == 0)
 	{
@@ -7274,7 +7267,7 @@ macro2 (struct mips_cl_insn *ip)
 		   ip->insn_mo->name);
 	  macro_build (&expr1, HAVE_32BIT_GPRS ? "addiu" : "daddiu", "t,r,j",
 		       dreg, 0, BFD_RELOC_LO16);
-	  return;
+	  break;
 	}
       if (imm_expr.X_op == O_constant
 	  && imm_expr.X_add_number >= 0
@@ -7297,9 +7290,7 @@ macro2 (struct mips_cl_insn *ip)
 	  used_at = 1;
 	}
       macro_build (NULL, "sltu", "d,v,t", dreg, 0, dreg);
-      if (used_at)
-	break;
-      return;
+      break;
 
     case M_DSUB_I:
       dbl = 1;
@@ -7311,8 +7302,9 @@ macro2 (struct mips_cl_insn *ip)
 	  imm_expr.X_add_number = -imm_expr.X_add_number;
 	  macro_build (&imm_expr, dbl ? "daddi" : "addi", "t,r,j",
 		       dreg, sreg, BFD_RELOC_LO16);
-	  return;
+	  break;
 	}
+      used_at = 1;
       load_register (AT, &imm_expr, dbl);
       macro_build (NULL, dbl ? "dsub" : "sub", "d,v,t", dreg, sreg, AT);
       break;
@@ -7327,8 +7319,9 @@ macro2 (struct mips_cl_insn *ip)
 	  imm_expr.X_add_number = -imm_expr.X_add_number;
 	  macro_build (&imm_expr, dbl ? "daddiu" : "addiu", "t,r,j",
 		       dreg, sreg, BFD_RELOC_LO16);
-	  return;
+	  break;
 	}
+      used_at = 1;
       load_register (AT, &imm_expr, dbl);
       macro_build (NULL, dbl ? "dsubu" : "subu", "d,v,t", dreg, sreg, AT);
       break;
@@ -7351,6 +7344,7 @@ macro2 (struct mips_cl_insn *ip)
     case M_TNE_I:
       s = "tne";
     trap:
+      used_at = 1;
       load_register (AT, &imm_expr, HAVE_64BIT_GPRS);
       macro_build (NULL, s, "s,t", sreg, AT);
       break;
@@ -7358,6 +7352,7 @@ macro2 (struct mips_cl_insn *ip)
     case M_TRUNCWS:
     case M_TRUNCWD:
       assert (mips_opts.isa == ISA_MIPS1);
+      used_at = 1;
       sreg = (ip->insn_opcode >> 11) & 0x1f;	/* floating reg */
       dreg = (ip->insn_opcode >> 06) & 0x1f;	/* floating reg */
 
@@ -7390,6 +7385,7 @@ macro2 (struct mips_cl_insn *ip)
     case M_ULHU:
       s = "lbu";
     ulh:
+      used_at = 1;
       if (offset_expr.X_add_number >= 0x7fff)
 	as_bad (_("operand overflow"));
       if (! target_big_endian)
@@ -7419,7 +7415,10 @@ macro2 (struct mips_cl_insn *ip)
       if (treg != breg)
 	tempreg = treg;
       else
-	tempreg = AT;
+	{
+	  used_at = 1;
+	  tempreg = AT;
+	}
       if (! target_big_endian)
 	offset_expr.X_add_number += off;
       macro_build (&offset_expr, s, "t,o(b)", tempreg, BFD_RELOC_LO16, breg);
@@ -7431,7 +7430,7 @@ macro2 (struct mips_cl_insn *ip)
 
       /* If necessary, move the result in tempreg the final destination.  */
       if (treg == tempreg)
-        return;
+        break;
       /* Protect second load's delay slot.  */
       load_delay_nop ();
       move_register (treg, tempreg);
@@ -7483,6 +7482,7 @@ macro2 (struct mips_cl_insn *ip)
       break;
 
     case M_USH:
+      used_at = 1;
       if (offset_expr.X_add_number >= 0x7fff)
 	as_bad (_("operand overflow"));
       if (target_big_endian)
@@ -7516,7 +7516,7 @@ macro2 (struct mips_cl_insn *ip)
       else
 	offset_expr.X_add_number += off;
       macro_build (&offset_expr, s2, "t,o(b)", treg, BFD_RELOC_LO16, breg);
-      return;
+      break;
 
     case M_USD_A:
       s = "sdl";
@@ -7573,8 +7573,8 @@ macro2 (struct mips_cl_insn *ip)
       as_bad (_("Macro %s not implemented yet"), ip->insn_mo->name);
       break;
     }
-  if (mips_opts.noat)
-    as_warn (_("Macro used $at after \".set noat\""));
+  if (mips_opts.noat && used_at)
+    as_bad (_("Macro used $at after \".set noat\""));
 }
 
 /* Implement macros in mips16 mode.  */
@@ -7664,7 +7664,7 @@ mips16_macro (struct mips_cl_insn *ip)
     case M_MUL:
       macro_build (NULL, dbl ? "dmultu" : "multu", "x,y", xreg, yreg);
       macro_build (NULL, "mflo", "x", zreg);
-      return;
+      break;
 
     case M_DSUBU_I:
       dbl = 1;
Index: gas/testsuite/gas/mips/mips.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips.exp,v
retrieving revision 1.98
diff -u -p -r1.98 mips.exp
--- gas/testsuite/gas/mips/mips.exp	15 Feb 2005 19:57:53 -0000	1.98
+++ gas/testsuite/gas/mips/mips.exp	17 Feb 2005 17:03:52 -0000
@@ -738,4 +738,12 @@ if { [istarget mips*-*-*] } then {
 	run_dump_test "macro-warn-1-n32"
 	run_dump_test "macro-warn-2-n32"
     }
+
+    run_dump_test "noat-1"
+    run_list_test "noat-2" ""
+    run_list_test "noat-3" ""
+    run_list_test "noat-4" ""
+    run_list_test "noat-5" ""
+    run_list_test "noat-6" ""
+    run_list_test "noat-7" ""
 }
Index: gas/testsuite/gas/mips/noat-1.d
===================================================================
RCS file: gas/testsuite/gas/mips/noat-1.d
diff -N gas/testsuite/gas/mips/noat-1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-1.d	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,15 @@
+#as: -32
+#objdump: -dr
+
+.*: +file format .*mips
+
+Disassembly of section \.text:
+
+00000000 <\.text>:
+   0:	8f7b7fff 	lw	k1,32767\(k1\)
+   4:	00000000 	nop
+   8:	8f7b8000 	lw	k1,-32768\(k1\)
+   c:	00000000 	nop
+  10:	af7b7fff 	sw	k1,32767\(k1\)
+  14:	af7b8000 	sw	k1,-32768\(k1\)
+	\.\.\.
Index: gas/testsuite/gas/mips/noat-1.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-1.s
diff -N gas/testsuite/gas/mips/noat-1.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-1.s	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,7 @@
+	.set noat
+	lw $27, 0x7fff($27)
+	lw $27, -0x8000($27)
+	sw $27, 0x7fff($27)
+	sw $27, -0x8000($27)
+
+	.space 8
Index: gas/testsuite/gas/mips/noat-2.l
===================================================================
RCS file: gas/testsuite/gas/mips/noat-2.l
diff -N gas/testsuite/gas/mips/noat-2.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-2.l	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,2 @@
+.*\.s: Assembler messages:
+.*\.s:2: Error: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/noat-2.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-2.s
diff -N gas/testsuite/gas/mips/noat-2.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-2.s	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,4 @@
+	.set noat
+	lw $27, 0x8000($27)
+
+	.space 8
Index: gas/testsuite/gas/mips/noat-3.l
===================================================================
RCS file: gas/testsuite/gas/mips/noat-3.l
diff -N gas/testsuite/gas/mips/noat-3.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-3.l	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,2 @@
+.*\.s: Assembler messages:
+.*\.s:2: Error: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/noat-3.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-3.s
diff -N gas/testsuite/gas/mips/noat-3.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-3.s	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,4 @@
+	.set noat
+	lw $27, -0x8001($27)
+
+	.space 8
Index: gas/testsuite/gas/mips/noat-4.l
===================================================================
RCS file: gas/testsuite/gas/mips/noat-4.l
diff -N gas/testsuite/gas/mips/noat-4.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-4.l	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,2 @@
+.*\.s: Assembler messages:
+.*\.s:2: Error: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/noat-4.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-4.s
diff -N gas/testsuite/gas/mips/noat-4.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-4.s	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,4 @@
+	.set noat
+	lw $27, symbol($27)
+
+	.space 8
Index: gas/testsuite/gas/mips/noat-5.l
===================================================================
RCS file: gas/testsuite/gas/mips/noat-5.l
diff -N gas/testsuite/gas/mips/noat-5.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-5.l	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,2 @@
+.*\.s: Assembler messages:
+.*\.s:2: Error: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/noat-5.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-5.s
diff -N gas/testsuite/gas/mips/noat-5.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-5.s	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,4 @@
+	.set noat
+	sw $27, 0x8000($27)
+
+	.space 8
Index: gas/testsuite/gas/mips/noat-6.l
===================================================================
RCS file: gas/testsuite/gas/mips/noat-6.l
diff -N gas/testsuite/gas/mips/noat-6.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-6.l	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,2 @@
+.*\.s: Assembler messages:
+.*\.s:2: Error: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/noat-6.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-6.s
diff -N gas/testsuite/gas/mips/noat-6.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-6.s	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,4 @@
+	.set noat
+	sw $27, -0x8001($27)
+
+	.space 8
Index: gas/testsuite/gas/mips/noat-7.l
===================================================================
RCS file: gas/testsuite/gas/mips/noat-7.l
diff -N gas/testsuite/gas/mips/noat-7.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-7.l	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,2 @@
+.*\.s: Assembler messages:
+.*\.s:2: Error: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/noat-7.s
===================================================================
RCS file: gas/testsuite/gas/mips/noat-7.s
diff -N gas/testsuite/gas/mips/noat-7.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/mips/noat-7.s	17 Feb 2005 17:03:52 -0000
@@ -0,0 +1,4 @@
+	.set noat
+	sw $27, symbol($27)
+
+	.space 8
Index: gas/testsuite/gas/mips/rol-hw.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/rol-hw.d,v
retrieving revision 1.3
diff -u -p -r1.3 rol-hw.d
--- gas/testsuite/gas/mips/rol-hw.d	7 May 2003 05:08:20 -0000	1.3
+++ gas/testsuite/gas/mips/rol-hw.d	17 Feb 2005 17:03:52 -0000
@@ -1,7 +1,6 @@
 #objdump: -dr --prefix-addresses
 #name: MIPS hardware rol/ror
 #source: rol.s
-#stderr: rol-hw.l
 #as: -32
 
 # Test the rol and ror macros.
Index: gas/testsuite/gas/mips/rol-hw.l
===================================================================
RCS file: gas/testsuite/gas/mips/rol-hw.l
diff -N gas/testsuite/gas/mips/rol-hw.l
--- gas/testsuite/gas/mips/rol-hw.l	18 Dec 2002 22:52:48 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,2 +0,0 @@
-.*: Assembler messages:
-.*:7: Warning: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/rol.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/rol.d,v
retrieving revision 1.7
diff -u -p -r1.7 rol.d
--- gas/testsuite/gas/mips/rol.d	7 May 2003 05:08:20 -0000	1.7
+++ gas/testsuite/gas/mips/rol.d	17 Feb 2005 17:03:52 -0000
@@ -1,6 +1,5 @@
 #objdump: -dr --prefix-addresses
 #name: MIPS macro rol/ror
-#stderr: rol.l
 #as: -32
 
 # Test the rol and ror macros.
Index: gas/testsuite/gas/mips/rol.l
===================================================================
RCS file: gas/testsuite/gas/mips/rol.l
diff -N gas/testsuite/gas/mips/rol.l
--- gas/testsuite/gas/mips/rol.l	18 Dec 2002 22:52:48 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,13 +0,0 @@
-.*: Assembler messages:
-.*:7: Warning: Macro used \$at after "\.set noat"
-.*:8: Warning: Macro used \$at after "\.set noat"
-.*:9: Warning: Macro used \$at after "\.set noat"
-.*:10: Warning: Macro used \$at after "\.set noat"
-.*:13: Warning: Macro used \$at after "\.set noat"
-.*:14: Warning: Macro used \$at after "\.set noat"
-.*:15: Warning: Macro used \$at after "\.set noat"
-.*:16: Warning: Macro used \$at after "\.set noat"
-.*:20: Warning: Macro used \$at after "\.set noat"
-.*:21: Warning: Macro used \$at after "\.set noat"
-.*:24: Warning: Macro used \$at after "\.set noat"
-.*:25: Warning: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/rol.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/rol.s,v
retrieving revision 1.3
diff -u -p -r1.3 rol.s
--- gas/testsuite/gas/mips/rol.s	18 Dec 2002 22:52:48 -0000	1.3
+++ gas/testsuite/gas/mips/rol.s	17 Feb 2005 17:03:52 -0000
@@ -1,8 +1,5 @@
 # Source file used to test the rol and ror macros.
 
-	# generate warnings for all uses of AT.
-	.set noat
-
 foo:
 	rol	$4,$5
 	rol	$4,$5,$6
Index: gas/testsuite/gas/mips/rol64-hw.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/rol64-hw.d,v
retrieving revision 1.2
diff -u -p -r1.2 rol64-hw.d
--- gas/testsuite/gas/mips/rol64-hw.d	27 Dec 2002 23:51:49 -0000	1.2
+++ gas/testsuite/gas/mips/rol64-hw.d	17 Feb 2005 17:03:52 -0000
@@ -1,7 +1,6 @@
 #objdump: -dr --prefix-addresses
 #name: MIPS hardware drol/dror
 #source: rol64.s
-#stderr: rol64-hw.l
 
 # Test the drol and dror macros.
 
Index: gas/testsuite/gas/mips/rol64-hw.l
===================================================================
RCS file: gas/testsuite/gas/mips/rol64-hw.l
diff -N gas/testsuite/gas/mips/rol64-hw.l
--- gas/testsuite/gas/mips/rol64-hw.l	18 Dec 2002 22:52:48 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,2 +0,0 @@
-.*: Assembler messages:
-.*:7: Warning: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/rol64.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/rol64.d,v
retrieving revision 1.4
diff -u -p -r1.4 rol64.d
--- gas/testsuite/gas/mips/rol64.d	27 Dec 2002 23:51:49 -0000	1.4
+++ gas/testsuite/gas/mips/rol64.d	17 Feb 2005 17:03:52 -0000
@@ -1,6 +1,5 @@
 #objdump: -dr --prefix-addresses
 #name: MIPS macro drol/dror
-#stderr: rol64.l
 
 # Test the drol and dror macros.
 
Index: gas/testsuite/gas/mips/rol64.l
===================================================================
RCS file: gas/testsuite/gas/mips/rol64.l
diff -N gas/testsuite/gas/mips/rol64.l
--- gas/testsuite/gas/mips/rol64.l	18 Dec 2002 22:52:48 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,27 +0,0 @@
-.*: Assembler messages:
-.*:7: Warning: Macro used \$at after "\.set noat"
-.*:8: Warning: Macro used \$at after "\.set noat"
-.*:9: Warning: Macro used \$at after "\.set noat"
-.*:11: Warning: Macro used \$at after "\.set noat"
-.*:12: Warning: Macro used \$at after "\.set noat"
-.*:13: Warning: Macro used \$at after "\.set noat"
-.*:14: Warning: Macro used \$at after "\.set noat"
-.*:15: Warning: Macro used \$at after "\.set noat"
-.*:18: Warning: Macro used \$at after "\.set noat"
-.*:19: Warning: Macro used \$at after "\.set noat"
-.*:20: Warning: Macro used \$at after "\.set noat"
-.*:22: Warning: Macro used \$at after "\.set noat"
-.*:23: Warning: Macro used \$at after "\.set noat"
-.*:24: Warning: Macro used \$at after "\.set noat"
-.*:25: Warning: Macro used \$at after "\.set noat"
-.*:26: Warning: Macro used \$at after "\.set noat"
-.*:29: Warning: Macro used \$at after "\.set noat"
-.*:30: Warning: Macro used \$at after "\.set noat"
-.*:31: Warning: Macro used \$at after "\.set noat"
-.*:32: Warning: Macro used \$at after "\.set noat"
-.*:33: Warning: Macro used \$at after "\.set noat"
-.*:35: Warning: Macro used \$at after "\.set noat"
-.*:36: Warning: Macro used \$at after "\.set noat"
-.*:37: Warning: Macro used \$at after "\.set noat"
-.*:38: Warning: Macro used \$at after "\.set noat"
-.*:39: Warning: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/rol64.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/rol64.s,v
retrieving revision 1.2
diff -u -p -r1.2 rol64.s
--- gas/testsuite/gas/mips/rol64.s	18 Dec 2002 22:52:48 -0000	1.2
+++ gas/testsuite/gas/mips/rol64.s	17 Feb 2005 17:03:52 -0000
@@ -1,8 +1,5 @@
 # Source file used to test the drol and dror macros.
 
-	# generate warnings for all uses of AT.
-	.set noat
-
 foo:
 	drol	$4,$5
 	drol	$4,$5,$6
Index: gas/testsuite/gas/mips/uld2-eb.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/uld2-eb.d,v
retrieving revision 1.2
diff -u -p -r1.2 uld2-eb.d
--- gas/testsuite/gas/mips/uld2-eb.d	19 May 2003 19:22:25 -0000	1.2
+++ gas/testsuite/gas/mips/uld2-eb.d	17 Feb 2005 17:03:52 -0000
@@ -2,7 +2,6 @@
 #objdump: -dr --prefix-addresses --show-raw-insn -M reg-names=numeric
 #name: uld2 -EB
 #source: uld2.s
-#stderr: uld2.l
 
 # Further checks of uld macro.
 # XXX: note: when 'move' is changed to use 'or' rather than daddu, the
Index: gas/testsuite/gas/mips/uld2-el.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/uld2-el.d,v
retrieving revision 1.2
diff -u -p -r1.2 uld2-el.d
--- gas/testsuite/gas/mips/uld2-el.d	19 May 2003 19:22:25 -0000	1.2
+++ gas/testsuite/gas/mips/uld2-el.d	17 Feb 2005 17:03:52 -0000
@@ -2,7 +2,6 @@
 #objdump: -dr --prefix-addresses --show-raw-insn -M reg-names=numeric
 #name: uld2 -EL
 #source: uld2.s
-#stderr: uld2.l
 
 # Further checks of uld macro.
 # XXX: note: when 'move' is changed to use 'or' rather than daddu, the
Index: gas/testsuite/gas/mips/uld2.l
===================================================================
RCS file: gas/testsuite/gas/mips/uld2.l
diff -N gas/testsuite/gas/mips/uld2.l
--- gas/testsuite/gas/mips/uld2.l	2 Apr 2003 18:43:16 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,3 +0,0 @@
-.*: Assembler messages:
-.*:11: Warning: Macro used \$at after "\.set noat"
-.*:12: Warning: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/uld2.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/uld2.s,v
retrieving revision 1.1
diff -u -p -r1.1 uld2.s
--- gas/testsuite/gas/mips/uld2.s	2 Apr 2003 18:43:16 -0000	1.1
+++ gas/testsuite/gas/mips/uld2.s	17 Feb 2005 17:03:52 -0000
@@ -1,7 +1,5 @@
 # Source file used to test the uld macro (harder).
 	
-	.set noat
-	
 	.text
 text_label:
 
Index: gas/testsuite/gas/mips/ulh2-eb.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/ulh2-eb.d,v
retrieving revision 1.2
diff -u -p -r1.2 ulh2-eb.d
--- gas/testsuite/gas/mips/ulh2-eb.d	7 May 2003 05:08:20 -0000	1.2
+++ gas/testsuite/gas/mips/ulh2-eb.d	17 Feb 2005 17:03:52 -0000
@@ -2,7 +2,6 @@
 #objdump: -dr --prefix-addresses --show-raw-insn -M reg-names=numeric
 #name: ulh2 -EB
 #source: ulh2.s
-#stderr: ulh2.l
 
 # Further checks of ulh/ulhu macros.
 
Index: gas/testsuite/gas/mips/ulh2-el.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/ulh2-el.d,v
retrieving revision 1.2
diff -u -p -r1.2 ulh2-el.d
--- gas/testsuite/gas/mips/ulh2-el.d	7 May 2003 05:08:20 -0000	1.2
+++ gas/testsuite/gas/mips/ulh2-el.d	17 Feb 2005 17:03:52 -0000
@@ -2,7 +2,6 @@
 #objdump: -dr --prefix-addresses --show-raw-insn -M reg-names=numeric
 #name: ulh2 -EL
 #source: ulh2.s
-#stderr: ulh2.l
 
 # Further checks of ulh/ulhu macros.
 
Index: gas/testsuite/gas/mips/ulh2.l
===================================================================
RCS file: gas/testsuite/gas/mips/ulh2.l
diff -N gas/testsuite/gas/mips/ulh2.l
--- gas/testsuite/gas/mips/ulh2.l	2 Apr 2003 18:43:16 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,9 +0,0 @@
-.*: Assembler messages:
-.*:8: Warning: Macro used \$at after "\.set noat"
-.*:9: Warning: Macro used \$at after "\.set noat"
-.*:11: Warning: Macro used \$at after "\.set noat"
-.*:12: Warning: Macro used \$at after "\.set noat"
-.*:14: Warning: Macro used \$at after "\.set noat"
-.*:15: Warning: Macro used \$at after "\.set noat"
-.*:17: Warning: Macro used \$at after "\.set noat"
-.*:18: Warning: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/ulh2.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/ulh2.s,v
retrieving revision 1.1
diff -u -p -r1.1 ulh2.s
--- gas/testsuite/gas/mips/ulh2.s	2 Apr 2003 18:43:16 -0000	1.1
+++ gas/testsuite/gas/mips/ulh2.s	17 Feb 2005 17:03:52 -0000
@@ -1,7 +1,5 @@
 # Source file used to test the ulh and ulhu macros (harder).
 
-	.set noat
-	
 	.text
 text_label:
 
Index: gas/testsuite/gas/mips/ulw2-eb-ilocks.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/ulw2-eb-ilocks.d,v
retrieving revision 1.2
diff -u -p -r1.2 ulw2-eb-ilocks.d
--- gas/testsuite/gas/mips/ulw2-eb-ilocks.d	7 May 2003 05:08:20 -0000	1.2
+++ gas/testsuite/gas/mips/ulw2-eb-ilocks.d	17 Feb 2005 17:03:52 -0000
@@ -2,7 +2,6 @@
 #objdump: -dr --prefix-addresses --show-raw-insn -M reg-names=numeric
 #name: ulw2 -EB interlocked
 #source: ulw2.s
-#stderr: ulw2.l
 
 # Further checks of ulw macro.
 # XXX: note: when 'move' is changed to use 'or' rather than addu/daddu, the
Index: gas/testsuite/gas/mips/ulw2-eb.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/ulw2-eb.d,v
retrieving revision 1.2
diff -u -p -r1.2 ulw2-eb.d
--- gas/testsuite/gas/mips/ulw2-eb.d	7 May 2003 05:08:20 -0000	1.2
+++ gas/testsuite/gas/mips/ulw2-eb.d	17 Feb 2005 17:03:52 -0000
@@ -2,7 +2,6 @@
 #objdump: -dr --prefix-addresses --show-raw-insn -M reg-names=numeric
 #name: ulw2 -EB non-interlocked
 #source: ulw2.s
-#stderr: ulw2.l
 
 # Further checks of ulw macro.
 # XXX: note: when 'move' is changed to use 'or' rather than addu/daddu, the
Index: gas/testsuite/gas/mips/ulw2-el-ilocks.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/ulw2-el-ilocks.d,v
retrieving revision 1.2
diff -u -p -r1.2 ulw2-el-ilocks.d
--- gas/testsuite/gas/mips/ulw2-el-ilocks.d	7 May 2003 05:08:20 -0000	1.2
+++ gas/testsuite/gas/mips/ulw2-el-ilocks.d	17 Feb 2005 17:03:52 -0000
@@ -2,7 +2,6 @@
 #objdump: -dr --prefix-addresses --show-raw-insn -M reg-names=numeric
 #name: ulw2 -EL interlocked
 #source: ulw2.s
-#stderr: ulw2.l
 
 # Further checks of ulw macro.
 # XXX: note: when 'move' is changed to use 'or' rather than addu/daddu, the
Index: gas/testsuite/gas/mips/ulw2-el.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/ulw2-el.d,v
retrieving revision 1.2
diff -u -p -r1.2 ulw2-el.d
--- gas/testsuite/gas/mips/ulw2-el.d	7 May 2003 05:08:20 -0000	1.2
+++ gas/testsuite/gas/mips/ulw2-el.d	17 Feb 2005 17:03:52 -0000
@@ -2,7 +2,6 @@
 #objdump: -dr --prefix-addresses --show-raw-insn -M reg-names=numeric
 #name: ulw2 -EL non-interlocked
 #source: ulw2.s
-#stderr: ulw2.l
 
 # Further checks of ulw macro.
 # XXX: note: when 'move' is changed to use 'or' rather than addu/daddu, the
Index: gas/testsuite/gas/mips/ulw2.l
===================================================================
RCS file: gas/testsuite/gas/mips/ulw2.l
diff -N gas/testsuite/gas/mips/ulw2.l
--- gas/testsuite/gas/mips/ulw2.l	2 Apr 2003 18:43:16 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,3 +0,0 @@
-.*: Assembler messages:
-.*:11: Warning: Macro used \$at after "\.set noat"
-.*:12: Warning: Macro used \$at after "\.set noat"
Index: gas/testsuite/gas/mips/ulw2.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/ulw2.s,v
retrieving revision 1.1
diff -u -p -r1.1 ulw2.s
--- gas/testsuite/gas/mips/ulw2.s	2 Apr 2003 18:43:16 -0000	1.1
+++ gas/testsuite/gas/mips/ulw2.s	17 Feb 2005 17:03:52 -0000
@@ -1,7 +1,5 @@
 # Source file used to test the ulw macro (harder).
 	
-	.set noat
-	
 	.text
 text_label:
 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] MIPS gas: Fix macro expansions for .set noat
  2005-02-17 21:33               ` Thiemo Seufer
@ 2005-02-18  0:21                 ` Maciej W. Rozycki
  2005-02-21  2:57                   ` Thiemo Seufer
  2005-02-18 23:01                 ` Eric Christopher
  2005-02-21  8:21                 ` Thiemo Seufer
  2 siblings, 1 reply; 13+ messages in thread
From: Maciej W. Rozycki @ 2005-02-18  0:21 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Eric Christopher, binutils

On Thu, 17 Feb 2005, Thiemo Seufer wrote:

> Ok, this patch converts $at uses in .set noat from warnings to errors.

 How about extracting these bits of test cases that used to be expected to 
trigger warnings into separate cases to test if errors are generated 
correctly?

> I haven't changed the .set nomacro behaviour yet, partially because
> this patch is already big enough, and partially because nomacro isn't
> fully equivalent to noat. Nomacro probably shouldn't fail if the number
> of instructions stays the same.

 That's the whole point IMHO.  A macro that expands into a single 
instruction can be seen as a mere alias and it doesn't violate code length 
or delay slot restrictions.  That is I think it should be allowed, for 
readability if nothing else, to call an instruction "li $2,1" instead of 
"addiu $2,$0,1" even with ".set nomacro" in effect.

  Maciej

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] MIPS gas: Fix macro expansions for .set noat
  2005-02-17 21:33               ` Thiemo Seufer
  2005-02-18  0:21                 ` Maciej W. Rozycki
@ 2005-02-18 23:01                 ` Eric Christopher
  2005-02-21  8:21                 ` Thiemo Seufer
  2 siblings, 0 replies; 13+ messages in thread
From: Eric Christopher @ 2005-02-18 23:01 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Maciej W. Rozycki, binutils


> Ok, this patch converts $at uses in .set noat from warnings to errors.
> I haven't changed the .set nomacro behaviour yet, partially because
> this patch is already big enough, and partially because nomacro isn't
> fully equivalent to noat. Nomacro probably shouldn't fail if the number
> of instructions stays the same.

Agreed.

-eric

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] MIPS gas: Fix macro expansions for .set noat
  2005-02-18  0:21                 ` Maciej W. Rozycki
@ 2005-02-21  2:57                   ` Thiemo Seufer
  0 siblings, 0 replies; 13+ messages in thread
From: Thiemo Seufer @ 2005-02-21  2:57 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Eric Christopher, binutils

Maciej W. Rozycki wrote:
> On Thu, 17 Feb 2005, Thiemo Seufer wrote:
> 
> > Ok, this patch converts $at uses in .set noat from warnings to errors.
> 
>  How about extracting these bits of test cases that used to be expected to 
> trigger warnings into separate cases to test if errors are generated 
> correctly?

Feel free to provide a patch. :-)


Thiemo

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] MIPS gas: Fix macro expansions for .set noat
  2005-02-17 21:33               ` Thiemo Seufer
  2005-02-18  0:21                 ` Maciej W. Rozycki
  2005-02-18 23:01                 ` Eric Christopher
@ 2005-02-21  8:21                 ` Thiemo Seufer
  2 siblings, 0 replies; 13+ messages in thread
From: Thiemo Seufer @ 2005-02-21  8:21 UTC (permalink / raw)
  To: binutils

Thiemo Seufer wrote:
[snip]
> 2005-02-17  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>
> 
> 	/gas/ChangeLog
> 	* config/tc-mips.c (macro_build_ldst_constoffset): Fail on $at
> 	uses after .set noat.
> 	(load_address): Likewise.
> 	(macro): Likewise. Don't try to avoid $at use by sacrificing
> 	the target register before it is stored, it won't work.
> 
> 	/gas/testsuite/ChangeLog
> 	* gas/mips/noat-1.s, gas/mips/noat-1.d, gas/mips/noat-2.s,
> 	gas/mips/noat2.l, gas/mips/noat-3.s, gas/mips/noat-3.l,
> 	gas/mips/noat-4.s, gas/mips/noat-4.l, gas/mips/noat-5.s,
> 	gas/mips/noat-5.l, gas/mips/noat-6.s, gas/mips/noat-6.l,
> 	gas/mips/noat-7.s, gas/mips/noat-7.l: New files, testcases for
> 	.set noat in macro expansions.
> 	* gas/mips/mips.exp: Run new testcases.
> 	* gas/mips/rol-hw.d, gas/mips/rol-hw.l, gas/mips/rol.d,
> 	gas/mips/rol.l, gas/mips/rol.s, gas/mips/rol64-hw.d,
> 	gas/mips/rol64-hw.l, gas/mips/rol64.d, gas/mips/rol64.l,
> 	gas/mips/rol64.s, gas/mips/uld2-eb.d, gas/mips/uld2-el.d,
> 	gas/mips/uld2.l, gas/mips/uld2.s, gas/mips/ulh2-eb.d,
> 	gas/mips/ulh2-el.d, gas/mips/ulh2.l, gas/mips/ulh2.s,
> 	gas/mips/ulw2-eb-ilocks.d, gas/mips/ulw2-eb.d,
> 	gas/mips/ulw2-el-ilocks.d, gas/mips/ulw2-el.d, gas/mips/ulw2.l,
> 	gas/mips/ulw2.s: Don't try to test .set noat.

Committed.


Thiemo

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2005-02-18 22:14 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-16 23:51 [PATCH] MIPS gas: Fix macro expansions for .set noat Thiemo Seufer
2005-02-17  0:25 ` Maciej W. Rozycki
2005-02-17  1:31   ` Maciej W. Rozycki
2005-02-17  1:34     ` Thiemo Seufer
2005-02-17  2:02       ` Maciej W. Rozycki
2005-02-17  7:10         ` Thiemo Seufer
2005-02-17 13:53           ` Eric Christopher
2005-02-17 20:50             ` Maciej W. Rozycki
2005-02-17 21:33               ` Thiemo Seufer
2005-02-18  0:21                 ` Maciej W. Rozycki
2005-02-21  2:57                   ` Thiemo Seufer
2005-02-18 23:01                 ` Eric Christopher
2005-02-21  8:21                 ` Thiemo Seufer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).