OSDN Git Service

* config/v850/v850.c (register_is_ok_for_epilogue,
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 Sep 1997 06:13:27 +0000 (06:13 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 Sep 1997 06:13:27 +0000 (06:13 +0000)
        pattern_is_ok_for_epilogue, construct_restore_jr,
        pattern_is_ok_for_prologue, construct_save_jarl): New functions.

        * config/v850/v850.h (pattern_is_ok_for_prologue,
        pattern_is_ok_for_epilogue, register_is_ok_for_epilogue): New
        predicates.

        * config/v850/v850.md: Replace prologue and epilogue patterns with a
        match_parallel pattern.

        * config/v850/v850.c (output_move_single_unsigned): Cope with zero
        extending and moving between registers at the same time.

Brought over from devo.

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

gcc/ChangeLog
gcc/config/v850/v850.c
gcc/config/v850/v850.h
gcc/config/v850/v850.md

index 36da8c8..266f78f 100644 (file)
@@ -1,3 +1,19 @@
+Tue Sep 16 00:13:20 1997  Nick Clifton  <nickc@cygnus.com>
+
+       * config/v850/v850.c (register_is_ok_for_epilogue,
+       pattern_is_ok_for_epilogue, construct_restore_jr,
+       pattern_is_ok_for_prologue, construct_save_jarl): New functions.
+
+       * config/v850/v850.h (pattern_is_ok_for_prologue,
+       pattern_is_ok_for_epilogue, register_is_ok_for_epilogue): New
+       predicates.
+
+       * config/v850/v850.md: Replace prologue and epilogue patterns with a
+       match_parallel pattern.
+
+       * config/v850/v850.c (output_move_single_unsigned): Cope with zero
+       extending and moving between registers at the same time.
+
 Mon Sep 15 22:53:01 1997  Jeffrey A Law  (law@cygnus.com)
 
        * aclocal.m4: Add replacement for AC_PROG_INSTALL.
index 6435d40..2247dae 100644 (file)
@@ -476,7 +476,15 @@ print_operand (file, x, code)
     case 'S':
       {
         /* if it's a referance to a TDA variable, use sst/sld vs. st/ld */
-        if (GET_CODE (x) == MEM && ep_memory_operand (x, GET_MODE (x)))
+        if (GET_CODE (x) == MEM && ep_memory_operand (x, GET_MODE (x), FALSE))
+          fputs ("s", file);
+
+        break;
+      }
+    case 'T':
+      {
+       /* Like an 'S' operand above, but for unsigned loads only.  */
+        if (GET_CODE (x) == MEM && ep_memory_operand (x, GET_MODE (x), TRUE))
           fputs ("s", file);
 
         break;
@@ -702,7 +710,9 @@ output_move_single (operands)
       else if (GET_CODE (src) == LABEL_REF
               || GET_CODE (src) == SYMBOL_REF
               || GET_CODE (src) == CONST)
-       return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0";
+       {
+         return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0";
+       }
 
       else if (GET_CODE (src) == HIGH)
        return "movhi hi(%1),%.,%0";
@@ -814,9 +824,10 @@ output_move_double (operands)
 /* Return true if OP is a valid short EP memory reference */
 
 int
-ep_memory_operand (op, mode)
+ep_memory_operand (op, mode, unsigned_load)
      rtx op;
      enum machine_mode mode;
+     int unsigned_load;
 {
   rtx addr, op0, op1;
   int max_offset;
@@ -831,18 +842,18 @@ ep_memory_operand (op, mode)
       return FALSE;
 
     case QImode:
-      max_offset = 128;
+         max_offset = (1 << 7);
       mask = 0;
       break;
 
     case HImode:
-      max_offset = 256;
+         max_offset = (1 << 8);
       mask = 1;
       break;
 
     case SImode:
     case SFmode:
-      max_offset = 256;
+      max_offset = (1 << 8);
       mask = 3;
       break;
     }
@@ -1218,7 +1229,7 @@ void v850_reorg (start_insn)
              else
                mem = NULL_RTX;
 
-             if (mem && ep_memory_operand (mem, GET_MODE (mem)))
+             if (mem && ep_memory_operand (mem, GET_MODE (mem), FALSE))
                use_ep = TRUE;
 
              else if (!use_ep && mem
@@ -1499,15 +1510,18 @@ expand_prologue ()
         stack space is allocated.  */
       if (save_func_len < save_normal_len)
        {
-         save_all = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (num_save + 2));
+         save_all = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (num_save + (TARGET_V850 ? 2 : 1)));
          XVECEXP (save_all, 0, 0) = gen_rtx (SET, VOIDmode,
                                              stack_pointer_rtx,
                                              gen_rtx (PLUS, Pmode,
                                                       stack_pointer_rtx,
                                                       GEN_INT (-alloc_stack)));
 
-         XVECEXP (save_all, 0, num_save+1)
-           = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 10));
+         if (TARGET_V850)
+           {
+             XVECEXP (save_all, 0, num_save+1)
+               = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 10));
+           }
 
          offset = - default_stack;
          for (i = 0; i < num_save; i++)
@@ -1555,15 +1569,15 @@ expand_prologue ()
            init_stack_alloc = compute_register_save_size (NULL);
          else
            init_stack_alloc = actual_fsize;
-
+             
          /* Save registers at the beginning of the stack frame */
          offset = init_stack_alloc - 4;
-
+         
          if (init_stack_alloc)
            emit_insn (gen_addsi3 (stack_pointer_rtx,
                                   stack_pointer_rtx,
                                   GEN_INT (-init_stack_alloc)));
-
+         
          /* Save the return pointer first.  */
          if (num_save > 0 && REGNO (save_regs[num_save-1]) == 31)
            {
@@ -1573,12 +1587,12 @@ expand_prologue ()
                              save_regs[--num_save]);
              offset -= 4;
            }
-
+         
          for (i = 0; i < num_save; i++)
            {
              emit_move_insn (gen_rtx (MEM, SImode,
                                       plus_constant (stack_pointer_rtx,
-                                      offset)),
+                                                     offset)),
                              save_regs[i]);
              offset -= 4;
            }
@@ -1940,3 +1954,366 @@ v850_encode_data_area (decl)
      here to make merges easier.  */
   return;
 }
+
+/* Return true if the given RTX is a register which can be restored
+   by a function epilogue.  */
+int
+register_is_ok_for_epilogue (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  /* The save/restore routines can only cope with registers 2, and 20 - 31 */
+  return (GET_CODE (op) == REG)
+         && (((REGNO (op) >= 20) && REGNO (op) <= 31)
+             || REGNO (op) == 2);
+}
+
+/* Return non-zero if the given RTX is suitable for collapsing into
+   jump to a function epilogue.  */
+int
+pattern_is_ok_for_epilogue (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  int count = XVECLEN (op, 0);
+  int i;
+  
+  /* If there are no registers to restore then the function epilogue
+     is not suitable.  */
+  if (count <= 2)
+    return 0;
+
+  /* The pattern matching has already established that we are performing a
+     function epilogue and that we are popping at least one register.  We must
+     now check the remaining entries in the vector to make sure that they are
+     also register pops.  There is no good reason why there should ever be
+     anything else in this vector, but being paranoid always helps...
+
+     The test below performs the C equivalent of this machine description
+     pattern match:
+
+        (set (match_operand:SI n "register_is_ok_for_epilogue" "r")
+         (mem:SI (plus:SI (reg:SI 3) (match_operand:SI n "immediate_operand" "i"))))
+     */
+
+  for (i = 3; i < count; i++)
+    {
+      rtx vector_element = XVECEXP (op, 0, i);
+      rtx dest;
+      rtx src;
+      rtx plus;
+      
+      if (GET_CODE (vector_element) != SET)
+       return 0;
+      
+      dest = SET_DEST (vector_element);
+      src = SET_SRC (vector_element);
+
+      if (GET_CODE (dest) != REG
+         || GET_MODE (dest) != SImode
+         || ! register_is_ok_for_epilogue (dest, SImode)
+         || GET_CODE (src) != MEM
+         || GET_MODE (src) != SImode)
+       return 0;
+
+      plus = XEXP (src, 0);
+
+      if (GET_CODE (plus) != PLUS
+         || GET_CODE (XEXP (plus, 0)) != REG
+         || GET_MODE (XEXP (plus, 0)) != SImode
+         || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
+         || GET_CODE (XEXP (plus, 1)) != CONST_INT)
+       return 0;
+    }
+
+  return 1;
+}
+
+/* Construct a JR instruction to a routine that will perform the equivalent of
+   the RTL passed in as an argument.  This RTL is a function epilogue that
+   pops registers off the stack and possibly releases some extra stack space
+   as well.  The code has already verified that the RTL matches these
+   requirements.  */
+char *
+construct_restore_jr (op)
+     rtx op;
+{
+  int count = XVECLEN (op, 0);
+  int stack_bytes;
+  unsigned long int mask;
+  unsigned long int first;
+  unsigned long int last;
+  int i;
+  static char buff [100]; /* XXX */
+  
+  if (count <= 2)
+    {
+      error ("Bogus JR construction: %d\n", count);
+      return NULL;
+    }
+
+  /* Work out how many bytes to pop off the stack before retrieving
+     registers.  */
+  if (GET_CODE (XVECEXP (op, 0, 1)) != SET)
+    abort ();
+  if (GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) != PLUS)
+    abort ();
+  if (GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1)) != CONST_INT)
+    abort ();
+    
+  stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1));
+
+  /* Each pop will remove 4 bytes from the stack... */
+  stack_bytes -= (count - 2) * 4;
+
+  /* Make sure that the amount we are popping either 0 or 16 bytes.  */
+  if (stack_bytes != 0 && stack_bytes != 16)
+    {
+      error ("Bad amount of stack space removal: %d", stack_bytes);
+      return NULL;
+    }
+
+  /* Now compute the bit mask of registers to push.  */
+  mask = 0;
+  for (i = 2; i < count; i++)
+    {
+      rtx vector_element = XVECEXP (op, 0, i);
+      
+      if (GET_CODE (vector_element) != SET)
+       abort ();
+      if (GET_CODE (SET_DEST (vector_element)) != REG)
+       abort ();
+      if (! register_is_ok_for_epilogue (SET_DEST (vector_element), SImode))
+       abort ();
+      
+      mask |= 1 << REGNO (SET_DEST (vector_element));
+    }
+
+  /* Scan for the first register to pop.  */
+  for (first = 0; first < 32; first++)
+    {
+      if (mask & (1 << first))
+       break;
+    }
+
+  if (first >= 32)
+    abort ();
+
+  /* Discover the last register to pop.  */
+  if (mask & (1 << 31))
+    {
+      if (stack_bytes != 16)
+       abort ();
+      
+      last = 31;
+    }
+  else
+    {
+      if (stack_bytes != 0)
+       abort ();
+      if ((mask & (1 << 29)) == 0)
+       abort ();
+      
+      last = 29;
+    }
+
+  /* Paranoia */
+  for (i = (first == 2 ? 20 : first + 1); i < 29; i++)
+    if ((mask & (1 << i)) == 0)
+      abort ();
+
+  if (first == last)
+    sprintf (buff, "jr __return_%s", reg_names [first]);
+  else
+    sprintf (buff, "jr __return_%s_%s", reg_names [first], reg_names [last]);
+
+  return buff;
+}
+
+
+/* Return non-zero if the given RTX is suitable for collapsing into
+   a jump to a function prologue.  */
+int
+pattern_is_ok_for_prologue (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  int count = XVECLEN (op, 0);
+  int i; 
+  rtx vector_element;
+  /* If there are no registers to save then the function prologue
+     is not suitable.  */
+  if (count <= 2)
+    return 0;
+
+  /* The pattern matching has already established that we are adjusting the
+     stack and pushing at least one register.  We must now check that the
+     remaining entries in the vector to make sure that they are also register
+     pushes, except for the last entry which should be a CLOBBER of r10.
+
+     The test below performs the C equivalent of this machine description
+     pattern match:
+
+     (set (mem:SI (plus:SI (reg:SI 3)
+      (match_operand:SI 2 "immediate_operand" "i")))
+      (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))
+
+     */
+
+  for (i = 2; i < count - 1; i++)
+    {
+      rtx dest;
+      rtx src;
+      rtx plus;
+      
+      vector_element = XVECEXP (op, 0, i);
+      
+      if (GET_CODE (vector_element) != SET)
+       return 0;
+      
+      dest = SET_DEST (vector_element);
+      src = SET_SRC (vector_element);
+
+      if (GET_CODE (dest) != MEM
+         || GET_MODE (dest) != SImode
+         || GET_CODE (src) != REG
+         || GET_MODE (src) != SImode
+         || ! register_is_ok_for_epilogue (src, SImode))
+       return 0;
+
+      plus = XEXP (dest, 0);
+
+      if ( GET_CODE (plus) != PLUS
+         || GET_CODE (XEXP (plus, 0)) != REG
+         || GET_MODE (XEXP (plus, 0)) != SImode
+         || REGNO (XEXP (plus, 0)) != STACK_POINTER_REGNUM
+         || GET_CODE (XEXP (plus, 1)) != CONST_INT)
+       return 0;
+
+      /* If the register is being pushed somewhere other than the stack
+        space just aquired by the first operand then abandon this quest.
+        Note: the test is <= becuase both values are negative.  */
+      if (INTVAL (XEXP (plus, 1))
+         <= INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)))
+       {
+         return 0;
+       }
+    }
+
+  /* Make sure that the last entry in the vector is a clobber.  */
+  vector_element = XVECEXP (op, 0, i);
+  
+  if (GET_CODE (vector_element) != CLOBBER
+      || GET_CODE (XEXP (vector_element, 0)) != REG
+      || REGNO (XEXP (vector_element, 0)) != 10)
+    return 0;
+  
+  return 1;
+}
+
+/* Construct a JARL instruction to a routine that will perform the equivalent
+   of the RTL passed as a parameter.  This RTL is a function prologue that
+   saves some of the registers r20 - r31 onto the stack, and possibly acquires
+   some stack space as well.  The code has already verified that the RTL
+   matches these requirements.  */
+char *
+construct_save_jarl (op)
+     rtx op;
+{
+  int count = XVECLEN (op, 0);
+  int stack_bytes;
+  unsigned long int mask;
+  unsigned long int first;
+  unsigned long int last;
+  int i;
+  static char buff [100]; /* XXX */
+  
+  if (count <= 2)
+    {
+      error ("Bogus JARL construction: %d\n", count);
+      return NULL;
+    }
+
+  /* Paranoia.  */
+  if (GET_CODE (XVECEXP (op, 0, 0)) != SET)
+    abort ();
+  if (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != PLUS)
+    abort ();
+  if (GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0)) != REG)
+    abort ();
+  if (GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)) != CONST_INT)
+    abort ();
+    
+  /* Work out how many bytes to push onto the stack after storing the
+     registers.  */
+  stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1));
+
+  /* Each push will put 4 bytes from the stack... */
+  stack_bytes += (count - 2) * 4;
+
+  /* Make sure that the amount we are popping either 0 or 16 bytes.  */
+  if (stack_bytes != 0 && stack_bytes != -16)
+    {
+      error ("Bad amount of stack space removal: %d", stack_bytes);
+      return NULL;
+    }
+
+  /* Now compute the bit mask of registers to push.  */
+  mask = 0;
+  for (i = 0; i < count; i++)
+    {
+      rtx vector_element = XVECEXP (op, 0, i);
+      
+      if (GET_CODE (vector_element) != SET)
+       abort ();
+      if (GET_CODE (SET_SRC (vector_element)) != REG)
+       abort ();
+      if (! register_is_ok_for_epilogue (SET_SRC (vector_element), SImode))
+       abort ();
+      
+      mask |= 1 << REGNO (SET_SRC (vector_element));
+    }
+
+  /* Scan for the first register to push.  */  
+  for (first = 0; first < 32; first++)
+    {
+      if (mask & (1 << first))
+       break;
+    }
+
+  if (first >= 32)
+    abort ();
+
+  /* Discover the last register to push.  */
+  if (mask & (1 << 31))
+    {
+      if (stack_bytes != -16)
+       abort();
+      
+      last = 31;
+    }
+  else
+    {
+      if (stack_bytes != 0)
+       abort ();
+      if ((mask & (1 << 29)) == 0)
+       abort ();
+      
+      last = 29;
+    }
+
+  /* Paranoia */
+  for (i = (first == 2 ? 20 : first + 1); i < 29; i++)
+    if ((mask & (1 << i)) == 0)
+      abort ();
+
+  if (first == last)
+    sprintf (buff, "jarl __save_%s, r10", reg_names [first]);
+  else
+    sprintf (buff, "jarl __save_%s_%s, r10", reg_names [first],
+            reg_names [last]);
+
+  return buff;
+}
+
index 6ab64fa..8e7f9fe 100644 (file)
@@ -55,6 +55,16 @@ extern int target_flags;
 #define MASK_PROLOG_FUNCTION   0x00000008
 #define MASK_DEBUG             0x40000000
 
+#define MASK_CPU                0x00000030
+#define MASK_V850               0x00000010
+
+#ifndef MASK_DEFAULT
+#define MASK_DEFAULT            MASK_V850
+#endif
+
+#define TARGET_V850                    ((target_flags & MASK_CPU) == MASK_V850)
+
+
 /* Macros used in the machine description to test the flags.  */
 
 /* The GHS calling convention support doesn't really work,
@@ -117,7 +127,7 @@ extern int target_flags;
 #endif
 
 #ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT MASK_DEFAULT
+#define TARGET_DEFAULT                 MASK_DEFAULT
 #endif
 
 /* Information about the various small memory areas.  */
@@ -458,18 +468,23 @@ enum reg_class {
 
 #define INT_7_BITS(VALUE) ((unsigned) (VALUE) + 0x40 < 0x80)
 #define INT_8_BITS(VALUE) ((unsigned) (VALUE) + 0x80 < 0x100)
+/* 0 bits */
 #define CONST_OK_FOR_I(VALUE) ((VALUE) == 0)
+/* 4 bits */
 #define CONST_OK_FOR_J(VALUE) ((unsigned) (VALUE) + 0x10 < 0x20)
+/* 15 bits */
 #define CONST_OK_FOR_K(VALUE) ((unsigned) (VALUE) + 0x8000 < 0x10000)
 #define CONST_OK_FOR_L(VALUE) \
   (((unsigned) ((int) (VALUE) >> 16) + 0x8000 < 0x10000) \
    && CONST_OK_FOR_I ((VALUE & 0xffff)))
-#define CONST_OK_FOR_M(VALUE) ((unsigned)(VALUE) < 0x10000)
+/* 16 bits */
+#define CONST_OK_FOR_M(VALUE) ((unsigned)(VALUE) < 0x10000
 
 #define CONST_OK_FOR_N(VALUE) ((unsigned) VALUE >= 0 && (unsigned) VALUE <= 31) /* 5 bit signed immediate in shift instructions */
 #define CONST_OK_FOR_O(VALUE) 0
 #define CONST_OK_FOR_P(VALUE) 0
 
+
 #define CONST_OK_FOR_LETTER_P(VALUE, C)  \
   ((C) == 'I' ? CONST_OK_FOR_I (VALUE) : \
    (C) == 'J' ? CONST_OK_FOR_J (VALUE) : \
@@ -1390,6 +1405,9 @@ do {                                                                      \
                                  REG, SUBREG }},                       \
 { "special_symbolref_operand", { SYMBOL_REF }},                        \
 { "power_of_two_operand",      { CONST_INT }},                         \
+{ "pattern_is_ok_for_prologue",        { PARALLEL }},                          \
+{ "pattern_is_ok_for_epilogue",        { PARALLEL }},                          \
+{ "register_is_ok_for_epilogue",{ REG }},                              \
 { "not_power_of_two_operand",  { CONST_INT }},
 
 extern void override_options ();
@@ -1415,3 +1433,11 @@ extern void expand_epilogue ();
 extern void notice_update_cc ();
 extern int v850_valid_machine_decl_attribute ();
 extern int v850_interrupt_function_p ();
+
+extern int pattern_is_ok_for_prologue();
+extern int pattern_is_ok_for_epilogue();
+extern int register_is_ok_for_epilogue ();
+extern char *construct_save_jarl ();
+extern char *construct_restore_jr ();
+
+
index 4107661..5db807b 100644 (file)
    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
    (set_attr "type" "other,other,other,load,other,load,other,other,other")])
 
+
+
 (define_expand "movdi"
   [(set (match_operand:DI 0 "general_operand" "")
        (match_operand:DI 1 "general_operand" ""))]
   [(set_attr "length" "4")
    (set_attr "cc" "set_znv")])
 
+
 (define_insn "zero_extendqisi2"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (zero_extend:SI
 
 ;;- sign extension instructions
 
+
+;; ??? This is missing a sign extend from memory pattern to match the ld.h
+;; instruction.
+
 (define_expand "extendhisi2"
   [(set (match_dup 2)
         (ashift:SI (match_operand:HI 1 "register_operand" "")
                    (const_int 16)))
    (set (match_operand:SI 0 "register_operand" "")
-        (ashiftrt:SI (match_dup 2)
+       (ashiftrt:SI (match_dup 2)
                      (const_int 16)))]
   ""
   "
   operands[2] = gen_reg_rtx (SImode);
 }")
 
+
+;; ??? This is missing a sign extend from memory pattern to match the ld.b
+;; instruction.
+
 (define_expand "extendqisi2"
   [(set (match_dup 2)
         (ashift:SI (match_operand:QI 1 "register_operand" "")
 ;; RTXs.  These RTXs will then be turned into a suitable call to a worker
 ;; function.
 
+
 (define_insn ""
  [(match_parallel 0 "pattern_is_ok_for_prologue"
    [(set (reg:SI 3)
         (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
-    (set (mem:SI
-          (plus:SI (reg:SI 3) (match_operand:SI 2 "immediate_operand" "i")))
+    (set (mem:SI (plus:SI (reg:SI 3)
+                          (match_operand:SI 2 "immediate_operand" "i")))
         (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
  "TARGET_PROLOG_FUNCTION"
  "* return construct_save_jarl (operands[0]);
  "
  [(set_attr "length" "4")
-  (set_attr "cc"     "clobber")
- ]
-)
+  (set_attr "cc"     "clobber")])
 
 
 ;; Initialize an interrupt function.  Do not depend on TARGET_PROLOG_FUNCTION.
 ;; and possible a stack adjustment as well.  These RTXs will be turned into
 ;; a suitable call to a worker function.
 
+
 (define_insn ""
 [(match_parallel 0 "pattern_is_ok_for_epilogue"
    [(return)
  "* return construct_restore_jr (operands[0]);
  "
  [(set_attr "length" "4")
-  (set_attr "cc"     "clobber")
- ]
-)
+  (set_attr "cc"     "clobber")])
 
 ;; Restore r1, r5, r10, and return from the interrupt
 (define_insn "restore_interrupt"