diff --git a/gas/ChangeLog b/gas/ChangeLog
index 0469acbc0c7..209bd809aba 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2001-05-03  Alan Modra  <amodra@one.net.au>
+
+	* config/tc-i386.c (i386_displacement): Call as_bad for bad GOTOFF
+	expressions rather than triggering an assert.
+
 2001-05-02  Johan Rydberg  <jrydberg@opencores.org>
 
         * config/tc-openrisc.c: New file.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 69dd6c0c95a..57b9b0fd03d 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -3466,26 +3466,6 @@ i386_displacement (disp_start, disp_end)
 
   exp_seg = expression (exp);
 
-#ifdef BFD_ASSEMBLER
-  /* We do this to make sure that the section symbol is in
-     the symbol table.  We will ultimately change the relocation
-     to be relative to the beginning of the section.  */
-  if (i.reloc[this_operand] == BFD_RELOC_386_GOTOFF
-      || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
-    {
-      if (S_IS_LOCAL (exp->X_add_symbol)
-	  && S_GET_SEGMENT (exp->X_add_symbol) != undefined_section)
-	section_symbol (S_GET_SEGMENT (exp->X_add_symbol));
-      assert (exp->X_op == O_symbol);
-      exp->X_op = O_subtract;
-      exp->X_op_symbol = GOT_symbol;
-      if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
-        i.reloc[this_operand] = BFD_RELOC_32_PCREL;
-      else
-        i.reloc[this_operand] = BFD_RELOC_32;
-    }
-#endif
-
   SKIP_WHITESPACE ();
   if (*input_line_pointer)
     as_bad (_("junk `%s' after expression"), input_line_pointer);
@@ -3499,6 +3479,34 @@ i386_displacement (disp_start, disp_end)
     free (gotfree_input_line);
 #endif
 
+#ifdef BFD_ASSEMBLER
+  /* We do this to make sure that the section symbol is in
+     the symbol table.  We will ultimately change the relocation
+     to be relative to the beginning of the section.  */
+  if (i.reloc[this_operand] == BFD_RELOC_386_GOTOFF
+      || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
+    {
+      if (exp->X_op != O_symbol)
+	{
+	  as_bad (_("bad expression used with @%s"),
+		  (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL
+		   ? "GOTPCREL"
+		   : "GOTOFF"));
+	  return 0;
+	}
+
+      if (S_IS_LOCAL (exp->X_add_symbol)
+	  && S_GET_SEGMENT (exp->X_add_symbol) != undefined_section)
+	section_symbol (S_GET_SEGMENT (exp->X_add_symbol));
+      exp->X_op = O_subtract;
+      exp->X_op_symbol = GOT_symbol;
+      if (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL)
+        i.reloc[this_operand] = BFD_RELOC_32_PCREL;
+      else
+        i.reloc[this_operand] = BFD_RELOC_32;
+    }
+#endif
+
   if (exp->X_op == O_absent || exp->X_op == O_big)
     {
       /* Missing or bad expr becomes absolute 0.  */