mn10300.h (CONSTANT_ALIGNMENT): Define.
authorNick Clifton <nickc@redhat.com>
Thu, 14 Oct 2010 09:12:50 +0000 (09:12 +0000)
committerNick Clifton <nickc@gcc.gnu.org>
Thu, 14 Oct 2010 09:12:50 +0000 (09:12 +0000)
        * config/mn10300/mn10300.h (CONSTANT_ALIGNMENT): Define.
        (DATA_ALIGNMENT, LOCAL_ALIGNMENT): Define.
        (FIRST_PSEUDO_REGISTER): Increase by one.
        (FIXED_REGISTERS, CALL_USED_REGISTERS): Update with CC_REG.
        (HARD_REGNO_MODE_OK): Call mn10300_hard_regno_mode_ok.
        (MODES_TIEABLE): Call mn10300_modes_tieable.
        (REG_CLASS_NAMES, REG_CLASS_CONTENTS, REGNO_REG_CLASS): Add
        CC_REGS.
        (LEGITIMATE_CONSTANT_P): Call mn10300_legitimate_constant_p.
        (CC_OVERFLOW_UNUSABLE, CC_NO_CARRY, NOTICE_UPDATE_CC)
        (SELECT_CC_MODE, REVERSIBLE_CC_MODE): Delete.
        (REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): Add CC register.
        (ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP): Delete.
        (mn10300_cc_status_mdep): Delete.
        (CC_STATUS_MDEP, CC_STATUS_MDEP_INIT): Delete.
        * config/mn10300/mn10300 (mn10300_option_override): Stop disabling
        the combine-stack-adjust pass.
        (print_operand): Use the mode of the comparison operation to
        select the comparison suffix.
        (notice_update_cc): Delete.
        (mn10300_secondary_reload_class): Remove test for stack pointer
        based arithmetic.
        (output_tst): Rename to mn10300_output_cmp.
        (impossible_plus_operand): Move into predicates.md.
        (mn10300_legitimize_address): Make static.
        (mn10300_legitimate_address_p): Make static.  Only allow SI sized
        constant pic operands.
        (mn10300_legitimate_constant_p): New function.
        (mn10300_case_values_threshold): Make static.
        (mn10300_hard_regno_mode_ok): New function.
        (mn10300_modes_tieable): New function.
        (mn10300_select_cc_mode): New function.
        * config/mn10300/predicates.md (impossible_plus_operand): Define.
        * config/mn10300/mn10300-protos.h: Tidy.
        (mn10300_legitimate_constant_p, mn10300_modes_tieable)
        (mn10300_hard_regno_mode_ok, mn10300_select_cc_mode): Prototype.
        * config/mn10300/mn10300.md (cc attribute): Delete.  Replace
        with clobbers or sets of CC_REG.
        (CC_REG): Define.
        (mov*): Remove use of CLR instruction.
        (cbranch_si4_<code>): New pattern/split.
        (integer_conditional_branch): New pattern.
        (cbranch_sf4_<code>): New pattern/split.
        (float_conditional_branch): New pattern.
        (casesi): Use addsi3 pattern instead of movsi pattern to add and
        move a value at the same time.
        (cc0 peepholes): Remove.

From-SVN: r165459

gcc/ChangeLog
gcc/config/mn10300/mn10300-protos.h
gcc/config/mn10300/mn10300.c
gcc/config/mn10300/mn10300.h
gcc/config/mn10300/mn10300.md
gcc/config/mn10300/predicates.md

index 5a8a4eb..470849b 100644 (file)
@@ -1,3 +1,53 @@
+2010-10-14  Nick Clifton  <nickc@redhat.com>
+
+       * config/mn10300/mn10300.h (CONSTANT_ALIGNMENT): Define.
+       (DATA_ALIGNMENT, LOCAL_ALIGNMENT): Define.
+       (FIRST_PSEUDO_REGISTER): Increase by one.
+       (FIXED_REGISTERS, CALL_USED_REGISTERS): Update with CC_REG.
+       (HARD_REGNO_MODE_OK): Call mn10300_hard_regno_mode_ok.
+       (MODES_TIEABLE): Call mn10300_modes_tieable.
+       (REG_CLASS_NAMES, REG_CLASS_CONTENTS, REGNO_REG_CLASS): Add
+       CC_REGS.
+       (LEGITIMATE_CONSTANT_P): Call mn10300_legitimate_constant_p.
+       (CC_OVERFLOW_UNUSABLE, CC_NO_CARRY, NOTICE_UPDATE_CC)
+       (SELECT_CC_MODE, REVERSIBLE_CC_MODE): Delete.
+       (REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): Add CC register.
+       (ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP): Delete.
+       (mn10300_cc_status_mdep): Delete.
+       (CC_STATUS_MDEP, CC_STATUS_MDEP_INIT): Delete.
+       * config/mn10300/mn10300 (mn10300_option_override): Stop disabling
+       the combine-stack-adjust pass.
+       (print_operand): Use the mode of the comparison operation to
+       select the comparison suffix.
+       (notice_update_cc): Delete.
+       (mn10300_secondary_reload_class): Remove test for stack pointer
+       based arithmetic.
+       (output_tst): Rename to mn10300_output_cmp.
+       (impossible_plus_operand): Move into predicates.md.
+       (mn10300_legitimize_address): Make static.
+       (mn10300_legitimate_address_p): Make static.  Only allow SI sized
+       constant pic operands.
+       (mn10300_legitimate_constant_p): New function.
+       (mn10300_case_values_threshold): Make static.
+       (mn10300_hard_regno_mode_ok): New function.
+       (mn10300_modes_tieable): New function.
+       (mn10300_select_cc_mode): New function.
+       * config/mn10300/predicates.md (impossible_plus_operand): Define.
+       * config/mn10300/mn10300-protos.h: Tidy.
+       (mn10300_legitimate_constant_p, mn10300_modes_tieable)
+       (mn10300_hard_regno_mode_ok, mn10300_select_cc_mode): Prototype.
+       * config/mn10300/mn10300.md (cc attribute): Delete.  Replace
+       with clobbers or sets of CC_REG.
+       (CC_REG): Define.
+       (mov*): Remove use of CLR instruction.
+       (cbranch_si4_<code>): New pattern/split.
+       (integer_conditional_branch): New pattern.
+       (cbranch_sf4_<code>): New pattern/split.
+       (float_conditional_branch): New pattern.
+       (casesi): Use addsi3 pattern instead of movsi pattern to add and
+       move a value at the same time.
+       (cc0 peepholes): Remove.
+
 2010-10-14  Andrey Belevantsev  <abel@ispras.ru>
 
        * sel-sched-ir.c (init_global_and_expr_for_insn): Set CANT_MOVE
index 02a7942..1e0f18e 100644 (file)
@@ -19,35 +19,40 @@ You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-#ifdef RTX_CODE
+#define Mmode enum machine_mode
+#define Cstar const char *
+#define Rclas enum reg_class
 
-extern rtx legitimize_pic_address (rtx, rtx);
-extern int legitimate_pic_operand_p (rtx);
-extern void print_operand (FILE *, rtx, int);
-extern void print_operand_address (FILE *, rtx);
-extern void mn10300_print_reg_list (FILE *, int);
-extern int mn10300_get_live_callee_saved_regs (void);
-extern void mn10300_gen_multiple_store (int);
-extern void notice_update_cc (rtx, rtx);
-extern enum reg_class mn10300_secondary_reload_class (enum reg_class,
-                                                     enum machine_mode, rtx);
-extern const char *output_tst (rtx, rtx);
-extern int store_multiple_operation (rtx, enum machine_mode);
-extern int symbolic_operand (rtx, enum machine_mode);
-extern int impossible_plus_operand (rtx, enum machine_mode);
-
-extern bool mn10300_wide_const_load_uses_clr (rtx operands[2]);
-
-extern bool mn10300_function_value_regno_p (const unsigned int);
+#ifdef RTX_CODE
+extern rtx   legitimize_pic_address (rtx, rtx);
+extern int   legitimate_pic_operand_p (rtx);
+extern bool  mn10300_function_value_regno_p (const unsigned int);
+extern void  mn10300_gen_multiple_store (int);
+extern int   mn10300_get_live_callee_saved_regs (void);
+extern bool  mn10300_hard_regno_mode_ok (unsigned int, Mmode);
+extern bool  mn10300_legitimate_constant_p (rtx);
+extern bool  mn10300_modes_tieable (Mmode, Mmode);
+extern Cstar mn10300_output_cmp (rtx, rtx);
+extern void  mn10300_print_reg_list (FILE *, int);
+extern Rclas mn10300_secondary_reload_class (Rclas, Mmode, rtx);
+extern Mmode mn10300_select_cc_mode (rtx);
+extern bool  mn10300_wide_const_load_uses_clr (rtx operands[2]);
+extern void  print_operand (FILE *, rtx, int);
+extern void  print_operand_address (FILE *, rtx);
+extern int   store_multiple_operation (rtx, Mmode);
+extern int   symbolic_operand (rtx, Mmode);
 #endif /* RTX_CODE */
 
 #ifdef TREE_CODE
-extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
-                                    enum machine_mode, tree, int);
+extern struct rtx_def *function_arg (CUMULATIVE_ARGS *, Mmode, tree, int);
 #endif /* TREE_CODE */
 
-extern void expand_prologue (void);
-extern void expand_epilogue (void);
-extern int initial_offset (int, int);
-extern int can_use_return_insn (void);
-extern int mask_ok_for_mem_btst (int, int);
+extern int   can_use_return_insn (void);
+extern void  expand_prologue (void);
+extern void  expand_epilogue (void);
+extern int   initial_offset (int, int);
+extern int   mask_ok_for_mem_btst (int, int);
+
+#undef Mmode
+#undef Cstar
+#undef Rclas
index 47e5293..5e420a5 100644 (file)
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm_p.h"
 #include "target.h"
 #include "target-def.h"
+#include "df.h"
 
 /* This is used by GOTaddr2picreg to uniquely identify
    UNSPEC_INT_LABELs.  */
@@ -190,12 +191,6 @@ mn10300_option_override (void)
 {
   if (TARGET_AM33)
     target_flags &= ~MASK_MULT_BUG;
-
-  /* FIXME: The combine stack adjustments pass is breaking
-     cc0-setter/cc0-user relationship by inserting a jump
-     instruction.  This should be investigated, but for now
-     just disable the pass.  */
-  flag_combine_stack_adjustments = 0;
 }
 
 static void
@@ -220,7 +215,7 @@ print_operand (FILE *file, rtx x, int code)
     {
       case 'b':
       case 'B':
-       if (cc_status.mdep.fpCC)
+       if (GET_MODE (XEXP (x, 0)) == CC_FLOATmode)
          {
            switch (code == 'b' ? GET_CODE (x)
                    : reverse_condition_maybe_unordered (GET_CODE (x)))
@@ -1008,7 +1003,7 @@ expand_epilogue (void)
   /* SIZE includes the fixed stack space needed for function calls.  */
   size = get_frame_size () + crtl->outgoing_args_size;
   size += (crtl->outgoing_args_size ? 4 : 0);
-
+  
   if (TARGET_AM33_2 && fp_regs_to_save ())
     {
       int num_regs_to_save = fp_regs_to_save (), i;
@@ -1236,59 +1231,6 @@ expand_epilogue (void)
     emit_jump_insn (gen_return_internal ());
 }
 
-/* Update the condition code from the insn.  */
-
-void
-notice_update_cc (rtx body, rtx insn)
-{
-  switch (get_attr_cc (insn))
-    {
-    case CC_NONE:
-      /* Insn does not affect CC at all.  */
-      break;
-
-    case CC_NONE_0HIT:
-      /* Insn does not change CC, but the 0'th operand has been changed.  */
-      if (cc_status.value1 != 0
-         && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
-       cc_status.value1 = 0;
-      break;
-
-    case CC_SET_ZN:
-      /* Insn sets the Z,N flags of CC to recog_data.operand[0].
-        V,C are unusable.  */
-      CC_STATUS_INIT;
-      cc_status.flags |= CC_NO_CARRY | CC_OVERFLOW_UNUSABLE;
-      cc_status.value1 = recog_data.operand[0];
-      break;
-
-    case CC_SET_ZNV:
-      /* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
-        C is unusable.  */
-      CC_STATUS_INIT;
-      cc_status.flags |= CC_NO_CARRY;
-      cc_status.value1 = recog_data.operand[0];
-      break;
-
-    case CC_COMPARE:
-      /* The insn is a compare instruction.  */
-      CC_STATUS_INIT;
-      cc_status.value1 = SET_SRC (body);
-      if (GET_CODE (SET_SRC (body)) == COMPARE
-         && GET_MODE (XEXP (SET_SRC (body), 0)) == SFmode)
-       cc_status.mdep.fpCC = 1;
-      break;
-
-    case CC_CLOBBER:
-      /* Insn doesn't leave CC in a usable state.  */
-      CC_STATUS_INIT;
-      break;
-
-    default:
-      gcc_unreachable ();
-    }
-}
-
 /* Recognize the PARALLEL rtx generated by mn10300_gen_multiple_store().
    This function is for MATCH_PARALLEL and so assumes OP is known to be
    parallel.  If OP is a multiple store, return a mask indicating which
@@ -1413,11 +1355,6 @@ mn10300_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
                  || XEXP (in, 1) == stack_pointer_rtx))))
     return ADDRESS_REGS;
 
-  if (GET_CODE (in) == PLUS
-      && (XEXP (in, 0) == stack_pointer_rtx
-         || XEXP (in, 1) == stack_pointer_rtx))
-    return GENERAL_REGS;
-
   if (TARGET_AM33_2
       && rclass == FP_REGS)
     {
@@ -1425,7 +1362,7 @@ mn10300_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
         constant address.  */
       if (GET_CODE (in) == MEM
          && CONSTANT_ADDRESS_P (XEXP (in, 0)))
-       return (TARGET_AM33 ? DATA_OR_EXTENDED_REGS : DATA_REGS);
+       return DATA_OR_EXTENDED_REGS;
 
       /* Handle case were a pseudo may not get a hard register
         but has an equivalent memory location defined.  */
@@ -1433,7 +1370,7 @@ mn10300_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
          && REGNO (inner) >= FIRST_PSEUDO_REGISTER
          && reg_equiv_mem [REGNO (inner)]
          && CONSTANT_ADDRESS_P (XEXP (reg_equiv_mem [REGNO (inner)], 0)))
-       return (TARGET_AM33 ? DATA_OR_EXTENDED_REGS : DATA_REGS);
+       return DATA_OR_EXTENDED_REGS;
     }
 
   /* Otherwise assume no secondary reloads are needed.  */
@@ -1696,9 +1633,10 @@ mn10300_function_value_regno_p (const unsigned int regno)
  return (regno == FIRST_DATA_REGNUM || regno == FIRST_ADDRESS_REGNUM);
 }
 
-/* Output a tst insn.  */
+/* Output a compare insn.  */
+
 const char *
-output_tst (rtx operand, rtx insn)
+mn10300_output_cmp (rtx operand, rtx insn)
 {
   rtx temp;
   int past_call = 0;
@@ -1786,19 +1724,6 @@ output_tst (rtx operand, rtx insn)
   return "cmp 0,%0";
 }
 
-int
-impossible_plus_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  if (GET_CODE (op) != PLUS)
-    return 0;
-
-  if (XEXP (op, 0) == stack_pointer_rtx
-      || XEXP (op, 1) == stack_pointer_rtx)
-    return 1;
-
-  return 0;
-}
-
 /* Similarly, but when using a zero_extract pattern for a btst where
    the source operand might end up in memory.  */
 int
@@ -1853,7 +1778,7 @@ symbolic_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
 
    But on a few ports with segmented architectures and indexed addressing
    (mn10300, hppa) it is used to rewrite certain problematical addresses.  */
-rtx
+static rtx
 mn10300_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
                            enum machine_mode mode ATTRIBUTE_UNUSED)
 {
@@ -1941,7 +1866,7 @@ legitimate_pic_operand_p (rtx x)
     {
       if (fmt[i] == 'E')
        {
-         register int j;
+         int j;
 
          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
            if (! legitimate_pic_operand_p (XVECEXP (x, i, j)))
@@ -1968,7 +1893,7 @@ legitimate_pic_operand_p (rtx x)
    workaround and solution, see the comments in pa.c before the
    function record_unscaled_index_insn_codes.  */
 
-bool
+static bool
 mn10300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
 {
   if (CONSTANT_ADDRESS_P (x)
@@ -2009,7 +1934,8 @@ mn10300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
          if (GET_CODE (index) == CONST
              && GET_CODE (XEXP (index, 0)) != PLUS
              && (! flag_pic
-                 || legitimate_pic_operand_p (index)))
+                 || (legitimate_pic_operand_p (index)
+                     && GET_MODE_SIZE (mode) == 4)))
            return TRUE;
        }
     }
@@ -2017,6 +1943,55 @@ mn10300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
   return FALSE;
 }
 
+/* Used by LEGITIMATE_CONSTANT_P().  Returns TRUE if X is a valid
+   constant.  Note that some "constants" aren't valid, such as TLS
+   symbols and unconverted GOT-based references, so we eliminate
+   those here.  */
+
+bool
+mn10300_legitimate_constant_p (rtx x)
+{
+  switch (GET_CODE (x))
+    {
+    case CONST:
+      x = XEXP (x, 0);
+
+      if (GET_CODE (x) == PLUS)
+       {
+         if (GET_CODE (XEXP (x, 1)) != CONST_INT)
+           return false;
+         x = XEXP (x, 0);
+       }
+
+      /* Only some unspecs are valid as "constants".  */
+      if (GET_CODE (x) == UNSPEC)
+       {
+         rtx sym = XVECEXP (x, 0, 0);
+         switch (XINT (x, 1))
+           {
+           case UNSPEC_INT_LABEL:
+           case UNSPEC_PIC:
+           case UNSPEC_GOT:
+           case UNSPEC_GOTOFF:
+           case UNSPEC_PLT:
+             return true;
+           default:
+             return false;
+           }
+       }
+
+      /* We must have drilled down to a symbol.  */
+      if (!symbolic_operand (x, Pmode))
+       return false;
+      break;
+
+    default:
+      break;
+    }
+
+  return true;
+}
+
 static int
 mn10300_address_cost_1 (rtx x, int *unsig)
 {
@@ -2215,7 +2190,8 @@ mn10300_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
    were solely optimizing for space, but we keep it "reasonable" to avoid
    serious code efficiency lossage.  */
 
-unsigned int mn10300_case_values_threshold (void)
+static unsigned int
+mn10300_case_values_threshold (void)
 {
   return 6;
 }
@@ -2310,3 +2286,48 @@ mn10300_can_output_mi_thunk (const_tree    thunk_fndecl ATTRIBUTE_UNUSED,
 {
   return true;
 }
+
+bool
+mn10300_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
+{
+  if (REGNO_REG_CLASS (regno) == FP_REGS
+      || REGNO_REG_CLASS (regno) == FP_ACC_REGS)
+    /* Do not store integer values in FP registers.  */
+    return GET_MODE_CLASS (mode) == MODE_FLOAT && ((regno & 1) == 0);
+  
+  if (((regno) & 1) == 0 || GET_MODE_SIZE (mode) == 4)
+    return true;
+
+  if (REGNO_REG_CLASS (regno) == DATA_REGS
+      || (TARGET_AM33 && REGNO_REG_CLASS (regno) == ADDRESS_REGS)
+      || REGNO_REG_CLASS (regno) == EXTENDED_REGS)
+    return GET_MODE_SIZE (mode) <= 4;
+  
+  return false;
+}
+
+bool
+mn10300_modes_tieable (enum machine_mode mode1, enum machine_mode mode2)
+{
+  if (GET_MODE_CLASS (mode1) == MODE_FLOAT
+      && GET_MODE_CLASS (mode2) != MODE_FLOAT)
+    return false;
+
+  if (GET_MODE_CLASS (mode2) == MODE_FLOAT
+      && GET_MODE_CLASS (mode1) != MODE_FLOAT)
+    return false;
+
+  if (TARGET_AM33
+      || mode1 == mode2
+      || (GET_MODE_SIZE (mode1) <= 4 && GET_MODE_SIZE (mode2) <= 4))
+    return true;
+
+  return false;
+}
+
+enum machine_mode
+mn10300_select_cc_mode (rtx x)
+{
+  return (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) ? CC_FLOATmode : CCmode;
+}
+\f
index 26990ad..82f3e04 100644 (file)
@@ -117,28 +117,32 @@ extern enum processor_type mn10300_processor;
    All registers that the compiler knows about must be given numbers,
    even those that are not normally considered general registers.  */
 
-#define FIRST_PSEUDO_REGISTER 51
-
-/* Specify machine-specific register numbers.  */
-#define FIRST_DATA_REGNUM 0
-#define LAST_DATA_REGNUM 3
-#define FIRST_ADDRESS_REGNUM 4
-#define LAST_ADDRESS_REGNUM 8
+#define FIRST_PSEUDO_REGISTER 52
+
+/* Specify machine-specific register numbers.  The commented out entries
+   are defined in mn10300.md.  */
+#define FIRST_DATA_REGNUM      0
+#define LAST_DATA_REGNUM       3
+#define FIRST_ADDRESS_REGNUM   4
+/* #define PIC_REG             6 */
+#define LAST_ADDRESS_REGNUM    8
+/* #define SP_REG              9 */
 #define FIRST_EXTENDED_REGNUM 10
-#define LAST_EXTENDED_REGNUM 17
-#define FIRST_FP_REGNUM 18
-#define LAST_FP_REGNUM 49
-#define MDR_REGNUM 50
-#define FIRST_ARGUMENT_REGNUM 0
+#define LAST_EXTENDED_REGNUM  17
+#define FIRST_FP_REGNUM       18
+#define LAST_FP_REGNUM        49
+#define MDR_REGNUM            50
+/* #define CC_REG             51 */
+#define FIRST_ARGUMENT_REGNUM  0
 
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
 
 /* Register to use for pushing function arguments.  */
-#define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM+1)
+#define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM + 1)
 
 /* Base register for access to local variables of the function.  */
-#define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM-1)
+#define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM - 1)
 
 /* Base register for access to arguments of the function.  This
    is a fake register and will be eliminated into either the frame
@@ -146,15 +150,15 @@ extern enum processor_type mn10300_processor;
 #define ARG_POINTER_REGNUM LAST_ADDRESS_REGNUM
 
 /* Register in which static-chain is passed to a function.  */
-#define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM+1)
+#define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM + 1)
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.  */
 
 #define FIXED_REGISTERS \
   { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \
+  , 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, 0, 0, 0, 0, 0, 0, 0, 1, 1 \
   }
 
 /* 1 for registers not available across function calls.
@@ -167,8 +171,8 @@ extern enum processor_type mn10300_processor;
 
 #define CALL_USED_REGISTERS \
   { 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 \
-  , 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \
-  , 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
+  , 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0      \
+  , 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
   }
 
 /* Note: The definition of CALL_REALLY_USED_REGISTERS is not
@@ -181,7 +185,7 @@ extern enum processor_type mn10300_processor;
 #define REG_ALLOC_ORDER \
   { 0, 1, 4, 5, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 8, 9 \
   , 42, 43, 44, 45, 46, 47, 48, 49, 34, 35, 36, 37, 38, 39, 40, 41 \
-  , 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 \
+  , 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 51 \
   }
 
 #define CONDITIONAL_REGISTER_USAGE \
@@ -197,8 +201,7 @@ extern enum processor_type mn10300_processor;
   if (!TARGET_AM33_2)                          \
     {                                          \
       for (i = FIRST_FP_REGNUM;                        \
-          i <= LAST_FP_REGNUM;                 \
-           i++)                                \
+          i <= LAST_FP_REGNUM; i++)            \
        fixed_regs[i] = call_used_regs[i] = 1;  \
     }                                          \
   if (flag_pic)                                        \
@@ -217,22 +220,15 @@ extern enum processor_type mn10300_processor;
 
 /* Value is 1 if hard register REGNO can hold a value of machine-mode
    MODE.  */
-
 #define HARD_REGNO_MODE_OK(REGNO, MODE) \
- ((REGNO_REG_CLASS (REGNO) == DATA_REGS \
-   || (TARGET_AM33 && REGNO_REG_CLASS (REGNO) == ADDRESS_REGS) \
-   || REGNO_REG_CLASS (REGNO) == EXTENDED_REGS) \
-  ? ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) <= 4    \
-  : ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) == 4)
+  mn10300_hard_regno_mode_ok ((REGNO), (MODE))
 
 /* Value is 1 if it is a good idea to tie two pseudo registers
    when one has mode MODE1 and one has mode MODE2.
    If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
    for any hard reg, then this must be 0 for correct output.  */
 #define MODES_TIEABLE_P(MODE1, MODE2) \
-  (TARGET_AM33  \
-   || MODE1 == MODE2 \
-   || (GET_MODE_SIZE (MODE1) <= 4 && GET_MODE_SIZE (MODE2) <= 4))
+  mn10300_modes_tieable ((MODE1), (MODE2))
 
 /* 4 data, and effectively 3 address registers is small as far as I'm
    concerned.  */
@@ -263,7 +259,7 @@ enum reg_class {
   DATA_OR_ADDRESS_REGS, SP_OR_ADDRESS_REGS,
   EXTENDED_REGS, DATA_OR_EXTENDED_REGS, ADDRESS_OR_EXTENDED_REGS,
   SP_OR_EXTENDED_REGS, SP_OR_ADDRESS_OR_EXTENDED_REGS,
-  FP_REGS, FP_ACC_REGS,
+  FP_REGS, FP_ACC_REGS, CC_REGS,
   GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
 };
 
@@ -271,35 +267,36 @@ enum reg_class {
 
 /* Give names of register classes as strings for dump file.  */
 
-#define REG_CLASS_NAMES \
-{ "NO_REGS", "DATA_REGS", "ADDRESS_REGS", \
-  "SP_REGS", "DATA_OR_ADDRESS_REGS", "SP_OR_ADDRESS_REGS", \
-  "EXTENDED_REGS", \
-  "DATA_OR_EXTENDED_REGS", "ADDRESS_OR_EXTENDED_REGS", \
-  "SP_OR_EXTENDED_REGS", "SP_OR_ADDRESS_OR_EXTENDED_REGS", \
-  "FP_REGS", "FP_ACC_REGS", \
+#define REG_CLASS_NAMES                                                \
+{ "NO_REGS", "DATA_REGS", "ADDRESS_REGS",                      \
+  "SP_REGS", "DATA_OR_ADDRESS_REGS", "SP_OR_ADDRESS_REGS",     \
+  "EXTENDED_REGS",                                             \
+  "DATA_OR_EXTENDED_REGS", "ADDRESS_OR_EXTENDED_REGS",         \
+  "SP_OR_EXTENDED_REGS", "SP_OR_ADDRESS_OR_EXTENDED_REGS",     \
+  "FP_REGS", "FP_ACC_REGS", "CC_REGS",                         \
   "GENERAL_REGS", "ALL_REGS", "LIM_REGS" }
 
 /* Define which registers fit in which classes.
    This is an initializer for a vector of HARD_REG_SET
    of length N_REG_CLASSES.  */
 
-#define REG_CLASS_CONTENTS                     \
-{  { 0,        0 },            /* No regs      */      \
- { 0x0000f, 0 },       /* DATA_REGS */         \
- { 0x001f0, 0 },       /* ADDRESS_REGS */      \
- { 0x00200, 0 },       /* SP_REGS */           \
- { 0x001ff, 0 },       /* DATA_OR_ADDRESS_REGS */\
- { 0x003f0, 0 },       /* SP_OR_ADDRESS_REGS */\
- { 0x3fc00, 0 },       /* EXTENDED_REGS */     \
- { 0x3fc0f, 0 },       /* DATA_OR_EXTENDED_REGS */     \
- { 0x3fdf0, 0 },       /* ADDRESS_OR_EXTENDED_REGS */  \
- { 0x3fe00, 0 },       /* SP_OR_EXTENDED_REGS */       \
- { 0x3fff0, 0 },       /* SP_OR_ADDRESS_OR_EXTENDED_REGS */    \
- { 0xfffc0000, 0x3ffff }, /* FP_REGS */                \
- { 0x03fc0000, 0 },    /* FP_ACC_REGS */       \
- { 0x3fdff, 0 },       /* GENERAL_REGS */      \
- { 0xffffffff, 0x7ffff } /* ALL_REGS   */      \
+#define REG_CLASS_CONTENTS                                     \
+{ { 0,         0 },      /* No regs      */                    \
+  { 0x0000000f, 0 },     /* DATA_REGS */                       \
+  { 0x000001f0, 0 },     /* ADDRESS_REGS */                    \
+  { 0x00000200, 0 },     /* SP_REGS */                         \
+  { 0x000001ff, 0 },     /* DATA_OR_ADDRESS_REGS */            \
+  { 0x000003f0, 0 },     /* SP_OR_ADDRESS_REGS */              \
+  { 0x0003fc00, 0 },     /* EXTENDED_REGS */                   \
+  { 0x0003fc0f, 0 },     /* DATA_OR_EXTENDED_REGS */           \
+  { 0x0003fdf0, 0 },     /* ADDRESS_OR_EXTENDED_REGS */        \
+  { 0x0003fe00, 0 },     /* SP_OR_EXTENDED_REGS */             \
+  { 0x0003fff0, 0 },     /* SP_OR_ADDRESS_OR_EXTENDED_REGS */  \
+  { 0xfffc0000, 0x3ffff },/* FP_REGS */                                \
+  { 0x03fc0000, 0 },     /* FP_ACC_REGS */                     \
+  { 0x00000000, 0x80000 },/* CC_REGS */                                \
+  { 0x0003fdff, 0 },     /* GENERAL_REGS */                    \
+  { 0xffffffff, 0xfffff } /* ALL_REGS  */                      \
 }
 
 /* The following macro defines cover classes for Integrated Register
@@ -326,6 +323,7 @@ enum reg_class {
    (REGNO) == STACK_POINTER_REGNUM ? SP_REGS : \
    (REGNO) <= LAST_EXTENDED_REGNUM ? EXTENDED_REGS : \
    (REGNO) <= LAST_FP_REGNUM ? FP_REGS : \
+   (REGNO) == CC_REG ? CC_REGS : \
    NO_REGS)
 
 /* The class value for index registers, and the one for base regs.  */
@@ -496,10 +494,11 @@ enum reg_class {
 #define REG_PARM_STACK_SPACE(DECL) 8
 #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
 #define ACCUMULATE_OUTGOING_ARGS 1
-
+#if 1
 /* So we can allocate space for return pointers once for the function
    instead of around every call.  */
 #define STACK_POINTER_OFFSET 4
+#endif
 
 /* 1 if N is a possible register number for function argument passing.
    On the MN10300, d0 and d1 are used in this way.  */
@@ -611,8 +610,7 @@ struct cum_arg {int nbytes; };
 
 /* Nonzero if the constant value X is a legitimate general operand.
    It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
-
-#define LEGITIMATE_CONSTANT_P(X) 1
+#define LEGITIMATE_CONSTANT_P(X) mn10300_legitimate_constant_p (X)
 
 /* Zero if this needs fixing up to become PIC.  */
 
@@ -675,20 +673,9 @@ struct cum_arg {int nbytes; };
       goto FAIL;                                                       \
   while (0)
 \f
-/* Tell final.c how to eliminate redundant test instructions.  */
-
-/* Here we define machine-dependent flags and fields in cc_status
-   (see `conditions.h').  No extra ones are needed for the VAX.  */
-
-/* Store in cc_status the expressions
-   that the condition codes will describe
-   after execution of an instruction whose pattern is EXP.
-   Do not alter them if the instruction would not alter the cc's.  */
-
-#define CC_OVERFLOW_UNUSABLE 0x200
-#define CC_NO_CARRY CC_NO_OVERFLOW
-#define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc(EXP, INSN)
-
+#define SELECT_CC_MODE(OP, X, Y)  mn10300_select_cc_mode (X)
+#define REVERSIBLE_CC_MODE(MODE)  0
+\f
 #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
   ((CLASS1 == CLASS2 && (CLASS1 == ADDRESS_REGS || CLASS1 == DATA_REGS)) ? 2 :\
    ((CLASS1 == ADDRESS_REGS || CLASS1 == DATA_REGS) && \
@@ -762,24 +749,26 @@ struct cum_arg {int nbytes; };
 /* How to refer to registers in assembler output.
    This sequence is indexed by compiler's hard-register-number (see above).  */
 
-#define REGISTER_NAMES \
-{ "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp", \
-  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" \
-, "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7" \
-, "fs8", "fs9", "fs10", "fs11", "fs12", "fs13", "fs14", "fs15" \
-, "fs16", "fs17", "fs18", "fs19", "fs20", "fs21", "fs22", "fs23" \
-    , "fs24", "fs25", "fs26", "fs27", "fs28", "fs29", "fs30", "fs31", "mdr"    \
+#define REGISTER_NAMES                                                 \
+{ "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp",          \
+  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"                       \
+, "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"               \
+, "fs8", "fs9", "fs10", "fs11", "fs12", "fs13", "fs14", "fs15"         \
+, "fs16", "fs17", "fs18", "fs19", "fs20", "fs21", "fs22", "fs23"       \
+, "fs24", "fs25", "fs26", "fs27", "fs28", "fs29", "fs30", "fs31"       \
+, "mdr", "EPSW"                                                                \
 }
 
-#define ADDITIONAL_REGISTER_NAMES \
-{ {"r8",  4}, {"r9",  5}, {"r10", 6}, {"r11", 7}, \
-  {"r12", 0}, {"r13", 1}, {"r14", 2}, {"r15", 3}, \
-  {"e0", 10}, {"e1", 11}, {"e2", 12}, {"e3", 13}, \
-  {"e4", 14}, {"e5", 15}, {"e6", 16}, {"e7", 17} \
-, {"fd0", 18}, {"fd2", 20}, {"fd4", 22}, {"fd6", 24} \
-, {"fd8", 26}, {"fd10", 28}, {"fd12", 30}, {"fd14", 32} \
-, {"fd16", 34}, {"fd18", 36}, {"fd20", 38}, {"fd22", 40} \
-, {"fd24", 42}, {"fd26", 44}, {"fd28", 46}, {"fd30", 48} \
+#define ADDITIONAL_REGISTER_NAMES                              \
+{ {"r8",  4}, {"r9",  5}, {"r10", 6}, {"r11", 7},              \
+  {"r12", 0}, {"r13", 1}, {"r14", 2}, {"r15", 3},              \
+  {"e0", 10}, {"e1", 11}, {"e2", 12}, {"e3", 13},              \
+  {"e4", 14}, {"e5", 15}, {"e6", 16}, {"e7", 17}               \
+, {"fd0", 18}, {"fd2", 20}, {"fd4", 22}, {"fd6", 24}           \
+, {"fd8", 26}, {"fd10", 28}, {"fd12", 30}, {"fd14", 32}                \
+, {"fd16", 34}, {"fd18", 36}, {"fd20", 38}, {"fd22", 40}       \
+, {"fd24", 42}, {"fd26", 44}, {"fd28", 46}, {"fd30", 48}       \
+, {"cc", CC_REG}                                               \
 }
 
 /* Print an instruction operand X on file FILE.
@@ -792,9 +781,6 @@ struct cum_arg {int nbytes; };
 
 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
 
-#define ASM_OUTPUT_REG_PUSH(FILE,REGNO)
-#define ASM_OUTPUT_REG_POP(FILE,REGNO)
-
 /* This is how to output an element of a case-vector that is absolute.  */
 
 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
@@ -883,12 +869,3 @@ struct cum_arg {int nbytes; };
 
 #define FILE_ASM_OP "\t.file\n"
 
-typedef struct mn10300_cc_status_mdep
-  {
-    int fpCC;
-  }
-cc_status_mdep;
-
-#define CC_STATUS_MDEP cc_status_mdep
-
-#define CC_STATUS_MDEP_INIT (cc_status.mdep.fpCC = 0)
index a2b6296..199617a 100644 (file)
@@ -1,6 +1,7 @@
 ;; GCC machine description for Matsushita MN10300
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-;; 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+;; 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
 ;; Contributed by Jeff Law (law@cygnus.com).
 
 ;; This file is part of GCC.
 
 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
 
-;; Condition code settings.
-;; none - insn does not affect cc
-;; none_0hit - insn does not affect cc but it does modify operand 0
-;;     This attribute is used to keep track of when operand 0 changes.
-;;     See the description of NOTICE_UPDATE_CC for more info.
-;; set_znv - insn sets z,n,v to usable values; c is unusable.
-;; set_zn  - insn sets z,n to usable values; v,c are unusable.
-;; compare - compare instruction
-;; clobber - value of cc is unknown
-(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
-  (const_string "clobber"))
-
 (define_constants [
-  (PIC_REG     6)
-  (SP_REG      9)
+  (PIC_REG 6)
+  (SP_REG  9)
+  (CC_REG 51)
 
   (UNSPEC_INT_LABEL    0)
   (UNSPEC_PIC          1)
 ;; movqi
 
 (define_expand "movqi"
-  [(set (match_operand:QI 0 "general_operand" "")
-       (match_operand:QI 1 "general_operand" ""))]
+  [(set (match_operand:QI 0 "general_operand")
+       (match_operand:QI 1 "general_operand"))]
   ""
   "
 {
-  /* One of the ops has to be in a register */
+  /* One of the ops has to be in a register */
   if (!register_operand (operand0, QImode)
       && !register_operand (operand1, QImode))
     operands[1] = copy_to_mode_reg (QImode, operand1);
 }")
 
-(define_insn ""
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
-       (match_operand:QI 1 "general_operand" "0,I,d*xai,m,d*xa,d*xa*f,*f"))]
+(define_insn "*am33_movqi"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=d*x*a*f,d*x*a,d*x*a,m,*f,d*x*a")
+       (match_operand:QI 1 "general_operand"      "0,d*xai,m,d*xa,d*xa*f,*f"))]
   "TARGET_AM33
    && (register_operand (operands[0], QImode)
        || register_operand (operands[1], QImode))"
@@ -82,8 +72,6 @@
     case 0:
       return \"nop\";
     case 1:
-      return \"clr %0\";
-    case 2:
       if (GET_CODE (operands[1]) == CONST_DOUBLE)
        {
          rtx xoperands[2];
            return \"movu %1,%0\";
        }
       return \"mov %1,%0\";
+    case 2:
     case 3:
-    case 4:
       return \"movbu %1,%0\";
+    case 4:
     case 5:
-    case 6:
       return \"fmov %1,%0\";
     default:
       gcc_unreachable ();
     }
 }"
-  [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+)
 
-(define_insn ""
+(define_insn "*mn10300_movqi"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d,!*a,d*a,d,m")
        (match_operand:QI 1 "general_operand" "0,I,i,i,da,m,d"))]
   "register_operand (operands[0], QImode)
     case 0:
       return \"nop\";
     case 1:
-      return \"clr %0\";
     case 2:
     case 3:
     case 4:
       gcc_unreachable ();
     }
 }"
-  [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+)
 
 ;; movhi
 
 (define_expand "movhi"
-  [(set (match_operand:HI 0 "general_operand" "")
-       (match_operand:HI 1 "general_operand" ""))]
+  [(set (match_operand:HI 0 "general_operand")
+       (match_operand:HI 1 "general_operand"))]
   ""
   "
 {
-  /* One of the ops has to be in a register */
+  /* One of the ops has to be in a register */
   if (!register_operand (operand1, HImode)
       && !register_operand (operand0, HImode))
     operands[1] = copy_to_mode_reg (HImode, operand1);
 }")
 
-(define_insn ""
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
-       (match_operand:HI 1 "general_operand" "0,I,d*x*ai,m,d*x*a,d*x*a*f,*f"))]
+(define_insn "*am33_movhi"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a*f,d*x*a,d*x*a,m,*f,d*x*a")
+       (match_operand:HI 1 "general_operand"      "0,d*x*ai,m,d*x*a,d*x*a*f,*f"))]
   "TARGET_AM33
    && (register_operand (operands[0], HImode)
        || register_operand (operands[1], HImode))"
     case 0:
       return \"nop\";
     case 1:
-      return \"clr %0\";
-    case 2:
       if (GET_CODE (operands[1]) == CONST_DOUBLE)
        {
          rtx xoperands[2];
            return \"movu %1,%0\";
        }
       return \"mov %1,%0\";
+    case 2:
     case 3:
-    case 4:
       return \"movhu %1,%0\";
+    case 4:
     case 5:
-    case 6:
       return \"fmov %1,%0\";
     default:
       gcc_unreachable ();
     }
 }"
-  [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+)
 
-(define_insn ""
+(define_insn "*mn10300_movhi"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d,!*a,d*a,d,m")
        (match_operand:HI 1 "general_operand" "0,I,i,i,da,m,d"))]
   "register_operand (operands[0], HImode)
     case 0:
       return \"nop\";
     case 1:
-      return \"clr %0\";
     case 2:
     case 3:
     case 4:
       gcc_unreachable ();
     }
 }"
-  [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+)
 
 ;; movsi and helpers
 
 ;; stack pointer and the other is a memory reference of some kind.  Reload
 ;; does not handle them correctly without this expander.
 (define_expand "reload_insi"
-  [(set (match_operand:SI 0 "register_operand" "=a")
-       (match_operand:SI 1 "impossible_plus_operand" ""))
+  [(set (match_operand:SI     0 "register_operand" "=a")
+       (match_operand:SI     1 "impossible_plus_operand" ""))
    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
   ""
   "
 {
+  gcc_assert (REGNO (operands[0]) != REGNO (operands[2]));
+
   if (XEXP (operands[1], 0) == stack_pointer_rtx)
     {
       if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
   "movm (sp),[a2]")
 
 (define_expand "movsi"
-  [(set (match_operand:SI 0 "general_operand" "")
-       (match_operand:SI 1 "general_operand" ""))]
+  [(set (match_operand:SI 0 "general_operand")
+       (match_operand:SI 1 "general_operand"))]
   ""
   "
 {
-  /* One of the ops has to be in a register */
+  /* One of the ops has to be in a register */
   if (!register_operand (operand1, SImode)
       && !register_operand (operand0, SImode))
     operands[1] = copy_to_mode_reg (SImode, operand1);
     }
 }")
 
-(define_insn ""
+(define_insn "*movsi_internal"
   [(set (match_operand:SI 0 "nonimmediate_operand"
                                "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,!*y,*f,*f,dxaQ")
        (match_operand:SI 1 "general_operand"
     case 1:
       return \"nop\";
     case 2:
-      return \"clr %0\";
     case 3:
     case 4:
     case 5:
       gcc_unreachable ();
     }
 }"
-  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none,none_0hit,none_0hit")])
+)
 
 (define_expand "movsf"
-  [(set (match_operand:SF 0 "general_operand" "")
-       (match_operand:SF 1 "general_operand" ""))]
+  [(set (match_operand:SF 0 "general_operand")
+       (match_operand:SF 1 "general_operand"))]
   ""
   "
 {
-  /* One of the ops has to be in a register */
+  /* One of the ops has to be in a register */
   if (!register_operand (operand1, SFmode)
       && !register_operand (operand0, SFmode))
     operands[1] = copy_to_mode_reg (SFmode, operand1);
 }")
 
-(define_insn ""
+(define_insn "*movsf_internal"
   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,dx,ax,dx,a,f,dxaQ,daxm,dax")
-       (match_operand:SF 1 "general_operand" "0,0,0,G,G,fdxaQF,f,dax,daxFm"))]
+       (match_operand:SF 1 "general_operand"       "0,0,0,G,G,fdxaQF,f,dax,daxFm"))]
   "register_operand (operands[0], SFmode)
    || register_operand (operands[1], SFmode)"
   "*
     case 1:
     case 2:
       return \"nop\";
-    case 3:
-      return \"clr %0\";
-    /* case 4: below */
+    /* Cases 3 & 4: below.  */
     case 5:
     case 6:
       return \"fmov %1, %0\";
+    case 3:
     case 4:
     case 7:
     case 8:
       gcc_unreachable ();
     }
 }"
-  [(set_attr "cc" "none,none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
+)
 
 (define_expand "movdi"
-  [(set (match_operand:DI 0 "general_operand" "")
-       (match_operand:DI 1 "general_operand" ""))]
+  [(set (match_operand:DI 0 "general_operand")
+       (match_operand:DI 1 "general_operand"))]
   ""
   "
 {
-  /* One of the ops has to be in a register */
+  /* One of the ops has to be in a register */
   if (!register_operand (operand1, DImode)
       && !register_operand (operand0, DImode))
     operands[1] = copy_to_mode_reg (DImode, operand1);
 }")
 
-(define_insn ""
+(define_insn "*movdi_internal"
   [(set (match_operand:DI 0 "nonimmediate_operand"
                                "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,*f,*f,*f,dxa,*f,Q")
        (match_operand:DI 1 "general_operand"
        return \"nop\";
 
       case 2:
-       return \"clr %L0\;clr %H0\";
+       return \"mov 0, %L0\;mov 0, %H0\";
 
       case 3:
        if (rtx_equal_p (operands[0], operands[1]))
                && val[0] == 0)
              {
                if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-                 output_asm_insn (\"clr %L0\", operands);
+                 output_asm_insn (\"mov 0, %L0\", operands);
                else
                  output_asm_insn (\"mov %L1,%L0\", operands);
              }
                && val[1] == 0)
              {
                if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-                 output_asm_insn (\"clr %H0\", operands);
+                 output_asm_insn (\"mov 0, %H0\", operands);
                else
                  output_asm_insn (\"mov %H1,%H0\", operands);
              }
       gcc_unreachable ();
     }
 }"
-  [(set (attr "cc")
-       (cond
-        [
-        (ior (lt (symbol_ref "which_alternative") (const_int 2))
-             (eq (symbol_ref "which_alternative") (const_int 12))
-             ) (const_string "none")
-        (eq (symbol_ref "which_alternative") (const_int 2)
-            ) (const_string "clobber")
-        (eq (symbol_ref "which_alternative") (const_int 3)
-            ) (if_then_else
-               (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
-                   (const_int 0)) (const_string "clobber")
-                   (const_string "none_0hit"))
-        (ior (eq (symbol_ref "which_alternative") (const_int 8))
-             (eq (symbol_ref "which_alternative") (const_int 9))
-             ) (if_then_else
-                (ne (symbol_ref "mn10300_wide_const_load_uses_clr
-                                 (operands)")
-                    (const_int 0)) (const_string "clobber")
-                    (const_string "none_0hit"))
-        ] (const_string "none_0hit")))])
+)
 
 (define_expand "movdf"
-  [(set (match_operand:DF 0 "general_operand" "")
-       (match_operand:DF 1 "general_operand" ""))]
+  [(set (match_operand:DF 0 "general_operand")
+       (match_operand:DF 1 "general_operand"))]
   ""
   "
 {
-  /* One of the ops has to be in a register */
+  /* One of the ops has to be in a register */
   if (!register_operand (operand1, DFmode)
       && !register_operand (operand0, DFmode))
     operands[1] = copy_to_mode_reg (DFmode, operand1);
 }")
 
-(define_insn ""
+(define_insn "*am33_2_movdf"
   [(set (match_operand:DF 0 "nonimmediate_operand"
+                         ;;      0 1  2  3  4 5 6   7 8 9 10  11  12  13  14 15 16 17
                                "=f,dx,ax,dx,f,f,dxa,f,Q,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
        (match_operand:DF 1 "general_operand"
+                         ;;     0 1 2 3 4 5    6 7 8 9 10 11 12 13 14   15   16   17
                                "0,0,0,G,f,dxaF,f,Q,f,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
-  "register_operand (operands[0], DFmode)
-   || register_operand (operands[1], DFmode)"
+  "TARGET_AM33_2
+       && (register_operand (operands[0], DFmode)
+       || register_operand (operands[1], DFmode))"
   "*
 {
   long val[2];
        return \"nop\";
 
       case 3:
-       return \"clr %L0\;clr %H0\";
+       return \"mov 0, %L0\;mov 0, %H0\";
 
       case 4:
       case 5:
                && val[0] == 0)
              {
                if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-                 output_asm_insn (\"clr %L0\", operands);
+                 output_asm_insn (\"mov 0, %L0\", operands);
                else
                  output_asm_insn (\"mov %L1,%L0\", operands);
              }
                && val[1] == 0)
              {
                if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
-                 output_asm_insn (\"clr %H0\", operands);
+                 output_asm_insn (\"mov 0, %H0\", operands);
                else
                  output_asm_insn (\"mov %H1,%H0\", operands);
              }
       gcc_unreachable ();
     }
 }"
-  [(set (attr "cc")
-       (cond
-        [
-        (lt (symbol_ref "which_alternative") (const_int 3)
-            ) (const_string "none")
-        (eq (symbol_ref "which_alternative") (const_int 3)
-            ) (const_string "clobber")
-        (eq (symbol_ref "which_alternative") (const_int 9)
-            ) (if_then_else
-               (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
-                   (const_int 0)) (const_string "clobber")
-                   (const_string "none_0hit"))
-        (ior (eq (symbol_ref "which_alternative") (const_int 14))
-             (eq (symbol_ref "which_alternative") (const_int 15))
-             ) (if_then_else
-                (ne (symbol_ref "mn10300_wide_const_load_uses_clr
-                                 (operands)")
-                    (const_int 0)) (const_string "clobber")
-                    (const_string "none_0hit"))
-        ] (const_string "none_0hit")))])
+)
 
+(define_insn "*mn10300_movdf"
+  [(set (match_operand:DF 0 "nonimmediate_operand"
+                         ;;     0    1  2 3   4   5   6   7  8  9  10
+                               "=dxa,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
+       (match_operand:DF 1 "general_operand"
+                         ;;        0 1 2 3  4  5  6  7    8    9    10
+                                  "0,G,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
+  "register_operand (operands[0], DFmode)
+   || register_operand (operands[1], DFmode)"
+  "*
+{
+  long val[2];
+  REAL_VALUE_TYPE rv;
 
-\f
-;; ----------------------------------------------------------------------
-;; TEST INSTRUCTIONS
-;; ----------------------------------------------------------------------
+  switch (which_alternative)
+    {
+      case 0:
+       return \"nop\";
 
-(define_insn "*tst_extqisi_am33"
-  [(set (cc0) (compare
-              (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a"))
-              (const_int 0)))]
-  "TARGET_AM33"
-  "* return output_tst (operands[0], insn);"
-  [(set_attr "cc" "set_znv")])
+      case 1:
+       return \"mov 0, %L0\;mov 0, %H0\";
 
-(define_insn "*tst_extqisi"
-  [(set (cc0) (compare
-              (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx"))
-              (const_int 0)))]
-  ""
-  "* return output_tst (operands[0], insn);"
-  [(set_attr "cc" "set_znv")])
+      case 2:
+        if (rtx_equal_p (operands[0], operands[1]))
+          return \"sub %L1,%L0\;mov %L0,%H0\";
+        else
+          return \"mov %1,%L0\;mov %L0,%H0\";
+      case 3:
+      case 4:
+      case 5:
+      case 6:
+      case 7:
+      case 8:
+      case 9:
+      case 10:
+       if (GET_CODE (operands[1]) == CONST_INT)
+         {
+           rtx low, high;
+           split_double (operands[1], &low, &high);
+           val[0] = INTVAL (low);
+           val[1] = INTVAL (high);
+         }
+       if (GET_CODE (operands[1]) == CONST_DOUBLE)
+         {
+           if (GET_MODE (operands[1]) == DFmode)
+             {
+               REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+               REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
+             }
+           else if (GET_MODE (operands[1]) == VOIDmode
+                    || GET_MODE (operands[1]) == DImode)
+             {
+               val[0] = CONST_DOUBLE_LOW (operands[1]);
+               val[1] = CONST_DOUBLE_HIGH (operands[1]);
+             }
+         }
 
-(define_insn "*tst_exthisi_am33"
-  [(set (cc0) (compare
-              (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a"))
-              (const_int 0)))]
-  "TARGET_AM33"
-  "* return output_tst (operands[0], insn);"
-  [(set_attr "cc" "set_znv")])
+       if (GET_CODE (operands[1]) == MEM
+           && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
+         {
+           rtx temp = operands[0];
 
-(define_insn "*tst_exthisi"
-  [(set (cc0) (compare
-              (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx"))
-              (const_int 0)))]
-  ""
-  "* return output_tst (operands[0], insn);"
-  [(set_attr "cc" "set_znv")])
+           while (GET_CODE (temp) == SUBREG)
+             temp = SUBREG_REG (temp);
 
-;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
-;; its operands hold equal values, but the operands of a cmp
-;; instruction must be distinct registers.  In the case where we'd
-;; like to compare a register to itself, we can achieve this effect
-;; with a btst 0,d0 instead.  (This will not alter the contents of d0
-;; but will have the proper effect on cc0.  Using d0 is arbitrary; any
-;; data register would work.)
+           gcc_assert (GET_CODE (temp) == REG);
 
-;; Even though the first alternative would be preferable if it can
-;; possibly match, reload must not be given the opportunity to attempt
-;; to use it.  It assumes that such matches can only occur when one of
-;; the operands is used for input and the other for output.  Since
-;; this is not the case, it abort()s.  Indeed, such a reload cannot be
-;; possibly satisfied, so just mark the alternative with a `!', so
-;; that it is not considered by reload.
+           if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
+                                        XEXP (operands[1], 0)))
+             return \"mov %H1,%H0\;mov %L1,%L0\";
+           else
+             return \"mov %L1,%L0\;mov %H1,%H0\";
 
-(define_insn "*cmpsi"
-  [(set (cc0)
-       (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax,dax")
-                (match_operand:SI 1 "nonmemory_operand" "*0,I,daxi")))]
-  ""
-  "*
-{
-  if (which_alternative == 0)
-    return \"btst 0,d0\";
-  if (which_alternative == 1)
-    return output_tst (operands[0], insn);
-  return \"cmp %1,%0\";
-}"
-  [(set_attr "cc" "compare,set_znv,compare")])
+         }
+       else if (GET_CODE (operands[1]) == MEM
+                && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
+                && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
+         {
+           rtx xoperands[2];
 
-(define_insn "*cmpsf"
-  [(set (cc0)
-       (compare (match_operand:SF 0 "register_operand" "f,f")
-                (match_operand:SF 1 "nonmemory_operand" "f,F")))]
-  "TARGET_AM33_2"
-  "fcmp %1,%0"
-  [(set_attr "cc" "compare,compare")])
+           xoperands[0] = operands[0];
+           xoperands[1] = XEXP (operands[1], 0);
+
+           output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
+                            xoperands);
+           return \"\";
+         }
+       else
+         {
+           if ((GET_CODE (operands[1]) == CONST_INT
+                || GET_CODE (operands[1]) == CONST_DOUBLE)
+               && val[0] == 0)
+             {
+               if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
+                 output_asm_insn (\"mov 0, %L0\", operands);
+               else
+                 output_asm_insn (\"mov %L1,%L0\", operands);
+             }
+           else if ((GET_CODE (operands[1]) == CONST_INT
+                     || GET_CODE (operands[1]) == CONST_DOUBLE)
+                    && (REGNO_REG_CLASS (true_regnum (operands[0]))
+                        == EXTENDED_REGS)
+                    && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
+                        || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
+             output_asm_insn (\"movu %L1,%L0\", operands);
+           else
+             output_asm_insn (\"mov %L1,%L0\", operands);
+
+           if ((GET_CODE (operands[1]) == CONST_INT
+                || GET_CODE (operands[1]) == CONST_DOUBLE)
+               && val[1] == 0)
+             {
+               if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
+                 output_asm_insn (\"mov 0, %H0\", operands);
+               else
+                 output_asm_insn (\"mov %H1,%H0\", operands);
+             }
+           else if ((GET_CODE (operands[1]) == CONST_INT
+                     || GET_CODE (operands[1]) == CONST_DOUBLE)
+                    && val[0] == val[1])
+             output_asm_insn (\"mov %L0,%H0\", operands);
+           else if ((GET_CODE (operands[1]) == CONST_INT
+                     || GET_CODE (operands[1]) == CONST_DOUBLE)
+                    && (REGNO_REG_CLASS (true_regnum (operands[0]))
+                        == EXTENDED_REGS)
+                    && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
+                        || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
+             output_asm_insn (\"movu %H1,%H0\", operands);
+           else
+             output_asm_insn (\"mov %H1,%H0\", operands);
+           return \"\";
+         }
+    default:
+      gcc_unreachable ();
+    }
+}"
+)
+       
 \f
 ;; ----------------------------------------------------------------------
 ;; ADD INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
 (define_expand "addsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (plus:SI (match_operand:SI 1 "register_operand" "")
-                (match_operand:SI 2 "nonmemory_operand" "")))]
+  [(parallel [(set (match_operand:SI          0 "register_operand")
+                  (plus:SI (match_operand:SI 1 "register_operand")
+                           (match_operand:SI 2 "nonmemory_operand")))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
   ""
   "")
 
-(define_insn ""
-  [(set (match_operand:SI 0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
+(define_insn "*am33_addsi3"
+  [(set (match_operand:SI          0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
        (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,dax")
-                (match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))]
+                (match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))
+   (clobber (reg:CC CC_REG))
+  ]
   "TARGET_AM33"
   "*
 {
       gcc_unreachable ();
     }
 }"
-  [(set_attr "cc" "set_zn,none_0hit,set_zn,none_0hit,set_zn,none_0hit,set_zn")])
+)
 
-(define_insn ""
-  [(set (match_operand:SI 0 "register_operand" "=dx,a,a,dax,!*y,!dax")
+(define_insn "*mn10300_addsi3"
+  [(set (match_operand:SI          0 "register_operand" "=dx,a,a,dax,!*y,!dax")
        (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
-                (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
+                (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "*
 {
       gcc_unreachable ();
     }
 }"
-  [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
+)
 
 ;; ----------------------------------------------------------------------
 ;; SUBTRACT INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
 (define_expand "subsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (minus:SI (match_operand:SI 1 "register_operand" "")
-                 (match_operand:SI 2 "nonmemory_operand" "")))]
+  [(parallel [(set (match_operand:SI           0 "register_operand")
+                  (minus:SI (match_operand:SI 1 "register_operand")
+                            (match_operand:SI 2 "nonmemory_operand")))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
   ""
   "")
 
-(define_insn ""
+(define_insn "*am33_subsi3"
   [(set (match_operand:SI 0 "register_operand" "=dax,!dax")
        (minus:SI (match_operand:SI 1 "register_operand" "0,dax")
                  (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
       return \"sub %2,%1,%0\";
     }
 }"
-  [(set_attr "cc" "set_zn")])
+)
 
-(define_insn ""
-  [(set (match_operand:SI 0 "register_operand" "=dax")
+(define_insn "*mn10300_subsi3"
+  [(set (match_operand:SI           0 "register_operand" "=dax")
        (minus:SI (match_operand:SI 1 "register_operand" "0")
-                 (match_operand:SI 2 "nonmemory_operand" "daxi")))]
+                 (match_operand:SI 2 "nonmemory_operand" "daxi")))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "sub %2,%0"
-  [(set_attr "cc" "set_zn")])
+)
 
 (define_expand "negsi2"
-  [(set (match_operand:SI 0 "register_operand" "")
-        (neg:SI (match_operand:SI 1 "register_operand" "")))]
+  [(set (match_operand:SI         0 "register_operand")
+        (neg:SI (match_operand:SI 1 "register_operand")))]
   ""
   "
 {
 (define_insn "mulsidi3"
   [(set (match_operand:DI 0 "register_operand" "=dax")
         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
-                 (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
+                 (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))
+   (clobber (reg:CC CC_REG))
+  ]
   "TARGET_AM33"
   "mul %1,%2,%H0,%L0"
-  [(set_attr "cc" "set_zn")])
+)
 
 (define_insn "umulsidi3"
   [(set (match_operand:DI 0 "register_operand" "=dax")
         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
-                 (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
+                 (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))
+   (clobber (reg:CC CC_REG))
+  ]
   "TARGET_AM33"
   "mulu %1,%2,%H0,%L0"
-  [(set_attr "cc" "set_zn")])
+)
 
 (define_expand "mulsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (mult:SI (match_operand:SI 1 "register_operand" "")
-                (match_operand:SI 2 "register_operand" "")))]
+  [(parallel [(set (match_operand:SI          0 "register_operand")
+                  (mult:SI (match_operand:SI 1 "register_operand")
+                           (match_operand:SI 2 "register_operand")))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
   ""
   "")
 
-(define_insn ""
-  [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
+(define_insn "*am33_mulsi3"
+  [(set (match_operand:SI          0 "register_operand" "=dx,!dax")
        (mult:SI (match_operand:SI 1 "register_operand" "%0,0")
-                (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
+                (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))
+   (clobber (reg:CC CC_REG))
+  ]
   "TARGET_AM33"
   "*
 {
   else
     return \"mul %2,%0\";
 }"
-  [(set_attr "cc" "set_zn")])
+)
 
-(define_insn ""
-  [(set (match_operand:SI 0 "register_operand" "=dx")
+(define_insn "*mn10300_mulsi3"
+  [(set (match_operand:SI          0 "register_operand" "=dx")
        (mult:SI (match_operand:SI 1 "register_operand" "%0")
-                (match_operand:SI 2 "register_operand" "dx")))]
+                (match_operand:SI 2 "register_operand" "dx")))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "*
 {
   else
     return \"mul %2,%0\";
 }"
-  [(set_attr "cc" "set_zn")])
-
-(define_insn "udivmodsi4"
+)
+
+(define_expand "udivmodsi4"
+  [(parallel [(set (match_operand:SI          0 "nonimmediate_operand")
+                  (udiv:SI (match_operand:SI 1 "general_operand")
+                           (match_operand:SI 2 "general_operand")))
+             (set (match_operand:SI          3 "nonimmediate_operand")
+                  (umod:SI (match_dup 1) (match_dup 2)))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
+  ""
+  "{
+    if (!register_operand (operands[1], SImode))
+      operands[1] = copy_to_mode_reg (SImode, operands[1]);
+    if (!register_operand (operands[2], SImode))
+      operands[2] = copy_to_mode_reg (SImode, operands[2]);
+   }"
+)
+
+(define_insn "*udivmodsi4_insn"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
-       (udiv:SI (match_operand:SI 1 "general_operand" "0")
-                (match_operand:SI 2 "general_operand" "dx")))
+       (udiv:SI (match_operand:SI 1 "register_operand" "0")
+                (match_operand:SI 2 "register_operand" "dx")))
    (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
-       (umod:SI (match_dup 1) (match_dup 2)))]
+       (umod:SI (match_dup 1) (match_dup 2)))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "*
 {
   else
     return \"divu %2,%0\;mov mdr,%3\";
 }"
-  [(set_attr "cc" "set_zn")])
+)
 
 (define_insn "divmodsi4"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
-       (div:SI (match_operand:SI 1 "general_operand" "0")
-                (match_operand:SI 2 "general_operand" "dx")))
-   (set (match_operand:SI 3 "nonimmediate_operand" "=d")
-       (mod:SI (match_dup 1) (match_dup 2)))]
+  [(set (match_operand:SI          0 "nonimmediate_operand" "=dx")
+       (div:SI (match_operand:SI  1 "general_operand"       "0")
+                (match_operand:SI 2 "general_operand"       "dx")))
+   (set (match_operand:SI          3 "nonimmediate_operand" "=d")
+       (mod:SI (match_dup 1) (match_dup 2)))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "*
 {
   else
     return \"ext %0\;div %2,%0\;mov mdr,%3\";
 }"
-  [(set_attr "cc" "set_zn")])
+)
 
 \f
 ;; ----------------------------------------------------------------------
 ;; ----------------------------------------------------------------------
 
 (define_expand "andsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (and:SI (match_operand:SI 1 "register_operand" "")
-               (match_operand:SI 2 "nonmemory_operand" "")))]
+  [(parallel [(set (match_operand:SI         0 "register_operand")
+                  (and:SI (match_operand:SI 1 "register_operand")
+                          (match_operand:SI 2 "nonmemory_operand")))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
   ""
   "")
 
-(define_insn ""
-  [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
+(define_insn "*am33_andsi3"
+  [(set (match_operand:SI         0 "register_operand" "=dx,dx,!dax")
        (and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
-               (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
+               (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))
+   (clobber (reg:CC CC_REG))
+  ]
   "TARGET_AM33"
   "*
 {
     return \"and %1,%0\";
   return \"and %2,%0\";
 }"
-  [(set (attr "cc")
-       (cond
-        [
-        (eq (symbol_ref "which_alternative") (const_int 0)
-            ) (const_string "none_0hit")
-        (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
-                         && (INTVAL (operands[2]) == 0x7fffffff
-                             || INTVAL (operands[2]) == 0x3fffffff
-                             || INTVAL (operands[2]) == 0x1fffffff
-                             || INTVAL (operands[2]) == 0x0fffffff
-                             || INTVAL (operands[2]) == 0xfffffffe
-                             || INTVAL (operands[2]) == 0xfffffffc
-                             || INTVAL (operands[2]) == 0xfffffff8
-                             || INTVAL (operands[2]) == 0xfffffff0)")
-            (const_int 0)) (const_string "set_zn")
-         ] (const_string "set_znv")))])
+)
 
-(define_insn ""
+(define_insn "*mn10300_andsi3"
   [(set (match_operand:SI 0 "register_operand" "=dx,dx")
        (and:SI (match_operand:SI 1 "register_operand" "%0,0")
-               (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
+               (match_operand:SI 2 "nonmemory_operand" "N,dxi")))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "*
 {
     return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
   return \"and %2,%0\";
 }"
-  [(set (attr "cc")
-       (cond
-        [
-        (eq (symbol_ref "which_alternative") (const_int 0)
-            ) (const_string "none_0hit")
-        ;; Shifts don't set the V flag, but bitwise operations clear
-        ;; it (which correctly reflects the absence of overflow in a
-        ;; compare-with-zero that might follow).  As for the
-        ;; 0xfffffffe case, the add may overflow, so we can't use the
-        ;; V flag.
-        (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
-                         && (INTVAL (operands[2]) == 0x7fffffff
-                             || INTVAL (operands[2]) == 0x3fffffff
-                             || INTVAL (operands[2]) == 0x1fffffff
-                             || INTVAL (operands[2]) == 0x0fffffff
-                             || INTVAL (operands[2]) == 0xfffffffe
-                             || INTVAL (operands[2]) == 0xfffffffc
-                             || INTVAL (operands[2]) == 0xfffffff8
-                             || INTVAL (operands[2]) == 0xfffffff0)")
-            (const_int 0)) (const_string "set_zn")
-         ] (const_string "set_znv")))])
+)
 
 ;; ----------------------------------------------------------------------
 ;; OR INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
 (define_expand "iorsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (ior:SI (match_operand:SI 1 "register_operand" "")
-               (match_operand:SI 2 "nonmemory_operand" "")))]
+  [(parallel [(set (match_operand:SI         0 "register_operand")
+                  (ior:SI (match_operand:SI 1 "register_operand")
+                          (match_operand:SI 2 "nonmemory_operand")))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
   ""
   "")
 
-(define_insn ""
+(define_insn "*am33_iorsi3"
   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
        (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
-               (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
+               (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))
+   (clobber (reg:CC CC_REG))
+  ]
   "TARGET_AM33"
   "*
 {
     return \"or %1,%0\";
   return \"or %2,%0\";
 }"
-  [(set_attr "cc" "set_znv")])
+)
 
-(define_insn ""
+(define_insn "*mn10300_iorsi3"
   [(set (match_operand:SI 0 "register_operand" "=dx")
        (ior:SI (match_operand:SI 1 "register_operand" "%0")
-               (match_operand:SI 2 "nonmemory_operand" "dxi")))]
+               (match_operand:SI 2 "nonmemory_operand" "dxi")))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "or %2,%0"
-  [(set_attr "cc" "set_znv")])
+)
 
 ;; ----------------------------------------------------------------------
 ;; XOR INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
 (define_expand "xorsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (xor:SI (match_operand:SI 1 "register_operand" "")
-               (match_operand:SI 2 "nonmemory_operand" "")))]
+  [(parallel [(set (match_operand:SI         0 "register_operand")
+                  (xor:SI (match_operand:SI 1 "register_operand")
+                          (match_operand:SI 2 "nonmemory_operand")))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
   ""
   "")
 
-(define_insn ""
+(define_insn "*am33_xorsi3"
   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
        (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
-               (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
+               (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))
+   (clobber (reg:CC CC_REG))
+  ]
   "TARGET_AM33"
   "*
 {
     return \"xor %1,%0\";
   return \"xor %2,%0\";
 }"
-  [(set_attr "cc" "set_znv")])
+)
 
-(define_insn ""
+(define_insn "*mn10300_xorsi3"
   [(set (match_operand:SI 0 "register_operand" "=dx")
        (xor:SI (match_operand:SI 1 "register_operand" "%0")
-               (match_operand:SI 2 "nonmemory_operand" "dxi")))]
+               (match_operand:SI 2 "nonmemory_operand" "dxi")))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "xor %2,%0"
-  [(set_attr "cc" "set_znv")])
+)
 
 ;; ----------------------------------------------------------------------
 ;; NOT INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
 (define_expand "one_cmplsi2"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (not:SI (match_operand:SI 1 "register_operand" "")))]
+  [(parallel [(set (match_operand:SI         0 "register_operand")
+                  (not:SI (match_operand:SI 1 "register_operand")))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
   ""
   "")
 
-(define_insn ""
-  [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
-       (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
+(define_insn "*am33_cmplsi2"
+  [(set (match_operand:SI         0 "register_operand" "=dx,!dax")
+       (not:SI (match_operand:SI 1 "register_operand" "0,0")))
+   (clobber (reg:CC CC_REG))
+  ]
   "TARGET_AM33"
   "not %0"
-  [(set_attr "cc" "set_znv")])
+)
 
-(define_insn ""
-  [(set (match_operand:SI 0 "register_operand" "=dx")
-       (not:SI (match_operand:SI 1 "register_operand" "0")))]
+(define_insn "*mn10300_cmplsi2"
+  [(set (match_operand:SI         0 "register_operand" "=dx")
+       (not:SI (match_operand:SI 1 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "not %0"
-  [(set_attr "cc" "set_znv")])
+)
 \f
 ;; -----------------------------------------------------------------
 ;; BIT FIELDS
 ;; They are no smaller/faster than loading the value into a register
 ;; and storing the register, but they don't need a scratch register
 ;; which may allow for better code generation.
-(define_insn ""
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))]
-  ""
+(define_insn "*byte_clear"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))
+   (clobber (reg:CC CC_REG))
+   ]
+  "GET_CODE (operands[0]) != MEM || (! MEM_VOLATILE_P (operands[0]) && GET_CODE (XEXP (operands[0], 0)) != PLUS)"
   "@
   bclr 255,%A0
   clr %0"
-  [(set_attr "cc" "clobber")])
+)
 
-(define_insn ""
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))]
-  ""
+(define_insn "*byte_set"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))
+   (clobber (reg:CC CC_REG))
+  ]
+  "GET_CODE (operands[0]) != MEM || (! MEM_VOLATILE_P (operands[0]) && GET_CODE (XEXP (operands[0], 0)) != PLUS)"
   "@
   bset 255,%A0
   mov -1,%0"
-  [(set_attr "cc" "clobber,none_0hit")])
+)
 
-(define_insn ""
+(define_insn "*bit_clear1"
   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
        (subreg:QI
          (and:SI (subreg:SI (match_dup 0) 0)
-                 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
+                 (match_operand:SI 1 "const_int_operand" "i,i")) 0))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "@
   bclr %N1,%A0
   and %1,%0"
-  [(set_attr "cc" "clobber,set_znv")])
+)
 
-(define_insn ""
+(define_insn "*bit_clear2"
   [(set (match_operand:QI 0 "memory_operand" "=R,T")
        (and:QI
         (match_dup 0)
-        (not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))]
+        (not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "@
   bclr %U1,%A0
   bclr %1,%0"
-  [(set_attr "cc" "clobber,clobber")])
+)
 
-(define_insn ""
+(define_insn "*bit_set"
   [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
        (subreg:QI
          (ior:SI (subreg:SI (match_dup 0) 0)
-                 (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
+                 (match_operand:SI 1 "const_int_operand" "i,i")) 0))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "@
   bset %U1,%A0
   or %1,%0"
-  [(set_attr "cc" "clobber,set_znv")])
+)
 
 (define_expand "iorqi3"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "")
-       (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
-               (match_operand:QI 2 "nonmemory_operand" "")))]
+  [(parallel [(set (match_operand:QI         0 "nonimmediate_operand")
+                  (ior:QI (match_operand:QI 1 "nonimmediate_operand")
+                          (match_operand:QI 2 "nonmemory_operand")))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
   ""
   "")
 
-(define_insn ""
+(define_insn "*am33_iorqi3"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,r")
        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
                ;; This constraint should really be nonmemory_operand,
                ;; but making it general_operand, along with the
                ;; condition that not both input operands are MEMs, it
                ;; here helps combine do a better job.
-               (match_operand:QI 2 "general_operand" "i,d,ir")))]
+               (match_operand:QI 2 "general_operand" "i,d,ir")))
+   (clobber (reg:CC CC_REG))
+  ]
   "TARGET_AM33 &&
    (GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM)"
   "@
   bset %U2,%A0
   bset %2,%0
   or %2,%0"
-  [(set_attr "cc" "clobber,clobber,set_znv")])
+)
 
-(define_insn ""
+(define_insn "*mn10300_iorqi3"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,d")
        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
                ;; This constraint should really be nonmemory_operand,
                ;; but making it general_operand, along with the
                ;; condition that not both input operands are MEMs, it
                ;; here helps combine do a better job.
-               (match_operand:QI 2 "general_operand" "i,d,id")))]
+               (match_operand:QI 2 "general_operand" "i,d,id")))
+   (clobber (reg:CC CC_REG))
+  ]
   "GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM"
   "@
   bset %U2,%A0
   bset %2,%0
   or %2,%0"
-  [(set_attr "cc" "clobber,clobber,set_znv")])
+)
 
-(define_insn ""
-  [(set (cc0)
+(define_insn "*test_int_bitfield"
+  [(set (reg:CC CC_REG)
      (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
                               (match_operand 1 "const_int_operand" "")
                               (match_operand 2 "const_int_operand" ""))
   output_asm_insn (\"btst %1,%0\", xoperands);
   return \"\";
 }"
-  [(set_attr "cc" "clobber")])
+)
 
-(define_insn ""
-  [(set (cc0)
+(define_insn "*test_byte_bitfield"
+  [(set (reg:CC CC_REG)
      (compare (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
                               (match_operand 1 "const_int_operand" "")
                               (match_operand 2 "const_int_operand" ""))
     output_asm_insn (\"btst %U1,%A0\", xoperands);
   return \"\";
 }"
-  [(set_attr "cc" "clobber")])
+)
 
-(define_insn ""
-  [(set (cc0) (compare (and:SI (match_operand:SI 0 "register_operand" "dx")
-                              (match_operand:SI 1 "const_int_operand" ""))
-                      (const_int 0)))]
+(define_insn "*bit_test"
+  [(set (reg:CC CC_REG)
+       (compare (and:SI (match_operand:SI 0 "register_operand" "dx")
+                        (match_operand:SI 1 "const_int_operand" ""))
+                (const_int 0)))
+  ]
   ""
   "btst %1,%0"
-  [(set_attr "cc" "clobber")])
+)
 
-(define_insn ""
-  [(set (cc0)
+(define_insn "*subreg_bit_test"
+  [(set (reg:CC CC_REG)
      (compare (and:SI
               (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
               (match_operand:SI 1 "const_8bit_operand" ""))
   "@
   btst %U1,%A0
   btst %1,%0"
-  [(set_attr "cc" "clobber")])
+)
 
 \f
 ;; ----------------------------------------------------------------------
-;; JUMP INSTRUCTIONS
+;; COMPARE AND BRANCH INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
+;; We expand the comparison into a single insn so that it will not be split
+;; up by reload.
 (define_expand "cbranchsi4"
-  [(set (cc0)
-       (compare (match_operand:SI 1 "register_operand" "")
-                (match_operand:SI 2 "nonmemory_operand" "")))
-   (set (pc)
-      (if_then_else
-            (match_operator 0 "ordered_comparison_operator" [(cc0)
-                                                            (const_int 0)])
-              (label_ref (match_operand 3 "" ""))
+  [(set (pc)
+       (if_then_else
+             (match_operator                    0 "ordered_comparison_operator"
+                             [(match_operand:SI 1 "register_operand")
+                              (match_operand:SI 2 "nonmemory_operand")])
+              (label_ref (match_operand          3 ""))
               (pc)))]
   ""
-  "")
+  ""
+)
 
-(define_expand "cbranchsf4"
-  [(set (cc0)
-       (compare (match_operand:SF 1 "register_operand" "")
-                (match_operand:SF 2 "nonmemory_operand" "")))
-   (set (pc)
-      (if_then_else
-            (match_operator 0 "ordered_comparison_operator" [(cc0)
-                                                            (const_int 0)])
-              (label_ref (match_operand 3 "" ""))
-              (pc)))]
-  "TARGET_AM33_2"
-  "")
+(define_insn_and_split "*cbranchsi4_post_reload"
+  [(set (pc)
+       (if_then_else (match_operator           3 "ordered_comparison_operator"
+                       [(match_operand:SI       0 "register_operand"  "dax")
+                       (match_operand:SI       1 "nonmemory_operand" "daxi")])
+                     (label_ref (match_operand 2 "" ""))
+                     (pc)))
+   ]
+  ""
+  "#"
+  "reload_completed"
+  [(const_int 0)]
+  "
+  /* We construct the split by hand as otherwise the JUMP_LABEL
+     attribute is not set correctly on the jump insn.  */
+  emit_insn (gen_cmpsi (operands[0], operands[1]));
+  
+  emit_jump_insn (gen_integer_conditional_branch (gen_rtx_fmt_ee (GET_CODE (operands[3]),
+                                                                CCmode,
+                                                                gen_rtx_REG (CCmode, CC_REG),
+                                                                const0_rtx),
+                                                 operands[2]));
+  "
+)
+
+;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
+;; its operands hold equal values, but the operands of a cmp
+;; instruction must be distinct registers.  In the case where we'd
+;; like to compare a register to itself, we can achieve this effect
+;; with a btst 0,d0 instead.  (This will not alter the contents of d0
+;; but will have the proper effect on cc0.  Using d0 is arbitrary; any
+;; data register would work.)
 
+;; Even though the first alternative would be preferable if it can
+;; possibly match, reload must not be given the opportunity to attempt
+;; to use it.  It assumes that such matches can only occur when one of
+;; the operands is used for input and the other for output.  Since
+;; this is not the case, it abort()s.  Indeed, such a reload cannot be
+;; possibly satisfied, so just mark the alternative with a `!', so
+;; that it is not considered by reload.
 
-;; Conditional jump instructions
+(define_insn "cmpsi"
+  [(set (reg:CC CC_REG)
+       (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax,dax")
+                (match_operand:SI 1 "nonmemory_operand" "*0,I,daxi")))]
+  ""
+  {
+    if (which_alternative == 0)
+      return \"btst 0,d0\";
+    if (which_alternative == 1)
+      return mn10300_output_cmp (operands[0], insn);
+    return \"cmp %1,%0\";
+  }
+)
 
-(define_insn ""
+(define_insn "integer_conditional_branch"
   [(set (pc)
-       (if_then_else (match_operator 1 "comparison_operator"
-                                     [(cc0) (const_int 0)])
-                     (label_ref (match_operand 0 "" ""))
+       (if_then_else (match_operator 0 "comparison_operator" [(reg:CC CC_REG) (const_int 0)])
+                     (label_ref (match_operand 1 "" ""))
                      (pc)))]
   ""
-  "*
-{
-  if (cc_status.mdep.fpCC)
-    return \"fb%b1 %0\";
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
-      && (GET_CODE (operands[1]) == GT
-         || GET_CODE (operands[1]) == GE
-         || GET_CODE (operands[1]) == LE
-         || GET_CODE (operands[1]) == LT))
-    return 0;
-  return \"b%b1 %0\";
-}"
- [(set_attr "cc" "none")])
+  "b%b0 %1"
+)
 
-(define_insn ""
+(define_expand "cbranchsf4"
   [(set (pc)
-       (if_then_else (match_operator 1 "comparison_operator"
-                                     [(cc0) (const_int 0)])
-                     (pc)
-                     (label_ref (match_operand 0 "" ""))))]
+      (if_then_else
+            (match_operator                    0 "ordered_comparison_operator"
+                           [(match_operand:SF 1 "register_operand")
+                            (match_operand:SF 2 "nonmemory_operand")])
+           (label_ref (match_operand          3 ""))
+           (pc)))]
+  "TARGET_AM33_2"
   ""
-  "*
-{
-  if (cc_status.mdep.fpCC)
-    return \"fb%B1 %0\";
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
-      && (GET_CODE (operands[1]) == GT
-         || GET_CODE (operands[1]) == GE
-         || GET_CODE (operands[1]) == LE
-         || GET_CODE (operands[1]) == LT))
-    return 0;
-  return \"b%B1 %0\";
-}"
- [(set_attr "cc" "none")])
+)
+
+(define_insn_and_split "*cbranchsf4_post_reload"
+  [(set (pc)
+       (if_then_else (match_operator            3 "ordered_comparison_operator"
+                       [(match_operand:SF       0 "register_operand"  "f")
+                        (match_operand:SF       1 "nonmemory_operand" "fF")])
+                     (label_ref (match_operand  2 "" ""))
+                     (pc)))
+   ]
+  "TARGET_AM33_2"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+  "
+  /* We construct the split by hand as otherwise the JUMP_LABEL
+     attribute is not set correctly on the jump insn.  */
+  emit_insn (gen_am33_cmpsf (operands[0], operands[1]));
+  
+  emit_jump_insn (gen_float_conditional_branch (gen_rtx_fmt_ee (GET_CODE (operands[3]),
+                                                              CC_FLOATmode,
+                                                              gen_rtx_REG (CC_FLOATmode, CC_REG),
+                                                              const0_rtx),
+                                               operands[2]));
+  "
+)
+
+(define_insn "am33_cmpsf"
+  [(set (reg:CC_FLOAT CC_REG)
+       (compare:CC_FLOAT (match_operand:SF 0 "register_operand"  "f")
+                         (match_operand:SF 1 "nonmemory_operand" "fF")))]
+  "TARGET_AM33_2"
+  "fcmp %1, %0"
+)
+
+(define_insn "float_conditional_branch"
+  [(set (pc)
+       (if_then_else (match_operator 0 "comparison_operator" [(reg:CC_FLOAT CC_REG) (const_int 0)])
+                     (label_ref (match_operand 1 "" ""))
+                     (pc)))]
+  "TARGET_AM33_2"
+  "fb%b0 %1"
+)
 
 ;; Unconditional and other jump instructions.
 
        (label_ref (match_operand 0 "" "")))]
   ""
   "jmp %l0"
- [(set_attr "cc" "none")])
+)
 
 (define_insn "indirect_jump"
   [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
   ""
   "jmp (%0)"
-  [(set_attr "cc" "none")])
+)
 
 (define_expand "builtin_setjmp_receiver"
   [(match_operand 0 "" "")]
 }")
 
 (define_expand "casesi"
-  [(match_operand:SI 0 "register_operand" "")
-   (match_operand:SI 1 "immediate_operand" "")
-   (match_operand:SI 2 "immediate_operand" "")
-   (match_operand 3 "" "") (match_operand 4 "" "")]
+  [(match_operand:SI 0 "register_operand")
+   (match_operand:SI 1 "immediate_operand")
+   (match_operand:SI 2 "immediate_operand")
+   (match_operand 3 "" "") (match_operand 4 "")]
   ""
   "
 {
   rtx test;
 
   emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
-  emit_move_insn (index, plus_constant (operands[0], - INTVAL (operands[1])));
+  emit_insn (gen_addsi3 (index, operands[0], GEN_INT (- INTVAL (operands[1]))));
   test = gen_rtx_fmt_ee (GTU, VOIDmode, index, operands[2]);
   emit_jump_insn (gen_cbranchsi4 (test, index, operands[2], operands[4]));
  
-  emit_move_insn (index, gen_rtx_ASHIFT (SImode, index, const2_rtx));
+  emit_insn (gen_ashlsi3 (index, index, const2_rtx));
   emit_move_insn (addr, gen_rtx_MEM (SImode,
                                     gen_rtx_PLUS (SImode, table, index)));
   if (flag_pic)
-    emit_move_insn (addr, gen_rtx_PLUS (SImode, addr, table));
+    emit_insn (gen_addsi3 (addr, addr, table));
 
   emit_jump_insn (gen_tablejump (addr, operands[3]));
   DONE;
    (use (label_ref (match_operand 1 "" "")))]
   ""
   "jmp (%0)"
-  [(set_attr "cc" "none")])
+)
 
 ;; Call subroutine with no return value.
 
 (define_expand "call"
-  [(call (match_operand:QI 0 "general_operand" "")
-        (match_operand:SI 1 "general_operand" ""))]
+  [(call (match_operand:QI 0 "general_operand")
+        (match_operand:SI 1 "general_operand"))]
   ""
   "
 {
   else
     return \"call %C0,[],0\";
 }"
-  [(set_attr "cc" "clobber")])
+)
 
 ;; Call subroutine, returning value in operand 0
 ;; (which must be a hard register).
 
 (define_expand "call_value"
-  [(set (match_operand 0 "" "")
-       (call (match_operand:QI 1 "general_operand" "")
-             (match_operand:SI 2 "general_operand" "")))]
+  [(set (match_operand 0 "")
+       (call (match_operand:QI 1 "general_operand")
+             (match_operand:SI 2 "general_operand")))]
   ""
   "
 {
   else
     return \"call %C1,[],0\";
 }"
-  [(set_attr "cc" "clobber")])
+)
 
 (define_expand "untyped_call"
-  [(parallel [(call (match_operand 0 "" "")
+  [(parallel [(call (match_operand 0 "")
                     (const_int 0))
-              (match_operand 1 "" "")
-              (match_operand 2 "" "")])]
+              (match_operand 1 "")
+              (match_operand 2 "")])]
   ""
   "
 {
   [(const_int 0)]
   ""
   "nop"
-  [(set_attr "cc" "none")])
+)
 \f
 ;; ----------------------------------------------------------------------
 ;; EXTEND INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
 (define_expand "zero_extendqisi2"
-  [(set (match_operand:SI 0 "general_operand" "")
+  [(set (match_operand:SI 0 "general_operand")
        (zero_extend:SI
-        (match_operand:QI 1 "general_operand" "")))]
+        (match_operand:QI 1 "general_operand")))]
   ""
   "")
 
   extbu %0
   mov %1,%0\;extbu %0
   movbu %1,%0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 (define_insn ""
   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
   extbu %0
   mov %1,%0\;extbu %0
   movbu %1,%0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 (define_expand "zero_extendhisi2"
-  [(set (match_operand:SI 0 "general_operand" "")
+  [(set (match_operand:SI 0 "general_operand")
        (zero_extend:SI
-        (match_operand:HI 1 "general_operand" "")))]
+        (match_operand:HI 1 "general_operand")))]
   ""
   "")
 
   exthu %0
   mov %1,%0\;exthu %0
   movhu %1,%0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 (define_insn ""
   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
   exthu %0
   mov %1,%0\;exthu %0
   movhu %1,%0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 ;;- sign extension instructions
 
 (define_expand "extendqisi2"
-  [(set (match_operand:SI 0 "general_operand" "")
+  [(set (match_operand:SI 0 "general_operand")
        (sign_extend:SI
-        (match_operand:QI 1 "general_operand" "")))]
+        (match_operand:QI 1 "general_operand")))]
   ""
   "")
 
   mov %1,%0\;extb %0
   extb %0
   mov %1,%0\;extb %0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 (define_insn ""
   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
   "@
   extb %0
   mov %1,%0\;extb %0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 (define_expand "extendhisi2"
-  [(set (match_operand:SI 0 "general_operand" "")
+  [(set (match_operand:SI 0 "general_operand")
        (sign_extend:SI
-        (match_operand:HI 1 "general_operand" "")))]
+        (match_operand:HI 1 "general_operand")))]
   ""
   "")
 
   mov %1,%0\;exth %0
   exth %0
   mov %1,%0\;exth %0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 (define_insn ""
   [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
   "@
   exth %0
   mov %1,%0\;exth %0"
-  [(set_attr "cc" "none_0hit")])
+)
 \f
 ;; ----------------------------------------------------------------------
 ;; SHIFTS
 ;; ----------------------------------------------------------------------
 
 (define_expand "ashlsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (ashift:SI
-        (match_operand:SI 1 "register_operand" "")
-        (match_operand:QI 2 "nonmemory_operand" "")))]
+  [(parallel [(set (match_operand:SI 0 "register_operand")
+                  (ashift:SI
+                   (match_operand:SI 1 "register_operand")
+                   (match_operand:QI 2 "nonmemory_operand")))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
   ""
   "")
 
-(define_insn ""
+(define_insn "*am33_ashlsi3"
   [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
        (ashift:SI
         (match_operand:SI 1 "register_operand" "0,0,dax")
-        (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
+        (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))
+   (clobber (reg:CC CC_REG))
+  ]
   "TARGET_AM33"
   "*
 {
     return \"mov %1,%0\;asl %S2,%0\";
   return \"asl %2,%1,%0\";
 }"
-  [(set_attr "cc" "set_zn")])
+)
 
-(define_insn ""
+(define_insn "*mn10300_ashlsi3"
   [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
        (ashift:SI
         (match_operand:SI 1 "register_operand" "0,0,0,0,0")
-        (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
+        (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "@
   add %0,%0
   asl2 %0\;add %0,%0
   asl2 %0\;asl2 %0
   asl %S2,%0"
-  [(set_attr "cc" "set_zn")])
+)
 
 (define_expand "lshrsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (lshiftrt:SI
-        (match_operand:SI 1 "register_operand" "")
-        (match_operand:QI 2 "nonmemory_operand" "")))]
+  [(parallel [(set (match_operand:SI 0 "register_operand")
+                  (lshiftrt:SI
+                   (match_operand:SI 1 "register_operand")
+                   (match_operand:QI 2 "nonmemory_operand")))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
   ""
   "")
 
-(define_insn ""
+(define_insn "*am33_lshrsi3"
   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
        (lshiftrt:SI
         (match_operand:SI 1 "register_operand" "0,dax")
-        (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
+        (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))
+   (clobber (reg:CC CC_REG))
+  ]
   "TARGET_AM33"
   "*
 {
     return \"mov %1,%0\;lsr %S2,%0\";
   return \"lsr %2,%1,%0\";
 }"
-  [(set_attr "cc" "set_zn")])
+)
 
-(define_insn ""
+(define_insn "*mn10300_lshrsi3"
   [(set (match_operand:SI 0 "register_operand" "=dx")
        (lshiftrt:SI
         (match_operand:SI 1 "register_operand" "0")
-        (match_operand:QI 2 "nonmemory_operand" "dxi")))]
+        (match_operand:QI 2 "nonmemory_operand" "dxi")))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "lsr %S2,%0"
-  [(set_attr "cc" "set_zn")])
+)
 
 (define_expand "ashrsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (ashiftrt:SI
-        (match_operand:SI 1 "register_operand" "")
-        (match_operand:QI 2 "nonmemory_operand" "")))]
+  [(parallel [(set (match_operand:SI 0 "register_operand")
+                  (ashiftrt:SI
+                   (match_operand:SI 1 "register_operand")
+                   (match_operand:QI 2 "nonmemory_operand")))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
   ""
   "")
 
-(define_insn ""
+(define_insn "*am33_ashrisi3"
   [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
        (ashiftrt:SI
         (match_operand:SI 1 "register_operand" "0,dax")
-        (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
+        (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))
+   (clobber (reg:CC CC_REG))
+  ]
   "TARGET_AM33"
   "*
 {
     return \"mov %1,%0\;asr %S2,%0\";
   return \"asr %2,%1,%0\";
 }"
-  [(set_attr "cc" "set_zn")])
+)
 
-(define_insn ""
+(define_insn "*mn10300_ashrsi3"
   [(set (match_operand:SI 0 "register_operand" "=dx")
        (ashiftrt:SI
         (match_operand:SI 1 "register_operand" "0")
-        (match_operand:QI 2 "nonmemory_operand" "dxi")))]
+        (match_operand:QI 2 "nonmemory_operand" "dxi")))
+   (clobber (reg:CC CC_REG))
+  ]
   ""
   "asr %S2,%0"
-  [(set_attr "cc" "set_zn")])
+)
 
 ;; ----------------------------------------------------------------------
 ;; FP INSTRUCTIONS
 ;;
 
 (define_expand "absdf2"
-  [(set (match_operand:DF 0 "register_operand" "")
-        (abs:DF (match_operand:DF 1 "register_operand" "")))]
+  [(set (match_operand:DF         0 "register_operand")
+        (abs:DF (match_operand:DF 1 "register_operand")))]
   ""
   "
 {
 }")
 
 (define_expand "abssf2"
-  [(set (match_operand:SF 0 "register_operand" "")
-        (abs:SF (match_operand:SF 1 "register_operand" "")))]
+  [(set (match_operand:SF         0 "register_operand")
+        (abs:SF (match_operand:SF 1 "register_operand")))]
   ""
   "
 {
 
 
 (define_insn "abssf2_am33_2"
-  [(set (match_operand:SF 0 "register_operand" "=f,f")
+  [(set (match_operand:SF         0 "register_operand" "=f,f")
        (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
   "TARGET_AM33_2"
   "@
    fabs %0
    fabs %1, %0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 (define_expand "negdf2"
-  [(set (match_operand:DF 0 "register_operand" "")
-        (neg:DF (match_operand:DF 1 "register_operand" "")))]
+  [(set (match_operand:DF         0 "register_operand")
+        (neg:DF (match_operand:DF 1 "register_operand")))]
   ""
   "
 {
 }")
 
 (define_expand "negsf2"
-  [(set (match_operand:SF 0 "register_operand" "")
-        (neg:SF (match_operand:SF 1 "register_operand" "")))]
+  [(set (match_operand:SF         0 "register_operand")
+        (neg:SF (match_operand:SF 1 "register_operand")))]
   ""
   "
 {
 }")
 
 (define_insn "negsf2_am33_2"
-  [(set (match_operand:SF 0 "register_operand" "=f,f")
+  [(set (match_operand:SF         0 "register_operand" "=f,f")
        (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
   "TARGET_AM33_2"
   "@
    fneg %0
    fneg %1, %0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 (define_expand "sqrtsf2"
-  [(set (match_operand:SF 0 "register_operand" "")
-       (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
+  [(set (match_operand:SF          0 "register_operand")
+       (sqrt:SF (match_operand:SF 1 "register_operand")))]
   "TARGET_AM33_2 && flag_unsafe_math_optimizations"
   "
 {
 }")
 
 (define_insn "rsqrtsf2"
-  [(set (match_operand:SF 0 "register_operand" "=f,f")
-       (div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
-               (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))]
+  [(set (match_operand:SF                  0 "register_operand" "=f,f")
+       (div:SF (match_operand:SF          2 "const_1f_operand" "F,F")
+               (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))
+   (clobber (reg:CC_FLOAT CC_REG))
+  ]
   "TARGET_AM33_2"
   "@
    frsqrt %0
    frsqrt %1, %0"
-  [(set_attr "cc" "none_0hit")])
+)
+
+(define_expand "addsf3"
+  [(parallel [(set (match_operand:SF          0 "register_operand")
+                  (plus:SF (match_operand:SF 1 "register_operand")
+                           (match_operand:SF 2 "nonmemory_operand")))
+             (clobber (reg:CC_FLOAT CC_REG))])
+  ]
+  "TARGET_AM33_2"
+  ""
+)
 
-(define_insn "addsf3"
-  [(set (match_operand:SF 0 "register_operand" "=f,f")
+(define_insn "*addsf3_internal"
+  [(set (match_operand:SF          0 "register_operand" "=f,f")
        (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
-                (match_operand:SF 2 "general_operand" "f,?fF")))]
+                (match_operand:SF 2 "general_operand" "f,?fF")))
+   (clobber (reg:CC_FLOAT CC_REG))
+  ]
   "TARGET_AM33_2"
   "@
    fadd %2, %0
    fadd %2, %1, %0"
-  [(set_attr "cc" "none_0hit")])
+)
+
+(define_expand "subsf3"
+  [(parallel [(set (match_operand:SF           0 "register_operand")
+                  (minus:SF (match_operand:SF 1 "register_operand")
+                            (match_operand:SF 2 "nonmemory_operand")))
+             (clobber (reg:CC_FLOAT CC_REG))])
+  ]
+  "TARGET_AM33_2"
+  ""
+)
 
-(define_insn "subsf3"
-  [(set (match_operand:SF 0 "register_operand" "=f,f")
+(define_insn "*subsf3_internal"
+  [(set (match_operand:SF           0 "register_operand" "=f,f")
        (minus:SF (match_operand:SF 1 "register_operand" "0,f")
-                 (match_operand:SF 2 "general_operand" "f,?fF")))]
+                 (match_operand:SF 2 "general_operand" "f,?fF")))
+   (clobber (reg:CC_FLOAT CC_REG))
+  ]
   "TARGET_AM33_2"
   "@
    fsub %2, %0
    fsub %2, %1, %0"
-  [(set_attr "cc" "none_0hit")])
+)
+
+(define_expand "mulsf3"
+  [(parallel [(set (match_operand:SF          0 "register_operand")
+                  (mult:SF (match_operand:SF 1 "register_operand")
+                           (match_operand:SF 2 "nonmemory_operand")))
+             (clobber (reg:CC_FLOAT CC_REG))])
+  ]
+  "TARGET_AM33_2"
+  ""
+)
 
-(define_insn "mulsf3"
-  [(set (match_operand:SF 0 "register_operand" "=f,f")
+(define_insn "*mulsf3_internal"
+  [(set (match_operand:SF          0 "register_operand" "=f,f")
        (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
-                (match_operand:SF 2 "general_operand" "f,?fF")))]
+                (match_operand:SF 2 "general_operand" "f,?fF")))
+  (clobber (reg:CC_FLOAT CC_REG))
+  ]
   "TARGET_AM33_2"
   "@
    fmul %2, %0
    fmul %2, %1, %0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 (define_insn "divsf3"
-  [(set (match_operand:SF 0 "register_operand" "=f,f")
-       (div:SF (match_operand:SF 1 "register_operand" "0,f")
-               (match_operand:SF 2 "general_operand" "f,?fF")))]
+  [(set (match_operand:SF         0 "register_operand" "=f,f")
+       (div:SF (match_operand:SF 1 "register_operand"  "0,f")
+               (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
+   (clobber (reg:CC_FLOAT CC_REG))
+  ]
   "TARGET_AM33_2"
   "@
    fdiv %2, %0
    fdiv %2, %1, %0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 (define_insn "fmaddsf4"
-  [(set (match_operand:SF 0 "register_operand" "=A")
+  [(set (match_operand:SF                   0 "register_operand" "=A")
        (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
                          (match_operand:SF 2 "register_operand" "f"))
-                (match_operand:SF 3 "register_operand" "f")))]
+                (match_operand:SF          3 "register_operand" "f")))
+   (clobber (reg:CC_FLOAT CC_REG))
+  ]
   "TARGET_AM33_2"
   "fmadd %1, %2, %3, %0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 (define_insn "fmsubsf4"
-  [(set (match_operand:SF 0 "register_operand" "=A")
+  [(set (match_operand:SF                    0 "register_operand" "=A")
        (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
                           (match_operand:SF 2 "register_operand" "f"))
-                 (match_operand:SF 3 "register_operand" "f")))]
+                 (match_operand:SF          3 "register_operand" "f")))
+   (clobber (reg:CC_FLOAT CC_REG))
+  ]
   "TARGET_AM33_2"
   "fmsub %1, %2, %3, %0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 (define_insn "fnmaddsf4"
-  [(set (match_operand:SF 0 "register_operand" "=A")
-       (minus:SF (match_operand:SF 3 "register_operand" "f")
+  [(set (match_operand:SF                    0 "register_operand" "=A")
+       (minus:SF (match_operand:SF          3 "register_operand" "f")
                  (mult:SF (match_operand:SF 1 "register_operand" "%f")
-                          (match_operand:SF 2 "register_operand" "f"))))]
+                          (match_operand:SF 2 "register_operand" "f"))))
+   (clobber (reg:CC_FLOAT CC_REG))
+  ]
   "TARGET_AM33_2"
   "fnmadd %1, %2, %3, %0"
-  [(set_attr "cc" "none_0hit")])
+)
 
 (define_insn "fnmsubsf4"
-  [(set (match_operand:SF 0 "register_operand" "=A")
+  [(set (match_operand:SF                            0 "register_operand" "=A")
        (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
                                   (match_operand:SF 2 "register_operand" "f")))
-                 (match_operand:SF 3 "register_operand" "f")))]
+                 (match_operand:SF                  3 "register_operand" "f")))
+   (clobber (reg:CC_FLOAT CC_REG))
+  ]
   "TARGET_AM33_2"
   "fnmsub %1, %2, %3, %0"
-  [(set_attr "cc" "none_0hit")])
-
+)
 
 ;; ----------------------------------------------------------------------
 ;; PROLOGUE/EPILOGUE
    (return)]
   ""
   "rets"
-  [(set_attr "cc" "clobber")])
+)
 
 ;; This insn restores the callee saved registers and does a return, it
 ;; can also deallocate stack space.
   fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
   return \"\";
 }"
-  [(set_attr "cc" "clobber")])
+)
 
 ;; This instruction matches one generated by mn10300_gen_multiple_store()
 (define_insn "store_movm"
   [(match_parallel 0 "store_multiple_operation"
-    [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
+    [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand 1 "" "")))])]
   ""
   "*
 {
   fprintf (asm_out_file, \",(sp)\\n\");
   return \"\";
 }"
-  [(set_attr "cc" "clobber")])
+)
 
 (define_insn "return"
   [(return)]
   else
     return \"rets\";
 }"
-  [(set_attr "cc" "clobber")])
+)
 
 ;; Try to combine consecutive updates of the stack pointer (or any
 ;; other register for that matter).
 (define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=dxay")
-       (plus:SI (match_dup 0)
-                (match_operand 1 "const_int_operand" "")))
-   (set (match_dup 0)
-       (plus:SI (match_dup 0)
-                (match_operand 2 "const_int_operand" "")))]
+  [(parallel [(set (match_operand:SI 0 "register_operand" "=dxay")
+                  (plus:SI (match_dup 0)
+                           (match_operand 1 "const_int_operand" "")))
+             (clobber (reg:CC CC_REG))
+            ])
+   (parallel [(set (match_dup 0)
+                  (plus:SI (match_dup 0)
+                           (match_operand 2 "const_int_operand" "")))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
   ""
   "*
 {
   operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
   return \"add %1,%0\";
 }"
-  [(set_attr "cc" "clobber")])
-
-;;
-;; We had patterns to check eq/ne, but the they don't work because
-;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
-;;
-;; The Z flag and C flag would be set, and we have no way to
-;; check for the Z flag set and C flag clear.
-;;
-;; This will work on the mn10200 because we can check the ZX flag
-;; if the comparison is in HImode.
-(define_peephole
-  [(set (cc0) (compare (match_operand:SI 0 "register_operand" "dx")
-                      (const_int 0)))
-   (set (pc) (if_then_else (ge (cc0) (const_int 0))
-                          (match_operand 1 "" "")
-                          (pc)))]
-  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
-  "add %0,%0\;bcc %1"
-  [(set_attr "cc" "clobber")])
-
-(define_peephole
-  [(set (cc0) (compare (match_operand:SI 0 "register_operand" "dx")
-                      (const_int 0)))
-   (set (pc) (if_then_else (lt (cc0) (const_int 0))
-                          (match_operand 1 "" "")
-                          (pc)))]
-  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
-  "add %0,%0\;bcs %1"
-  [(set_attr "cc" "clobber")])
-
-(define_peephole
-  [(set (cc0) (compare (match_operand:SI 0 "register_operand" "dx")
-                      (const_int 0)))
-   (set (pc) (if_then_else (ge (cc0) (const_int 0))
-                          (pc)
-                          (match_operand 1 "" "")))]
-  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
-  "add %0,%0\;bcs %1"
-  [(set_attr "cc" "clobber")])
-
-(define_peephole
-  [(set (cc0) (compare (match_operand:SI 0 "register_operand" "dx")
-                      (const_int 0)))
-   (set (pc) (if_then_else (lt (cc0) (const_int 0))
-                          (pc)
-                          (match_operand 1 "" "")))]
-  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
-  "add %0,%0\;bcc %1"
-  [(set_attr "cc" "clobber")])
+)
 
 (define_expand "int_label"
   [(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)]
     [(set (reg:SI PIC_REG) (pc))
      (use (match_operand 0 "" ""))])]
   "TARGET_AM33"
-  "%0:\;mov pc,a2")
-
+  "%0:\;mov pc,a2"
+)
 
 (define_insn_and_split "mn10300_loadPC"
   [(parallel
     [(set (reg:SI PIC_REG) (pc))
      (use (match_operand 0 "" ""))])]
-  ""
+  "! TARGET_AM33"
   "#"
-  "reload_completed"
+  "&& reload_completed"
   [(match_operand 0 "" "")]
-  "
-{
-  rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
-  int need_stack_space = (get_frame_size () == 0
-                         && crtl->outgoing_args_size == 0);
+  {
+    rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
+    int need_stack_space = (get_frame_size () == 0
+                           && crtl->outgoing_args_size == 0);
 
-  if (need_stack_space)
-    emit_move_insn (sp_reg, plus_constant (sp_reg, -4));
+    if (need_stack_space)
+      emit_insn (gen_addsi3 (sp_reg, sp_reg, GEN_INT (-4)));
 
-  emit_insn (gen_call_next_insn (operands[0]));
+    emit_insn (gen_call_next_insn (operands[0]));
 
-  if (need_stack_space)
-    emit_insn (gen_pop_pic_reg ());
-  else
-    emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
-
-  DONE;
-}")
+    if (need_stack_space)
+      emit_insn (gen_pop_pic_reg ());
+    else
+      emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
+    DONE;
+  }
+)
 
 (define_insn "call_next_insn"
   [(parallel
   "calls %0\;%0:")
 
 (define_expand "add_GOT_to_pic_reg"
-  [(set (reg:SI PIC_REG)
-       (plus:SI
-        (reg:SI PIC_REG)
-        (const:SI
-         (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_GOTSYM_OFF))))]
-  "")
+  [(parallel [(set (reg:SI PIC_REG)
+                  (plus:SI
+                   (reg:SI PIC_REG)
+                   (const:SI
+                    (unspec:SI [(minus:SI
+                              (match_dup 1)
+                              (const (minus:SI
+                                      (const (match_operand:SI 0 "" ""))
+                                      (pc))))
+                             ] UNSPEC_PIC))))
+             (clobber (reg:CC CC_REG))
+             ])
+  ]
+  ""
+  "operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);"
+)
+
+(define_expand "add_GOT_to_any_reg"
+  [(parallel [(set (match_operand:SI 0 "" "")
+                  (plus:SI
+                   (match_operand:SI 1 "" "")
+                   (const
+                    (unspec [(minus:SI
+                              (match_dup 3)
+                              (const (minus:SI
+                                      (const (match_operand:SI 2 "" ""))
+                                      (pc))))
+                             ] UNSPEC_PIC))))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
+  ""
+  "operands[3] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);"
+)
 
 (define_expand "symGOT2reg"
-  [(match_operand:SI 0 "" "")
-   (match_operand:SI 1 "" "")]
+  [(match_operand:SI 0 "")
+   (match_operand:SI 1 "")]
   ""
   "
 {
 }")
 
 (define_expand "symGOT2reg_i"
-  [(set (match_operand:SI 0 "" "")
+  [(set (match_operand:SI 0 "")
        (mem:SI (plus:SI (reg:SI PIC_REG)
-                        (const (unspec [(match_operand:SI 1 "" "")]
+                        (const (unspec [(match_operand:SI 1 "")]
                                        UNSPEC_GOT)))))]
   ""
   "")
 
 (define_expand "symGOTOFF2reg"
-  [(match_operand:SI 0 "" "") (match_operand:SI 1 "" "")]
+  [(match_operand:SI 0 "") (match_operand:SI 1 "")]
   ""
   "
 {
 }")
 
 (define_expand "symGOTOFF2reg_i"
-  [(set (match_operand:SI 0 "" "")
-       (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOTOFF)))
-  (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI PIC_REG)))]
+  [(set (match_operand:SI 0 "")
+       (const (unspec [(match_operand:SI 1 "")] UNSPEC_GOTOFF)))
+   (parallel [(set (match_dup 0)
+                  (plus:SI (match_dup 0)
+                           (reg:SI PIC_REG)))
+             (clobber (reg:CC CC_REG))
+            ])
+  ]
   ""
   "")
 
 (define_expand "sym2PIC"
-  [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC)]
+  [(unspec [(match_operand:SI 0 "")] UNSPEC_PIC)]
   "" "")
 
 (define_expand "sym2PLT"
-  [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT)]
+  [(unspec [(match_operand:SI 0 "")] UNSPEC_PLT)]
   "" "")
index 8166e72..0f76a49 100644 (file)
 
   return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
 })
+
+(define_predicate "impossible_plus_operand"
+  (match_code "plus")
+{
+  return XEXP (op, 0) == stack_pointer_rtx
+      || XEXP (op, 1) == stack_pointer_rtx;
+})