diff --git a/gas/ChangeLog b/gas/ChangeLog
index dd723a67855..672cad5715f 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,39 @@
 Fri Jul 16 08:56:04 1993  Ian Lance Taylor  (ian@cygnus.com)
 
+	* read.c (float_cons): Simplified parsing logic.  If
+	REPEAT_CONS_EXPRESSIONS is defined, accept a repeat count.
+
+	* symbols.c (colon): Rather than a special case for TC_HPPA,
+	use new macro tc_frob_label.
+	* config/tc-hppa.h (tc_frob_label): Define.
+
+	* config/tc-mips.c: Many changes to support simple assembler
+	optimization.
+	(insn_label, prev_insn, prev_prev_insn, dummy_opcode,
+	prev_insn_valid, prev_insn_frag, prev_insn_where,
+	prev_insn_fixp, prev_insn_is_delay_slot): New static
+	variables.
+	(insn_uses_reg, mips_no_prev_insn, mips_emit_delays,
+	mips_align, s_stringer, s_mips_space): New static functions.
+	(mips_define_label): New global function.
+	(md_pseudo_table): For "ascii", "asciz", "asciiz", call
+	s_stringer.  Changed argument to float_cons from 0 or 1 to 'f'
+	or 'd'.  For "space" call s_mips_space.
+	(md_begin): Call mips_no_prev_insn.
+	(append_insn): Only insert necessary NOP instructions.
+	(macro): Call mips_emit_delays before setting mips_noreorder.
+	Increment and decrement mips_noreorder rather than using
+	save_reorder_condition.  Don't bother to use noreorder in
+	M_L_DOB and M_L_DAB, since append_insn will not insert a NOP.
+	(md_atof): Handle floating point numbers correctly for both
+	big and little endian targets.
+	(s_align, s_cons): Call mips_align rather than frag_align.
+	(s_change_seg, s_cons): Call mips_emit_delays.
+	(s_float_cons): Let float_cons do the work.
+	(s_mipsset): Call mips_emit_delays when setting noreorder.
+	* config/tc-mips.h (tc_frob_label): Define to be
+	mips_define_label.
+
 	* config/obj-ecoff.c (ecoff_build_symbols, ecoff_build_procs,
 	ecoff_frob_files): Consistently use S_GET_VALUE rather than
 	bfd_asymbol_value.  Warn if taking difference of symbols in
diff --git a/gas/read.c b/gas/read.c
index c3cb7113aa7..be3ea77f1aa 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -2165,36 +2165,26 @@ float_cons (float_type)		/* Worker to do .float etc statements. */
      register int float_type;	/* 'f':.ffloat ... 'F':.float ... */
 {
   register char *p;
-  register char c;
   int length;			/* Number of chars in an object. */
   register char *err;		/* Error from scanning floating literal. */
   char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
 
-  /*
-   * The following awkward logic is to parse ZERO or more strings,
-   * comma seperated. Recall an expression includes its leading &
-   * trailing blanks. We fake a leading ',' if there is (supposed to
-   * be) a 1st expression, and keep demanding 1 expression for each ','.
-   */
   if (is_it_end_of_statement ())
     {
-      c = 0;			/* Skip loop. */
-      ++input_line_pointer;	/*->past termintor. */
+      demand_empty_rest_of_line ();
+      return;
     }
-  else
-    {
-      c = ',';			/* Do loop. */
-    }
-  while (c == ',')
+
+  do
     {
       /* input_line_pointer->1st char of a flonum (we hope!). */
       SKIP_WHITESPACE ();
+
       /* Skip any 0{letter} that may be present. Don't even check if the
        * letter is legal. Someone may invent a "z" format and this routine
        * has no use for such information. Lusers beware: you get
        * diagnostics if your input is ill-conditioned.
        */
-
       if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1]))
 	input_line_pointer += 2;
 
@@ -2205,23 +2195,44 @@ float_cons (float_type)		/* Worker to do .float etc statements. */
 	{
 	  as_bad ("Bad floating literal: %s", err);
 	  ignore_rest_of_line ();
-	  /* Input_line_pointer->just after end-of-line. */
-	  c = 0;		/* Break out of loop. */
+	  return;
 	}
-      else
+
+      if (!need_pass_2)
 	{
-	  if (!need_pass_2)
+	  int count;
+
+	  count = 1;
+
+#ifdef REPEAT_CONS_EXPRESSIONS
+	  if (*input_line_pointer == ':')
+	    {
+	      segT segment;
+	      expressionS count_exp;
+
+	      ++input_line_pointer;
+	      segment = expression (&count_exp);
+	      if (segment != absolute_section
+		  || count_exp.X_add_number <= 0)
+		{
+		  as_warn ("Unresolvable or nonpositive repeat count; using 1");
+		}
+	      else
+		count = count_exp.X_add_number;
+	    }
+#endif
+
+	  while (--count >= 0)
 	    {
 	      p = frag_more (length);
 	      bcopy (temp, p, length);
 	    }
-	  SKIP_WHITESPACE ();
-	  c = *input_line_pointer++;
-	  /* C contains 1st non-white character after number. */
-	  /* input_line_pointer->just after terminator (c). */
 	}
+      SKIP_WHITESPACE ();
     }
-  --input_line_pointer;		/*->terminator (is not ','). */
+  while (*input_line_pointer++ == ',');
+
+  --input_line_pointer;		/* Put terminator back into stream.  */
   demand_empty_rest_of_line ();
 }				/* float_cons() */
 
diff --git a/gas/symbols.c b/gas/symbols.c
index 535810f1f96..d305024b28f 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -312,8 +312,9 @@ colon (sym_name)		/* just seen "x:" - rattle symbols & frags */
 
       symbol_table_insert (symbolP);
     }				/* if we have seen this symbol before */
-#ifdef TC_HPPA
-    pa_define_label(symbolP);
+
+#ifdef tc_frob_label
+  tc_frob_label (symbolP);
 #endif
 
   return;