diff mbox

[4.8,26/26] Backport Power8 and LE support: Missing support

Message ID 1395257703.17148.28.camel@gnopaine
State New
Headers show

Commit Message

Bill Schmidt March 19, 2014, 7:35 p.m. UTC
Hi,

This patch (diff-trunk-missing) backports some LE pieces that were found
not to have been backported from trunk to the IBM 4.8 branch until
relatively recently.

Thanks,
Bill


2014-03-19  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	Back port from trunk
	2013-04-25  Alan Modra  <amodra@gmail.com>

	PR target/57052
	* config/rs6000/rs6000.md (rotlsi3_internal7): Rename to
	rotlsi3_internal7le and condition on !BYTES_BIG_ENDIAN.
	(rotlsi3_internal8be): New BYTES_BIG_ENDIAN insn.
	Repeat for many other rotate/shift and mask patterns using subregs.
	Name lshiftrt insns.
	(ashrdisi3_noppc64): Rename to ashrdisi3_noppc64be and condition
	on WORDS_BIG_ENDIAN.

	2013-06-07  Alan Modra  <amodra@gmail.com>

	* config/rs6000/rs6000.c (rs6000_option_override_internal): Don't
	override user -mfp-in-toc.
	(offsettable_ok_by_alignment): Consider just the current access
	rather than the whole object, unless BLKmode.  Handle
	CONSTANT_POOL_ADDRESS_P constants that lack a decl too.
	(use_toc_relative_ref): Allow CONSTANT_POOL_ADDRESS_P constants
	for -mcmodel=medium.
	* config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Don't
	override user -mfp-in-toc or -msum-in-toc.  Default to
	-mno-fp-in-toc for -mcmodel=medium.

	2013-06-18  Alan Modra  <amodra@gmail.com>

	* config/rs6000/rs6000.h (enum data_align): New.
	(LOCAL_ALIGNMENT, DATA_ALIGNMENT): Use rs6000_data_alignment.
	(DATA_ABI_ALIGNMENT): Define.
	(CONSTANT_ALIGNMENT): Correct comment.
	* config/rs6000/rs6000-protos.h (rs6000_data_alignment): Declare.
	* config/rs6000/rs6000.c (rs6000_data_alignment): New function.

	2013-07-11  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* config/rs6000/rs6000.md (""*tls_gd_low<TLSmode:tls_abi_suffix>"):
	Require GOT register as additional operand in UNSPEC.
	("*tls_ld_low<TLSmode:tls_abi_suffix>"): Likewise.
	("*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"): Likewise.
	("*tls_got_tprel_low<TLSmode:tls_abi_suffix>"): Likewise.
	("*tls_gd<TLSmode:tls_abi_suffix>"): Update splitter.
	("*tls_ld<TLSmode:tls_abi_suffix>"): Likewise.
	("tls_got_dtprel_<TLSmode:tls_abi_suffix>"): Likewise.
	("tls_got_tprel_<TLSmode:tls_abi_suffix>"): Likewise.

	2014-01-23  Pat Haugen  <pthaugen@us.ibm.com>

	* config/rs6000/rs6000.c (rs6000_option_override_internal): Don't
	force flag_ira_loop_pressure if set via command line.

	2014-02-06  Alan Modra  <amodra@gmail.com>

	PR target/60032
	* config/rs6000/rs6000.c (rs6000_secondary_memory_needed_mode): Only
	change SDmode to DDmode when lra_in_progress.

Comments

David Edelsohn April 3, 2014, 2:45 p.m. UTC | #1
On Wed, Mar 19, 2014 at 3:35 PM, Bill Schmidt
<wschmidt@linux.vnet.ibm.com> wrote:
> Hi,
>
> This patch (diff-trunk-missing) backports some LE pieces that were found
> not to have been backported from trunk to the IBM 4.8 branch until
> relatively recently.
>
> Thanks,
> Bill
>
>
> 2014-03-19  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
>
>         Back port from trunk
>         2013-04-25  Alan Modra  <amodra@gmail.com>
>
>         PR target/57052
>         * config/rs6000/rs6000.md (rotlsi3_internal7): Rename to
>         rotlsi3_internal7le and condition on !BYTES_BIG_ENDIAN.
>         (rotlsi3_internal8be): New BYTES_BIG_ENDIAN insn.
>         Repeat for many other rotate/shift and mask patterns using subregs.
>         Name lshiftrt insns.
>         (ashrdisi3_noppc64): Rename to ashrdisi3_noppc64be and condition
>         on WORDS_BIG_ENDIAN.
>
>         2013-06-07  Alan Modra  <amodra@gmail.com>
>
>         * config/rs6000/rs6000.c (rs6000_option_override_internal): Don't
>         override user -mfp-in-toc.
>         (offsettable_ok_by_alignment): Consider just the current access
>         rather than the whole object, unless BLKmode.  Handle
>         CONSTANT_POOL_ADDRESS_P constants that lack a decl too.
>         (use_toc_relative_ref): Allow CONSTANT_POOL_ADDRESS_P constants
>         for -mcmodel=medium.
>         * config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Don't
>         override user -mfp-in-toc or -msum-in-toc.  Default to
>         -mno-fp-in-toc for -mcmodel=medium.
>
>         2013-06-18  Alan Modra  <amodra@gmail.com>
>
>         * config/rs6000/rs6000.h (enum data_align): New.
>         (LOCAL_ALIGNMENT, DATA_ALIGNMENT): Use rs6000_data_alignment.
>         (DATA_ABI_ALIGNMENT): Define.
>         (CONSTANT_ALIGNMENT): Correct comment.
>         * config/rs6000/rs6000-protos.h (rs6000_data_alignment): Declare.
>         * config/rs6000/rs6000.c (rs6000_data_alignment): New function.
>
>         2013-07-11  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
>
>         * config/rs6000/rs6000.md (""*tls_gd_low<TLSmode:tls_abi_suffix>"):
>         Require GOT register as additional operand in UNSPEC.
>         ("*tls_ld_low<TLSmode:tls_abi_suffix>"): Likewise.
>         ("*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"): Likewise.
>         ("*tls_got_tprel_low<TLSmode:tls_abi_suffix>"): Likewise.
>         ("*tls_gd<TLSmode:tls_abi_suffix>"): Update splitter.
>         ("*tls_ld<TLSmode:tls_abi_suffix>"): Likewise.
>         ("tls_got_dtprel_<TLSmode:tls_abi_suffix>"): Likewise.
>         ("tls_got_tprel_<TLSmode:tls_abi_suffix>"): Likewise.
>
>         2014-01-23  Pat Haugen  <pthaugen@us.ibm.com>
>
>         * config/rs6000/rs6000.c (rs6000_option_override_internal): Don't
>         force flag_ira_loop_pressure if set via command line.
>
>         2014-02-06  Alan Modra  <amodra@gmail.com>
>
>         PR target/60032
>         * config/rs6000/rs6000.c (rs6000_secondary_memory_needed_mode): Only
>         change SDmode to DDmode when lra_in_progress.

Okay.

Thanks, David
diff mbox

Patch

Index: gcc-4_8-test/gcc/config/rs6000/linux64.h
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/linux64.h
+++ gcc-4_8-test/gcc/config/rs6000/linux64.h
@@ -149,8 +149,11 @@  extern int dot_symbols;
 		SET_CMODEL (CMODEL_MEDIUM);			\
 	      if (rs6000_current_cmodel != CMODEL_SMALL)	\
 		{						\
-		  TARGET_NO_FP_IN_TOC = 0;			\
-		  TARGET_NO_SUM_IN_TOC = 0;			\
+		  if (!global_options_set.x_TARGET_NO_FP_IN_TOC) \
+		    TARGET_NO_FP_IN_TOC				\
+		      = rs6000_current_cmodel == CMODEL_MEDIUM;	\
+		  if (!global_options_set.x_TARGET_NO_SUM_IN_TOC) \
+		    TARGET_NO_SUM_IN_TOC = 0;			\
 		}						\
 	    }							\
 	}							\
Index: gcc-4_8-test/gcc/config/rs6000/rs6000-protos.h
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/rs6000-protos.h
+++ gcc-4_8-test/gcc/config/rs6000/rs6000-protos.h
@@ -152,6 +152,7 @@  extern void rs6000_split_logical (rtx []
 #endif /* RTX_CODE */
 
 #ifdef TREE_CODE
+extern unsigned int rs6000_data_alignment (tree, unsigned int, enum data_align);
 extern unsigned int rs6000_special_round_type_align (tree, unsigned int,
 						     unsigned int);
 extern unsigned int darwin_rs6000_special_round_type_align (tree, unsigned int,
Index: gcc-4_8-test/gcc/config/rs6000/rs6000.c
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.c
+++ gcc-4_8-test/gcc/config/rs6000/rs6000.c
@@ -3031,7 +3031,8 @@  rs6000_option_override_internal (bool gl
      calculation works better for RTL loop invariant motion on targets
      with enough (>= 32) registers.  It is an expensive optimization.
      So it is on only for peak performance.  */
-  if (optimize >= 3 && global_init_p)
+  if (optimize >= 3 && global_init_p
+      && !global_options_set.x_flag_ira_loop_pressure)
     flag_ira_loop_pressure = 1;
 
   /* Set the pointer size.  */
@@ -3520,7 +3521,8 @@  rs6000_option_override_internal (bool gl
 
   /* Place FP constants in the constant pool instead of TOC
      if section anchors enabled.  */
-  if (flag_section_anchors)
+  if (flag_section_anchors
+      && !global_options_set.x_TARGET_NO_FP_IN_TOC)
     TARGET_NO_FP_IN_TOC = 1;
 
   if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET)
@@ -5788,6 +5790,48 @@  invalid_e500_subreg (rtx op, enum machin
   return false;
 }
 
+/* Return alignment of TYPE.  Existing alignment is ALIGN.  HOW
+   selects whether the alignment is abi mandated, optional, or
+   both abi and optional alignment.  */
+   
+unsigned int
+rs6000_data_alignment (tree type, unsigned int align, enum data_align how)
+{
+  if (how != align_opt)
+    {
+      if (TREE_CODE (type) == VECTOR_TYPE)
+	{
+	  if ((TARGET_SPE && SPE_VECTOR_MODE (TYPE_MODE (type)))
+	      || (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (TYPE_MODE (type))))
+	    {
+	      if (align < 64)
+		align = 64;
+	    }
+	  else if (align < 128)
+	    align = 128;
+	}
+      else if (TARGET_E500_DOUBLE
+	       && TREE_CODE (type) == REAL_TYPE
+	       && TYPE_MODE (type) == DFmode)
+	{
+	  if (align < 64)
+	    align = 64;
+	}
+    }
+
+  if (how != align_abi)
+    {
+      if (TREE_CODE (type) == ARRAY_TYPE
+	  && TYPE_MODE (TREE_TYPE (type)) == QImode)
+	{
+	  if (align < BITS_PER_WORD)
+	    align = BITS_PER_WORD;
+	}
+    }
+
+  return align;
+}
+
 /* AIX increases natural record alignment to doubleword if the first
    field is an FP double while the FP fields remain word aligned.  */
 
@@ -6112,91 +6156,102 @@  virtual_stack_registers_memory_p (rtx op
 	  && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
 }
 
-/* Return true if memory accesses to OP are known to never straddle
-   a 32k boundary.  */
+/* Return true if a MODE sized memory accesses to OP plus OFFSET
+   is known to not straddle a 32k boundary.  */
 
 static bool
 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
 			     enum machine_mode mode)
 {
   tree decl, type;
-  unsigned HOST_WIDE_INT dsize, dalign;
+  unsigned HOST_WIDE_INT dsize, dalign, lsb, mask;
 
   if (GET_CODE (op) != SYMBOL_REF)
     return false;
 
+  dsize = GET_MODE_SIZE (mode);
   decl = SYMBOL_REF_DECL (op);
   if (!decl)
     {
-      if (GET_MODE_SIZE (mode) == 0)
+      if (dsize == 0)
 	return false;
 
       /* -fsection-anchors loses the original SYMBOL_REF_DECL when
 	 replacing memory addresses with an anchor plus offset.  We
 	 could find the decl by rummaging around in the block->objects
 	 VEC for the given offset but that seems like too much work.  */
-      dalign = 1;
+      dalign = BITS_PER_UNIT;
       if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
 	  && SYMBOL_REF_ANCHOR_P (op)
 	  && SYMBOL_REF_BLOCK (op) != NULL)
 	{
 	  struct object_block *block = SYMBOL_REF_BLOCK (op);
-	  HOST_WIDE_INT lsb, mask;
 
-	  /* Given the alignment of the block..  */
 	  dalign = block->alignment;
-	  mask = dalign / BITS_PER_UNIT - 1;
-
-	  /* ..and the combined offset of the anchor and any offset
-	     to this block object..  */
 	  offset += SYMBOL_REF_BLOCK_OFFSET (op);
-	  lsb = offset & -offset;
+	}
+      else if (CONSTANT_POOL_ADDRESS_P (op))
+	{
+	  /* It would be nice to have get_pool_align()..  */
+	  enum machine_mode cmode = get_pool_mode (op);
 
-	  /* ..find how many bits of the alignment we know for the
-	     object.  */
-	  mask &= lsb - 1;
-	  dalign = mask + 1;
+	  dalign = GET_MODE_ALIGNMENT (cmode);
 	}
-      return dalign >= GET_MODE_SIZE (mode);
     }
-
-  if (DECL_P (decl))
+  else if (DECL_P (decl))
     {
-      if (TREE_CODE (decl) == FUNCTION_DECL)
-	return true;
+      dalign = DECL_ALIGN (decl);
 
-      if (!DECL_SIZE_UNIT (decl))
-	return false;
+      if (dsize == 0)
+	{
+	  /* Allow BLKmode when the entire object is known to not
+	     cross a 32k boundary.  */
+	  if (!DECL_SIZE_UNIT (decl))
+	    return false;
 
-      if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
-	return false;
+	  if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
+	    return false;
 
-      dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
-      if (dsize > 32768)
-	return false;
+	  dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
+	  if (dsize > 32768)
+	    return false;
 
-      dalign = DECL_ALIGN_UNIT (decl);
-      return dalign >= dsize;
+	  return dalign / BITS_PER_UNIT >= dsize;
+	}
     }
+  else
+    {
+      type = TREE_TYPE (decl);
 
-  type = TREE_TYPE (decl);
+      dalign = TYPE_ALIGN (type);
+      if (CONSTANT_CLASS_P (decl))
+	dalign = CONSTANT_ALIGNMENT (decl, dalign);
+      else
+	dalign = DATA_ALIGNMENT (decl, dalign);
 
-  if (TREE_CODE (decl) == STRING_CST)
-    dsize = TREE_STRING_LENGTH (decl);
-  else if (TYPE_SIZE_UNIT (type)
-	   && host_integerp (TYPE_SIZE_UNIT (type), 1))
-    dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
-  else
-    return false;
-  if (dsize > 32768)
-    return false;
+      if (dsize == 0)
+	{
+	  /* BLKmode, check the entire object.  */
+	  if (TREE_CODE (decl) == STRING_CST)
+	    dsize = TREE_STRING_LENGTH (decl);
+	  else if (TYPE_SIZE_UNIT (type)
+		   && host_integerp (TYPE_SIZE_UNIT (type), 1))
+	    dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
+	  else
+	    return false;
+	  if (dsize > 32768)
+	    return false;
+
+	  return dalign / BITS_PER_UNIT >= dsize;
+	}
+    }
+
+  /* Find how many bits of the alignment we know for this access.  */
+  mask = dalign / BITS_PER_UNIT - 1;
+  lsb = offset & -offset;
+  mask &= lsb - 1;
+  dalign = mask + 1;
 
-  dalign = TYPE_ALIGN (type);
-  if (CONSTANT_CLASS_P (decl))
-    dalign = CONSTANT_ALIGNMENT (decl, dalign);
-  else
-    dalign = DATA_ALIGNMENT (decl, dalign);
-  dalign /= BITS_PER_UNIT;
   return dalign >= dsize;
 }
 
Index: gcc-4_8-test/gcc/config/rs6000/rs6000.h
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.h
+++ gcc-4_8-test/gcc/config/rs6000/rs6000.h
@@ -848,12 +848,6 @@  extern unsigned rs6000_pointer_size;
 /* No data type wants to be aligned rounder than this.  */
 #define BIGGEST_ALIGNMENT 128
 
-/* A C expression to compute the alignment for a variables in the
-   local store.  TYPE is the data type, and ALIGN is the alignment
-   that the object would ordinarily have.  */
-#define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
-  DATA_ALIGNMENT (TYPE, ALIGN)
-
 /* Alignment of field after `int : 0' in a structure.  */
 #define EMPTY_FIELD_BOUNDARY 32
 
@@ -863,8 +857,15 @@  extern unsigned rs6000_pointer_size;
 /* A bit-field declared as `int' forces `int' alignment for the struct.  */
 #define PCC_BITFIELD_TYPE_MATTERS 1
 
-/* Make strings word-aligned so strcpy from constants will be faster.
-   Make vector constants quadword aligned.  */
+enum data_align { align_abi, align_opt, align_both };
+
+/* A C expression to compute the alignment for a variables in the
+   local store.  TYPE is the data type, and ALIGN is the alignment
+   that the object would ordinarily have.  */
+#define LOCAL_ALIGNMENT(TYPE, ALIGN)				\
+  rs6000_data_alignment (TYPE, ALIGN, align_both)
+
+/* Make strings word-aligned so strcpy from constants will be faster.  */
 #define CONSTANT_ALIGNMENT(EXP, ALIGN)                           \
   (TREE_CODE (EXP) == STRING_CST	                         \
    && (STRICT_ALIGNMENT || !optimize_size)                       \
@@ -872,21 +873,14 @@  extern unsigned rs6000_pointer_size;
    ? BITS_PER_WORD                                               \
    : (ALIGN))
 
-/* Make arrays of chars word-aligned for the same reasons.
-   Align vectors to 128 bits.  Align SPE vectors and E500 v2 doubles to
+/* Make arrays of chars word-aligned for the same reasons.  */
+#define DATA_ALIGNMENT(TYPE, ALIGN) \
+  rs6000_data_alignment (TYPE, ALIGN, align_opt)
+
+/* Align vectors to 128 bits.  Align SPE vectors and E500 v2 doubles to
    64 bits.  */
-#define DATA_ALIGNMENT(TYPE, ALIGN)					\
-  (TREE_CODE (TYPE) == VECTOR_TYPE					\
-   ? (((TARGET_SPE && SPE_VECTOR_MODE (TYPE_MODE (TYPE)))		\
-       || (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (TYPE_MODE (TYPE)))) \
-      ? 64 : 128)							\
-   : ((TARGET_E500_DOUBLE						\
-       && TREE_CODE (TYPE) == REAL_TYPE					\
-       && TYPE_MODE (TYPE) == DFmode)					\
-      ? 64								\
-      : (TREE_CODE (TYPE) == ARRAY_TYPE					\
-	 && TYPE_MODE (TREE_TYPE (TYPE)) == QImode			\
-	 && (ALIGN) < BITS_PER_WORD) ? BITS_PER_WORD : (ALIGN)))
+#define DATA_ABI_ALIGNMENT(TYPE, ALIGN) \
+  rs6000_data_alignment (TYPE, ALIGN, align_abi)
 
 /* Nonzero if move instructions will actually fail to work
    when given unaligned data.  */
Index: gcc-4_8-test/gcc/config/rs6000/rs6000.md
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.md
+++ gcc-4_8-test/gcc/config/rs6000/rs6000.md
@@ -3975,20 +3975,33 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn "*rotlsi3_internal7"
+(define_insn "*rotlsi3_internal7le"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(zero_extend:SI
 	 (subreg:QI
 	  (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
 		     (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
-  ""
+  "!BYTES_BIG_ENDIAN"
+  "rlw%I2nm %0,%1,%h2,0xff"
+  [(set (attr "cell_micro")
+     (if_then_else (match_operand:SI 2 "const_int_operand" "")
+	(const_string "not")
+	(const_string "always")))])
+
+(define_insn "*rotlsi3_internal7be"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+	(zero_extend:SI
+	 (subreg:QI
+	  (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+		     (match_operand:SI 2 "reg_or_cint_operand" "ri")) 3)))]
+  "BYTES_BIG_ENDIAN"
   "rlw%I2nm %0,%1,%h2,0xff"
   [(set (attr "cell_micro")
      (if_then_else (match_operand:SI 2 "const_int_operand" "")
 	(const_string "not")
 	(const_string "always")))])
 
-(define_insn "*rotlsi3_internal8"
+(define_insn "*rotlsi3_internal8le"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (zero_extend:SI
 		     (subreg:QI
@@ -3996,7 +4009,24 @@ 
 				 (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r,r,r"))]
-  ""
+  "!BYTES_BIG_ENDIAN"
+  "@
+   rlwnm. %3,%1,%2,0xff
+   rlwinm. %3,%1,%h2,0xff
+   #
+   #"
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_insn "*rotlsi3_internal8be"
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+	(compare:CC (zero_extend:SI
+		     (subreg:QI
+		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+				 (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 3))
+		    (const_int 0)))
+   (clobber (match_scratch:SI 3 "=r,r,r,r"))]
+  "BYTES_BIG_ENDIAN"
   "@
    rlwnm. %3,%1,%2,0xff
    rlwinm. %3,%1,%h2,0xff
@@ -4013,7 +4043,7 @@ 
 				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "!BYTES_BIG_ENDIAN && reload_completed"
   [(set (match_dup 3)
 	(zero_extend:SI (subreg:QI
 		      (rotate:SI (match_dup 1)
@@ -4023,7 +4053,25 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn "*rotlsi3_internal9"
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC (zero_extend:SI
+		     (subreg:QI
+		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
+				 (match_operand:SI 2 "reg_or_cint_operand" "")) 3))
+		    (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "BYTES_BIG_ENDIAN && reload_completed"
+  [(set (match_dup 3)
+	(zero_extend:SI (subreg:QI
+		      (rotate:SI (match_dup 1)
+				 (match_dup 2)) 3)))
+   (set (match_dup 0)
+	(compare:CC (match_dup 3)
+		    (const_int 0)))]
+  "")
+
+(define_insn "*rotlsi3_internal9le"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (zero_extend:SI
 		     (subreg:QI
@@ -4032,7 +4080,25 @@ 
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
 	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
-  ""
+  "!BYTES_BIG_ENDIAN"
+  "@
+   rlwnm. %0,%1,%2,0xff
+   rlwinm. %0,%1,%h2,0xff
+   #
+   #"
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_insn "*rotlsi3_internal9be"
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+	(compare:CC (zero_extend:SI
+		     (subreg:QI
+		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+				 (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 3))
+		    (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
+	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))]
+  "BYTES_BIG_ENDIAN"
   "@
    rlwnm. %0,%1,%2,0xff
    rlwinm. %0,%1,%h2,0xff
@@ -4050,7 +4116,7 @@ 
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
-  "reload_completed"
+  "!BYTES_BIG_ENDIAN && reload_completed"
   [(set (match_dup 0)
 	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -4058,20 +4124,48 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn "*rotlsi3_internal10"
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC (zero_extend:SI
+		     (subreg:QI
+		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
+				 (match_operand:SI 2 "reg_or_cint_operand" "")) 3))
+		    (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))]
+  "BYTES_BIG_ENDIAN && reload_completed"
+  [(set (match_dup 0)
+	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 3)))
+   (set (match_dup 3)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  "")
+
+(define_insn "*rotlsi3_internal10le"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(zero_extend:SI
 	 (subreg:HI
 	  (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
 		     (match_operand:SI 2 "reg_or_cint_operand" "r,i")) 0)))]
-  ""
+  "!BYTES_BIG_ENDIAN"
   "@
    rlwnm %0,%1,%2,0xffff
    rlwinm %0,%1,%h2,0xffff"
   [(set_attr "type" "var_shift_rotate,integer")])
 
+(define_insn "*rotlsi3_internal10be"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+	(zero_extend:SI
+	 (subreg:HI
+	  (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+		     (match_operand:SI 2 "reg_or_cint_operand" "r,i")) 2)))]
+  "BYTES_BIG_ENDIAN"
+  "@
+   rlwnm %0,%1,%2,0xffff
+   rlwinm %0,%1,%h2,0xffff"
+  [(set_attr "type" "var_shift_rotate,integer")])
 
-(define_insn "*rotlsi3_internal11"
+(define_insn "*rotlsi3_internal11le"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (zero_extend:SI
 		     (subreg:HI
@@ -4079,7 +4173,24 @@ 
 				 (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r,r,r"))]
-  ""
+  "!BYTES_BIG_ENDIAN"
+  "@
+   rlwnm. %3,%1,%2,0xffff
+   rlwinm. %3,%1,%h2,0xffff
+   #
+   #"
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_insn "*rotlsi3_internal11be"
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+	(compare:CC (zero_extend:SI
+		     (subreg:HI
+		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+				 (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 2))
+		    (const_int 0)))
+   (clobber (match_scratch:SI 3 "=r,r,r,r"))]
+  "BYTES_BIG_ENDIAN"
   "@
    rlwnm. %3,%1,%2,0xffff
    rlwinm. %3,%1,%h2,0xffff
@@ -4096,7 +4207,7 @@ 
 				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "!BYTES_BIG_ENDIAN && reload_completed"
   [(set (match_dup 3)
 	(zero_extend:SI (subreg:HI
 		      (rotate:SI (match_dup 1)
@@ -4106,7 +4217,25 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn "*rotlsi3_internal12"
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC (zero_extend:SI
+		     (subreg:HI
+		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
+				 (match_operand:SI 2 "reg_or_cint_operand" "")) 2))
+		    (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "BYTES_BIG_ENDIAN && reload_completed"
+  [(set (match_dup 3)
+	(zero_extend:SI (subreg:HI
+		      (rotate:SI (match_dup 1)
+				 (match_dup 2)) 2)))
+   (set (match_dup 0)
+	(compare:CC (match_dup 3)
+		    (const_int 0)))]
+  "")
+
+(define_insn "*rotlsi3_internal12le"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (zero_extend:SI
 		     (subreg:HI
@@ -4115,7 +4244,25 @@ 
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
 	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
-  ""
+  "!BYTES_BIG_ENDIAN"
+  "@
+   rlwnm. %0,%1,%2,0xffff
+   rlwinm. %0,%1,%h2,0xffff
+   #
+   #"
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_insn "*rotlsi3_internal12be"
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+	(compare:CC (zero_extend:SI
+		     (subreg:HI
+		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+				 (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 2))
+		    (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
+	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))]
+  "BYTES_BIG_ENDIAN"
   "@
    rlwnm. %0,%1,%2,0xffff
    rlwinm. %0,%1,%h2,0xffff
@@ -4133,7 +4280,7 @@ 
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
-  "reload_completed"
+  "!BYTES_BIG_ENDIAN && reload_completed"
   [(set (match_dup 0)
 	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -4141,6 +4288,23 @@ 
 		    (const_int 0)))]
   "")
 
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC (zero_extend:SI
+		     (subreg:HI
+		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
+				 (match_operand:SI 2 "reg_or_cint_operand" "")) 2))
+		    (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))]
+  "BYTES_BIG_ENDIAN && reload_completed"
+  [(set (match_dup 0)
+	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 2)))
+   (set (match_dup 3)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  "")
+
 (define_insn "ashlsi3"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
@@ -4454,16 +4618,25 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn ""
+(define_insn "*lshiftrt_internal1le"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(zero_extend:SI
 	 (subreg:QI
 	  (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
 		       (match_operand:SI 2 "const_int_operand" "i")) 0)))]
-  "includes_rshift_p (operands[2], GEN_INT (255))"
+  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
   "rlwinm %0,%1,%s2,0xff")
 
-(define_insn ""
+(define_insn "*lshiftrt_internal1be"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+	(zero_extend:SI
+	 (subreg:QI
+	  (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+		       (match_operand:SI 2 "const_int_operand" "i")) 3)))]
+  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
+  "rlwinm %0,%1,%s2,0xff")
+
+(define_insn "*lshiftrt_internal2le"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
 	(compare:CC
 	 (zero_extend:SI
@@ -4472,7 +4645,23 @@ 
 			(match_operand:SI 2 "const_int_operand" "i,i")) 0))
 	 (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r"))]
-  "includes_rshift_p (operands[2], GEN_INT (255))"
+  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
+  "@
+   rlwinm. %3,%1,%s2,0xff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_insn "*lshiftrt_internal2be"
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+	(compare:CC
+	 (zero_extend:SI
+	  (subreg:QI
+	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+			(match_operand:SI 2 "const_int_operand" "i,i")) 3))
+	 (const_int 0)))
+   (clobber (match_scratch:SI 3 "=r,r"))]
+  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
   "@
    rlwinm. %3,%1,%s2,0xff
    #"
@@ -4488,7 +4677,7 @@ 
 			(match_operand:SI 2 "const_int_operand" "")) 0))
 	 (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
+  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
   [(set (match_dup 3)
 	(zero_extend:SI (subreg:QI
 	   (lshiftrt:SI (match_dup 1)
@@ -4498,7 +4687,26 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn ""
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC
+	 (zero_extend:SI
+	  (subreg:QI
+	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+			(match_operand:SI 2 "const_int_operand" "")) 3))
+	 (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
+  [(set (match_dup 3)
+	(zero_extend:SI (subreg:QI
+	   (lshiftrt:SI (match_dup 1)
+			(match_dup 2)) 3)))
+   (set (match_dup 0)
+	(compare:CC (match_dup 3)
+		    (const_int 0)))]
+  "")
+
+(define_insn "*lshiftrt_internal3le"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
 	(compare:CC
 	 (zero_extend:SI
@@ -4508,7 +4716,24 @@ 
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
-  "includes_rshift_p (operands[2], GEN_INT (255))"
+  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
+  "@
+   rlwinm. %0,%1,%s2,0xff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_insn "*lshiftrt_internal3be"
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+	(compare:CC
+	 (zero_extend:SI
+	  (subreg:QI
+	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+			(match_operand:SI 2 "const_int_operand" "i,i")) 3))
+	 (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))]
+  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255))"
   "@
    rlwinm. %0,%1,%s2,0xff
    #"
@@ -4525,7 +4750,7 @@ 
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
-  "includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
+  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
   [(set (match_dup 0)
 	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -4533,16 +4758,43 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn ""
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC
+	 (zero_extend:SI
+	  (subreg:QI
+	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+			(match_operand:SI 2 "const_int_operand" "")) 3))
+	 (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))]
+  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
+  [(set (match_dup 0)
+	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 3)))
+   (set (match_dup 3)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  "")
+
+(define_insn "*lshiftrt_internal4le"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(zero_extend:SI
 	 (subreg:HI
 	  (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
 		       (match_operand:SI 2 "const_int_operand" "i")) 0)))]
-  "includes_rshift_p (operands[2], GEN_INT (65535))"
+  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
   "rlwinm %0,%1,%s2,0xffff")
 
-(define_insn ""
+(define_insn "*lshiftrt_internal4be"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+	(zero_extend:SI
+	 (subreg:HI
+	  (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+		       (match_operand:SI 2 "const_int_operand" "i")) 2)))]
+  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
+  "rlwinm %0,%1,%s2,0xffff")
+
+(define_insn "*lshiftrt_internal5le"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
 	(compare:CC
 	 (zero_extend:SI
@@ -4551,7 +4803,23 @@ 
 			(match_operand:SI 2 "const_int_operand" "i,i")) 0))
 	 (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r"))]
-  "includes_rshift_p (operands[2], GEN_INT (65535))"
+  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
+  "@
+   rlwinm. %3,%1,%s2,0xffff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_insn "*lshiftrt_internal5be"
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+	(compare:CC
+	 (zero_extend:SI
+	  (subreg:HI
+	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+			(match_operand:SI 2 "const_int_operand" "i,i")) 2))
+	 (const_int 0)))
+   (clobber (match_scratch:SI 3 "=r,r"))]
+  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
   "@
    rlwinm. %3,%1,%s2,0xffff
    #"
@@ -4567,7 +4835,7 @@ 
 			(match_operand:SI 2 "const_int_operand" "")) 0))
 	 (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
+  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
   [(set (match_dup 3)
 	(zero_extend:SI (subreg:HI
 	   (lshiftrt:SI (match_dup 1)
@@ -4577,7 +4845,26 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn ""
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC
+	 (zero_extend:SI
+	  (subreg:HI
+	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+			(match_operand:SI 2 "const_int_operand" "")) 2))
+	 (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
+  [(set (match_dup 3)
+	(zero_extend:SI (subreg:HI
+	   (lshiftrt:SI (match_dup 1)
+			(match_dup 2)) 2)))
+   (set (match_dup 0)
+	(compare:CC (match_dup 3)
+		    (const_int 0)))]
+  "")
+
+(define_insn "*lshiftrt_internal5le"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
 	(compare:CC
 	 (zero_extend:SI
@@ -4587,7 +4874,24 @@ 
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
-  "includes_rshift_p (operands[2], GEN_INT (65535))"
+  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
+  "@
+   rlwinm. %0,%1,%s2,0xffff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_insn "*lshiftrt_internal5be"
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+	(compare:CC
+	 (zero_extend:SI
+	  (subreg:HI
+	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+			(match_operand:SI 2 "const_int_operand" "i,i")) 2))
+	 (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))]
+  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535))"
   "@
    rlwinm. %0,%1,%s2,0xffff
    #"
@@ -4604,7 +4908,7 @@ 
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
-  "includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
+  "!BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
   [(set (match_dup 0)
 	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -4612,6 +4916,24 @@ 
 		    (const_int 0)))]
   "")
 
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC
+	 (zero_extend:SI
+	  (subreg:HI
+	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+			(match_operand:SI 2 "const_int_operand" "")) 2))
+	 (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))]
+  "BYTES_BIG_ENDIAN && includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
+  [(set (match_dup 0)
+	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 2)))
+   (set (match_dup 3)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  "")
+
 (define_insn "ashrsi3"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
@@ -6379,11 +6701,11 @@ 
   [(set_attr "type" "two,three")
    (set_attr "length" "8,12")])
 
-(define_insn "*ashrdisi3_noppc64"
+(define_insn "*ashrdisi3_noppc64be"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
         (subreg:SI (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
                                 (const_int 32)) 4))]
-  "TARGET_32BIT && !TARGET_POWERPC64"
+  "TARGET_32BIT && !TARGET_POWERPC64 && WORDS_BIG_ENDIAN"
   "*
 {
   if (REGNO (operands[0]) == REGNO (operands[1]))
@@ -6670,19 +6992,31 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn "*rotldi3_internal7"
+(define_insn "*rotldi3_internal7le"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
 	(zero_extend:DI
 	 (subreg:QI
 	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
 		     (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))]
-  "TARGET_POWERPC64"
+  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
   "@
    rldcl %0,%1,%2,56
    rldicl %0,%1,%H2,56"
   [(set_attr "type" "var_shift_rotate,integer")])
 
-(define_insn "*rotldi3_internal8"
+(define_insn "*rotldi3_internal7be"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+	(zero_extend:DI
+	 (subreg:QI
+	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+		     (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 7)))]
+  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
+  "@
+   rldcl %0,%1,%2,56
+   rldicl %0,%1,%H2,56"
+  [(set_attr "type" "var_shift_rotate,integer")])
+
+(define_insn "*rotldi3_internal8le"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (zero_extend:DI
 		     (subreg:QI
@@ -6690,7 +7024,24 @@ 
 				 (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:DI 3 "=r,r,r,r"))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && !BYTES_BIG_ENDIAN"
+  "@
+   rldcl. %3,%1,%2,56
+   rldicl. %3,%1,%H2,56
+   #
+   #"
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_insn "*rotldi3_internal8be"
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+	(compare:CC (zero_extend:DI
+		     (subreg:QI
+		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+				 (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 7))
+		    (const_int 0)))
+   (clobber (match_scratch:DI 3 "=r,r,r,r"))]
+  "TARGET_64BIT && BYTES_BIG_ENDIAN"
   "@
    rldcl. %3,%1,%2,56
    rldicl. %3,%1,%H2,56
@@ -6707,7 +7058,7 @@ 
 				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
   [(set (match_dup 3)
 	(zero_extend:DI (subreg:QI
 		      (rotate:DI (match_dup 1)
@@ -6717,7 +7068,25 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn "*rotldi3_internal9"
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC (zero_extend:DI
+		     (subreg:QI
+		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+				 (match_operand:DI 2 "reg_or_cint_operand" "")) 7))
+		    (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
+  [(set (match_dup 3)
+	(zero_extend:DI (subreg:QI
+		      (rotate:DI (match_dup 1)
+				 (match_dup 2)) 7)))
+   (set (match_dup 0)
+	(compare:CC (match_dup 3)
+		    (const_int 0)))]
+  "")
+
+(define_insn "*rotldi3_internal9le"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (zero_extend:DI
 		     (subreg:QI
@@ -6726,7 +7095,25 @@ 
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
 	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && !BYTES_BIG_ENDIAN"
+  "@
+   rldcl. %0,%1,%2,56
+   rldicl. %0,%1,%H2,56
+   #
+   #"
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_insn "*rotldi3_internal9be"
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+	(compare:CC (zero_extend:DI
+		     (subreg:QI
+		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+				 (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 7))
+		    (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
+	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))]
+  "TARGET_64BIT && BYTES_BIG_ENDIAN"
   "@
    rldcl. %0,%1,%2,56
    rldicl. %0,%1,%H2,56
@@ -6744,7 +7131,7 @@ 
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
   [(set (match_dup 0)
 	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -6752,19 +7139,48 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn "*rotldi3_internal10"
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC (zero_extend:DI
+		     (subreg:QI
+		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+				 (match_operand:DI 2 "reg_or_cint_operand" "")) 7))
+		    (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))]
+  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
+  [(set (match_dup 0)
+	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 7)))
+   (set (match_dup 3)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  "")
+
+(define_insn "*rotldi3_internal10le"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
 	(zero_extend:DI
 	 (subreg:HI
 	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
 		     (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))]
-  "TARGET_POWERPC64"
+  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
+  "@
+   rldcl %0,%1,%2,48
+   rldicl %0,%1,%H2,48"
+  [(set_attr "type" "var_shift_rotate,integer")])
+
+(define_insn "*rotldi3_internal10be"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+	(zero_extend:DI
+	 (subreg:HI
+	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+		     (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 6)))]
+  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
   "@
    rldcl %0,%1,%2,48
    rldicl %0,%1,%H2,48"
   [(set_attr "type" "var_shift_rotate,integer")])
 
-(define_insn "*rotldi3_internal11"
+(define_insn "*rotldi3_internal11le"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (zero_extend:DI
 		     (subreg:HI
@@ -6772,7 +7188,24 @@ 
 				 (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:DI 3 "=r,r,r,r"))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && !BYTES_BIG_ENDIAN"
+  "@
+   rldcl. %3,%1,%2,48
+   rldicl. %3,%1,%H2,48
+   #
+   #"
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_insn "*rotldi3_internal11be"
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+	(compare:CC (zero_extend:DI
+		     (subreg:HI
+		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+				 (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 6))
+		    (const_int 0)))
+   (clobber (match_scratch:DI 3 "=r,r,r,r"))]
+  "TARGET_64BIT && BYTES_BIG_ENDIAN"
   "@
    rldcl. %3,%1,%2,48
    rldicl. %3,%1,%H2,48
@@ -6789,7 +7222,7 @@ 
 				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
   [(set (match_dup 3)
 	(zero_extend:DI (subreg:HI
 		      (rotate:DI (match_dup 1)
@@ -6799,7 +7232,25 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn "*rotldi3_internal12"
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC (zero_extend:DI
+		     (subreg:HI
+		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+				 (match_operand:DI 2 "reg_or_cint_operand" "")) 6))
+		    (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
+  [(set (match_dup 3)
+	(zero_extend:DI (subreg:HI
+		      (rotate:DI (match_dup 1)
+				 (match_dup 2)) 6)))
+   (set (match_dup 0)
+	(compare:CC (match_dup 3)
+		    (const_int 0)))]
+  "")
+
+(define_insn "*rotldi3_internal12le"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (zero_extend:DI
 		     (subreg:HI
@@ -6808,7 +7259,25 @@ 
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
 	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && !BYTES_BIG_ENDIAN"
+  "@
+   rldcl. %0,%1,%2,48
+   rldicl. %0,%1,%H2,48
+   #
+   #"
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_insn "*rotldi3_internal12be"
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+	(compare:CC (zero_extend:DI
+		     (subreg:HI
+		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+				 (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 6))
+		    (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
+	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))]
+  "TARGET_64BIT && BYTES_BIG_ENDIAN"
   "@
    rldcl. %0,%1,%2,48
    rldicl. %0,%1,%H2,48
@@ -6826,7 +7295,7 @@ 
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
   [(set (match_dup 0)
 	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -6834,19 +7303,48 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn "*rotldi3_internal13"
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC (zero_extend:DI
+		     (subreg:HI
+		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+				 (match_operand:DI 2 "reg_or_cint_operand" "")) 6))
+		    (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))]
+  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
+  [(set (match_dup 0)
+	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 6)))
+   (set (match_dup 3)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  "")
+
+(define_insn "*rotldi3_internal13le"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
 	(zero_extend:DI
 	 (subreg:SI
 	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
 		     (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))]
-  "TARGET_POWERPC64"
+  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN"
   "@
    rldcl %0,%1,%2,32
    rldicl %0,%1,%H2,32"
   [(set_attr "type" "var_shift_rotate,integer")])
 
-(define_insn "*rotldi3_internal14"
+(define_insn "*rotldi3_internal13be"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+	(zero_extend:DI
+	 (subreg:SI
+	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+		     (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 4)))]
+  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN"
+  "@
+   rldcl %0,%1,%2,32
+   rldicl %0,%1,%H2,32"
+  [(set_attr "type" "var_shift_rotate,integer")])
+
+(define_insn "*rotldi3_internal14le"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (zero_extend:DI
 		     (subreg:SI
@@ -6854,7 +7352,24 @@ 
 				 (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:DI 3 "=r,r,r,r"))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && !BYTES_BIG_ENDIAN"
+  "@
+   rldcl. %3,%1,%2,32
+   rldicl. %3,%1,%H2,32
+   #
+   #"
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_insn "*rotldi3_internal14be"
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+	(compare:CC (zero_extend:DI
+		     (subreg:SI
+		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+				 (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 4))
+		    (const_int 0)))
+   (clobber (match_scratch:DI 3 "=r,r,r,r"))]
+  "TARGET_64BIT && BYTES_BIG_ENDIAN"
   "@
    rldcl. %3,%1,%2,32
    rldicl. %3,%1,%H2,32
@@ -6871,7 +7386,7 @@ 
 				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
   [(set (match_dup 3)
 	(zero_extend:DI (subreg:SI
 		      (rotate:DI (match_dup 1)
@@ -6881,7 +7396,25 @@ 
 		    (const_int 0)))]
   "")
 
-(define_insn "*rotldi3_internal15"
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC (zero_extend:DI
+		     (subreg:SI
+		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+				 (match_operand:DI 2 "reg_or_cint_operand" "")) 4))
+		    (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
+  [(set (match_dup 3)
+	(zero_extend:DI (subreg:SI
+		      (rotate:DI (match_dup 1)
+				 (match_dup 2)) 4)))
+   (set (match_dup 0)
+	(compare:CC (match_dup 3)
+		    (const_int 0)))]
+  "")
+
+(define_insn "*rotldi3_internal15le"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
 	(compare:CC (zero_extend:DI
 		     (subreg:SI
@@ -6890,7 +7423,25 @@ 
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
 	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && !BYTES_BIG_ENDIAN"
+  "@
+   rldcl. %0,%1,%2,32
+   rldicl. %0,%1,%H2,32
+   #
+   #"
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_insn "*rotldi3_internal15be"
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+	(compare:CC (zero_extend:DI
+		     (subreg:SI
+		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+				 (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 4))
+		    (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
+	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))]
+  "TARGET_64BIT && BYTES_BIG_ENDIAN"
   "@
    rldcl. %0,%1,%2,32
    rldicl. %0,%1,%H2,32
@@ -6908,7 +7459,7 @@ 
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && !BYTES_BIG_ENDIAN && reload_completed"
   [(set (match_dup 0)
 	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -6916,6 +7467,23 @@ 
 		    (const_int 0)))]
   "")
 
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+	(compare:CC (zero_extend:DI
+		     (subreg:SI
+		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+				 (match_operand:DI 2 "reg_or_cint_operand" "")) 4))
+		    (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))]
+  "TARGET_POWERPC64 && BYTES_BIG_ENDIAN && reload_completed"
+  [(set (match_dup 0)
+	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 4)))
+   (set (match_dup 3)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  "")
+
 (define_expand "ashldi3"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
 	(ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
@@ -10791,7 +11359,7 @@ 
 	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
    (set (match_dup 0)
    	(lo_sum:TLSmode (match_dup 3)
-	    (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)))]
+	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
   "
 {
   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
@@ -10814,7 +11382,8 @@ 
 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
-       (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+       (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
+			(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
 		       UNSPEC_TLSGD)))]
   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
   "addi %0,%1,%2@got@tlsgd@l"
@@ -10927,7 +11496,7 @@ 
 	    (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
    (set (match_dup 0)
    	(lo_sum:TLSmode (match_dup 2)
-	    (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))]
+	    (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
   "
 {
   operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
@@ -10950,7 +11519,9 @@ 
 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
-       (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))]
+       (unspec:TLSmode [(const_int 0)
+                        (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
+                       UNSPEC_TLSLD)))]
   "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
   "addi %0,%1,%&@got@tlsld@l"
   [(set_attr "length" "4")])
@@ -11023,7 +11594,7 @@ 
 	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
    (set (match_dup 0)
 	(lo_sum:TLSmode (match_dup 3)
-	    (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
+	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
   "
 {
   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
@@ -11046,7 +11617,8 @@ 
 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
-	 (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+	 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
+			  (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
 			 UNSPEC_TLSGOTDTPREL)))]
   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
   "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
@@ -11092,7 +11664,7 @@ 
 	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
    (set (match_dup 0)
 	(lo_sum:TLSmode (match_dup 3)
-	    (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL)))]
+	    (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
   "
 {
   operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
@@ -11115,7 +11687,8 @@ 
 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
      (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
-	 (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+	 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
+			  (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
 			 UNSPEC_TLSGOTTPREL)))]
   "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
   "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"