Sophie

Sophie

distrib > Mandriva > 2009.0 > i586 > by-pkgid > 2aa29a72bfe83e0109f283c71247f237 > files > 18

gcc4.2-4.2.3-6mnb2.src.rpm

2006-10-24  Gwenole Beauchesne  <gbeauchesne@mandriva.com>

	* config/rs6000/rs6000.c (rs6000_override_options): Add
	MASK_ALTIVEC to Cell target flags (through POWERPC_7400_MASK).
	Rename the target option to "cell".

2006-10-23  Gwenole Beauchesne  <gbeauchesne@mandriva.com>

	* config/rs6000/rs6000.c (rs6000_override_options): Don't override
	rs6000_gen_microcode if the user set it from command line.
	* config/rs6000/rs6000.md: Rework conditions to avoid generation
	of microcoded instructions. Fix ICE when -m32 -mno-gen-microcode
	are used altogether with a 64-bit compiler. Fix typos. Add extra
	"mc" notes.

2006-10-12  Gwenole Beauchesne  <gbeauchesne@mandriva.com>

	* Merge PPU code from SCEI / BSC source tree.

--- gcc-4.2.0/gcc/config/rs6000/rs6000.opt.cell-ppu-sched	2007-06-01 17:11:36.000000000 +0200
+++ gcc-4.2.0/gcc/config/rs6000/rs6000.opt	2007-06-04 14:06:28.000000000 +0200
@@ -245,3 +245,15 @@
 mprioritize-restricted-insns=
 Target RejectNegative Joined UInteger Var(rs6000_sched_restricted_insns_priority)
 Specify scheduling priority for dispatch slot restricted insns
+
+mgen-microcode
+Target Var(rs6000_gen_microcode) Init(-1)
+Generate microcoded instructions
+
+mwarn-microcode
+Target Var(rs6000_warn_microcode) Init(0)
+Warn about microcoded instructions
+
+mhint=
+Target RejectNegative Joined
+Specify static prediction hint bits as always/never/likely
\ No newline at end of file
--- gcc-4.2.0/gcc/config/rs6000/rs6000.c.cell-ppu-sched	2007-06-01 17:11:36.000000000 +0200
+++ gcc-4.2.0/gcc/config/rs6000/rs6000.c	2007-06-04 16:01:11.000000000 +0200
@@ -63,6 +63,7 @@
 #if TARGET_MACHO
 #include "gstab.h"  /* for N_SLINE */
 #endif
+#include "c-common.h"	/* CELL LOCAL */
 
 #ifndef TARGET_NO_PROTOTYPE
 #define TARGET_NO_PROTOTYPE 0
@@ -139,8 +140,14 @@
   { (const char *)0,	"-mtune=",		1,	0 },
 };
 
-/* Always emit branch hint bits.  */
-static GTY(()) bool rs6000_always_hint;
+/* Specify when branch hint bits are emitted.  */
+enum rs6000_hint_t {
+  hint_likely, /* only if one direction is very likely */
+  hint_always,
+  hint_never
+};
+const char *rs6000_hint_str;
+static GTY(()) enum rs6000_hint_t rs6000_hint;
 
 /* Schedule instructions for group formation.  */
 static GTY(()) bool rs6000_sched_groups;
@@ -572,6 +579,21 @@
   COSTS_N_INSNS (17),   /* ddiv */
 };
 
+/* Instruction costs on Cell processors.  */
+static const
+struct processor_costs cellbe_cost = {
+  COSTS_N_INSNS (5),    /* mulsi */
+  COSTS_N_INSNS (4),    /* mulsi_const */
+  COSTS_N_INSNS (3),    /* mulsi_const9 */
+  COSTS_N_INSNS (7),    /* muldi */
+  COSTS_N_INSNS (21),   /* divsi */
+  COSTS_N_INSNS (37),   /* divdi */
+  COSTS_N_INSNS (3),    /* fp */
+  COSTS_N_INSNS (3),    /* dmul */
+  COSTS_N_INSNS (17),   /* sdiv */
+  COSTS_N_INSNS (21),   /* ddiv */
+};
+
 
 static bool rs6000_function_ok_for_sibcall (tree, tree);
 static const char *rs6000_invalid_within_doloop (rtx);
@@ -647,6 +669,9 @@
 static bool rs6000_rtx_costs (rtx, int, int, int *);
 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
 static bool is_microcoded_insn (rtx);
+/* CELL LOCAL Begin */
+static bool is_nonpipeline_insn (rtx);
+/* CELL LOCAL End */
 static int is_dispatch_slot_restricted (rtx);
 static bool is_cracked_insn (rtx);
 static bool is_branch_slot_insn (rtx);
@@ -662,6 +687,11 @@
 static void rs6000_sched_finish (FILE *, int);
 static int rs6000_use_sched_lookahead (void);
 static tree rs6000_builtin_mask_for_load (void);
+/* CELL LOCAL Begin */
+static int rs6000_use_sched_lookahead_guard (rtx);
+/* FIXME */
+static int rs6000_sched_reorder(FILE *, int, rtx *, int *, int);
+/* CELL LOCAL End */
 
 static void def_builtin (int, const char *, tree, int);
 static void rs6000_init_builtins (void);
@@ -895,6 +925,17 @@
 #undef TARGET_ASM_FUNCTION_EPILOGUE
 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
 
+/* CELL LOCAL Begin */
+#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
+
+#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
+
+#undef TARGET_SCHED_REORDER
+#define TARGET_SCHED_REORDER rs6000_sched_reorder
+/* CELL LOCAL End */
+
 #undef  TARGET_SCHED_VARIABLE_ISSUE
 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
 
@@ -1043,6 +1084,12 @@
 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
 
+/* CELL LOCAL Begin */
+static void rs6000_machine_dependent_reorg (void);
+#undef TARGET_MACHINE_DEPENDENT_REORG
+#define TARGET_MACHINE_DEPENDENT_REORG rs6000_machine_dependent_reorg
+/* CELL LOCAL END */
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 
@@ -1200,6 +1247,8 @@
 	 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
 	 {"powerpc64", PROCESSOR_POWERPC64,
 	  POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
+	 {"cell", PROCESSOR_CELLPPU,
+	  POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
 	 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
 	 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
 	 {"rios2", PROCESSOR_RIOS2,
@@ -1398,11 +1447,21 @@
 	rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
     }
 
-  rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
-			&& rs6000_cpu != PROCESSOR_POWER5);
+  rs6000_hint = (rs6000_cpu != PROCESSOR_POWER4
+		 && rs6000_cpu != PROCESSOR_POWER5
+		 && rs6000_cpu != PROCESSOR_CELLPPU)
+     ? hint_always
+     : hint_likely;
+
   rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
 			 || rs6000_cpu == PROCESSOR_POWER5);
 
+  if (rs6000_gen_microcode == -1)
+    {
+      rs6000_gen_microcode = (rs6000_cpu != PROCESSOR_CELLPPU
+			      || optimize_size);
+    }
+
   rs6000_sched_restricted_insns_priority
     = (rs6000_sched_groups ? 1 : 0);
 
@@ -1569,6 +1628,10 @@
 	rs6000_cost = &power4_cost;
 	break;
 
+      case PROCESSOR_CELLPPU:
+	rs6000_cost = &cellbe_cost;
+	break;
+
       default:
 	gcc_unreachable ();
       }
@@ -1900,6 +1963,15 @@
       rs6000_sched_costly_dep_str = arg;
       break;
 
+    case OPT_mhint_:
+      if (! strcmp (arg, "never"))
+	rs6000_hint = hint_never;
+      else if (! strcmp (arg, "likely"))
+	rs6000_hint = hint_likely;
+      else if (! strcmp (arg, "always"))
+	rs6000_hint = hint_always;
+      break;
+
     case OPT_malign_:
       rs6000_explicit_options.alignment = true;
       if (! strcmp (arg, "power"))
@@ -3861,20 +3933,33 @@
 	  if (ud1 != 0)
 	    emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
 	}
+       /* CELL LOCAL Begin */
+      else if (ud4 == 0 && ud3 == 0 && (ud2 & 0x8000) && ! (ud1 & 0x8000))
+	{
+	  /* addi tgt,r0,ud1 ; oris tgt,tgt,ud2 */
+	  emit_move_insn (dest, GEN_INT (ud1));
+	  if (ud2 != 0)
+	    emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2 << 16)));
+	}
+      /* CELL LOCAL End */
       else if ((ud4 == 0xffff && (ud3 & 0x8000))
 	       || (ud4 == 0 && ! (ud3 & 0x8000)))
 	{
+
+	  /* CELL LOCAL Begin */
 	  if (ud3 & 0x8000)
-	    emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
-					   - 0x80000000));
+	    emit_move_insn (dest, GEN_INT (((ud3) ^ 0x8000) 
+					   - 0x8000));
 	  else
-	    emit_move_insn (dest, GEN_INT (ud3 << 16));
+	    emit_move_insn (dest, GEN_INT (ud3));
 
+	  if (ud3 != 0)
+	    emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
 	  if (ud2 != 0)
-	    emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
-	  emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
+	    emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2 << 16)));
 	  if (ud1 != 0)
 	    emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
+	  /* CELL LOCAL End */
 	}
       else
 	{
@@ -11557,7 +11642,8 @@
 	 assume not taken for branches that are very close to 50% as a
 	 mispredicted taken branch is more expensive than a
 	 mispredicted not-taken branch.  */
-      if (rs6000_always_hint
+      if (rs6000_hint != hint_never)
+      if (rs6000_hint == hint_always
 	  || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
 	      && br_prob_note_reliable_p (note)))
 	{
@@ -16517,6 +16603,12 @@
       || GET_CODE (PATTERN (insn)) == CLOBBER)
     return more;
 
+/* CELL LOCAL Begin */
+  /* if no reservation, but reach here */
+  if (recog_memoized (insn) < 0)
+    return more;
+/* CELL LOCAL End */
+  
   if (rs6000_sched_groups)
     {
       if (is_microcoded_insn (insn))
@@ -16525,6 +16617,11 @@
 	return more > 2 ? more - 2 : 0;
     }
 
+  /* CELL LOCAL Begin */
+  if (rs6000_cpu == PROCESSOR_CELLPPU && is_nonpipeline_insn(insn))
+	return 0;
+  /* CELL LOCAL End */
+
   return more - 1;
 }
 
@@ -16557,6 +16654,13 @@
 
       switch (get_attr_type (insn))
 	{
+	case TYPE_CR_LOGICAL:
+	case TYPE_DELAYED_CR:
+	  return cost + 8;
+	case TYPE_MFJMPR:
+	  if (!(REGNO(XEXP (PATTERN(insn), 0)) == CTR_REGNO 
+		|| REGNO(XEXP (PATTERN(insn), 0)) == LR_REGNO))
+	    return 30;
 	case TYPE_JMPREG:
 	  /* Tell the first scheduling pass about the latency between
 	     a mtctr and bctr (and mtlr and br/blr).  The first
@@ -16575,6 +16679,7 @@
 	       || rs6000_cpu_attr == CPU_PPC750
 	       || rs6000_cpu_attr == CPU_PPC7400
 	       || rs6000_cpu_attr == CPU_PPC7450
+	       || rs6000_cpu_attr == CPU_CELL	/* CELL LOCAL */
 	       || rs6000_cpu_attr == CPU_POWER4
 	       || rs6000_cpu_attr == CPU_POWER5)
 	      && recog_memoized (dep_insn)
@@ -16611,17 +16716,55 @@
   if (rs6000_sched_groups)
     {
       enum attr_type type = get_attr_type (insn);
-      if (type == TYPE_LOAD_EXT_U
-	  || type == TYPE_LOAD_EXT_UX
-	  || type == TYPE_LOAD_UX
-	  || type == TYPE_STORE_UX
-	  || type == TYPE_MFCR)
-	return true;
+      /* CELL LOCAL Begin */
+      if (rs6000_cpu == PROCESSOR_CELLPPU) 
+        {
+          if (get_attr_microcode(insn) == MICROCODE_MC)
+	    return true;
+	}
+      else 
+      /* CELL LOCAL End */
+	{
+          if (type == TYPE_LOAD_EXT_U
+	    || type == TYPE_LOAD_EXT_UX
+	    || type == TYPE_LOAD_UX
+	    || type == TYPE_STORE_UX
+	    || type == TYPE_MFCR)
+	  return true;
+	}
     }
 
   return false;
 }
 
+/* CELL LOCAL Begin */
+static bool 
+is_nonpipeline_insn (rtx insn)
+{
+  enum attr_type type;
+  if (!insn || !INSN_P (insn)
+      || GET_CODE (PATTERN (insn)) == USE
+      || GET_CODE (PATTERN (insn)) == CLOBBER)
+    return false;
+
+  type = get_attr_type (insn);
+  if (type == TYPE_IMUL 
+      || type == TYPE_IMUL2 
+      || type == TYPE_IMUL3 
+      || type == TYPE_LMUL
+      || type == TYPE_IDIV 
+      || type == TYPE_LDIV 
+      || type == TYPE_SDIV
+      || type == TYPE_DDIV
+      || type == TYPE_SSQRT
+      || type == TYPE_MFJMPR)
+    {
+      return true;
+    }
+  return false;
+}
+/* CELL LOCAL End */
+ 
 /* The function returns a nonzero value if INSN can be scheduled only
    as the first insn in a dispatch group ("dispatch-slot restricted").
    In this case, the returned value indicates how many dispatch slots
@@ -16685,6 +16828,17 @@
   if (rs6000_sched_groups)
     {
       enum attr_type type = get_attr_type (insn);
+     
+      /* CELL LOCAL Begin */
+      if (rs6000_cpu == PROCESSOR_CELLPPU)
+        {
+          if (type == TYPE_LOAD_U
+            || type == TYPE_LOAD_UX
+            )
+          return true;
+        }
+      /* CELL LOCAL End */
+      
       if (type == TYPE_LOAD_U || type == TYPE_STORE_U
 	  || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
 	  || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
@@ -16803,6 +16957,7 @@
   case CPU_PPC750:
   case CPU_PPC7400:
   case CPU_PPC8540:
+  case CPU_CELL:	/* CELL LOCAL */
     return 2;
   case CPU_RIOS2:
   case CPU_PPC604:
@@ -16826,8 +16981,78 @@
 {
   if (rs6000_cpu_attr == CPU_PPC8540)
     return 4;
+  /* CELL LOCAL Begin */
+  else if (rs6000_cpu_attr == CPU_CELL)
+    return (reload_completed ? 4 : 0);
+  /* CELL LOCAL End */
   return 0;
 }
+/* CELL LOCAL Begin */
+
+/* We are choosing insn from the ready queue.  Return nonzero if INSN  can be chosen.  */
+static int
+rs6000_use_sched_lookahead_guard (rtx insn)
+{
+  if (rs6000_cpu_attr != CPU_CELL)
+    return 0;
+
+   if (insn == NULL_RTX || !INSN_P (insn))
+     abort ();
+   
+  if (!reload_completed || is_nonpipeline_insn(insn) || is_microcoded_insn(insn))
+    return 0;
+
+  return 1;
+}
+
+/* Resort the array A in which only element at index N may be out of order.  */
+
+static inline  void
+swap (rtx *a, int n)
+{
+  rtx insn = a[n - 1];
+  int i = n - 2;
+
+  while (i >= 0 )
+    {
+      a[i + 1] = a[i];
+      i -= 1;
+     }
+   a[i + 1] = insn;
+}
+
+/* CELLPU, if the top priority is nonepipeline insn, try to swap with other ready insn*/
+static int 
+rs6000_sched_reorder(FILE *dump ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, rtx *ready, int *pn_ready, int clock ATTRIBUTE_UNUSED)
+{
+  int n_ready = *pn_ready;
+  /* reorder the ready list, if the first ready insn is nonepipeline insn */ 
+  if (rs6000_cpu == PROCESSOR_CELLPPU && n_ready > 1)
+  {
+    if (is_nonpipeline_insn(ready[n_ready-1]) && (recog_memoized (ready[n_ready-2])>0))
+    /*simply swap first two */
+      swap ((ready+n_ready-2),2); 
+  }
+  
+  return rs6000_issue_rate();
+}
+
+static inline bool
+long_latency_pipeline_insn(rtx insn)
+{
+  if (!insn || !INSN_P (insn)
+      || GET_CODE (PATTERN (insn)) == USE
+      || GET_CODE (PATTERN (insn)) == CLOBBER)
+    return false;
+  return (get_attr_type(insn) == TYPE_FP 
+	|| get_attr_type(insn) == TYPE_VECCOMPLEX 
+	|| get_attr_type(insn) == TYPE_VECFLOAT);
+}
+static void 
+rs6000_machine_dependent_reorg(void)
+{
+}
+/* CELL LOCAL END */
 
 /* Determine is PAT refers to memory.  */
 
@@ -18692,6 +18917,24 @@
     {
       /* On the RS/6000, if it is valid in the insn, it is free.  */
     case CONST_INT:
+      /* CELL LOCAL Begin */
+      /* CELL FIXME: Check to see if this CELL specific code lifted from
+	 a 3.4.1 code base works with the 4.0.x code below
+
+      /* A CONST_INT that is too large will be split into multiple
+       * insns. */
+      *total = 0;
+#if HOST_BITS_PER_WIDE_INT != 32
+      *total += ((INTVAL (x) & (~ (HOST_WIDE_INT) 0xffffffff)) != 0)
+		? COSTS_N_INSNS (2)
+		: 0;
+#endif
+      *total += ((INTVAL (x) & (~ (HOST_WIDE_INT) 0xffff)) != 0
+		 && ((INTVAL (x) & 0xffff) != 0))
+		? COSTS_N_INSNS (1)
+		: 0;
+      /* CELL LOCAL End */
+
       if (((outer_code == SET
 	    || outer_code == PLUS
 	    || outer_code == MINUS)
--- /dev/null	2007-06-04 14:06:28.000000000 +0200
+++ gcc-4.2.0/gcc/config/rs6000/cellbe.md	2007-06-04 14:06:28.000000000 +0200
@@ -0,0 +1,331 @@
+;; Scheduling description for cell processors.
+
+;; (C) Copyright
+;; Sony Computer Entertainment, Inc.,
+;; Toshiba Corporation,
+;; International Business Machines Corporation,
+;; 2001,2002,2003,2004,2005.
+
+;; This file 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 2 of the License, or (at your option) 
+;; any later version.
+
+;; This file 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 this file; see the file COPYING.  If not, write to the Free
+;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;; Sources: BE BOOK4 (/sfs/enc/doc/PPU_BookIV_DD3.0_latest.pdf)
+
+;; BE Architechture *DD3.0 and DD3.1*
+;; This file simulate PPU processor unit backend of pipeline, maualP24. 
+;; manual P27, stall and flush points
+;; IU, XU, VSU, dipatcher decodes and dispatch 2 insns per cycle in program order, the grouped adress are aligned by 8
+;; This file only simulate one thread situation
+;; XU executes all fixed point insns(3 units, a simple alu, a complex unit, and load/store unit)
+;; VSU executes all scalar floating points insn(a float unit), VMX insns(VMX unit, 4 sub units, simple, permute, complex, floating point)
+
+;; Dual issue combination
+
+;;	FXU	LSU	BR 	VMX(sx,cx,vsu_fp,fp_arith)	VMX(perm,vsu_ls,fp_ls)
+;;FXU	X
+
+;;LSU		X               	X               	X	
+
+;;BR			X
+
+;;VMX(sx,cx,vsu_fp,fp_arth)		X
+
+;;VMX(perm,vsu_ls, fp_ls)					X
+
+;; Dual issue exceptons: 
+;;(1) nop-pipelined FXU instr in slot 0 
+;;(2) non-pipelined FPU inst in slot 0
+;; CSI instr(contex-synchronizing insn)
+;; Microcode insn
+
+;; BRU unit: bru(none register stall), bru_cr(cr register stall)
+;; VSU unit: vus(vmx simple), vup(vmx permute), vuc(vmx complex), vuf(vmx float), fpu(floats). fpu_div is hypthetical, it is for nonpipelined simulation
+;; micr insns will stall at least 7 cycles to get the first instr from ROM, micro instructions are not dual issued. 
+
+;; slot0 is older than slot1
+;; non-pipelined insn need to be in slot1 to avoid 1cycle stall
+
+;; There different stall point
+;; IB2, only stall one thread if stall here, so try to stall here as much as we can 
+;; condition(1) insert nop, OR and ORI instruction form 
+;; condition(2) flush happens, in case of: RAW, WAW, D-ERAT miss, or CR0-access while stdcx, or stwcx
+;; IS2 stall ;; Page91 for details
+;; VQ8 stall
+;; IS2 stall can be activated by VQ8 stall and trying to issue a vsu instr to the vsu issue queue
+
+;;(define_automaton "cellxu")
+
+;;(define_cpu_unit "fxu_sim_cell,fxu_mul_div_cell,lsu_cell,bru_cell,bru_cr_cell,vsu1_cell,vsu2_cell" "cellxu")
+
+;; ndfa
+(define_automaton "cellxu,cellvsu,cellbru")
+
+(define_cpu_unit "fxu_sim_cell,fxu_mul_div_cell,lsu_cell" "cellxu")
+(define_cpu_unit "bru_cell,bru_cr_cell" "cellbru")
+(define_cpu_unit "vsu1_cell,vsu2_cell" "cellvsu")
+
+
+(automata_option "v")
+(automata_option "progress")
+(automata_option "time")
+
+(exclusion_set "fxu_sim_cell" "fxu_mul_div_cell")
+(exclusion_set "bru_cell" "bru_cr_cell")
+
+(define_reservation "nonpipeline" "fxu_mul_div_cell+lsu_cell+vsu1_cell+vsu2_cell")
+
+;; Load/store
+;;lmw, lswi, lswx are only generated for optimize for space, MC, these instr are not simulated
+(define_insn_reservation "cell-load" 2
+  (and (eq_attr "type" "load")
+       (eq_attr "cpu" "cell"))
+  "lsu_cell")
+
+;;ldux,ldu,lbzux,lbzu, hardware breaks it down to two instrs,if with 32bytes alignment,CMC
+(define_insn_reservation "cell-load-ux" 2
+  (and (eq_attr "type" "load_ux,load_u")
+       (eq_attr "cpu" "cell"))
+  "fxu_sim_cell+lsu_cell")
+
+;;lha,lhax,lhau,lhaux,lwa,lwax,lwaux, MC, latency unknow 11/7, 11/8, 11/12
+(define_insn_reservation "cell-load-ext" 2
+  (and (eq_attr "type" "load_ext,load_ext_u,load_ext_ux")
+       (eq_attr "cpu" "cell"))
+  "fxu_sim_cell+lsu_cell")
+
+;;lfs,lfsx,lfd,lfdx, 1 cycle
+(define_insn_reservation "cell-fpload" 1
+  (and (eq_attr "type" "fpload")
+       (eq_attr "cpu" "cell"))
+  "vsu2_cell+lsu_cell")
+
+;; lfsu,lfsux,lfdu,lfdux 1cycle(fpr) 2 cycle(gpr)
+(define_insn_reservation "cell-fpload-update" 1
+  (and (eq_attr "type" "fpload,fpload_u,fpload_ux")
+       (eq_attr "cpu" "cell"))
+  "fxu_sim_cell+vsu2_cell+lsu_cell")
+
+(define_insn_reservation "cell-vecload" 2
+  (and (eq_attr "type" "vecload")
+       (eq_attr "cpu" "cell"))
+  "vsu2_cell+lsu_cell")
+
+;;st? stw(MC)
+(define_insn_reservation "cell-store" 1
+  (and (eq_attr "type" "store")
+       (eq_attr "cpu" "cell"))
+  "lsu_cell")
+
+;;stdux, stdu, (hardware breaks into store and add) 2 for update reg
+(define_insn_reservation "cell-store-update" 1
+  (and (eq_attr "type" "store_ux,store_u")
+       (eq_attr "cpu" "cell"))
+  "fxu_sim_cell+lsu_cell")
+
+(define_insn_reservation "cell-fpstore" 1
+  (and (eq_attr "type" "fpstore")
+       (eq_attr "cpu" "cell"))
+  "vsu2_cell+lsu_cell")
+
+(define_insn_reservation "cell-fpstore-update" 1
+  (and (eq_attr "type" "fpstore_ux,fpstore_u")
+       (eq_attr "cpu" "cell"))
+  "vsu2_cell+fxu_sim_cell+lsu_cell")
+
+(define_insn_reservation "cell-vecstore" 1
+  (and (eq_attr "type" "vecstore")
+       (eq_attr "cpu" "cell"))
+  "vsu2_cell+lsu_cell")
+
+;; Integer latency is 2 cycles
+(define_insn_reservation "cell-integer" 2
+  (and (eq_attr "type" "integer")
+       (eq_attr "cpu" "cell"))
+  "fxu_sim_cell")
+
+;; rlwimi, alter cr0  
+(define_insn_reservation "cell-insert" 2
+  (and (eq_attr "type" "insert_word")
+       (eq_attr "cpu" "cell"))
+ "fxu_sim_cell")
+
+;; cmpi, cmpli, cmpla, add, addo, sub, subo, alter cr0 
+(define_insn_reservation "cell-cmp" 1
+  (and (eq_attr "type" "cmp,fast_compare")
+       (eq_attr "cpu" "cell"))
+  "fxu_sim_cell")
+
+;; add, addo, sub, subo, alter cr0, rldcli, rlwinm 
+(define_insn_reservation "cell-fast-cmp" 2
+  (and (eq_attr "type" "compare,fast_compare,delayed_compare")
+       (eq_attr "cpu" "cell"))
+  "fxu_sim_cell")
+
+;; mulld
+(define_insn_reservation "cell-lmul-cmp" 15
+  (and (eq_attr "type" "lmul,lmul_compare")
+       (eq_attr "cpu" "cell"))
+  "nonpipeline,nonpipeline*14")
+
+;; mulli, 8 cycles, not simulated
+(define_insn_reservation "cell-imul" 10
+  (and (eq_attr "type" "imul,imul2,imul3")
+       (eq_attr "cpu" "cell"))
+  "nonpipeline,nonpipeline*9")
+ 
+;; divide
+(define_insn_reservation "cell-idiv" 32
+  (and (eq_attr "type" "idiv")
+       (eq_attr "cpu" "cell"))
+  "nonpipeline,nonpipeline*31")
+
+(define_insn_reservation "cell-ldiv" 64
+  (and (eq_attr "type" "ldiv")
+       (eq_attr "cpu" "cell"))
+  "nonpipeline,nonpipeline*63")
+
+;;mflr mfctr other spr are non-pipelined,
+(define_insn_reservation "cell-mfjmpr" 2
+  (and (eq_attr "type" "mfjmpr")
+       (eq_attr "cpu" "cell"))
+  "bru_cell*2")
+
+;;mtlr, mtctr,
+;;mtspr fully pipelined 
+(define_insn_reservation "cell-mtjmpr" 1
+ (and (eq_attr "type" "mtjmpr")
+       (eq_attr "cpu" "cell"))
+  "bru_cell")
+
+;; Branches
+;; b, ba, bl, bla, unconditional branch always predicts correctly n/a latency
+;; bcctr, bcctrl, latency 2, actually adjust by be to 4
+(define_insn_reservation "cell-branch" 1
+  (and (eq_attr "type" "branch")
+       (eq_attr "cpu" "cell"))
+  "bru_cell")
+
+(define_insn_reservation "cell-branchreg" 1
+  (and (eq_attr "type" "jmpreg")
+       (eq_attr "cpu" "cell"))
+  "bru_cell")
+
+;; cr hazard
+;; page 90, special cases for CR hazard, only one instr can access cr per cycle
+;; if insn reads CR following a stwcx, pipeline stall till stwcx finish
+(define_insn_reservation "cell-crlogical" 1
+  (and (eq_attr "type" "cr_logical,delayed_cr")
+       (eq_attr "cpu" "cell"))
+  "bru_cr_cell")
+
+(define_insn_reservation "cell-mfcr" 34
+  (and (eq_attr "type" "mfcr")
+       (eq_attr "cpu" "cell"))
+   "bru_cr_cell,bru_cr_cell*33")
+
+; mtcrf (1 field)
+(define_insn_reservation "cell-mtcrf" 1
+  (and (eq_attr "type" "mtcr")
+       (eq_attr "cpu" "cell"))
+  "fxu_sim_cell")
+
+
+; Basic FP latency is 10 cycles, thoughput is 1/cycle
+(define_insn_reservation "cell-fp" 10
+  (and (eq_attr "type" "fp,dmul")
+       (eq_attr "cpu" "cell"))
+  "vsu1_cell")
+
+(define_insn_reservation "cell-fpcompare" 1
+  (and (eq_attr "type" "fpcompare")
+       (eq_attr "cpu" "cell"))
+  "vsu1_cell")
+
+;; sdiv thoughput 1/69, not pipelined, 
+(define_insn_reservation "cell-sdiv" 69
+  (and (eq_attr "type" "sdiv,ddiv")
+       (eq_attr "cpu" "cell"))
+  "vsu1_cell, vsu1_cell*68")
+
+;; fsqrt thoughput 1/79, not pipelined
+(define_insn_reservation "cell-sqrt" 79
+  (and (eq_attr "type" "ssqrt,dsqrt")
+       (eq_attr "cpu" "cell"))
+ "vsu1_cell, vsu1_cell*78")
+
+; VMX
+(define_insn_reservation "cell-vecsimple" 4
+  (and (eq_attr "type" "vecsimple")
+       (eq_attr "cpu" "cell"))
+  "vsu1_cell")
+
+;; mult, div, madd
+(define_insn_reservation "cell-veccomplex" 10
+  (and (eq_attr "type" "veccomplex")
+       (eq_attr "cpu" "cell"))
+  "vsu1_cell")
+
+(define_insn_reservation "cell-veccmp" 4
+  (and (eq_attr "type" "veccmp")
+       (eq_attr "cpu" "cell"))
+  "vsu1_cell")
+
+(define_insn_reservation "cell-vecfloat" 12
+  (and (eq_attr "type" "vecfloat")
+       (eq_attr "cpu" "cell"))
+  "vsu1_cell")
+
+(define_insn_reservation "cell-vecperm" 4
+  (and (eq_attr "type" "vecperm")
+       (eq_attr "cpu" "cell"))
+  "vsu2_cell")
+
+;; (define_bypass cycle "out-insns" "in-insns" [guards])
+;; number defines when the result generated by the instructions given in string out_insn_names will be ready for the instructions given in string in_insn_names. The instructions in the string are separated by commas.
+
+;; RAW register dependency
+
+;; addi r3, r3, 1
+;; lw r4,offset(r3)
+;; there are 5 cycle deplay for r3 bypassing
+;; there are 5 cycle delay for a dependent load after a load
+(define_bypass 5 "cell-integer" "cell-load")
+(define_bypass 5 "cell-integer" "cell-load-ext")
+(define_bypass 5 "cell-load,cell-load-ext" "cell-load,cell-load-ext")
+
+;; VXU float RAW
+(define_bypass 11 "cell-vecfloat" "cell-vecfloat")
+
+;; VXU and FPU
+(define_bypass 6 "cell-veccomplex" "cell-vecsimple")
+(define_bypass 3 "cell-vecfloat" "cell-veccomplex")
+(define_bypass 13 "cell-vecstore" "cell-fpstore")
+(define_bypass 7 "cell-fp" "cell-fpload")
+;; vsu1 should avoid writing to the same target register as vsu2 insn within 12 cycles. 
+ 
+;; WAW hazard
+
+;; the target of VSU estimate should not be reused within 10 dispatch groups
+;; the target of VSU float should not be reused within 8 dispatch groups
+;; the target of VSU complex should not be reused within 5 dispatch groups
+;; FP LOAD should not reuse an FPU Arithmetic target with 6 dispatch gropus
+
+;; mtctr-bcctr/bcctrl, branch target ctr register shadow update at ex4 stage(10 cycles)
+(define_bypass 10 "cell-mtjmpr" "cell-branchreg")
+
+;;Things are not simulated:
+;;update instruction, update address gpr are not simulated
+;;vrefp, vrsqrtefp have latency(14), currently simluated as 12cycle float insns
+
--- gcc-4.2.0/gcc/config/rs6000/rs6000.md.cell-ppu-sched	2007-06-01 17:11:36.000000000 +0200
+++ gcc-4.2.0/gcc/config/rs6000/rs6000.md	2007-06-04 16:18:30.000000000 +0200
@@ -106,9 +106,13 @@
 ;; Processor type -- this attribute must exactly match the processor_type
 ;; enumeration in rs6000.h.
 
-(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,power4,power5"
+(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,cell,power4,power5"
   (const (symbol_ref "rs6000_cpu_attr")))
 
+;; not microcode, conditional microcode, microcode
+(define_attr "microcode" "nmc, cmc, mc"
+  (const_string "nmc"))
+
 (automata_option "ndfa")
 
 (include "rios1.md")
@@ -122,6 +126,7 @@
 (include "7xx.md")
 (include "7450.md")
 (include "8540.md")
+(include "cellbe.md")
 (include "power4.md")
 (include "power5.md")
 
@@ -195,14 +200,16 @@
    rldicl. %2,%1,0,<dbits>
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:DI 2 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 2)
 	(zero_extend:DI (match_dup 1)))
    (set (match_dup 0)
@@ -221,15 +228,17 @@
    rldicl. %0,%1,0,<dbits>
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 2 "cc_reg_operand" "")
 	(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(zero_extend:DI (match_dup 1)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[2], CCmode))"
   [(set (match_dup 0)
 	(zero_extend:DI (match_dup 1)))
    (set (match_dup 2)
@@ -253,14 +262,16 @@
    extsb. %2,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:DI 2 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 2)
 	(sign_extend:DI (match_dup 1)))
    (set (match_dup 0)
@@ -279,15 +290,17 @@
    extsb. %0,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 2 "cc_reg_operand" "")
 	(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(sign_extend:DI (match_dup 1)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[2], CCmode))"
   [(set (match_dup 0)
 	(sign_extend:DI (match_dup 1)))
    (set (match_dup 2)
@@ -302,13 +315,19 @@
   "")
 
 (define_insn ""
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(sign_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+	(sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r")))]
   "TARGET_POWERPC64"
-  "@
-   lha%U1%X1 %0,%1
-   extsh %0,%1"
-  [(set_attr "type" "load_ext,*")])
+  "extsh %0,%1"
+  [(set_attr "type" "integer")])
+
+(define_insn ""
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+	(sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
+  "TARGET_POWERPC64 && rs6000_gen_microcode"
+  "lha%U1%X1 %0,%1"
+  [(set_attr "type" "load_ext")
+   (set_attr "microcode" "mc")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -320,14 +339,16 @@
    extsh. %2,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:DI 2 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 2)
 	(sign_extend:DI (match_dup 1)))
    (set (match_dup 0)
@@ -346,15 +367,17 @@
    extsh. %0,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 2 "cc_reg_operand" "")
 	(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(sign_extend:DI (match_dup 1)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[2], CCmode))"
   [(set (match_dup 0)
 	(sign_extend:DI (match_dup 1)))
    (set (match_dup 2)
@@ -369,13 +392,18 @@
   "")
 
 (define_insn ""
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(sign_extend:DI (match_operand:SI 1 "lwa_operand" "m,r")))]
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+	(sign_extend:DI (match_operand:SI 1 "lwa_mem_operand" "m")))]
+  "TARGET_POWERPC64 && rs6000_gen_microcode"
+  "lwa%U1%X1 %0,%1"
+  [(set_attr "type" "load_ext")
+   (set_attr "microcode" "mc")])
+
+(define_insn ""
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+	(sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")))]
   "TARGET_POWERPC64"
-  "@
-   lwa%U1%X1 %0,%1
-   extsw %0,%1"
-  [(set_attr "type" "load_ext,*")])
+  "extsw %0,%1")
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -387,14 +415,16 @@
    extsw. %2,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:DI 2 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 2)
 	(sign_extend:DI (match_dup 1)))
    (set (match_dup 0)
@@ -413,15 +443,17 @@
    extsw. %0,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 2 "cc_reg_operand" "")
 	(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(sign_extend:DI (match_dup 1)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[2], CCmode))"
   [(set (match_dup 0)
 	(sign_extend:DI (match_dup 1)))
    (set (match_dup 2)
@@ -454,14 +486,16 @@
    {andil.|andi.} %2,%1,0xff
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 ""))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 2)
 	(zero_extend:SI (match_dup 1)))
    (set (match_dup 0)
@@ -480,15 +514,17 @@
    {andil.|andi.} %0,%1,0xff
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 2 "cc_reg_operand" "")
 	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(zero_extend:SI (match_dup 1)))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[2], CCmode))"
   [(set (match_dup 0)
 	(zero_extend:SI (match_dup 1)))
    (set (match_dup 2)
@@ -527,14 +563,16 @@
    extsb. %2,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 ""))]
-  "TARGET_POWERPC && reload_completed"
+  "TARGET_POWERPC && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 2)
 	(sign_extend:SI (match_dup 1)))
    (set (match_dup 0)
@@ -553,15 +591,17 @@
    extsb. %0,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 2 "cc_reg_operand" "")
 	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(sign_extend:SI (match_dup 1)))]
-  "TARGET_POWERPC && reload_completed"
+  "TARGET_POWERPC && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[2], CCmode))"
   [(set (match_dup 0)
 	(sign_extend:SI (match_dup 1)))
    (set (match_dup 2)
@@ -620,14 +660,16 @@
    {andil.|andi.} %2,%1,0xff
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:HI 2 ""))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 2)
 	(zero_extend:HI (match_dup 1)))
    (set (match_dup 0)
@@ -646,15 +688,17 @@
    {andil.|andi.} %0,%1,0xff
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 2 "cc_reg_operand" "")
 	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:HI 0 "gpc_reg_operand" "")
 	(zero_extend:HI (match_dup 1)))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[2], CCmode))"
   [(set (match_dup 0)
 	(zero_extend:HI (match_dup 1)))
    (set (match_dup 2)
@@ -693,14 +737,16 @@
    extsb. %2,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:HI 2 ""))]
-  "TARGET_POWERPC && reload_completed"
+  "TARGET_POWERPC && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 2)
 	(sign_extend:HI (match_dup 1)))
    (set (match_dup 0)
@@ -719,15 +765,17 @@
    extsb. %0,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 2 "cc_reg_operand" "")
 	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:HI 0 "gpc_reg_operand" "")
 	(sign_extend:HI (match_dup 1)))]
-  "TARGET_POWERPC && reload_completed"
+  "TARGET_POWERPC && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[2], CCmode))"
   [(set (match_dup 0)
 	(sign_extend:HI (match_dup 1)))
    (set (match_dup 2)
@@ -788,14 +836,16 @@
    {andil.|andi.} %2,%1,0xffff
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 ""))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 2)
 	(zero_extend:SI (match_dup 1)))
    (set (match_dup 0)
@@ -814,15 +864,17 @@
    {andil.|andi.} %0,%1,0xffff
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 2 "cc_reg_operand" "")
 	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(zero_extend:SI (match_dup 1)))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[2], CCmode))"
   [(set (match_dup 0)
 	(zero_extend:SI (match_dup 1)))
    (set (match_dup 2)
@@ -837,13 +889,19 @@
   "")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+	(sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r")))]
   ""
-  "@
-   lha%U1%X1 %0,%1
-   {exts|extsh} %0,%1"
-  [(set_attr "type" "load_ext,*")])
+  "{exts|extsh} %0,%1"
+  [(set_attr "type" "integer")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+	(sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
+  "rs6000_gen_microcode"
+  "lha%U1%X1 %0,%1"
+  [(set_attr "type" "load_ext")
+   (set_attr "microcode" "mc")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -855,14 +913,16 @@
    {exts.|extsh.} %2,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 ""))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 2)
 	(sign_extend:SI (match_dup 1)))
    (set (match_dup 0)
@@ -881,6 +941,7 @@
    {exts.|extsh.} %0,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 ;; IBM 405 and 440 half-word multiplication operations.
@@ -1415,12 +1476,13 @@
 })
 
 (define_split
-  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 2 "cc_reg_operand" "")
 	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(sign_extend:SI (match_dup 1)))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[2], CCmode))"
   [(set (match_dup 0)
 	(sign_extend:SI (match_dup 1)))
    (set (match_dup 2)
@@ -1498,6 +1560,7 @@
    #
    #"
   [(set_attr "type" "fast_compare,compare,compare,compare")
+   (set_attr "microcode" "mc,mc,*,*")
    (set_attr "length" "4,4,8,8")])
 
 (define_split
@@ -1530,6 +1593,7 @@
    #
    #"
   [(set_attr "type" "fast_compare,compare,compare,compare")
+   (set_attr "microcode" "mc,mc,*,*")
    (set_attr "length" "4,4,8,8")])
 
 (define_split
@@ -1594,6 +1658,7 @@
    nor. %2,%1,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -1620,6 +1685,7 @@
    nor. %0,%1,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -1663,6 +1729,7 @@
    {sf.|subfc.} %3,%2,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_insn ""
@@ -1676,6 +1743,7 @@
    subf. %3,%2,%1
    #"
   [(set_attr "type" "fast_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -1705,6 +1773,7 @@
    {sf.|subfc.} %0,%2,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_insn ""
@@ -1720,6 +1789,7 @@
    subf. %0,%2,%1
    #"
   [(set_attr "type" "fast_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -1895,6 +1965,7 @@
    doz%I2. %3,%1,%2
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -1933,6 +2004,7 @@
    doz%I2. %0,%1,%2
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -2054,6 +2126,7 @@
    neg. %2,%1
    #"
   [(set_attr "type" "fast_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -2080,6 +2153,7 @@
    neg. %0,%1
    #"
   [(set_attr "type" "fast_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -2220,6 +2294,7 @@
    {muls.|mullw.} %3,%1,%2
    #"
   [(set_attr "type" "imul_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -2249,15 +2324,17 @@
    {muls.|mullw.} %3,%1,%2
    #"
   [(set_attr "type" "imul_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			     (match_operand:SI 2 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "! TARGET_POWER && reload_completed"
+  "! TARGET_POWER && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(mult:SI (match_dup 1) (match_dup 2)))
    (set (match_dup 0)
@@ -2278,6 +2355,7 @@
    {muls.|mullw.} %0,%1,%2
    #"
   [(set_attr "type" "imul_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -2309,16 +2387,18 @@
    {muls.|mullw.} %0,%1,%2
    #"
   [(set_attr "type" "imul_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			     (match_operand:SI 2 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(mult:SI (match_dup 1) (match_dup 2)))]
-  "! TARGET_POWER && reload_completed"
+  "! TARGET_POWER && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(mult:SI (match_dup 1) (match_dup 2)))
    (set (match_dup 3)
@@ -2500,13 +2580,14 @@
    (set_attr "length" "8,12")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
 			     (match_operand:GPR 2 "exact_log2_cint_operand"
 			      ""))
 		    (const_int 0)))
    (clobber (match_scratch:GPR 3 ""))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(div:<MODE> (match_dup 1) (match_dup 2)))
    (set (match_dup 0)
@@ -2526,17 +2607,19 @@
    {srai|sra<wd>i} %0,%1,%p2\;{aze.|addze.} %0,%0
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "8,12")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
 			     (match_operand:GPR 2 "exact_log2_cint_operand"
 			      ""))
 		    (const_int 0)))
    (set (match_operand:GPR 0 "gpc_reg_operand" "")
 	(div:GPR (match_dup 1) (match_dup 2)))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(div:<MODE> (match_dup 1) (match_dup 2)))
    (set (match_dup 3)
@@ -2720,31 +2803,51 @@
 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
 ;; those rotate-and-mask operations.  Thus, the AND insns come first.
 
-(define_insn "andsi3"
+(define_expand "andsi3"
+  [(parallel
+    [(set (match_operand:SI 0 "gpc_reg_operand" "")
+	  (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
+		  (match_operand:SI 2 "and_operand" "")))
+    (clobber (match_scratch:CC 3 ""))])]
+  ""
+  "")
+
+(define_insn "andsi3_mc"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
 	(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_microcode"
   "@
    and %0,%1,%2
    {rlinm|rlwinm} %0,%1,0,%m2,%M2
    {andil.|andi.} %0,%1,%b2
    {andiu.|andis.} %0,%1,%u2"
-  [(set_attr "type" "*,*,compare,compare")])
+  [(set_attr "type" "*,*,compare,compare")
+   (set_attr "microcode" "*,*,mc,mc")])
+
+(define_insn "andsi3_nomc"
+  [(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")))
+   (clobber (match_scratch:CC 3 "=X,X"))]
+  "! rs6000_gen_microcode"
+  "@
+   and %0,%1,%2
+   {rlinm|rlwinm} %0,%1,0,%m2,%M2")
 
 ;; Note to set cr's other than cr0 we do the and immediate and then
 ;; the test again -- this avoids a mfcr which on the higher end
 ;; machines causes an execution serialization
 
-(define_insn "*andsi3_internal2"
+(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"))
 		    (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"))]
-  "TARGET_32BIT"
+  "TARGET_32BIT && rs6000_gen_microcode"
   "@
    and. %3,%1,%2
    {andil.|andi.} %3,%1,%b2
@@ -2755,16 +2858,17 @@
    #
    #"
   [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+   (set_attr "microcode" "mc,mc,mc,mc,*,*,*,*")
    (set_attr "length" "4,4,4,4,8,8,8,8")])
 
-(define_insn "*andsi3_internal3"
+(define_insn "*andsi3_internal3_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"))
 		    (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"))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && rs6000_gen_microcode"
   "@
    #
    {andil.|andi.} %3,%1,%b2
@@ -2775,16 +2879,30 @@
    #
    #"
   [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+   (set_attr "microcode" "*,mc,mc,mc,*,*,*,*")
    (set_attr "length" "8,4,4,4,8,8,8,8")])
 
+(define_insn "*andsi3_internal3_nomc"
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
+			    (match_operand:SI 2 "and_operand" "r"))
+		    (const_int 0)))
+   (clobber (match_scratch:SI 3 "=r"))
+   (clobber (match_scratch:CC 4 "=X"))]
+  "! rs6000_gen_microcode"
+  "#"
+  [(set_attr "type" "compare")
+   (set_attr "length" "8")])
+
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
 			     (match_operand:GPR 2 "and_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:GPR 3 ""))
    (clobber (match_scratch:CC 4 ""))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(parallel [(set (match_dup 3)
 		   (and:<MODE> (match_dup 1)
 			       (match_dup 2)))
@@ -2814,7 +2932,7 @@
 		    (const_int 0)))]
   "")
 
-(define_insn "*andsi3_internal4"
+(define_insn "*andsi3_internal4_mc"
   [(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"))
@@ -2823,7 +2941,7 @@
 	(and:SI (match_dup 1)
 		(match_dup 2)))
    (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
-  "TARGET_32BIT"
+  "TARGET_32BIT && rs6000_gen_microcode"
   "@
    and. %0,%1,%2
    {andil.|andi.} %0,%1,%b2
@@ -2834,9 +2952,10 @@
    #
    #"
   [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+   (set_attr "microcode" "mc,mc,mc,mc,*,*,*,*")
    (set_attr "length" "4,4,4,4,8,8,8,8")])
 
-(define_insn "*andsi3_internal5"
+(define_insn "*andsi3_internal5_mc"
   [(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"))
@@ -2845,7 +2964,7 @@
 	(and:SI (match_dup 1)
 		(match_dup 2)))
    (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && rs6000_gen_microcode"
   "@
    #
    {andil.|andi.} %0,%1,%b2
@@ -2856,10 +2975,44 @@
    #
    #"
   [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+   (set_attr "microcode" "*,mc,mc,mc,*,*,*,*")
    (set_attr "length" "8,4,4,4,8,8,8,8")])
 
+(define_insn "*andsi3_internal5_nomc"
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+        (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
+                            (match_operand:SI 2 "and_operand" "r"))
+                    (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+        (and:SI (match_dup 1)
+                (match_dup 2)))
+   (clobber (match_scratch:CC 4 "=X"))]
+  "TARGET_64BIT && ! rs6000_gen_microcode"
+  "#"
+  [(set_attr "type" "compare")
+   (set_attr "length" "8")])
+
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
+        (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                            (match_operand:SI 2 "gpc_reg_operand" ""))
+                    (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+        (and:SI (match_dup 1)
+                (match_dup 2)))
+   (clobber (match_scratch:CC 4 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+                   (and:SI (match_dup 1)
+                           (match_dup 2)))
+              (clobber (match_dup 4))])
+   (set (match_dup 3)
+        (compare:CC (match_dup 0)
+                    (const_int 0)))]
+  "")
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			    (match_operand:SI 2 "and_operand" ""))
 		    (const_int 0)))
@@ -2867,7 +3020,8 @@
 	(and:SI (match_dup 1)
 		(match_dup 2)))
    (clobber (match_scratch:CC 4 ""))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(parallel [(set (match_dup 0)
 		   (and:SI (match_dup 1)
 			   (match_dup 2)))
@@ -2985,6 +3139,7 @@
    %q4. %3,%1,%2
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3014,6 +3169,7 @@
    %q4. %0,%1,%2
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3073,6 +3229,7 @@
    %q4. %3,%2,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3102,6 +3259,7 @@
    %q4. %0,%2,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3139,6 +3297,7 @@
    %q4. %3,%1,%2
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3168,6 +3327,7 @@
    %q4. %0,%1,%2
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3241,6 +3401,7 @@
    maskir. %0,%3,%2
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3279,6 +3440,7 @@
    maskir. %0,%3,%2
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3317,6 +3479,7 @@
    maskir. %0,%3,%2
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3355,6 +3518,7 @@
    maskir. %0,%3,%2
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -3554,6 +3718,75 @@
   return \"rldimi %0,%3,%H1,%H2\";
 }")
 
+(define_insn_and_split "insvdi_internal"
+  [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
+			 (match_operand:SI 1 "const_int_operand" "i")
+			 (match_operand:SI 2 "const_int_operand" "i"))
+	(match_operand:DI 3 "const_int_operand" "i"))
+   (clobber (match_operand:DI 4 "gpc_reg_operand" "=&r"))]
+  "TARGET_POWERPC64"
+  "#"
+  ""
+  [(set (match_dup:DI 4) (match_dup:DI 3))
+   (set (zero_extract:DI (match_dup:DI 0)
+			 (match_dup:SI 1)
+			 (match_dup:SI 2))
+	(match_dup:DI 4))]
+   "")
+
+(define_insn_and_split "insvdi_internal2"
+  [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
+			 (match_operand:SI 1 "const_int_operand" "i")
+			 (match_operand:SI 2 "const_int_operand" "i"))
+	(lshiftrt:DI (match_operand:DI 3 "register_operand" "r")
+	             (match_operand:DI 4 "const_int_operand" "i")))
+   (clobber (match_operand:DI 5 "gpc_reg_operand" "=&r"))]
+  "TARGET_POWERPC64"
+  "#"
+  ""
+  [(set (match_dup:DI 5) (lshiftrt:DI (match_dup:DI 3) (match_dup:DI 4)))
+   (set (zero_extract:DI (match_dup:DI 0)
+			 (match_dup:SI 1)
+			 (match_dup:SI 2))
+	(match_dup:DI 5))]
+   "")
+
+(define_insn_and_split "insvdi_internal3"
+  [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
+			 (match_operand:SI 1 "const_int_operand" "i")
+			 (match_operand:SI 2 "const_int_operand" "i"))
+	(zero_extract:DI (match_operand:DI 3 "gpc_reg_operand" "+r")
+			 (match_operand:SI 4 "const_int_operand" "i")
+			 (match_operand:SI 5 "const_int_operand" "i")))
+   (clobber (match_operand:DI 6 "gpc_reg_operand" "=&r"))]
+  "TARGET_POWERPC64"
+  "#"
+  ""
+  [(set (match_dup:DI 6)
+        (zero_extract:DI (match_dup:DI 3)
+			 (match_dup:SI 4)
+			 (match_dup:SI 5)))
+   (set (zero_extract:DI (match_dup:DI 0)
+			 (match_dup:SI 1)
+			 (match_dup:SI 2))
+	(match_dup:DI 6))]
+   "")
+
+(define_insn_and_split "insvdi_internal4"
+  [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
+			 (match_operand:SI 1 "const_int_operand" "i")
+			 (match_operand:SI 2 "const_int_operand" "i"))
+	(and:DI (match_operand:DI 3 "register_operand" "r")
+	        (match_operand:DI 4 "const_int_operand" "i")))]
+  "TARGET_POWERPC64 && (1 << INTVAL(operands[1])) - 1 == INTVAL(operands[4])"
+  "#"
+  ""
+  [(set (zero_extract:DI (match_dup:DI 0)
+			 (match_dup:SI 1)
+			 (match_dup:SI 2))
+	(match_dup:DI 3))]
+   "")
+
 (define_insn "*insvdi_internal2"
   [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
 			 (match_operand:SI 1 "const_int_operand" "i")
@@ -3674,16 +3907,18 @@
   return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\";
 }"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			 (match_operand:SI 2 "const_int_operand" "")
 			 (match_operand:SI 3 "const_int_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 4 ""))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 4)
 	(zero_extract:SI (match_dup 1) (match_dup 2)
 			 (match_dup 3)))
@@ -3725,17 +3960,19 @@
   return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\";
 }"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 4 "cc_reg_operand" "")
 	(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			 (match_operand:SI 2 "const_int_operand" "")
 			 (match_operand:SI 3 "const_int_operand" ""))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[4], CCmode))"
   [(set (match_dup 0)
 	(zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))
    (set (match_dup 4)
@@ -3769,7 +4006,7 @@
 			 (match_operand:SI 3 "const_int_operand" "i"))
 		    (const_int 0)))
    (clobber (match_scratch:DI 4 "=r"))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && rs6000_gen_microcode"
   "*
 {
   int start = INTVAL (operands[3]) & 63;
@@ -3782,7 +4019,8 @@
   operands[2] = GEN_INT (64 - size);
   return \"rldicl. %4,%1,%3,%2\";
 }"
-  [(set_attr "type" "compare")])
+  [(set_attr "type" "compare")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*extzvdi_internal2"
   [(set (match_operand:CC 4 "gpc_reg_operand" "=x")
@@ -3792,7 +4030,7 @@
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "=r")
 	(zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && rs6000_gen_microcode"
   "*
 {
   int start = INTVAL (operands[3]) & 63;
@@ -3805,7 +4043,8 @@
   operands[2] = GEN_INT (64 - size);
   return \"rldicl. %0,%1,%3,%2\";
 }"
-  [(set_attr "type" "compare")])
+  [(set_attr "type" "compare")
+   (set_attr "microcode" "mc")])
 
 (define_insn "rotlsi3"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
@@ -3825,15 +4064,17 @@
    {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			       (match_operand:SI 2 "reg_or_cint_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(rotate:SI (match_dup 1) (match_dup 2)))
    (set (match_dup 0)
@@ -3853,16 +4094,18 @@
    {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			       (match_operand:SI 2 "reg_or_cint_operand" ""))
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(rotate:SI (match_dup 1) (match_dup 2)))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(rotate:SI (match_dup 1) (match_dup 2)))
    (set (match_dup 3)
@@ -3891,17 +4134,19 @@
    {rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (and:SI
 		     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
 				(match_operand:SI 2 "reg_or_cint_operand" ""))
 		     (match_operand:SI 3 "mask_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 4 ""))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 4)
 	(and:SI (rotate:SI (match_dup 1)
 				(match_dup 2))
@@ -3925,10 +4170,11 @@
    {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 4 "cc_reg_operand" "")
 	(compare:CC (and:SI
 		     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
 				(match_operand:SI 2 "reg_or_cint_operand" ""))
@@ -3936,7 +4182,8 @@
 		    (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"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[4], CCmode))"
   [(set (match_dup 0)
 	(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (set (match_dup 4)
@@ -3966,17 +4213,19 @@
    {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (zero_extend:SI
 		     (subreg:QI
 		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
 				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(zero_extend:SI (subreg:QI
 		      (rotate:SI (match_dup 1)
@@ -4000,10 +4249,11 @@
    {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (zero_extend:SI
 		     (subreg:QI
 		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
@@ -4011,7 +4261,8 @@
 		    (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"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -4041,17 +4292,19 @@
    {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (zero_extend:SI
 		     (subreg:HI
 		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
 				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(zero_extend:SI (subreg:HI
 		      (rotate:SI (match_dup 1)
@@ -4075,10 +4328,11 @@
    {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (zero_extend:SI
 		     (subreg:HI
 		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
@@ -4086,7 +4340,8 @@
 		    (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"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -4126,7 +4381,8 @@
 	(ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
 		   (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
   "! TARGET_POWER"
-  "{sl|slw}%I2 %0,%1,%h2")
+  "{sl|slw}%I2 %0,%1,%h2"
+  [(set_attr "microcode" "mc")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
@@ -4142,6 +4398,7 @@
    #
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,mc,*,*")
    (set_attr "length" "4,4,8,8")])
 
 (define_split
@@ -4171,6 +4428,7 @@
    {sl|slw}%I2. %3,%1,%h2
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -4202,6 +4460,7 @@
    #
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,mc,*,*")
    (set_attr "length" "4,4,8,8")])
 
 (define_split
@@ -4233,6 +4492,7 @@
    {sl|slw}%I2. %0,%1,%h2
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -4271,17 +4531,19 @@
    {rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC
 	 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			    (match_operand:SI 2 "const_int_operand" ""))
 		 (match_operand:SI 3 "mask_operand" ""))
 	 (const_int 0)))
    (clobber (match_scratch:SI 4 ""))]
-  "includes_lshift_p (operands[2], operands[3]) && reload_completed"
+  "includes_lshift_p (operands[2], operands[3]) && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 4)
 	(and:SI (ashift:SI (match_dup 1) (match_dup 2))
 		 (match_dup 3)))
@@ -4304,10 +4566,11 @@
    {rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 4 "cc_reg_operand" "")
 	(compare:CC
 	 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			    (match_operand:SI 2 "const_int_operand" ""))
@@ -4315,7 +4578,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"
+  "includes_lshift_p (operands[2], operands[3]) && reload_completed
+   && reload_completed && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[4], CCmode))"
   [(set (match_dup 0)
 	(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (set (match_dup 4)
@@ -4357,7 +4621,8 @@
   "! TARGET_POWER"
   "@
   mr %0,%1
-  {sr|srw}%I2 %0,%1,%h2")
+  {sr|srw}%I2 %0,%1,%h2"
+  [(set_attr "microcode" "*,mc")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y")
@@ -4375,6 +4640,7 @@
   #
   #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,mc,mc,*,*,*")
    (set_attr "length" "4,4,4,8,8,8")])
 
 (define_split
@@ -4406,6 +4672,7 @@
    #
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,mc,*,*")
    (set_attr "length" "4,4,8,8")])
 
 (define_split
@@ -4439,6 +4706,7 @@
   #
   #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,mc,mc,*,*,*")
    (set_attr "length" "4,4,4,8,8,8")])
 
 (define_split
@@ -4472,6 +4740,7 @@
    #
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,mc,*,*")
    (set_attr "length" "4,4,8,8")])
 
 (define_split
@@ -4510,17 +4779,19 @@
    {rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC
 	 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			      (match_operand:SI 2 "const_int_operand" ""))
 		 (match_operand:SI 3 "mask_operand" ""))
 	 (const_int 0)))
    (clobber (match_scratch:SI 4 ""))]
-  "includes_rshift_p (operands[2], operands[3]) && reload_completed"
+  "includes_rshift_p (operands[2], operands[3]) && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 4)
 	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
 		 (match_dup 3)))
@@ -4543,10 +4814,11 @@
    {rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 4 "cc_reg_operand" "")
 	(compare:CC
 	 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
 			      (match_operand:SI 2 "const_int_operand" ""))
@@ -4554,7 +4826,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"
+  "includes_rshift_p (operands[2], operands[3]) && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[4], CCmode))"
   [(set (match_dup 0)
 	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (set (match_dup 4)
@@ -4585,10 +4858,11 @@
    {rlinm.|rlwinm.} %3,%1,%s2,0xff
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC
 	 (zero_extend:SI
 	  (subreg:QI
@@ -4596,7 +4870,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"
+  "includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(zero_extend:SI (subreg:QI
 	   (lshiftrt:SI (match_dup 1)
@@ -4621,10 +4896,11 @@
    {rlinm.|rlwinm.} %0,%1,%s2,0xff
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC
 	 (zero_extend:SI
 	  (subreg:QI
@@ -4633,7 +4909,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"
+  "includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -4664,10 +4941,11 @@
    {rlinm.|rlwinm.} %3,%1,%s2,0xffff
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC
 	 (zero_extend:SI
 	  (subreg:HI
@@ -4675,7 +4953,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"
+  "includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(zero_extend:SI (subreg:HI
 	   (lshiftrt:SI (match_dup 1)
@@ -4700,10 +4979,11 @@
    {rlinm.|rlwinm.} %0,%1,%s2,0xffff
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC
 	 (zero_extend:SI
 	  (subreg:HI
@@ -4712,7 +4992,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"
+  "includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -4777,7 +5058,8 @@
 	(ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
 		     (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
   "! TARGET_POWER"
-  "{sra|sraw}%I2 %0,%1,%h2")
+  "{sra|sraw}%I2 %0,%1,%h2"
+   [(set_attr "microcode" "mc")])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
@@ -4793,6 +5075,7 @@
    #
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,mc,*,*")
    (set_attr "length" "4,4,8,8")])
 
 (define_split
@@ -4822,6 +5105,7 @@
    {sra|sraw}%I2. %3,%1,%h2
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -4853,6 +5137,7 @@
    #
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,mc,*,*")
    (set_attr "length" "4,4,8,8")])
 
 (define_split
@@ -4884,6 +5169,7 @@
    {sra|sraw}%I2. %0,%1,%h2
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -6447,15 +6733,17 @@
    mulld. %3,%1,%2
    #"
   [(set_attr "type" "lmul_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			     (match_operand:DI 2 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(mult:DI (match_dup 1) (match_dup 2)))
    (set (match_dup 0)
@@ -6475,16 +6763,18 @@
    mulld. %0,%1,%2
    #"
   [(set_attr "type" "lmul_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			     (match_operand:DI 2 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(mult:DI (match_dup 1) (match_dup 2)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(mult:DI (match_dup 1) (match_dup 2)))
    (set (match_dup 3)
@@ -6534,15 +6824,17 @@
    rld%I2cl. %3,%1,%H2,0
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			       (match_operand:DI 2 "reg_or_cint_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(rotate:DI (match_dup 1) (match_dup 2)))
    (set (match_dup 0)
@@ -6562,16 +6854,18 @@
    rld%I2cl. %0,%1,%H2,0
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			       (match_operand:DI 2 "reg_or_cint_operand" ""))
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(rotate:DI (match_dup 1) (match_dup 2)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(rotate:DI (match_dup 1) (match_dup 2)))
    (set (match_dup 3)
@@ -6600,17 +6894,19 @@
    rld%I2c%B3. %4,%1,%H2,%S3
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (and:DI
 		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
 				(match_operand:DI 2 "reg_or_cint_operand" ""))
 		     (match_operand:DI 3 "mask64_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:DI 4 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 4)
 	(and:DI (rotate:DI (match_dup 1)
 				(match_dup 2))
@@ -6634,10 +6930,11 @@
    rld%I2c%B3. %0,%1,%H2,%S3
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 4 "cc_reg_operand" "")
 	(compare:CC (and:DI
 		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
 				(match_operand:DI 2 "reg_or_cint_operand" ""))
@@ -6645,7 +6942,8 @@
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[4], CCmode))"
   [(set (match_dup 0)
 	(and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
    (set (match_dup 4)
@@ -6675,17 +6973,19 @@
    rld%I2cl. %3,%1,%H2,56
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (zero_extend:DI
 		     (subreg:QI
 		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
 				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(zero_extend:DI (subreg:QI
 		      (rotate:DI (match_dup 1)
@@ -6709,10 +7009,11 @@
    rld%I2cl. %0,%1,%H2,56
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (zero_extend:DI
 		     (subreg:QI
 		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
@@ -6720,7 +7021,8 @@
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -6750,17 +7052,19 @@
    rld%I2cl. %3,%1,%H2,48
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (zero_extend:DI
 		     (subreg:HI
 		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
 				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(zero_extend:DI (subreg:HI
 		      (rotate:DI (match_dup 1)
@@ -6784,10 +7088,11 @@
    rld%I2cl. %0,%1,%H2,48
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (zero_extend:DI
 		     (subreg:HI
 		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
@@ -6795,7 +7100,8 @@
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -6825,17 +7131,19 @@
    rld%I2cl. %3,%1,%H2,32
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (zero_extend:DI
 		     (subreg:SI
 		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
 				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
 		    (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(zero_extend:DI (subreg:SI
 		      (rotate:DI (match_dup 1)
@@ -6859,10 +7167,11 @@
    rld%I2cl. %0,%1,%H2,32
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (zero_extend:DI
 		     (subreg:SI
 		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
@@ -6870,7 +7179,8 @@
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
    (set (match_dup 3)
@@ -6914,6 +7224,7 @@
    sld%I2. %3,%1,%H2
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -6942,6 +7253,7 @@
    sld%I2. %0,%1,%H2
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -6980,10 +7292,11 @@
    rldic. %4,%1,%H2,%W3
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			    (match_operand:SI 2 "const_int_operand" ""))
@@ -6991,7 +7304,8 @@
 	 (const_int 0)))
    (clobber (match_scratch:DI 4 ""))]
   "TARGET_POWERPC64 && reload_completed
-   && includes_rldic_lshift_p (operands[2], operands[3])"
+   && includes_rldic_lshift_p (operands[2], operands[3])
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 4)
 	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
 		(match_dup 3)))
@@ -7014,10 +7328,11 @@
    rldic. %0,%1,%H2,%W3
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 4 "cc_reg_operand" "")
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			    (match_operand:SI 2 "const_int_operand" ""))
@@ -7026,7 +7341,8 @@
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
   "TARGET_POWERPC64 && reload_completed
-   && includes_rldic_lshift_p (operands[2], operands[3])"
+   && includes_rldic_lshift_p (operands[2], operands[3])
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[4], CCmode))"
   [(set (match_dup 0)
 	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
 		(match_dup 3)))
@@ -7056,10 +7372,11 @@
    rldicr. %4,%1,%H2,%S3
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			    (match_operand:SI 2 "const_int_operand" ""))
@@ -7067,7 +7384,8 @@
 	 (const_int 0)))
    (clobber (match_scratch:DI 4 ""))]
   "TARGET_POWERPC64 && reload_completed
-   && includes_rldicr_lshift_p (operands[2], operands[3])"
+   && includes_rldicr_lshift_p (operands[2], operands[3])
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 4)
 	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
 		(match_dup 3)))
@@ -7090,10 +7408,11 @@
    rldicr. %0,%1,%H2,%S3
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 4 "cc_reg_operand" "")
 	(compare:CC
 	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			    (match_operand:SI 2 "const_int_operand" ""))
@@ -7102,7 +7421,8 @@
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
   "TARGET_POWERPC64 && reload_completed
-   && includes_rldicr_lshift_p (operands[2], operands[3])"
+   && includes_rldicr_lshift_p (operands[2], operands[3])
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[4], CCmode))"
   [(set (match_dup 0)
 	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
 		(match_dup 3)))
@@ -7147,15 +7467,17 @@
    srd%I2. %3,%1,%H2
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
 				 (match_operand:SI 2 "reg_or_cint_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(lshiftrt:DI (match_dup 1) (match_dup 2)))
    (set (match_dup 0)
@@ -7175,16 +7497,18 @@
    srd%I2. %0,%1,%H2
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
 				 (match_operand:SI 2 "reg_or_cint_operand" ""))
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(lshiftrt:DI (match_dup 1) (match_dup 2)))
    (set (match_dup 3)
@@ -7221,7 +7545,8 @@
 	(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
 		     (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
   "TARGET_POWERPC64"
-  "srad%I2 %0,%1,%H2")
+  "srad%I2 %0,%1,%H2"
+  [(set_attr "microcode" "mc")])
 
 (define_insn "*ashrdi3_internal2"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -7234,6 +7559,7 @@
    srad%I2. %3,%1,%H2
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -7262,6 +7588,7 @@
    srad%I2. %0,%1,%H2
    #"
   [(set_attr "type" "delayed_compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
@@ -7279,12 +7606,21 @@
 		    (const_int 0)))]
   "")
 
-(define_insn "anddi3"
+(define_expand "anddi3"
+  [(parallel
+    [(set (match_operand:DI 0 "gpc_reg_operand" "")
+	  (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
+		  (match_operand:DI 2 "and64_2_operand" "")))
+     (clobber (match_scratch:CC 3 ""))])]
+  "TARGET_POWERPC64"
+  "")
+
+(define_insn "anddi3_mc"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
 	(and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r")
 		(match_operand:DI 2 "and64_2_operand" "?r,S,T,K,J,t")))
    (clobber (match_scratch:CC 3 "=X,X,X,x,x,X"))]
-  "TARGET_POWERPC64"
+  "TARGET_POWERPC64 && rs6000_gen_microcode"
   "@
    and %0,%1,%2
    rldic%B2 %0,%1,0,%S2
@@ -7295,6 +7631,19 @@
   [(set_attr "type" "*,*,*,compare,compare,*")
    (set_attr "length" "4,4,4,4,4,8")])
 
+(define_insn "anddi3_nomc"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
+	(and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r")
+		(match_operand:DI 2 "and64_2_operand" "?r,S,T,t")))
+   (clobber (match_scratch:CC 3 "=X,X,X,X"))]
+  "TARGET_POWERPC64 && !rs6000_gen_microcode"
+  "@
+   and %0,%1,%2
+   rldic%B2 %0,%1,0,%S2
+   rlwinm %0,%1,0,%m2,%M2
+   #"
+  [(set_attr "length" "4,4,4,8")])
+
 (define_split
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
 	(and:DI (match_operand:DI 1 "gpc_reg_operand" "")
@@ -7316,14 +7665,14 @@
   build_mask64_2_operands (operands[2], &operands[4]);
 })
 
-(define_insn "*anddi3_internal2"
+(define_insn "*anddi3_internal2_mc"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y")
 	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r")
 			    (match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t"))
 		    (const_int 0)))
    (clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r,r,r,r,r"))
    (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,x,x,X"))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && rs6000_gen_microcode"
   "@
    and. %3,%1,%2
    rldic%B2. %3,%1,0,%S2
@@ -7338,8 +7687,21 @@
    #
    #"
   [(set_attr "type" "compare,compare,compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
+   (set_attr "microcode" "mc,mc,mc,mc,mc,*,*,*,*,*,*,*")
    (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
 
+(define_insn "*anddi3_internal2_nomc"
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y,?y,??y,??y,?y")
+	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r")
+			    (match_operand:DI 2 "and64_2_operand" "t,r,S,K,J,t"))
+		    (const_int 0)))
+   (clobber (match_scratch:DI 3 "=r,r,r,r,r,r"))
+   (clobber (match_scratch:CC 4 "=X,X,X,x,x,X"))]
+  "TARGET_64BIT && !rs6000_gen_microcode"
+  "#"
+  [(set_attr "type" "delayed_compare,compare,compare,compare,compare,compare")
+   (set_attr "length" "8,8,8,8,8,12")])
+
 (define_split
   [(set (match_operand:CC 0 "cc_reg_operand" "")
         (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
@@ -7366,7 +7728,7 @@
   build_mask64_2_operands (operands[2], &operands[5]);
 }")
 
-(define_insn "*anddi3_internal3"
+(define_insn "*anddi3_internal3_mc"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y")
 	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r")
 			    (match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t"))
@@ -7374,7 +7736,7 @@
    (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r,r,r")
 	(and:DI (match_dup 1) (match_dup 2)))
    (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,x,x,X"))]
-  "TARGET_64BIT"
+  "TARGET_64BIT && rs6000_gen_microcode"
   "@
    and. %0,%1,%2
    rldic%B2. %0,%1,0,%S2
@@ -7389,17 +7751,32 @@
    #
    #"
   [(set_attr "type" "compare,compare,compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
+   (set_attr "microcode" "mc,mc,mc,mc,mc,*,*,*,*,*,*,*")
    (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
 
+(define_insn "*anddi3_internal3_nomc"
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?y,??y,??y,?y")
+	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r")
+			    (match_operand:DI 2 "and64_2_operand" "t,r,S,K,J,t"))
+		    (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
+	(and:DI (match_dup 1) (match_dup 2)))
+   (clobber (match_scratch:CC 4 "=X,X,X,x,x,X"))]
+  "TARGET_64BIT"
+  "#"
+  [(set_attr "type" "delayed_compare,compare,compare,compare,compare,compare")
+   (set_attr "length" "8,8,8,8,8,12")])
+
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			    (match_operand:DI 2 "and64_2_operand" ""))
 		    (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(and:DI (match_dup 1) (match_dup 2)))
    (clobber (match_scratch:CC 4 ""))]
-  "TARGET_64BIT && reload_completed"
+  "TARGET_64BIT && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(parallel [(set (match_dup 0)
 		    (and:DI (match_dup 1) (match_dup 2)))
 	       (clobber (match_dup 4))])
@@ -7527,16 +7904,18 @@
    %q4. %3,%1,%2
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (match_operator:DI 4 "boolean_operator"
 	 [(match_operand:DI 1 "gpc_reg_operand" "")
 	  (match_operand:DI 2 "gpc_reg_operand" "")])
 	 (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3) (match_dup 4))
    (set (match_dup 0)
 	(compare:CC (match_dup 3)
@@ -7556,17 +7935,19 @@
    %q4. %0,%1,%2
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (match_operator:DI 4 "boolean_operator"
 	 [(match_operand:DI 1 "gpc_reg_operand" "")
 	  (match_operand:DI 2 "gpc_reg_operand" "")])
 	 (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(match_dup 4))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0) (match_dup 4))
    (set (match_dup 3)
 	(compare:CC (match_dup 0)
@@ -7627,16 +8008,18 @@
    %q4. %3,%2,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (match_operator:DI 4 "boolean_operator"
 	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
 	  (match_operand:DI 2 "gpc_reg_operand" "")])
 	 (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3) (match_dup 4))
    (set (match_dup 0)
 	(compare:CC (match_dup 3)
@@ -7656,17 +8039,19 @@
    %q4. %0,%2,%1
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (match_operator:DI 4 "boolean_operator"
 	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
 	  (match_operand:DI 2 "gpc_reg_operand" "")])
 	 (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(match_dup 4))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0) (match_dup 4))
    (set (match_dup 3)
 	(compare:CC (match_dup 0)
@@ -7693,16 +8078,18 @@
    %q4. %3,%1,%2
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC (match_operator:DI 4 "boolean_operator"
 	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
 	  (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))])
 	 (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3) (match_dup 4))
    (set (match_dup 0)
 	(compare:CC (match_dup 3)
@@ -7722,17 +8109,19 @@
    %q4. %0,%1,%2
    #"
   [(set_attr "type" "compare")
+   (set_attr "microcode" "mc,*")
    (set_attr "length" "4,8")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC (match_operator:DI 4 "boolean_operator"
 	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
 	  (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))])
 	 (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(match_dup 4))]
-  "TARGET_POWERPC64 && reload_completed"
+  "TARGET_POWERPC64 && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0) (match_dup 4))
    (set (match_dup 3)
 	(compare:CC (match_dup 0)
@@ -7861,6 +8250,7 @@
    mr. %0,%1
    #"
   [(set_attr "type" "cmp,compare,cmp")
+   (set_attr "microcode" "*,mc,*")
    (set_attr "length" "4,4,8")])
 
 (define_split
@@ -8730,7 +9120,8 @@
       return \"#\";
     }
 }"
-  [(set_attr "type" "store,store,*,load,load,*")])
+  [(set_attr "type" "store,store,*,load,load,*")
+   (set_attr "microcode" "mc,*,*,mc,*,*")])
 
 (define_insn "*movti_string"
   [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,o<>,????r,????r,????r,r")
@@ -8761,7 +9152,8 @@
       return \"#\";
     }
 }"
-  [(set_attr "type" "store_ux,store_ux,*,load_ux,load_ux,*")])
+  [(set_attr "type" "store_ux,store_ux,*,load_ux,load_ux,*")
+   (set_attr "microcode" "mc,*,*,mc,*,*")])
 
 (define_insn "*movti_ppc64"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o<>,r")
@@ -9020,7 +9412,8 @@
 	  (match_operand:SI 10 "gpc_reg_operand" "r"))])]
   "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 9"
   "{stsi|stswi} %2,%1,%O0"
-  [(set_attr "type" "store_ux")])
+  [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*stmsi7"
   [(match_parallel 0 "store_multiple_operation"
@@ -9041,7 +9434,8 @@
 	  (match_operand:SI 9 "gpc_reg_operand" "r"))])]
   "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 8"
   "{stsi|stswi} %2,%1,%O0"
-  [(set_attr "type" "store_ux")])
+  [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*stmsi6"
   [(match_parallel 0 "store_multiple_operation"
@@ -9060,7 +9454,8 @@
 	  (match_operand:SI 8 "gpc_reg_operand" "r"))])]
   "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 7"
   "{stsi|stswi} %2,%1,%O0"
-  [(set_attr "type" "store_ux")])
+  [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*stmsi5"
   [(match_parallel 0 "store_multiple_operation"
@@ -9077,7 +9472,8 @@
 	  (match_operand:SI 7 "gpc_reg_operand" "r"))])]
   "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 6"
   "{stsi|stswi} %2,%1,%O0"
-  [(set_attr "type" "store_ux")])
+ [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*stmsi4"
   [(match_parallel 0 "store_multiple_operation"
@@ -9092,7 +9488,8 @@
 	  (match_operand:SI 6 "gpc_reg_operand" "r"))])]
   "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 5"
   "{stsi|stswi} %2,%1,%O0"
-  [(set_attr "type" "store_ux")])
+  [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*stmsi3"
   [(match_parallel 0 "store_multiple_operation"
@@ -9105,7 +9502,8 @@
 	  (match_operand:SI 5 "gpc_reg_operand" "r"))])]
   "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 4"
   "{stsi|stswi} %2,%1,%O0"
-  [(set_attr "type" "store_ux")])
+  [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*stmsi8_power"
   [(match_parallel 0 "store_multiple_operation"
@@ -9128,7 +9526,8 @@
 	  (match_operand:SI 10 "gpc_reg_operand" "r"))])]
   "TARGET_STRING && TARGET_POWER && XVECLEN (operands[0], 0) == 9"
   "{stsi|stswi} %2,%1,%O0"
-  [(set_attr "type" "store_ux")])
+  [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*stmsi7_power"
   [(match_parallel 0 "store_multiple_operation"
@@ -9149,7 +9548,8 @@
 	  (match_operand:SI 9 "gpc_reg_operand" "r"))])]
   "TARGET_STRING && TARGET_POWER && XVECLEN (operands[0], 0) == 8"
   "{stsi|stswi} %2,%1,%O0"
-  [(set_attr "type" "store_ux")])
+  [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*stmsi6_power"
   [(match_parallel 0 "store_multiple_operation"
@@ -9168,7 +9568,8 @@
 	  (match_operand:SI 8 "gpc_reg_operand" "r"))])]
   "TARGET_STRING && TARGET_POWER && XVECLEN (operands[0], 0) == 7"
   "{stsi|stswi} %2,%1,%O0"
-  [(set_attr "type" "store_ux")])
+  [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*stmsi5_power"
   [(match_parallel 0 "store_multiple_operation"
@@ -9185,7 +9586,8 @@
 	  (match_operand:SI 7 "gpc_reg_operand" "r"))])]
   "TARGET_STRING && TARGET_POWER && XVECLEN (operands[0], 0) == 6"
   "{stsi|stswi} %2,%1,%O0"
-  [(set_attr "type" "store_ux")])
+  [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*stmsi4_power"
   [(match_parallel 0 "store_multiple_operation"
@@ -9200,7 +9602,8 @@
 	  (match_operand:SI 6 "gpc_reg_operand" "r"))])]
   "TARGET_STRING && TARGET_POWER && XVECLEN (operands[0], 0) == 5"
   "{stsi|stswi} %2,%1,%O0"
-  [(set_attr "type" "store_ux")])
+  [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*stmsi3_power"
   [(match_parallel 0 "store_multiple_operation"
@@ -9213,7 +9616,8 @@
 	  (match_operand:SI 5 "gpc_reg_operand" "r"))])]
   "TARGET_STRING && TARGET_POWER && XVECLEN (operands[0], 0) == 4"
   "{stsi|stswi} %2,%1,%O0"
-  [(set_attr "type" "store_ux")])
+  [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")])
 
 (define_expand "setmemsi"
   [(parallel [(set (match_operand:BLK 0 "" "")
@@ -9295,6 +9699,7 @@
    && REGNO (operands[4]) == 5"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")
    (set_attr "length" "8")])
 
 (define_insn ""
@@ -9319,6 +9724,7 @@
    && REGNO (operands[4]) == 5"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")
    (set_attr "length" "8")])
 
 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
@@ -9358,6 +9764,7 @@
    && REGNO (operands[4]) == 5"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")
    (set_attr "length" "8")])
 
 (define_insn ""
@@ -9379,6 +9786,7 @@
    && REGNO (operands[4]) == 5"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")
    (set_attr "length" "8")])
 
 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
@@ -9414,6 +9822,7 @@
    && REGNO (operands[4]) == 5"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")
    (set_attr "length" "8")])
 
 (define_insn ""
@@ -9433,6 +9842,7 @@
    && REGNO (operands[4]) == 5"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")
    (set_attr "length" "8")])
 
 ;; Move up to 8 bytes at a time.
@@ -9457,6 +9867,7 @@
    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")
    (set_attr "length" "8")])
 
 (define_insn ""
@@ -9470,6 +9881,7 @@
    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")
    (set_attr "length" "8")])
 
 ;; Move up to 4 bytes at a time.
@@ -9494,6 +9906,7 @@
    && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")
    (set_attr "length" "8")])
 
 (define_insn ""
@@ -9507,6 +9920,7 @@
    && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")
    (set_attr "length" "8")])
 
 ;; Define insns that do load or store with update.  Some of these we can
@@ -9561,9 +9975,10 @@
 			  (match_operand:DI 2 "gpc_reg_operand" "r")))))
    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
 	(plus:DI (match_dup 1) (match_dup 2)))]
-  "TARGET_POWERPC64"
+  "TARGET_POWERPC64 && rs6000_gen_microcode"
   "lwaux %3,%0,%2"
-  [(set_attr "type" "load_ext_ux")])
+  [(set_attr "type" "load_ext_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "movsi_update"
   [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
@@ -9609,7 +10024,7 @@
 			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_UPDATE"
+  "TARGET_UPDATE && rs6000_gen_microcode"
   "@
    lhaux %3,%0,%2
    lhau %3,%2(%0)"
@@ -11798,7 +12213,7 @@
    (set_attr "length" "8,16")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC
 	 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
 				       [(match_operand 2 "cc_reg_operand" "")
@@ -11808,7 +12223,8 @@
    (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"
+  "reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 4)
 	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
 		   (match_dup 3)))
@@ -12208,7 +12624,7 @@
    (set_attr "length" "8,12")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC
 	 (plus:DI (lshiftrt:DI
 		   (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "")))
@@ -12216,7 +12632,8 @@
 		  (match_operand:DI 2 "gpc_reg_operand" ""))
 	 (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_64BIT && reload_completed"
+  "TARGET_64BIT && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1)))
 		   (const_int 63))
@@ -12287,7 +12704,7 @@
    (set_attr "length" "8,12")])
 
 (define_split
-  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 4 "cc_reg_operand" "")
 	(compare:CC
 	 (plus:DI (lshiftrt:DI
 		   (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "")))
@@ -12298,7 +12715,8 @@
 	(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
 		 (match_dup 2)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_64BIT && reload_completed"
+  "TARGET_64BIT && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[4], CCmode))"
   [(parallel [(set (match_dup 0)
 	(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
 		 (match_dup 2)))
@@ -13285,14 +13703,15 @@
    (set_attr "length" "12,16")])
 
 (define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 0 "cc_reg_operand" "")
 	(compare:CC
 	 (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			 (const_int 0))
 		  (match_operand:DI 2 "gpc_reg_operand" ""))
 	 (const_int 0)))
    (clobber (match_scratch:DI 3 ""))]
-  "TARGET_64BIT && reload_completed"
+  "TARGET_64BIT && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[0], CCmode))"
   [(set (match_dup 3)
 	(plus:DI (gt:DI (match_dup 1) (const_int 0))
 		 (match_dup 2)))
@@ -13351,7 +13770,7 @@
    (set_attr "length" "12,16")])
 
 (define_split
-  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+  [(set (match_operand:CC 3 "cc_reg_operand" "")
 	(compare:CC
 	 (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "")
 			 (const_int 0))
@@ -13359,7 +13778,8 @@
 	 (const_int 0)))
    (set (match_operand:DI 0 "gpc_reg_operand" "")
 	(plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))]
-  "TARGET_64BIT && reload_completed"
+  "TARGET_64BIT && reload_completed
+   && (! rs6000_gen_microcode || ! cr0_reg_operand (operands[3], CCmode))"
   [(set (match_dup 0)
 	(plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))
    (set (match_dup 3)
@@ -13778,6 +14198,16 @@
   [(const_int 0)]
   ""
   "{cror 0,0,0|nop}")
+
+(define_insn "db8cyc"
+  [(const_int 1)]
+  ""
+  "or 28,28,28")
+
+(define_insn "db10cyc"
+  [(const_int 2)]
+  ""
+  "or 29,29,29")
 
 ;; Define the subtract-one-and-jump insns, starting with the template
 ;; so loop.c knows what to generate.
@@ -14052,7 +14482,8 @@
        			 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
   "TARGET_MULTIPLE"
   "{stm|stmw} %2,%1"
-  [(set_attr "type" "store_ux")])
+  [(set_attr "type" "store_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*save_fpregs_<mode>"
   [(match_parallel 0 "any_parallel_operand"
@@ -14135,7 +14566,8 @@
        			 (match_operand:SI 2 "memory_operand" "m"))])]
   "TARGET_MULTIPLE"
   "{lm|lmw} %1,%2"
-  [(set_attr "type" "load_ux")])
+  [(set_attr "type" "load_ux")
+   (set_attr "microcode" "mc")])
 
 (define_insn "*return_internal_<mode>"
   [(return)
--- gcc-4.2.0/gcc/config/rs6000/predicates.md.cell-ppu-sched	2007-06-01 17:11:36.000000000 +0200
+++ gcc-4.2.0/gcc/config/rs6000/predicates.md	2007-06-04 14:06:28.000000000 +0200
@@ -91,6 +91,16 @@
 		     && !((TARGET_E500_DOUBLE || TARGET_SPE)
 			  && invalid_e500_subreg (op, mode))")))
 
+;; Return 1 if op is a register that is the CR0 field.
+(define_predicate "cr0_reg_operand"
+  (and (match_operand 0 "register_operand")
+       (match_test "REGNO (op) == CR0_REGNO")))
+
+;; Return 1 if op is a register that is the CR6 field.
+(define_predicate "cr6_reg_operand"
+  (and (match_operand 0 "register_operand")
+       (match_test "REGNO (op) == CR6_REGNO")))
+
 ;; Return 1 if op is a register that is a condition register field.
 (define_predicate "cc_reg_operand"
    (and (match_operand 0 "register_operand")
@@ -659,6 +669,24 @@
 	    || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
 })
 
+;; Return 1 if the operand is a memory operand without pre_inc or
+;; pre_dec, which produces invalid form of PowerPC lwa instruction.
+(define_predicate "lwa_mem_operand"
+  (match_code "reg,subreg,mem")
+{
+  rtx inner = op;
+
+  if (reload_completed && GET_CODE (inner) == SUBREG)
+    inner = SUBREG_REG (inner);
+
+  return (memory_operand (inner, mode)
+	&& GET_CODE (XEXP (inner, 0)) != PRE_INC
+	&& GET_CODE (XEXP (inner, 0)) != PRE_DEC
+	&& (GET_CODE (XEXP (inner, 0)) != PLUS
+	    || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT
+	    || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
+})
+
 ;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF.
 (define_predicate "symbol_ref_operand"
   (and (match_code "symbol_ref")
--- gcc-4.2.0/gcc/config/rs6000/rs6000.h.cell-ppu-sched	2007-06-01 17:11:36.000000000 +0200
+++ gcc-4.2.0/gcc/config/rs6000/rs6000.h	2007-06-04 14:06:28.000000000 +0200
@@ -59,6 +59,7 @@
 
 /* Common ASM definitions used by ASM_SPEC among the various targets
    for handling -mcpu=xxx switches.  */
+/* CELL LOCAL: add mcpu=cell_pu below */
 #define ASM_CPU_SPEC \
 "%{!mcpu*: \
   %{mpower: %{!mpower2: -mpwr}} \
@@ -111,6 +112,7 @@
 %{mcpu=970: -mpower4 -maltivec} \
 %{mcpu=G5: -mpower4 -maltivec} \
 %{mcpu=8540: -me500} \
+%{mcpu=cell: -mcell -maltivec} \
 %{maltivec: -maltivec} \
 -many"
 
@@ -211,6 +213,7 @@
    PROCESSOR_PPC7400,
    PROCESSOR_PPC7450,
    PROCESSOR_PPC8540,
+   PROCESSOR_CELLPPU,	/* CELL LOCAL */
    PROCESSOR_POWER4,
    PROCESSOR_POWER5
 };
@@ -696,11 +699,14 @@
 }
 
 #define MQ_REGNO     64
+#define LR_REGNO     65
+#define CTR_REGNO    66
 #define CR0_REGNO    68
 #define CR1_REGNO    69
 #define CR2_REGNO    70
 #define CR3_REGNO    71
 #define CR4_REGNO    72
+#define CR6_REGNO    74		/* CELL LOCAL */
 #define MAX_CR_REGNO 75
 #define XER_REGNO    76
 #define FIRST_ALTIVEC_REGNO	77
--- gcc-4.2.0/gcc/final.c.cell-ppu-sched	2007-06-01 17:11:50.000000000 +0200
+++ gcc-4.2.0/gcc/final.c	2007-06-04 14:06:28.000000000 +0200
@@ -2465,6 +2465,17 @@
 	targetm.asm_out.unwind_emit (asm_out_file, insn);
 #endif
 
+
+#ifdef RS6000_GENERATE_MICROCODE
+   	/* 0, notmicrocode, 1, conditional microcode, 2, microcode */
+        if (rs6000_warn_microcode)
+        {
+          if (get_attr_microcode(insn) == 2)
+            pedwarn ("emitting microcode insn %s\t[%s] #%d",template, insn_data[INSN_CODE(insn)].name,INSN_UID(insn));
+          else if (get_attr_microcode(insn) == 1)
+            pedwarn ("emitting conditional microcode insn %s\t[%s] #%d",template, insn_data[INSN_CODE(insn)].name,INSN_UID(insn));
+	}
+#endif
 	/* Output assembler code from the template.  */
 	output_asm_insn (template, recog_data.operand);
 
--- gcc-4.2.0/gcc/config.gcc.cell-ppu-sched	2007-06-01 17:11:50.000000000 +0200
+++ gcc-4.2.0/gcc/config.gcc	2007-06-04 14:06:28.000000000 +0200
@@ -301,7 +301,7 @@
 	extra_headers="ppc-asm.h altivec.h spe.h"
 	need_64bit_hwint=yes
 	case x$with_cpu in
-	    xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[3456]|xrs64a)
+	    xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[3456]|xrs64a|xcell)
 		cpu_is_64bit=yes
 		;;
 	esac
@@ -2870,7 +2870,8 @@
 			| 401 | 403 | 405 | 405fp | 440 | 440fp | 505 \
 			| 601 | 602 | 603 | 603e | ec603e | 604 \
 			| 604e | 620 | 630 | 740 | 750 | 7400 | 7450 \
-			| 854[08] | 801 | 821 | 823 | 860 | 970 | G3 | G4 | G5)
+			| 854[08] | 801 | 821 | 823 | 860 | 970 | G3 | G4 | G5 \
+			| cell)
 				# OK
 				;;
 			*)
--- gcc-4.2.0/gcc/tree-ssa-operands.c.cell-ppu-sched	2007-06-01 17:11:50.000000000 +0200
+++ gcc-4.2.0/gcc/tree-ssa-operands.c	2007-06-04 14:06:28.000000000 +0200
@@ -1375,6 +1375,11 @@
   if (TREE_THIS_VOLATILE (sym) && s_ann)
     s_ann->has_volatile_ops = true;
 
+  /* When a variable has a hard register assigned to it, we must be
+     careful not to optimize references to it. */
+  if (TREE_CODE (sym) == VAR_DECL && DECL_HARD_REGISTER (sym) && s_ann)
+    s_ann->has_volatile_ops = true;
+
   if (is_real_op)
     {
       /* The variable is a GIMPLE register.  Add it to real operands.  */