Patchwork PowerPC VLE port

login
register
mail settings
Submitter James Lemke
Date Sept. 25, 2012, 1:44 a.m.
Message ID <50610C62.7060901@codesourcery.com>
Download mbox | patch
Permalink /patch/186671/
State New
Headers show

Comments

James Lemke - Sept. 25, 2012, 1:44 a.m.
The initial patch for this port caused much comment.  I have attached
an updated patch trying to address many of those points.
All comments are welcome.  I would prefer comments are made on-list.

I have tried to simplify this patch by:
1) Removing as many compound tests as possible and now rely on feature flags.
I have removed TARGET_VLE_ISEL, TARGET_VLE_MULTIPLE, TARGET_VLE_ISEL64 &
TARGET_MFCRF_NOVLE.
-mcpu now implies the following options:
-mcpu=e200z[0-2]: -mvle -misel -mno-mfcrf -mmultiple -msoft-float
-mcpu=e200z[367]: -mvle -misel -mno-mfcrf -mmultiple -mfloat-gprs=single \
   -mspe=yes -mabi=spe
2) When gcc is configured for a non-VLE target, TARGET_VLE evaluates to "0"
so that most VLE-specific compiler code is optimized away.
3) Separated all VLE-only items from rs6000.md to a new file, vle.md.
In the cases where there was strong commonality there is still VLE code in
rs6000.md.

On r191665 I have run the DejaGNU suite.  A bootstrap is running.

Comments?
Jim.

Patch

Index: gcc/config/rs6000/rs6000-tables.opt
===================================================================
--- gcc/config/rs6000/rs6000-tables.opt	(revision 191665)
+++ gcc/config/rs6000/rs6000-tables.opt	(working copy)
@@ -114,74 +114,92 @@ 
 Enum(rs6000_cpu_opt_value) String(a2) Value(28)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(e300c2) Value(29)
+Enum(rs6000_cpu_opt_value) String(e200z0) Value(29)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(e300c3) Value(30)
+Enum(rs6000_cpu_opt_value) String(e200z1) Value(30)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(e500mc) Value(31)
+Enum(rs6000_cpu_opt_value) String(e200z2) Value(31)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(e500mc64) Value(32)
+Enum(rs6000_cpu_opt_value) String(e200z3) Value(32)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(e5500) Value(33)
+Enum(rs6000_cpu_opt_value) String(e200z6) Value(33)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(e6500) Value(34)
+Enum(rs6000_cpu_opt_value) String(e200z7) Value(34)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(860) Value(35)
+Enum(rs6000_cpu_opt_value) String(e300c2) Value(35)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(970) Value(36)
+Enum(rs6000_cpu_opt_value) String(e300c3) Value(36)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(cell) Value(37)
+Enum(rs6000_cpu_opt_value) String(e500mc) Value(37)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(ec603e) Value(38)
+Enum(rs6000_cpu_opt_value) String(e500mc64) Value(38)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(G3) Value(39)
+Enum(rs6000_cpu_opt_value) String(e5500) Value(39)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(G4) Value(40)
+Enum(rs6000_cpu_opt_value) String(e6500) Value(40)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(G5) Value(41)
+Enum(rs6000_cpu_opt_value) String(860) Value(41)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(titan) Value(42)
+Enum(rs6000_cpu_opt_value) String(970) Value(42)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(power3) Value(43)
+Enum(rs6000_cpu_opt_value) String(cell) Value(43)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(power4) Value(44)
+Enum(rs6000_cpu_opt_value) String(ec603e) Value(44)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(power5) Value(45)
+Enum(rs6000_cpu_opt_value) String(G3) Value(45)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(power5+) Value(46)
+Enum(rs6000_cpu_opt_value) String(G4) Value(46)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(power6) Value(47)
+Enum(rs6000_cpu_opt_value) String(G5) Value(47)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(power6x) Value(48)
+Enum(rs6000_cpu_opt_value) String(titan) Value(48)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(power7) Value(49)
+Enum(rs6000_cpu_opt_value) String(power3) Value(49)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(powerpc) Value(50)
+Enum(rs6000_cpu_opt_value) String(power4) Value(50)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(powerpc64) Value(51)
+Enum(rs6000_cpu_opt_value) String(power5) Value(51)
 
 EnumValue
-Enum(rs6000_cpu_opt_value) String(rs64) Value(52)
+Enum(rs6000_cpu_opt_value) String(power5+) Value(52)
 
+EnumValue
+Enum(rs6000_cpu_opt_value) String(power6) Value(53)
+
+EnumValue
+Enum(rs6000_cpu_opt_value) String(power6x) Value(54)
+
+EnumValue
+Enum(rs6000_cpu_opt_value) String(power7) Value(55)
+
+EnumValue
+Enum(rs6000_cpu_opt_value) String(powerpc) Value(56)
+
+EnumValue
+Enum(rs6000_cpu_opt_value) String(powerpc64) Value(57)
+
+EnumValue
+Enum(rs6000_cpu_opt_value) String(rs64) Value(58)
+
Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md	(revision 191665)
+++ gcc/config/rs6000/predicates.md	(working copy)
@@ -185,6 +185,144 @@ 
   return INT_REGNO_P (REGNO (op)) || FP_REGNO_P (REGNO (op));
 })
 
+;; Return 1 if op is a register in the range 0-7 or 24-31.
+(define_predicate "vle_reg_operand"
+   (and (match_operand 0 "register_operand")
+        (match_test "(REGNO (op) <= 7
+		       || (REGNO (op) >= 24 && REGNO (op) <= 31))")))
+
+;; Return 1 if op is a valid add operand for VLE instructions.
+(define_predicate "vle_add_operand"
+  (if_then_else (match_code "const_int")
+    (match_test "satisfies_constraint_I (op)
+		 || satisfies_constraint_L (op)
+		 || satisfies_constraint_koim5 (op)
+		 || satisfies_constraint_ksci8 (op)")
+    (match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if op is a valid three-argument add operand for VLE instructions.
+(define_predicate "vle_add3_operand"
+  (if_then_else (match_code "const_int")
+    (match_test "satisfies_constraint_I (op)
+		 || satisfies_constraint_ksci8 (op)")
+    (match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if op is a non-special register or a constant integer whose
+;; negation is a valid add operand for VLE instructions.
+(define_predicate "vle_reg_or_neg_imm_operand"
+  (if_then_else (match_code "const_int")
+    (match_test "satisfies_constraint_I (op)
+		 || satisfies_constraint_kscp8 (op)")
+    (match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if op is a valid VLE sub 1st or xor 2nd operand.
+(define_predicate "vle_r_or_sci8_operand"
+  (if_then_else (match_code "const_int")
+    (match_test "satisfies_constraint_ksci8 (op)")
+    (match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if op is a valid 2nd subtract operand for VLE instructions.
+(define_predicate "vle_sub_operand2"
+  (if_then_else (match_code "const_int")
+    (match_test "satisfies_constraint_koim5 (op)")
+    (match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if op is a valid and operand for VLE instructions.
+(define_predicate "vle_and_operand"
+  (if_then_else (match_code "const_int")
+		(ior (match_test "satisfies_constraint_kuim5 (op)")
+		     (match_test "satisfies_constraint_kbic5 (op)")
+		     (match_test "satisfies_constraint_ksci8 (op)")
+		     (match_test "satisfies_constraint_T (op)")
+		     (match_test "satisfies_constraint_K (op)")
+		     (match_test "satisfies_constraint_L (op)"))
+		(match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if op is a valid andc operand for VLE instructions.
+(define_predicate "vle_andc_operand"
+  (if_then_else (match_code "const_int")
+		(match_test "satisfies_constraint_kbit5 (op)")
+		(match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if op is a valid or operand for VLE instructions.
+(define_predicate "vle_or_operand"
+  (if_then_else (match_code "const_int")
+		(ior (match_test "satisfies_constraint_kuim5 (op)")
+		     (match_test "satisfies_constraint_kbit5 (op)")
+		     (match_test "satisfies_constraint_K (op)")
+		     (match_test "satisfies_constraint_L (op)")
+		     (match_test "satisfies_constraint_ksci8 (op)"))
+		(match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if op is a valid and-compare operand for VLE instructions.
+(define_predicate "vle_andcmp_operand"
+  (if_then_else (match_code "const_int")
+		(ior (match_test "satisfies_constraint_K (op)")
+		     (match_test "satisfies_constraint_L (op)")
+		     (match_test "satisfies_constraint_ksci8 (op)"))
+		(match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if op is a valid operand for the SImode VLE arithmetic compares.
+(define_predicate "vle_arith_cmpsi_operand"
+  (if_then_else (match_code "const_int")
+       (match_test "satisfies_constraint_kuim5 (op)
+		 || satisfies_constraint_I (op)
+		 || satisfies_constraint_ksci8 (op)")
+    (match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if op is a valid operand for the SImode VLE logical compares.
+(define_predicate "vle_logical_cmpsi_operand"
+  (if_then_else (match_code "const_int")
+       (match_test "satisfies_constraint_koim5 (op)
+		 || satisfies_constraint_K (op)
+		 || satisfies_constraint_ksci8 (op)")
+    (match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if op is a valid operand for the HImode VLE arithmetic compares.
+(define_predicate "vle_arith_cmphi_operand"
+  (if_then_else (match_code "const_int")
+       (match_test "satisfies_constraint_I (op)")
+    (match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if op is a valid operand for the HImode VLE logical compares.
+(define_predicate "vle_logical_cmphi_operand"
+  (if_then_else (match_code "const_int")
+       (match_test "satisfies_constraint_K (op)")
+    (match_operand 0 "gpc_reg_operand")))
+
+;; Return 1 if op is a valid SCI8 field.
+(define_predicate "vle_sci8_operand"
+   (and (match_code "const_int")
+        (match_test "satisfies_constraint_ksci8 (op)")))
+
+;; Return 1 if op is a valid D8 field.
+(define_predicate "vle_d8_operand"
+   (and (match_code "const_int")
+        (match_test "satisfies_constraint_kmmd8 (op)")))
+
+;; Return 1 if the operand is a memory operand with an address divisible
+;; by 4 and not requesting an address update.
+(define_predicate "vle_sd4_operand"
+   (and (match_operand 0 "memory_operand")
+        (match_test "valid_vle_sd4_field (op, GET_MODE (op))")))
+
+;; Return 1 if the operand is a condition register field
+;; that is valid in VLE instructions.
+(define_predicate "vle_cc_reg_operand"
+  (match_operand 0 "register_operand")
+{
+  if (GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+
+  if (!REG_P (op))
+    return 0;
+
+  if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+    return 1;
+
+  return VLE_CR_REGNO_P (REGNO (op));
+})
+
 ;; Return 1 if op is a register that is a condition register field.
 (define_predicate "cc_reg_operand"
   (match_operand 0 "register_operand")
@@ -201,6 +339,26 @@ 
   return CR_REGNO_P (REGNO (op));
 })
 
+;; Return 1 if op is a register that is a condition register field
+;; suitable for the cmpi/cmpli/bc instructions in the current mode.
+(define_predicate "cmpi_cc_reg_operand"
+  (match_operand 0 "register_operand")
+{
+  if (GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+
+  if (!REG_P (op))
+    return 0;
+
+  if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+    return 1;
+
+  if (TARGET_VLE)
+    return VLE_CR_REGNO_P (REGNO (op));
+  else
+    return CR_REGNO_P (REGNO (op));
+})
+
 ;; Return 1 if op is a register that is a condition register field not cr0.
 (define_predicate "cc_reg_not_cr0_operand"
   (match_operand 0 "register_operand")
@@ -217,7 +375,44 @@ 
   return CR_REGNO_NOT_CR0_P (REGNO (op));
 })
 
-;; Return 1 if op is a register that is a condition register field and if generating microcode, not cr0.
+;; Return 1 if op is a register that is a condition register field not cr0
+;; suitable for the cmpi/cmpli/bc instructions in the current mode.
+(define_predicate "cmpi_cc_reg_not_cr0_operand"
+  (match_operand 0 "register_operand")
+{
+  if (GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+
+  if (!REG_P (op))
+    return 0;
+
+  if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+    return 1;
+
+  if (TARGET_VLE)
+    return VLE_CR_REGNO_NOT_CR0_P (REGNO (op));
+  else
+    return CR_REGNO_NOT_CR0_P (REGNO (op));
+})
+
+;; Return 1 if op is a register that is condition register field cr0.
+(define_predicate "cc_reg_cr0_operand"
+  (match_operand 0 "register_operand")
+{
+  if (GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+
+  if (!REG_P (op))
+    return 0;
+
+  if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+    return 1;
+
+  return CR0_REGNO_P (REGNO (op));
+})
+
+;; Return 1 if op is a register that is a condition register field
+;; and if generating microcode, not cr0.
 (define_predicate "cc_reg_not_micro_cr0_operand"
   (match_operand 0 "register_operand")
 {
@@ -236,6 +431,56 @@ 
     return CR_REGNO_P (REGNO (op));
 })
 
+;; Return 1 if op is a register that is a condition register field
+;; suitable for the cmpi/cmpli/bc instructions in the current mode
+;; and if generating microcode, not cr0.
+(define_predicate "cmpi_cc_reg_not_micro_cr0_operand"
+  (match_operand 0 "register_operand")
+{
+  if (GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+
+  if (!REG_P (op))
+    return 0;
+
+  if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+    return 1;
+
+  if (rs6000_gen_cell_microcode)
+    if (TARGET_VLE)
+      return VLE_CR_REGNO_NOT_CR0_P (REGNO (op));
+    else
+      return CR_REGNO_NOT_CR0_P (REGNO (op));
+  else
+    if (TARGET_VLE)
+      return VLE_CR_REGNO_P (REGNO (op));
+    else
+      return CR_REGNO_P (REGNO (op));
+})
+
+;; Return 1 if op is a register that is a condition register field
+;; suitable for the cmpi/cmpli/bc instructions in the current mode
+;; and if non-VLE and generating microcode, not cr0.
+(define_predicate "cmpi_cc_reg_vle_or_not_micro_cr0_operand"
+  (match_operand 0 "register_operand")
+{
+  if (GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+
+  if (!REG_P (op))
+    return 0;
+
+  if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+    return 1;
+
+  if (TARGET_VLE)
+    return VLE_CR_REGNO_P (REGNO (op));
+  else if (rs6000_gen_cell_microcode)
+    return CR_REGNO_NOT_CR0_P (REGNO (op));
+  else
+    return CR_REGNO_P (REGNO (op));
+})
+
 ;; Return 1 if op is a constant integer valid for D field
 ;; or non-special register register.
 (define_predicate "reg_or_short_operand"
@@ -243,6 +488,15 @@ 
     (match_operand 0 "short_cint_operand")
     (match_operand 0 "gpc_reg_operand")))
 
+;; Return 1 if op is a constant integer whose negation is valid for
+;; D or D8 field, as applicable to the selected instruction set for the
+;; load/store-with-update instruction, or a non-special register.
+(define_predicate "reg_or_neg_d_d8_operand"
+  (if_then_else (match_code "const_int")
+    (match_test "(!TARGET_VLE && INTVAL (op) >= -32767 && INTVAL (op) <= 32768)
+		 || (INTVAL (op) >= -127 && INTVAL (op) <= 128)")
+    (match_operand 0 "gpc_reg_operand")))
+
 ;; Return 1 if op is a constant integer valid whose negation is valid for
 ;; D field or non-special register register.
 ;; Do not allow a constant zero because all patterns that call this
@@ -489,8 +743,12 @@ 
   (and (match_code "const_int,const_double,const_vector")
        (match_test "op == CONST0_RTX (mode)")))
 
+;; Return 1 if operand is constant one.
+(define_predicate "one_constant"
+  (and (match_code "const_int")
+       (match_test "op == CONST1_RTX (mode)")))
+
 ;; Return 1 if operand is 0.0.
-;; or non-special register register field no cr0
 (define_predicate "zero_fp_constant"
   (and (match_code "const_double")
        (match_test "SCALAR_FLOAT_MODE_P (mode)
@@ -570,11 +828,12 @@ 
 		 || satisfies_constraint_L (op)")
     (match_operand 0 "gpc_reg_operand")))
 
-;; Return 1 if OP is a constant but not a valid add_operand.
+;; Return 1 if OP is a constant but not a valid add_operand/vle_add_operand.
 (define_predicate "non_add_cint_operand"
   (and (match_code "const_int")
-       (match_test "!satisfies_constraint_I (op)
-		    && !satisfies_constraint_L (op)")))
+       (if_then_else (match_test "TARGET_VLE")
+		     (match_test "!vle_add_operand (op, mode)")
+		     (match_test "!add_operand (op, mode)"))))
 
 ;; Return 1 if the operand is a constant that can be used as the operand
 ;; of an OR or XOR.
@@ -847,7 +1106,6 @@ 
 		    && (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))")))
 
 ;; Return 1 if op is an operand that can be loaded via the GOT.
-;; or non-special register register field no cr0
 (define_predicate "got_operand"
   (match_code "symbol_ref,const,label_ref"))
 
@@ -1385,7 +1643,7 @@ 
       if (base_regno == 0)
 	return 0;
     }
-  else if (rs6000_legitimate_offset_address_p (SImode, src_addr, false, false))
+  else if (rs6000_legitimate_offset_address_p (SImode, src_addr, false, false, false))
     {
       offset = INTVAL (XEXP (src_addr, 1));
       base_regno = REGNO (XEXP (src_addr, 0));
@@ -1413,7 +1671,7 @@ 
 	  newoffset = 0;
 	  addr_reg = newaddr;
 	}
-      else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false))
+      else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false, false))
 	{
 	  addr_reg = XEXP (newaddr, 0);
 	  newoffset = INTVAL (XEXP (newaddr, 1));
@@ -1460,7 +1718,7 @@ 
       if (base_regno == 0)
 	return 0;
     }
-  else if (rs6000_legitimate_offset_address_p (SImode, dest_addr, false, false))
+  else if (rs6000_legitimate_offset_address_p (SImode, dest_addr, false, false, false))
     {
       offset = INTVAL (XEXP (dest_addr, 1));
       base_regno = REGNO (XEXP (dest_addr, 0));
@@ -1488,7 +1746,7 @@ 
 	  newoffset = 0;
 	  addr_reg = newaddr;
 	}
-      else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false))
+      else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false, false))
 	{
 	  addr_reg = XEXP (newaddr, 0);
 	  newoffset = INTVAL (XEXP (newaddr, 1));
Index: gcc/config/rs6000/vle.md
===================================================================
--- gcc/config/rs6000/vle.md	(revision 0)
+++ gcc/config/rs6000/vle.md	(revision 0)
@@ -0,0 +1,413 @@ 
+;; PowerPC VLE description
+;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012
+;; Free Software Foundation, Inc.
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_insn "*extendhisi2_vle"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,kregs,r")
+	(sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,0,r")))]
+  "TARGET_VLE"
+  "@
+   %e1lha%U1%X1 %0,%1
+   se_extsh %0
+   extsh %0,%1"
+  [(set_attr "type" "load_ext,exts,exts")
+   (set_attr "length" "4,2,4")])
+
+(define_insn "*addsi3_vle1"
+  [(set (match_operand: GPR 0 "gpc_reg_operand" "=kregs,kregs,r,r,r,r")
+	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "0,0,r,r,0,r")
+		  (match_operand:GPR 2 "vle_add_operand" "koim5,kregs,ksci8,I,L,r")))]
+  "TARGET_VLE"
+  "@
+   se_addi %0,%2
+   se_add %0,%2
+   e_addi %0,%1,%2
+   e_add16i %0,%1,%2
+   e_add2is %0,%v2
+   add %0,%1,%2"
+  [(set_attr "length" "2,2,4,4,4,4")])
+
+(define_insn "*subsi3_vle1"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=kregs,kregs,kregs,r,r")
+	(minus:SI (match_operand:SI 1 "vle_r_or_sci8_operand" "0,kregs,0,ksci8,r")
+		  (match_operand:SI 2 "vle_sub_operand2" "kregs,0,koim5,r,r")))]
+  "TARGET_VLE"
+  "@
+  se_sub %0, %2
+  se_subf %0, %1
+  se_subi %0, %2
+  e_subfic %0, %2, %1
+  subf %0, %2, %1"
+  [(set_attr "length" "2,2,2,4,4")])
+
+(define_insn ""
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
+	(minus:GPR (match_operand:GPR 1 "vle_r_or_sci8_operand" "r,ksci8")
+		   (match_operand:GPR 2 "gpc_reg_operand" "r,r")))]
+  "TARGET_VLE"
+  "@
+   subf %0,%2,%1
+   e_subfic %0,%2,%1")
+
+(define_insn "mulsi3_vle"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=kregs,r,r,r")
+	(mult:SI (match_operand:SI 1 "gpc_reg_operand" "%0,r,r,0")
+		 (match_operand:SI 2 "reg_or_short_operand" "kregs,r,ksci8,I")))]
+  "TARGET_VLE"
+  "@
+   se_mullw %0,%2
+   mullw %0,%1,%2
+   e_mulli %0,%1,%2
+   e_mull2i %0,%2"
+   [(set_attr "length" "2,4,4,4")
+    (set_attr "type" "imul")])
+
+;; Logical instructions
+
+(define_insn "*andsi3_vle"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=kregs,r,kregs,kregs,r,r,r,r")
+        (and:SI (match_operand:SI 1 "gpc_reg_operand" "%0,r,0,0,r,r,0,0")
+                (match_operand:SI 2 "vle_and_operand" "?kregs,?r,kuim5,kbic5,ksci8,T,K,L")))
+   (clobber (match_scratch:CC 3 "=X,X,X,X,X,X,x,x"))]
+  "TARGET_VLE"
+  "@
+   se_and %0,%2
+   and %0,%1,%2
+   se_andi %0,%2
+   se_bclri %0,%g2
+   e_andi %0,%1,%2
+   e_rlwinm %0,%1,0,%m2,%M2
+   e_and2i. %0,%b2
+   e_and2is. %0,%u2"
+  [(set_attr "length" "2,4,2,2,4,4,4,4")])
+
+(define_insn "*andsi3_vle2"
+  [(set (match_operand:CC 0 "cc_reg_cr0_operand" "=x,x,x,x,x")
+	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%kregs,r,r,r,r")
+			    (match_operand:SI 2 "vle_andcmp_operand" "?1,?r,K,L,ksci8"))
+		    (const_int 0)))
+   (clobber (match_scratch:SI 3 "=1,r,1,1,r"))
+   (clobber (match_scratch:CC 4 "=X,X,X,X,X"))]
+  "TARGET_VLE"
+  "@
+   se_and. %1,%2
+   and. %3,%1,%2
+   e_and2i. %1,%b2
+   e_and2is. %1,%u2
+   e_andi. %3,%1,%2"
+  [(set_attr "type" "compare,compare,fast_compare,fast_compare,fast_compare")
+   (set_attr "length" "2,4,4,4,4")])
+
+(define_insn "*andsi3_vle3"
+  [(set (match_operand:CC 3 "cc_reg_cr0_operand" "=x,x,x,x,x")
+	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r,r,0,0")
+			    (match_operand:SI 2 "vle_andcmp_operand" "?kregs,?r,ksci8,K,L"))
+		    (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=kregs,r,r,r,r")
+	(and:SI (match_dup 1)
+		(match_dup 2)))
+   (clobber (match_scratch:CC 4 "=X,X,X,X,X"))]
+  "TARGET_VLE"
+  "@
+   se_and. %0,%2
+   and. %0,%1,%2
+   e_andi. %0,%1,%2
+   e_and2i. %0,%b2
+   e_and2is. %0,%u2"
+  [(set_attr "type" "compare,compare,fast_compare,fast_compare,fast_compare")
+   (set_attr "length" "2,4,4,4,4")])
+
+(define_insn "*andcsi3_vle"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=kregs,r")
+	(and:SI (not:SI (match_operand:SI 1 "vle_andc_operand" "kregs,r"))
+	        (match_operand:SI 2 "gpc_reg_operand" "0,r")))]
+  "TARGET_VLE"
+  "@
+   se_andc %0,%1
+   andc %0,%2,%1"
+  [(set_attr "length" "2,4")])
+
+(define_insn "*xorsi3_vle"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+	(xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
+	        (match_operand:SI 2 "vle_r_or_sci8_operand" "ksci8,r")))]
+  "TARGET_VLE"
+  "@
+   e_xori %0,%1,%2
+   xor %0,%1,%2")
+
+(define_insn "*iorsi3_vle"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=kregs,kregs,r,r,r,r")
+	(ior:SI (match_operand:SI 1 "gpc_reg_operand" "%0,0,r,0,0,r")
+	        (match_operand:SI 2 "vle_or_operand" "kbit5,kregs,ksci8,K,L,r")))]
+  "TARGET_VLE"
+  "@
+   se_bseti %0,%o2
+   se_or %0,%2
+   e_ori %0,%1,%2
+   e_or2i %0,%2
+   e_or2is %0,%u2
+   or %0,%1,%2"
+  [(set_attr "length" "2,2,4,4,4,4")])
+
+(define_insn "*extzvsi_vle"
+  [(set (match_operand:CCUNS 0 "cc_reg_cr0_operand" "=x")
+	(compare:CCUNS
+	    (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "kregs")
+			     (match_operand:SI 2 "one_constant" "kone1")
+			     (match_operand:SI 3 "const_int_operand" "i"))
+	    (const_int 0)))]
+  "TARGET_VLE"
+  "se_btsti %1,%h3"
+  [(set_attr "type" "fast_compare")
+   (set_attr "length" "2")])
+
+;; Define the DImode operations that can be done in a small number
+;; of instructions.  The & constraints are to prevent the register
+;; allocator from allocating registers that overlap with the inputs
+;; (for example, having an input in 7,8 and an output in 6,7).  We
+;; also allow for the output being the same as one of the inputs.
+
+(define_insn "*adddi3_vle"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
+	(plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,0")
+		 (match_operand:DI 2 "reg_or_short_operand" "r,r")))]
+  "TARGET_VLE"
+  "addc %L0,%L1,%L2; adde %0,%1,%2"
+  [(set_attr "type" "two")
+   (set_attr "length" "8")])
+
+(define_insn "*movsi_vle"
+  [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=kregs,kareg,kregs,r,cl,kregs,?cl,?r,kregs,r,kmsd4,m,kregs,kregs,kregs,r,r,r,r")
+	(match_operand:SI 1 "input_operand" "kregs,kregs,kareg,r,kregs,cl,r,cl,kmsd4,m,kregs,r,kuim7,kbit5,kmsk5,kli20,L,K,n"))]
+  "TARGET_VLE
+   && (gpc_reg_operand (operands[0], SImode)
+       || gpc_reg_operand (operands[1], SImode))"
+  "@
+   se_mr %0,%1
+   se_mtar %0,%1
+   se_mfar %0,%1
+   mr %0,%1
+   se_mt%0 %1
+   se_mf%1 %0
+   mt%0 %1
+   mf%1 %0
+   se_lwz %0,%1
+   %e1lwz%U1%X1 %0,%1
+   se_stw %1,%0
+   %e0stw%U0%X0 %1,%0
+   se_li %0,%1
+   se_bgeni %0,%o1
+   se_bmaski %0,%r1
+   e_li %0,%1
+   e_lis %0,%v1
+   e_li %0,%u1
+   #"
+  [(set_attr "length" "2,2,2,4,2,2,4,4,2,4,2,4,2,2,2,4,4,4,8")])
+
+(define_insn "*movhi_vle"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=kregs,kareg,kregs,r,cl,kregs,?cl,?r,kregs,r,kmsd4,m,kregs,kregs,kregs,r")
+	(match_operand:HI 1 "input_operand" "kregs,kregs,kareg,r,kregs,cl,r,cl,kmsd4,m,kregs,r,kuim7,kbit5,kmsk5,i"))]
+  "TARGET_VLE
+   && (gpc_reg_operand (operands[0], HImode)
+       || gpc_reg_operand (operands[1], HImode))"
+  "@
+   se_mr %0,%1
+   se_mtar %0,%1
+   se_mfar %0,%1
+   mr %0,%1
+   se_mt%0 %1
+   se_mf%1 %0
+   mt%0 %1
+   mf%1 %0
+   se_lhz %0,%1
+   %e1lhz%U1%X1 %0,%1
+   se_sth %1,%0
+   %e0sth%U0%X0 %1,%0
+   se_li %0,%1
+   se_bgeni %0,%o1
+   se_bmaski %0,%r1
+   e_li %0,%1"
+  [(set_attr "length" "2,2,2,4,2,2,4,4,2,4,2,4,2,2,2,4")])
+
+(define_insn "*movqi_vle"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=kregs,kareg,kregs,r,cl,kregs,?cl,?r,kregs,r,kmsd4,m,kregs,kregs,kregs,r")
+	(match_operand:QI 1 "input_operand" "kregs,kregs,kareg,r,kregs,cl,r,cl,kmsd4,m,kregs,r,kuim7,kbit5,kmsk5,i"))]
+  "TARGET_VLE
+   && (gpc_reg_operand (operands[0], QImode)
+       || gpc_reg_operand (operands[1], QImode))"
+  "@
+   se_mr %0,%1
+   se_mtar %0,%1
+   se_mfar %0,%1
+   mr %0,%1
+   se_mt%0 %1
+   se_mf%1 %0
+   mt%0 %1
+   mf%1 %0
+   se_lbz %0,%1
+   %e1lbz%U1%X1 %0,%1
+   se_stb %1,%0
+   %e0stb%U0%X0 %1,%0
+   se_li %0,%1
+   se_bgeni %0,%o1
+   se_bmaski %0,%r1
+   e_li %0,%1"
+  [(set_attr "length" "2,2,2,4,2,2,4,4,2,4,2,4,2,2,2,4")])
+
+(define_insn "*movsi_vle2"
+  [(set (match_operand:CC 2 "cc_reg_cr0_operand" "=x")
+	(compare:CC (match_operand:P 1 "vle_reg_operand" "0")
+		    (const_int 0)))
+   (set (match_operand:P 0 "vle_reg_operand" "=kregs") (match_dup 1))]
+  "TARGET_VLE"
+  "se_cmpi %1,0"
+  [(set_attr "type" "cmp")
+   (set_attr "length" "2")])
+
+(define_insn "*movcc_vle"
+  [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,kregs,kareg,kregs,r,kregs,r,cl,cl,r,m")
+	(match_operand:CC 1 "general_operand" "y,r,r,O,x,y,kregs,kregs,kareg,I,cl,cl,kregs,r,m,r"))]
+  "TARGET_VLE
+   && (register_operand (operands[0], CCmode)
+       || register_operand (operands[1], CCmode))"
+  "@
+   e_mcrf %0,%1
+   mtcrf 128,%1
+   e_rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;e_rlwinm %1,%1,%f0,0xffffffff
+   e_crxor %0,%0,%0
+   mfcr %0%Q1
+   mfcr %0%Q1\;e_rlwinm %0,%0,%f1,0xf0000000
+   se_mr %0,%1
+   se_mtar %0, %1
+   se_mfar %0, %1
+   e_li %0,%1
+   se_mf%1 %0
+   mf%1 %0
+   se_mt%0 %1
+   mt%0 %1
+   %e1lwz%U1%X1 %0,%1
+   %e0stw%U0%U1 %1,%0"
+  [(set (attr "type")
+     (cond [(eq_attr "alternative" "0,3")
+		(const_string "cr_logical")
+	    (eq_attr "alternative" "1,2")
+		(const_string "mtcr")
+	    (eq_attr "alternative" "6,7,8,9,12")
+		(const_string "integer")
+	    (eq_attr "alternative" "10,11")
+		(const_string "mfjmpr")
+	    (eq_attr "alternative" "13")
+		(const_string "mtjmpr")
+	    (eq_attr "alternative" "14")
+		(const_string "load")
+	    (eq_attr "alternative" "15")
+		(const_string "store")
+	    (ne (symbol_ref "TARGET_MFCRF") (const_int 0))
+		(const_string "mfcrf")
+	   ]
+	(const_string "mfcr")))
+   (set_attr "length" "4,4,12,4,4,8,2,2,2,4,2,4,2,4,4,4")])
+
+(define_insn "*movsf_softfloat_vle"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=kregs,kareg,kregs,r,cl,cl,r,m,r,r,*cl,r,r")
+	(match_operand:SF 1 "input_operand" "kregs,kregs,kareg,r,kregs,r,m,r,kli20,L,0,G,Fn"))]
+  "(gpc_reg_operand (operands[0], SFmode)
+   || gpc_reg_operand (operands[1], SFmode))
+   && (TARGET_VLE && (TARGET_SOFT_FLOAT || !TARGET_FPRS))"
+  "@
+   se_mr %0,%1
+   se_mtar %0,%1
+   se_mfar %0,%1
+   mr %0,%1
+   se_mt%0 %1
+   mt%0 %1
+   %e1lwz%U1%X1 %0,%1
+   %e0stw%U0%X0 %1,%0
+   e_li %0,%1
+   e_lis %0,%1
+   se_nop
+   #
+   #"
+  [(set_attr "length" "2,2,2,2,4,4,4,4,4,4,2,4,8")])
+
+(define_insn "*cmpsi_logical_vle"
+  [(set (match_operand:CCUNS 0 "cc_reg_operand" "=x,x,x,kcreg,?y")
+	(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "kregs,kregs,r,r,r")
+		       (match_operand:SI 2 "vle_logical_cmpsi_operand" "kregs,koim5,K,ksci8,r")))]
+  "TARGET_VLE"
+  "@
+   se_cmpl %1,%2
+   se_cmpli %1,%2
+   e_cmpl16i %1,%b2
+   e_cmpli %0,%1,%2
+   cmpl %0,%1,%2"
+  [(set_attr "type" "cmp,cmp,cmp,cmp,cmp")
+   (set_attr "length" "2,2,4,4,4")])
+
+(define_insn "*cmpsi_arithmetic_vle"
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,kcreg,?y")
+	(compare:CC (match_operand:SI 1 "gpc_reg_operand" "kregs,kregs,r,r,r")
+		    (match_operand:SI 2 "vle_arith_cmpsi_operand" "kregs,kuim5,I,ksci8,r")))]
+  "TARGET_VLE"
+  "@
+   se_cmp %1,%2
+   se_cmpi %1,%2
+   e_cmp16i %1,%2
+   e_cmpi %0,%1,%2
+   cmp %0,%1,%2"
+  [(set_attr "type" "cmp,cmp,cmp,cmp,cmp")
+   (set_attr "length" "2,2,4,4,4")])
+
+(define_insn "*cmphi_logical_vle"
+  [(set (match_operand:CCUNS 0 "cc_reg_operand" "=x,x,?y")
+	(compare:CCUNS (match_operand:HI 1 "gpc_reg_operand" "kregs,r,r")
+		       (match_operand:HI 2 "vle_logical_cmphi_operand" "kregs,K,r")))]
+  "TARGET_VLE"
+  "@
+   se_cmphl %1,%2
+   e_cmphl16i %1,%b2
+   e_cmphl %0,%1,%2"
+  [(set_attr "type" "cmp,cmp,cmp")
+   (set_attr "length" "2,4,4")])
+
+(define_insn "*cmphi_arithmetic_vle"
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y")
+	(compare:CC (match_operand:HI 1 "gpc_reg_operand" "kregs,r,r")
+		    (match_operand:HI 2 "vle_arith_cmphi_operand" "kregs,I,r")))]
+  "TARGET_VLE"
+  "@
+   se_cmph %1,%2
+   e_cmph16i %1,%2
+   e_cmph %0,%1,%2"
+  [(set_attr "type" "cmp,cmp,cmp")
+   (set_attr "length" "2,4,4")])
+
+(define_insn "*plus_eqsi_vle"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r")
+	(plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
+			(match_operand:SI 2 "scc_eq_operand" "r,O,ksci8"))
+		 (match_operand:SI 3 "gpc_reg_operand" "r,r,r")))]
+  "TARGET_VLE"
+  "@
+   xor %0,%1,%2\;e_subfic %0,%0,0\;addze %0,%3
+   e_subfic %0,%1,0\;addze %0,%3
+   e_xori %0,%1,%2\;e_subfic %0,%0,0\;addze %0,%3"
+  [(set_attr "type" "three,two,three")
+   (set_attr "length" "12,8,12")])
Index: gcc/config/rs6000/ppc-asm.h
===================================================================
--- gcc/config/rs6000/ppc-asm.h	(revision 191665)
+++ gcc/config/rs6000/ppc-asm.h	(working copy)
@@ -238,6 +238,32 @@ 
 #define vs63	63
 #endif
 
+#ifdef __VLE__
+#define ADD16I	e_add16i
+#define B	e_b
+#define BDZ	e_bdz
+#define BLR	se_blr
+#define LWZ	e_lwz
+#define MFAR	se_mfar
+#define MTAR	se_mtar
+#define MFLR	se_mflr
+#define MTLR	se_mtlr
+#define STW	e_stw
+#define STWU	e_stwu
+#else
+#define ADD16I	addi
+#define B	b
+#define BDZ	bdz
+#define BLR	blr
+#define LWZ	lwz
+#define MFAR	mr
+#define MTAR	mr
+#define MFLR	mflr
+#define MTLR	mtlr
+#define STW	stw
+#define STWU	stwu
+#endif
+
 /*
  * Macros to glue together two tokens.
  */
Index: gcc/config/rs6000/sync.md
===================================================================
--- gcc/config/rs6000/sync.md	(revision 191665)
+++ gcc/config/rs6000/sync.md	(working copy)
@@ -95,7 +95,7 @@ 
 (define_insn "isync"
   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_ISYNC)]
   ""
-  "isync"
+  "%+isync"
   [(set_attr "type" "isync")])
 
 ;; The control dependency used for load dependency described
Index: gcc/config/rs6000/spe.md
===================================================================
--- gcc/config/rs6000/spe.md	(revision 191665)
+++ gcc/config/rs6000/spe.md	(working copy)
@@ -2289,9 +2289,9 @@ 
 	known to be dead.  */
       if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
 			     operands[1], 0))
-	return \"lwz %L0,%L1\;lwz %0,%1\";
+	return \"%^lwz %L0,%L1\;%^lwz %0,%1\";
       else
-        return \"lwz%U1%X1 %0,%1\;lwz %L0,%L1\";
+	return \"%e1lwz%U1%X1 %0,%1\;%^lwz %L0,%L1\";
     }
 }"
   [(set_attr "length" "8,8")])
@@ -2315,9 +2315,9 @@ 
 	return \"evldd%X1 %Z0,%y1\;evmergehi %Y0,%Z0,%Z0\";
       if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
 			     operands[1], 0))
-	return \"lwz %Z0,%L1\;lwz %Y0,%1\";
+	return \"%^lwz %Z0,%L1\;%^lwz %Y0,%1\";
       else
-        return \"lwz%U1%X1 %Y0,%1\;lwz %Z0,%L1\";
+	return \"%e1lwz%U1%X1 %Y0,%1\;%^lwz %Z0,%L1\";
     }
 }"
   [(set_attr "length" "8,8")])
@@ -2336,7 +2336,7 @@ 
    || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
   "@
    evmergelo %0,%1,%0
-   evmergelohi %0,%0,%0\;lwz%U1%X1 %0,%1\;evmergelohi %0,%0,%0"
+   evmergelohi %0,%0,%0\;%e1lwz%U1%X1 %0,%1\;evmergelohi %0,%0,%0"
   [(set_attr "length" "4,12")])
 
 (define_insn_and_split "*mov_si<mode>_e500_subreg0_elf_low"
@@ -2366,7 +2366,7 @@ 
    || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
   "@
    evmergehi %0,%0,%1
-   evmergelohi %1,%1,%1\;stw%U0%X0 %1,%0"
+   evmergelohi %1,%1,%1\;%e0stw%U0%X0 %1,%0"
   [(set_attr "length" "4,8")])
 
 (define_insn "*mov_si<mode>_e500_subreg4"
@@ -2376,7 +2376,7 @@ 
    || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
   "@
    mr %0,%1
-   lwz%U1%X1 %0,%1")
+   %e1lwz%U1%X1 %0,%1")
 
 (define_insn "*mov_si<mode>_e500_subreg4_elf_low"
   [(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r") 4)
@@ -2394,7 +2394,7 @@ 
    || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
   "@
    mr %0,%1
-   stw%U0%X0 %1,%0")
+   %e0stw%U0%X0 %1,%0")
 
 (define_insn "*mov_sitf_e500_subreg8"
   [(set (subreg:SI (match_operand:TF 0 "register_operand" "+r,&r") 8)
@@ -2402,7 +2402,7 @@ 
   "TARGET_E500_DOUBLE"
   "@
    evmergelo %L0,%1,%L0
-   evmergelohi %L0,%L0,%L0\;lwz%U1%X1 %L0,%1\;evmergelohi %L0,%L0,%L0"
+   evmergelohi %L0,%L0,%L0\;%e0lwz%U1%X1 %L0,%1\;evmergelohi %L0,%L0,%L0"
   [(set_attr "length" "4,12")])
 
 (define_insn "*mov_sitf_e500_subreg8_2"
@@ -2411,7 +2411,7 @@ 
   "TARGET_E500_DOUBLE"
   "@
    evmergehi %0,%0,%L1
-   evmergelohi %L1,%L1,%L1\;stw%U0%X0 %L1,%0"
+   evmergelohi %L1,%L1,%L1\;%e0stw%U0%X0 %L1,%0"
   [(set_attr "length" "4,8")])
 
 (define_insn "*mov_sitf_e500_subreg12"
@@ -2420,7 +2420,7 @@ 
   "TARGET_E500_DOUBLE"
   "@
    mr %L0,%1
-   lwz%U1%X1 %L0,%1")
+   %e1lwz%U1%X1 %L0,%1")
 
 (define_insn "*mov_sitf_e500_subreg12_2"
   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
@@ -2428,7 +2428,7 @@ 
   "TARGET_E500_DOUBLE"
   "@
    mr %0,%L1
-   stw%U0%X0 %L1,%0")
+   %e0stw%U0%X0 %L1,%0")
 
 ;; FIXME: Allow r=CONST0.
 (define_insn "*movdf_e500_double"
@@ -2573,7 +2573,7 @@ 
    (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))]
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128"
-  "mfspefscr %3\;rlwinm %4,%3,0,0,29\;ori %4,%4,1\;efdadd %2,%1,%L1\;mtspefscr %3\;efdctsiz %0, %2"
+  "mfspefscr %3\;%^rlwinm %4,%3,0,0,29\;%^ori %4,%4,1\;efdadd %2,%1,%L1\;mtspefscr %3\;efdctsiz %0, %2"
   [(set_attr "length" "24")])
 
 (define_insn "spe_negtf2_internal"
@@ -3098,7 +3098,7 @@ 
 ;; Same thing, but for IBM long double.
 
 (define_insn "cmptfeq_gpr"
-  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+  [(set (match_operand:CCFP 0 "cmpi_cc_reg_operand" "=kcrxx")
 	(unspec:CCFP
 	 [(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r")
 			(match_operand:TF 2 "gpc_reg_operand" "r"))]
@@ -3106,12 +3106,12 @@ 
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
    && !(flag_finite_math_only && !flag_trapping_math)"
-  "efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmpeq %0,%L1,%L2"
+  "efdcmpeq %0,%1,%2\;%^bng %0,$+8\;efdcmpeq %0,%L1,%L2"
   [(set_attr "type" "veccmp")
    (set_attr "length" "12")])
 
 (define_insn "tsttfeq_gpr"
-  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+  [(set (match_operand:CCFP 0 "cmpi_cc_reg_operand" "=kcrxx")
 	(unspec:CCFP
 	 [(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r")
 			(match_operand:TF 2 "gpc_reg_operand" "r"))]
@@ -3119,12 +3119,12 @@ 
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
    && flag_finite_math_only && !flag_trapping_math"
-  "efdtsteq %0,%1,%2\;bng %0,$+8\;efdtsteq %0,%L1,%L2"
+  "efdtsteq %0,%1,%2\;%^bng %0,$+8\;efdtsteq %0,%L1,%L2"
   [(set_attr "type" "veccmpsimple")
    (set_attr "length" "12")])
 
 (define_insn "cmptfgt_gpr"
-  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+  [(set (match_operand:CCFP 0 "cmpi_cc_reg_operand" "=kcrxx")
 	(unspec:CCFP
 	 [(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r")
 			(match_operand:TF 2 "gpc_reg_operand" "r"))]
@@ -3132,12 +3132,12 @@ 
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
    && !(flag_finite_math_only && !flag_trapping_math)"
-  "efdcmpgt %0,%1,%2\;bgt %0,$+16\;efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmpgt %0,%L1,%L2"
+  "efdcmpgt %0,%1,%2\;%^bgt %0,$+16\;efdcmpeq %0,%1,%2\;%^bng %0,$+8\;efdcmpgt %0,%L1,%L2"
   [(set_attr "type" "veccmp")
    (set_attr "length" "20")])
 
 (define_insn "tsttfgt_gpr"
-  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+  [(set (match_operand:CCFP 0 "cmpi_cc_reg_operand" "=kcrxx")
 	(unspec:CCFP
 	 [(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r")
 			(match_operand:TF 2 "gpc_reg_operand" "r"))]
@@ -3145,12 +3145,12 @@ 
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
    && flag_finite_math_only && !flag_trapping_math"
-  "efdtstgt %0,%1,%2\;bgt %0,$+16\;efdtsteq %0,%1,%2\;bng %0,$+8\;efdtstgt %0,%L1,%L2"
+  "efdtstgt %0,%1,%2\;%^bgt %0,$+16\;efdtsteq %0,%1,%2\;%^bng %0,$+8\;efdtstgt %0,%L1,%L2"
   [(set_attr "type" "veccmpsimple")
    (set_attr "length" "20")])
 
 (define_insn "cmptflt_gpr"
-  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+  [(set (match_operand:CCFP 0 "cmpi_cc_reg_operand" "=kcrxx")
 	(unspec:CCFP
 	 [(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r")
 			(match_operand:TF 2 "gpc_reg_operand" "r"))]
@@ -3158,12 +3158,12 @@ 
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
    && !(flag_finite_math_only && !flag_trapping_math)"
-  "efdcmplt %0,%1,%2\;bgt %0,$+16\;efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmplt %0,%L1,%L2"
+  "efdcmplt %0,%1,%2\;%^bgt %0,$+16\;efdcmpeq %0,%1,%2\;%^bng %0,$+8\;efdcmplt %0,%L1,%L2"
   [(set_attr "type" "veccmp")
    (set_attr "length" "20")])
 
 (define_insn "tsttflt_gpr"
-  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+  [(set (match_operand:CCFP 0 "cmpi_cc_reg_operand" "=kcrxx")
 	(unspec:CCFP
 	 [(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r")
 			(match_operand:TF 2 "gpc_reg_operand" "r"))]
@@ -3171,7 +3171,7 @@ 
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
    && flag_finite_math_only && !flag_trapping_math"
-  "efdtstlt %0,%1,%2\;bgt %0,$+16\;efdtsteq %0,%1,%2\;bng %0,$+8\;efdtstlt %0,%L1,%L2"
+  "efdtstlt %0,%1,%2\;%^bgt %0,$+16\;efdtsteq %0,%1,%2\;%^bng %0,$+8\;efdtstlt %0,%L1,%L2"
   [(set_attr "type" "veccmpsimple")
    (set_attr "length" "20")])
 
@@ -3182,7 +3182,7 @@ 
 		      (match_operand 2 "cc_reg_operand" "y")]
 		     E500_CR_IOR_COMPARE))]
   "TARGET_HARD_FLOAT && !TARGET_FPRS"
-  "cror 4*%0+gt,4*%1+gt,4*%2+gt"
+  "%^cror 4*%0+gt,4*%1+gt,4*%2+gt"
   [(set_attr "type" "cr_logical")])
 
 ;; Out-of-line prologues and epilogues.
@@ -3194,7 +3194,7 @@ 
 		    (set (match_operand:V2SI 2 "memory_operand" "=m")
 			 (match_operand:V2SI 3 "gpc_reg_operand" "r"))])]
   "TARGET_SPE_ABI"
-  "bl %z1"
+  "%^bl %z1"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
 
@@ -3206,7 +3206,7 @@ 
 		   (set (match_operand:V2SI 2 "gpc_reg_operand" "=r")
 			(match_operand:V2SI 3 "memory_operand" "m"))])]
  "TARGET_SPE_ABI"
- "bl %z1"
+ "%^bl %z1"
  [(set_attr "type" "branch")
   (set_attr "length" "4")])
 
@@ -3219,6 +3219,6 @@ 
 		   (set (match_operand:V2SI 2 "gpc_reg_operand" "=r")
 			(match_operand:V2SI 3 "memory_operand" "m"))])]
  "TARGET_SPE_ABI"
- "b %z1"
+ "%^b %z1"
  [(set_attr "type" "branch")
   (set_attr "length" "4")])
Index: gcc/config/rs6000/driver-rs6000.c
===================================================================
--- gcc/config/rs6000/driver-rs6000.c	(revision 191665)
+++ gcc/config/rs6000/driver-rs6000.c	(working copy)
@@ -413,6 +413,12 @@ 
   { "G5",	"-mpower4 -maltivec" },
   { "8540",	"-me500" },
   { "8548",	"-me500" },
+  { "e200z0",	"-mvle" },
+  { "e200z1",	"-mvle" },
+  { "e200z2",	"-mvle" },
+  { "e200z3",	"-mvle" },
+  { "e200z6",	"-mvle" },
+  { "e200z7",	"-mvle" },
   { "e300c2",	"-me300" },
   { "e300c3",	"-me300" },
   { "e500mc",	"-me500mc" },
Index: gcc/config/rs6000/constraints.md
===================================================================
--- gcc/config/rs6000/constraints.md	(revision 191665)
+++ gcc/config/rs6000/constraints.md	(working copy)
@@ -116,6 +116,102 @@ 
   (and (match_code "const_int")
        (match_test "(unsigned HOST_WIDE_INT) ((- ival) + 0x8000) < 0x10000")))
 
+;; VLE constraints
+
+(define_register_constraint "kareg" "VLE_ALT_REGS"
+  "@internal")
+
+(define_register_constraint "kcreg" "VLE_CR_REGS"
+  "@internal")
+
+(define_register_constraint "kcrxx"
+  "rs6000_constraints[RS6000_CONSTRAINT_kcrxx]"
+  "@internal")
+
+(define_constraint "kli20"
+  "A signed 20-bit immediate"
+  (and (match_code "const_int")
+       (match_test "ival >= -524288 && ival <= 524287")))
+
+(define_constraint "kmsd4"
+  "An SD4(Rx) form memory operand"
+  (match_operand 0 "vle_sd4_operand"))
+
+(define_constraint "kmmd8"
+  "An 8-bit signed immediate"
+  (and (match_code "const_int")
+       (match_test " ival >= -128 && ival < 128")))
+
+(define_constraint "koim5"
+  "A constant in the range 1-32"
+  (and (match_code "const_int")
+       (match_test "ival >= 1 && ival <= 32")))
+
+(define_constraint "kone1"
+  "The constant 1"
+  (match_test "op == const1_rtx || op == CONST1_RTX (GET_MODE (op))"))
+
+(define_register_constraint "kregs" "VLE_REGS"
+  "@internal")
+
+(define_constraint "ksci8"
+  "An eight bit immediate constant shifted left by 0, 1, 2 or 3 bytes"
+  (and (match_code "const_int")
+       (match_test "valid_sci8_immediate (ival)")))
+
+(define_constraint "kscp8"
+  "A constant whose negation is an eight bit immediate shifted left by 0, 1, 2 or 3 bytes"
+  (and (match_code "const_int")
+       (match_test "valid_sci8_immediate (-ival)")))
+
+(define_constraint "kscI8"
+  "An immediate constant that matches the ksci8 or I constraint if making VLE or non-VLE code respectively"
+  (and (match_code "const_int")
+       (if_then_else (match_test "TARGET_VLE")
+		     (match_test "satisfies_constraint_ksci8 (op)")
+		     (match_test "satisfies_constraint_I (op)"))))
+
+(define_constraint "kscP8"
+  "An immediate constant that matches the kscp8 or P constraint if making VLE or non-VLE code respectively"
+  (and (match_code "const_int")
+       (if_then_else (match_test "TARGET_VLE")
+		     (match_test "satisfies_constraint_kscp8 (op)")
+		     (match_test "satisfies_constraint_P (op)"))))
+
+(define_constraint "kuim5"
+  "A constant in the range 0-31"
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 31")))
+
+(define_constraint "kbit5"
+  "A 32-bit constant that has exactly one bit set"
+  (and (match_code "const_int")
+       (ior (match_test "(ival & -ival & 0xffffffff) == ival")
+	    (match_test "TARGET_32BIT && ival + 0x80000000 == 0"))))
+
+(define_constraint "kbic5"
+  "A 32-bit constant that has exactly one bit clear"
+  (and (match_code "const_int")
+       (ior (match_test "(~ival & -~ival & 0xffffffff) == ~ival")
+	    (match_test "TARGET_32BIT && ival == 0x7fffffff"))))
+
+(define_constraint "kmsk5"
+  "A 32-bit constant that is a contiguous mask of 1-32 low-order bits set"
+  (and (match_code "const_int")
+       (ior (and (match_test "((ival | 0xffffffff) ^ 0xffffffff) == 0")
+		 (match_test "((ival + 1) & -(ival + 1)) == ival + 1"))
+	    (match_test "TARGET_32BIT && ival + 1 == 0"))))
+
+(define_constraint "kuim7"
+  "A constant in the range 0-127"
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 127")))
+
+(define_constraint "kui16"
+  "An unsigned 16-bit constant."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 65535")))
+
 ;; Floating-point constraints
 
 (define_constraint "G"
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 191665)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -142,6 +142,9 @@ 
 
 /* Support targetm.vectorize.builtin_mask_for_load.  */
 static GTY(()) tree altivec_builtin_mask_for_load;
+ 
+/* Nonzero if generating VLE code.  */
+int vle_code = 0;
 
 /* Set to nonzero once AIX common-mode calls have been defined.  */
 static GTY(()) int common_mode_defined;
@@ -1461,7 +1464,8 @@ 
 /* Simplifications for entries below.  */
 
 enum {
-  POWERPC_7400_MASK = MASK_PPC_GFXOPT | MASK_ALTIVEC
+  POWERPC_7400_MASK = MASK_PPC_GFXOPT | MASK_ALTIVEC,
+  POWERPC_E200_MASK = MASK_ISEL | MASK_MULTIPLE
 };
 
 /* Some OSs don't support saving the high part of 64-bit registers on context
@@ -1762,20 +1766,22 @@ 
 
   fprintf (stderr,
 	   "\n"
-	   "d  reg_class = %s\n"
-	   "f  reg_class = %s\n"
-	   "v  reg_class = %s\n"
-	   "wa reg_class = %s\n"
-	   "wd reg_class = %s\n"
-	   "wf reg_class = %s\n"
-	   "ws reg_class = %s\n\n",
+	   "d     reg_class = %s\n"
+	   "f     reg_class = %s\n"
+	   "v     reg_class = %s\n"
+	   "wa    reg_class = %s\n"
+	   "wd    reg_class = %s\n"
+	   "wf    reg_class = %s\n"
+	   "ws    reg_class = %s\n"
+	   "kcrxx reg_class = %s\n\n",
 	   reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
 	   reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
 	   reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
 	   reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
 	   reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
 	   reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
-	   reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
+	   reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]],
+	   reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_kcrxx]]);
 
   for (m = 0; m < NUM_MACHINE_MODES; ++m)
     if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
@@ -1962,6 +1968,11 @@ 
   rs6000_regno_regclass[0] = GENERAL_REGS;
   for (r = 1; r < 32; ++r)
     rs6000_regno_regclass[r] = BASE_REGS;
+  if (TARGET_VLE)
+    {
+      for (r = 8; r < 24; ++r)
+        rs6000_regno_regclass[r] = VLE_ALT_REGS;
+    }
 
   for (r = 32; r < 64; ++r)
     rs6000_regno_regclass[r] = FLOAT_REGS;
@@ -1975,6 +1986,11 @@ 
   rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
   for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
     rs6000_regno_regclass[r] = CR_REGS;
+  if (TARGET_VLE)
+    {
+      for (r = CR1_REGNO; r <= CR3_REGNO; ++r)
+	rs6000_regno_regclass[r] = VLE_CR_REGS;
+    }
 
   rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
   rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
@@ -2149,6 +2165,11 @@ 
 	}
     }
 
+  if (TARGET_VLE)
+    rs6000_constraints[RS6000_CONSTRAINT_kcrxx] = VLE_CR_REGS;
+  else
+    rs6000_constraints[RS6000_CONSTRAINT_kcrxx] = CR_REGS;
+
   /* Precalculate HARD_REGNO_NREGS.  */
   for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
     for (m = 0; m < NUM_MACHINE_MODES; ++m)
@@ -2488,7 +2509,10 @@ 
   {
     int spe_capable_cpu =
       (rs6000_cpu == PROCESSOR_PPC8540
-       || rs6000_cpu == PROCESSOR_PPC8548);
+       || rs6000_cpu == PROCESSOR_PPC8548
+       || rs6000_cpu == PROCESSOR_PPCE200Z3
+       || rs6000_cpu == PROCESSOR_PPCE200Z6
+       || rs6000_cpu == PROCESSOR_PPCE200Z7);
 
     if (!global_options_set.x_rs6000_spe_abi)
       rs6000_spe_abi = spe_capable_cpu;
@@ -2497,10 +2521,23 @@ 
       rs6000_spe = spe_capable_cpu;
 
     if (!global_options_set.x_rs6000_float_gprs)
-      rs6000_float_gprs =
-        (rs6000_cpu == PROCESSOR_PPC8540 ? 1
-         : rs6000_cpu == PROCESSOR_PPC8548 ? 2
-         : 0);
+      {
+        switch (rs6000_cpu)
+	  {
+	  case PROCESSOR_PPC8540:
+	  case PROCESSOR_PPCE200Z3:
+	  case PROCESSOR_PPCE200Z6:
+	  case PROCESSOR_PPCE200Z7:
+            rs6000_float_gprs = 1;
+	    break;
+	  case PROCESSOR_PPC8548:
+            rs6000_float_gprs = 2;
+	    break;
+	  default:
+            rs6000_float_gprs = 0;
+	  }
+      }
+
   }
 
   if (global_options_set.x_rs6000_spe_abi
@@ -2623,6 +2660,20 @@ 
   else if (TARGET_ALTIVEC)
     target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
 
+  if (global_options_set.x_rs6000_vle
+      && rs6000_vle
+      && !TARGET_VLE)
+    error ("not configured for VLE instruction set");
+
+  /* VLE special processing.  */
+  if (TARGET_VLE)
+    {
+      if (!BYTES_BIG_ENDIAN)
+	error ("-mvle cannot be used with -mlittle-endian");
+
+      vle_code = 1;
+    }
+
   /* E500mc does "better" if we inline more aggressively.  Respect the
      user's opinion, though.  */
   if (rs6000_block_move_inline_limit == 0
@@ -2766,6 +2817,7 @@ 
      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. 
+     Also, all E200 cores do not have string insns.
 
      For other families, clear ISEL in case it was set implicitly.
   */
@@ -2778,6 +2830,12 @@ 
     case PROCESSOR_PPCE500MC64:
     case PROCESSOR_PPCE5500:
     case PROCESSOR_PPCE6500:
+    case PROCESSOR_PPCE200Z0:
+    case PROCESSOR_PPCE200Z1:
+    case PROCESSOR_PPCE200Z2:
+    case PROCESSOR_PPCE200Z3:
+    case PROCESSOR_PPCE200Z6:
+    case PROCESSOR_PPCE200Z7:
 
       rs6000_single_float = TARGET_E500_SINGLE || TARGET_E500_DOUBLE;
       rs6000_double_float = TARGET_E500_DOUBLE;
@@ -3026,6 +3084,15 @@ 
 	rs6000_cost = &ppc8540_cost;
 	break;
 
+      case PROCESSOR_PPCE200Z0:
+      case PROCESSOR_PPCE200Z1:
+      case PROCESSOR_PPCE200Z2:
+      case PROCESSOR_PPCE200Z3:
+      case PROCESSOR_PPCE200Z6:
+      case PROCESSOR_PPCE200Z7:
+	/* Placeholder for now.  */
+	rs6000_cost = &ppce500mc_cost;
+
       case PROCESSOR_PPCE300C2:
       case PROCESSOR_PPCE300C3:
 	rs6000_cost = &ppce300c2c3_cost;
@@ -4401,9 +4468,9 @@ 
   operands[1] = CONST_VECTOR_ELT (vec, 0);
   operands[2] = CONST_VECTOR_ELT (vec, 1);
   if (cst == cst2)
-    return "li %0,%1\n\tevmergelo %0,%0,%0";
+    return "%^li %0,%1\n\tevmergelo %0,%0,%0";
   else
-    return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
+    return "%^li %0,%1\n\tevmergelo %0,%0,%0\n\t%^li %0,%2";
 }
 
 /* Initialize TARGET of vector PAIRED to VALS.  */
@@ -5325,7 +5392,8 @@ 
 
 bool
 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x,
-				    bool strict, bool worst_case)
+				    bool strict, bool worst_case,
+				    bool vle_update)
 {
   unsigned HOST_WIDE_INT offset;
   unsigned int extra;
@@ -5398,8 +5466,17 @@ 
       break;
     }
 
-  offset += 0x8000;
-  return offset < 0x10000 - extra;
+  /* The offset of an e_stwu instruction is 8 bits signed.  */
+  if (vle_update)
+    {
+      offset += 0x80;
+      return offset < 0x100 - extra;
+    }
+  else
+    {
+      offset += 0x8000;
+      return offset < 0x10000 - extra;
+    }
 }
 
 bool
@@ -6403,7 +6480,7 @@ 
 	  || XEXP (x, 0) == arg_pointer_rtx)
       && GET_CODE (XEXP (x, 1)) == CONST_INT)
     return 1;
-  if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict, false))
+  if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict, false, false))
     return 1;
   if (mode != TImode
       && mode != TFmode
@@ -6432,7 +6509,7 @@ 
       && TARGET_UPDATE
       && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
       && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1),
-					      reg_ok_strict, false)
+					      reg_ok_strict, false, TARGET_VLE)
 	  || (!avoiding_indexed_address_p (mode)
 	      && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
       && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
@@ -6589,7 +6666,7 @@ 
   worst_case = ((TARGET_POWERPC64 && GET_MODE_CLASS (reg_mode) == MODE_INT)
 		|| GET_MODE_SIZE (reg_mode) == 4);
   return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0),
-					     true, worst_case);
+					     true, worst_case, false);
 }
 
 /* Change register usage conditional on target flags.  */
@@ -6694,7 +6771,7 @@ 
 
   switch (mode)
     {
-      case  QImode:
+    case QImode:
     case HImode:
       if (dest == NULL)
 	dest = gen_reg_rtx (mode);
@@ -13097,7 +13174,7 @@ 
   rtx xop[10];
 
   if (XVECLEN (operands[0], 0) == 1)
-    return "lwz %2,0(%1)";
+    return "%^lwz %2,0(%1)";
 
   for (i = 0; i < words; i++)
     if (refers_to_regno_p (REGNO (operands[2]) + i,
@@ -13108,7 +13185,7 @@ 
 	    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);
+	    output_asm_insn ("lswi %2,%1,%0\n\t%^lwz %1,%0(%1)", xop);
 	    return "";
 	  }
 	else if (i == 0)
@@ -13116,7 +13193,7 @@ 
 	    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);
+	    output_asm_insn ("%^addi %1,%1,4\n\tlswi %2,%1,%0\n\t%^lwz %1,-4(%1)", xop);
 	    return "";
 	  }
 	else
@@ -13127,11 +13204,11 @@ 
 		  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);
+		  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);
+	    output_asm_insn ("%^lwz %1,%0(%1)", xop);
 	    return "";
 	  }
       }
@@ -13618,7 +13695,7 @@ 
 	    {
 	      if (!legitimate_indirect_address_p (addr, false)
 		  && !rs6000_legitimate_offset_address_p (TImode, addr,
-							  false, true))
+							  false, true, false))
 		{
 		  sri->icode = icode;
 		  /* account for splitting the loads, and converting the
@@ -13826,7 +13903,7 @@ 
       if (GET_CODE (addr) == PLUS
 	  && (and_op2 != NULL_RTX
 	      || !rs6000_legitimate_offset_address_p (TImode, addr,
-						      false, true)))
+						      false, true, false)))
 	{
 	  addr_op1 = XEXP (addr, 0);
 	  addr_op2 = XEXP (addr, 1);
@@ -13859,7 +13936,7 @@ 
 	}
       else if (!legitimate_indirect_address_p (addr, false)
 	       && !rs6000_legitimate_offset_address_p (TImode, addr,
-						       false, true))
+						       false, true, false))
 	{
 	  if (TARGET_DEBUG_ADDR)
 	    {
@@ -13918,7 +13995,7 @@ 
 	      && GET_MODE_SIZE (mode) == 8
 	      && and_op2 == NULL_RTX
 	      && scratch_or_premodify == scratch
-	      && rs6000_legitimate_offset_address_p (mode, addr, false, false)))
+	      && rs6000_legitimate_offset_address_p (mode, addr, false, false, false)))
 	;
 
       else if (GET_CODE (addr) == PLUS)
@@ -14179,6 +14256,13 @@ 
       return rclass;
     }
 
+  /* For VLE, we have cheaper insns for moving to LR and CTR.  */
+  if (TARGET_VLE
+      && REG_P (x)
+      && (REGNO (x) == LR_REGNO || REGNO (x) == CTR_REGNO)
+      && reg_classes_intersect_p (rclass, VLE_ALT_REGS))
+    return VLE_REGS;
+
   return rclass;
 }
 
@@ -14313,9 +14397,15 @@ 
   else
     regno = -1;
 
+  if (TARGET_VLE
+      && CR_REGNO4_THRU_7_P (regno)
+      && rclass == CR_REGS)
+    return VLE_CR_REGS;
+	
   /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
      into anything.  */
   if (rclass == GENERAL_REGS || rclass == BASE_REGS
+      || (TARGET_VLE && rclass == VLE_REGS)
       || (regno >= 0 && INT_REGNO_P (regno)))
     return NO_REGS;
 
@@ -14670,10 +14760,29 @@ 
 print_operand (FILE *file, rtx x, int code)
 {
   int i;
+  HOST_WIDE_INT val;
   unsigned HOST_WIDE_INT uval;
 
   switch (code)
     {
+    case '^':
+      /* Print the "e_" prefix for VLE instructions.  */
+      if (TARGET_VLE)
+        fprintf (file, "%s", "e_");
+      return;
+
+    case '+':
+      /* Print the "se_" prefix for VLE instructions.  */
+      if (TARGET_VLE)
+        fprintf (file, "%s", "se_");
+      return;
+
+    case '-':
+      /* Print a '-' suffix on branch insns if not VLE.  */
+      if (!TARGET_VLE)
+	fprintf (file, "-");
+      return;
+
       /* %a is output_address.  */
 
     case 'A':
@@ -14716,6 +14825,18 @@ 
       fprintf (file, "%d", i + 1);
       return;
 
+    case 'e':
+      /* Like 'X' but used to print the "e_" prefix for non-indexed
+	 VLE instructions.  */
+      if (TARGET_VLE
+	  && ! (GET_CODE (x) == MEM
+		&& (legitimate_indexed_address_p (XEXP (x, 0), 0)
+		    || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
+			&& legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1),
+							 0)))))
+	fprintf (file, "e_");
+      return;
+
     case 'E':
       /* X is a CR register.  Print the number of the EQ bit of the CR */
       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
@@ -14742,6 +14863,23 @@ 
 	fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
       return;
 
+    case 'g':
+      /* X is a CONST_INT that is a 32-bit complement of a power of two.
+	 Output the number of most significant one bits.  */
+      val = 0;
+      if (INT_P (x))
+	{
+	  val = INT_LOWPART (x);
+	  if (TARGET_32BIT && val == 0x7fffffff)
+	    val = ~val ^ 0xffffffff;
+	  val = ~val;
+	}
+      if (!INT_P (x) || val < 0 || (i = exact_log2 (val)) < 0 || i > 31)
+	output_operand_lossage ("invalid %%g value");
+      else
+	fprintf (file, "%d", 31 - i);
+      return;
+
     case 'G':
       /* X is a constant integer.  If it is negative, print "m",
 	 otherwise print "z".  This is to make an aze or ame insn.  */
@@ -14771,6 +14909,12 @@ 
 	print_operand (file, x, 0);
       return;
 
+    case 'i':
+      /* If constant, print the "e_" prefix for VLE instructions.  */
+      if (TARGET_VLE && INT_P (x))
+        fprintf (file, "%s", "e_");
+      return;
+
     case 'I':
       /* Print `i' if this is a constant, else nothing.  */
       if (INT_P (x))
@@ -14877,6 +15021,22 @@ 
 	fprintf (file, "%d", XVECLEN (x, 0) * 4);
       return;
 
+    case 'o':
+      /* X is a CONST_INT that is a 32-bit power of two.  Output the number
+	 of most significant zero bits.  */
+      val = 0;
+      if (INT_P (x))
+	{
+	  val = INT_LOWPART (x);
+	  if (TARGET_32BIT && val + 0x80000000 == 0)
+	    val &= 0xffffffff;
+	}
+      if (!INT_P (x) || val < 0 || (i = exact_log2 (val)) < 0 || i > 31)
+	output_operand_lossage ("invalid %%o value");
+      else
+	fprintf (file, "%d", 31 - i);
+      return;
+
     case 'O':
       /* Similar, but subtract 1 first.  */
       if (GET_CODE (x) != PARALLEL)
@@ -14944,11 +15104,10 @@ 
       return;
 
     case 'Q':
-      if (TARGET_MFCRF)
-	fputc (',', file);
-        /* FALLTHRU */
-      else
+      if (! TARGET_MFCRF)
 	return;
+      fputc (',', file);
+      /* FALLTHRU */
 
     case 'R':
       /* X is a CR register.  Print the mask for `mtcrf'.  */
@@ -14958,6 +15117,25 @@ 
 	fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
       return;
 
+    case 'r':
+      /* X is a CONST_INT that is a contiguous mask of 1-32 low-order bits
+	 set.  Print the number of bits set, or 0 for 32.  */
+      val = 0;
+      if (INT_P (x))
+	{
+	  val = INT_LOWPART (x);
+	  if (TARGET_32BIT && val + 1 == 0)
+	    val &= 0xffffffff;
+	}
+      if (!INT_P (x)
+	  || ((val | 0xffffffff) ^ 0xffffffff) != 0
+	  || (i = exact_log2 (val + 1)) < 0)
+	output_operand_lossage ("invalid %%r value");
+      else
+	fprintf (file, "%d", i & 0x1f);
+      fflush (file);
+      return;
+
     case 's':
       /* Low 5 bits of 32 - value */
       if (! INT_P (x))
@@ -15893,7 +16071,7 @@ 
 }
 
 /* Return the string to output a conditional branch to LABEL, which is
-   the operand number of the label, or -1 if the branch is really a
+   the operand template of the label, or NULL if the branch is really a
    conditional return.
 
    OP is the conditional expression.  XEXP (OP, 0) is assumed to be a
@@ -15913,6 +16091,7 @@ 
   enum machine_mode mode = GET_MODE (cc_reg);
   int cc_regno = REGNO (cc_reg) - CR0_REGNO;
   int need_longbranch = label != NULL && get_attr_length (insn) == 8;
+  int short_rbranch = TARGET_VLE && need_longbranch && cc_regno == 0;
   int really_reversed = reversed ^ need_longbranch;
   char *s = string;
   const char *ccode;
@@ -16004,23 +16183,41 @@ 
 	}
     }
 
-  if (label == NULL)
-    s += sprintf (s, "b%slr%s ", ccode, pred);
+  if (TARGET_VLE)
+    {
+      gcc_assert (label != NULL);
+      s += sprintf (s, "%sb%s", short_rbranch ? "se_" : "e_", ccode);
+    }
   else
-    s += sprintf (s, "b%s%s ", ccode, pred);
+    {
+      if (label == NULL)
+	s += sprintf (s, "b%slr%s", ccode, pred);
+      else
+	s += sprintf (s, "b%s%s", ccode, pred);
+    }
 
   /* We need to escape any '%' characters in the reg_names string.
      Assume they'd only be the first character....  */
-  if (reg_names[cc_regno + CR0_REGNO][0] == '%')
-    *s++ = '%';
-  s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
+  if (!short_rbranch)
+    {
+      *s++ = ' ';
+      if (reg_names[cc_regno + CR0_REGNO][0] == '%')
+	*s++ = '%';
+      s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
+    }
 
   if (label != NULL)
     {
       /* If the branch distance was too far, we may have to use an
 	 unconditional branch to go the distance.  */
       if (need_longbranch)
-	s += sprintf (s, ",$+8\n\tb %s", label);
+	{
+	  if (short_rbranch)
+	    s += sprintf (s, " $+6");
+	  else
+	    s += sprintf (s, ",$+8");
+	  s += sprintf (s, "\n\t%sb %s", TARGET_VLE ? "e_" : "", label);
+	}
       else
 	s += sprintf (s, ",%s", label);
     }
@@ -16042,7 +16239,7 @@ 
   a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
   b = 4 * (REGNO (src) - CR0_REGNO) + 1;
 
-  sprintf (string, "crnot %d,%d", a, b);
+  sprintf (string, "%%^crnot %d,%d", a, b);
   return string;
 }
 
@@ -17160,11 +17357,9 @@ 
 	      if (TARGET_UPDATE)
 		{
 		  rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
-		  emit_insn (TARGET_32BIT
-			     ? (TARGET_POWERPC64
-				? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
-				: gen_movsi_update (breg, breg, delta_rtx, nsrc))
-			     : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
+		  emit_insn (!TARGET_32BIT || TARGET_POWERPC64
+			     ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
+			     : gen_movsi_update (breg, breg, delta_rtx, nsrc));
 		  used_update = true;
 		}
 	      else
@@ -17465,7 +17660,8 @@ 
       && !TARGET_POWERPC64
       && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
       && info->first_gp_reg_save < 31
-      && !global_regs_p (info->first_gp_reg_save, 32))
+      && !global_regs_p (info->first_gp_reg_save, 32)
+      && (!TARGET_VLE || info->total_size < 128))
     strategy |= SAVRES_MULTIPLE;
 
   if (crtl->calls_eh_return
@@ -18697,7 +18893,7 @@ 
 	emit_move_insn (copy_reg, stack_reg);
     }
 
-  if (size > 32767)
+  if ((TARGET_VLE && size > 128) || size > 32768)
     {
       /* Need a note here so that try_split doesn't get confused.  */
       if (get_last_insn () == NULL_RTX)
@@ -18709,9 +18905,9 @@ 
   
   insn = emit_insn (TARGET_32BIT
 		    ? gen_movsi_update_stack (stack_reg, stack_reg,
-					todec, stack_reg)
+					      todec, stack_reg)
 		    : gen_movdi_di_update_stack (stack_reg, stack_reg,
-					   todec, stack_reg));
+						 todec, stack_reg));
   /* Since we didn't use gen_frame_mem to generate the MEM, grab
      it now and set the alias set/attributes. The above gen_*_update
      calls will generate a PARALLEL with the MEM set being the first
@@ -24386,7 +24582,12 @@ 
 
     case ABI_DARWIN:
     case ABI_V4:
-      ret = (TARGET_32BIT) ? 40 : 48;
+      if (TARGET_VLE)
+	ret = VLE_TRAMPOLINE_SIZE;
+      else if (TARGET_32BIT)
+	ret = TARGET_32BIT_TRAMPOLINE_SIZE;
+      else
+	ret = TARGET_64BIT_TRAMPOLINE_SIZE;
       break;
     }
 
@@ -25743,52 +25944,98 @@ 
     {
       /* On the RS/6000, if it is valid in the insn, it is free.  */
     case CONST_INT:
-      if (((outer_code == SET
-	    || outer_code == PLUS
-	    || outer_code == MINUS)
-	   && (satisfies_constraint_I (x)
-	       || satisfies_constraint_L (x)))
-	  || (outer_code == AND
-	      && (satisfies_constraint_K (x)
-		  || (mode == SImode
-		      ? satisfies_constraint_L (x)
-		      : satisfies_constraint_J (x))
-		  || mask_operand (x, mode)
-		  || (mode == DImode
-		      && mask64_operand (x, DImode))))
-	  || ((outer_code == IOR || outer_code == XOR)
-	      && (satisfies_constraint_K (x)
-		  || (mode == SImode
-		      ? satisfies_constraint_L (x)
-		      : satisfies_constraint_J (x))))
-	  || outer_code == ASHIFT
-	  || outer_code == ASHIFTRT
-	  || outer_code == LSHIFTRT
-	  || outer_code == ROTATE
-	  || outer_code == ROTATERT
-	  || outer_code == ZERO_EXTRACT
-	  || (outer_code == MULT
-	      && satisfies_constraint_I (x))
-	  || ((outer_code == DIV || outer_code == UDIV
-	       || outer_code == MOD || outer_code == UMOD)
-	      && exact_log2 (INTVAL (x)) >= 0)
-	  || (outer_code == COMPARE
-	      && (satisfies_constraint_I (x)
-		  || satisfies_constraint_K (x)))
-	  || ((outer_code == EQ || outer_code == NE)
-	      && (satisfies_constraint_I (x)
-		  || satisfies_constraint_K (x)
-		  || (mode == SImode
-		      ? satisfies_constraint_L (x)
-		      : satisfies_constraint_J (x))))
-	  || (outer_code == GTU
-	      && satisfies_constraint_I (x))
-	  || (outer_code == LTU
-	      && satisfies_constraint_P (x)))
+      if (TARGET_VLE
+	  && ((outer_code == SET
+	       && (satisfies_constraint_kuim7 (x)
+		   || satisfies_constraint_kbit5 (x)
+		   || satisfies_constraint_kmsk5 (x)))
+	      || ((outer_code == PLUS || outer_code == MINUS)
+		  && satisfies_constraint_koim5 (x))
+	      || (outer_code == AND
+		  && (satisfies_constraint_kuim5 (x)
+		     || satisfies_constraint_kbic5 (x)))
+	      || (outer_code == IOR
+		  && satisfies_constraint_kbit5 (x))
+	      || outer_code == ASHIFT
+	      || outer_code == ASHIFTRT
+	      || outer_code == LSHIFTRT
+	      || ((outer_code == DIV || outer_code == UDIV)
+		  && exact_log2 (INTVAL (x)) >= 0)
+	      || ((outer_code == MOD || outer_code == UMOD)
+		  && exact_log2 (INTVAL (x)) >= 0
+		  && satisfies_constraint_kuim5 (GEN_INT (INTVAL (x) - 1)))
+	      || (outer_code == COMPARE
+		  && (satisfies_constraint_koim5 (x)
+		      || satisfies_constraint_kuim5 (x)))))
 	{
 	  *total = 0;
 	  return true;
 	}
+      else if ((outer_code == SET
+		&& ((!TARGET_VLE && satisfies_constraint_I (x))
+		    || (TARGET_VLE
+			&& (satisfies_constraint_kli20 (x)
+			    || satisfies_constraint_K (x)))
+		    || satisfies_constraint_L (x)))
+	       || ((outer_code == PLUS
+		    || outer_code == MINUS)
+		   && ((TARGET_VLE && satisfies_constraint_ksci8 (x))
+		       || satisfies_constraint_I (x)
+		       || satisfies_constraint_L (x)))
+	       || (outer_code == AND
+		   && ((TARGET_VLE && satisfies_constraint_ksci8 (x))
+		       || satisfies_constraint_K (x)
+		       || (mode == SImode
+			   ? satisfies_constraint_L (x)
+			   : satisfies_constraint_J (x))
+		       || mask_operand (x, mode)
+		       || (mode == DImode
+			   && mask64_operand (x, DImode))))
+	       || (outer_code == IOR
+		   && ((TARGET_VLE && satisfies_constraint_ksci8 (x))
+		       || satisfies_constraint_K (x)
+		       || (mode == SImode
+			   ? satisfies_constraint_L (x)
+			   : satisfies_constraint_J (x))))
+	       || (outer_code == XOR
+		   && (TARGET_VLE
+		       ? satisfies_constraint_ksci8 (x)
+		       : (satisfies_constraint_K (x)
+			  || (mode == SImode
+			      ? satisfies_constraint_L (x)
+			      : satisfies_constraint_J (x)))))
+	       || outer_code == ASHIFT
+	       || outer_code == ASHIFTRT
+	       || outer_code == LSHIFTRT
+	       || outer_code == ROTATE
+	       || outer_code == ROTATERT
+	       || outer_code == ZERO_EXTRACT
+	       || (outer_code == MULT
+		   && ((TARGET_VLE && satisfies_constraint_ksci8 (x))
+		       || satisfies_constraint_I (x)))
+	       || ((outer_code == DIV || outer_code == UDIV
+		    || outer_code == MOD || outer_code == UMOD)
+		   && exact_log2 (INTVAL (x)) >= 0)
+	       || (outer_code == COMPARE
+		   && ((TARGET_VLE && satisfies_constraint_ksci8 (x))
+		       || satisfies_constraint_I (x)
+		       || satisfies_constraint_K (x)))
+	       || ((outer_code == EQ || outer_code == NE)
+		   && (TARGET_VLE
+		       ? satisfies_constraint_ksci8 (x)
+		       : (satisfies_constraint_I (x)
+			  || satisfies_constraint_K (x)
+			  || (mode == SImode
+			      ? satisfies_constraint_L (x)
+			      : satisfies_constraint_J (x)))))
+	       || (outer_code == GTU
+		   && satisfies_constraint_kscI8 (x))
+	       || (outer_code == LTU
+		   && satisfies_constraint_kscP8 (x)))
+	{
+	  *total = TARGET_VLE ? COSTS_N_INSNS (1) / 2 : 0;
+	  return true;
+	}
       else if ((outer_code == PLUS
 		&& reg_or_add_cint_operand (x, VOIDmode))
 	       || (outer_code == MINUS
@@ -25796,8 +26043,11 @@ 
 	       || ((outer_code == SET
 		    || outer_code == IOR
 		    || outer_code == XOR)
-		   && (INTVAL (x)
-		       & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
+		   && ((INTVAL (x) & ~(unsigned HOST_WIDE_INT) 0xffffffff) == 0
+		       || (TARGET_32BIT
+			   && ((INTVAL (x)
+				& ~(unsigned HOST_WIDE_INT) 0x7fffffff)
+			       == ~(unsigned HOST_WIDE_INT) 0x7fffffff)))))
 	{
 	  *total = COSTS_N_INSNS (1);
 	  return true;
@@ -26132,7 +26382,12 @@ 
     {
       reg_class_t rclass = from;
 
-      if (! reg_classes_intersect_p (to, GENERAL_REGS))
+      if (TARGET_VLE)
+        {
+          if (from != VLE_ALT_REGS && ! reg_classes_intersect_p (to, GENERAL_REGS))
+           from = to;
+        }
+      else if (! reg_classes_intersect_p (to, GENERAL_REGS))
 	rclass = to;
 
       if (rclass == FLOAT_REGS || rclass == ALTIVEC_REGS || rclass == VSX_REGS)
@@ -26151,6 +26406,21 @@ 
 	       && reg_classes_intersect_p (rclass, LINK_OR_CTR_REGS))
         ret = 6 * hard_regno_nregs[0][mode];
 
+      else if (TARGET_VLE
+	       && (from == VLE_ALT_REGS
+		   && (to == VLE_ALT_REGS
+		       || to == LINK_REGS
+		       || to == CTR_REGS
+                       || to == LINK_OR_CTR_REGS)))
+	ret = 8;
+
+      else if (TARGET_VLE
+	       && (to == VLE_ALT_REGS
+		   && (from == LINK_REGS
+		       || from == CTR_REGS
+                       || from == LINK_OR_CTR_REGS)))
+	ret = 8;
+
       else
 	/* A move will cost one instruction per GPR moved.  */
 	ret = 2 * hard_regno_nregs[0][mode];
@@ -28026,7 +28296,8 @@ 
   if (!legitimate_indirect_address_p (addr, strict_p))
     {
       if (offsettable_p
-	  && !rs6000_legitimate_offset_address_p (mode, addr, strict_p, true))
+	  && !rs6000_legitimate_offset_address_p (mode, addr, strict_p, true,
+	                                          TARGET_VLE))
 	stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
 
       else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
@@ -28331,4 +28602,88 @@ 
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+bool
+valid_vle_sd4_field (rtx mem, enum machine_mode mode)
+{
+  int high = 0;
+  /* Address inside MEM.  */
+  rtx op = XEXP (mem, 0);
+  rtx base, addend;
+
+  if (mode == QImode)
+    high = 0xf;
+  else if (mode == HImode)
+    high = 0x1e;
+  else if (mode == SImode)
+    high = 0x3c;
+
+  if (REG_P (op))
+    {
+      base = op;
+      addend = const0_rtx;
+    }
+  else if (GET_CODE (op) == PLUS)
+    {
+      base = XEXP (op, 0);
+      addend = XEXP (op, 1);
+    }
+  else
+    return false;
+
+  if (!REG_P (base)
+      || (REGNO (base) > 7 && REGNO (base) <= 23)
+      || (REGNO (base) > 31 && REGNO (base) <= LAST_VIRTUAL_REGISTER))
+    return false;
+
+  if (GET_CODE (addend) != CONST_INT)
+    return false;
+
+  if (INTVAL (addend) % GET_MODE_SIZE (mode) != 0)
+    return false;
+
+  if (INTVAL (addend) < 0
+      || INTVAL (addend) > high)
+    return false;
+
+  return true;
+}
+
+/* Check if IVAL can be SCI8-encoded.  According to VLEPEM immediates
+   such encoded are 32-bit words, hence we allow zero-extended 32-bit
+   values universally and then sign-extended 32-bit values on 32-bit
+   targets only as they will truncate the operation performed to 32
+   bits anyway.  */
+
+bool
+valid_sci8_immediate (HOST_WIDE_INT ival)
+{
+  if ((ival & ~(unsigned HOST_WIDE_INT) 0xffffffff) == 0
+      || (TARGET_32BIT
+	  && ((ival & ~(unsigned HOST_WIDE_INT) 0x7fffffff)
+	      == ~(unsigned HOST_WIDE_INT) 0x7fffffff)))
+    {
+      unsigned int ival32 = ival & 0xffffffff;
+
+      if ((ival32 & 0x000000ff) == ival32)
+	return true;
+      if ((ival32 & 0x0000ff00) == ival32)
+	return true;
+      if ((ival32 & 0x00ff0000) == ival32)
+	return true;
+      if ((ival32 & 0xff000000) == ival32)
+	return true;
+
+      if ((ival32 | 0xffffff00) == ival32)
+	return true;
+      if ((ival32 | 0xffff00ff) == ival32)
+	return true;
+      if ((ival32 | 0xff00ffff) == ival32)
+	return true;
+      if ((ival32 | 0x00ffffff) == ival32)
+	return true;
+    }
+
+  return false;
+}
+
 #include "gt-rs6000.h"
Index: gcc/config/rs6000/sysv4.h
===================================================================
--- gcc/config/rs6000/sysv4.h	(revision 191665)
+++ gcc/config/rs6000/sysv4.h	(working copy)
@@ -573,8 +573,11 @@ 
 %{msdata: -msdata=default} \
 %{mno-sdata: -msdata=none} \
 %{!mbss-plt: %{!msecure-plt: %(cc1_secure_plt_default)}} \
-%{profile: -p}"
+%{profile: -p}" \
+CC1_EXTRA_SPEC
 
+#define CC1_EXTRA_SPEC
+
 /* Default starting address if specified.  */
 #define LINK_START_SPEC "\
 %{mads         : %(link_start_ads)         ; \
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 191665)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -149,6 +149,12 @@ 
 %{mcpu=G5: -mpower4 -maltivec} \
 %{mcpu=8540: -me500} \
 %{mcpu=8548: -me500} \
+%{mcpu=e200z0: -mvle} \
+%{mcpu=e200z1: -mvle} \
+%{mcpu=e200z2: -mvle} \
+%{mcpu=e200z3: -mvle} \
+%{mcpu=e200z6: -mvle} \
+%{mcpu=e200z7: -mvle} \
 %{mcpu=e300c2: -me300} \
 %{mcpu=e300c3: -me300} \
 %{mcpu=e500mc: -me500mc} \
@@ -156,6 +162,7 @@ 
 %{mcpu=e5500: -me5500} \
 %{mcpu=e6500: -me6500} \
 %{maltivec: -maltivec} \
+%{mvle: -mvle} \
 %{mvsx: -mvsx %{!maltivec: -maltivec} %{!mcpu*: %(asm_cpu_power7)}} \
 -many"
 
@@ -481,11 +488,13 @@ 
 				      || TARGET_ALTIVEC			 \
 				      || TARGET_VSX)))
 
-/* E500 cores only support plain "sync", not lwsync.  */
+#define TARGET_VLE 0
+
+/* E500 & VLE cores only support plain "sync", not lwsync.  */
 #define TARGET_NO_LWSYNC (rs6000_cpu == PROCESSOR_PPC8540 \
-			  || rs6000_cpu == PROCESSOR_PPC8548)
+			  || rs6000_cpu == PROCESSOR_PPC8548 \
+			  || TARGET_VLE)
 
-
 /* Which machine supports the various reciprocal estimate instructions.  */
 #define TARGET_FRES	(TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT \
 			 && TARGET_FPRS && TARGET_SINGLE_FLOAT)
@@ -678,7 +687,7 @@ 
     ? 64 : 128)
 
 /* Allocation boundary (in *bits*) for the code of a function.  */
-#define FUNCTION_BOUNDARY 32
+#define FUNCTION_BOUNDARY (TARGET_VLE ? 16 : 32)
 
 /* No data type wants to be aligned rounder than this.  */
 #define BIGGEST_ALIGNMENT 128
@@ -955,9 +964,24 @@ 
 /* True if register is a condition register.  */
 #define CR_REGNO_P(N) ((N) >= CR0_REGNO && (N) <= CR7_REGNO)
 
+/* True if register is condition register cr0.  */
+#define CR0_REGNO_P(N) ((N) == CR0_REGNO)
+
 /* True if register is a condition register, but not cr0.  */
 #define CR_REGNO_NOT_CR0_P(N) ((N) >= CR1_REGNO && (N) <= CR7_REGNO)
 
+/* True if register is a condition register between 4 and 7.  */
+#define CR_REGNO4_THRU_7_P(N) ((N) >= CR4_REGNO && (N) <= CR7_REGNO)
+
+/* True if register is a valid VLE condition register.  */
+#define VLE_CR_REGNO_P(N) ((N) >= CR0_REGNO && (N) <= CR3_REGNO)
+
+/* True if register is a valid VLE condition register, but not cr0.  */
+#define VLE_CR_REGNO_NOT_CR0_P(N) ((N) >= CR1_REGNO && (N) <= CR3_REGNO)
+
+/* True if register is a valid VLE alternate register.  */
+#define VLE_ALT_REGNO_P(N) ((N) >= 8 && (N) <= 23)
+
 /* True if register is an integer register.  */
 #define INT_REGNO_P(N) \
   ((N) <= 31 || (N) == ARG_POINTER_REGNUM || (N) == FRAME_POINTER_REGNUM)
@@ -1167,6 +1191,9 @@ 
   CR_REGS,
   NON_FLOAT_REGS,
   CA_REGS,
+  VLE_REGS,
+  VLE_ALT_REGS,
+  VLE_CR_REGS,
   ALL_REGS,
   LIM_REG_CLASSES
 };
@@ -1197,6 +1224,9 @@ 
   "CR_REGS",								\
   "NON_FLOAT_REGS",							\
   "CA_REGS",								\
+  "VLE_REGS",								\
+  "VLE_ALT_REGS",							\
+  "VLE_CR_REGS",							\
   "ALL_REGS"								\
 }
 
@@ -1226,6 +1256,9 @@ 
   { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */	     \
   { 0xffffffff, 0x00000000, 0x00000ffe, 0x00020000 }, /* NON_FLOAT_REGS */   \
   { 0x00000000, 0x00000000, 0x00001000, 0x00000000 }, /* CA_REGS */	     \
+  { 0xff0000ff, 0x00000000, 0x00000000, 0x00000000 }, /* VLE_REGS */	     \
+  { 0x00ffff00, 0x00000000, 0x00000000, 0x00000000 }, /* VLE_ALT_REGS */     \
+  { 0x00000000, 0x00000000, 0x000000f0, 0x00000000 }, /* VLE_CR_REGS */	     \
   { 0xffffffff, 0xffffffff, 0xfffffffe, 0x0003ffff }  /* ALL_REGS */	     \
 }
 
@@ -1255,6 +1288,7 @@ 
   RS6000_CONSTRAINT_wd,		/* VSX register for V2DF */
   RS6000_CONSTRAINT_wf,		/* VSX register for V4SF */
   RS6000_CONSTRAINT_ws,		/* VSX register for DF */
+  RS6000_CONSTRAINT_kcrxx,	/* CRs for cmpi/cmpli/bc instructions */
   RS6000_CONSTRAINT_MAX
 };
 
@@ -1591,6 +1625,10 @@ 
        && (REGNO) == 2))
 
 
+#define VLE_TRAMPOLINE_SIZE		32
+#define TARGET_32BIT_TRAMPOLINE_SIZE	40
+#define TARGET_64BIT_TRAMPOLINE_SIZE	48
+
 /* Length in units of the trampoline for entering a nested function.  */
 
 #define TRAMPOLINE_SIZE rs6000_trampoline_size ()
@@ -1862,10 +1900,11 @@ 
    comparison.  CCmode should be used in all other cases.  */
 
 #define SELECT_CC_MODE(OP,X,Y) \
-  (SCALAR_FLOAT_MODE_P (GET_MODE (X)) ? CCFPmode	\
-   : (OP) == GTU || (OP) == LTU || (OP) == GEU || (OP) == LEU ? CCUNSmode \
-   : (((OP) == EQ || (OP) == NE) && COMPARISON_P (X)			  \
-      ? CCEQmode : CCmode))
+  (SCALAR_FLOAT_MODE_P (GET_MODE (X)) ? CCFPmode			\
+   : (((OP) == GTU || (OP) == LTU || (OP) == GEU || (OP) == LEU		\
+       || (TARGET_VLE && GET_CODE (X) == ZERO_EXTRACT)) ? CCUNSmode	\
+      : (((OP) == EQ || (OP) == NE) && COMPARISON_P (X)			\
+	 ? CCEQmode : CCmode)))
 
 /* Can the condition code MODE be safely reversed?  This is safe in
    all cases on this port, because at present it doesn't use the
@@ -2230,7 +2269,12 @@ 
 /* Define which CODE values are valid.  */
 
 #define PRINT_OPERAND_PUNCT_VALID_P(CODE)  \
-  ((CODE) == '.' || (CODE) == '&')
+  ((CODE) == '.'     \
+    || (CODE) == '&' \
+    || (CODE) == '^' \
+    || (CODE) == '+' \
+    || (CODE) == '-' \
+    || (CODE) == '?')
 
 /* Print a memory address as an operand to reference that memory location.  */
 
@@ -2243,6 +2287,9 @@ 
 
 /* General flags.  */
 extern int frame_pointer_needed;
+ 
+/* Nonzero if generating VLE code.  */
+extern int vle_code;
 
 /* Classification of the builtin functions as to which switches enable the
    builtin, and what attributes it should have.  We used to use the target
Index: gcc/config/rs6000/t-eabivle
===================================================================
--- gcc/config/rs6000/t-eabivle	(revision 0)
+++ gcc/config/rs6000/t-eabivle	(revision 0)
@@ -0,0 +1,12 @@ 
+# Multilibs for powerpc-vle embedded ELF targets.
+
+MULTILIB_OPTIONS	= msoft-float/mcpu=e200z0/mcpu=e200z3
+
+MULTILIB_DIRNAMES	= nof e200z0 e200z3
+
+MULTILIB_EXTRA_OPTS	= mno-eabi mstrict-align
+
+MULTILIB_MATCHES	= ${MULTILIB_MATCHES_FLOAT} \
+			  ${MULTILIB_MATCHES_ENDIAN} \
+			  mcpu?e200z0=mcpu?e200z1 mcpu?e200z0=mcpu?e200z2 \
+			  mpcu?e200z3=mpcu?e200z6 mpcu?e200z3=mpcu?e200z7
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 191665)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -148,6 +148,8 @@ 
 ;; Define floating point instruction sub-types for use with Xfpu.md
 (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
 
+(define_attr "is_vle" "no,yes" (const (symbol_ref "vle_code")))
+
 ;; Length (in bytes).
 ; '(pc)' in the following doesn't include the instruction itself; it is
 ; calculated as if the instruction had zero size.
@@ -156,15 +158,24 @@ 
 		(if_then_else (and (ge (minus (match_dup 0) (pc))
 				       (const_int -32768))
 				   (lt (minus (match_dup 0) (pc))
-				       (const_int 32764)))
+				       (const_int 32766)))
 			      (const_int 4)
 			      (const_int 8))
 		(const_int 4)))
 
+;; Used to control the "enabled" attribute on a per-instruction basis.
+(define_attr "isa" "common,novle,vle"
+  (const_string "common"))
+
+(define_attr "enabled" ""
+  (cond [(eq_attr "isa" "vle") (symbol_ref "TARGET_VLE")
+         (eq_attr "isa" "novle") (symbol_ref "!TARGET_VLE")]
+        (const_int 1)))
+
 ;; Processor type -- this attribute must exactly match the processor_type
 ;; enumeration in rs6000.h.
 
-(define_attr "cpu" "rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,power4,power5,power6,power7,cell,ppca2,titan"
+(define_attr "cpu" "rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppc8548,ppce200z0,ppce200z1,ppce200z2,ppce200z3,ppce200z6,ppce200z7,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,power4,power5,power6,power7,cell,ppca2,titan"
   (const (symbol_ref "rs6000_cpu_attr")))
 
 
@@ -266,7 +277,7 @@ 
 ; Conditional returns.
 (define_code_iterator any_return [return simple_return])
 (define_code_attr return_pred [(return "direct_return ()")
-			       (simple_return "")])
+			       (simple_return "1")])
 (define_code_attr return_str [(return "") (simple_return "simple_")])
 
 ; Various instructions that come in SI and DI forms.
@@ -308,6 +319,8 @@ 
 
 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
 				(DF "TARGET_DOUBLE_FLOAT")])
+
+(include "vle.md")
 
 ;; Start with fixed-point load and store insns.  Here we put only the more
 ;; complex forms.  Basic data transfer is done later.
@@ -593,28 +606,32 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=kregs,r,kregs,r")
+	(zero_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "kmsd4,m,0,r")))]
   ""
   "@
-   lbz%U1%X1 %0,%1
-   rlwinm %0,%1,0,0xff"
-  [(set_attr "type" "load,*")])
+   se_lbz %0,%1
+   %e1lbz%U1%X1 %0,%1
+   se_extzb %0
+   %^rlwinm %0,%1,0,0xff"
+  [(set_attr "type" "load,load,*,*")
+   (set_attr "length" "2,4,2,4")
+   (set_attr "isa" "vle,*,vle,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 "=r,r"))]
   ""
   "@
-   andi. %2,%1,0xff
+   %^andi. %2,%1,0xff
    #"
   [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 ""))]
@@ -627,20 +644,20 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(zero_extend:SI (match_dup 1)))]
   ""
   "@
-   andi. %0,%1,0xff
+   %^andi. %0,%1,0xff
    #"
   [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
@@ -654,14 +671,18 @@ 
   "")
 
 (define_insn "extendqisi2"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=kregs,r")
+	(sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "0,r")))]
   ""
-  "extsb %0,%1"
-  [(set_attr "type" "exts")])
+  "@
+   se_extsb %0
+   extsb %0,%1"
+  [(set_attr "type" "exts")
+   (set_attr "length" "2,4")
+   (set_attr "isa" "vle,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 "=r,r"))]
@@ -673,7 +694,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 ""))]
@@ -686,7 +707,7 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
@@ -699,7 +720,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
@@ -712,29 +733,39 @@ 
 		    (const_int 0)))]
   "")
 
+(define_expand "zero_extendqihi2"
+  [(set (match_operand:HI 0 "gpc_reg_operand" "")
+	(zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")))]
+  ""
+  "")
+
 (define_insn ""
-  [(set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
+  [(set (match_operand:HI 0 "gpc_reg_operand" "=kregs,r,kregs,r")
+	(zero_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "kmsd4,m,0,r")))]
   ""
   "@
-   lbz%U1%X1 %0,%1
-   rlwinm %0,%1,0,0xff"
-  [(set_attr "type" "load,*")])
+   se_lbz %0,%1
+   %e1lbz%U1%X1 %0,%1
+   se_extzb %0
+   %^rlwinm %0,%1,0,0xff"
+  [(set_attr "type" "load,load,*,*")
+   (set_attr "length" "2,4,2,4")
+   (set_attr "isa" "vle,*,vle,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (clobber (match_scratch:HI 2 "=r,r"))]
   ""
   "@
-   andi. %2,%1,0xff
+   %^andi. %2,%1,0xff
    #"
   [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:HI 2 ""))]
@@ -747,20 +778,20 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
 	(zero_extend:HI (match_dup 1)))]
   ""
   "@
-   andi. %0,%1,0xff
+   %^andi. %0,%1,0xff
    #"
   [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:HI 0 "gpc_reg_operand" "")
@@ -781,7 +812,7 @@ 
   [(set_attr "type" "exts")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (clobber (match_scratch:HI 2 "=r,r"))]
@@ -793,7 +824,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:HI 2 ""))]
@@ -806,7 +837,7 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
@@ -819,7 +850,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:HI 0 "gpc_reg_operand" "")
@@ -839,28 +870,34 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=kregs,r,kregs,r")
+	(zero_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "kmsd4,m,0,r")))]
   ""
   "@
-   lhz%U1%X1 %0,%1
-   rlwinm %0,%1,0,0xffff"
-  [(set_attr "type" "load,*")])
+   se_lhz %0,%1
+   %e1lhz%U1%X1 %0,%1
+   se_extzh %0
+   %^rlwinm %0,%1,0,0xffff"
+  [(set_attr "type" "load,load,*,*")
+   (set_attr "length" "2,4,2,4")
+   (set_attr "isa" "vle,*,vle,*")])
 
-(define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
+(define_insn "*cmphi_logical_powerpc"
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,x,?kcrxx")
+	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r,r"))
 		    (const_int 0)))
-   (clobber (match_scratch:SI 2 "=r,r"))]
+   (clobber (match_scratch:SI 2 "=X,r,r"))]
   ""
   "@
+   e_cmphl16i %1,0
    andi. %2,%1,0xffff
    #"
-  [(set_attr "type" "fast_compare,compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "fast_compare,fast_compare,compare")
+   (set_attr "length" "4,4,8")
+   (set_attr "isa" "vle,novle,*")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 ""))]
@@ -873,20 +910,25 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
+  [(set (match_operand:CC 2 "cmpi_cc_reg_operand" "=x,x,?kcrxx")
+	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "0,r,r"))
 		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
 	(zero_extend:SI (match_dup 1)))]
   ""
   "@
+   e_and2i. %0,0xffff
    andi. %0,%1,0xffff
    #"
-  [(set_attr "type" "fast_compare,compare")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "fast_compare,fast_compare,compare")
+   (set_attr "length" "4,4,8")
+   (set_attr "isa" "vle,novle,*")])
 
+;; Need to include cr0 here in the VLE mode to handle the limitation
+;; of e_and2i. capable of operating on the same source and destination
+;; register only.
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_vle_or_not_micro_cr0_operand" "")
 	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
@@ -922,7 +964,7 @@ 
   [(set_attr "type" "exts")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 "=r,r"))]
@@ -934,7 +976,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 ""))]
@@ -947,7 +989,7 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
@@ -960,7 +1002,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
@@ -1518,7 +1560,11 @@ 
 	FAIL;
     }
   else if (GET_CODE (operands[2]) == CONST_INT
-	   && ! add_operand (operands[2], <MODE>mode))
+	   && (TARGET_VLE
+	       ? !(vle_add3_operand (operands[2], <MODE>mode)
+		   || (vle_add_operand (operands[2], <MODE>mode)
+		       && rtx_equal_p (operands[0], operands[1])))
+	       : !add_operand (operands[2], <MODE>mode)))
     {
       rtx tmp = ((!can_create_pseudo_p ()
 		  || rtx_equal_p (operands[0], operands[1]))
@@ -1528,18 +1574,32 @@ 
       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
       HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
 
-      if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
+      rtx opr = GEN_INT (rest);
+      rtx opl = GEN_INT (low);
+
+      if (<MODE>mode == DImode && !satisfies_constraint_L (opr))
 	FAIL;
 
+      if (TARGET_VLE
+	  && !vle_add3_operand (opr, <MODE>mode)
+	  && !(vle_add_operand (opr, <MODE>mode)
+	       && rtx_equal_p (tmp, operands[1])))
+	{
+	  gcc_assert (!rtx_equal_p (tmp, operands[1]));
+	  emit_move_insn (tmp, operands[2]);
+	  emit_insn (gen_add<mode>3 (operands[0], tmp, operands[1]));
+	  DONE;
+	}
+
       /* The ordering here is important for the prolog expander.
 	 When space is allocated from the stack, adding 'low' first may
 	 produce a temporary deallocation (which would be bad).  */
-      emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
-      emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
+      emit_insn (gen_add<mode>3 (tmp, operands[1], opr));
+      emit_insn (gen_add<mode>3 (operands[0], tmp, opl));
       DONE;
     }
 })
-
+ 
 ;; Discourage ai/addic because of carry but provide it in an alternative
 ;; allowing register zero as source.
 (define_insn "*add<mode>3_internal1"
@@ -1563,22 +1623,27 @@ 
   [(set_attr "length" "4")])
 
 (define_insn "*add<mode>3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
-	(compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r")
-			    (match_operand:P 2 "reg_or_short_operand" "r,I,r,I"))
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,x,x,x,?kcrxx,?kcrxx")
+	(compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r,r,r")
+			    (match_operand:P 2 "reg_or_short_operand" "r,I,I,ksci8,r,I"))
 		    (const_int 0)))
-   (clobber (match_scratch:P 3 "=r,r,r,r"))]
+   (clobber (match_scratch:P 3 "=r,r,1,r,r,r"))]
   ""
   "@
    add. %3,%1,%2
    addic. %3,%1,%2
+   e_add2i. %1,%2
+   e_addi. %3,%1,%2
    #
    #"
-  [(set_attr "type" "fast_compare,compare,compare,compare")
-   (set_attr "length" "4,4,8,8")])
+  [(set_attr "type" "fast_compare,compare,compare,compare,compare,compare")
+   (set_attr "length" "4,4,4,4,8,8")
+   (set_attr "isa" "*,novle,vle,vle,*,*")])
 
+;; Need to include cr0 here to handle the limitation of e_add2i. capable
+;; of operating on the same source and destination register only.
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "")
 	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
 			      (match_operand:GPR 2 "reg_or_short_operand" ""))
 		    (const_int 0)))
@@ -1593,24 +1658,29 @@ 
   "")
 
 (define_insn "*add<mode>3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
-	(compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r")
-			    (match_operand:P 2 "reg_or_short_operand" "r,I,r,I"))
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,x,x,x,?kcrxx,?kcrxx")
+	(compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,0,r,r,r")
+			    (match_operand:P 2 "reg_or_short_operand" "r,I,I,ksci8,r,I"))
 		    (const_int 0)))
-   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r")
+   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r,r,r")
 	(plus:P (match_dup 1)
 		(match_dup 2)))]
   ""
   "@
    add. %0,%1,%2
    addic. %0,%1,%2
+   e_add2i. %0,%2
+   e_addi. %0,%1,%2
    #
    #"
-  [(set_attr "type" "fast_compare,compare,compare,compare")
-   (set_attr "length" "4,4,8,8")])
+  [(set_attr "type" "fast_compare,compare,compare,compare,compare,compare")
+   (set_attr "length" "4,4,4,4,8,8")
+   (set_attr "isa" "*,novle,vle,vle,*,*")])
 
+;; Need to include cr0 here to handle the limitation of e_add2i. capable
+;; of operating on the same source and destination register only.
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "")
 	(compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "")
 			    (match_operand:P 2 "reg_or_short_operand" ""))
 		    (const_int 0)))
@@ -1640,10 +1710,26 @@ 
   HOST_WIDE_INT val = INTVAL (operands[2]);
   HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
   HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
+  rtx opr = GEN_INT (rest);
+  rtx opl = GEN_INT (low);
 
-  operands[4] = GEN_INT (low);
-  if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
-    operands[3] = GEN_INT (rest);
+  operands[4] = opl;
+  if (TARGET_VLE
+      ? (vle_add3_operand (opr, <MODE>mode)
+	 || (vle_add_operand (opr, <MODE>mode)
+	     && rtx_equal_p (operands[0], operands[1])))
+      : (<MODE>mode == SImode || satisfies_constraint_L (opr)))
+    operands[3] = opr;
+  else if (TARGET_VLE
+	   && (<MODE>mode == SImode || satisfies_constraint_L (opr)))
+    {
+      gcc_assert (!rtx_equal_p (operands[0], operands[1]));
+      operands[3] = (can_create_pseudo_p ()
+		     ? gen_reg_rtx (<MODE>mode) : operands[0]);
+      emit_move_insn (operands[3], operands[2]);
+      emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[3]));
+      DONE;
+    }
   else if (can_create_pseudo_p ())
     {
       operands[3] = gen_reg_rtx (DImode);
@@ -1655,14 +1741,24 @@ 
     FAIL;
 })
 
-(define_insn "one_cmpl<mode>2"
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
-	(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
+(define_expand "one_cmpl<mode>2"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
+        (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
   ""
-  "nor %0,%1,%1")
+  "")
 
+(define_insn "*one_cmpl2_internal"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=kregs,r")
+	(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "0,r")))]
+  ""
+  "@
+   se_not %0
+   nor %0,%1,%1"
+  [(set_attr "length" "2,4")
+   (set_attr "isa" "vle,*")])
+
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (clobber (match_scratch:P 2 "=r,r"))]
@@ -1674,7 +1770,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:P 2 ""))]
@@ -1687,7 +1783,7 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
@@ -1700,7 +1796,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:P 0 "gpc_reg_operand" "")
@@ -1717,13 +1813,13 @@ 
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
 	(minus:GPR (match_operand:GPR 1 "reg_or_short_operand" "r,I")
 		   (match_operand:GPR 2 "gpc_reg_operand" "r,r")))]
-  ""
+  "!TARGET_VLE"
   "@
    subf %0,%2,%1
    subfic %0,%2,%1")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "r,r")
 			     (match_operand:P 2 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
@@ -1736,7 +1832,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "")
 			     (match_operand:P 2 "gpc_reg_operand" ""))
 		    (const_int 0)))
@@ -1751,7 +1847,7 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "r,r")
 			     (match_operand:P 2 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
@@ -1766,7 +1862,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "")
 			     (match_operand:P 2 "gpc_reg_operand" ""))
 		    (const_int 0)))
@@ -1795,6 +1891,12 @@ 
 				 negate_rtx (<MODE>mode, operands[2])));
       DONE;
     }
+  else if (TARGET_VLE)
+    {
+      if (GET_CODE (operands[1]) == CONST_INT
+	  && !satisfies_constraint_ksci8 (operands[1]))
+	operands[1] = force_reg (<MODE>mode, operands[1]);
+    }
 }")
 
 (define_expand "neg<mode>2"
@@ -1804,13 +1906,17 @@ 
   "")
 
 (define_insn "*neg<mode>2_internal"
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
-	(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=kregs,r")
+	(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "0,r")))]
   ""
-  "neg %0,%1")
+  "@
+   se_neg %0
+   neg %0,%1"
+  [(set_attr "length" "2,4")
+   (set_attr "isa" "vle,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (clobber (match_scratch:P 2 "=r,r"))]
@@ -1822,7 +1928,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:P 2 ""))]
@@ -1835,7 +1941,7 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
@@ -1848,7 +1954,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 2 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:P 0 "gpc_reg_operand" "")
@@ -2395,11 +2501,25 @@ 
   emit_insn (gen_bswapsi2 (dest_low, src_high));
 }")
 
-(define_insn "mulsi3"
+(define_expand "mulsi3"
+  [(use (match_operand:SI 0 "gpc_reg_operand" ""))
+   (use (match_operand:SI 1 "gpc_reg_operand" ""))
+   (use (match_operand:SI 2 "reg_or_short_operand" ""))]
+  ""
+  "
+{
+  if (TARGET_VLE)
+    emit_insn (gen_mulsi3_vle (operands[0], operands[1], operands[2]));
+  else
+    emit_insn (gen_mulsi3_novle (operands[0], operands[1], operands[2]));
+  DONE;
+}")
+
+(define_insn "mulsi3_novle"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
 		 (match_operand:SI 2 "reg_or_short_operand" "r,I")))]
-  ""
+  "! TARGET_VLE"
   "@
    mullw %0,%1,%2
    mulli %0,%1,%2"
@@ -2424,7 +2544,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			     (match_operand:SI 2 "gpc_reg_operand" ""))
 		    (const_int 0)))
@@ -2438,7 +2558,7 @@ 
   "")
 
 (define_insn "*mulsi3_internal2"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
 			     (match_operand:SI 2 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
@@ -2452,7 +2572,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			     (match_operand:SI 2 "gpc_reg_operand" ""))
 		    (const_int 0)))
@@ -2531,30 +2651,36 @@ 
 }")
 
 (define_insn ""
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
-	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
-		 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))]
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=kregs,r")
+	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "0,r")
+		 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N")))]
   ""
-  "sra<wd>i %0,%1,%p2\;addze %0,%0"
+  "@
+   se_sra<wd>i %0,%p2\;addze %0,%0
+   sra<wd>i %0,%1,%p2\;addze %0,%0"
   [(set_attr "type" "two")
-   (set_attr "length" "8")])
+   (set_attr "length" "6,8")
+   (set_attr "isa" "vle,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r")
-			   (match_operand:P 2 "exact_log2_cint_operand" "N,N"))
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,=x,?kcreg,?kcrxx")
+	(compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "kregs,r,kregs,r")
+			   (match_operand:P 2 "exact_log2_cint_operand" "N,N,N,N"))
 		    (const_int 0)))
-   (clobber (match_scratch:P 3 "=r,r"))]
+   (clobber (match_scratch:P 3 "=1,r,1,r"))]
   ""
   "@
+   se_sra<wd>i %1,%p2\;addze. %1,%1
    sra<wd>i %3,%1,%p2\;addze. %3,%3
+   #
    #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8,12")
-   (set_attr "cell_micro" "not")])
+   (set_attr "length" "6,8,10,12")
+   (set_attr "cell_micro" "not")
+   (set_attr "isa" "vle,*,vle,*")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
 			     (match_operand:GPR 2 "exact_log2_cint_operand"
 			      ""))
@@ -2569,22 +2695,25 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r")
-			   (match_operand:P 2 "exact_log2_cint_operand" "N,N"))
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,x,?kcreg,?kcrxx")
+	(compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "0,r,0,r")
+			   (match_operand:P 2 "exact_log2_cint_operand" "N,N,N,N"))
 		    (const_int 0)))
-   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:P 0 "gpc_reg_operand" "=kregs,r,kregs,r")
 	(div:P (match_dup 1) (match_dup 2)))]
   ""
   "@
+   se_sra<wd>i %0,%p2\;addze. %0,%0
    sra<wd>i %0,%1,%p2\;addze. %0,%0
+   #
    #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8,12")
-   (set_attr "cell_micro" "not")])
+   (set_attr "length" "6,8,10,12")
+   (set_attr "cell_micro" "not")
+   (set_attr "isa" "vle,*,vle,*")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
 			     (match_operand:GPR 2 "exact_log2_cint_operand"
 			      ""))
@@ -2619,7 +2748,7 @@ 
 	(and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
 		(match_operand:SI 2 "and_operand" "?r,T,K,L")))
    (clobber (match_scratch:CC 3 "=X,X,x,x"))]
-  "rs6000_gen_cell_microcode"
+  "!TARGET_VLE && rs6000_gen_cell_microcode"
   "@
    and %0,%1,%2
    rlwinm %0,%1,0,%m2,%M2
@@ -2632,7 +2761,7 @@ 
 	(and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
 		(match_operand:SI 2 "and_operand" "?r,T")))
    (clobber (match_scratch:CC 3 "=X,X"))]
-  "!rs6000_gen_cell_microcode"
+  "!TARGET_VLE && !rs6000_gen_cell_microcode"
   "@
    and %0,%1,%2
    rlwinm %0,%1,0,%m2,%M2")
@@ -2641,7 +2770,7 @@ 
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
         (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
                 (match_operand:SI 2 "and_operand" "?r,T")))]
-  "!rs6000_gen_cell_microcode"
+  "!TARGET_VLE && !rs6000_gen_cell_microcode"
   "@
    and %0,%1,%2
    rlwinm %0,%1,0,%m2,%M2")
@@ -2652,25 +2781,36 @@ 
 ;; machines causes an execution serialization
 
 (define_insn "*andsi3_internal2_mc"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
-	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r")
-			    (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T"))
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,x,x,x,x,x,x,?kcreg,?kcrxx,?kcreg,?kcreg,??kcreg,??y,??kcreg,??y,?kcrxx")
+	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,kregs,r,kregs,r,r,r,r,r,r")
+			    (match_operand:SI 2 "and_operand" "r,ksci8,K,K,L,L,T,kregs,r,kuim5,ksci8,K,K,L,L,T"))
 		    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r"))
-   (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
+   (clobber (match_scratch:SI 3 "=r,r,1,r,1,r,r,1,r,1,r,1,r,1,r,r"))
+   (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,X,X,x,x,x,x,X"))]
   "TARGET_32BIT && rs6000_gen_cell_microcode"
   "@
    and. %3,%1,%2
+   e_andi. %3,%1,%2
+   e_and2i. %1,%b2
    andi. %3,%1,%b2
+   e_and2is. %1,%u2
    andis. %3,%1,%u2
    rlwinm. %3,%1,0,%m2,%M2
    #
    #
    #
+   #
+   #
+   #
+   #
+   #
    #"
-  [(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\
-		     compare,compare,compare,compare")
-   (set_attr "length" "4,4,4,4,8,8,8,8")])
+  [(set_attr "type" "fast_compare,fast_compare,fast_compare,fast_compare,\
+		     fast_compare,fast_compare,delayed_compare,compare,\
+		     compare,compare,compare,compare,compare,compare,compare,\
+		     compare")
+   (set_attr "length" "4,4,4,4,4,4,4,6,8,6,8,8,8,8,8,8")
+   (set_attr "isa" "*,vle,vle,novle,vle,novle,novle,vle,*,vle,vle,vle,novle,vle,novle,*")])
 
 (define_insn "*andsi3_internal3_mc"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
@@ -2694,7 +2834,7 @@ 
    (set_attr "length" "8,4,4,4,8,8,8,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
 			     (match_operand:GPR 2 "and_operand" ""))
 		    (const_int 0)))
@@ -2731,27 +2871,38 @@ 
   "")
 
 (define_insn "*andsi3_internal4"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
-	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r")
-			    (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T"))
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,x,x,x,x,x,x,?kcreg,?kcrxx,?kcreg,?kcreg,??kcreg,??y,??kcreg,??y,?kcrxx")
+	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,0,r,0,r,r,0,r,0,r,0,r,0,r,r")
+			    (match_operand:SI 2 "and_operand" "r,ksci8,K,K,L,L,T,kregs,r,kuim5,ksci8,K,K,L,L,T"))
 		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,kregs,r,kregs,r,r,r,r,r,r")
 	(and:SI (match_dup 1)
 		(match_dup 2)))
-   (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
+   (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,X,X,x,x,x,x,X"))]
   "TARGET_32BIT && rs6000_gen_cell_microcode"
   "@
    and. %0,%1,%2
+   e_andi. %0,%1,%2
+   e_and2i. %0,%b2
    andi. %0,%1,%b2
+   e_and2is. %0,%u2
    andis. %0,%1,%u2
    rlwinm. %0,%1,0,%m2,%M2
    #
    #
    #
+   #
+   #
+   #
+   #
+   #
    #"
-  [(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\
-		     compare,compare,compare,compare")
-   (set_attr "length" "4,4,4,4,8,8,8,8")])
+  [(set_attr "type" "fast_compare,fast_compare,fast_compare,fast_compare,\
+		     fast_compare,fast_compare,delayed_compare,compare,\
+		     compare,compare,compare,compare,compare,compare,compare,\
+		     compare")
+   (set_attr "length" "4,4,4,4,4,4,4,6,8,6,8,8,8,8,8,8")
+   (set_attr "isa" "*,vle,vle,novle,vle,novle,novle,vle,*,vle,vle,vle,novle,vle,novle,*")])
 
 (define_insn "*andsi3_internal5_mc"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
@@ -2777,7 +2928,7 @@ 
    (set_attr "length" "8,4,4,4,8,8,8,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			    (match_operand:SI 2 "and_operand" ""))
 		    (const_int 0)))
@@ -2867,9 +3018,15 @@ 
   ""
   "
 {
-  if (GET_CODE (operands[2]) == CONST_INT
-      && ! logical_operand (operands[2], SImode))
+  if (TARGET_VLE)
     {
+      if ((GET_CODE (operands[2]) == CONST_INT)
+          && (!satisfies_constraint_ksci8 (operands[2])))
+	operands[2] = force_reg (SImode, operands[2]);
+    }
+  else if (GET_CODE (operands[2]) == CONST_INT
+	   && ! logical_operand (operands[2], SImode))
+    {
       HOST_WIDE_INT value = INTVAL (operands[2]);
       rtx tmp = ((!can_create_pseudo_p ()
 		  || rtx_equal_p (operands[0], operands[1]))
@@ -2887,14 +3044,14 @@ 
 	(match_operator:SI 3 "boolean_or_operator"
 	 [(match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
 	  (match_operand:SI 2 "logical_operand" "r,K,L")]))]
-  ""
+  "!TARGET_VLE"
   "@
    %q3 %0,%1,%2
    %q3i %0,%1,%b2
    %q3is %0,%1,%u2")
 
 (define_insn "*boolsi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (match_operator:SI 4 "boolean_or_operator"
 	 [(match_operand:SI 1 "gpc_reg_operand" "%r,r")
 	  (match_operand:SI 2 "gpc_reg_operand" "r,r")])
@@ -2908,7 +3065,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (match_operator:SI 4 "boolean_operator"
 	 [(match_operand:SI 1 "gpc_reg_operand" "")
 	  (match_operand:SI 2 "gpc_reg_operand" "")])
@@ -2922,7 +3079,7 @@ 
   "")
 
 (define_insn "*boolsi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (match_operator:SI 4 "boolean_operator"
 	 [(match_operand:SI 1 "gpc_reg_operand" "%r,r")
 	  (match_operand:SI 2 "gpc_reg_operand" "r,r")])
@@ -2937,7 +3094,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (match_operator:SI 4 "boolean_operator"
 	 [(match_operand:SI 1 "gpc_reg_operand" "")
 	  (match_operand:SI 2 "gpc_reg_operand" "")])
@@ -2959,7 +3116,7 @@ 
 	(match_operator:SI 3 "boolean_or_operator"
 	 [(match_operand:SI 1 "gpc_reg_operand" "")
 	  (match_operand:SI 2 "non_logical_cint_operand" "")]))]
-  ""
+  "!TARGET_VLE"
   [(set (match_dup 0) (match_dup 4))
    (set (match_dup 0) (match_dup 5))]
 "
@@ -2982,7 +3139,7 @@ 
   "%q3 %0,%2,%1")
 
 (define_insn "*boolcsi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (match_operator:SI 4 "boolean_operator"
 	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
 	  (match_operand:SI 2 "gpc_reg_operand" "r,r")])
@@ -2996,7 +3153,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (match_operator:SI 4 "boolean_operator"
 	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
 	  (match_operand:SI 2 "gpc_reg_operand" "")])
@@ -3010,7 +3167,7 @@ 
   "")
 
 (define_insn "*boolcsi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (match_operator:SI 4 "boolean_operator"
 	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r"))
 	  (match_operand:SI 2 "gpc_reg_operand" "r,r")])
@@ -3025,7 +3182,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (match_operator:SI 4 "boolean_operator"
 	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
 	  (match_operand:SI 2 "gpc_reg_operand" "")])
@@ -3048,7 +3205,7 @@ 
   "%q3 %0,%1,%2")
 
 (define_insn "*boolccsi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (match_operator:SI 4 "boolean_operator"
 	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
 	  (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))])
@@ -3062,7 +3219,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (match_operator:SI 4 "boolean_operator"
 	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
 	  (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))])
@@ -3076,7 +3233,7 @@ 
   "")
 
 (define_insn "*boolccsi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC (match_operator:SI 4 "boolean_operator"
 	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r"))
 	  (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))])
@@ -3091,7 +3248,7 @@ 
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (match_operator:SI 4 "boolean_operator"
 	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
 	  (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))])
@@ -3132,6 +3289,8 @@ 
   DONE;
 }")
 
+;; Insert a bit field
+
 (define_insn "insvsi"
   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
 			 (match_operand:SI 1 "const_int_operand" "i")
@@ -3145,7 +3304,7 @@ 
 
   operands[4] = GEN_INT (32 - start - size);
   operands[1] = GEN_INT (start + size - 1);
-  return \"rlwimi %0,%3,%h4,%h2,%h1\";
+  return \"%^rlwimi %0,%3,%h4,%h2,%h1\";
 }"
   [(set_attr "type" "insert_word")])
 
@@ -3164,7 +3323,7 @@ 
 
   operands[4] = GEN_INT (shift - start - size);
   operands[1] = GEN_INT (start + size - 1);
-  return \"rlwimi %0,%3,%h4,%h2,%h1\";
+  return \"%^rlwimi %0,%3,%h4,%h2,%h1\";
 }"
   [(set_attr "type" "insert_word")])
 
@@ -3183,7 +3342,7 @@ 
 
   operands[4] = GEN_INT (32 - shift - start - size);
   operands[1] = GEN_INT (start + size - 1);
-  return \"rlwimi %0,%3,%h4,%h2,%h1\";
+  return \"%^rlwimi %0,%3,%h4,%h2,%h1\";
 }"
   [(set_attr "type" "insert_word")])
 
@@ -3202,7 +3361,7 @@ 
 
   operands[4] = GEN_INT (32 - shift - start - size);
   operands[1] = GEN_INT (start + size - 1);
-  return \"rlwimi %0,%3,%h4,%h2,%h1\";
+  return \"%^rlwimi %0,%3,%h4,%h2,%h1\";
 }"
   [(set_attr "type" "insert_word")])
 
@@ -3224,7 +3383,7 @@ 
 /* Align extract field with insert field */
   operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size);
   operands[1] = GEN_INT (insert_start + insert_size - 1);
-  return \"rlwimi %0,%3,%h5,%h2,%h1\";
+  return \"%^rlwimi %0,%3,%h5,%h2,%h1\";
 }"
   [(set_attr "type" "insert_word")])
 
@@ -3244,7 +3403,7 @@ 
  operands[4] = GEN_INT(32 - INTVAL(operands[2]));
  operands[2] = GEN_INT(mb);
  operands[1] = GEN_INT(me);
- return \"rlwimi %0,%3,%h4,%h2,%h1\";
+ return \"%^rlwimi %0,%3,%h4,%h2,%h1\";
 }"
   [(set_attr "type" "insert_word")])
 
@@ -3263,7 +3422,7 @@ 
  operands[4] = GEN_INT(32 - INTVAL(operands[2]));
  operands[2] = GEN_INT(mb);
  operands[1] = GEN_INT(me);
- return \"rlwimi %0,%3,%h4,%h2,%h1\";
+ return \"%^rlwimi %0,%3,%h4,%h2,%h1\";
 }"
   [(set_attr "type" "insert_word")])
 
@@ -3360,7 +3519,7 @@ 
     operands[3] = const0_rtx;
   else
     operands[3] = GEN_INT (start + size);
-  return \"rlwinm %0,%1,%3,%s2,31\";
+  return \"%^rlwinm %0,%1,%3,%s2,31\";
 }")
 
 (define_insn "*extzvsi_internal1"
@@ -3370,7 +3529,7 @@ 
 			 (match_operand:SI 3 "const_int_operand" "i,i"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 4 "=r,r"))]
-  ""
+  "!TARGET_VLE"
   "*
 {
   int start = INTVAL (operands[3]) & 31;
@@ -3429,7 +3588,7 @@ 
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
-  ""
+  "!TARGET_VLE"
   "*
 {
   int start = INTVAL (operands[3]) & 31;
@@ -3537,14 +3696,17 @@ 
   [(set_attr "type" "compare")])
 
 (define_insn "rotlsi3"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-		   (match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
+	(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+		   (match_operand:SI 2 "reg_or_cint_operand" "r,r,i,i")))]
   ""
   "@
+   e_rlw %0,%1,%2
    rlwnm %0,%1,%2,0xffffffff
+   e_rlwi %0,%1,%h2
    rlwinm %0,%1,%h2,0xffffffff"
-  [(set_attr "type" "var_shift_rotate,integer")])
+  [(set_attr "type" "var_shift_rotate,var_shift_rotate,integer,integer")
+   (set_attr "isa" "vle,novle,vle,novle")])
 
 (define_insn "*rotlsi3_64"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
@@ -3558,22 +3720,25 @@ 
   [(set_attr "type" "var_shift_rotate,integer")])
 
 (define_insn "*rotlsi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
-	(compare:CC (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"))
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,x,x,x,?kcrxx,?kcrxx")
+	(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+			       (match_operand:SI 2 "reg_or_cint_operand" "r,r,i,i,r,i"))
 		    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r,r,r"))]
+   (clobber (match_scratch:SI 3 "=r,r,r,r,r,r"))]
   ""
   "@
+   e_rlw. %0,%1,%2
    rlwnm. %3,%1,%2,0xffffffff
+   e_rlwi. %0,%1,%h2
    rlwinm. %3,%1,%h2,0xffffffff
    #
    #"
-  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
-   (set_attr "length" "4,4,8,8")])
+  [(set_attr "type" "var_delayed_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,4,4,8,8")
+   (set_attr "isa" "vle,novle,vle,novle,*,*")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			       (match_operand:SI 2 "reg_or_cint_operand" ""))
 		    (const_int 0)))
@@ -3587,23 +3752,26 @@ 
   "")
 
 (define_insn "*rotlsi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
-	(compare:CC (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"))
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,x,x,x,?kcrxx,?kcrxx")
+	(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+			       (match_operand:SI 2 "reg_or_cint_operand" "r,r,i,i,r,i"))
 		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
 	(rotate:SI (match_dup 1) (match_dup 2)))]
   ""
   "@
+   e_rlw. %0,%1,%2
    rlwnm. %0,%1,%2,0xffffffff
+   e_rlwi. %0,%1,%h2
    rlwinm. %0,%1,%h2,0xffffffff
    #
    #"
-  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
-   (set_attr "length" "4,4,8,8")])
+  [(set_attr "type" "var_delayed_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,4,4,8,8")
+   (set_attr "isa" "vle,novle,vle,novle,*,*")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			       (match_operand:SI 2 "reg_or_cint_operand" ""))
 		    (const_int 0)))
@@ -3625,8 +3793,9 @@ 
   ""
   "@
    rlwnm %0,%1,%2,%m3,%M3
-   rlwinm %0,%1,%h2,%m3,%M3"
-  [(set_attr "type" "var_shift_rotate,integer")])
+   %^rlwinm %0,%1,%h2,%m3,%M3"
+  [(set_attr "type" "var_shift_rotate,integer")
+   (set_attr "isa" "novle,*")])
 
 (define_insn "*rotlsi3_internal5"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
@@ -3636,7 +3805,7 @@ 
 		     (match_operand:SI 3 "mask_operand" "n,n,n,n"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 4 "=r,r,r,r"))]
-  ""
+  "!TARGET_VLE"
   "@
    rlwnm. %4,%1,%2,%m3,%M3
    rlwinm. %4,%1,%h2,%m3,%M3
@@ -3653,7 +3822,7 @@ 
 		     (match_operand:SI 3 "mask_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 4 ""))]
-  "reload_completed"
+  "!TARGET_VLE && reload_completed"
   [(set (match_dup 4)
 	(and:SI (rotate:SI (match_dup 1)
 				(match_dup 2))
@@ -3672,7 +3841,7 @@ 
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
 	(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  ""
+  "!TARGET_VLE"
   "@
    rlwnm. %0,%1,%2,%m3,%M3
    rlwinm. %0,%1,%h2,%m3,%M3
@@ -3690,7 +3859,7 @@ 
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "reload_completed"
+  "!TARGET_VLE && reload_completed"
   [(set (match_dup 0)
 	(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (set (match_dup 4)
@@ -3699,17 +3868,20 @@ 
   "")
 
 (define_insn "*rotlsi3_internal7"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,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)))]
+	  (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+		     (match_operand:SI 2 "reg_or_cint_operand" "r,i")) 0)))]
   ""
-  "rlw%I2nm %0,%1,%h2,0xff"
+  "@
+   rlwnm %0,%1,%2,0xff
+   %^rlwinm %0,%1,%h2,0xff"
   [(set (attr "cell_micro")
      (if_then_else (match_operand:SI 2 "const_int_operand" "")
 	(const_string "not")
-	(const_string "always")))])
+	(const_string "always")))
+   (set_attr "isa" "novle,*")])
 
 (define_insn "*rotlsi3_internal8"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
@@ -3719,7 +3891,7 @@ 
 				 (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"))]
-  ""
+  "!TARGET_VLE"
   "@
    rlwnm. %3,%1,%2,0xff
    rlwinm. %3,%1,%h2,0xff
@@ -3736,7 +3908,7 @@ 
 				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "!TARGET_VLE && reload_completed"
   [(set (match_dup 3)
 	(zero_extend:SI (subreg:QI
 		      (rotate:SI (match_dup 1)
@@ -3755,7 +3927,7 @@ 
 		    (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)))]
-  ""
+  "!TARGET_VLE"
   "@
    rlwnm. %0,%1,%2,0xff
    rlwinm. %0,%1,%h2,0xff
@@ -3773,7 +3945,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"
+  "!TARGET_VLE && reload_completed"
   [(set (match_dup 0)
 	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -3790,8 +3962,9 @@ 
   ""
   "@
    rlwnm %0,%1,%2,0xffff
-   rlwinm %0,%1,%h2,0xffff"
-  [(set_attr "type" "var_shift_rotate,integer")])
+   %^rlwinm %0,%1,%h2,0xffff"
+  [(set_attr "type" "var_shift_rotate,integer")
+   (set_attr "isa" "novle,*")])
 
 
 (define_insn "*rotlsi3_internal11"
@@ -3802,7 +3975,7 @@ 
 				 (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"))]
-  ""
+  "!TARGET_VLE"
   "@
    rlwnm. %3,%1,%2,0xffff
    rlwinm. %3,%1,%h2,0xffff
@@ -3819,7 +3992,7 @@ 
 				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "!TARGET_VLE && reload_completed"
   [(set (match_dup 3)
 	(zero_extend:SI (subreg:HI
 		      (rotate:SI (match_dup 1)
@@ -3838,7 +4011,7 @@ 
 		    (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)))]
-  ""
+  "!TARGET_VLE"
   "@
    rlwnm. %0,%1,%2,0xffff
    rlwinm. %0,%1,%h2,0xffff
@@ -3856,7 +4029,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"
+  "!TARGET_VLE && reload_completed"
   [(set (match_dup 0)
 	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -3865,14 +4038,18 @@ 
   "")
 
 (define_insn "ashlsi3"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-		   (match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=kregs,kregs,r,r")
+        (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "0,0,r,r")
+                   (match_operand:SI 2 "reg_or_cint_operand" "kregs,kuim5,r,i")))]
   ""
   "@
+   se_slw %0, %2
+   se_slwi %0, %2
    slw %0,%1,%2
-   slwi %0,%1,%h2"
-  [(set_attr "type" "var_shift_rotate,shift")])
+   %^slwi %0,%1,%h2"
+  [(set_attr "type" "var_shift_rotate,shift,var_shift_rotate,shift")
+   (set_attr "length" "2,2,4,4")
+   (set_attr "isa" "vle,vle,*,*")])
 
 (define_insn "*ashlsi3_64"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
@@ -3894,14 +4071,14 @@ 
   "TARGET_32BIT"
   "@
    slw. %3,%1,%2
-   slwi. %3,%1,%h2
+   %^slwi. %3,%1,%h2
    #
    #"
   [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
    (set_attr "length" "4,4,8,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			       (match_operand:SI 2 "reg_or_cint_operand" ""))
 		    (const_int 0)))
@@ -3924,14 +4101,14 @@ 
   "TARGET_32BIT"
   "@
    slw. %0,%1,%2
-   slwi. %0,%1,%h2
+   %^slwi. %0,%1,%h2
    #
    #"
   [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
    (set_attr "length" "4,4,8,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			       (match_operand:SI 2 "reg_or_cint_operand" ""))
 		    (const_int 0)))
@@ -3951,7 +4128,7 @@ 
 			   (match_operand:SI 2 "const_int_operand" "i"))
 		(match_operand:SI 3 "mask_operand" "n")))]
   "includes_lshift_p (operands[2], operands[3])"
-  "rlwinm %0,%1,%h2,%m3,%M3")
+  "%^rlwinm %0,%1,%h2,%m3,%M3")
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -3961,7 +4138,7 @@ 
 		 (match_operand:SI 3 "mask_operand" "n,n"))
 	 (const_int 0)))
    (clobber (match_scratch:SI 4 "=r,r"))]
-  "includes_lshift_p (operands[2], operands[3])"
+  "!TARGET_VLE && includes_lshift_p (operands[2], operands[3])"
   "@
    rlwinm. %4,%1,%h2,%m3,%M3
    #"
@@ -3976,7 +4153,8 @@ 
 		 (match_operand:SI 3 "mask_operand" ""))
 	 (const_int 0)))
    (clobber (match_scratch:SI 4 ""))]
-  "includes_lshift_p (operands[2], operands[3]) && reload_completed"
+  "!TARGET_VLE && includes_lshift_p (operands[2], operands[3])
+   && reload_completed"
   [(set (match_dup 4)
 	(and:SI (ashift:SI (match_dup 1) (match_dup 2))
 		 (match_dup 3)))
@@ -3994,7 +4172,7 @@ 
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "includes_lshift_p (operands[2], operands[3])"
+  "!TARGET_VLE && includes_lshift_p (operands[2], operands[3])"
   "@
    rlwinm. %0,%1,%h2,%m3,%M3
    #"
@@ -4010,7 +4188,8 @@ 
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "includes_lshift_p (operands[2], operands[3]) && reload_completed"
+  "!TARGET_VLE && includes_lshift_p (operands[2], operands[3])
+   && reload_completed"
   [(set (match_dup 0)
 	(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (set (match_dup 4)
@@ -4019,15 +4198,22 @@ 
   "")
 
 (define_insn "lshrsi3"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
-	(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
-		     (match_operand:SI 2 "reg_or_cint_operand" "O,r,i")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=kregs,kregs,kareg,r,kregs,kregs,r,r")
+	(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "kregs,kareg,kregs,r,0,0,r,r")
+		     (match_operand:SI 2 "reg_or_cint_operand" "O,O,O,O,kregs,kuim5,r,i")))]
   ""
   "@
+  se_mr %0,%1
+  se_mfar %0,%1
+  se_mtar %0,%1
   mr %0,%1
+  se_srw %0,%2
+  se_srwi %0,%h2
   srw %0,%1,%2
-  srwi %0,%1,%h2"
-  [(set_attr "type" "integer,var_shift_rotate,shift")])
+  %^srwi %0,%1,%h2"
+  [(set_attr "type" "integer,integer,integer,integer,var_shift_rotate,shift,var_shift_rotate,shift")
+   (set_attr "length" "2,2,2,4,2,2,4,4")
+   (set_attr "isa" "vle,vle,vle,*,vle,vle,*,*")])
 
 (define_insn "*lshrsi3_64"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
@@ -4041,24 +4227,28 @@ 
   [(set_attr "type" "var_shift_rotate,shift")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y")
-	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
-				 (match_operand:SI 2 "reg_or_cint_operand" "O,r,i,O,r,i"))
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,x,x,kcreg,y,?kcreg,?kcrxx,?kcreg,?kcrxx")
+	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,kregs,r,kregs,r")
+				 (match_operand:SI 2 "reg_or_cint_operand" "O,r,i,O,O,kregs,r,kuim5,i"))
 		    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=X,r,r,X,r,r"))]
+   (clobber (match_scratch:SI 3 "=X,r,r,X,X,1,r,1,r"))]
   "TARGET_32BIT"
   "@
    mr. %1,%1
    srw. %3,%1,%2
-   srwi. %3,%1,%h2
+   %^srwi. %3,%1,%h2
+   e_cmpi %0,%1,0
+   cmpwi %0,%1,0
    #
    #
+   #
    #"
-  [(set_attr "type" "delayed_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
-   (set_attr "length" "4,4,4,8,8,8")])
+  [(set_attr "type" "delayed_compare,var_delayed_compare,delayed_compare,compare,compare,var_delayed_compare,var_delayed_compare,delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,4,4,4,6,8,6,8")
+   (set_attr "isa" "*,*,*,vle,novle,vle,*,vle,*")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
 				 (match_operand:SI 2 "reg_or_cint_operand" ""))
 		    (const_int 0)))
@@ -4072,25 +4262,33 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y,?y,?y")
-	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
-				 (match_operand:SI 2 "reg_or_cint_operand" "O,r,i,O,r,i"))
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,x,x,?kcreg,?kcreg,?kcrxx,?kcreg,?kcrxx,?kcreg,?kcrxx")
+	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,kregs,kareg,r,0,r,0,r")
+				 (match_operand:SI 2 "reg_or_cint_operand" "O,r,i,O,O,O,kregs,r,kuim5,i"))
 		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,kregskareg,kregs,r,kregs,r,kregs,r")
 	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
   "TARGET_32BIT"
   "@
    mr. %0,%1
    srw. %0,%1,%2
-   srwi. %0,%1,%h2
+   %^srwi. %0,%1,%h2
    #
    #
+   #
+   #
+   #
+   #
    #"
-  [(set_attr "type" "delayed_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
-   (set_attr "length" "4,4,4,8,8,8")])
+  [(set_attr "type" "delayed_compare,var_delayed_compare,delayed_compare,\
+		     delayed_compare,delayed_compare,delayed_compare,\
+		     var_delayed_compare,var_delayed_compare,delayed_compare,\
+		     delayed_compare")
+   (set_attr "length" "4,4,4,6,6,8,6,8,6,8")
+   (set_attr "isa" "*,*,*,vle,vle,*,vle,*,vle,*")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
 				 (match_operand:SI 2 "reg_or_cint_operand" ""))
 		    (const_int 0)))
@@ -4110,7 +4308,7 @@ 
 			     (match_operand:SI 2 "const_int_operand" "i"))
 		(match_operand:SI 3 "mask_operand" "n")))]
   "includes_rshift_p (operands[2], operands[3])"
-  "rlwinm %0,%1,%s2,%m3,%M3")
+  "%^rlwinm %0,%1,%s2,%m3,%M3")
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -4120,7 +4318,7 @@ 
 		 (match_operand:SI 3 "mask_operand" "n,n"))
 	 (const_int 0)))
    (clobber (match_scratch:SI 4 "=r,r"))]
-  "includes_rshift_p (operands[2], operands[3])"
+  "!TARGET_VLE && includes_rshift_p (operands[2], operands[3])"
   "@
    rlwinm. %4,%1,%s2,%m3,%M3
    #"
@@ -4135,7 +4333,8 @@ 
 		 (match_operand:SI 3 "mask_operand" ""))
 	 (const_int 0)))
    (clobber (match_scratch:SI 4 ""))]
-  "includes_rshift_p (operands[2], operands[3]) && reload_completed"
+  "!TARGET_VLE && includes_rshift_p (operands[2], operands[3])
+   && reload_completed"
   [(set (match_dup 4)
 	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
 		 (match_dup 3)))
@@ -4153,7 +4352,7 @@ 
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "includes_rshift_p (operands[2], operands[3])"
+  "!TARGET_VLE && includes_rshift_p (operands[2], operands[3])"
   "@
    rlwinm. %0,%1,%s2,%m3,%M3
    #"
@@ -4169,7 +4368,8 @@ 
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "includes_rshift_p (operands[2], operands[3]) && reload_completed"
+  "!TARGET_VLE && includes_rshift_p (operands[2], operands[3])
+   && reload_completed"
   [(set (match_dup 0)
 	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (set (match_dup 4)
@@ -4184,7 +4384,7 @@ 
 	  (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))"
-  "rlwinm %0,%1,%s2,0xff")
+  "%^rlwinm %0,%1,%s2,0xff")
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -4195,7 +4395,7 @@ 
 			(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))"
+  "!TARGET_VLE && includes_rshift_p (operands[2], GEN_INT (255))"
   "@
    rlwinm. %3,%1,%s2,0xff
    #"
@@ -4211,7 +4411,8 @@ 
 			(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"
+  "!TARGET_VLE && includes_rshift_p (operands[2], GEN_INT (255))
+   && reload_completed"
   [(set (match_dup 3)
 	(zero_extend:SI (subreg:QI
 	   (lshiftrt:SI (match_dup 1)
@@ -4231,7 +4432,7 @@ 
 	 (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))"
+  "!TARGET_VLE && includes_rshift_p (operands[2], GEN_INT (255))"
   "@
    rlwinm. %0,%1,%s2,0xff
    #"
@@ -4248,7 +4449,8 @@ 
 	 (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"
+  "!TARGET_VLE && 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)
@@ -4263,7 +4465,7 @@ 
 	  (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))"
-  "rlwinm %0,%1,%s2,0xffff")
+  "%^rlwinm %0,%1,%s2,0xffff")
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -4274,7 +4476,7 @@ 
 			(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))"
+  "!TARGET_VLE && includes_rshift_p (operands[2], GEN_INT (65535))"
   "@
    rlwinm. %3,%1,%s2,0xffff
    #"
@@ -4290,7 +4492,8 @@ 
 			(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"
+  "!TARGET_VLE && includes_rshift_p (operands[2], GEN_INT (65535))
+   && reload_completed"
   [(set (match_dup 3)
 	(zero_extend:SI (subreg:HI
 	   (lshiftrt:SI (match_dup 1)
@@ -4310,7 +4513,7 @@ 
 	 (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))"
+  "!TARGET_VLE && includes_rshift_p (operands[2], GEN_INT (65535))"
   "@
    rlwinm. %0,%1,%s2,0xffff
    #"
@@ -4327,7 +4530,8 @@ 
 	 (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"
+  "!TARGET_VLE && 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)
@@ -4336,14 +4540,18 @@ 
   "")
 
 (define_insn "ashrsi3"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-		     (match_operand:SI 2 "reg_or_cint_operand" "r,i")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=kregs,kregs,r,r")
+	(ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "0,0,r,r")
+		     (match_operand:SI 2 "reg_or_cint_operand" "kregs,kuim5,r,i")))]
   ""
   "@
+   se_sraw %0, %2
+   se_srawi %0, %2
    sraw %0,%1,%2
    srawi %0,%1,%h2"
-  [(set_attr "type" "var_shift_rotate,shift")])
+  [(set_attr "type" "var_shift_rotate,shift,var_shift_rotate,shift")
+   (set_attr "length" "2,2,4,4")
+   (set_attr "isa" "vle,vle,*,*")])
 
 (define_insn "*ashrsi3_64"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
@@ -4369,7 +4577,8 @@ 
    #
    #"
   [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
-   (set_attr "length" "4,4,8,8")])
+   (set_attr "length" "4,4,8,8")
+   (set_attr "isa" "*,*,novle,novle")])
 
 (define_split
   [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
@@ -4386,20 +4595,23 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
-	(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
-				 (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,x,?kcreg,?kcrxx,?kcreg,?kcrxx")
+	(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,0,r,0,r")
+				 (match_operand:SI 2 "reg_or_cint_operand" "r,i,kregs,r,kuim5,i"))
 		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,kregs,r,kregs,r")
 	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
   ""
   "@
    sraw. %0,%1,%2
    srawi. %0,%1,%h2
    #
+   #
+   #
    #"
-  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
-   (set_attr "length" "4,4,8,8")])
+  [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,var_delayed_compare,delayed_compare,delayed_compare")
+   (set_attr "length" "4,4,6,8,6,8")
+   (set_attr "isa" "*,*,vle,*,vle,*")])
 
 ;; Builtins to replace a division to generate FRE reciprocal estimate
 ;; instructions and the necessary fixup instructions
@@ -4441,7 +4653,7 @@ 
 })
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
 				 (match_operand:SI 2 "reg_or_cint_operand" ""))
 		    (const_int 0)))
@@ -4506,6 +4718,13 @@ 
   "frsp %0,%1"
   [(set_attr "type" "fp")])
 
+(define_insn "aux_truncdfsf2"
+  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRSP))]
+  "!TARGET_VLE && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "frsp %0,%1"
+  [(set_attr "type" "fp")])
+
 (define_expand "negsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(neg:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
@@ -4555,6 +4774,14 @@ 
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_addsub_s")])
 
+(define_insn ""
+  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
+		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
+  "!TARGET_VLE && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "fadd %0,%1,%2"
+  [(set_attr "type" "fp")])
+
 (define_expand "subsf3"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
@@ -4571,6 +4798,14 @@ 
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_addsub_s")])
 
+(define_insn ""
+  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
+		  (match_operand:SF 2 "gpc_reg_operand" "f")))]
+  "!TARGET_VLE && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "fsub %0,%1,%2"
+  [(set_attr "type" "fp")])
+
 (define_expand "mulsf3"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
@@ -4587,6 +4822,14 @@ 
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_mul_s")])
 
+(define_insn ""
+  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
+		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
+  "!TARGET_VLE && TARGET_HARD_FLOAT && TARGET_FPRS"
+  "fmul %0,%1,%2"
+  [(set_attr "type" "dmul")])
+
 (define_expand "divsf3"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	(div:SF (match_operand:SF 1 "gpc_reg_operand" "")
@@ -4603,6 +4846,15 @@ 
   "fdivs %0,%1,%2"
   [(set_attr "type" "sdiv")])
 
+(define_insn ""
+  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+	(div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
+		(match_operand:SF 2 "gpc_reg_operand" "f")))]
+  "!TARGET_VLE && TARGET_HARD_FLOAT && TARGET_FPRS
+   && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
+  "fdiv %0,%1,%2"
+  [(set_attr "type" "ddiv")])
+
 (define_insn "fres"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
 	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
@@ -6054,12 +6306,12 @@ 
 ;; allocator from allocating registers that overlap with the inputs
 ;; (for example, having an input in 7,8 and an output in 6,7).  We
 ;; also allow for the output being the same as one of the inputs.
-
+ 
 (define_insn "*adddi3_noppc64"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r")
 	(plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0")
 		 (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))]
-  "! TARGET_POWERPC64"
+  "! TARGET_POWERPC64 && ! TARGET_VLE"
   "*
 {
   if (WORDS_BIG_ENDIAN)
@@ -6084,11 +6336,11 @@ 
   if (WORDS_BIG_ENDIAN)
     return (GET_CODE (operands[1]) != CONST_INT)
 	    ? \"subfc %L0,%L2,%L1\;subfe %0,%2,%1\"
-	    : \"subfic %L0,%L2,%1\;subf%G1e %0,%2\";
+	    : \"%^subfic %L0,%L2,%1\;subf%G1e %0,%2\";
   else
     return (GET_CODE (operands[1]) != CONST_INT)
 	    ? \"subfc %0,%2,%1\;subfe %L0,%L2,%L1\"
-	    : \"subfic %0,%2,%1\;subf%G1e %L0,%L2\";
+	    : \"%^subfic %0,%2,%1\;subf%G1e %L0,%L2\";
 }"
   [(set_attr "type" "two")
    (set_attr "length" "8")])
@@ -6100,7 +6352,7 @@ 
   "*
 {
   return (WORDS_BIG_ENDIAN)
-    ? \"subfic %L0,%L1,0\;subfze %0,%1\"
+    ? \"%^subfic %L0,%L1,0\;subfze %0,%1\"
     : \"subfic %0,%1,0\;subfze %L0,%L1\";
 }"
   [(set_attr "type" "two")
@@ -6206,7 +6458,7 @@ 
   "TARGET_32BIT && !TARGET_POWERPC64 && WORDS_BIG_ENDIAN"
   "@
    srawi %0,%1,31\;srawi %L0,%1,%h2
-   srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2"
+   %^srwi %L0,%L1,%h2\;%^insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2"
   [(set_attr "type" "two,three")
    (set_attr "length" "8,12")])
 
@@ -7640,7 +7892,7 @@ 
 		    (match_operand:SI 2 "gpc_reg_operand" "b")]
 		   UNSPEC_MOVSI_GOT))]
   "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
-  "lwz %0,%a1@got(%2)"
+  "%^lwz %0,%a1@got(%2)"
   [(set_attr "type" "load")])
 
 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
@@ -7679,8 +7931,8 @@ 
   "@
    mr %0,%1
    la %0,%a1
-   lwz%U1%X1 %0,%1
-   stw%U0%X0 %1,%0
+   %e1lwz%U1%X1 %0,%1
+   %e0stw%U0%X0 %1,%0
    li %0,%1
    lis %0,%v1
    #
@@ -7699,8 +7951,8 @@ 
   "@
    mr %0,%1
    la %0,%a1
-   lwz%U1%X1 %0,%1
-   stw%U0%X0 %1,%0
+   %e1lwz%U1%X1 %0,%1
+   %0stw%U0%X0 %1,%0
    li %0,%1
    lis %0,%v1
    #
@@ -7720,7 +7972,12 @@ 
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
 	(match_operand:SI 1 "const_int_operand" ""))]
   "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
-   && (INTVAL (operands[1]) & 0xffff) != 0"
+   && (INTVAL (operands[1]) & 0xffff) != 0
+   && !(TARGET_VLE
+	&& vle_reg_operand (operands[0], SImode)
+	&& (satisfies_constraint_kbit5 (operands[1])
+	    || satisfies_constraint_kmsk5 (operands[1])
+	    || satisfies_constraint_kli20 (operands[1])))"
   [(set (match_dup 0)
 	(match_dup 2))
    (set (match_dup 0)
@@ -7740,7 +7997,7 @@ 
 	(compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
 		    (const_int 0)))
    (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
-  ""
+  "!TARGET_VLE"
   "@
    cmp<wd>i %2,%0,0
    mr. %0,%1
@@ -7767,8 +8024,8 @@ 
    || gpc_reg_operand (operands[1], HImode)"
   "@
    mr %0,%1
-   lhz%U1%X1 %0,%1
-   sth%U0%X0 %1,%0
+   %e1lhz%U1%X1 %0,%1
+   %e0sth%U0%X0 %1,%0
    li %0,%w1
    mf%1 %0
    mt%0 %1
@@ -7788,8 +8045,8 @@ 
    || gpc_reg_operand (operands[1], QImode)"
   "@
    mr %0,%1
-   lbz%U1%X1 %0,%1
-   stb%U0%X0 %1,%0
+   %e1lbz%U1%X1 %0,%1
+   %e0stb%U0%X0 %1,%0
    li %0,%1
    mf%1 %0
    mt%0 %1
@@ -7901,6 +8158,7 @@ 
   [(set_attr "type" "*,load,store,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*")
    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8")])
 
+;;(set_attr "type" "*,mtjmpr,*,mfjmpr,load,store,*,*,*,*,*,*")
 (define_insn "*movsf_softfloat"
   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
 	(match_operand:SF 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
@@ -9240,7 +9498,8 @@ 
    (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"
+  "TARGET_STRING
+   && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
   "lswi %4,%1,%2\;stswi %4,%0,%2"
   [(set_attr "type" "store_ux")
    (set_attr "cell_micro" "always")
@@ -9300,18 +9559,20 @@ 
   [(set_attr "type" "store_ux,store_u")])
 
 (define_insn "*movsi_update1"
-  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
-	(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
-			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
+  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r,r")
+	(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0,0")
+			 (match_operand:SI 2 "reg_or_short_operand" "r,kmmd8,I"))))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   "TARGET_UPDATE
    && (!avoiding_indexed_address_p (SImode)
        || !gpc_reg_operand (operands[2], SImode))"
   "@
    lwzux %3,%0,%2
+   e_lwzu %3,%2(%0)
    lwzu %3,%2(%0)"
-  [(set_attr "type" "load_ux,load_u")])
+  [(set_attr "type" "load_ux,load_u,load_u")
+   (set_attr "isa" "*,vle,novle")])
 
 (define_insn "*movsi_update2"
   [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
@@ -9326,10 +9587,10 @@ 
   [(set_attr "type" "load_ext_ux")])
 
 (define_insn "movsi_update"
-  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
-			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
-	(match_operand:SI 3 "gpc_reg_operand" "r,r"))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
+  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0,0")
+			 (match_operand:SI 2 "reg_or_short_operand" "r,kmmd8,I")))
+	(match_operand:SI 3 "gpc_reg_operand" "r,r,r"))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   "TARGET_UPDATE
    && (!avoiding_indexed_address_p (SImode)
@@ -9338,123 +9599,141 @@ 
 	   && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
   "@
    stwux %3,%0,%2
+   e_stwu %3,%2(%0)
    stwu %3,%2(%0)"
-  [(set_attr "type" "store_ux,store_u")])
+  [(set_attr "type" "store_ux,store_u,store_u")
+   (set_attr "isa" "*,vle,novle")])
 
 ;; This is an unconditional pattern; needed for stack allocation, even
 ;; if the user passes -mno-update.
 (define_insn "movsi_update_stack"
-  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
-			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
-	(match_operand:SI 3 "gpc_reg_operand" "r,r"))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
+  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0,0")
+			 (match_operand:SI 2 "reg_or_short_operand" "r,kmmd8,I")))
+	(match_operand:SI 3 "gpc_reg_operand" "r,r,r"))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "@
    stwux %3,%0,%2
+   e_stwu %3,%2(%0)
    stwu %3,%2(%0)"
-  [(set_attr "type" "store_ux,store_u")])
+  [(set_attr "type" "store_ux,store_u,store_u")
+   (set_attr "isa" "*,vle,novle")])
 
 (define_insn "*movhi_update1"
-  [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
-	(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
-			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
+  [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r,r")
+	(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0,0")
+			 (match_operand:SI 2 "reg_or_short_operand" "r,kmmd8,I"))))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   "TARGET_UPDATE
    && (!avoiding_indexed_address_p (SImode)
        || !gpc_reg_operand (operands[2], SImode))"
   "@
    lhzux %3,%0,%2
+   e_lhzu %3,%2(%0)
    lhzu %3,%2(%0)"
-  [(set_attr "type" "load_ux,load_u")])
+  [(set_attr "type" "load_ux,load_u,load_u")
+   (set_attr "isa" "*,vle,novle")])
 
 (define_insn "*movhi_update2"
-  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
+  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r,r")
 	(zero_extend:SI
-	 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
-			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
+	 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0,0")
+			  (match_operand:SI 2 "reg_or_short_operand" "r,kmmd8,I")))))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   "TARGET_UPDATE
    && (!avoiding_indexed_address_p (SImode)
        || !gpc_reg_operand (operands[2], SImode))"
   "@
    lhzux %3,%0,%2
+   e_lhzu %3,%2(%0)
    lhzu %3,%2(%0)"
-  [(set_attr "type" "load_ux,load_u")])
+  [(set_attr "type" "load_ux,load_u,load_u")
+   (set_attr "isa" "*,vle,novle")])
 
 (define_insn "*movhi_update3"
-  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
+  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r,r")
 	(sign_extend:SI
-	 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
-			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
+	 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0,0")
+			  (match_operand:SI 2 "reg_or_short_operand" "r,kmmd8,I")))))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   "TARGET_UPDATE && rs6000_gen_cell_microcode
    && (!avoiding_indexed_address_p (SImode)
        || !gpc_reg_operand (operands[2], SImode))"
   "@
    lhaux %3,%0,%2
+   e_lhau %3,%2(%0)
    lhau %3,%2(%0)"
-  [(set_attr "type" "load_ext_ux,load_ext_u")])
+  [(set_attr "type" "load_ext_ux,load_ext_u,load_ext_u")
+   (set_attr "isa" "*,vle,novle")])
 
 (define_insn "*movhi_update4"
-  [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
-			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
-	(match_operand:HI 3 "gpc_reg_operand" "r,r"))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
+  [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0,0")
+			 (match_operand:SI 2 "reg_or_short_operand" "r,kmmd8,I")))
+	(match_operand:HI 3 "gpc_reg_operand" "r,r,r"))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   "TARGET_UPDATE
    && (!avoiding_indexed_address_p (SImode)
        || !gpc_reg_operand (operands[2], SImode))"
   "@
    sthux %3,%0,%2
+   e_sthu %3,%2(%0)
    sthu %3,%2(%0)"
-  [(set_attr "type" "store_ux,store_u")])
+  [(set_attr "type" "store_ux,store_u,store_u")
+   (set_attr "isa" "*,vle,novle")])
 
 (define_insn "*movqi_update1"
-  [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
-	(mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
-			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
+  [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r,r")
+	(mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0,0")
+			 (match_operand:SI 2 "reg_or_short_operand" "r,kmmd8,I"))))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   "TARGET_UPDATE
    && (!avoiding_indexed_address_p (SImode)
        || !gpc_reg_operand (operands[2], SImode))"
   "@
    lbzux %3,%0,%2
+   e_lbzu %3,%2(%0)
    lbzu %3,%2(%0)"
-  [(set_attr "type" "load_ux,load_u")])
+  [(set_attr "type" "load_ux,load_u,load_u")
+   (set_attr "isa" "*,vle,novle")])
 
 (define_insn "*movqi_update2"
-  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
+  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r,r")
 	(zero_extend:SI
-	 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
-			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
+	 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0,0")
+			  (match_operand:SI 2 "reg_or_short_operand" "r,kmmd8,I")))))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   "TARGET_UPDATE
    && (!avoiding_indexed_address_p (SImode)
        || !gpc_reg_operand (operands[2], SImode))"
   "@
    lbzux %3,%0,%2
+   e_lbzu %3,%2(%0)
    lbzu %3,%2(%0)"
-  [(set_attr "type" "load_ux,load_u")])
+  [(set_attr "type" "load_ux,load_u,load_u")
+   (set_attr "isa" "*,vle,novle")])
 
 (define_insn "*movqi_update3"
-  [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
-			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
-	(match_operand:QI 3 "gpc_reg_operand" "r,r"))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
+  [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0,0")
+			 (match_operand:SI 2 "reg_or_short_operand" "r,kmmd8,I")))
+	(match_operand:QI 3 "gpc_reg_operand" "r,r,r"))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   "TARGET_UPDATE
    && (!avoiding_indexed_address_p (SImode)
        || !gpc_reg_operand (operands[2], SImode))"
   "@
    stbux %3,%0,%2
+   e_stbu %3,%2(%0)
    stbu %3,%2(%0)"
-  [(set_attr "type" "store_ux,store_u")])
+  [(set_attr "type" "store_ux,store_u,store_u")
+   (set_attr "isa" "*,vle,novle")])
 
 (define_insn "*movsf_update1"
   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
@@ -9997,7 +10276,7 @@ 
 
 (define_expand "allocate_stack"
   [(set (match_operand 0 "gpc_reg_operand" "")
-	(minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
+	(minus (reg 1) (match_operand 1 "reg_or_neg_d_d8_operand" "")))
    (set (reg 1)
 	(minus (reg 1) (match_dup 1)))]
   ""
@@ -10019,9 +10298,7 @@ 
       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
     }
 
-  if (GET_CODE (operands[1]) != CONST_INT
-      || INTVAL (operands[1]) < -32767
-      || INTVAL (operands[1]) > 32768)
+  if (GET_CODE (operands[1]) != CONST_INT)
     {
       neg_op0 = gen_reg_rtx (Pmode);
       if (TARGET_32BIT)
@@ -10032,10 +10309,10 @@ 
   else
     neg_op0 = GEN_INT (- INTVAL (operands[1]));
 
-  insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
-				       : gen_movdi_di_update_stack))
-			(stack_pointer_rtx, stack_pointer_rtx, neg_op0,
-			 chain));
+  insn = emit_insn ((*(TARGET_32BIT
+		       ? gen_movsi_update_stack
+		       : gen_movdi_di_update_stack))
+		    (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
   /* Since we didn't use gen_frame_mem to generate the MEM, grab
      it now and set the alias set/attributes. The above gen_*_update
      calls will generate a PARALLEL with the MEM set being the first
@@ -10185,7 +10462,7 @@ 
   [(set (reg:SI LR_REGNO)
 	(unspec:SI [(const_int 0)] UNSPEC_TOC))]
   "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
-  "bl _GLOBAL_OFFSET_TABLE_@local-4"
+  "%^bl _GLOBAL_OFFSET_TABLE_@local-4"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
 
@@ -10203,7 +10480,7 @@ 
    (use (unspec [(match_dup 0)] UNSPEC_TOC))]
   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX
    && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
-  "bcl 20,31,%0\\n%0:"
+  "%^bl %0\\n%0:"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
 
@@ -10241,7 +10518,7 @@ 
 		UNSPEC_TOCPTR))
    (match_dup 1)]
   "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
-  "bcl 20,31,$+8\;.long %0-$"
+  "%^bcl 20,31,$+8\;.long %0-$"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
 
@@ -10270,7 +10547,7 @@ 
 		   (minus:SI (match_operand:SI 2 "immediate_operand" "s")
 			     (match_operand:SI 3 "immediate_operand" "s")))))]
   "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
-  "lwz %0,%2-%3(%1)"
+  "%^lwz %0,%2-%3(%1)"
   [(set_attr "type" "load")])
 
 (define_insn "load_toc_v4_PIC_3b"
@@ -10372,16 +10649,18 @@ 
   [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
 	(high:SI (match_operand 1 "" "")))]
   "TARGET_ELF && ! TARGET_64BIT"
-  "lis %0,%1@ha")
+  "%^lis %0,%1@ha")
 
 (define_insn "elf_low"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r")
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
+	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r,!*r")
 		   (match_operand 2 "" "")))]
    "TARGET_ELF && ! TARGET_64BIT"
    "@
-    la %0,%2@l(%1)
-    addic %0,%1,%K2")
+    %^la %0,%2@l(%1)
+    e_add16i %0,%1,%K2
+    addic %0,%1,%K2"
+   [(set_attr "isa" "*,vle,novle")])
 
 ;; Call and call_value insns
 (define_expand "call"
@@ -10493,7 +10772,7 @@ 
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn (\"creqv 6,6,6\", operands);
 
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"%^bl %z0@local\" : \"%^bl %z0\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
@@ -10507,12 +10786,12 @@ 
   "*
 {
   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn (\"%^crxor 6,6,6\", operands);
 
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
+    output_asm_insn (\"%^creqv 6,6,6\", operands);
 
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"%^bl %z0@local\" : \"%^bl %z0\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
@@ -10532,7 +10811,7 @@ 
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn (\"creqv 6,6,6\", operands);
 
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"%^bl %z1@local\" : \"%^bl %z1\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
@@ -10548,12 +10827,12 @@ 
   "*
 {
   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn (\"%^crxor 6,6,6\", operands);
 
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
+    output_asm_insn (\"%^creqv 6,6,6\", operands);
 
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"%^bl %z1@local\" : \"%^bl %z1\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
@@ -10703,12 +10982,12 @@ 
    || DEFAULT_ABI == ABI_DARWIN"
 {
   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn ("crxor 6,6,6", operands);
+    output_asm_insn ("%^crxor 6,6,6", operands);
 
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn ("creqv 6,6,6", operands);
+    output_asm_insn ("%^creqv 6,6,6", operands);
 
-  return "b%T0l";
+  return "%+b%T0l";
 }
   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
    (set_attr "length" "4,4,8,8")])
@@ -10723,10 +11002,10 @@ 
        && (INTVAL (operands[2]) & CALL_LONG) == 0))"
 {
   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn ("crxor 6,6,6", operands);
+    output_asm_insn ("%^crxor 6,6,6", operands);
 
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn ("creqv 6,6,6", operands);
+    output_asm_insn ("%^creqv 6,6,6", operands);
 
 #if TARGET_MACHO
   return output_call(insn, operands, 0, 2);
@@ -10734,10 +11013,10 @@ 
   if (DEFAULT_ABI == ABI_V4 && flag_pic)
     {
       gcc_assert (!TARGET_SECURE_PLT);
-      return "bl %z0@plt";
+      return "%^bl %z0@plt";
     }
   else
-    return "bl %z0";
+    return "%^bl %z0";
 #endif
 }
   "DEFAULT_ABI == ABI_V4
@@ -10765,18 +11044,18 @@ 
     && (INTVAL (operands[2]) & CALL_LONG) == 0)"
 {
   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn ("crxor 6,6,6", operands);
+    output_asm_insn ("%^crxor 6,6,6", operands);
 
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn ("creqv 6,6,6", operands);
+    output_asm_insn ("%^creqv 6,6,6", operands);
 
   if (flag_pic == 2)
     /* The magic 32768 offset here and in the other sysv call insns
        corresponds to the offset of r30 in .got2, as given by LCTOC1.
        See sysv4.h:toc_section.  */
-    return "bl %z0+32768@plt";
+    return "%^bl %z0+32768@plt";
   else
-    return "bl %z0@plt";
+    return "%^bl %z0@plt";
 }
   [(set_attr "type" "branch,branch")
    (set_attr "length" "4,8")])
@@ -10791,12 +11070,12 @@ 
    || DEFAULT_ABI == ABI_DARWIN"
 {
   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn ("crxor 6,6,6", operands);
+    output_asm_insn ("%^crxor 6,6,6", operands);
 
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn ("creqv 6,6,6", operands);
+    output_asm_insn ("%^creqv 6,6,6", operands);
 
-  return "b%T1l";
+  return "%+b%T1l";
 }
   [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
    (set_attr "length" "4,4,8,8")])
@@ -10812,10 +11091,10 @@ 
        && (INTVAL (operands[3]) & CALL_LONG) == 0))"
 {
   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn ("crxor 6,6,6", operands);
+    output_asm_insn ("%^crxor 6,6,6", operands);
 
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn ("creqv 6,6,6", operands);
+    output_asm_insn ("%^creqv 6,6,6", operands);
 
 #if TARGET_MACHO
   return output_call(insn, operands, 1, 3);
@@ -10823,10 +11102,10 @@ 
   if (DEFAULT_ABI == ABI_V4 && flag_pic)
     {
       gcc_assert (!TARGET_SECURE_PLT);
-      return "bl %z1@plt";
+      return "%^bl %z1@plt";
     }
   else
-    return "bl %z1";
+    return "%^bl %z1";
 #endif
 }
   "DEFAULT_ABI == ABI_V4
@@ -10932,12 +11211,12 @@ 
   "*
 {
   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn (\"%^crxor 6,6,6\", operands);
 
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
+    output_asm_insn (\"%^creqv 6,6,6\", operands);
 
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"%^b %z0@local\" : \"%^b %z0\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
@@ -10973,12 +11252,12 @@ 
   "*
 {
   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
-    output_asm_insn (\"crxor 6,6,6\", operands);
+    output_asm_insn (\"%^crxor 6,6,6\", operands);
 
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
-    output_asm_insn (\"creqv 6,6,6\", operands);
+    output_asm_insn (\"%^creqv 6,6,6\", operands);
 
-  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
+  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"%^b %z1@local\" : \"%^b %z1\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
@@ -11052,14 +11331,14 @@ 
     output_asm_insn (\"creqv 6,6,6\", operands);
 
   if (which_alternative >= 2)
-    return \"b%T0\";
+    return \"%+b%T0\";
   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
     {
       gcc_assert (!TARGET_SECURE_PLT);
-      return \"b %z0@plt\";
+      return \"%^b %z0@plt\";
     }
   else
-    return \"b %z0\";
+    return \"%^b %z0\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "4,8,4,8")])
@@ -11104,14 +11383,14 @@ 
     output_asm_insn (\"creqv 6,6,6\", operands);
 
   if (which_alternative >= 2)
-    return \"b%T1\";
+    return \"%+b%T1\";
   else if (DEFAULT_ABI == ABI_V4 && flag_pic)
     {
       gcc_assert (!TARGET_SECURE_PLT);
-      return \"b %z1@plt\";
+      return \"%^b %z1@plt\";
     }
   else
-    return \"b %z1\";
+    return \"%^b %z1\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "4,8,4,8")])
@@ -11307,9 +11586,14 @@ 
    (clobber (match_scratch:SI 3 "=&r,&r"))]
   "TARGET_32BIT"
   "@
-   lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
-   lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
-  [(set_attr "length" "16,20")])
+   %e1lwz%U1%X1 %3,%1\;%e2lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;%+li %4,0
+   %e1lwz%U1%X1 %3,%1\;%e2lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;%+li %3,0\;%+li %4,0"
+  [(set_attr_alternative "length" [(if_then_else (eq_attr "is_vle" "yes")
+						 (const_int 14)
+						 (const_int 16))
+				   (if_then_else (eq_attr "is_vle" "yes")
+						 (const_int 16)
+						 (const_int 20))])])
 
 (define_insn "stack_protect_testdi"
   [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
@@ -11330,7 +11614,7 @@ 
   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
 	(compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
 		    (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
-  ""
+  "!TARGET_VLE"
   "cmp<wd>%I2 %0,%1,%2"
   [(set_attr "type" "cmp")])
 
@@ -11356,7 +11640,8 @@ 
                        [(match_dup 4) (const_int 0)])
                       (match_operand 7 "" "")
                       (match_operand 8 "" "")))]
-  "peep2_reg_dead_p (3, operands[0])
+  "!TARGET_VLE
+   && peep2_reg_dead_p (3, operands[0])
    && peep2_reg_dead_p (4, operands[4])"
  [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
   (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
@@ -11381,7 +11666,7 @@ 
   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
 	(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
 		       (match_operand:SI 2 "reg_or_u_short_operand" "rK")))]
-  ""
+  "!TARGET_VLE"
   "cmplw%I2 %0,%1,%b2"
   [(set_attr "type" "cmp")])
 
@@ -11404,7 +11689,7 @@ 
 		    (match_operand:SI 2 "short_cint_operand" "i")))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
-  ""
+  "!TARGET_VLE"
   "#"
   [(set_attr "length" "8")])
 
@@ -11414,7 +11699,7 @@ 
 		       (match_operand:SI 2 "u_short_cint_operand" "i")))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
-  ""
+  "!TARGET_VLE"
   "#"
   [(set_attr "length" "8")])
 
@@ -11424,7 +11709,7 @@ 
 		    (match_operand:SI 2 "short_cint_operand" "")))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
-  ""
+  "!TARGET_VLE"
   [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
 
@@ -11434,7 +11719,7 @@ 
 		       (match_operand:SI 2 "u_short_cint_operand" "")))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
-  ""
+  "!TARGET_VLE"
   [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
 
@@ -11540,7 +11825,7 @@ 
 			   [(match_operand 2 "cc_reg_operand" "y")
 			    (const_int 0)]))]
   ""
-  "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
+  "mfcr %0%Q2\;%^rlwinm %0,%0,%J1,1"
   [(set (attr "type")
      (cond [(match_test "TARGET_MFCRF")
 		(const_string "mfcrf")
@@ -11553,7 +11838,7 @@ 
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
   "TARGET_HARD_FLOAT && !TARGET_FPRS"
-  "mfcr %0\;rlwinm %0,%0,%D1,31,31"
+  "mfcr %0\;%^rlwinm %0,%0,%D1,31,31"
   [(set_attr "type" "mfcr")
    (set_attr "length" "8")])
 
@@ -11562,7 +11847,7 @@ 
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_OV))]
   "TARGET_ISEL"
-  "mfcr %0\;rlwinm %0,%0,%t1,1"
+  "mfcr %0\;%^rlwinm %0,%0,%t1,1"
   [(set_attr "type" "mfcr")
    (set_attr "length" "8")])
 
@@ -11588,7 +11873,7 @@ 
 		    (const_int 0)))
    (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
 	(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
-  "TARGET_32BIT"
+  "TARGET_32BIT && !TARGET_VLE"
   "@
    mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
    #"
@@ -11603,7 +11888,7 @@ 
 		    (const_int 0)))
    (set (match_operand:SI 3 "gpc_reg_operand" "")
 	(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
-  "TARGET_32BIT && reload_completed"
+  "TARGET_32BIT && !TARGET_VLE && reload_completed"
   [(set (match_dup 3)
 	(match_op_dup 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
@@ -11632,7 +11917,7 @@ 
   operands[4] = GEN_INT (count);
   operands[5] = GEN_INT (put_bit);
 
-  return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
+  return \"mfcr %0%Q2\;%^rlwinm %0,%0,%4,%5,%5\";
 }"
   [(set (attr "type")
      (cond [(match_test "TARGET_MFCRF")
@@ -11652,7 +11937,7 @@ 
    (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
 	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
 		   (match_dup 3)))]
-  ""
+  "!TARGET_VLE"
   "*
 {
   int is_bit = ccr_bit (operands[1], 1);
@@ -11687,7 +11972,7 @@ 
    (set (match_operand:SI 4 "gpc_reg_operand" "")
 	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
 		   (match_dup 3)))]
-  "reload_completed"
+  "!TARGET_VLE && reload_completed"
   [(set (match_dup 4)
 	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
 		   (match_dup 3)))
@@ -11709,7 +11994,7 @@ 
 			   [(match_operand 5 "cc_reg_operand" "y")
 			    (const_int 0)]))]
   "REGNO (operands[2]) != REGNO (operands[5])"
-  "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1"
+  "mfcr %3\;%^rlwinm %0,%3,%J1,1\;%^rlwinm %3,%3,%J4,1"
   [(set_attr "type" "mfcr")
    (set_attr "length" "12")])
 
@@ -11762,9 +12047,7 @@ 
 	operands[3] = operands[0];
 
 	if (logical_operand (operands[2], <MODE>mode))
-	  emit_insn (gen_rtx_SET (VOIDmode, operands[3],
-				  gen_rtx_XOR (<MODE>mode,
-					       operands[1], operands[2])));
+	  emit_insn (gen_xor<mode>3 (operands[3], operands[1], operands[2]));
 	else
 	  emit_insn (gen_rtx_SET (VOIDmode, operands[3],
 				  gen_rtx_PLUS (<MODE>mode, operands[1],
@@ -11778,7 +12061,7 @@ 
   })
 
 (define_insn_and_split "*eq<mode>_compare"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=y")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=kcrxx")
 	(compare:CC
 	 (eq:P (match_operand:P 1 "gpc_reg_operand" "=r")
 	       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
@@ -11802,9 +12085,7 @@ 
 	operands[4] = operands[0];
 
 	if (logical_operand (operands[2], <MODE>mode))
-	  emit_insn (gen_rtx_SET (VOIDmode, operands[4],
-				  gen_rtx_XOR (<MODE>mode,
-					       operands[1], operands[2])));
+	  emit_insn (gen_xor<mode>3 (operands[4], operands[1], operands[2]));
 	else
 	  emit_insn (gen_rtx_SET (VOIDmode, operands[4],
 				  gen_rtx_PLUS (<MODE>mode, operands[1],
@@ -11837,7 +12118,7 @@ 
 	(plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
 			(match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I"))
 		 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))]
-  "TARGET_32BIT"
+  "TARGET_32BIT && !TARGET_VLE"
   "@
    xor %0,%1,%2\;subfic %0,%0,0\;addze %0,%3
    subfic %0,%1,0\;addze %0,%3
@@ -11856,7 +12137,7 @@ 
 	  (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r"))
 	 (const_int 0)))
    (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))]
-  "TARGET_32BIT && optimize_size"
+  "TARGET_32BIT && !TARGET_VLE && optimize_size"
   "@
    xor %4,%1,%2\;subfic %4,%4,0\;addze. %4,%3
    subfic %4,%1,0\;addze. %4,%3
@@ -11880,7 +12161,7 @@ 
 	  (match_operand:SI 3 "gpc_reg_operand" ""))
 	 (const_int 0)))
    (clobber (match_scratch:SI 4 ""))]
-  "TARGET_32BIT && optimize_size && reload_completed"
+  "TARGET_32BIT && !TARGET_VLE && optimize_size && reload_completed"
   [(set (match_dup 4)
 	(plus:SI (eq:SI (match_dup 1)
 		 (match_dup 2))
@@ -11900,7 +12181,7 @@ 
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r")
 	(plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "TARGET_32BIT && optimize_size"
+  "TARGET_32BIT && !TARGET_VLE && optimize_size"
   "@
    xor %0,%1,%2\;subfic %0,%0,0\;addze. %0,%3
    subfic %0,%1,0\;addze. %0,%3
@@ -11925,7 +12206,7 @@ 
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "TARGET_32BIT && optimize_size && reload_completed"
+  "TARGET_32BIT && !TARGET_VLE && optimize_size && reload_completed"
   [(set (match_dup 0)
 	(plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (set (match_dup 4)
@@ -11938,7 +12219,7 @@ 
 	(neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
 		     (const_int 0))))]
   ""
-  "addic %0,%1,-1\;subfe %0,%0,%0"
+  "%^addic %0,%1,-1\;subfe %0,%0,%0"
   [(set_attr "type" "two")
    (set_attr "length" "8")])
 
@@ -11957,9 +12238,7 @@ 
 	operands[3] = operands[0];
 
 	if (logical_operand (operands[2], <MODE>mode))
-	  emit_insn (gen_rtx_SET (VOIDmode, operands[3],
-				  gen_rtx_XOR (<MODE>mode,
-					       operands[1], operands[2])));
+	  emit_insn (gen_xor<mode>3 (operands[3], operands[1], operands[2]));
 	else
 	  emit_insn (gen_rtx_SET (VOIDmode, operands[3],
 				  gen_rtx_PLUS (<MODE>mode, operands[1],
@@ -11978,7 +12257,7 @@ 
 		     (const_int 31)))
    (clobber (match_scratch:SI 2 "=&r"))]
   "TARGET_32BIT && !TARGET_ISEL"
-  "addic %2,%1,-1\;subfe %0,%2,%1"
+  "%^addic %2,%1,-1\;subfe %0,%2,%1"
   [(set_attr "type" "two")
    (set_attr "length" "8")])
 
@@ -12001,7 +12280,7 @@ 
 		 (match_operand:SI 2 "gpc_reg_operand" "r")))
    (clobber (match_scratch:SI 3 "=&r"))]
   "TARGET_32BIT"
-  "addic %3,%1,-1\;addze %0,%2"
+  "%^addic %3,%1,-1\;addze %0,%2"
   [(set_attr "type" "two")
    (set_attr "length" "8")])
 
@@ -12018,7 +12297,7 @@ 
    (set_attr "length" "8")])
 
 (define_insn "*compare_plus_ne0si"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC
 	 (plus:SI (lshiftrt:SI
 		   (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")))
@@ -12029,13 +12308,13 @@ 
    (clobber (match_scratch:SI 4 "=X,&r"))]
   "TARGET_32BIT"
   "@
-   addic %3,%1,-1\;addze. %3,%2
+   %^addic %3,%1,-1\;addze. %3,%2
    #"
   [(set_attr "type" "compare")
    (set_attr "length" "8,12")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC
 	 (plus:SI (lshiftrt:SI
 		   (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))
@@ -12091,7 +12370,7 @@ 
   "")
 
 (define_insn "*plus_ne0si_compare"
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 4 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC
 	 (plus:SI (lshiftrt:SI
 		   (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")))
@@ -12104,13 +12383,13 @@ 
    (clobber (match_scratch:SI 3 "=&r,&r"))]
   "TARGET_32BIT"
   "@
-   addic %3,%1,-1\;addze. %0,%2
+   %^addic %3,%1,-1\;addze. %0,%2
    #"
   [(set_attr "type" "compare")
    (set_attr "length" "8,12")])
 
 (define_split
-  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 4 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC
 	 (plus:SI (lshiftrt:SI
 		   (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))
@@ -12173,31 +12452,36 @@ 
   "")
 
 (define_insn "*leu<mode>"
-  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
-	(leu:P (match_operand:P 1 "gpc_reg_operand" "r")
-	       (match_operand:P 2 "reg_or_short_operand" "rI")))]
+  [(set (match_operand:P 0 "gpc_reg_operand" "=kregs,r")
+	(leu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
+	       (match_operand:P 2 "reg_or_short_operand" "rksci8,rkscI8")))]
   ""
-  "subf%I2c %0,%1,%2\;li %0,0\;adde %0,%0,%0"
+  "@
+   %i2subf%I2c %0,%1,%2\;%+li %0,0\;adde %0,%0,%0
+   %i2subf%I2c %0,%1,%2\;%^li %0,0\;adde %0,%0,%0"
   [(set_attr "type" "three")
-   (set_attr "length" "12")])
+   (set_attr "length" "10,12")
+   (set_attr "isa" "vle,*")])
 
 (define_insn "*leu<mode>_compare"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,x,?kcrxx")
 	(compare:CC
-	 (leu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
-		(match_operand:P 2 "reg_or_short_operand" "rI,rI"))
+	 (leu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r")
+		(match_operand:P 2 "reg_or_short_operand" "rksci8,rkscI8,rkscI8"))
 	 (const_int 0)))
-   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:P 0 "gpc_reg_operand" "=kregs,r,r")
 	(leu:P (match_dup 1) (match_dup 2)))]
   ""
   "@
-   subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0
+   %i2subf%I2c %0,%1,%2\;%+li %0,0\;adde. %0,%0,%0
+   %i2subf%I2c %0,%1,%2\;%^li %0,0\;adde. %0,%0,%0
    #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12,16")])
+   (set_attr "length" "10,12,16")
+   (set_attr "isa" "vle,*,*")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC
 	 (leu:P (match_operand:P 1 "gpc_reg_operand" "")
 		(match_operand:P 2 "reg_or_short_operand" ""))
@@ -12215,30 +12499,30 @@ 
 (define_insn "*plus_leu<mode>"
   [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
 	(plus:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
-		       (match_operand:P 2 "reg_or_short_operand" "rI"))
+		       (match_operand:P 2 "reg_or_short_operand" "rkscI8"))
 		(match_operand:P 3 "gpc_reg_operand" "r")))]
   ""
-  "subf%I2c %0,%1,%2\;addze %0,%3"
+  "%i2subf%I2c %0,%1,%2\;addze %0,%3"
   [(set_attr "type" "two")
    (set_attr "length" "8")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC
 	 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			  (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
+			  (match_operand:SI 2 "reg_or_short_operand" "rkscI8,rkscI8"))
 		  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
 	 (const_int 0)))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
   "TARGET_32BIT"
   "@
-   subf%I2c %4,%1,%2\;addze. %4,%3
+   %i2subf%I2c %4,%1,%2\;addze. %4,%3
    #"
   [(set_attr "type" "compare")
    (set_attr "length" "8,12")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC
 	 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			  (match_operand:SI 2 "reg_or_short_operand" ""))
@@ -12255,23 +12539,23 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 4 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC
 	 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			  (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
+			  (match_operand:SI 2 "reg_or_short_operand" "rkscI8,rkscI8"))
 		  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
 	(plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
   "TARGET_32BIT"
   "@
-   subf%I2c %0,%1,%2\;addze. %0,%3
+   %i2subf%I2c %0,%1,%2\;addze. %0,%3
    #"
   [(set_attr "type" "compare")
    (set_attr "length" "8,12")])
 
 (define_split
-  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 4 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC
 	 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			  (match_operand:SI 2 "reg_or_short_operand" ""))
@@ -12290,41 +12574,41 @@ 
 (define_insn "*neg_leu<mode>"
   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
 	(neg:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
-		      (match_operand:P 2 "reg_or_short_operand" "rI"))))]
+		      (match_operand:P 2 "reg_or_short_operand" "rkscI8"))))]
   ""
-  "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;nand %0,%0,%0"
-   [(set_attr "type" "three")
-    (set_attr "length" "12")])
+  "%i2subf%I2c %0,%1,%2\;subfe %0,%0,%0\;nand %0,%0,%0"
+  [(set_attr "type" "three")
+   (set_attr "length" "12")])
 
 (define_insn "*and_neg_leu<mode>"
   [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
 	(and:P (neg:P
 		 (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
-			(match_operand:P 2 "reg_or_short_operand" "rI")))
+			(match_operand:P 2 "reg_or_short_operand" "rkscI8")))
 		(match_operand:P 3 "gpc_reg_operand" "r")))]
   ""
-  "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;andc %0,%3,%0"
+  "%i2subf%I2c %0,%1,%2\;subfe %0,%0,%0\;andc %0,%3,%0"
   [(set_attr "type" "three")
    (set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC
 	 (and:SI (neg:SI
 		  (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			  (match_operand:SI 2 "reg_or_short_operand" "rI,rI")))
+			  (match_operand:SI 2 "reg_or_short_operand" "rkscI8,rkscI8")))
 		 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
 	 (const_int 0)))
    (clobber (match_scratch:SI 4 "=&r,&r"))]
   "TARGET_32BIT"
   "@
-   subf%I2c %4,%1,%2\;subfe %4,%4,%4\;andc. %4,%3,%4
+   %i2subf%I2c %4,%1,%2\;subfe %4,%4,%4\;andc. %4,%3,%4
    #"
   [(set_attr "type" "compare")
    (set_attr "length" "12,16")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC
 	 (and:SI (neg:SI
 		  (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
@@ -12342,24 +12626,24 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 4 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC
 	 (and:SI (neg:SI
 		  (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-			  (match_operand:SI 2 "reg_or_short_operand" "rI,rI")))
+			  (match_operand:SI 2 "reg_or_short_operand" "rkscI8,rkscI8")))
 		 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
 	(and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
   "TARGET_32BIT"
   "@
-   subf%I2c %0,%1,%2\;subfe %0,%0,%0\;andc. %0,%3,%0
+   %i2subf%I2c %0,%1,%2\;subfe %0,%0,%0\;andc. %0,%3,%0
    #"
   [(set_attr "type" "compare")
    (set_attr "length" "12,16")])
 
 (define_split
-  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 4 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC
 	 (and:SI (neg:SI
 		  (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
@@ -12389,7 +12673,7 @@ 
   "")
 
 (define_insn_and_split "*ltu<mode>_compare"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,x,?kcrxx,?kcrxx")
 	(compare:CC
 	 (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
 		(match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P"))
@@ -12418,7 +12702,7 @@ 
   "")
 
 (define_insn_and_split "*plus_ltu<mode>_compare"
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
+  [(set (match_operand:CC 4 "cmpi_cc_reg_operand" "=x,x,?kcrxx,?kcrxx")
 	(compare:CC
 	 (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
 			(match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P"))
@@ -12439,44 +12723,43 @@ 
 (define_insn "*neg_ltu<mode>"
   [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
 	(neg:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
-		      (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))))]
+		      (match_operand:P 2 "vle_reg_or_neg_imm_operand" "r,kscP8"))))]
   ""
   "@
    subfc %0,%2,%1\;subfe %0,%0,%0
-   addic %0,%1,%n2\;subfe %0,%0,%0"
+   %i2addic %0,%1,%n2\;subfe %0,%0,%0"
   [(set_attr "type" "two")
    (set_attr "length" "8")])
 
 (define_insn "*geu<mode>"
   [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
 	(geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
-	       (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))]
+	       (match_operand:P 2 "vle_reg_or_neg_imm_operand" "r,kscP8")))]
   ""
   "@
-   subfc %0,%2,%1\;li %0,0\;adde %0,%0,%0
-   addic %0,%1,%n2\;li %0,0\;adde %0,%0,%0"
+   subfc %0,%2,%1\;%^li %0,0\;adde %0,%0,%0
+   %i2addic %0,%1,%n2\;%^li %0,0\;adde %0,%0,%0"
   [(set_attr "type" "three")
    (set_attr "length" "12")])
 
 (define_insn "*geu<mode>_compare"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,x,?kcrxx")
 	(compare:CC
-	 (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
-		(match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P"))
+	 (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r")
+		(match_operand:P 2 "vle_reg_or_neg_imm_operand" "r,kscP8,rkscP8"))
 	 (const_int 0)))
-   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r")
+   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r")
 	(geu:P (match_dup 1) (match_dup 2)))]
   ""
   "@
-   subfc %0,%2,%1\;li %0,0\;adde. %0,%0,%0
-   addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0
-   #
+   subfc %0,%2,%1\;%^li %0,0\;adde. %0,%0,%0
+   %i2addic %0,%1,%n2\;%^li %0,0\;adde. %0,%0,%0
    #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12,12,16,16")])
+   (set_attr "length" "12,12,16")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_micro_cr0_operand" "")
 	(compare:CC
 	 (geu:P (match_operand:P 1 "gpc_reg_operand" "")
 		(match_operand:P 2 "reg_or_neg_short_operand" ""))
@@ -12494,34 +12777,33 @@ 
 (define_insn "*plus_geu<mode>"
   [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r")
 	(plus:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
-		       (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))
+		       (match_operand:P 2 "vle_reg_or_neg_imm_operand" "r,kscP8"))
 		(match_operand:P 3 "gpc_reg_operand" "r,r")))]
   ""
   "@
    subfc %0,%2,%1\;addze %0,%3
-   addic %0,%1,%n2\;addze %0,%3"
+   %i2addic %0,%1,%n2\;addze %0,%3"
   [(set_attr "type" "two")
    (set_attr "length" "8")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,x,?kcrxx")
 	(compare:CC
-	 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
-			  (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
-		  (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
+	 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
+			  (match_operand:SI 2 "vle_reg_or_neg_imm_operand" "r,kscP8,rkscP8"))
+		  (match_operand:SI 3 "gpc_reg_operand" "r,r,r"))
 	 (const_int 0)))
-   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r"))]
   "TARGET_32BIT"
   "@
    subfc %4,%2,%1\;addze. %4,%3
-   addic %4,%1,%n2\;addze. %4,%3
-   #
+   %i2addic %4,%1,%n2\;addze. %4,%3
    #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8,8,12,12")])
+   (set_attr "length" "8,8,12")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC
 	 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			  (match_operand:SI 2 "reg_or_neg_short_operand" ""))
@@ -12538,25 +12820,24 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
+  [(set (match_operand:CC 4 "cmpi_cc_reg_operand" "=x,x,?kcrxx")
 	(compare:CC
-	 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
-			  (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
-		  (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
+	 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
+			  (match_operand:SI 2 "vle_reg_or_neg_imm_operand" "r,kscP8,rkscP8"))
+		  (match_operand:SI 3 "gpc_reg_operand" "r,r,r"))
 	 (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r")
 	(plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
   "TARGET_32BIT"
   "@
    subfc %0,%2,%1\;addze. %0,%3
-   addic %0,%1,%n2\;addze. %0,%3
-   #
+   %i2addic %0,%1,%n2\;addze. %0,%3
    #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8,8,12,12")])
+   (set_attr "length" "8,8,12")])
 
 (define_split
-  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 4 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC
 	 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			  (match_operand:SI 2 "reg_or_neg_short_operand" ""))
@@ -12575,11 +12856,11 @@ 
 (define_insn "*neg_geu<mode>"
   [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
 	(neg:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
-		      (match_operand:P 2 "reg_or_short_operand" "r,I"))))]
+		      (match_operand:P 2 "reg_or_short_operand" "r,kscI8"))))]
   ""
   "@
    subfc %0,%2,%1\;subfe %0,%0,%0\;nand %0,%0,%0
-   subfic %0,%1,-1\;add%I2c %0,%0,%2\;subfe %0,%0,%0"
+   %^subfic %0,%1,-1\;%i2add%I2c %0,%0,%2\;subfe %0,%0,%0"
   [(set_attr "type" "three")
    (set_attr "length" "12")])
 
@@ -12587,35 +12868,34 @@ 
   [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r")
 	(and:P (neg:P
 		 (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
-			(match_operand:P 2 "reg_or_neg_short_operand" "r,P")))
+			(match_operand:P 2 "vle_reg_or_neg_imm_operand" "r,kscP8")))
 		(match_operand:P 3 "gpc_reg_operand" "r,r")))]
   ""
   "@
    subfc %0,%2,%1\;subfe %0,%0,%0\;andc %0,%3,%0
-   addic %0,%1,%n2\;subfe %0,%0,%0\;andc %0,%3,%0"
+   %i2addic %0,%1,%n2\;subfe %0,%0,%0\;andc %0,%3,%0"
   [(set_attr "type" "three")
    (set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,x,?kcrxx")
 	(compare:CC
 	 (and:SI (neg:SI
-		  (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
-			  (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")))
-		 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
+		  (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
+			  (match_operand:SI 2 "vle_reg_or_neg_imm_operand" "r,kscP8,rkscP8")))
+		 (match_operand:SI 3 "gpc_reg_operand" "r,r,r"))
 	 (const_int 0)))
-   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r"))]
   "TARGET_32BIT"
   "@
    subfc %4,%2,%1\;subfe %4,%4,%4\;andc. %4,%3,%4
-   addic %4,%1,%n2\;subfe %4,%4,%4\;andc. %4,%3,%4
-   #
+   %i2addic %4,%1,%n2\;subfe %4,%4,%4\;andc. %4,%3,%4
    #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12,12,16,16")])
+   (set_attr "length" "12,12,16")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC
 	 (and:SI (neg:SI
 		  (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
@@ -12633,26 +12913,25 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
+  [(set (match_operand:CC 4 "cmpi_cc_reg_operand" "=x,x,?kcrxx")
 	(compare:CC
 	 (and:SI (neg:SI
-		  (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
-			  (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")))
-		 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
+		  (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
+			  (match_operand:SI 2 "vle_reg_or_neg_imm_operand" "r,kscP8,rkscP8")))
+		 (match_operand:SI 3 "gpc_reg_operand" "r,r,r"))
 	 (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r")
 	(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
   "TARGET_32BIT"
   "@
    subfc %0,%2,%1\;subfe %0,%0,%0\;andc. %0,%3,%0
-   addic %0,%1,%n2\;subfe %0,%0,%0\;andc. %0,%3,%0
-   #
+   %i2addic %0,%1,%n2\;subfe %0,%0,%0\;andc. %0,%3,%0
    #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12,12,16,16")])
+   (set_attr "length" "12,12,16")])
 
 (define_split
-  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 4 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC
 	 (and:SI (neg:SI
 		  (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
@@ -12680,7 +12959,7 @@ 
    (set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC
 	 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
 			 (const_int 0))
@@ -12695,7 +12974,7 @@ 
    (set_attr "length" "12,16")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC
 	 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			 (const_int 0))
@@ -12744,7 +13023,7 @@ 
   "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC
 	 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
 			 (const_int 0))
@@ -12760,7 +13039,7 @@ 
    (set_attr "length" "12,16")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_not_cr0_operand" "")
 	(compare:CC
 	 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			 (const_int 0))
@@ -12821,7 +13100,7 @@ 
   "")
 
 (define_insn_and_split "*gtu<mode>_compare"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+  [(set (match_operand:CC 3 "cmpi_cc_reg_operand" "=x,?kcrxx")
 	(compare:CC
 	 (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
 		 (match_operand:P 2 "reg_or_short_operand" "rI,rI"))
@@ -12850,7 +13129,7 @@ 
   "")
 
 (define_insn_and_split "*plus_gtu<mode>_compare"
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
+  [(set (match_operand:CC 4 "cmpi_cc_reg_operand" "=x,x,?kcrxx,?kcrxx")
 	(compare:CC
 	 (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
 			(match_operand:P 2 "reg_or_short_operand" "I,r,I,r"))
@@ -12871,9 +13150,9 @@ 
 (define_insn "*neg_gtu<mode>"
   [(set (match_operand:P 0 "gpc_reg_operand" "=r")
 	(neg:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
-		      (match_operand:P 2 "reg_or_short_operand" "rI"))))]
+		      (match_operand:P 2 "reg_or_short_operand" "rkscI8"))))]
   ""
-  "subf%I2c %0,%1,%2\;subfe %0,%0,%0"
+  "%i2subf%I2c %0,%1,%2\;subfe %0,%0,%0"
   [(set_attr "type" "two")
    (set_attr "length" "8")])
 
@@ -12882,12 +13161,11 @@ 
 ;; register, we'd rather use CR0 since it is much easier to copy a
 ;; register CC value to there.
 
-(define_insn ""
+(define_insn "*cbranch_direct"
   [(set (pc)
 	(if_then_else (match_operator 1 "branch_comparison_operator"
-				      [(match_operand 2
-						      "cc_reg_operand" "y")
-				       (const_int 0)])
+		       [(match_operand 2 "cmpi_cc_reg_operand" "kcrxx")
+			(const_int 0)])
 		      (label_ref (match_operand 0 "" ""))
 		      (pc)))]
   ""
@@ -12897,15 +13175,14 @@ 
 }"
   [(set_attr "type" "branch")])
 
-(define_insn ""
+(define_insn "*creturn_direct"
   [(set (pc)
 	(if_then_else (match_operator 0 "branch_comparison_operator"
-				      [(match_operand 1
-						      "cc_reg_operand" "y")
-				       (const_int 0)])
+		       [(match_operand 1 "cc_reg_operand" "y")
+			(const_int 0)])
 		      (any_return)
 		      (pc)))]
-  "<return_pred>"
+  "!TARGET_VLE && <return_pred>"
   "*
 {
   return output_cbranch (operands[0], NULL, 0, insn);
@@ -12913,12 +13190,11 @@ 
   [(set_attr "type" "jmpreg")
    (set_attr "length" "4")])
 
-(define_insn ""
+(define_insn "*cbranch_reverse"
   [(set (pc)
 	(if_then_else (match_operator 1 "branch_comparison_operator"
-				      [(match_operand 2
-						      "cc_reg_operand" "y")
-				       (const_int 0)])
+		       [(match_operand 2 "cmpi_cc_reg_operand" "kcrxx")
+			(const_int 0)])
 		      (pc)
 		      (label_ref (match_operand 0 "" ""))))]
   ""
@@ -12928,15 +13204,14 @@ 
 }"
   [(set_attr "type" "branch")])
 
-(define_insn ""
+(define_insn "*creturn_reverse"
   [(set (pc)
 	(if_then_else (match_operator 0 "branch_comparison_operator"
-				      [(match_operand 1
-						      "cc_reg_operand" "y")
-				       (const_int 0)])
+		       [(match_operand 1 "cc_reg_operand" "y")
+			(const_int 0)])
 		      (pc)
 		      (any_return)))]
-  "<return_pred>"
+  "!TARGET_VLE && <return_pred>"
   "*
 {
   return output_cbranch (operands[0], NULL, 1, insn);
@@ -12968,7 +13243,7 @@ 
 				       (const_int 0)])])
 		      (const_int 1)))]
   ""
-  "cr%q1 %E0,%j2,%j4"
+  "%^cr%q1 %E0,%j2,%j4"
   [(set_attr "type" "cr_logical,delayed_cr")])
 
 ; Why is the constant -1 here, but 1 in the previous pattern?
@@ -12988,7 +13263,7 @@ 
 				 (const_int 0)])])
 		      (const_int -1)))]
   ""
-  "cr%q1 %E0,%j2,%j4"
+  "%^cr%q1 %E0,%j2,%j4"
   [(set_attr "type" "cr_logical,delayed_cr")])
 
 (define_insn "*cceq_rev_compare"
@@ -13000,7 +13275,7 @@ 
 				       (const_int 0)])
 		      (const_int 0)))]
   ""
-  "crnot %E0,%j1"
+  "%^crnor %E0,%j1,%j1"
   [(set_attr "type" "cr_logical,delayed_cr")])
 
 ;; If we are comparing the result of two comparisons, this can be done
@@ -13063,15 +13338,22 @@ 
   [(set (pc)
 	(label_ref (match_operand 0 "" "")))]
   ""
-  "b %l0"
+  "%^b %l0"
   [(set_attr "type" "branch")])
 
-(define_insn "<return_str>return"
+(define_expand "<return_str>return"
   [(any_return)]
   "<return_pred>"
-  "blr"
-  [(set_attr "type" "jmpreg")])
+  "")
 
+(define_insn "*return"
+  [(any_return)]
+  "<return_pred>"
+  "%+blr"
+  [(set_attr "type" "jmpreg")
+   (set (attr "length") (cond [(eq_attr "is_vle" "yes") (const_int 2)]
+			      (const_int 4)))])
+
 (define_expand "indirect_jump"
   [(set (pc) (match_operand 0 "register_operand" ""))])
 
@@ -13079,8 +13361,8 @@ 
   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
   ""
   "@
-   bctr
-   blr"
+   %+bctr
+   %+blr"
   [(set_attr "type" "jmpreg")])
 
 ;; Table jump for switch statements:
@@ -13131,14 +13413,14 @@ 
    (use (label_ref (match_operand 1 "" "")))]
   ""
   "@
-   bctr
-   blr"
+   %+bctr
+   %+blr"
   [(set_attr "type" "jmpreg")])
 
 (define_insn "nop"
   [(const_int 0)]
   ""
-  "nop")
+  "%+nop")
 
 (define_insn "group_ending_nop"
   [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
@@ -13159,7 +13441,7 @@ 
    (use (match_operand 2 "" ""))	; max iterations
    (use (match_operand 3 "" ""))	; loop level
    (use (match_operand 4 "" ""))]	; label
-  ""
+  "!TARGET_VLE"
   "
 {
   /* Only use this on innermost loops.  */
@@ -13217,9 +13499,9 @@ 
   if (which_alternative != 0)
     return \"#\";
   else if (get_attr_length (insn) == 4)
-    return \"bdnz %l0\";
+    return \"%^bdnz %l0\";
   else
-    return \"bdz $+8\;b %l0\";
+    return \"%^bdz $+8\;%^b %l0\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "*,12,16,16")])
@@ -13241,9 +13523,9 @@ 
   if (which_alternative != 0)
     return \"#\";
   else if (get_attr_length (insn) == 4)
-    return \"bdz %l0\";
+    return \"%^bdz %l0\";
   else
-    return \"bdnz $+8\;b %l0\";
+    return \"%^bdnz $+8\;%^b %l0\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "*,12,16,16")])
@@ -13267,9 +13549,9 @@ 
   if (which_alternative != 0)
     return \"#\";
   else if (get_attr_length (insn) == 4)
-    return \"bdz %l0\";
+    return \"%^bdz %l0\";
   else
-    return \"bdnz $+8\;b %l0\";
+    return \"%^bdnz $+8\;%^b %l0\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "*,12,16,16")])
@@ -13291,9 +13573,9 @@ 
   if (which_alternative != 0)
     return \"#\";
   else if (get_attr_length (insn) == 4)
-    return \"bdnz %l0\";
+    return \"%^bdnz %l0\";
   else
-    return \"bdz $+8\;b %l0\";
+    return \"%^bdz $+8\;%^b %l0\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "*,12,16,16")])
@@ -13370,12 +13652,13 @@ 
 
 (define_insn ""
   [(trap_if (match_operator 0 "ordered_comparison_operator"
-                            [(match_operand:GPR 1 "register_operand" "r")
-                             (match_operand:GPR 2 "reg_or_short_operand" "rI")])
+                            [(match_operand:GPR 1 "register_operand" "r,r")
+                             (match_operand:GPR 2 "reg_or_short_operand" "r,I")])
 	    (const_int 0))]
   ""
   "t<wd>%V0%I2 %1,%2"
-  [(set_attr "type" "trap")])
+  [(set_attr "type" "trap")
+   (set_attr "isa" "*,novle")])
 
 ;; Insns related to generating the function prologue and epilogue.
 
@@ -13426,7 +13709,7 @@ 
 		   [(set (match_operand:SI 1 "memory_operand" "=m")
        			 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
   "TARGET_MULTIPLE"
-  "stmw %2,%1"
+  "%^stmw %2,%1"
   [(set_attr "type" "store_ux")])
 
 ; The following comment applies to:
@@ -13452,7 +13735,7 @@ 
 		    (set (match_operand:P 2 "memory_operand" "=m")
 			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
   ""
-  "bl %1"
+  "%^bl %1"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
 
@@ -13464,7 +13747,7 @@ 
 		    (set (match_operand:P 2 "memory_operand" "=m")
 			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
   ""
-  "bl %1"
+  "%^bl %1"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
 
@@ -13585,7 +13868,7 @@ 
 		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
        			 (match_operand:SI 2 "memory_operand" "m"))])]
   "TARGET_MULTIPLE"
-  "lmw %1,%2"
+  "%^lmw %1,%2"
   [(set_attr "type" "load_ux")
    (set_attr "cell_micro" "always")])
 
@@ -13593,8 +13876,10 @@ 
   [(simple_return)
    (use (match_operand:P 0 "register_operand" "lc"))]
   ""
-  "b%T0"
-  [(set_attr "type" "jmpreg")])
+  "%+b%T0"
+  [(set_attr "type" "jmpreg")
+   (set (attr "length") (cond [(eq_attr "is_vle" "yes") (const_int 2)]
+			      (const_int 4)))])
 
 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
@@ -13622,7 +13907,7 @@ 
 		   (set (match_operand:P 3 "gpc_reg_operand" "=r")
 			(match_operand:P 4 "memory_operand" "m"))])]
  ""
- "bl %2"
+ "%^bl %2"
  [(set_attr "type" "branch")
   (set_attr "length" "4")])
 
@@ -13659,7 +13944,7 @@ 
 		   (set (match_operand:P 3 "gpc_reg_operand" "=r")
 			(match_operand:P 4 "memory_operand" "m"))])]
  ""
- "b %2"
+ "%^b %2"
  [(set_attr "type" "branch")
   (set_attr "length" "4")])
 
@@ -13672,7 +13957,7 @@ 
 		   (set (match_operand:P 3 "gpc_reg_operand" "=r")
 			(match_operand:P 4 "memory_operand" "m"))])]
  ""
- "b %2"
+ "%^b %2"
  [(set_attr "type" "branch")
   (set_attr "length" "4")])
 
Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(revision 191665)
+++ gcc/config/rs6000/rs6000-c.c	(working copy)
@@ -382,6 +382,23 @@ 
   /* Used by libstdc++.  */
   if (TARGET_NO_LWSYNC)
     builtin_define ("__NO_LWSYNC__");
+  if (TARGET_VLE)
+    {
+      builtin_define ("__VLE__");
+      builtin_define ("__PPCVLE__");
+    }
+  if (rs6000_cpu == PROCESSOR_PPCE200Z0)
+    builtin_define ("__PPCE200Z0__");
+  if (rs6000_cpu == PROCESSOR_PPCE200Z1)
+    builtin_define ("__PPCE200Z1__");
+  if (rs6000_cpu == PROCESSOR_PPCE200Z2)
+    builtin_define ("__PPCE200Z2__");
+  if (rs6000_cpu == PROCESSOR_PPCE200Z3)
+    builtin_define ("__PPCE200Z3__");
+  if (rs6000_cpu == PROCESSOR_PPCE200Z6)
+    builtin_define ("__PPCE200Z6__");
+  if (rs6000_cpu == PROCESSOR_PPCE200Z7)
+    builtin_define ("__PPCE200Z7__");
 
   if (TARGET_EXTRA_BUILTINS)
     {
Index: gcc/config/rs6000/rs6000.opt
===================================================================
--- gcc/config/rs6000/rs6000.opt	(revision 191665)
+++ gcc/config/rs6000/rs6000.opt	(working copy)
@@ -130,6 +130,10 @@ 
 Target Report Mask(ALTIVEC) Save
 Use AltiVec instructions
 
+mvle
+Target Report Var(rs6000_vle) Save
+Use VLE instructions
+
 mhard-dfp
 Target Report Mask(DFP) Save
 Use decimal floating point instructions
Index: gcc/config/rs6000/eabivle.h
===================================================================
--- gcc/config/rs6000/eabivle.h	(revision 0)
+++ gcc/config/rs6000/eabivle.h	(revision 0)
@@ -0,0 +1,69 @@ 
+/* Core target definitions for GNU compiler
+   for IBM RS/6000 PowerPC targeted to embedded ELF systems.
+   Copyright (C) 2012
+   Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+/* Add -meabi to target flags.  */
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_EABI)
+
+/* Enable VLE insns.  */
+#undef TARGET_VLE
+#define TARGET_VLE rs6000_vle
+
+/* Invoke an initializer function to set up the GOT.  */
+
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS()          \
+  do                                      \
+    {                                     \
+      builtin_define_std ("PPC");         \
+      builtin_define ("__embedded__");    \
+      builtin_define ("__PPC_EABI__");    \
+      builtin_assert ("system=embedded"); \
+      builtin_assert ("cpu=powerpc");     \
+      builtin_assert ("machine=powerpc"); \
+      TARGET_OS_SYSV_CPP_BUILTINS ();     \
+    }                                     \
+  while (0)
+
+#undef CC1_EXTRA_SPEC
+#define CC1_EXTRA_SPEC							\
+" %{mcpu=e200z0: -mvle -misel -mno-mfcrf -mmultiple -msoft-float;"	\
+  " mcpu=e200z1: -mvle -misel -mno-mfcrf -mmultiple -msoft-float;"	\
+  " mcpu=e200z2: -mvle -misel -mno-mfcrf -mmultiple -msoft-float;"	\
+  " mcpu=e200z3: -mvle -misel -mno-mfcrf -mmultiple -mfloat-gprs=single -mspe=yes -mabi=spe;"	\
+  " mcpu=e200z6: -mvle -misel -mno-mfcrf -mmultiple -mfloat-gprs=single -mspe=yes -mabi=spe;"	\
+  " mcpu=e200z7: -mvle -misel -mno-mfcrf -mmultiple -mfloat-gprs=single -mspe=yes -mabi=spe}"
+
+#undef ASM_DEFAULT_SPEC
+#define ASM_DEFAULT_SPEC	\
+  "%{mcpu=e200z0: -mvle;	\
+     mcpu=e200z1: -mvle;	\
+     mcpu=e200z2: -mvle;	\
+     mcpu=e200z3: -mvle;	\
+     mcpu=e200z6: -mvle;	\
+     mcpu=e200z7: -mvle;	\
+     :-mppc%{m64:64}}"
+
+/* Disable paging by default.  This can still be overridden with
+   -Wl,--no-omagic,-Bdynamic that'll make GCC pass --no-omagic -Bdynamic
+   to the linker after -n implied here.  */
+#undef LINK_OS_DEFAULT_SPEC
+#define LINK_OS_DEFAULT_SPEC "%{n:; N:; :-n}"
Index: gcc/config/rs6000/rs6000-cpus.def
===================================================================
--- gcc/config/rs6000/rs6000-cpus.def	(revision 191665)
+++ gcc/config/rs6000/rs6000-cpus.def	(working copy)
@@ -67,6 +67,12 @@ 
 RS6000_CPU ("a2", PROCESSOR_PPCA2,
 	    MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB | MASK_CMPB
 	    | MASK_NO_UPDATE)
+RS6000_CPU ("e200z0", PROCESSOR_PPCE200Z0, POWERPC_E200_MASK | MASK_SOFT_FLOAT)
+RS6000_CPU ("e200z1", PROCESSOR_PPCE200Z1, POWERPC_E200_MASK | MASK_SOFT_FLOAT)
+RS6000_CPU ("e200z2", PROCESSOR_PPCE200Z2, POWERPC_E200_MASK | MASK_SOFT_FLOAT)
+RS6000_CPU ("e200z3", PROCESSOR_PPCE200Z3, POWERPC_E200_MASK)
+RS6000_CPU ("e200z6", PROCESSOR_PPCE200Z6, POWERPC_E200_MASK)
+RS6000_CPU ("e200z7", PROCESSOR_PPCE200Z7, POWERPC_E200_MASK)
 RS6000_CPU ("e300c2", PROCESSOR_PPCE300C2, MASK_SOFT_FLOAT)
 RS6000_CPU ("e300c3", PROCESSOR_PPCE300C3, 0)
 RS6000_CPU ("e500mc", PROCESSOR_PPCE500MC, MASK_PPC_GFXOPT | MASK_ISEL)
Index: gcc/config/rs6000/rs6000-opts.h
===================================================================
--- gcc/config/rs6000/rs6000-opts.h	(revision 191665)
+++ gcc/config/rs6000/rs6000-opts.h	(working copy)
@@ -47,6 +47,12 @@ 
    PROCESSOR_PPC7450,
    PROCESSOR_PPC8540,
    PROCESSOR_PPC8548,
+   PROCESSOR_PPCE200Z0,
+   PROCESSOR_PPCE200Z1,
+   PROCESSOR_PPCE200Z2,
+   PROCESSOR_PPCE200Z3,
+   PROCESSOR_PPCE200Z6,
+   PROCESSOR_PPCE200Z7,
    PROCESSOR_PPCE300C2,
    PROCESSOR_PPCE300C3,
    PROCESSOR_PPCE500MC,
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
--- gcc/config/rs6000/rs6000-protos.h	(revision 191665)
+++ gcc/config/rs6000/rs6000-protos.h	(working copy)
@@ -47,6 +47,8 @@ 
 extern bool legitimate_indirect_address_p (rtx, int);
 extern bool legitimate_indexed_address_p (rtx, int);
 extern bool avoiding_indexed_address_p (enum machine_mode);
+extern bool valid_vle_sd4_field (rtx, enum machine_mode);
+extern bool valid_sci8_immediate (HOST_WIDE_INT);
 
 extern rtx rs6000_got_register (rtx);
 extern rtx find_addr_reg (rtx);
@@ -123,7 +125,7 @@ 
 extern rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode,
 						    int, int, int, int *);
 extern bool rs6000_legitimate_offset_address_p (enum machine_mode, rtx,
-						bool, bool);
+						bool, bool, bool);
 extern rtx rs6000_find_base_term (rtx);
 extern rtx rs6000_return_addr (int, rtx);
 extern void rs6000_output_symbol_ref (FILE*, rtx);
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 191665)
+++ gcc/doc/invoke.texi	(working copy)
@@ -803,6 +803,7 @@ 
 -mcmodel=@var{code-model} @gol
 -mpowerpc64 @gol
 -maltivec  -mno-altivec @gol
+-mvle -mno-vle @gol
 -mpowerpc-gpopt  -mno-powerpc-gpopt @gol
 -mpowerpc-gfxopt  -mno-powerpc-gfxopt @gol
 -mmfcrf  -mno-mfcrf  -mpopcntb  -mno-popcntb -mpopcntd -mno-popcntd @gol
@@ -16757,7 +16758,8 @@ 
 @samp{476}, @samp{476fp}, @samp{505}, @samp{601}, @samp{602}, @samp{603},
 @samp{603e}, @samp{604}, @samp{604e}, @samp{620}, @samp{630}, @samp{740},
 @samp{7400}, @samp{7450}, @samp{750}, @samp{801}, @samp{821}, @samp{823},
-@samp{860}, @samp{970}, @samp{8540}, @samp{a2}, @samp{e300c2},
+@samp{860}, @samp{970}, @samp{8540}, @samp{a2}, @samp{e200z0}, @samp{e200z1},
+@samp{e200z2}, @samp{e200z3}, @samp{e200z6}, @samp{e200z7}, @samp{e300c2},
 @samp{e300c3}, @samp{e500mc}, @samp{e500mc64}, @samp{e5500},
 @samp{e6500}, @samp{ec603e}, @samp{G3}, @samp{G4}, @samp{G5},
 @samp{titan}, @samp{power3}, @samp{power4}, @samp{power5}, @samp{power5+},
@@ -16779,7 +16781,7 @@ 
 @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}
+-msimple-fpu -mstring  -mmulhw  -mdlmzb  -mmfpgpr -mvle -mvsx}
 
 The particular options set for any particular CPU varies between
 compiler versions, depending on what setting seems to produce optimal
@@ -16830,6 +16832,21 @@ 
 @option{-mabi=altivec} to adjust the current ABI with AltiVec ABI
 enhancements.
 
+@item -mvle
+@itemx -mno-vle
+@opindex mvle
+@opindex mno-vle
+Generate code that uses (does not use) VLE (Variable Length Encoding)
+instructions.
+Options @option{-mcpu=e200z0}, @option{-mcpu=e200z1} and @option{-mcpu=e200z2}
+set @option{-mvle}, @option{-misel}, @option{-mno-mfcrf},
+@option{-mmultiple} and @option{-msoft-float}
+by default.
+Options @option{-mcpu=e200z3}, @option{-mcpu=e200z6} and @option{-mcpu=e200z7}
+set @option{-mvle}, @option{-misel}, @option{-mno-mfcrf}, @option{-mmultiple},
+@option{-mfloat-gprs=single}, @option{-mspe=yes} and @option{-mabi=spe}
+by default.
+
 @item -mvrsave
 @itemx -mno-vrsave
 @opindex mvrsave
Index: gcc/config.gcc
===================================================================
--- gcc/config.gcc	(revision 191665)
+++ gcc/config.gcc	(working copy)
@@ -1954,6 +1954,12 @@ 
 	tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
 	use_gcc_stdint=wrap
 	;;
+powerpc-*-eabivle*)
+	tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabivle.h rs6000/e500.h"
+	extra_options="${extra_options} rs6000/sysv4.opt"
+	tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm rs6000/t-eabivle"
+	use_gcc_stdint=wrap
+	;;
 powerpc-*-elf*)
 	tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h"
 	extra_options="${extra_options} rs6000/sysv4.opt"
Index: gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc/testsuite/lib/target-supports.exp	(revision 191665)
+++ gcc/testsuite/lib/target-supports.exp	(working copy)
@@ -1869,7 +1869,8 @@ 
 	set et_vect_int_saved 0
 	if { [istarget i?86-*-*]
              || ([istarget powerpc*-*-*]
-                  && ![istarget powerpc-*-linux*paired*])
+                  && ![istarget powerpc-*-linux*paired*]
+		  && ![check_effective_target_power_vle])
 	      || [istarget spu-*-*]
 	      || [istarget x86_64-*-*]
 	      || [istarget sparc*-*-*]
@@ -2501,7 +2502,8 @@ 
 
 proc check_effective_target_powerpc_altivec_ok { } {
     if { ([istarget powerpc*-*-*]
-         && ![istarget powerpc-*-linux*paired*])
+          && ![istarget powerpc-*-linux*paired*]
+	  && ![check_effective_target_power_vle])
 	 || [istarget rs6000-*-*] } {
 	# AltiVec is not supported on AIX before 5.3.
 	if { [istarget powerpc*-*-aix4*]
@@ -2639,6 +2641,15 @@ 
     }
 }
 
+# Return 1 if this is a Power target using VLE instructions.
+proc check_effective_target_power_vle { } {
+    return [check_no_compiler_messages vle assembly {
+	#ifndef __VLE__
+	#error FOO
+	#endif
+    }]
+}
+
 # Return 1 if this is a SPU target with a toolchain that
 # supports automatic overlay generation.
 
@@ -2789,7 +2800,8 @@ 
     } else {
 	set et_vect_float_saved 0
 	if { [istarget i?86-*-*]
-	      || [istarget powerpc*-*-*]
+	      || ([istarget powerpc*-*-*]
+		  && ![check_effective_target_power_vle])
 	      || [istarget spu-*-*]
 	      || [istarget mipsisa64*-*-*]
 	      || [istarget x86_64-*-*]
Index: libgcc/config/rs6000/tramp.S
===================================================================
--- libgcc/config/rs6000/tramp.S	(revision 191665)
+++ libgcc/config/rs6000/tramp.S	(working copy)
@@ -29,8 +29,84 @@ 
 #include "ppc-asm.h"
 #include "config.h"
 
-#ifndef __powerpc64__
+#ifdef __VLE__
 	.type	trampoline_initial,@object
+	.align	1
+trampoline_initial:
+	se_mflr	r0
+	se_bl	1f
+.Lfunc = .-trampoline_initial
+	.long	0			/* will be replaced with function address */
+.Lchain = .-trampoline_initial
+	.long	0			/* will be replaced with static chain */
+1:	mflr	r11
+	se_mtlr	r0	
+	e_lwz	r0,0(r11)		/* function address */
+	e_lwz	r11,4(r11)		/* static chain */
+	se_mtctr	r0
+	se_bctr
+	se_nop				/* Bump initialization size to 32.  */
+
+trampoline_size = .-trampoline_initial
+	.size	trampoline_initial,trampoline_size
+
+
+/* R3 = stack address to store trampoline */
+/* R4 = length of trampoline area */
+/* R5 = function address */
+/* R6 = static chain */
+
+FUNC_START(__trampoline_setup)
+	se_mflr	r0		/* save return address */
+	se_bl	.LCF0		/* load up __trampoline_initial into r7 */
+.LCF0:
+        mflr	r11
+        e_add16i r7,r11,trampoline_initial-4-.LCF0 /* trampoline address -4 */
+
+	e_li	r8,trampoline_size	/* verify that the trampoline is big enough */
+	cmpw	cr1,r8,r4
+	e_srwi	r4,r4,2		/* # words to move */
+	e_add16i r9,r3,-4	/* adjust pointer for lwzu */
+	se_mtctr r4
+	e_blt	cr1,.Labort
+
+	se_mtlr	r0
+
+	/* Copy the instructions to the stack */
+.Lmove:
+	e_lwzu	r10,4(r7)
+	e_stwu	r10,4(r9)
+	e_bdnz	.Lmove
+
+	/* Store correct function and static chain */
+	e_stw	r5,.Lfunc(r3)
+	e_stw	r6,.Lchain(r3)
+
+	/* Now flush both caches */
+	se_mtctr r4
+.Lcache:
+	icbi	0,r3
+	dcbf	0,r3
+	e_add16i r3,r3,4
+	e_bdnz	.Lcache
+
+	/* Finally synchronize things & return */
+	sync
+	se_isync
+	se_blr
+
+.Labort:
+#if (defined __PIC__ || defined __pic__) && defined HAVE_AS_REL16
+	se_bl	1f
+1:	se_mflr	r30
+	e_add2is r30,_GLOBAL_OFFSET_TABLE_-1b@ha
+	e_add16i r30,r30,_GLOBAL_OFFSET_TABLE_-1b@l
+#endif
+	e_bl	JUMP_TARGET(abort)
+FUNC_END(__trampoline_setup)
+
+#elif !defined (__powerpc64__)
+	.type	trampoline_initial,@object
 	.align	2
 trampoline_initial:
 	mflr	r0
Index: libgcc/config/rs6000/sol-ci.S
===================================================================
--- libgcc/config/rs6000/sol-ci.S	(revision 191665)
+++ libgcc/config/rs6000/sol-ci.S	(working copy)
@@ -27,7 +27,7 @@ 
  
 	.ident	"GNU C scrti.s"
 
-#ifndef __powerpc64__
+#if !defined (__powerpc64__) && !defined (__VLE__)
 # Start of .text
 	.section ".text"
 	.globl	_ex_text0
Index: libgcc/config/rs6000/eabi-ci.S
===================================================================
--- libgcc/config/rs6000/eabi-ci.S	(revision 191665)
+++ libgcc/config/rs6000/eabi-ci.S	(working copy)
@@ -23,6 +23,8 @@ 
 
 /* This file just supplies labeled starting points for the .got* and other
    special sections.  It is linked in first before other modules.  */
+
+#include "ppc-asm.h"
  
 	.ident	"GNU C crti.s"
 
@@ -99,15 +101,15 @@ 
 	.section ".init","ax"
 	.align 2
 FUNC_START(__init)
-	stwu 1,-16(1)
-	mflr 0
-	stw 0,20(1)
+	STWU 1,-16(1)
+	MFLR 0
+	STW 0,20(1)
 
 /* Head of __fini function used for static destructors.  */
 	.section ".fini","ax"
 	.align 2
 FUNC_START(__fini)
-	stwu 1,-16(1)
-	mflr 0
-	stw 0,20(1)
+	STWU 1,-16(1)
+	MFLR 0
+	STW 0,20(1)
 #endif
Index: libgcc/config/rs6000/sol-cn.S
===================================================================
--- libgcc/config/rs6000/sol-cn.S	(revision 191665)
+++ libgcc/config/rs6000/sol-cn.S	(working copy)
@@ -27,7 +27,7 @@ 
  
 	.ident	"GNU C scrtn.s"
 
-#ifndef __powerpc64__
+#if !defined (__powerpc64__) && !defined (__VLE__)
 # Default versions of exception handling register/deregister
 	.weak	_ex_register
 	.weak	_ex_deregister
Index: libgcc/config/rs6000/eabi-cn.S
===================================================================
--- libgcc/config/rs6000/eabi-cn.S	(revision 191665)
+++ libgcc/config/rs6000/eabi-cn.S	(working copy)
@@ -26,6 +26,8 @@ 
  
 	.ident	"GNU C crtn.s"
 
+#include "ppc-asm.h"
+
 #ifndef __powerpc64__
 	.section ".got","aw"
 	.globl	__GOT_END__
@@ -90,15 +92,15 @@ 
 
 /* Tail of __init function used for static constructors.  */
 	.section ".init","ax"
-	lwz 0,20(1)
-	mtlr 0
-	addi 1,1,16
-	blr
+	LWZ 0,20(1)
+	MTLR 0
+	ADD16I 1,1,16
+	BLR
 
 /* Tail of __fini function used for static destructors.  */
 	.section ".fini","ax"
-	lwz 0,20(1)
-	mtlr 0
-	addi 1,1,16
-	blr
+	LWZ 0,20(1)
+	MTLR 0
+	ADD16I 1,1,16
+	BLR
 #endif
Index: libgcc/config/rs6000/crtresxfpr.S
===================================================================
--- libgcc/config/rs6000/crtresxfpr.S	(revision 191665)
+++ libgcc/config/rs6000/crtresxfpr.S	(working copy)
@@ -32,7 +32,7 @@ 
 	#include "ppc-asm.h"
 
 /* On PowerPC64 Linux, these functions are provided by the linker.  */
-#ifndef __powerpc64__
+#if !defined (__powerpc64__) && !defined(__VLE__)
 
 /* Routines for restoring floating point registers, called by the compiler.  */
 /* Called with r11 pointing to the stack header word of the caller of the */
Index: libgcc/config/rs6000/crtresxgpr.S
===================================================================
--- libgcc/config/rs6000/crtresxgpr.S	(revision 191665)
+++ libgcc/config/rs6000/crtresxgpr.S	(working copy)
@@ -59,48 +59,48 @@ 
 CFI_OFFSET (29, -12)
 CFI_OFFSET (30, -8)
 CFI_OFFSET (31, -4)
-HIDDEN_FUNC(_restgpr_14_x)	lwz	14,-72(11)	/* restore gp registers */
+HIDDEN_FUNC(_restgpr_14_x)	LWZ	14,-72(11)	/* restore gp registers */
 CFI_RESTORE (14)
-HIDDEN_FUNC(_restgpr_15_x)	lwz	15,-68(11)
+HIDDEN_FUNC(_restgpr_15_x)	LWZ	15,-68(11)
 CFI_RESTORE (15)
-HIDDEN_FUNC(_restgpr_16_x)	lwz	16,-64(11)
+HIDDEN_FUNC(_restgpr_16_x)	LWZ	16,-64(11)
 CFI_RESTORE (16)
-HIDDEN_FUNC(_restgpr_17_x)	lwz	17,-60(11)
+HIDDEN_FUNC(_restgpr_17_x)	LWZ	17,-60(11)
 CFI_RESTORE (17)
-HIDDEN_FUNC(_restgpr_18_x)	lwz	18,-56(11)
+HIDDEN_FUNC(_restgpr_18_x)	LWZ	18,-56(11)
 CFI_RESTORE (18)
-HIDDEN_FUNC(_restgpr_19_x)	lwz	19,-52(11)
+HIDDEN_FUNC(_restgpr_19_x)	LWZ	19,-52(11)
 CFI_RESTORE (19)
-HIDDEN_FUNC(_restgpr_20_x)	lwz	20,-48(11)
+HIDDEN_FUNC(_restgpr_20_x)	LWZ	20,-48(11)
 CFI_RESTORE (20)
-HIDDEN_FUNC(_restgpr_21_x)	lwz	21,-44(11)
+HIDDEN_FUNC(_restgpr_21_x)	LWZ	21,-44(11)
 CFI_RESTORE (21)
-HIDDEN_FUNC(_restgpr_22_x)	lwz	22,-40(11)
+HIDDEN_FUNC(_restgpr_22_x)	LWZ	22,-40(11)
 CFI_RESTORE (22)
-HIDDEN_FUNC(_restgpr_23_x)	lwz	23,-36(11)
+HIDDEN_FUNC(_restgpr_23_x)	LWZ	23,-36(11)
 CFI_RESTORE (23)
-HIDDEN_FUNC(_restgpr_24_x)	lwz	24,-32(11)
+HIDDEN_FUNC(_restgpr_24_x)	LWZ	24,-32(11)
 CFI_RESTORE (24)
-HIDDEN_FUNC(_restgpr_25_x)	lwz	25,-28(11)
+HIDDEN_FUNC(_restgpr_25_x)	LWZ	25,-28(11)
 CFI_RESTORE (25)
-HIDDEN_FUNC(_restgpr_26_x)	lwz	26,-24(11)
+HIDDEN_FUNC(_restgpr_26_x)	LWZ	26,-24(11)
 CFI_RESTORE (26)
-HIDDEN_FUNC(_restgpr_27_x)	lwz	27,-20(11)
+HIDDEN_FUNC(_restgpr_27_x)	LWZ	27,-20(11)
 CFI_RESTORE (27)
-HIDDEN_FUNC(_restgpr_28_x)	lwz	28,-16(11)
+HIDDEN_FUNC(_restgpr_28_x)	LWZ	28,-16(11)
 CFI_RESTORE (28)
-HIDDEN_FUNC(_restgpr_29_x)	lwz	29,-12(11)
+HIDDEN_FUNC(_restgpr_29_x)	LWZ	29,-12(11)
 CFI_RESTORE (29)
-HIDDEN_FUNC(_restgpr_30_x)	lwz	30,-8(11)
+HIDDEN_FUNC(_restgpr_30_x)	LWZ	30,-8(11)
 CFI_RESTORE (30)
-HIDDEN_FUNC(_restgpr_31_x)	lwz	0,4(11)
-				lwz	31,-4(11)
+HIDDEN_FUNC(_restgpr_31_x)	LWZ	0,4(11)
+				LWZ	31,-4(11)
 CFI_RESTORE (31)
-				mtlr	0
+				MTLR	0
 CFI_RESTORE (65)
-				mr	1,11
+				MFAR	1,11
 CFI_DEF_CFA_REGISTER (1)
-				blr
+				BLR
 FUNC_END(_restgpr_31_x)
 FUNC_END(_restgpr_30_x)
 FUNC_END(_restgpr_29_x)
Index: libgcc/config/rs6000/crtresfpr.S
===================================================================
--- libgcc/config/rs6000/crtresfpr.S	(revision 191665)
+++ libgcc/config/rs6000/crtresfpr.S	(working copy)
@@ -32,7 +32,7 @@ 
 	#include "ppc-asm.h"
 
 /* On PowerPC64 Linux, these functions are provided by the linker.  */
-#ifndef __powerpc64__
+#if !defined (__powerpc64__) && !defined (__VLE__)
 
 /* Routines for restoring floating point registers, called by the compiler.  */
 /* Called with r11 pointing to the stack header word of the caller of the */
Index: libgcc/config/rs6000/crtsavfpr.S
===================================================================
--- libgcc/config/rs6000/crtsavfpr.S	(revision 191665)
+++ libgcc/config/rs6000/crtsavfpr.S	(working copy)
@@ -32,7 +32,7 @@ 
 	#include "ppc-asm.h"
 
 /* On PowerPC64 Linux, these functions are provided by the linker.  */
-#ifndef __powerpc64__
+#if !defined (__powerpc64__) && !defined (__VLE__)
 
 /* Routines for saving floating point registers, called by the compiler.  */
 /* Called with r11 pointing to the stack header word of the caller of the */
Index: libgcc/config/rs6000/crtresgpr.S
===================================================================
--- libgcc/config/rs6000/crtresgpr.S	(revision 191665)
+++ libgcc/config/rs6000/crtresgpr.S	(working copy)
@@ -39,25 +39,25 @@ 
 /* function, just beyond the end of the integer restore area.  */
 
 CFI_STARTPROC
-HIDDEN_FUNC(_restgpr_14)	lwz	14,-72(11)	/* restore gp registers */
-HIDDEN_FUNC(_restgpr_15)	lwz	15,-68(11)
-HIDDEN_FUNC(_restgpr_16)	lwz	16,-64(11)
-HIDDEN_FUNC(_restgpr_17)	lwz	17,-60(11)
-HIDDEN_FUNC(_restgpr_18)	lwz	18,-56(11)
-HIDDEN_FUNC(_restgpr_19)	lwz	19,-52(11)
-HIDDEN_FUNC(_restgpr_20)	lwz	20,-48(11)
-HIDDEN_FUNC(_restgpr_21)	lwz	21,-44(11)
-HIDDEN_FUNC(_restgpr_22)	lwz	22,-40(11)
-HIDDEN_FUNC(_restgpr_23)	lwz	23,-36(11)
-HIDDEN_FUNC(_restgpr_24)	lwz	24,-32(11)
-HIDDEN_FUNC(_restgpr_25)	lwz	25,-28(11)
-HIDDEN_FUNC(_restgpr_26)	lwz	26,-24(11)
-HIDDEN_FUNC(_restgpr_27)	lwz	27,-20(11)
-HIDDEN_FUNC(_restgpr_28)	lwz	28,-16(11)
-HIDDEN_FUNC(_restgpr_29)	lwz	29,-12(11)
-HIDDEN_FUNC(_restgpr_30)	lwz	30,-8(11)
-HIDDEN_FUNC(_restgpr_31)	lwz	31,-4(11)
-			blr
+HIDDEN_FUNC(_restgpr_14)	LWZ	14,-72(11)	/* restore gp registers */
+HIDDEN_FUNC(_restgpr_15)	LWZ	15,-68(11)
+HIDDEN_FUNC(_restgpr_16)	LWZ	16,-64(11)
+HIDDEN_FUNC(_restgpr_17)	LWZ	17,-60(11)
+HIDDEN_FUNC(_restgpr_18)	LWZ	18,-56(11)
+HIDDEN_FUNC(_restgpr_19)	LWZ	19,-52(11)
+HIDDEN_FUNC(_restgpr_20)	LWZ	20,-48(11)
+HIDDEN_FUNC(_restgpr_21)	LWZ	21,-44(11)
+HIDDEN_FUNC(_restgpr_22)	LWZ	22,-40(11)
+HIDDEN_FUNC(_restgpr_23)	LWZ	23,-36(11)
+HIDDEN_FUNC(_restgpr_24)	LWZ	24,-32(11)
+HIDDEN_FUNC(_restgpr_25)	LWZ	25,-28(11)
+HIDDEN_FUNC(_restgpr_26)	LWZ	26,-24(11)
+HIDDEN_FUNC(_restgpr_27)	LWZ	27,-20(11)
+HIDDEN_FUNC(_restgpr_28)	LWZ	28,-16(11)
+HIDDEN_FUNC(_restgpr_29)	LWZ	29,-12(11)
+HIDDEN_FUNC(_restgpr_30)	LWZ	30,-8(11)
+HIDDEN_FUNC(_restgpr_31)	LWZ	31,-4(11)
+			BLR
 FUNC_END(_restgpr_31)
 FUNC_END(_restgpr_30)
 FUNC_END(_restgpr_29)
Index: libgcc/config/rs6000/crtsavgpr.S
===================================================================
--- libgcc/config/rs6000/crtsavgpr.S	(revision 191665)
+++ libgcc/config/rs6000/crtsavgpr.S	(working copy)
@@ -39,25 +39,25 @@ 
 /* function, just beyond the end of the integer save area.  */
 
 CFI_STARTPROC
-HIDDEN_FUNC(_savegpr_14)	stw	14,-72(11)	/* save gp registers */
-HIDDEN_FUNC(_savegpr_15)	stw	15,-68(11)
-HIDDEN_FUNC(_savegpr_16)	stw	16,-64(11)
-HIDDEN_FUNC(_savegpr_17)	stw	17,-60(11)
-HIDDEN_FUNC(_savegpr_18)	stw	18,-56(11)
-HIDDEN_FUNC(_savegpr_19)	stw	19,-52(11)
-HIDDEN_FUNC(_savegpr_20)	stw	20,-48(11)
-HIDDEN_FUNC(_savegpr_21)	stw	21,-44(11)
-HIDDEN_FUNC(_savegpr_22)	stw	22,-40(11)
-HIDDEN_FUNC(_savegpr_23)	stw	23,-36(11)
-HIDDEN_FUNC(_savegpr_24)	stw	24,-32(11)
-HIDDEN_FUNC(_savegpr_25)	stw	25,-28(11)
-HIDDEN_FUNC(_savegpr_26)	stw	26,-24(11)
-HIDDEN_FUNC(_savegpr_27)	stw	27,-20(11)
-HIDDEN_FUNC(_savegpr_28)	stw	28,-16(11)
-HIDDEN_FUNC(_savegpr_29)	stw	29,-12(11)
-HIDDEN_FUNC(_savegpr_30)	stw	30,-8(11)
-HIDDEN_FUNC(_savegpr_31)	stw	31,-4(11)
-			blr
+HIDDEN_FUNC(_savegpr_14)	STW	14,-72(11)	/* save gp registers */
+HIDDEN_FUNC(_savegpr_15)	STW	15,-68(11)
+HIDDEN_FUNC(_savegpr_16)	STW	16,-64(11)
+HIDDEN_FUNC(_savegpr_17)	STW	17,-60(11)
+HIDDEN_FUNC(_savegpr_18)	STW	18,-56(11)
+HIDDEN_FUNC(_savegpr_19)	STW	19,-52(11)
+HIDDEN_FUNC(_savegpr_20)	STW	20,-48(11)
+HIDDEN_FUNC(_savegpr_21)	STW	21,-44(11)
+HIDDEN_FUNC(_savegpr_22)	STW	22,-40(11)
+HIDDEN_FUNC(_savegpr_23)	STW	23,-36(11)
+HIDDEN_FUNC(_savegpr_24)	STW	24,-32(11)
+HIDDEN_FUNC(_savegpr_25)	STW	25,-28(11)
+HIDDEN_FUNC(_savegpr_26)	STW	26,-24(11)
+HIDDEN_FUNC(_savegpr_27)	STW	27,-20(11)
+HIDDEN_FUNC(_savegpr_28)	STW	28,-16(11)
+HIDDEN_FUNC(_savegpr_29)	STW	29,-12(11)
+HIDDEN_FUNC(_savegpr_30)	STW	30,-8(11)
+HIDDEN_FUNC(_savegpr_31)	STW	31,-4(11)
+			BLR
 FUNC_END(_savegpr_31)
 FUNC_END(_savegpr_30)
 FUNC_END(_savegpr_29)
Index: libgcc/longlong.h
===================================================================
--- libgcc/longlong.h	(revision 191665)
+++ libgcc/longlong.h	(working copy)
@@ -849,7 +849,8 @@ 
    system vendor compilers.
    FIXME: What's needed for gcc PowerPC VxWorks?  __vxworks__ is not good
    enough, since that hits ARM and m68k too.  */
-#if (defined (_ARCH_PPC)	/* AIX */				\
+#if !defined (__VLE__)							\
+    && (defined (_ARCH_PPC)	/* AIX */				\
      || defined (__powerpc__)	/* gcc */				\
      || defined (__POWERPC__)	/* BEOS */				\
      || defined (__ppc__)	/* Darwin */				\