diff -urN binutils-2.8.1.orig/bfd/elf32-mips.c binutils-2.8.1/bfd/elf32-mips.c
--- binutils-2.8.1.orig/bfd/elf32-mips.c	Mon May 26 19:34:03 1997
+++ binutils-2.8.1/bfd/elf32-mips.c	Sat Jun  5 12:43:09 1999
@@ -5103,36 +5103,43 @@
 		    }
 		  else
 		    {
-		      long indx;
-
-		      if (h == NULL)
-			sec = local_sections[r_symndx];
-		      else
-			{
-			  BFD_ASSERT (h->root.type == bfd_link_hash_defined
-				      || (h->root.type
-					  == bfd_link_hash_defweak));
-			  sec = h->root.u.def.section;
-			}
-		      if (sec != NULL && bfd_is_abs_section (sec))
-			indx = 0;
-		      else if (sec == NULL || sec->owner == NULL)
+		      if (r_type == R_MIPS_32)
 			{
-			  bfd_set_error (bfd_error_bad_value);
-			  return false;
+			  outrel.r_info = ELF32_R_INFO (0, R_MIPS_REL32);
+			  addend += relocation;
 			}
-		      else
-			{
-			  asection *osec;
+		       else
+                        {
+		          long indx;
 
-			  osec = sec->output_section;
-			  indx = elf_section_data (osec)->dynindx;
-			  if (indx == 0)
-			    abort ();
-			}
+		          if (h == NULL)
+			    sec = local_sections[r_symndx];
+		          else
+			    {
+			      BFD_ASSERT (h->root.type == bfd_link_hash_defined
+				          || (h->root.type
+					      == bfd_link_hash_defweak));
+			      sec = h->root.u.def.section;
+			    }
+		          if (sec != NULL && bfd_is_abs_section (sec))
+			    indx = 0;
+		          else if (sec == NULL || sec->owner == NULL)
+			    {
+			      bfd_set_error (bfd_error_bad_value);
+			      return false;
+			    }
+		          else
+			    {
+			      asection *osec;
 
-		      outrel.r_info = ELF32_R_INFO (indx, R_MIPS_REL32);
-		      addend += relocation;
+			      osec = sec->output_section;
+			      indx = elf_section_data (osec)->dynindx;
+			      if (indx == 0)
+			        abort ();
+			    }
+		          outrel.r_info = ELF32_R_INFO (indx, R_MIPS_REL32);
+		          addend += relocation;
+		        }
 		    }
 
 		  if (! skip)
diff -urN binutils-2.8.1.orig/gas/ChangeLog binutils-2.8.1/gas/ChangeLog
--- binutils-2.8.1.orig/gas/ChangeLog	Mon May 26 19:32:45 1997
+++ binutils-2.8.1/gas/ChangeLog	Sat Jun  5 12:43:09 1999
@@ -1,3 +1,10 @@
+Tue Oct 21 03:23:59 1997  Ralf Baechle  <ralf@gnu.ai.mit.edu>
+
+	* config/tc-mips.c (macro): Only emit a BFD_RELOC_MIPS_LITERAL
+	when the symbol is in the .lit section.  Required for a.out
+	support.
+	(mips_ip): Fix %HI, %hi and %lo operators.
+
 Mon May 26 13:24:25 1997  Ian Lance Taylor  <ian@cygnus.com>
 
 	* doc/as.texinfo: Don't use @value in section names or index
diff -urN binutils-2.8.1.orig/gas/config/obj-elf.c binutils-2.8.1/gas/config/obj-elf.c
--- binutils-2.8.1.orig/gas/config/obj-elf.c	Mon May 26 19:32:36 1997
+++ binutils-2.8.1/gas/config/obj-elf.c	Sat Jun  5 13:03:43 1999
@@ -58,7 +58,6 @@
 void obj_elf_version PARAMS ((int));
 static void obj_elf_size PARAMS ((int));
 static void obj_elf_type PARAMS ((int));
-static void obj_elf_ident PARAMS ((int));
 static void obj_elf_weak PARAMS ((int));
 static void obj_elf_local PARAMS ((int));
 static void obj_elf_common PARAMS ((int));
@@ -1132,7 +1131,7 @@
   demand_empty_rest_of_line ();
 }
 
-static void
+void
 obj_elf_ident (ignore)
      int ignore;
 {
diff -urN binutils-2.8.1.orig/gas/config/obj-elf.h binutils-2.8.1/gas/config/obj-elf.h
--- binutils-2.8.1.orig/gas/config/obj-elf.h	Mon May 26 19:32:36 1997
+++ binutils-2.8.1/gas/config/obj-elf.h	Sat Jun  5 13:09:46 1999
@@ -94,6 +94,8 @@
 #define obj_app_file elf_file_symbol
 extern void elf_file_symbol PARAMS ((char *));
 
+extern void obj_elf_ident PARAMS ((int));
+
 extern void obj_elf_section_change_hook PARAMS ((void));
 
 extern void obj_elf_section PARAMS ((int));
diff -urN binutils-2.8.1.orig/gas/config/tc-mips.c binutils-2.8.1/gas/config/tc-mips.c
--- binutils-2.8.1.orig/gas/config/tc-mips.c	Mon May 26 19:32:40 1997
+++ binutils-2.8.1/gas/config/tc-mips.c	Sat Jun  5 13:08:28 1999
@@ -598,6 +598,7 @@
 static void s_align PARAMS ((int));
 static void s_change_sec PARAMS ((int));
 static void s_cons PARAMS ((int));
+static void s_ident PARAMS ((int));
 static void s_float_cons PARAMS ((int));
 static void s_mips_globl PARAMS ((int));
 static void s_option PARAMS ((int));
@@ -668,6 +669,7 @@
   {"globl", s_mips_globl, 0},
   {"global", s_mips_globl, 0},
   {"hword", s_cons, 1},
+  {"ident", s_ident, 1},
   {"int", s_cons, 2},
   {"long", s_cons, 2},
   {"octa", s_cons, 4},
@@ -4863,13 +4865,22 @@
       else
 	{
 	  assert (offset_expr.X_op == O_symbol
-		  && strcmp (segment_name (S_GET_SEGMENT
-					   (offset_expr.X_add_symbol)),
-			     ".lit4") == 0
 		  && offset_expr.X_add_number == 0);
-	  macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",
-		       treg, (int) BFD_RELOC_MIPS_LITERAL, GP);
-	  return;
+	  s = segment_name (S_GET_SEGMENT (offset_expr.X_add_symbol));
+	  if (strcmp (s, ".lit4") == 0)
+	    {
+	      macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",
+			   treg, (int) BFD_RELOC_MIPS_LITERAL, GP);
+	      return;
+	    }
+	  else
+	    {
+	      /* FIXME: This won't work for a 64 bit address.  */
+	      macro_build_lui ((char *) NULL, &icnt, &offset_expr, AT);
+	      macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",
+			   treg, (int) BFD_RELOC_LO16, AT);
+	      return;
+	    }
 	}
 
     case M_LI_D:
@@ -6965,11 +6976,23 @@
 	      c = my_getSmallExpression (&imm_expr, s);
 	      if (c != '\0')
 		{
-		  if (c != 'l')
+		  if (c == 'l')
 		    {
 		      if (imm_expr.X_op == O_constant)
-			imm_expr.X_add_number =
-			  (imm_expr.X_add_number >> 16) & 0xffff;
+			{
+			  imm_expr.X_add_number &= 0xffff;
+			  imm_reloc = BFD_RELOC_LO16;
+			}
+		    }
+		  else
+		    {
+		      if (imm_expr.X_op == O_constant)
+			{
+			  if (c == 'h' && (imm_expr.X_add_number & 0x8000))
+			    imm_expr.X_add_number += 0x1000;
+			  imm_expr.X_add_number =
+			    (imm_expr.X_add_number >> 16) & 0xffff;
+			}
 		      else if (c == 'h')
 			{
 			  imm_reloc = BFD_RELOC_HI16_S;
@@ -7064,11 +7087,22 @@
 		break;
 
 	      offset_reloc = BFD_RELOC_LO16;
-	      if (c == 'h' || c == 'H')
+	      if (c)
 		{
-		  assert (offset_expr.X_op == O_constant);
-		  offset_expr.X_add_number =
-		    (offset_expr.X_add_number >> 16) & 0xffff;
+		  if (c != 'l')
+		    {
+		      if (offset_expr.X_op == O_constant)
+			{
+			  if (c == 'h' && (offset_expr.X_add_number & 0x8000))
+			    offset_expr.X_add_number += 0x1000;
+			  offset_expr.X_add_number =
+			    (offset_expr.X_add_number >> 16) & 0xffff;
+			}
+		      else if (c == 'h')
+			offset_reloc = BFD_RELOC_HI16_S;
+		      else
+			offset_reloc = BFD_RELOC_HI16;
+		    }
 		}
 	      s = expr_end;
 	      continue;
@@ -7081,10 +7115,13 @@
 
 	    case 'u':		/* upper 16 bits */
 	      c = my_getSmallExpression (&imm_expr, s);
-	      if (imm_expr.X_op == O_constant
-		  && (imm_expr.X_add_number < 0
-		      || imm_expr.X_add_number >= 0x10000))
-		as_bad ("lui expression not in range 0..65535");
+	      if (!c)
+		{
+		  if (imm_expr.X_op == O_constant
+		      && (imm_expr.X_add_number < 0
+			  || imm_expr.X_add_number >= 0x10000))
+		    as_bad ("lui expression not in range 0..65535");
+		}
 	      imm_reloc = BFD_RELOC_LO16;
 	      if (c)
 		{
@@ -9150,6 +9187,14 @@
 mips_enable_auto_align ()
 {
   auto_align = 1;
+}
+
+static void
+s_ident (ignore)
+     int ignore;
+{
+  mips_emit_delays (true);
+  obj_elf_ident(0);
 }
 
 static void
diff -urN binutils-2.8.1.orig/opcodes/mips-opc.c binutils-2.8.1/opcodes/mips-opc.c
--- binutils-2.8.1.orig/opcodes/mips-opc.c	Mon May 26 21:34:19 1997
+++ binutils-2.8.1/opcodes/mips-opc.c	Wed Oct  7 14:16:21 1998
@@ -655,10 +655,10 @@
 {"tgeu",    "s,t",	0x00000031, 0xfc00003f, RD_s|RD_t|I2|TRAP },
 {"tgeu",    "s,j",	0x04090000, 0xfc1f0000, RD_s|I2|TRAP	}, /* tgeiu */
 {"tgeu",    "s,I",	2,    (int) M_TGEU_I,	INSN_MACRO	},
-{"tlbp",    "",		0x42000008, 0xffffffff,	INSN_TLB	},
-{"tlbr",    "",		0x42000001, 0xffffffff,	INSN_TLB	},
-{"tlbwi",   "",		0x42000002, 0xffffffff,	INSN_TLB	},
-{"tlbwr",   "",		0x42000006, 0xffffffff,	INSN_TLB	},
+{"tlbp",    "",		0x42000008, 0xffffffff,	INSN_TLB|INSN_COP|COD	},
+{"tlbr",    "",		0x42000001, 0xffffffff,	INSN_TLB|INSN_COP|COD	},
+{"tlbwi",   "",		0x42000002, 0xffffffff,	INSN_TLB|INSN_COP|COD	},
+{"tlbwr",   "",		0x42000006, 0xffffffff,	INSN_TLB|INSN_COP|COD	},
 {"tlti",    "s,j",	0x040a0000, 0xfc1f0000,	RD_s|I2|TRAP	},
 {"tlt",     "s,t",	0x00000032, 0xfc00003f, RD_s|RD_t|I2|TRAP },
 {"tlt",     "s,j",	0x040a0000, 0xfc1f0000,	RD_s|I2|TRAP	}, /* tlti */
