rs6000: Remove -mstring

Message ID 3ad732a38f420222035c8a146e5083fdd6131f6c.1515773690.git.segher@kernel.crashing.org
State New
Headers show
Series
  • rs6000: Remove -mstring
Related show

Commit Message

Segher Boessenkool Jan. 12, 2018, 4:22 p.m.
-mstring is only enabled by default on 601, and with -Os on some
configurations.  It is almost always slower (than not using it) and
does not very often lead to smaller code.

This patch disables it.  If a user uses -mstring he gets a warning
(but not with -mno-string).  I left the target attribute in place, it
just doesn't do anything anymore.

The patch also deletes a whole bunch of code.  The 'N' and 'O' output
modifiers are now unused, but now is not the time to delete them.

Tested on powerpc64-linux {-m32,-m64}.  Is this okay for trunk?


Segher


2018-01-12  Segher Boessenkool  <segher@kernel.crashing.org>

	* config/rs6000/predicates.md (load_multiple_operation): Delete.
	(store_multiple_operation): Delete.
	* config/rs6000/rs6000-cpus.def (601): Remove MASK_STRING.
	* config/rs6000/rs6000-protos.h (rs6000_output_load_multiple): Delete.
	* config/rs6000/rs6000-string.c (expand_block_move): Delete everything
	guarded by TARGET_STRING.
	(rs6000_output_load_multiple): Delete.
	* config/rs6000/rs6000.c (rs6000_option_override_internal): Delete
	OPTION_MASK_STRING / TARGET_STRING handling.
	(print_operand) <'N', 'O'>: Add comment that these are unused now.
	(const rs6000_opt_masks) <"string">: Change mask to 0.
	* config/rs6000/rs6000.h (TARGET_DEFAULT): Remove MASK_STRING.
	(MASK_STRING): Delete.
	* config/rs6000/rs6000.md (*mov<mode>_string): Delete TARGET_STRING
	parts.  Simplify.
	(load_multiple): Delete.
	(*ldmsi8): Delete.
	(*ldmsi7): Delete.
	(*ldmsi6): Delete.
	(*ldmsi5): Delete.
	(*ldmsi4): Delete.
	(*ldmsi3): Delete.
	(store_multiple): Delete.
	(*stmsi8): Delete.
	(*stmsi7): Delete.
	(*stmsi6): Delete.
	(*stmsi5): Delete.
	(*stmsi4): Delete.
	(*stmsi3): Delete.
	(movmemsi_8reg): Delete.
	(corresponding unnamed define_insn): Delete.
	(movmemsi_6reg): Delete.
	(corresponding unnamed define_insn): Delete.
	(movmemsi_4reg): Delete.
	(corresponding unnamed define_insn): Delete.
	(movmemsi_2reg): Delete.
	(corresponding unnamed define_insn): Delete.
	(movmemsi_1reg): Delete.
	(corresponding unnamed define_insn): Delete.
	* config/rs6000/rs6000.opt (mno-string): New.
	(mstring): Replace by deprecation warning stub.
	* doc/invoke.texi (RS/6000 and PowerPC Options): Delete -mstring.

---
 gcc/config/rs6000/predicates.md   |  79 ------
 gcc/config/rs6000/rs6000-cpus.def |   2 +-
 gcc/config/rs6000/rs6000-protos.h |   1 -
 gcc/config/rs6000/rs6000-string.c | 104 --------
 gcc/config/rs6000/rs6000.c        |  48 ++--
 gcc/config/rs6000/rs6000.h        |   3 +-
 gcc/config/rs6000/rs6000.md       | 541 +-------------------------------------
 gcc/config/rs6000/rs6000.opt      |   7 +-
 gcc/doc/invoke.texi               |  17 +-
 9 files changed, 27 insertions(+), 775 deletions(-)

Comments

David Edelsohn Jan. 12, 2018, 7:53 p.m. | #1
On Fri, Jan 12, 2018 at 11:22 AM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> -mstring is only enabled by default on 601, and with -Os on some
> configurations.  It is almost always slower (than not using it) and
> does not very often lead to smaller code.
>
> This patch disables it.  If a user uses -mstring he gets a warning
> (but not with -mno-string).  I left the target attribute in place, it
> just doesn't do anything anymore.
>
> The patch also deletes a whole bunch of code.  The 'N' and 'O' output
> modifiers are now unused, but now is not the time to delete them.
>
> Tested on powerpc64-linux {-m32,-m64}.  Is this okay for trunk?
>
>
> Segher
>
>
> 2018-01-12  Segher Boessenkool  <segher@kernel.crashing.org>
>
>         * config/rs6000/predicates.md (load_multiple_operation): Delete.
>         (store_multiple_operation): Delete.
>         * config/rs6000/rs6000-cpus.def (601): Remove MASK_STRING.
>         * config/rs6000/rs6000-protos.h (rs6000_output_load_multiple): Delete.
>         * config/rs6000/rs6000-string.c (expand_block_move): Delete everything
>         guarded by TARGET_STRING.
>         (rs6000_output_load_multiple): Delete.
>         * config/rs6000/rs6000.c (rs6000_option_override_internal): Delete
>         OPTION_MASK_STRING / TARGET_STRING handling.
>         (print_operand) <'N', 'O'>: Add comment that these are unused now.
>         (const rs6000_opt_masks) <"string">: Change mask to 0.
>         * config/rs6000/rs6000.h (TARGET_DEFAULT): Remove MASK_STRING.
>         (MASK_STRING): Delete.
>         * config/rs6000/rs6000.md (*mov<mode>_string): Delete TARGET_STRING
>         parts.  Simplify.
>         (load_multiple): Delete.
>         (*ldmsi8): Delete.
>         (*ldmsi7): Delete.
>         (*ldmsi6): Delete.
>         (*ldmsi5): Delete.
>         (*ldmsi4): Delete.
>         (*ldmsi3): Delete.
>         (store_multiple): Delete.
>         (*stmsi8): Delete.
>         (*stmsi7): Delete.
>         (*stmsi6): Delete.
>         (*stmsi5): Delete.
>         (*stmsi4): Delete.
>         (*stmsi3): Delete.
>         (movmemsi_8reg): Delete.
>         (corresponding unnamed define_insn): Delete.
>         (movmemsi_6reg): Delete.
>         (corresponding unnamed define_insn): Delete.
>         (movmemsi_4reg): Delete.
>         (corresponding unnamed define_insn): Delete.
>         (movmemsi_2reg): Delete.
>         (corresponding unnamed define_insn): Delete.
>         (movmemsi_1reg): Delete.
>         (corresponding unnamed define_insn): Delete.
>         * config/rs6000/rs6000.opt (mno-string): New.
>         (mstring): Replace by deprecation warning stub.
>         * doc/invoke.texi (RS/6000 and PowerPC Options): Delete -mstring.

Okay.

Thanks, David

Patch

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 0055236..b6d18f3 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -1220,85 +1220,6 @@  (define_predicate "branch_positive_comparison_operator"
   (and (match_operand 0 "branch_comparison_operator")
        (match_code "eq,lt,gt,ltu,gtu,unordered")))
 
-;; Return 1 if OP is a load multiple operation, known to be a PARALLEL.
-(define_predicate "load_multiple_operation"
-  (match_code "parallel")
-{
-  int count = XVECLEN (op, 0);
-  unsigned int dest_regno;
-  rtx src_addr;
-  int i;
-
-  /* Perform a quick check so we don't blow up below.  */
-  if (count <= 1
-      || GET_CODE (XVECEXP (op, 0, 0)) != SET
-      || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
-      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
-    return 0;
-
-  dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
-  src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
-
-  for (i = 1; i < count; i++)
-    {
-      rtx elt = XVECEXP (op, 0, i);
-
-      if (GET_CODE (elt) != SET
-	  || GET_CODE (SET_DEST (elt)) != REG
-	  || GET_MODE (SET_DEST (elt)) != SImode
-	  || REGNO (SET_DEST (elt)) != dest_regno + i
-	  || GET_CODE (SET_SRC (elt)) != MEM
-	  || GET_MODE (SET_SRC (elt)) != SImode
-	  || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
-	  || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
-	  || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
-	  || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
-	return 0;
-    }
-
-  return 1;
-})
-
-;; Return 1 if OP is a store multiple operation, known to be a PARALLEL.
-;; The second vector element is a CLOBBER.
-(define_predicate "store_multiple_operation"
-  (match_code "parallel")
-{
-  int count = XVECLEN (op, 0) - 1;
-  unsigned int src_regno;
-  rtx dest_addr;
-  int i;
-
-  /* Perform a quick check so we don't blow up below.  */
-  if (count <= 1
-      || GET_CODE (XVECEXP (op, 0, 0)) != SET
-      || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
-      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
-    return 0;
-
-  src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
-  dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
-
-  for (i = 1; i < count; i++)
-    {
-      rtx elt = XVECEXP (op, 0, i + 1);
-
-      if (GET_CODE (elt) != SET
-	  || GET_CODE (SET_SRC (elt)) != REG
-	  || GET_MODE (SET_SRC (elt)) != SImode
-	  || REGNO (SET_SRC (elt)) != src_regno + i
-	  || GET_CODE (SET_DEST (elt)) != MEM
-	  || GET_MODE (SET_DEST (elt)) != SImode
-	  || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
-	  || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
-	  || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
-	  || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
-	return 0;
-    }
-
-  return 1;
-})
-
 ;; Return 1 if OP is valid for a save_world call in prologue, known to be
 ;; a PARLLEL.
 (define_predicate "save_world_operation"
diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index 3615e6d..105e002 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -170,7 +170,7 @@  RS6000_CPU ("476fp", PROCESSOR_PPC476,
 	    MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND
 	    | MASK_CMPB | MASK_MULHW | MASK_DLMZB)
 RS6000_CPU ("505", PROCESSOR_MPCCORE, 0)
-RS6000_CPU ("601", PROCESSOR_PPC601, MASK_MULTIPLE | MASK_STRING)
+RS6000_CPU ("601", PROCESSOR_PPC601, MASK_MULTIPLE)
 RS6000_CPU ("602", PROCESSOR_PPC603, MASK_PPC_GFXOPT)
 RS6000_CPU ("603", PROCESSOR_PPC603, MASK_PPC_GFXOPT)
 RS6000_CPU ("603e", PROCESSOR_PPC603, MASK_PPC_GFXOPT)
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 74a6d35..9d920b9 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -77,7 +77,6 @@  extern int expand_block_clear (rtx[]);
 extern int expand_block_move (rtx[]);
 extern bool expand_block_compare (rtx[]);
 extern bool expand_strn_compare (rtx[], int);
-extern const char * rs6000_output_load_multiple (rtx[]);
 extern bool rs6000_is_valid_mask (rtx, int *, int *, machine_mode);
 extern bool rs6000_is_valid_and_mask (rtx, machine_mode);
 extern bool rs6000_is_valid_shift_mask (rtx, rtx, machine_mode);
diff --git a/gcc/config/rs6000/rs6000-string.c b/gcc/config/rs6000/rs6000-string.c
index 815c454..e817f3d 100644
--- a/gcc/config/rs6000/rs6000-string.c
+++ b/gcc/config/rs6000/rs6000-string.c
@@ -2234,42 +2234,6 @@  expand_block_move (rtx operands[])
 	  mode = V4SImode;
 	  gen_func.mov = gen_movv4si;
 	}
-      else if (TARGET_STRING
-	  && bytes > 24		/* move up to 32 bytes at a time */
-	  && ! fixed_regs[5]
-	  && ! fixed_regs[6]
-	  && ! fixed_regs[7]
-	  && ! fixed_regs[8]
-	  && ! fixed_regs[9]
-	  && ! fixed_regs[10]
-	  && ! fixed_regs[11]
-	  && ! fixed_regs[12])
-	{
-	  move_bytes = (bytes > 32) ? 32 : bytes;
-	  gen_func.movmemsi = gen_movmemsi_8reg;
-	}
-      else if (TARGET_STRING
-	       && bytes > 16	/* move up to 24 bytes at a time */
-	       && ! fixed_regs[5]
-	       && ! fixed_regs[6]
-	       && ! fixed_regs[7]
-	       && ! fixed_regs[8]
-	       && ! fixed_regs[9]
-	       && ! fixed_regs[10])
-	{
-	  move_bytes = (bytes > 24) ? 24 : bytes;
-	  gen_func.movmemsi = gen_movmemsi_6reg;
-	}
-      else if (TARGET_STRING
-	       && bytes > 8	/* move up to 16 bytes at a time */
-	       && ! fixed_regs[5]
-	       && ! fixed_regs[6]
-	       && ! fixed_regs[7]
-	       && ! fixed_regs[8])
-	{
-	  move_bytes = (bytes > 16) ? 16 : bytes;
-	  gen_func.movmemsi = gen_movmemsi_4reg;
-	}
       else if (bytes >= 8 && TARGET_POWERPC64
 	       && (align >= 64 || !STRICT_ALIGNMENT))
 	{
@@ -2302,11 +2266,6 @@  expand_block_move (rtx operands[])
 		}
 	    }
 	}
-      else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
-	{			/* move up to 8 bytes at a time */
-	  move_bytes = (bytes > 8) ? 8 : bytes;
-	  gen_func.movmemsi = gen_movmemsi_2reg;
-	}
       else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
 	{			/* move 4 bytes */
 	  move_bytes = 4;
@@ -2319,11 +2278,6 @@  expand_block_move (rtx operands[])
 	  mode = HImode;
 	  gen_func.mov = gen_movhi;
 	}
-      else if (TARGET_STRING && bytes > 1)
-	{			/* move up to 4 bytes at a time */
-	  move_bytes = (bytes > 4) ? 4 : bytes;
-	  gen_func.movmemsi = gen_movmemsi_1reg;
-	}
       else /* move 1 byte at a time */
 	{
 	  move_bytes = 1;
@@ -2376,61 +2330,3 @@  expand_block_move (rtx operands[])
 
   return 1;
 }
-
-
-/* Return a string to perform a load_multiple operation.
-   operands[0] is the vector.
-   operands[1] is the source address.
-   operands[2] is the first destination register.  */
-
-const char *
-rs6000_output_load_multiple (rtx operands[3])
-{
-  /* We have to handle the case where the pseudo used to contain the address
-     is assigned to one of the output registers.  */
-  int i, j;
-  int words = XVECLEN (operands[0], 0);
-  rtx xop[10];
-
-  if (XVECLEN (operands[0], 0) == 1)
-    return "lwz %2,0(%1)";
-
-  for (i = 0; i < words; i++)
-    if (refers_to_regno_p (REGNO (operands[2]) + i, operands[1]))
-      {
-	if (i == words-1)
-	  {
-	    xop[0] = GEN_INT (4 * (words-1));
-	    xop[1] = operands[1];
-	    xop[2] = operands[2];
-	    output_asm_insn ("lswi %2,%1,%0\n\tlwz %1,%0(%1)", xop);
-	    return "";
-	  }
-	else if (i == 0)
-	  {
-	    xop[0] = GEN_INT (4 * (words-1));
-	    xop[1] = operands[1];
-	    xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
-	    output_asm_insn ("addi %1,%1,4\n\tlswi %2,%1,%0\n\tlwz %1,-4(%1)", xop);
-	    return "";
-	  }
-	else
-	  {
-	    for (j = 0; j < words; j++)
-	      if (j != i)
-		{
-		  xop[0] = GEN_INT (j * 4);
-		  xop[1] = operands[1];
-		  xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
-		  output_asm_insn ("lwz %2,%0(%1)", xop);
-		}
-	    xop[0] = GEN_INT (i * 4);
-	    xop[1] = operands[1];
-	    output_asm_insn ("lwz %1,%0(%1)", xop);
-	    return "";
-	  }
-      }
-
-  return "lswi %2,%1,%N0";
-}
-
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 37ceb24..eec512a 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4200,34 +4200,21 @@  rs6000_option_override_internal (bool global_init_p)
     }
 
   /* If we are optimizing big endian systems for space, use the load/store
-     multiple and string instructions.  */
+     multiple instructions.  */
   if (BYTES_BIG_ENDIAN && optimize_size)
-    rs6000_isa_flags |= ~rs6000_isa_flags_explicit & (OPTION_MASK_MULTIPLE
-						      | OPTION_MASK_STRING);
+    rs6000_isa_flags |= ~rs6000_isa_flags_explicit & OPTION_MASK_MULTIPLE;
 
-  /* Don't allow -mmultiple or -mstring on little endian systems
-     unless the cpu is a 750, because the hardware doesn't support the
-     instructions used in little endian mode, and causes an alignment
-     trap.  The 750 does not cause an alignment trap (except when the
-     target is unaligned).  */
+  /* Don't allow -mmultiple on little endian systems unless the cpu is a 750,
+     because the hardware doesn't support the instructions used in little
+     endian mode, and causes an alignment trap.  The 750 does not cause an
+     alignment trap (except when the target is unaligned).  */
 
-  if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
+  if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750 && TARGET_MULTIPLE)
     {
-      if (TARGET_MULTIPLE)
-	{
-	  rs6000_isa_flags &= ~OPTION_MASK_MULTIPLE;
-	  if ((rs6000_isa_flags_explicit & OPTION_MASK_MULTIPLE) != 0)
-	    warning (0, "%qs is not supported on little endian systems",
-		     "-mmultiple");
-	}
-
-      if (TARGET_STRING)
-	{
-	  rs6000_isa_flags &= ~OPTION_MASK_STRING;
-	  if ((rs6000_isa_flags_explicit & OPTION_MASK_STRING) != 0)
-	    warning (0, "%qs is not supported on little endian systems",
-		     "-mstring");
-	}
+      rs6000_isa_flags &= ~OPTION_MASK_MULTIPLE;
+      if ((rs6000_isa_flags_explicit & OPTION_MASK_MULTIPLE) != 0)
+	warning (0, "%qs is not supported on little endian systems",
+		 "-mmultiple");
     }
 
   /* If little-endian, default to -mstrict-align on older processors.
@@ -4808,9 +4795,7 @@  rs6000_option_override_internal (bool global_init_p)
     rs6000_print_isa_options (stderr, 0, "after subtarget", rs6000_isa_flags);
 
   /* For the E500 family of cores, reset the single/double FP flags to let us
-     check that they remain constant across attributes or pragmas.  Also,
-     clear a possible request for string instructions, not supported and which
-     we might have silently queried above for -Os.  */
+     check that they remain constant across attributes or pragmas.  */
 
   switch (rs6000_cpu)
     {
@@ -4822,7 +4807,6 @@  rs6000_option_override_internal (bool global_init_p)
     case PROCESSOR_PPCE6500:
       rs6000_single_float = 0;
       rs6000_double_float = 0;
-      rs6000_isa_flags &= ~OPTION_MASK_STRING;
       break;
 
     default:
@@ -21359,7 +21343,7 @@  print_operand (FILE *file, rtx x, int code)
 	}
       return;
 
-    case 'N':
+    case 'N': /* Unused */
       /* Write the number of elements in the vector times 4.  */
       if (GET_CODE (x) != PARALLEL)
 	output_operand_lossage ("invalid %%N value");
@@ -21367,7 +21351,7 @@  print_operand (FILE *file, rtx x, int code)
 	fprintf (file, "%d", XVECLEN (x, 0) * 4);
       return;
 
-    case 'O':
+    case 'O': /* Unused */
       /* Similar, but subtract 1 first.  */
       if (GET_CODE (x) != PARALLEL)
 	output_operand_lossage ("invalid %%O value");
@@ -36677,7 +36661,7 @@  static struct rs6000_opt_mask const rs6000_opt_masks[] =
   { "quad-memory-atomic",	OPTION_MASK_QUAD_MEMORY_ATOMIC,	false, true  },
   { "recip-precision",		OPTION_MASK_RECIP_PRECISION,	false, true  },
   { "save-toc-indirect",	OPTION_MASK_SAVE_TOC_INDIRECT,	false, true  },
-  { "string",			OPTION_MASK_STRING,		false, true  },
+  { "string",			0,				false, true  },
   { "toc-fusion",		OPTION_MASK_TOC_FUSION,		false, true  },
   { "update",			OPTION_MASK_NO_UPDATE,		true , true  },
   { "vsx",			OPTION_MASK_VSX,		false, true  },
@@ -36704,7 +36688,7 @@  static struct rs6000_opt_mask const rs6000_opt_masks[] =
   { "strict-align",		OPTION_MASK_STRICT_ALIGN,	false, false },
 #endif
   { "soft-float",		OPTION_MASK_SOFT_FLOAT,		false, false },
-  { "string",			OPTION_MASK_STRING,		false, false },
+  { "string",			0,				false, false },
 };
 
 /* Builtin mask mapping for printing the flags.  */
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 6e3d7df..b65639f 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -380,7 +380,7 @@  extern const char *host_detect_local_cpu (int argc, const char **argv);
     /* The option machinery will define this.  */
 #endif
 
-#define TARGET_DEFAULT (MASK_MULTIPLE | MASK_STRING)
+#define TARGET_DEFAULT (MASK_MULTIPLE)
 
 /* FPU operations supported. 
    Each use of TARGET_SINGLE_FLOAT or TARGET_DOUBLE_FLOAT must 
@@ -656,7 +656,6 @@  extern int rs6000_vector_align[];
 #define MASK_RECIP_PRECISION		OPTION_MASK_RECIP_PRECISION
 #define MASK_SOFT_FLOAT			OPTION_MASK_SOFT_FLOAT
 #define MASK_STRICT_ALIGN		OPTION_MASK_STRICT_ALIGN
-#define MASK_STRING			OPTION_MASK_STRING
 #define MASK_UPDATE			OPTION_MASK_UPDATE
 #define MASK_VSX			OPTION_MASK_VSX
 
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 7aea8f1..fd8f10d 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -8764,37 +8764,11 @@  (define_insn "*mov<mode>_string"
    && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
-  "*
-{
-  switch (which_alternative)
-    {
-    default:
-      gcc_unreachable ();
-    case 0:
-      if (TARGET_STRING)
-        return \"stswi %1,%P0,16\";
-      /* FALLTHRU */
-    case 1:
-      return \"#\";
-    case 2:
-      /* If the address is not used in the output, we can use lsi.  Otherwise,
-	 fall through to generating four loads.  */
-      if (TARGET_STRING
-          && ! reg_overlap_mentioned_p (operands[0], operands[1]))
-	return \"lswi %0,%P1,16\";
-      /* fall through */
-    case 3:
-    case 4:
-    case 5:
-      return \"#\";
-    }
-}"
+  "#"
   [(set_attr "type" "store,store,load,load,*,*")
    (set_attr "update" "yes")
    (set_attr "indexed" "yes")
-   (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
-   			                  (const_string "always")
-					  (const_string "conditional")))])
+   (set_attr "cell_micro" "conditional")])
 
 (define_insn "*mov<mode>_ppc64"
   [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
@@ -8846,337 +8820,6 @@  (define_split
   [(pc)]
 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
 
-(define_expand "load_multiple"
-  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
-			  (match_operand:SI 1 "" ""))
-		     (use (match_operand:SI 2 "" ""))])]
-  "TARGET_STRING && !TARGET_POWERPC64"
-  "
-{
-  int regno;
-  int count;
-  rtx op1;
-  int i;
-
-  /* Support only loading a constant number of fixed-point registers from
-     memory and only bother with this if more than two; the machine
-     doesn't support more than eight.  */
-  if (GET_CODE (operands[2]) != CONST_INT
-      || INTVAL (operands[2]) <= 2
-      || INTVAL (operands[2]) > 8
-      || GET_CODE (operands[1]) != MEM
-      || GET_CODE (operands[0]) != REG
-      || REGNO (operands[0]) >= 32)
-    FAIL;
-
-  count = INTVAL (operands[2]);
-  regno = REGNO (operands[0]);
-
-  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
-  op1 = replace_equiv_address (operands[1],
-			       force_reg (SImode, XEXP (operands[1], 0)));
-
-  for (i = 0; i < count; i++)
-    XVECEXP (operands[3], 0, i)
-      = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
-		     adjust_address_nv (op1, SImode, i * 4));
-}")
-
-(define_insn "*ldmsi8"
-  [(match_parallel 0 "load_multiple_operation"
-    [(set (match_operand:SI 2 "gpc_reg_operand" "")
-          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
-     (set (match_operand:SI 3 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
-     (set (match_operand:SI 4 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
-     (set (match_operand:SI 5 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
-     (set (match_operand:SI 6 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
-     (set (match_operand:SI 7 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 20))))
-     (set (match_operand:SI 8 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 24))))
-     (set (match_operand:SI 9 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
-  "*
-{ return rs6000_output_load_multiple (operands); }"
-  [(set_attr "type" "load")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "length" "32")])
-
-(define_insn "*ldmsi7"
-  [(match_parallel 0 "load_multiple_operation"
-    [(set (match_operand:SI 2 "gpc_reg_operand" "")
-          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
-     (set (match_operand:SI 3 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
-     (set (match_operand:SI 4 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
-     (set (match_operand:SI 5 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
-     (set (match_operand:SI 6 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
-     (set (match_operand:SI 7 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 20))))
-     (set (match_operand:SI 8 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
-  "*
-{ return rs6000_output_load_multiple (operands); }"
-  [(set_attr "type" "load")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "length" "32")])
-
-(define_insn "*ldmsi6"
-  [(match_parallel 0 "load_multiple_operation"
-    [(set (match_operand:SI 2 "gpc_reg_operand" "")
-          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
-     (set (match_operand:SI 3 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
-     (set (match_operand:SI 4 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
-     (set (match_operand:SI 5 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
-     (set (match_operand:SI 6 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
-     (set (match_operand:SI 7 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
-  "*
-{ return rs6000_output_load_multiple (operands); }"
-  [(set_attr "type" "load")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "length" "32")])
-
-(define_insn "*ldmsi5"
-  [(match_parallel 0 "load_multiple_operation"
-    [(set (match_operand:SI 2 "gpc_reg_operand" "")
-          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
-     (set (match_operand:SI 3 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
-     (set (match_operand:SI 4 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
-     (set (match_operand:SI 5 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
-     (set (match_operand:SI 6 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
-  "*
-{ return rs6000_output_load_multiple (operands); }"
-  [(set_attr "type" "load")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "length" "32")])
-
-(define_insn "*ldmsi4"
-  [(match_parallel 0 "load_multiple_operation"
-    [(set (match_operand:SI 2 "gpc_reg_operand" "")
-          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
-     (set (match_operand:SI 3 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
-     (set (match_operand:SI 4 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
-     (set (match_operand:SI 5 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
-  "*
-{ return rs6000_output_load_multiple (operands); }"
-  [(set_attr "type" "load")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "length" "32")])
-
-(define_insn "*ldmsi3"
-  [(match_parallel 0 "load_multiple_operation"
-    [(set (match_operand:SI 2 "gpc_reg_operand" "")
-          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
-     (set (match_operand:SI 3 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
-     (set (match_operand:SI 4 "gpc_reg_operand" "")
-          (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
-  "*
-{ return rs6000_output_load_multiple (operands); }"
-  [(set_attr "type" "load")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "length" "32")])
-
-(define_expand "store_multiple"
-  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
-			  (match_operand:SI 1 "" ""))
-		     (clobber (scratch:SI))
-		     (use (match_operand:SI 2 "" ""))])]
-  "TARGET_STRING && !TARGET_POWERPC64"
-  "
-{
-  int regno;
-  int count;
-  rtx to;
-  rtx op0;
-  int i;
-
-  /* Support only storing a constant number of fixed-point registers to
-     memory and only bother with this if more than two; the machine
-     doesn't support more than eight.  */
-  if (GET_CODE (operands[2]) != CONST_INT
-      || INTVAL (operands[2]) <= 2
-      || INTVAL (operands[2]) > 8
-      || GET_CODE (operands[0]) != MEM
-      || GET_CODE (operands[1]) != REG
-      || REGNO (operands[1]) >= 32)
-    FAIL;
-
-  count = INTVAL (operands[2]);
-  regno = REGNO (operands[1]);
-
-  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
-  to = force_reg (SImode, XEXP (operands[0], 0));
-  op0 = replace_equiv_address (operands[0], to);
-
-  XVECEXP (operands[3], 0, 0)
-    = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
-  XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
-						 gen_rtx_SCRATCH (SImode));
-
-  for (i = 1; i < count; i++)
-    XVECEXP (operands[3], 0, i + 1)
-      = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
-		     gen_rtx_REG (SImode, regno + i));
-}")
-
-(define_insn "*stmsi8"
-  [(match_parallel 0 "store_multiple_operation"
-    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
-	  (match_operand:SI 2 "gpc_reg_operand" "r"))
-     (clobber (match_scratch:SI 3 "=X"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
-	  (match_operand:SI 4 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
-	  (match_operand:SI 5 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
-	  (match_operand:SI 6 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
-	  (match_operand:SI 7 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
-	  (match_operand:SI 8 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
-	  (match_operand:SI 9 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
-	  (match_operand:SI 10 "gpc_reg_operand" "r"))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
-  "stswi %2,%1,%O0"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")])
-
-(define_insn "*stmsi7"
-  [(match_parallel 0 "store_multiple_operation"
-    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
-	  (match_operand:SI 2 "gpc_reg_operand" "r"))
-     (clobber (match_scratch:SI 3 "=X"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
-	  (match_operand:SI 4 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
-	  (match_operand:SI 5 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
-	  (match_operand:SI 6 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
-	  (match_operand:SI 7 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
-	  (match_operand:SI 8 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
-	  (match_operand:SI 9 "gpc_reg_operand" "r"))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
-  "stswi %2,%1,%O0"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")])
-
-(define_insn "*stmsi6"
-  [(match_parallel 0 "store_multiple_operation"
-    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
-	  (match_operand:SI 2 "gpc_reg_operand" "r"))
-     (clobber (match_scratch:SI 3 "=X"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
-	  (match_operand:SI 4 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
-	  (match_operand:SI 5 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
-	  (match_operand:SI 6 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
-	  (match_operand:SI 7 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
-	  (match_operand:SI 8 "gpc_reg_operand" "r"))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
-  "stswi %2,%1,%O0"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")])
-
-(define_insn "*stmsi5"
-  [(match_parallel 0 "store_multiple_operation"
-    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
-	  (match_operand:SI 2 "gpc_reg_operand" "r"))
-     (clobber (match_scratch:SI 3 "=X"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
-	  (match_operand:SI 4 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
-	  (match_operand:SI 5 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
-	  (match_operand:SI 6 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
-	  (match_operand:SI 7 "gpc_reg_operand" "r"))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
-  "stswi %2,%1,%O0"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")])
-
-(define_insn "*stmsi4"
-  [(match_parallel 0 "store_multiple_operation"
-    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
-	  (match_operand:SI 2 "gpc_reg_operand" "r"))
-     (clobber (match_scratch:SI 3 "=X"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
-	  (match_operand:SI 4 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
-	  (match_operand:SI 5 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
-	  (match_operand:SI 6 "gpc_reg_operand" "r"))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
-  "stswi %2,%1,%O0"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")])
-
-(define_insn "*stmsi3"
-  [(match_parallel 0 "store_multiple_operation"
-    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
-	  (match_operand:SI 2 "gpc_reg_operand" "r"))
-     (clobber (match_scratch:SI 3 "=X"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
-	  (match_operand:SI 4 "gpc_reg_operand" "r"))
-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
-	  (match_operand:SI 5 "gpc_reg_operand" "r"))])]
-  "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
-  "stswi %2,%1,%O0"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")])
-
 (define_expand "setmemsi"
   [(parallel [(set (match_operand:BLK 0 "" "")
 		   (match_operand 2 "const_int_operand" ""))
@@ -9281,186 +8924,6 @@  (define_expand "movmemsi"
   else
     FAIL;
 }")
-
-;; Move up to 32 bytes at a time.  The fixed registers are needed because the
-;; register allocator doesn't have a clue about allocating 8 word registers.
-;; rD/rS = r5 is preferred, efficient form.
-(define_expand "movmemsi_8reg"
-  [(parallel [(set (match_operand 0 "" "")
-		   (match_operand 1 "" ""))
-	      (use (match_operand 2 "" ""))
-	      (use (match_operand 3 "" ""))
-	      (clobber (reg:SI  5))
-	      (clobber (reg:SI  6))
-	      (clobber (reg:SI  7))
-	      (clobber (reg:SI  8))
-	      (clobber (reg:SI  9))
-	      (clobber (reg:SI 10))
-	      (clobber (reg:SI 11))
-	      (clobber (reg:SI 12))
-	      (clobber (match_scratch:SI 4 ""))])]
-  "TARGET_STRING"
-  "")
-
-(define_insn ""
-  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
-	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
-   (use (match_operand:SI 2 "immediate_operand" "i"))
-   (use (match_operand:SI 3 "immediate_operand" "i"))
-   (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
-   (clobber (reg:SI  6))
-   (clobber (reg:SI  7))
-   (clobber (reg:SI  8))
-   (clobber (reg:SI  9))
-   (clobber (reg:SI 10))
-   (clobber (reg:SI 11))
-   (clobber (reg:SI 12))
-   (clobber (match_scratch:SI 5 "=X"))]
-  "TARGET_STRING
-   && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
-       || INTVAL (operands[2]) == 0)
-   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
-   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
-   && REGNO (operands[4]) == 5"
-  "lswi %4,%1,%2\;stswi %4,%0,%2"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")
-   (set_attr "length" "8")])
-
-;; Move up to 24 bytes at a time.  The fixed registers are needed because the
-;; register allocator doesn't have a clue about allocating 6 word registers.
-;; rD/rS = r5 is preferred, efficient form.
-(define_expand "movmemsi_6reg"
-  [(parallel [(set (match_operand 0 "" "")
-		   (match_operand 1 "" ""))
-	      (use (match_operand 2 "" ""))
-	      (use (match_operand 3 "" ""))
-	      (clobber (reg:SI  5))
-	      (clobber (reg:SI  6))
-	      (clobber (reg:SI  7))
-	      (clobber (reg:SI  8))
-	      (clobber (reg:SI  9))
-	      (clobber (reg:SI 10))
-	      (clobber (match_scratch:SI 4 ""))])]
-  "TARGET_STRING"
-  "")
-
-(define_insn ""
-  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
-	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
-   (use (match_operand:SI 2 "immediate_operand" "i"))
-   (use (match_operand:SI 3 "immediate_operand" "i"))
-   (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
-   (clobber (reg:SI  6))
-   (clobber (reg:SI  7))
-   (clobber (reg:SI  8))
-   (clobber (reg:SI  9))
-   (clobber (reg:SI 10))
-   (clobber (match_scratch:SI 5 "=X"))]
-  "TARGET_STRING
-   && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
-   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
-   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
-   && REGNO (operands[4]) == 5"
-  "lswi %4,%1,%2\;stswi %4,%0,%2"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")
-   (set_attr "length" "8")])
-
-;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
-;; problems with TImode.
-;; rD/rS = r5 is preferred, efficient form.
-(define_expand "movmemsi_4reg"
-  [(parallel [(set (match_operand 0 "" "")
-		   (match_operand 1 "" ""))
-	      (use (match_operand 2 "" ""))
-	      (use (match_operand 3 "" ""))
-	      (clobber (reg:SI 5))
-	      (clobber (reg:SI 6))
-	      (clobber (reg:SI 7))
-	      (clobber (reg:SI 8))
-	      (clobber (match_scratch:SI 4 ""))])]
-  "TARGET_STRING"
-  "")
-
-(define_insn ""
-  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
-	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
-   (use (match_operand:SI 2 "immediate_operand" "i"))
-   (use (match_operand:SI 3 "immediate_operand" "i"))
-   (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
-   (clobber (reg:SI 6))
-   (clobber (reg:SI 7))
-   (clobber (reg:SI 8))
-   (clobber (match_scratch:SI 5 "=X"))]
-  "TARGET_STRING
-   && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
-   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
-   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
-   && REGNO (operands[4]) == 5"
-  "lswi %4,%1,%2\;stswi %4,%0,%2"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")
-   (set_attr "length" "8")])
-
-;; Move up to 8 bytes at a time.
-(define_expand "movmemsi_2reg"
-  [(parallel [(set (match_operand 0 "" "")
-		   (match_operand 1 "" ""))
-	      (use (match_operand 2 "" ""))
-	      (use (match_operand 3 "" ""))
-	      (clobber (match_scratch:DI 4 ""))
-	      (clobber (match_scratch:SI 5 ""))])]
-  "TARGET_STRING && ! TARGET_POWERPC64"
-  "")
-
-(define_insn ""
-  [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
-	(mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
-   (use (match_operand:SI 2 "immediate_operand" "i"))
-   (use (match_operand:SI 3 "immediate_operand" "i"))
-   (clobber (match_scratch:DI 4 "=&r"))
-   (clobber (match_scratch:SI 5 "=X"))]
-  "TARGET_STRING && ! TARGET_POWERPC64
-   && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
-  "lswi %4,%1,%2\;stswi %4,%0,%2"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")
-   (set_attr "length" "8")])
-
-;; Move up to 4 bytes at a time.
-(define_expand "movmemsi_1reg"
-  [(parallel [(set (match_operand 0 "" "")
-		   (match_operand 1 "" ""))
-	      (use (match_operand 2 "" ""))
-	      (use (match_operand 3 "" ""))
-	      (clobber (match_scratch:SI 4 ""))
-	      (clobber (match_scratch:SI 5 ""))])]
-  "TARGET_STRING"
-  "")
-
-(define_insn ""
-  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
-	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
-   (use (match_operand:SI 2 "immediate_operand" "i"))
-   (use (match_operand:SI 3 "immediate_operand" "i"))
-   (clobber (match_scratch:SI 4 "=&r"))
-   (clobber (match_scratch:SI 5 "=X"))]
-  "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
-  "lswi %4,%1,%2\;stswi %4,%0,%2"
-  [(set_attr "type" "store")
-   (set_attr "update" "yes")
-   (set_attr "indexed" "yes")
-   (set_attr "cell_micro" "always")
-   (set_attr "length" "8")])
 
 ;; Define insns that do load or store with update.  Some of these we can
 ;; get by using pre-decrement or pre-increment, but the hardware can also
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index ed6a9bd..5464380 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -180,9 +180,12 @@  mmultiple
 Target Report Mask(MULTIPLE) Var(rs6000_isa_flags)
 Generate load/store multiple instructions.
 
+;; This option existed in the past, but now is always off.
+mno-string
+Target RejectNegative Undocumented Ignore
+
 mstring
-Target Report Mask(STRING) Var(rs6000_isa_flags)
-Generate string instructions for block moves.
+Target RejectNegative Undocumented Warn(%<-mstring%> is deprecated)
 
 msoft-float
 Target Report RejectNegative Mask(SOFT_FLOAT) Var(rs6000_isa_flags)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 928561d..9564238 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1016,7 +1016,7 @@  See RS/6000 and PowerPC Options.
 -malign-power  -malign-natural @gol
 -msoft-float  -mhard-float  -mmultiple  -mno-multiple @gol
 -msingle-float  -mdouble-float  -msimple-fpu @gol
--mstring  -mno-string  -mupdate  -mno-update @gol
+-mupdate  -mno-update @gol
 -mavoid-indexed-addresses  -mno-avoid-indexed-addresses @gol
 -mfused-madd  -mno-fused-madd  -mbit-align  -mno-bit-align @gol
 -mstrict-align  -mno-strict-align  -mrelocatable @gol
@@ -22225,7 +22225,7 @@  following options:
 @gccoptlist{-maltivec  -mfprnd  -mhard-float  -mmfcrf  -mmultiple @gol
 -mpopcntb -mpopcntd  -mpowerpc64 @gol
 -mpowerpc-gpopt  -mpowerpc-gfxopt  -msingle-float -mdouble-float @gol
--msimple-fpu -mstring  -mmulhw  -mdlmzb  -mmfpgpr -mvsx @gol
+-msimple-fpu  -mmulhw  -mdlmzb  -mmfpgpr -mvsx @gol
 -mcrypto -mdirect-move -mhtm -mpower8-fusion -mpower8-vector @gol
 -mquad-memory -mquad-memory-atomic -mfloat128 -mfloat128-hardware}
 
@@ -22622,19 +22622,6 @@  PowerPC systems, since those instructions do not work when the
 processor is in little-endian mode.  The exceptions are PPC740 and
 PPC750 which permit these instructions in little-endian mode.
 
-@item -mstring
-@itemx -mno-string
-@opindex mstring
-@opindex mno-string
-Generate code that uses (does not use) the load string instructions
-and the store string word instructions to save multiple registers and
-do small block moves.  These instructions are generated by default on
-POWER systems, and not generated on PowerPC systems.  Do not use
-@option{-mstring} on little-endian PowerPC systems, since those
-instructions do not work when the processor is in little-endian mode.
-The exceptions are PPC740 and PPC750 which permit these instructions
-in little-endian mode.
-
 @item -mupdate
 @itemx -mno-update
 @opindex mupdate