OSDN Git Service

* sparc/sparc.h (MASK_LIVE_G0,TARGET_LIVE_G0): Define.
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 8 Mar 1996 00:12:21 +0000 (00:12 +0000)
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 8 Mar 1996 00:12:21 +0000 (00:12 +0000)
(TARGET_SWITCHES): Add live-g0.
(FIRST_PSEUDO_REGISTER): Add 1 for %icc (now 101).
(FIXED_REGISTERS,CALL_USED_REGISTERS): Update.
(FIXED_REGISTERS): %g0 is fixed by default.
(SPARC_{FIRST,LAST}_V9_FCC_REG): Define.
(SPARC_{ICC,FCC}_REG): Define.
(CONDITIONAL_REGISTER_USAGE): Don't fix %fcc0 if v8.
(REG_CLASS_CONTENTS): Reg 0 is an int reg, reg 100 is %icc.
(REGNO_REG_CLASS): Rewrite to use global `sparc_regno_reg_class'.
(REG_ALLOC_ORDER,REG_LEAF_ALLOC_ORDER,LEAF_REGISTERS): Add %icc.
(REG_CLASS_FROM_LETTER): Handle 'c' for FPCC_REGS in non-v9 case.
(REGNO_OK_FOR_{BASE,INDEX}_P): Treat %g0 as a normal reg.
(REG_OK_FOR_{BASE,INDEX}_P,EXTRA_CONSTRAINT): Likewise.
(REGISTER_NAMES): Add %icc.
(ADDITIONAL_REGISTER_NAMES): Use SPARC_ICC_REG.
* sparc/sparc.c (leaf_reg_remap): Add %icc=100.
(reg_or_0_operand): Don't allow 0 if TARGET_LIVE_G0.
(fcc_reg_operand): Renamed from ccfp_reg_operand.
Use SPARC_FCC_REG.  Don't treat reg 0 as an fcc reg.  Don't match
modes if `mode' argument is VOIDmode.
(icc_or_fcc_reg_operand): New function.
(gen_compare_reg): Use SPARC_FCC_REG for v8 fp compares.
Use SPARC_ICC_REG for int compares.
(eligible_for_epilogue_delay): Don't allow anything if TARGET_LIVE_G0.
Delete unnecessary test for %g0.
(emit_move_sequence): Don't emit (set (mem) (const_int 0)) if
TARGET_LIVE_G0.
(output_scc_insn): Label moved to operand 3.  Condition code reg
moved to operand 2.
(sparc_mode_class): Enum C_MODE renamed to CC_MODE.
(hard_32bit_mode_classes): Set reg 0 to S_MODES.  Add entry for %icc.
(hard_64bit_mode_classes): Set reg 0 to D_MODES.  Add entry for %icc.
(sparc_regno_reg_class): New global.
(sparc_init_modes): Initialize it.
(output_cbranch): Delete fp_cond_reg argument.
(print_operand, MEM op): Don't print "%g0+" if TARGET_SPARCLET.
(sparc_flat_eligible_for_epilogue_delay): Don't allow anything if
TARGET_LIVE_G0.
* sparc/sparc.md (live_g0): New attribute.
(*): Integer condition code register is now reg 100.
Use SPARC_ICC_REG instead of hardcoding reg 100 where possible.
Non-v9 floating point condition code register is now reg 96.
(*cmp{sf,df,tf}_{fpe,fp}_sp{32,64}): Combine v9/non-v9 cases.
(*{normal,inverted}_{,fp,fpe}_branch): Update call to output_cbranch.
(*mov{qi,hi,si}_insn): Don't use if TARGET_LIVE_G0.
(*mov{qi,hi,si}_insn_liveg0): New patterns.
(*mov{si,di,sf,df,tf}_ccfp{,e}_sp64): ccfp_reg_operand renamed to
fcc_reg_operand.
(*negdi2_sp32,negsi2,one_cmplsi2,ffssi2): Ensure %%g0 is 0 if
TARGET_LIVE_G0.
(*one_cmpldi2_sp32): Move operand 1 to rs1 and use 0 as rs2.
(patterns that use %g0 in rs2): Use 0 immediate value instead.
(patterns that read %g0): Don't use if TARGET_LIVE_G0.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@11494 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/sparc/sparc.md

index 8bf67aa..dc6bcbf 100644 (file)
@@ -99,7 +99,7 @@ char leaf_reg_remap[] =
   72, 73, 74, 75, 76, 77, 78, 79,
   80, 81, 82, 83, 84, 85, 86, 87,
   88, 89, 90, 91, 92, 93, 94, 95,
-  96, 97, 98, 99};
+  96, 97, 98, 99, 100};
 
 #endif
 
@@ -268,13 +268,19 @@ v9_regcmp_p (code)
 /* Operand constraints.  */
 
 /* Return non-zero only if OP is a register of mode MODE,
-   or const0_rtx.  */
+   or const0_rtx.  Don't allow const0_rtx if TARGET_LIVE_G0 because
+   %g0 may contain anything.  */
+
 int
 reg_or_0_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
-  if (op == const0_rtx || register_operand (op, mode))
+  if (register_operand (op, mode))
+    return 1;
+  if (TARGET_LIVE_G0)
+    return 0;
+  if (op == const0_rtx)
     return 1;
   if (GET_MODE (op) == VOIDmode && GET_CODE (op) == CONST_DOUBLE
       && CONST_DOUBLE_HIGH (op) == 0
@@ -288,6 +294,7 @@ reg_or_0_operand (op, mode)
 }
 
 /* Nonzero if OP is a floating point value with value 0.0.  */
+
 int
 fp_zero_operand (op)
      rtx op;
@@ -312,26 +319,38 @@ intreg_operand (op, mode)
 /* Nonzero if OP is a floating point condition code register.  */
 
 int
-ccfp_reg_operand (op, mode)
+fcc_reg_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
   /* This can happen when recog is called from combine.  Op may be a MEM.
      Fail instead of calling abort in this case.  */
-  if (GET_CODE (op) != REG || REGNO (op) == 0)
+  if (GET_CODE (op) != REG)
     return 0;
-  if (GET_MODE (op) != mode)
+  if (mode != VOIDmode && mode != GET_MODE (op))
     return 0;
 
-#if 0  /* ??? ==> 1 when %fcc1-3 are pseudos first.  See gen_compare_reg().  */
+#if 0  /* ??? ==> 1 when %fcc0-3 are pseudos first.  See gen_compare_reg().  */
   if (reg_renumber == 0)
     return REGNO (op) >= FIRST_PSEUDO_REGISTER;
   return REGNO_OK_FOR_CCFP_P (REGNO (op));
 #else
-  return (unsigned) REGNO (op) - 96 < 4;
+  return (unsigned) REGNO (op) - SPARC_FIRST_V9_FCC_REG < 4;
 #endif
 }
 
+/* Nonzero if OP is an integer or floating point condition code register.  */
+
+int
+icc_or_fcc_reg_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_CODE (op) == REG && REGNO (op) == SPARC_ICC_REG)
+    return 1;
+  return fcc_reg_operand (op, mode);
+}
+
 /* Nonzero if OP can appear as the dest of a RESTORE insn.  */
 int
 restore_operand (op, mode)
@@ -855,7 +874,7 @@ gen_compare_reg (code, x, y)
   rtx cc_reg;
 
   /* ??? We don't have movcc patterns so we cannot generate pseudo regs for the
-     fpcc regs (cse can't tell they're really call clobbered regs and will
+     fcc regs (cse can't tell they're really call clobbered regs and will
      remove a duplicate comparison even if there is an intervening function
      call - it will then try to reload the cc reg via an int reg which is why
      we need the movcc patterns).  It is possible to provide the movcc
@@ -875,8 +894,8 @@ gen_compare_reg (code, x, y)
     {
       int reg;
       /* We cycle through the registers to ensure they're all exercised.  */
-      static int next_fpcc_reg = 0;
-      /* Previous x,y for each fpcc reg.  */
+      static int next_fcc_reg = 0;
+      /* Previous x,y for each fcc reg.  */
       static rtx prev_args[4][2];
 
       /* Scan prev_args for x,y.  */
@@ -885,18 +904,20 @@ gen_compare_reg (code, x, y)
          break;
       if (reg == 4)
        {
-         reg = next_fpcc_reg;
+         reg = next_fcc_reg;
          prev_args[reg][0] = x;
          prev_args[reg][1] = y;
-         next_fpcc_reg = (next_fpcc_reg + 1) & 3;
+         next_fcc_reg = (next_fcc_reg + 1) & 3;
        }
-      cc_reg = gen_rtx (REG, mode, reg + 96);
+      cc_reg = gen_rtx (REG, mode, reg + SPARC_FIRST_V9_FCC_REG);
     }
 #else
     cc_reg = gen_reg_rtx (mode);
 #endif /* ! experiment */
+  else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
+    cc_reg = gen_rtx (REG, mode, SPARC_FCC_REG);
   else
-    cc_reg = gen_rtx (REG, mode, 0);
+    cc_reg = gen_rtx (REG, mode, SPARC_ICC_REG);
 
   emit_insn (gen_rtx (SET, VOIDmode, cc_reg,
                      gen_rtx (COMPARE, mode, x, y)));
@@ -1062,6 +1083,14 @@ eligible_for_epilogue_delay (trial, slot)
   if (get_attr_length (trial) != 1)
     return 0;
 
+  pat = PATTERN (trial);
+
+  /* If %g0 is live, there are lots of things we can't handle.
+     Rather than trying to find them all now, let's punt and only
+     optimize things as necessary.  */
+  if (TARGET_LIVE_G0)
+    return 0;
+
   /* In the case of a true leaf function, anything can go into the delay slot.
      A delay slot only exists however if the frame size is zero, otherwise
      we will put an insn to adjust the stack after the return.  */
@@ -1074,9 +1103,7 @@ eligible_for_epilogue_delay (trial, slot)
 
   /* Otherwise, only operations which can be done in tandem with
      a `restore' insn can go into the delay slot.  */
-  pat = PATTERN (trial);
   if (GET_CODE (SET_DEST (pat)) != REG
-      || REGNO (SET_DEST (pat)) == 0
       || REGNO (SET_DEST (pat)) >= 32
       || REGNO (SET_DEST (pat)) < 24)
     return 0;
@@ -1442,7 +1469,8 @@ emit_move_sequence (operands, mode)
     }
   else if (GET_CODE (operand0) == MEM)
     {
-      if (register_operand (operand1, mode) || operand1 == const0_rtx)
+      if (register_operand (operand1, mode)
+         || (operand1 == const0_rtx && ! TARGET_LIVE_G0))
        {
          /* Run this case quickly.  */
          emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
@@ -2575,7 +2603,8 @@ output_scc_insn (operands, insn)
 
   LABEL_NUSES (label) += 1;
 
-  operands[2] = label;
+  /* operands[3] is an unused slot.  */
+  operands[3] = label;
 
   /* If we are in a delay slot, assume it is the delay slot of an fpcc
      insn since our type isn't allowed anywhere else.  */
@@ -2598,17 +2627,17 @@ output_scc_insn (operands, insn)
   if (final_sequence)
     {
       strcpy (string, "mov 0,%0\n\t");
-      strcat (string, output_cbranch (operands[1], 0, 2, 0, 1, 0));
+      strcat (string, output_cbranch (operands[2], 3, 0, 1, 0));
       strcat (string, "\n\tmov 1,%0");
     }
   else
     {
-      strcpy (string, output_cbranch (operands[1], 0, 2, 0, 1, 0));
+      strcpy (string, output_cbranch (operands[2], 3, 0, 1, 0));
       strcat (string, "\n\tmov 1,%0\n\tmov 0,%0");
     }
 
   if (need_label)
-    strcat (string, "\n%l2:");
+    strcat (string, "\n%l3:");
 
   return string;
 }
@@ -2623,15 +2652,11 @@ output_scc_insn (operands, insn)
    mapped into one sparc_mode_class mode.  */
 
 enum sparc_mode_class {
-  C_MODE, CCFP_MODE,
   S_MODE, D_MODE, T_MODE, O_MODE,
-  SF_MODE, DF_MODE, TF_MODE, OF_MODE
+  SF_MODE, DF_MODE, TF_MODE, OF_MODE,
+  CC_MODE, CCFP_MODE
 };
 
-/* Modes for condition codes.  */
-#define C_MODES ((1 << (int) C_MODE) | (1 << (int) CCFP_MODE))
-#define CCFP_MODES (1 << (int) CCFP_MODE)
-
 /* Modes for single-word and smaller quantities.  */
 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
 
@@ -2653,7 +2678,8 @@ enum sparc_mode_class {
 #define DF_MODES64 (SF_MODES | DF_MODE /* | D_MODE*/)
 
 /* Modes for double-float only quantities.  */
-/* ??? Sparc64 fp regs cannot hold DImode values.  */
+/* ??? Sparc64 fp regs cannot hold DImode values.
+   See fix_truncsfdi2.  */
 #define DF_ONLY_MODES ((1 << (int) DF_MODE) /*| (1 << (int) D_MODE)*/)
 
 /* Modes for double-float and larger quantities.  */
@@ -2665,20 +2691,25 @@ enum sparc_mode_class {
 /* Modes for quad-float and smaller quantities.  */
 #define TF_MODES (DF_MODES | TF_ONLY_MODES)
 
-/* ??? Sparc64 fp regs cannot hold DImode values.  */
+/* ??? Sparc64 fp regs cannot hold DImode values.
+   See fix_truncsfdi2.  */
 #define TF_MODES64 (DF_MODES64 | TF_ONLY_MODES)
 
+/* Modes for condition codes.  */
+#define CC_MODES (1 << (int) CC_MODE)
+#define CCFP_MODES (1 << (int) CCFP_MODE)
+
 /* Value is 1 if register/mode pair is acceptable on sparc.
    The funny mixture of D and T modes is because integer operations
    do not specially operate on tetra quantities, so non-quad-aligned
    registers can hold quadword quantities (except %o4 and %i4 because
-   they cross fixed registers.  */
+   they cross fixed registers).  */
 
 /* This points to either the 32 bit or the 64 bit version.  */
 int *hard_regno_mode_classes;
 
 static int hard_32bit_mode_classes[] = {
-  C_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
+  S_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
   T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES,
   T_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
   T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES,
@@ -2696,11 +2727,14 @@ static int hard_32bit_mode_classes[] = {
   DF_UP_MODES, 0, DF_ONLY_MODES, 0, DF_UP_MODES, 0, DF_ONLY_MODES, 0,
 
   /* %fcc[0123] */
-  CCFP_MODE, CCFP_MODE, CCFP_MODE, CCFP_MODE
+  CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES,
+
+  /* %icc */
+  CC_MODES
 };
 
 static int hard_64bit_mode_classes[] = {
-  C_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES,
+  D_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES,
   T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES,
   T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES,
   T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES,
@@ -2718,11 +2752,16 @@ static int hard_64bit_mode_classes[] = {
   DF_UP_MODES, 0, DF_ONLY_MODES, 0, DF_UP_MODES, 0, DF_ONLY_MODES, 0,
 
   /* %fcc[0123] */
-  CCFP_MODE, CCFP_MODE, CCFP_MODE, CCFP_MODE
+  CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES,
+
+  /* %icc */
+  CC_MODES
 };
 
 int sparc_mode_class [NUM_MACHINE_MODES];
 
+enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
+
 static void
 sparc_init_modes ()
 {
@@ -2767,7 +2806,7 @@ sparc_init_modes ()
            sparc_mode_class[i] = 1 << (int) CCFP_MODE;
          else if (i == (int) CCmode || i == (int) CC_NOOVmode
                   || i == (int) CCXmode || i == (int) CCX_NOOVmode)
-           sparc_mode_class[i] = 1 << (int) C_MODE;
+           sparc_mode_class[i] = 1 << (int) CC_MODE;
          else
            sparc_mode_class[i] = 0;
          break;
@@ -2778,6 +2817,21 @@ sparc_init_modes ()
     hard_regno_mode_classes = hard_64bit_mode_classes;
   else
     hard_regno_mode_classes = hard_32bit_mode_classes;
+
+  /* Initialize the array used by REGNO_REG_CLASS.  */
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    {
+      if (i < 32)
+       sparc_regno_reg_class[i] = GENERAL_REGS;
+      else if (i < 64)
+       sparc_regno_reg_class[i] = FP_REGS;
+      else if (i < 96)
+       sparc_regno_reg_class[i] = EXTRA_FP_REGS;
+      else if (i < 100)
+       sparc_regno_reg_class[i] = FPCC_REGS;
+      else
+       sparc_regno_reg_class[i] = NO_REGS;
+    }
 }
 \f
 /* Save non call used registers from LOW to HIGH at BASE+OFFSET.
@@ -3320,11 +3374,9 @@ sparc_builtin_saveregs (arglist)
 #endif /* ! SPARC_ARCH64 */
 \f
 /* Return the string to output a conditional branch to LABEL, which is
-   the operand number of the label.  OP is the conditional expression.  The
-   mode of register 0 says what kind of comparison we made.
-
-   FP_COND_REG indicates which fp condition code register to use if this is
-   a floating point branch.
+   the operand number of the label.  OP is the conditional expression.
+   XEXP (OP, 0) is assumed to be a condition code register (integer or
+   floating point) and its mode specifies what kind of comparison we made.
 
    REVERSED is non-zero if we should reverse the sense of the comparison.
 
@@ -3333,14 +3385,15 @@ sparc_builtin_saveregs (arglist)
    NOOP is non-zero if we have to follow this branch by a noop.  */
 
 char *
-output_cbranch (op, fp_cond_reg, label, reversed, annul, noop)
-     rtx op, fp_cond_reg;
+output_cbranch (op, label, reversed, annul, noop)
+     rtx op;
      int label;
      int reversed, annul, noop;
 {
   static char string[20];
   enum rtx_code code = GET_CODE (op);
-  enum machine_mode mode = GET_MODE (XEXP (op, 0));
+  rtx cc_reg = XEXP (op, 0);
+  enum machine_mode mode = GET_MODE (cc_reg);
   static char v8_labelno[] = " %lX";
   static char v9_icc_labelno[] = " %%icc,%lX";
   static char v9_xcc_labelno[] = " %%xcc,%lX";
@@ -3467,7 +3520,7 @@ output_cbranch (op, fp_cond_reg, label, reversed, annul, noop)
          labeloff = 10;
          labelno = v9_fcc_labelno;
          /* Set the char indicating the number of the fcc reg to use.  */
-         labelno[6] = REGNO (fp_cond_reg) - 96 + '0';
+         labelno[6] = REGNO (cc_reg) - SPARC_FIRST_V9_FCC_REG + '0';
        }
       else if (mode == CCXmode || mode == CCX_NOOVmode)
        labelno = v9_xcc_labelno;
@@ -3930,8 +3983,9 @@ print_operand (file, x, code)
   else if (GET_CODE (x) == MEM)
     {
       fputc ('[', file);
-      if (CONSTANT_P (XEXP (x, 0)))
        /* Poor Sun assembler doesn't understand absolute addressing.  */
+      if (CONSTANT_P (XEXP (x, 0))
+         && ! TARGET_LIVE_G0)
        fputs ("%g0+", file);
       output_address (XEXP (x, 0));
       fputc (']', file);
@@ -4847,10 +4901,21 @@ sparc_flat_eligible_for_epilogue_delay (trial, slot)
      rtx trial;
      int slot;
 {
-  if (get_attr_length (trial) == 1
-      && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (trial))
-      && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (trial)))
+  rtx pat = PATTERN (trial);
+
+  if (get_attr_length (trial) != 1)
+    return 0;
+
+  /* If %g0 is live, there are lots of things we can't handle.
+     Rather than trying to find them all now, let's punt and only
+     optimize things as necessary.  */
+  if (TARGET_LIVE_G0)
+    return 0;
+
+  if (! reg_mentioned_p (stack_pointer_rtx, pat)
+      && ! reg_mentioned_p (frame_pointer_rtx, pat))
     return 1;
+
   return 0;
 }
 \f
index 0b54f24..b634957 100644 (file)
@@ -369,6 +369,13 @@ extern int target_flags;
 #define MASK_STACK_BIAS 0x80000
 #define TARGET_STACK_BIAS (target_flags & MASK_STACK_BIAS)
 
+/* Non-zero means %g0 is a normal register.
+   We still clobber it as necessary, but we can't rely on it always having
+   a zero value.
+   We don't bother to support this in true 64 bit mode.  */
+#define MASK_LIVE_G0 0x100000
+#define TARGET_LIVE_G0 (target_flags & MASK_LIVE_G0)
+
 /* Macro to define tables used to set the flags.
    This is a list in braces of pairs in braces,
    each pair being { "NAME", VALUE }
@@ -392,6 +399,7 @@ extern int target_flags;
     {"no-app-regs", -MASK_APP_REGS},   \
     {"hard-quad-float", MASK_HARD_QUAD}, \
     {"soft-quad-float", -MASK_HARD_QUAD}, \
+    {"live-g0", MASK_LIVE_G0},         \
     /* ??? These are coerced to -mcpu=.  Delete in 2.9.  */ \
     {"cypress", 0},                    \
     {"sparclite", 0},                  \
@@ -673,18 +681,23 @@ extern struct sparc_cpu_select sparc_select[];
    accessible.  We still account for them to simplify register computations
    (eg: in CLASS_MAX_NREGS).  There are also 4 fp condition code registers, so
    32+32+32+4 == 100.
-   Register 0 is used as the integer condition code register.  */
+   Register 100 is used as the integer condition code register.  */
 
-#define FIRST_PSEUDO_REGISTER 100
+#define FIRST_PSEUDO_REGISTER 101
 
 /* Additional V9 fp regs.  */
 #define SPARC_FIRST_V9_FP_REG 64
-#define SPARC_LAST_V9_FP_REG  99
+#define SPARC_LAST_V9_FP_REG  95
+/* V9 %fcc[0123].  V8 uses (figuratively) %fcc0.  */
+#define SPARC_FIRST_V9_FCC_REG 96
+#define SPARC_LAST_V9_FCC_REG  99
+/* V8 fcc reg.  */
+#define SPARC_FCC_REG 96
+/* Integer CC reg.  We don't distinguish %icc from %xcc.  */
+#define SPARC_ICC_REG 100
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.
-   g0 is used for the condition code and not to represent %g0, which is
-   hardwired to 0, so reg 0 is *not* fixed.
    On non-v9 systems:
    g1 is free to use as temporary.
    g2-g4 are reserved for applications.  Gcc normally uses them as
@@ -705,7 +718,7 @@ extern struct sparc_cpu_select sparc_select[];
 */
 
 #define FIXED_REGISTERS  \
- {0, 0, 0, 0, 0, 0, 1, 1,      \
+ {1, 0, 0, 0, 0, 0, 1, 1,      \
   0, 0, 0, 0, 0, 0, 1, 0,      \
   0, 0, 0, 0, 0, 0, 0, 0,      \
   0, 0, 0, 0, 0, 0, 1, 1,      \
@@ -720,7 +733,7 @@ extern struct sparc_cpu_select sparc_select[];
   0, 0, 0, 0, 0, 0, 0, 0,      \
   0, 0, 0, 0, 0, 0, 0, 0,      \
                                \
-  0, 0, 0, 0}
+  0, 0, 0, 0, 0}
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -745,10 +758,10 @@ extern struct sparc_cpu_select sparc_select[];
   1, 1, 1, 1, 1, 1, 1, 1,      \
   1, 1, 1, 1, 1, 1, 1, 1,      \
                                \
-  1, 1, 1, 1}
+  1, 1, 1, 1, 1}
 
-/* If !TARGET_FPU, then make the fp registers fixed so that they won't
-   be allocated.  On v9, also make the fp cc regs fixed.  */
+/* If !TARGET_FPU, then make the fp registers and fp cc regs fixed so that
+   they won't be allocated.  */
 
 #define CONDITIONAL_REGISTER_USAGE                             \
 do                                                             \
@@ -772,11 +785,16 @@ do                                                                \
             regno <= SPARC_LAST_V9_FP_REG;                     \
             regno++)                                           \
          fixed_regs[regno] = 1;                                \
+       /* %fcc0 is used by v8 and v9.  */                      \
+       for (regno = SPARC_FIRST_V9_FCC_REG + 1;                \
+            regno <= SPARC_LAST_V9_FCC_REG;                    \
+            regno++)                                           \
+         fixed_regs[regno] = 1;                                \
       }                                                                \
     if (! TARGET_FPU)                                          \
       {                                                                \
        int regno;                                              \
-       for (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno++) \
+       for (regno = 32; regno < SPARC_LAST_V9_FCC_REG; regno++) \
          fixed_regs[regno] = 1;                                \
       }                                                                \
     /* Don't unfix g2-g4 if they were fixed with -ffixed-.  */ \
@@ -982,7 +1000,12 @@ extern int sparc_mode_class[];
    have a class that is the union of FPCC_REGS with either of the others,
    it is important that it appear first.  Otherwise the compiler will die
    trying to compile _fixunsdfsi because fix_truncdfsi2 won't match its
-   constraints.  */
+   constraints.
+
+   It is important that SPARC_ICC_REG have class NO_REGS.  Otherwise combine
+   may try to use it to hold an SImode value.  See register_operand.
+   ??? Should %fcc[0123] be handled similarily?
+*/
 
 enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS,
                 GENERAL_OR_FP_REGS, GENERAL_OR_EXTRA_FP_REGS,
@@ -1001,21 +1024,18 @@ enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS,
    of length N_REG_CLASSES.  */
 
 #define REG_CLASS_CONTENTS \
-  {{0, 0, 0, 0}, {0, 0, 0, 0xf}, {-2, 0, 0, 0}, \
-   {0, -1, 0, 0}, {0, -1, -1, 0}, {-2, -1, 0, 0}, {-2, -1, -1, 0}, \
-   {-2, -1, -1, 0xf}}
+  {{0, 0, 0, 0}, {0, 0, 0, 0xf}, \
+   {-1, 0, 0, 0}, {0, -1, 0, 0}, {0, -1, -1, 0}, \
+   {-1, -1, 0, 0}, {-1, -1, -1, 0}, {-1, -1, -1, 0x1f}}
 
 /* The same information, inverted:
    Return the class number of the smallest class containing
    reg number REGNO.  This could be a conditional expression
    or could index an array.  */
 
-#define REGNO_REG_CLASS(REGNO) \
-  ((REGNO) == 0 ? NO_REGS              \
-   : (REGNO) < 32 ? GENERAL_REGS       \
-   : (REGNO) < 64 ? FP_REGS            \
-   : (REGNO) < 96 ? EXTRA_FP_REGS      \
-   : FPCC_REGS)
+extern enum reg_class sparc_regno_reg_class[];
+
+#define REGNO_REG_CLASS(REGNO) sparc_regno_reg_class[(REGNO)]
 
 /* This is the order in which to allocate registers normally.  
    
@@ -1040,7 +1060,7 @@ enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS,
   64, 65, 66, 67, 68, 69, 70, 71,      /* %f32-%f39 */ \
   72, 73, 74, 75, 76, 77, 78, 79,      /* %f40-%f47 */ \
   32, 33,                              /* %f0,%f1 */   \
-  96, 97, 98, 99,                      /* %fcc0-3 */   \
+  96, 97, 98, 99, 100,                 /* %fcc0-3, %icc */ \
   1, 4, 5, 6, 7, 0, 14, 30}
 
 /* This is the order in which to allocate registers for
@@ -1062,7 +1082,7 @@ enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS,
   64, 65, 66, 67, 68, 69, 70, 71,      \
   72, 73, 74, 75, 76, 77, 78, 79,      \
   32, 33,                              \
-  96, 97, 98, 99,                      \
+  96, 97, 98, 99, 100,                 \
   1, 4, 5, 6, 7, 0, 14, 30, 31}
 
 #define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
@@ -1086,7 +1106,7 @@ enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS,
   1, 1, 1, 1, 1, 1, 1, 1,      \
   1, 1, 1, 1, 1, 1, 1, 1,      \
   1, 1, 1, 1, 1, 1, 1, 1,      \
-  1, 1, 1, 1}
+  1, 1, 1, 1, 1}
 
 extern char leaf_reg_remap[];
 #define LEAF_REG_REMAP(REGNO) (leaf_reg_remap[REGNO])
@@ -1110,6 +1130,7 @@ extern char leaf_reg_remap[];
     : NO_REGS)                 \
  : ((C) == 'f' ? FP_REGS       \
     : (C) == 'e' ? FP_REGS     \
+    : (C) == 'c' ? FPCC_REGS   \
     : NO_REGS))
 
 /* The letters I, J, K, L and M in a register constraint string
@@ -1624,7 +1645,7 @@ extern int leaf_function;
 #define FUNCTION_PROLOGUE(FILE, SIZE) \
   (TARGET_FLAT ? sparc_flat_output_function_prologue (FILE, SIZE) \
    : output_function_prologue (FILE, SIZE, leaf_function))
-
+\f
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */
 
@@ -1981,7 +2002,7 @@ while(0)
   asm ("LSFLGNZVC" ID ":");\
   asm ("       unimp");\
   asm ("LFLGRET" ID ":");
-
+\f
 /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
    the stack pointer does not matter.  The value is tested only in
    functions that have frame pointers.
@@ -2136,15 +2157,16 @@ extern struct rtx_def *sparc_builtin_saveregs ();
    has been allocated, which happens in local-alloc.c.  */
 
 #define REGNO_OK_FOR_INDEX_P(REGNO) \
-(((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) && (REGNO) != 0)
+((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32)
 #define REGNO_OK_FOR_BASE_P(REGNO) \
-(((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) && (REGNO) != 0)
+((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32)
 #define REGNO_OK_FOR_FP_P(REGNO) \
   (((unsigned) (REGNO) - 32 < (TARGET_V9 ? 64 : 32)) \
    || ((unsigned) reg_renumber[REGNO] - 32 < (TARGET_V9 ? 64 : 32)))
 #define REGNO_OK_FOR_CCFP_P(REGNO) \
  (TARGET_V9 \
-  && ((unsigned) (REGNO) - 96 < 4) || ((unsigned) reg_renumber[REGNO] - 96 < 4))
+  && (((unsigned) (REGNO) - 96 < 4) \
+      || ((unsigned) reg_renumber[REGNO] - 96 < 4)))
 
 /* Now macros that check whether X is a register and also,
    strictly, whether it is in a specified class.
@@ -2210,11 +2232,11 @@ extern struct rtx_def *sparc_builtin_saveregs ();
 /* Nonzero if X is a hard reg that can be used as an index
    or if it is a pseudo reg.  */
 #define REG_OK_FOR_INDEX_P(X) \
-  (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32) && REGNO (X) != 0)
+  (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32))
 /* Nonzero if X is a hard reg that can be used as a base reg
    or if it is a pseudo reg.  */
 #define REG_OK_FOR_BASE_P(X) \
-  (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32) && REGNO (X) != 0)
+  (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32))
 
 /* 'T', 'U' are for aligned memory loads which aren't needed for v9.  */
 
@@ -2249,8 +2271,9 @@ extern struct rtx_def *sparc_builtin_saveregs ();
    : (! TARGET_ARCH64 && (C) == 'U')                   \
    ? (GET_CODE (OP) == REG                             \
       && (REGNO (OP) < FIRST_PSEUDO_REGISTER           \
-         || reg_renumber[REGNO (OP)] > 0)              \
-      && register_ok_for_ldd (OP)) : 0)
+         || reg_renumber[REGNO (OP)] >= 0)             \
+      && register_ok_for_ldd (OP))                     \
+   : 0)
 #endif
 \f
 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
@@ -2468,8 +2491,7 @@ extern struct rtx_def *legitimize_pic_address ();
    We also have two modes to indicate that the relevant condition code is
    in the floating-point condition code register.  One for comparisons which
    will generate an exception if the result is unordered (CCFPEmode) and
-   one for comparisons which will never trap (CCFPmode).  This really should
-   be a separate register, but we don't want to go to 65 registers.
+   one for comparisons which will never trap (CCFPmode).
 
    CCXmode and CCX_NOOVmode are only used by v9.  */
 
@@ -2703,16 +2725,12 @@ extern struct rtx_def *legitimize_pic_address ();
  "%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47",       \
  "%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55",       \
  "%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63",       \
- "%fcc0", "%fcc1", "%fcc2", "%fcc3"}
-
-/* Define additional names for use in asm clobbers and asm declarations.
+ "%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc"}
 
-   We define the fake Condition Code register as an alias for reg 0 (which
-   is our `condition code' register), so that condition codes can easily
-   be clobbered by an asm.  No such register actually exists.  Condition
-   codes are partly stored in the PSR and partly in the FSR.  */
+/* Define additional names for use in asm clobbers and asm declarations.  */
 
-#define ADDITIONAL_REGISTER_NAMES      {"ccr", 0, "cc", 0}
+#define ADDITIONAL_REGISTER_NAMES \
+{{"ccr", SPARC_ICC_REG}, {"cc", SPARC_ICC_REG}}
 
 /* How to renumber registers for dbx and gdb.  */
 
index 4598922..fc5279b 100644 (file)
@@ -28,6 +28,9 @@
 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
+;;
+;; -mlive-g0 is *not* supported for TARGET_ARCH64, so we don't bother to
+;; test TARGET_LIVE_G0 if we have TARGET_ARCH64.
 
 ;; Attribute for cpu type.
 ;; These must match the values for enum processor_type in sparc.h.
   (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
        (const_string "arch32bit"))))
 
+;; Whether -mlive-g0 is in effect.
+(define_attr "live_g0" "no,yes"
+ (const
+  (cond [(symbol_ref "TARGET_LIVE_G0") (const_string "yes")]
+       (const_string "no"))))
+
 ;; Insn type.  Used to default other attribute values.
 
 ;; type "unary" insns have one input operand (1) and one output operand (0)
 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
 
 (define_expand "cmpsi"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC (match_operand:SI 0 "register_operand" "")
                    (match_operand:SI 1 "arith_operand" "")))]
   ""
 }")
 
 (define_expand "cmpdi"
-  [(set (reg:CCX 0)
+  [(set (reg:CCX 100)
        (compare:CCX (match_operand:DI 0 "register_operand" "")
                     (match_operand:DI 1 "arith_double_operand" "")))]
   "TARGET_ARCH64"
 }")
 
 (define_expand "cmpsf"
-  [(set (reg:CCFP 0)
+  ;; The 96 here isn't ever used by anyone.
+  [(set (reg:CCFP 96)
        (compare:CCFP (match_operand:SF 0 "register_operand" "")
                      (match_operand:SF 1 "register_operand" "")))]
   "TARGET_FPU"
 }")
 
 (define_expand "cmpdf"
-  [(set (reg:CCFP 0)
+  ;; The 96 here isn't ever used by anyone.
+  [(set (reg:CCFP 96)
        (compare:CCFP (match_operand:DF 0 "register_operand" "")
                      (match_operand:DF 1 "register_operand" "")))]
   "TARGET_FPU"
 }")
 
 (define_expand "cmptf"
-  [(set (reg:CCFP 0)
+  ;; The 96 here isn't ever used by anyone.
+  [(set (reg:CCFP 96)
        (compare:CCFP (match_operand:TF 0 "register_operand" "")
                      (match_operand:TF 1 "register_operand" "")))]
   "TARGET_FPU"
 ;; Now the compare DEFINE_INSNs.
 
 (define_insn "*cmpsi_insn"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC (match_operand:SI 0 "register_operand" "r")
                    (match_operand:SI 1 "arith_operand" "rI")))]
   ""
   "cmp %0,%1"
   [(set_attr "type" "compare")])
 
-(define_insn "*cmpsf_fpe_sp32"
-  [(set (reg:CCFPE 0)
-       (compare:CCFPE (match_operand:SF 0 "register_operand" "f")
-                      (match_operand:SF 1 "register_operand" "f")))]
-  "! TARGET_V9 && TARGET_FPU"
-  "fcmpes %0,%1"
-  [(set_attr "type" "fpcmp")])
-
-(define_insn "*cmpdf_fpe_sp32"
-  [(set (reg:CCFPE 0)
-       (compare:CCFPE (match_operand:DF 0 "register_operand" "e")
-                      (match_operand:DF 1 "register_operand" "e")))]
-  "! TARGET_V9 && TARGET_FPU"
-  "fcmped %0,%1"
-  [(set_attr "type" "fpcmp")])
-
-(define_insn "*cmptf_fpe_sp32"
-  [(set (reg:CCFPE 0)
-       (compare:CCFPE (match_operand:TF 0 "register_operand" "e")
-                      (match_operand:TF 1 "register_operand" "e")))]
-  "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
-  "fcmpeq %0,%1"
-  [(set_attr "type" "fpcmp")])
-
-(define_insn "*cmpsf_fp_sp32"
-  [(set (reg:CCFP 0)
-       (compare:CCFP (match_operand:SF 0 "register_operand" "f")
-                     (match_operand:SF 1 "register_operand" "f")))]
-  "! TARGET_V9 && TARGET_FPU"
-  "fcmps %0,%1"
-  [(set_attr "type" "fpcmp")])
-
-(define_insn "*cmpdf_fp_sp32"
-  [(set (reg:CCFP 0)
-       (compare:CCFP (match_operand:DF 0 "register_operand" "e")
-                     (match_operand:DF 1 "register_operand" "e")))]
-  "! TARGET_V9 && TARGET_FPU"
-  "fcmpd %0,%1"
-  [(set_attr "type" "fpcmp")])
-
-(define_insn "*cmptf_fp_sp32"
-  [(set (reg:CCFP 0)
-       (compare:CCFP (match_operand:TF 0 "register_operand" "e")
-                     (match_operand:TF 1 "register_operand" "e")))]
-  "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
-  "fcmpq %0,%1"
-  [(set_attr "type" "fpcmp")])
-
 (define_insn "*cmpdi_sp64"
-  [(set (reg:CCX 0)
+  [(set (reg:CCX 100)
        (compare:CCX (match_operand:DI 0 "register_operand" "r")
                     (match_operand:DI 1 "arith_double_operand" "rHI")))]
   "TARGET_ARCH64"
   "cmp %0,%1"
   [(set_attr "type" "compare")])
 
-(define_insn "*cmpsf_fpe_sp64"
-  [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
+(define_insn "*cmpsf_fpe"
+  [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
        (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
                       (match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_V9 && TARGET_FPU"
-  "fcmpes %0,%1,%2"
+  "TARGET_FPU"
+  "*
+{
+  if (TARGET_V9)
+    return \"fcmpes %0,%1,%2\";
+  return \"fcmpes %1,%2\";
+}"
   [(set_attr "type" "fpcmp")])
 
-(define_insn "*cmpdf_fpe_sp64"
-  [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
+(define_insn "*cmpdf_fpe"
+  [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
        (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
                       (match_operand:DF 2 "register_operand" "e")))]
-  "TARGET_V9 && TARGET_FPU"
-  "fcmped %0,%1,%2"
+  "TARGET_FPU"
+  "*
+{
+  if (TARGET_V9)
+    return \"fcmped %0,%1,%2\";
+  return \"fcmped %1,%2\";
+}"
   [(set_attr "type" "fpcmp")])
 
-(define_insn "*cmptf_fpe_sp64"
-  [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
+(define_insn "*cmptf_fpe"
+  [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
        (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
                       (match_operand:TF 2 "register_operand" "e")))]
-  "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
-  "fcmpeq %0,%1,%2"
+  "TARGET_FPU && TARGET_HARD_QUAD"
+  "*
+{
+  if (TARGET_V9)
+    return \"fcmpeq %0,%1,%2\";
+  return \"fcmpeq %1,%2\";
+}"
   [(set_attr "type" "fpcmp")])
 
-(define_insn "*cmpsf_fp_sp64"
-  [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
+(define_insn "*cmpsf_fp"
+  [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
        (compare:CCFP (match_operand:SF 1 "register_operand" "f")
                      (match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_V9 && TARGET_FPU"
-  "fcmps %0,%1,%2"
+  "TARGET_FPU"
+  "*
+{
+  if (TARGET_V9)
+    return \"fcmps %0,%1,%2\";
+  return \"fcmps %1,%2\";
+}"
   [(set_attr "type" "fpcmp")])
 
-(define_insn "*cmpdf_fp_sp64"
-  [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
+(define_insn "*cmpdf_fp"
+  [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
        (compare:CCFP (match_operand:DF 1 "register_operand" "e")
                      (match_operand:DF 2 "register_operand" "e")))]
-  "TARGET_V9 && TARGET_FPU"
-  "fcmpd %0,%1,%2"
+  "TARGET_FPU"
+  "*
+{
+  if (TARGET_V9)
+    return \"fcmpd %0,%1,%2\";
+  return \"fcmpd %1,%2\";
+}"
   [(set_attr "type" "fpcmp")])
 
-(define_insn "*cmptf_fp_sp64"
-  [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
+(define_insn "*cmptf_fp"
+  [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
        (compare:CCFP (match_operand:TF 1 "register_operand" "e")
                      (match_operand:TF 2 "register_operand" "e")))]
-  "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
-  "fcmpq %0,%1,%2"
+  "TARGET_FPU && TARGET_HARD_QUAD"
+  "*
+{
+  if (TARGET_V9)
+    return \"fcmpq %0,%1,%2\";
+  return \"fcmpq %1,%2\";
+}"
   [(set_attr "type" "fpcmp")])
 \f
 ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
                (match_operand:SI 2 "register_operand" "")))
    (parallel [(set (match_operand:SI 0 "register_operand" "")
                   (eq:SI (match_dup 3) (const_int 0)))
-             (clobber (reg:CC 0))])]
-  ""
+             (clobber (reg:CC 100))])]
+  "! TARGET_LIVE_G0"
   "{ operands[3] = gen_reg_rtx (SImode); }")
 
 (define_expand "seqdi_special"
                (match_operand:DI 2 "register_operand" "")))
    (parallel [(set (match_operand:DI 0 "register_operand" "")
                   (eq:DI (match_dup 3) (const_int 0)))
-             (clobber (reg:CCX 0))])]
+             (clobber (reg:CCX 100))])]
   "TARGET_ARCH64"
   "{ operands[3] = gen_reg_rtx (DImode); }")
 
                (match_operand:SI 2 "register_operand" "")))
    (parallel [(set (match_operand:SI 0 "register_operand" "")
                   (ne:SI (match_dup 3) (const_int 0)))
-             (clobber (reg:CC 0))])]
-  ""
+             (clobber (reg:CC 100))])]
+  "! TARGET_LIVE_G0"
   "{ operands[3] = gen_reg_rtx (SImode); }")
 
 (define_expand "snedi_special"
                (match_operand:DI 2 "register_operand" "")))
    (parallel [(set (match_operand:DI 0 "register_operand" "")
                   (ne:DI (match_dup 3) (const_int 0)))
-             (clobber (reg:CCX 0))])]
+             (clobber (reg:CCX 100))])]
   "TARGET_ARCH64"
   "{ operands[3] = gen_reg_rtx (DImode); }")
 
                (match_operand:DI 2 "register_operand" "")))
    (parallel [(set (match_operand:SI 0 "register_operand" "")
                   (eq:DI (match_dup 3) (const_int 0)))
-             (clobber (reg:CCX 0))])]
+             (clobber (reg:CCX 100))])]
   "TARGET_ARCH64"
   "{ operands[3] = gen_reg_rtx (DImode); }")
 
                (match_operand:DI 2 "register_operand" "")))
    (parallel [(set (match_operand:SI 0 "register_operand" "")
                   (ne:DI (match_dup 3) (const_int 0)))
-             (clobber (reg:CCX 0))])]
+             (clobber (reg:CCX 100))])]
   "TARGET_ARCH64"
   "{ operands[3] = gen_reg_rtx (DImode); }")
 
                (match_operand:SI 2 "register_operand" "")))
    (parallel [(set (match_operand:DI 0 "register_operand" "")
                   (eq:SI (match_dup 3) (const_int 0)))
-             (clobber (reg:CC 0))])]
+             (clobber (reg:CC 100))])]
   "TARGET_ARCH64"
   "{ operands[3] = gen_reg_rtx (SImode); }")
 
                (match_operand:SI 2 "register_operand" "")))
    (parallel [(set (match_operand:DI 0 "register_operand" "")
                   (ne:SI (match_dup 3) (const_int 0)))
-             (clobber (reg:CC 0))])]
+             (clobber (reg:CC 100))])]
   "TARGET_ARCH64"
   "{ operands[3] = gen_reg_rtx (SImode); }")
 
 (define_expand "seq"
   [(set (match_operand:SI 0 "intreg_operand" "")
        (eq:SI (match_dup 1) (const_int 0)))]
-  ""
+  "! TARGET_LIVE_G0"
   "
 {
   if (GET_MODE (sparc_compare_op0) == SImode)
 (define_expand "sne"
   [(set (match_operand:SI 0 "intreg_operand" "")
        (ne:SI (match_dup 1) (const_int 0)))]
-  ""
+  "! TARGET_LIVE_G0"
   "
 {
   if (GET_MODE (sparc_compare_op0) == SImode)
 (define_expand "sgt"
   [(set (match_operand:SI 0 "intreg_operand" "")
        (gt:SI (match_dup 1) (const_int 0)))]
-  ""
+  "! TARGET_LIVE_G0"
   "
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
 (define_expand "slt"
   [(set (match_operand:SI 0 "intreg_operand" "")
        (lt:SI (match_dup 1) (const_int 0)))]
-  ""
+  "! TARGET_LIVE_G0"
   "
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
 (define_expand "sge"
   [(set (match_operand:SI 0 "intreg_operand" "")
        (ge:SI (match_dup 1) (const_int 0)))]
-  ""
+  "! TARGET_LIVE_G0"
   "
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
 (define_expand "sle"
   [(set (match_operand:SI 0 "intreg_operand" "")
        (le:SI (match_dup 1) (const_int 0)))]
-  ""
+  "! TARGET_LIVE_G0"
   "
 {
   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
 (define_expand "sgtu"
   [(set (match_operand:SI 0 "intreg_operand" "")
        (gtu:SI (match_dup 1) (const_int 0)))]
-  ""
+  "! TARGET_LIVE_G0"
   "
 {
   if (! TARGET_V9)
 (define_expand "sltu"
   [(set (match_operand:SI 0 "intreg_operand" "")
        (ltu:SI (match_dup 1) (const_int 0)))]
-  ""
+  "! TARGET_LIVE_G0"
   "
 {
   if (TARGET_V9)
 (define_expand "sgeu"
   [(set (match_operand:SI 0 "intreg_operand" "")
        (geu:SI (match_dup 1) (const_int 0)))]
-  ""
+  "! TARGET_LIVE_G0"
   "
 {
   if (TARGET_V9)
 (define_expand "sleu"
   [(set (match_operand:SI 0 "intreg_operand" "")
        (leu:SI (match_dup 1) (const_int 0)))]
-  ""
+  "! TARGET_LIVE_G0"
   "
 {
   if (! TARGET_V9)
   [(set (match_operand:SI 0 "register_operand" "=r")
        (ne:SI (match_operand:SI 1 "register_operand" "r")
               (const_int 0)))
-   (clobber (reg:CC 0))]
-  ""
+   (clobber (reg:CC 100))]
+  "! TARGET_LIVE_G0"
   "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
   [(set_attr "type" "unary")
    (set_attr "length" "2")])
   [(set (match_operand:SI 0 "register_operand" "=r")
        (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
                       (const_int 0))))
-   (clobber (reg:CC 0))]
-  ""
+   (clobber (reg:CC 100))]
+  "! TARGET_LIVE_G0"
   "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
   [(set_attr "type" "unary")
    (set_attr "length" "2")])
   [(set (match_operand:DI 0 "register_operand" "=r")
        (ne:SI (match_operand:SI 1 "register_operand" "r")
               (const_int 0)))
-   (clobber (reg:CC 0))]
+   (clobber (reg:CC 100))]
   "TARGET_ARCH64"
   "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
   [(set_attr "type" "unary")
   [(set (match_operand:DI 0 "register_operand" "=r")
        (ne:DI (match_operand:DI 1 "register_operand" "r")
               (const_int 0)))
-   (clobber (reg:CCX 0))]
+   (clobber (reg:CCX 100))]
   "TARGET_ARCH64"
   "mov 0,%0\;movrnz %1,1,%0"
   [(set_attr "type" "unary")
   [(set (match_operand:DI 0 "register_operand" "=r")
        (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
                       (const_int 0))))
-   (clobber (reg:CCX 0))]
+   (clobber (reg:CCX 100))]
   "TARGET_ARCH64"
   "mov 0,%0\;movrnz %1,-1,%0"
   [(set_attr "type" "unary")
   [(set (match_operand:SI 0 "register_operand" "=r")
        (ne:DI (match_operand:DI 1 "register_operand" "r")
               (const_int 0)))
-   (clobber (reg:CCX 0))]
-  "! TARGET_ARCH64"
+   (clobber (reg:CCX 100))]
+  "! TARGET_ARCH64 && ! TARGET_LIVE_G0"
   "xor %1,%R1,%0\;subcc %%g0,%0,%%g0\;addx %%g0,0,%0"
   [(set_attr "type" "unary")
    (set_attr "length" "3")])
   [(set (match_operand:SI 0 "register_operand" "=r")
        (ne:DI (match_operand:DI 1 "register_operand" "r")
               (const_int 0)))
-   (clobber (reg:CCX 0))]
+   (clobber (reg:CCX 100))]
   "TARGET_ARCH64"
   "mov 0,%0\;movrnz %1,1,%0"
   [(set_attr "type" "unary")
   [(set (match_operand:SI 0 "register_operand" "=r")
        (eq:SI (match_operand:SI 1 "register_operand" "r")
               (const_int 0)))
-   (clobber (reg:CC 0))]
-  ""
+   (clobber (reg:CC 100))]
+  "! TARGET_LIVE_G0"
   "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
   [(set_attr "type" "unary")
    (set_attr "length" "2")])
   [(set (match_operand:SI 0 "register_operand" "=r")
        (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
                       (const_int 0))))
-   (clobber (reg:CC 0))]
-  ""
+   (clobber (reg:CC 100))]
+  "! TARGET_LIVE_G0"
   "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
   [(set_attr "type" "unary")
    (set_attr "length" "2")])
   [(set (match_operand:DI 0 "register_operand" "=r")
        (eq:SI (match_operand:SI 1 "register_operand" "r")
               (const_int 0)))
-   (clobber (reg:CC 0))]
+   (clobber (reg:CC 100))]
   "TARGET_ARCH64"
   "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
   [(set_attr "type" "unary")
   [(set (match_operand:DI 0 "register_operand" "=r")
        (eq:DI (match_operand:DI 1 "register_operand" "r")
               (const_int 0)))
-   (clobber (reg:CCX 0))]
+   (clobber (reg:CCX 100))]
   "TARGET_ARCH64"
   "mov 0,%0\;movrz %1,1,%0"
   [(set_attr "type" "unary")
   [(set (match_operand:DI 0 "register_operand" "=r")
        (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
                       (const_int 0))))
-   (clobber (reg:CCX 0))]
+   (clobber (reg:CCX 100))]
   "TARGET_ARCH64"
   "mov 0,%0\;movrz %1,-1,%0"
   [(set_attr "type" "unary")
   [(set (match_operand:SI 0 "register_operand" "=r")
        (eq:DI (match_operand:DI 1 "register_operand" "r")
               (const_int 0)))
-   (clobber (reg:CCX 0))]
-  "! TARGET_ARCH64"
+   (clobber (reg:CCX 100))]
+  "! TARGET_ARCH64 && ! TARGET_LIVE_G0"
   "xor %1,%R1,%0\;subcc %%g0,%0,%%g0\;subx %%g0,-1,%0"
   [(set_attr "type" "unary")
    (set_attr "length" "3")])
   [(set (match_operand:SI 0 "register_operand" "=r")
        (eq:DI (match_operand:DI 1 "register_operand" "r")
               (const_int 0)))
-   (clobber (reg:CCX 0))]
+   (clobber (reg:CCX 100))]
   "TARGET_ARCH64"
   "mov 0,%0\;movrz %1,1,%0"
   [(set_attr "type" "unary")
        (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
                        (const_int 0))
                 (match_operand:SI 2 "register_operand" "r")))
-   (clobber (reg:CC 0))]
-  ""
+   (clobber (reg:CC 100))]
+  "! TARGET_LIVE_G0"
   "subcc %%g0,%1,%%g0\;addx %2,0,%0"
   [(set_attr "length" "2")])
 
        (minus:SI (match_operand:SI 2 "register_operand" "r")
                  (ne:SI (match_operand:SI 1 "register_operand" "r")
                         (const_int 0))))
-   (clobber (reg:CC 0))]
-  ""
+   (clobber (reg:CC 100))]
+  "! TARGET_LIVE_G0"
   "subcc %%g0,%1,%%g0\;subx %2,0,%0"
   [(set_attr "length" "2")])
 
        (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
                        (const_int 0))
                 (match_operand:SI 2 "register_operand" "r")))
-   (clobber (reg:CC 0))]
-  ""
+   (clobber (reg:CC 100))]
+  "! TARGET_LIVE_G0"
   "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
   [(set_attr "length" "2")])
 
        (minus:SI (match_operand:SI 2 "register_operand" "r")
                  (eq:SI (match_operand:SI 1 "register_operand" "r")
                         (const_int 0))))
-   (clobber (reg:CC 0))]
-  ""
+   (clobber (reg:CC 100))]
+  "! TARGET_LIVE_G0"
   "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
   [(set_attr "length" "2")])
 
 
 (define_insn "*sltu_insn"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (ltu:SI (reg:CC 0) (const_int 0)))]
-  ""
+       (ltu:SI (reg:CC 100) (const_int 0)))]
+  "! TARGET_LIVE_G0"
   "addx %%g0,0,%0"
   [(set_attr "type" "misc")])
 
 (define_insn "*neg_sltu_insn"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
-  ""
+       (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
+  "! TARGET_LIVE_G0"
   "subx %%g0,0,%0"
   [(set_attr "type" "misc")])
 
 ;; ??? Combine should canonicalize these next two to the same pattern.
 (define_insn "*neg_sltu_minus_x"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0)))
+       (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
                  (match_operand:SI 1 "arith_operand" "rI")))]
-  ""
+  "! TARGET_LIVE_G0"
   "subx %%g0,%1,%0"
   [(set_attr "type" "unary")])
 
 (define_insn "*neg_sltu_plus_x"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
+       (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
                         (match_operand:SI 1 "arith_operand" "rI"))))]
-  ""
+  "! TARGET_LIVE_G0"
   "subx %%g0,%1,%0"
   [(set_attr "type" "unary")])
 
 (define_insn "*sgeu_insn"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (geu:SI (reg:CC 0) (const_int 0)))]
-  ""
+       (geu:SI (reg:CC 100) (const_int 0)))]
+  "! TARGET_LIVE_G0"
   "subx %%g0,-1,%0"
   [(set_attr "type" "misc")])
 
 (define_insn "*neg_sgeu_insn"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
-  ""
+       (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
+  "! TARGET_LIVE_G0"
   "addx %%g0,-1,%0"
   [(set_attr "type" "misc")])
 
 
 (define_insn "*sltu_plus_x"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
+       (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
                 (match_operand:SI 1 "arith_operand" "rI")))]
-  ""
+  "! TARGET_LIVE_G0"
   "addx %%g0,%1,%0"
   [(set_attr "type" "unary")])
 
 (define_insn "*sltu_plus_x_plus_y"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
+       (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
                 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
                          (match_operand:SI 2 "arith_operand" "rI"))))]
   ""
 (define_insn "*x_minus_sltu"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (minus:SI (match_operand:SI 1 "register_operand" "r")
-                 (ltu:SI (reg:CC 0) (const_int 0))))]
+                 (ltu:SI (reg:CC 100) (const_int 0))))]
   ""
   "subx %1,0,%0"
   [(set_attr "type" "unary")])
   [(set (match_operand:SI 0 "register_operand" "=r")
        (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
                            (match_operand:SI 2 "arith_operand" "rI"))
-                 (ltu:SI (reg:CC 0) (const_int 0))))]
+                 (ltu:SI (reg:CC 100) (const_int 0))))]
   ""
   "subx %1,%2,%0")
 
 (define_insn "*x_minus_sltu_plus_y"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (minus:SI (match_operand:SI 1 "register_operand" "r")
-                 (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
+                 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
                           (match_operand:SI 2 "arith_operand" "rI"))))]
   ""
   "subx %1,%2,%0")
 
 (define_insn "*sgeu_plus_x"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (plus:SI (geu:SI (reg:CC 0) (const_int 0))
+       (plus:SI (geu:SI (reg:CC 100) (const_int 0))
                 (match_operand:SI 1 "register_operand" "r")))]
   ""
   "subx %1,-1,%0"
 (define_insn "*x_minus_sgeu"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (minus:SI (match_operand:SI 1 "register_operand" "r")
-                 (geu:SI (reg:CC 0) (const_int 0))))]
+                 (geu:SI (reg:CC 100) (const_int 0))))]
   ""
   "addx %1,-1,%0"
   [(set_attr "type" "unary")])
 
 (define_insn "*scc_si"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (match_operator:SI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
+       (match_operator:SI 2 "noov_compare_op"
+                          [(match_operand 1 "icc_or_fcc_reg_operand" "")
+                           (const_int 0)]))]
   ""
   "* return output_scc_insn (operands, insn); "
   [(set_attr "type" "multi")
 
 (define_insn "*scc_di"
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (match_operator:DI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
+       (match_operator:DI 2 "noov_compare_op"
+                          [(match_operand 1 "icc_or_fcc_reg_operand" "")
+                           (const_int 0)]))]
   "TARGET_ARCH64"
   "* return output_scc_insn (operands, insn); "
   [(set_attr "type" "multi")
 (define_insn "*normal_branch"
   [(set (pc)
        (if_then_else (match_operator 0 "noov_compare_op"
-                                     [(reg 0) (const_int 0)])
+                                     [(reg 100) (const_int 0)])
                      (label_ref (match_operand 1 "" ""))
                      (pc)))]
   ""
   "*
 {
-  return output_cbranch (operands[0], 0, 1, 0,
+  return output_cbranch (operands[0], 1, 0,
                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
                         ! final_sequence);
 }"
 (define_insn "*inverted_branch"
   [(set (pc)
        (if_then_else (match_operator 0 "noov_compare_op"
-                                     [(reg 0) (const_int 0)])
+                                     [(reg 100) (const_int 0)])
                      (pc)
                      (label_ref (match_operand 1 "" ""))))]
   ""
   "*
 {
-  return output_cbranch (operands[0], 0, 1, 1,
+  return output_cbranch (operands[0], 1, 1,
                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
                         ! final_sequence);
 }"
   [(set_attr "type" "branch")])
 
-(define_insn "*normal_fp_branch_sp64"
+(define_insn "*normal_fp_branch"
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
-                                     [(match_operand:CCFP 1 "ccfp_reg_operand" "c")
+       (if_then_else (match_operator 1 "comparison_operator"
+                                     [(match_operand:CCFP 0 "fcc_reg_operand" "c")
                                       (const_int 0)])
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
-  "TARGET_V9"
+  ""
   "*
 {
-  return output_cbranch (operands[0], operands[1], 2, 0,
+  return output_cbranch (operands[1], 2, 0,
                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
                         ! final_sequence);
 }"
   [(set_attr "type" "branch")])
 
-(define_insn "*inverted_fp_branch_sp64"
+(define_insn "*inverted_fp_branch"
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
-                                     [(match_operand:CCFP 1 "ccfp_reg_operand" "c")
+       (if_then_else (match_operator 1 "comparison_operator"
+                                     [(match_operand:CCFP 0 "fcc_reg_operand" "c")
                                       (const_int 0)])
                      (pc)
                      (label_ref (match_operand 2 "" ""))))]
-  "TARGET_V9"
+  ""
   "*
 {
-  return output_cbranch (operands[0], operands[1], 2, 1,
+  return output_cbranch (operands[1], 2, 1,
                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
                         ! final_sequence);
 }"
   [(set_attr "type" "branch")])
 
-(define_insn "*normal_fpe_branch_sp64"
+(define_insn "*normal_fpe_branch"
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
-                                     [(match_operand:CCFPE 1 "ccfp_reg_operand" "c")
+       (if_then_else (match_operator 1 "comparison_operator"
+                                     [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
                                       (const_int 0)])
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
-  "TARGET_V9"
+  ""
   "*
 {
-  return output_cbranch (operands[0], operands[1], 2, 0,
+  return output_cbranch (operands[1], 2, 0,
                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
                         ! final_sequence);
 }"
   [(set_attr "type" "branch")])
 
-(define_insn "*inverted_fpe_branch_sp64"
+(define_insn "*inverted_fpe_branch"
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
-                                     [(match_operand:CCFPE 1 "ccfp_reg_operand" "c")
+       (if_then_else (match_operator 1 "comparison_operator"
+                                     [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
                                       (const_int 0)])
                      (pc)
                      (label_ref (match_operand 2 "" ""))))]
-  "TARGET_V9"
+  ""
   "*
 {
-  return output_cbranch (operands[0], operands[1], 2, 1,
+  return output_cbranch (operands[1], 2, 1,
                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
                         ! final_sequence);
 }"
 (define_insn "*movqi_insn"
   [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
        (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
-  "register_operand (operands[0], QImode)
-   || register_operand (operands[1], QImode)
-   || operands[1] == const0_rtx"
+  "! TARGET_LIVE_G0
+   && (register_operand (operands[0], QImode)
+       || register_operand (operands[1], QImode)
+       || operands[1] == const0_rtx)"
   "@
    mov %1,%0
    sethi %%hi(%a1),%0
   [(set_attr "type" "move,move,load,store")
    (set_attr "length" "1")])
 
+(define_insn "*movqi_insn_liveg0"
+  [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q")
+       (match_operand:QI 1 "move_operand" "r,J,I,K,Q,r"))]
+  "TARGET_LIVE_G0
+   && (register_operand (operands[0], QImode)
+       || register_operand (operands[1], QImode))"
+  "@
+   mov %1,%0
+   and %0,0,%0
+   and %0,0,%0\;or %0,%1,%0
+   sethi %%hi(%a1),%0
+   ldub %1,%0
+   stb %1,%0"
+  [(set_attr "type" "move,move,move,move,load,store")
+   (set_attr "length" "1,1,2,1,1,1")])
+
 (define_insn "*lo_sum_qi"
   [(set (match_operand:QI 0 "register_operand" "=r")
        (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
   [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
        (match_operand:QI 1 "reg_or_0_operand" "rJ"))
    (clobber (match_scratch:SI 2 "=&r"))]
-  "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
+  "(reload_completed || reload_in_progress)
+   && ! TARGET_PTR64"
   "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
   [(set_attr "type" "store")
    (set_attr "length" "2")])
 (define_insn "*movhi_insn"
   [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
        (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
-  "register_operand (operands[0], HImode)
-   || register_operand (operands[1], HImode)
-   || operands[1] == const0_rtx"
+  "! TARGET_LIVE_G0
+   && (register_operand (operands[0], HImode)
+       || register_operand (operands[1], HImode)
+       || operands[1] == const0_rtx)"
   "@
    mov %1,%0
    sethi %%hi(%a1),%0
   [(set_attr "type" "move,move,load,store")
    (set_attr "length" "1")])
 
+(define_insn "*movhi_insn_liveg0"
+  [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q")
+       (match_operand:HI 1 "move_operand" "r,J,I,K,Q,r"))]
+  "TARGET_LIVE_G0
+   && (register_operand (operands[0], HImode)
+       || register_operand (operands[1], HImode))"
+  "@
+   mov %1,%0
+   and %0,0,%0
+   and %0,0,%0\;or %0,%1,%0
+   sethi %%hi(%a1),%0
+   lduh %1,%0
+   sth %1,%0"
+  [(set_attr "type" "move,move,move,move,load,store")
+   (set_attr "length" "1,1,2,1,1,1")])
+
 (define_insn "*lo_sum_hi"
   [(set (match_operand:HI 0 "register_operand" "=r")
        (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
   [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
        (match_operand:HI 1 "reg_or_0_operand" "rJ"))
    (clobber (match_scratch:SI 2 "=&r"))]
-  "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
+  "(reload_completed || reload_in_progress)
+   && ! TARGET_PTR64"
   "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
   [(set_attr "type" "store")
    (set_attr "length" "2")])
 (define_insn "*movsi_insn"
   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q")
        (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))]
-  "register_operand (operands[0], SImode)
-   || register_operand (operands[1], SImode)
-   || operands[1] == const0_rtx"
+  "! TARGET_LIVE_G0
+   && (register_operand (operands[0], SImode)
+       || register_operand (operands[1], SImode)
+       || operands[1] == const0_rtx)"
   "@
    mov %1,%0
    fmovs %1,%0
   [(set_attr "type" "move,fp,move,load,fpload,store,fpstore")
    (set_attr "length" "1")])
 
+(define_insn "*movsi_insn_liveg0"
+  [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,f,r,r,f,Q,Q")
+       (match_operand:SI 1 "move_operand" "r,J,I,!f,K,Q,!Q,r,!f"))]
+  "TARGET_LIVE_G0
+   && (register_operand (operands[0], SImode)
+       || register_operand (operands[1], SImode))"
+  "@
+   mov %1,%0
+   and %0,0,%0
+   and %0,0,%0\;or %0,%1,%0
+   fmovs %1,%0
+   sethi %%hi(%a1),%0
+   ld %1,%0
+   ld %1,%0
+   st %1,%0
+   st %1,%0"
+  [(set_attr "type" "move,move,move,fp,move,load,fpload,store,fpstore")
+   (set_attr "length" "1,1,2,1,1,1,1,1,1")])
+
 (define_insn "*store_si"
   [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
        (match_operand:SI 1 "reg_or_0_operand" "rJ"))
    (clobber (match_scratch:SI 2 "=&r"))]
-  "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
+  "(reload_completed || reload_in_progress)
+   && ! TARGET_PTR64"
   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
   [(set_attr "type" "store")
    (set_attr "length" "2")])
 ;            (clobber (match_dup 0))
 ;            (clobber (match_dup 1))
 ;            (clobber (match_scratch:SI 4 ""))
-;            (clobber (reg:SI 0))
+;            (clobber (reg:SI 100))
 ;            (clobber (reg:SI 1))])]
 ;  ""
 ;  "
 ;   (clobber (match_dup 0))
 ;   (clobber (match_dup 1))
 ;   (clobber (match_scratch:SI 4 "=&r"))
-;   (clobber (reg:SI 0))
+;   (clobber (reg:SI 100))
 ;   (clobber (reg:SI 1))]
 ;  ""
 ;  "* return output_block_move (operands);"
   [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
        (match_operand:SF 1 "reg_or_0_operand" "rfG"))
    (clobber (match_scratch:SI 2 "=&r"))]
-  "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
+  "(reload_completed || reload_in_progress)
+   && ! TARGET_PTR64"
   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
   [(set_attr "type" "store")
    (set_attr "length" "2")])
   [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
        (match_operand:DF 1 "reg_or_0_operand" "re,G"))
    (clobber (match_scratch:SI 2 "=&r,&r"))]
-  "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
+  "(reload_completed || reload_in_progress)
+   && ! TARGET_PTR64"
   "*
 {
   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
   [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
        (match_operand:TF 1 "reg_or_0_operand" "re,G"))
    (clobber (match_scratch:SI 2 "=&r,&r"))]
-  "0 && (reload_completed || reload_in_progress) && ! TARGET_PTR64"
+  "0 && (reload_completed || reload_in_progress)
+   && ! TARGET_PTR64"
   "*
 {
   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
 (define_insn "*movsi_cc_sp64"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (if_then_else (match_operator 1 "comparison_operator"
-                                     [(reg:CC 0) (const_int 0)])
+                                     [(reg:CC 100) (const_int 0)])
                      (match_operand:SI 2 "arith11_operand" "ri")
                      (match_operand:SI 3 "register_operand" "0")))]
   "TARGET_V9"
 (define_insn "*movdi_cc_sp64"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (if_then_else (match_operator 1 "comparison_operator"
-                                     [(reg:CC 0) (const_int 0)])
+                                     [(reg:CC 100) (const_int 0)])
                      (match_operand:DI 2 "arith11_double_operand" "rHI")
                      (match_operand:DI 3 "register_operand" "0")))]
   "TARGET_ARCH64"
 (define_insn "*movsi_ccx_sp64"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (if_then_else (match_operator 1 "comparison_operator"
-                                     [(reg:CCX 0) (const_int 0)])
+                                     [(reg:CCX 100) (const_int 0)])
                      (match_operand:SI 2 "arith11_operand" "ri")
                      (match_operand:SI 3 "register_operand" "0")))]
   "TARGET_ARCH64"
 (define_insn "*movdi_ccx_sp64"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (if_then_else (match_operator 1 "comparison_operator"
-                                     [(reg:CCX 0) (const_int 0)])
+                                     [(reg:CCX 100) (const_int 0)])
                      (match_operand:DI 2 "arith11_double_operand" "rHI")
                      (match_operand:DI 3 "register_operand" "0")))]
   "TARGET_ARCH64"
 (define_insn "*movsi_ccfp_sp64"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (if_then_else (match_operator 1 "comparison_operator"
-                               [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
+                               [(match_operand:CCFP 2 "fcc_reg_operand" "c")
                                 (const_int 0)])
                      (match_operand:SI 3 "arith11_operand" "ri")
                      (match_operand:SI 4 "register_operand" "0")))]
 (define_insn "*movsi_ccfpe_sp64"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (if_then_else (match_operator 1 "comparison_operator"
-                               [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
+                               [(match_operand:CCFPE 2 "fcc_reg_operand" "c")
                                 (const_int 0)])
                      (match_operand:SI 3 "arith11_operand" "ri")
                      (match_operand:SI 4 "register_operand" "0")))]
 (define_insn "*movdi_ccfp_sp64"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (if_then_else (match_operator 1 "comparison_operator"
-                               [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
+                               [(match_operand:CCFP 2 "fcc_reg_operand" "c")
                                 (const_int 0)])
                      (match_operand:DI 3 "arith11_double_operand" "rHI")
                      (match_operand:DI 4 "register_operand" "0")))]
 (define_insn "*movdi_ccfpe_sp64"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (if_then_else (match_operator 1 "comparison_operator"
-                               [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
+                               [(match_operand:CCFPE 2 "fcc_reg_operand" "c")
                                 (const_int 0)])
                      (match_operand:DI 3 "arith11_double_operand" "rHI")
                      (match_operand:DI 4 "register_operand" "0")))]
 (define_insn "*movsf_ccfp_sp64"
   [(set (match_operand:SF 0 "register_operand" "=f")
        (if_then_else (match_operator 1 "comparison_operator"
-                               [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
+                               [(match_operand:CCFP 2 "fcc_reg_operand" "c")
                                 (const_int 0)])
                      (match_operand:SF 3 "register_operand" "f")
                      (match_operand:SF 4 "register_operand" "0")))]
 (define_insn "*movsf_ccfpe_sp64"
   [(set (match_operand:SF 0 "register_operand" "=f")
        (if_then_else (match_operator 1 "comparison_operator"
-                               [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
+                               [(match_operand:CCFPE 2 "fcc_reg_operand" "c")
                                 (const_int 0)])
                      (match_operand:SF 3 "register_operand" "f")
                      (match_operand:SF 4 "register_operand" "0")))]
 (define_insn "*movdf_ccfp_sp64"
   [(set (match_operand:DF 0 "register_operand" "=e")
        (if_then_else (match_operator 1 "comparison_operator"
-                               [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
+                               [(match_operand:CCFP 2 "fcc_reg_operand" "c")
                                 (const_int 0)])
                      (match_operand:DF 3 "register_operand" "e")
                      (match_operand:DF 4 "register_operand" "0")))]
 (define_insn "*movdf_ccfpe_sp64"
   [(set (match_operand:DF 0 "register_operand" "=e")
        (if_then_else (match_operator 1 "comparison_operator"
-                               [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
+                               [(match_operand:CCFPE 2 "fcc_reg_operand" "c")
                                 (const_int 0)])
                      (match_operand:DF 3 "register_operand" "e")
                      (match_operand:DF 4 "register_operand" "0")))]
 (define_insn "*movtf_ccfp_sp64"
   [(set (match_operand:TF 0 "register_operand" "=e")
        (if_then_else (match_operator 1 "comparison_operator"
-                               [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
+                               [(match_operand:CCFP 2 "fcc_reg_operand" "c")
                                 (const_int 0)])
                      (match_operand:TF 3 "register_operand" "e")
                      (match_operand:TF 4 "register_operand" "0")))]
 (define_insn "*movtf_ccfpe_sp64"
   [(set (match_operand:TF 0 "register_operand" "=e")
        (if_then_else (match_operator 1 "comparison_operator"
-                               [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
+                               [(match_operand:CCFPE 2 "fcc_reg_operand" "c")
                                 (const_int 0)])
                      (match_operand:TF 3 "register_operand" "e")
                      (match_operand:TF 4 "register_operand" "0")))]
 (define_insn "*movsf_cc_sp64"
   [(set (match_operand:SF 0 "register_operand" "=f")
        (if_then_else (match_operator 1 "comparison_operator"
-                                     [(reg:CC 0) (const_int 0)])
+                                     [(reg:CC 100) (const_int 0)])
                      (match_operand:SF 2 "register_operand" "f")
                      (match_operand:SF 3 "register_operand" "0")))]
   "TARGET_V9 && TARGET_FPU"
 (define_insn "*movdf_cc_sp64"
   [(set (match_operand:DF 0 "register_operand" "=e")
        (if_then_else (match_operator 1 "comparison_operator"
-                                     [(reg:CC 0) (const_int 0)])
+                                     [(reg:CC 100) (const_int 0)])
                      (match_operand:DF 2 "register_operand" "e")
                      (match_operand:DF 3 "register_operand" "0")))]
   "TARGET_V9 && TARGET_FPU"
 (define_insn "*movtf_cc_sp64"
   [(set (match_operand:TF 0 "register_operand" "=e")
        (if_then_else (match_operator 1 "comparison_operator"
-                                     [(reg:CC 0) (const_int 0)])
+                                     [(reg:CC 100) (const_int 0)])
                      (match_operand:TF 2 "register_operand" "e")
                      (match_operand:TF 3 "register_operand" "0")))]
   "TARGET_V9 && TARGET_FPU"
 (define_insn "*movsf_ccx_sp64"
   [(set (match_operand:SF 0 "register_operand" "=f")
        (if_then_else (match_operator 1 "comparison_operator"
-                                     [(reg:CCX 0) (const_int 0)])
+                                     [(reg:CCX 100) (const_int 0)])
                      (match_operand:SF 2 "register_operand" "f")
                      (match_operand:SF 3 "register_operand" "0")))]
   "TARGET_ARCH64 && TARGET_FPU"
 (define_insn "*movdf_ccx_sp64"
   [(set (match_operand:DF 0 "register_operand" "=e")
        (if_then_else (match_operator 1 "comparison_operator"
-                                     [(reg:CCX 0) (const_int 0)])
+                                     [(reg:CCX 100) (const_int 0)])
                      (match_operand:DF 2 "register_operand" "e")
                      (match_operand:DF 3 "register_operand" "0")))]
   "TARGET_ARCH64 && TARGET_FPU"
 (define_insn "*movtf_ccx_sp64"
   [(set (match_operand:TF 0 "register_operand" "=e")
        (if_then_else (match_operator 1 "comparison_operator"
-                                     [(reg:CCX 0) (const_int 0)])
+                                     [(reg:CCX 100) (const_int 0)])
                      (match_operand:TF 2 "register_operand" "e")
                      (match_operand:TF 3 "register_operand" "0")))]
   "TARGET_ARCH64 && TARGET_FPU"
 ;; Simplify comparisons of extended values.
 
 (define_insn "*cmp_zero_extendqisi2"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
                    (const_int 0)))]
   ""
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_zero_extendqisi2_set"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
                    (const_int 0)))
    (set (match_operand:SI 0 "register_operand" "=r")
 ;; Similarly, handle SI->QI mode truncation followed by a compare.
 
 (define_insn "*cmp_siqi_trunc"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
                    (const_int 0)))]
   ""
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_siqi_trunc_set"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
                    (const_int 0)))
    (set (match_operand:QI 0 "register_operand" "=r")
 ;; because combine uses this as a canonical form.
 
 (define_insn "*cmp_zero_extract"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC
         (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
                          (match_operand:SI 1 "small_int" "n")
 }")
 
 (define_insn "*cmp_zero_extract_sp64"
-  [(set (reg:CCX 0)
+  [(set (reg:CCX 100)
        (compare:CCX
         (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
                          (match_operand:SI 1 "small_int" "n")
                          gen_rtx (SET, VOIDmode, operands[0],
                                   gen_rtx (PLUS, DImode, operands[1],
                                                  operands[2])),
-                         gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
+                         gen_rtx (CLOBBER, VOIDmode,
+                                  gen_rtx (REG, SImode, SPARC_ICC_REG)))));
       DONE;
     }
 }")
   [(set (match_operand:DI 0 "register_operand" "=r")
        (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
                 (match_operand:DI 2 "arith_double_operand" "rHI")))
-   (clobber (reg:SI 0))]
+   (clobber (reg:SI 100))]
   "! TARGET_ARCH64"
   "*
 {
   [(set_attr "type" "ialu")])
 
 (define_insn "*cmp_cc_plus"
-  [(set (reg:CC_NOOV 0)
+  [(set (reg:CC_NOOV 100)
        (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
                                  (match_operand:SI 1 "arith_operand" "rI"))
                         (const_int 0)))]
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_ccx_plus"
-  [(set (reg:CCX_NOOV 0)
+  [(set (reg:CCX_NOOV 100)
        (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
                                   (match_operand:DI 1 "arith_double_operand" "rHI"))
                          (const_int 0)))]
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_cc_plus_set"
-  [(set (reg:CC_NOOV 0)
+  [(set (reg:CC_NOOV 100)
        (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
                                  (match_operand:SI 2 "arith_operand" "rI"))
                         (const_int 0)))
   "addcc %1,%2,%0")
 
 (define_insn "*cmp_ccx_plus_set"
-  [(set (reg:CCX_NOOV 0)
+  [(set (reg:CCX_NOOV 100)
        (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
                                   (match_operand:DI 2 "arith_double_operand" "rHI"))
                          (const_int 0)))
                          gen_rtx (SET, VOIDmode, operands[0],
                                   gen_rtx (MINUS, DImode, operands[1],
                                                   operands[2])),
-                         gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
+                         gen_rtx (CLOBBER, VOIDmode,
+                                  gen_rtx (REG, SImode, SPARC_ICC_REG)))));
       DONE;
     }
 }")
   [(set (match_operand:DI 0 "register_operand" "=r")
        (minus:DI (match_operand:DI 1 "register_operand" "r")
                  (match_operand:DI 2 "arith_double_operand" "rHI")))
-   (clobber (reg:SI 0))]
+   (clobber (reg:SI 100))]
   "! TARGET_ARCH64"
   "*
 {
   [(set_attr "type" "ialu")])
 
 (define_insn "*cmp_minus_cc"
-  [(set (reg:CC_NOOV 0)
+  [(set (reg:CC_NOOV 100)
        (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
                                   (match_operand:SI 1 "arith_operand" "rI"))
                         (const_int 0)))]
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_minus_ccx"
-  [(set (reg:CCX_NOOV 0)
+  [(set (reg:CCX_NOOV 100)
        (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
                                    (match_operand:DI 1 "arith_double_operand" "rHI"))
                          (const_int 0)))]
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_minus_cc_set"
-  [(set (reg:CC_NOOV 0)
+  [(set (reg:CC_NOOV 100)
        (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
                                   (match_operand:SI 2 "arith_operand" "rI"))
                         (const_int 0)))
   "subcc %1,%2,%0")
 
 (define_insn "*cmp_minus_ccx_set"
-  [(set (reg:CCX_NOOV 0)
+  [(set (reg:CCX_NOOV 100)
        (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
                                    (match_operand:DI 2 "arith_double_operand" "rHI"))
                          (const_int 0)))
   [(set (match_operand:SI 0 "register_operand" "=r")
        (mult:SI (match_operand:SI 1 "arith_operand" "%r")
                 (match_operand:SI 2 "arith_operand" "rI")))
-   (set (reg:CC_NOOV 0)
+   (set (reg:CC_NOOV 100)
        (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
                         (const_int 0)))]
   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (div:SI (match_operand:SI 1 "register_operand" "r")
                (match_operand:SI 2 "arith_operand" "rI")))
-   (set (reg:CC 0)
+   (set (reg:CC 100)
        (compare:CC (div:SI (match_dup 1) (match_dup 2))
                    (const_int 0)))
    (clobber (match_scratch:SI 3 "=&r"))]
   [(set (match_operand:SI 0 "register_operand" "=r")
        (udiv:SI (match_operand:SI 1 "register_operand" "r")
                (match_operand:SI 2 "arith_operand" "rI")))
-   (set (reg:CC 0)
+   (set (reg:CC 100)
        (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
                    (const_int 0)))]
   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
     {
       int sign = INTVAL (op2);
       if (sign < 0)
-       return \"mov -1,%0\;or %R1,%2,%R0\";
+       {
+         if (TARGET_LIVE_G0)
+           return \"and %0,0,%0\;add %0,-1,%0\;or %R1,%2,%R0\";
+         else
+           return \"mov -1,%0\;or %R1,%2,%R0\";
+       }
       return \"mov %1,%0\;or %R1,%2,%R0\";
     }
   else if (GET_CODE (op2) == CONST_DOUBLE)
 ;; want to set the condition code.  
 
 (define_insn "*cmp_cc_arith_op"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC
         (match_operator:SI 2 "cc_arithop"
                            [(match_operand:SI 0 "arith_operand" "%r")
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_ccx_arith_op"
-  [(set (reg:CCX 0)
+  [(set (reg:CCX 100)
        (compare:CCX
         (match_operator:DI 2 "cc_arithop"
                            [(match_operand:DI 0 "arith_double_operand" "%r")
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_cc_arith_op_set"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC
         (match_operator:SI 3 "cc_arithop"
                            [(match_operand:SI 1 "arith_operand" "%r")
   "%A3cc %1,%2,%0")
 
 (define_insn "*cmp_ccx_arith_op_set"
-  [(set (reg:CCX 0)
+  [(set (reg:CCX 100)
        (compare:CCX
         (match_operator:DI 3 "cc_arithop"
                            [(match_operand:DI 1 "arith_double_operand" "%r")
   "%A3cc %1,%2,%0")
 
 (define_insn "*cmp_cc_xor_not"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC
         (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
                         (match_operand:SI 1 "arith_operand" "rI")))
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_ccx_xor_not"
-  [(set (reg:CCX 0)
+  [(set (reg:CCX 100)
        (compare:CCX
         (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
                         (match_operand:DI 1 "arith_double_operand" "rHI")))
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_cc_xor_not_set"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC
         (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
                         (match_operand:SI 2 "arith_operand" "rI")))
   "xnorcc %r1,%2,%0")
 
 (define_insn "*cmp_ccx_xor_not_set"
-  [(set (reg:CCX 0)
+  [(set (reg:CCX 100)
        (compare:CCX
         (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
                         (match_operand:DI 2 "arith_double_operand" "rHI")))
   "xnorcc %r1,%2,%0")
 
 (define_insn "*cmp_cc_arith_op_not"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC
         (match_operator:SI 2 "cc_arithopn"
                            [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_ccx_arith_op_not"
-  [(set (reg:CCX 0)
+  [(set (reg:CCX 100)
        (compare:CCX
         (match_operator:DI 2 "cc_arithopn"
                            [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_cc_arith_op_not_set"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC
         (match_operator:SI 3 "cc_arithopn"
                            [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
   "%B3cc %r2,%1,%0")
 
 (define_insn "*cmp_ccx_arith_op_not_set"
-  [(set (reg:CCX 0)
+  [(set (reg:CCX 100)
        (compare:CCX
         (match_operator:DI 3 "cc_arithopn"
                            [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
       emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
                          gen_rtx (SET, VOIDmode, operand0,
                                   gen_rtx (NEG, DImode, operand1)),
-                         gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
+                         gen_rtx (CLOBBER, VOIDmode,
+                                  gen_rtx (REG, SImode, SPARC_ICC_REG)))));
       DONE;
     }
 }")
 (define_insn "*negdi2_sp32"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (neg:DI (match_operand:DI 1 "register_operand" "r")))
-   (clobber (reg:SI 0))]
+   (clobber (reg:SI 100))]
   "! TARGET_ARCH64"
-  "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
+  "*
+{
+  if (TARGET_LIVE_G0)
+    output_asm_insn (\"and %%g0,0,%%g0\", operands);
+  return \"subcc %%g0,%R1,%R0\;subx %%g0,%1,%0\";
+}"
   [(set_attr "type" "unary")
+   ;; ??? This is wrong for TARGET_LIVE_G0 but it's not critical.
    (set_attr "length" "2")])
 
 (define_insn "*negdi2_sp64"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
   ""
-  "sub %%g0,%1,%0"
-  [(set_attr "type" "unary")])
+  "*
+{
+  if (TARGET_LIVE_G0)
+    return \"and %%g0,0,%%g0\;sub %%g0,%1,%0\";
+  return \"sub %%g0,%1,%0\";
+}"
+  [(set_attr "type" "unary")
+   (set (attr "length")
+       (if_then_else (eq_attr "live_g0" "yes") (const_int 2) (const_int 1)))])
 
 (define_insn "*cmp_cc_neg"
-  [(set (reg:CC_NOOV 0)
+  [(set (reg:CC_NOOV 100)
        (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
                         (const_int 0)))]
-  ""
+  "! TARGET_LIVE_G0"
   "subcc %%g0,%0,%%g0"
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_ccx_neg"
-  [(set (reg:CCX_NOOV 0)
+  [(set (reg:CCX_NOOV 100)
        (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
                          (const_int 0)))]
   "TARGET_ARCH64"
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_cc_set_neg"
-  [(set (reg:CC_NOOV 0)
+  [(set (reg:CC_NOOV 100)
        (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
                         (const_int 0)))
    (set (match_operand:SI 0 "register_operand" "=r")
        (neg:SI (match_dup 1)))]
-  ""
+  "! TARGET_LIVE_G0"
   "subcc %%g0,%1,%0"
   [(set_attr "type" "unary")])
 
 (define_insn "*cmp_ccx_set_neg"
-  [(set (reg:CCX_NOOV 0)
+  [(set (reg:CCX_NOOV 100)
        (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
                          (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
   [(set (match_operand:DI 0 "register_operand" "=r")
        (not:DI (match_operand:DI 1 "register_operand" "r")))]
   "! TARGET_ARCH64"
-  "xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0"
+  "xnor %1,0,%0\;xnor %R1,0,%R0"
   [(set_attr "type" "unary")
    (set_attr "length" "2")])
 
   [(set (match_operand:DI 0 "register_operand" "=r")
        (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
   "TARGET_ARCH64"
-  "xnor %%g0,%1,%0"
+  "xnor %1,0,%0"
   [(set_attr "type" "unary")])
 
 (define_insn "one_cmplsi2"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+       (not:SI (match_operand:SI 1 "arith_operand" "r,I")))]
   ""
-  "xnor %%g0,%1,%0"
-  [(set_attr "type" "unary")])
+  "*
+{
+  if (which_alternative == 0)
+    return \"xnor %1,0,%0\";
+  if (TARGET_LIVE_G0)
+    output_asm_insn (\"and %%g0,0,%%g0\", operands);
+  return \"xnor %%g0,%1,%0\";
+}"
+  [(set_attr "type" "unary")
+   (set_attr_alternative "length"
+     [(const_int 1)
+      (if_then_else (eq_attr "live_g0" "yes") (const_int 2) (const_int 1))])])
 
 (define_insn "*cmp_cc_not"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
                    (const_int 0)))]
-  ""
+  "! TARGET_LIVE_G0"
   "xnorcc %%g0,%0,%%g0"
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_ccx_not"
-  [(set (reg:CCX 0)
+  [(set (reg:CCX 100)
        (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
                     (const_int 0)))]
   "TARGET_ARCH64"
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_cc_set_not"
-  [(set (reg:CC 0)
+  [(set (reg:CC 100)
        (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
                    (const_int 0)))
    (set (match_operand:SI 0 "register_operand" "=r")
        (not:SI (match_dup 1)))]
-  ""
+  "! TARGET_LIVE_G0"
   "xnorcc %%g0,%1,%0"
   [(set_attr "type" "unary")])
 
 (define_insn "*cmp_ccx_set_not"
-  [(set (reg:CCX 0)
+  [(set (reg:CCX 100)
        (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
                    (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
 }")
 
 (define_insn "*cmp_cc_ashift_1"
-  [(set (reg:CC_NOOV 0)
+  [(set (reg:CC_NOOV 100)
        (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
                                    (const_int 1))
                         (const_int 0)))]
   [(set_attr "type" "compare")])
 
 (define_insn "*cmp_cc_set_ashift_1"
-  [(set (reg:CC_NOOV 0)
+  [(set (reg:CC_NOOV 100)
        (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
                                    (const_int 1))
                         (const_int 0)))
        (ffs:SI (match_operand:SI 1 "register_operand" "r")))
    (clobber (match_scratch:SI 2 "=&r"))]
   "TARGET_SPARCLITE || TARGET_SPARCLET"
-  "sub %%g0,%1,%0\;and %0,%1,%0\;scan %0,0,%0\;mov 32,%2\;sub %2,%0,%0\;sra %0,31,%2\;and %2,31,%2\;add %2,%0,%0"
+  "*
+{
+  if (TARGET_LIVE_G0)
+    output_asm_insn (\"and %%g0,0,%%g0\", operands);
+  return \"sub %%g0,%1,%0\;and %0,%1,%0\;scan %0,0,%0\;mov 32,%2\;sub %2,%0,%0\;sra %0,31,%2\;and %2,31,%2\;add %2,%0,%0\";
+}"
   [(set_attr "type" "multi")
    (set_attr "length" "8")])
 
        (ffs:DI (match_operand:DI 1 "register_operand" "r")))
    (clobber (match_scratch:DI 2 "=&r"))]
   "TARGET_ARCH64"
-  "neg %1,%2\;not %2,%2\;xor %1,%2,%2\;popc %2,%0\;movrz %1,%%g0,%0"
+  "neg %1,%2\;not %2,%2\;xor %1,%2,%2\;popc %2,%0\;movrz %1,0,%0"
   [(set_attr "type" "multi")
    (set_attr "length" "5")])
 \f
   [(set (match_operand:SI 0 "register_operand" "")
        (ne:SI (match_operand:SI 1 "register_operand" "")
               (const_int 0)))
-   (clobber (reg:CC 0))]
+   (clobber (reg:CC 100))]
   ""
-  [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
-                                        (const_int 0)))
-   (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
+  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
+                                          (const_int 0)))
+   (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
   "")
 
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
        (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
                       (const_int 0))))
-   (clobber (reg:CC 0))]
+   (clobber (reg:CC 100))]
   ""
-  [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
-                                        (const_int 0)))
-   (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
+  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
+                                          (const_int 0)))
+   (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
   "")
 
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
        (eq:SI (match_operand:SI 1 "register_operand" "")
               (const_int 0)))
-   (clobber (reg:CC 0))]
+   (clobber (reg:CC 100))]
   ""
-  [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
-                                        (const_int 0)))
-   (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
+  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
+                                          (const_int 0)))
+   (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
   "")
 
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
        (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
                       (const_int 0))))
-   (clobber (reg:CC 0))]
+   (clobber (reg:CC 100))]
   ""
-  [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
-                                        (const_int 0)))
-   (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
+  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
+                                          (const_int 0)))
+   (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
   "")
 
 (define_split
        (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
                        (const_int 0))
                 (match_operand:SI 2 "register_operand" "")))
-   (clobber (reg:CC 0))]
+   (clobber (reg:CC 100))]
   ""
-  [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
-                                        (const_int 0)))
-   (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
+  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
+                                          (const_int 0)))
+   (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
                               (match_dup 2)))]
   "")
 
        (minus:SI (match_operand:SI 2 "register_operand" "")
                  (ne:SI (match_operand:SI 1 "register_operand" "")
                         (const_int 0))))
-   (clobber (reg:CC 0))]
+   (clobber (reg:CC 100))]
   ""
-  [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
-                                        (const_int 0)))
+  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
+                                          (const_int 0)))
    (set (match_dup 0) (minus:SI (match_dup 2)
-                               (ltu:SI (reg:CC 0) (const_int 0))))]
+                               (ltu:SI (reg:CC 100) (const_int 0))))]
   "")
 
 (define_split
        (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
                        (const_int 0))
                 (match_operand:SI 2 "register_operand" "")))
-   (clobber (reg:CC 0))]
+   (clobber (reg:CC 100))]
   ""
-  [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
-                                        (const_int 0)))
-   (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
+  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
+                                          (const_int 0)))
+   (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
                               (match_dup 2)))]
   "")
 
        (minus:SI (match_operand:SI 2 "register_operand" "")
                  (eq:SI (match_operand:SI 1 "register_operand" "")
                         (const_int 0))))
-   (clobber (reg:CC 0))]
+   (clobber (reg:CC 100))]
   ""
-  [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
-                                        (const_int 0)))
+  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
+                                          (const_int 0)))
    (set (match_dup 0) (minus:SI (match_dup 2)
-                               (geu:SI (reg:CC 0) (const_int 0))))]
+                               (geu:SI (reg:CC 100) (const_int 0))))]
   "")
 \f
 ;; Peepholes go at the end.
 (define_peephole
   [(set (match_operand:SI 0 "register_operand" "=r")
        (match_operand:SI 1 "register_operand" "r"))
-   (set (reg:CC 0)
+   (set (reg:CC 100)
        (compare:CC (match_operand:SI 2 "register_operand" "r")
                    (const_int 0)))]
   "(rtx_equal_p (operands[2], operands[0])
     || rtx_equal_p (operands[2], operands[1]))
    && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
-  "orcc %1,%%g0,%0")
+  "orcc %1,0,%0")
 
 (define_peephole
   [(set (match_operand:DI 0 "register_operand" "=r")
        (match_operand:DI 1 "register_operand" "r"))
-   (set (reg:CCX 0)
+   (set (reg:CCX 100)
        (compare:CCX (match_operand:DI 2 "register_operand" "r")
                    (const_int 0)))]
   "TARGET_ARCH64
    && (rtx_equal_p (operands[2], operands[0])
        || rtx_equal_p (operands[2], operands[1]))
    && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
-  "orcc %1,%%g0,%0")
+  "orcc %1,0,%0")
 
 ;; Do {sign,zero}-extended compares somewhat more efficiently.
 ;; ??? Is this now the Right Way to do this?  Or will SCRATCH
        (match_operand:HI 1 "memory_operand" ""))
    (set (match_operand:SI 2 "register_operand" "")
        (sign_extend:SI (match_dup 0)))
-   (set (reg:CC 0)
+   (set (reg:CC 100)
        (compare:CC (match_dup 2)
                    (const_int 0)))]
   ""
-  "ldsh %1,%0\;orcc %0,%%g0,%2")
+  "ldsh %1,%0\;orcc %0,0,%2")
 
 (define_peephole
   [(set (match_operand:HI 0 "register_operand" "")
        (match_operand:HI 1 "memory_operand" ""))
    (set (match_operand:DI 2 "register_operand" "")
        (sign_extend:DI (match_dup 0)))
-   (set (reg:CCX 0)
+   (set (reg:CCX 100)
        (compare:CCX (match_dup 2)
                     (const_int 0)))]
   "TARGET_ARCH64"
-  "ldsh %1,%0\;orcc %0,%%g0,%2")
+  "ldsh %1,%0\;orcc %0,0,%2")
 
 (define_peephole
   [(set (match_operand:QI 0 "register_operand" "")
        (match_operand:QI 1 "memory_operand" ""))
    (set (match_operand:SI 2 "register_operand" "")
        (sign_extend:SI (match_dup 0)))
-   (set (reg:CC 0)
+   (set (reg:CC 100)
        (compare:CC (match_dup 2)
                    (const_int 0)))]
   ""
-  "ldsb %1,%0\;orcc %0,%%g0,%2")
+  "ldsb %1,%0\;orcc %0,0,%2")
 
 (define_peephole
   [(set (match_operand:QI 0 "register_operand" "")
        (match_operand:QI 1 "memory_operand" ""))
    (set (match_operand:DI 2 "register_operand" "")
        (sign_extend:DI (match_dup 0)))
-   (set (reg:CCX 0)
+   (set (reg:CCX 100)
        (compare:CCX (match_dup 2)
                     (const_int 0)))]
   "TARGET_ARCH64"
-  "ldsb %1,%0\;orcc %0,%%g0,%2")
+  "ldsb %1,%0\;orcc %0,0,%2")
 
 ;; Floating-point move peepholes
 ;; ??? v9: Do we want similar ones?
   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
   "ld [%0+%%lo(%a1)],%2")
 
-;; Return peepholes.  First the "normal" ones
-
-;; ??? There are QImode, HImode, and SImode versions of this pattern.
-;; It might be possible to write one more general pattern instead of three.
+;; Return peepholes.  First the "normal" ones.
+;; These are necessary to catch insns ending up in the epilogue delay list.
 
 (define_insn "*return_qi"
   [(set (match_operand:QI 0 "restore_operand" "")
        (match_operand:QI 1 "arith_operand" "rI"))
    (return)]
-  "! TARGET_EPILOGUE"
+  "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
   "*
 {
   if (! TARGET_ARCH64 && current_function_returns_struct)
   [(set (match_operand:HI 0 "restore_operand" "")
        (match_operand:HI 1 "arith_operand" "rI"))
    (return)]
-  "! TARGET_EPILOGUE"
+  "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
   "*
 {
   if (! TARGET_ARCH64 && current_function_returns_struct)
   [(set (match_operand:SI 0 "restore_operand" "")
        (match_operand:SI 1 "arith_operand" "rI"))
    (return)]
-  "! TARGET_EPILOGUE"
+  "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
   "*
 {
   if (! TARGET_ARCH64 && current_function_returns_struct)
   [(set (match_operand:SF 0 "restore_operand" "r")
        (match_operand:SF 1 "register_operand" "r"))
    (return)]
-  "! TARGET_FPU && ! TARGET_EPILOGUE"
+  "! TARGET_FPU && ! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
   "*
 {
   if (! TARGET_ARCH64 && current_function_returns_struct)
        (plus:SI (match_operand:SI 1 "arith_operand" "%r")
                 (match_operand:SI 2 "arith_operand" "rI")))
    (return)]
-  "! TARGET_EPILOGUE"
+  "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
   "*
 {
   if (! TARGET_ARCH64 && current_function_returns_struct)
 
 ;; Other miscellaneous peepholes.
 
+;; (reg:SI 100) is created by the {add,neg,sub}di patterns.
 (define_peephole
   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
                   (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
-                            (reg:SI 0)))
-             (clobber (reg:CC 0))])
-   (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
+                            (reg:SI 100)))
+             (clobber (reg:CC 100))])
+   (set (reg:CC 100) (compare (match_dup 0) (const_int 0)))]
   ""
   "subxcc %r1,0,%0")