OSDN Git Service

Update Copyright years for files modified in 2008 and/or 2009.
[pf3gnuchains/gcc-fork.git] / gcc / config / h8300 / h8300.c
index 81e104f..f75a496 100644 (file)
@@ -1,6 +1,7 @@
 /* Subroutines for insn-output.c for Renesas H8/300.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Free Software Foundation, Inc.
    Contributed by Steve Chamberlain (sac@cygnus.com),
    Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
 
@@ -8,7 +9,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -17,9 +18,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -83,8 +83,8 @@ static int h8300_interrupt_function_p (tree);
 static int h8300_saveall_function_p (tree);
 static int h8300_monitor_function_p (tree);
 static int h8300_os_task_function_p (tree);
-static void h8300_emit_stack_adjustment (int, unsigned int);
-static int round_frame_size (int);
+static void h8300_emit_stack_adjustment (int, HOST_WIDE_INT);
+static HOST_WIDE_INT round_frame_size (HOST_WIDE_INT);
 static unsigned int compute_saved_regs (void);
 static void push (int);
 static void pop (int);
@@ -112,6 +112,7 @@ static unsigned int  h8300_bitfield_length        (rtx, rtx);
 static unsigned int  h8300_binary_length          (rtx, const h8300_length_table *);
 static bool          h8300_short_move_mem_p       (rtx, enum rtx_code);
 static unsigned int  h8300_move_length            (rtx *, const h8300_length_table *);
+static bool         h8300_hard_regno_scratch_ok  (unsigned int);
 
 /* CPU_TYPE, says what cpu we're compiling for.  */
 int cpu_type;
@@ -481,8 +482,7 @@ byte_reg (rtx x, int b)
     "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7l", "r7h"
   };
 
-  if (!REG_P (x))
-    abort ();
+  gcc_assert (REG_P (x));
 
   return names_small[REGNO (x) * 2 + b];
 }
@@ -495,12 +495,12 @@ byte_reg (rtx x, int b)
    && ! TREE_THIS_VOLATILE (current_function_decl)                     \
    && (h8300_saveall_function_p (current_function_decl)                        \
        /* Save any call saved register that was used.  */              \
-       || (regs_ever_live[regno] && !call_used_regs[regno])            \
+       || (df_regs_ever_live_p (regno) && !call_used_regs[regno])      \
        /* Save the frame pointer if it was used.  */                   \
-       || (regno == HARD_FRAME_POINTER_REGNUM && regs_ever_live[regno])        \
+       || (regno == HARD_FRAME_POINTER_REGNUM && df_regs_ever_live_p (regno)) \
        /* Save any register used in an interrupt handler.  */          \
        || (h8300_current_function_interrupt_function_p ()              \
-          && regs_ever_live[regno])                                    \
+          && df_regs_ever_live_p (regno))                              \
        /* Save call clobbered registers in non-leaf interrupt          \
          handlers.  */                                                 \
        || (h8300_current_function_interrupt_function_p ()              \
@@ -511,7 +511,7 @@ byte_reg (rtx x, int b)
    SIZE to adjust the stack pointer.  */
 
 static void
-h8300_emit_stack_adjustment (int sign, unsigned int size)
+h8300_emit_stack_adjustment (int sign, HOST_WIDE_INT size)
 {
   /* If the frame size is 0, we don't have anything to do.  */
   if (size == 0)
@@ -547,8 +547,8 @@ h8300_emit_stack_adjustment (int sign, unsigned int size)
 
 /* Round up frame size SIZE.  */
 
-static int
-round_frame_size (int size)
+static HOST_WIDE_INT
+round_frame_size (HOST_WIDE_INT size)
 {
   return ((size + STACK_BOUNDARY / BITS_PER_UNIT - 1)
          & -STACK_BOUNDARY / BITS_PER_UNIT);
@@ -932,7 +932,7 @@ h8300_expand_epilogue (void)
     }
 
   if (!returned_p)
-    emit_insn (gen_rtx_RETURN (VOIDmode));
+    emit_jump_insn (gen_rtx_RETURN (VOIDmode));
 }
 
 /* Return nonzero if the current function is an interrupt
@@ -1001,7 +1001,7 @@ split_adds_subs (enum machine_mode mode, rtx *operands)
       break;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   /* Try different amounts in descending order.  */
@@ -1153,7 +1153,7 @@ h8300_shift_costs (rtx x)
 /* Worker function for TARGET_RTX_COSTS.  */
 
 static bool
-h8300_rtx_costs (rtx x, int code, int outer_code, int *total)
+h8300_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
 {
   if (TARGET_H8300SX && outer_code == MEM)
     {
@@ -1179,7 +1179,7 @@ h8300_rtx_costs (rtx x, int code, int outer_code, int *total)
          {
            /* Constant operands need the same number of processor
               states as register operands.  Although we could try to
-              use a size-based cost for optimize_size, the lack of
+              use a size-based cost for !speed, the lack of
               of a mode makes the results very unpredictable.  */
            *total = 0;
            return true;
@@ -1244,11 +1244,11 @@ h8300_rtx_costs (rtx x, int code, int outer_code, int *total)
          {
          case QImode:
          case HImode:
-           *total = COSTS_N_INSNS (optimize_size ? 4 : 10);
+           *total = COSTS_N_INSNS (!speed ? 4 : 10);
            return false;
 
          case SImode:
-           *total = COSTS_N_INSNS (optimize_size ? 4 : 18);
+           *total = COSTS_N_INSNS (!speed ? 4 : 18);
            return false;
 
          default:
@@ -1322,20 +1322,20 @@ h8300_rtx_costs (rtx x, int code, int outer_code, int *total)
        If this operand isn't a register, fall back to 'R' handling.
    'Z' print int & 7.
    'c' print the opcode corresponding to rtl
-   'e' first word of 32 bit value - if reg, then least reg. if mem
+   'e' first word of 32-bit value - if reg, then least reg. if mem
        then least. if const then most sig word
-   'f' second word of 32 bit value - if reg, then biggest reg. if mem
+   'f' second word of 32-bit value - if reg, then biggest reg. if mem
        then +2. if const then least sig word
    'j' print operand as condition code.
    'k' print operand as reverse condition code.
    'm' convert an integer operand to a size suffix (.b, .w or .l)
    'o' print an integer without a leading '#'
-   's' print as low byte of 16 bit value
-   't' print as high byte of 16 bit value
-   'w' print as low byte of 32 bit value
-   'x' print as 2nd byte of 32 bit value
-   'y' print as 3rd byte of 32 bit value
-   'z' print as msb of 32 bit value
+   's' print as low byte of 16-bit value
+   't' print as high byte of 16-bit value
+   'w' print as low byte of 32-bit value
+   'x' print as 2nd byte of 32-bit value
+   'y' print as 3rd byte of 32-bit value
+   'z' print as msb of 32-bit value
 */
 
 /* Return assembly language string which identifies a comparison type.  */
@@ -1366,7 +1366,7 @@ cond_string (enum rtx_code code)
     case LTU:
       return "lo";
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }
 
@@ -1391,7 +1391,7 @@ print_operand (FILE *file, rtx x, int code)
          fprintf (file, "#%ld", (-INTVAL (x)) & 0xff);
          break;
        default:
-         abort ();
+         gcc_unreachable ();
        }
       break;
     case 'F':
@@ -1404,12 +1404,11 @@ print_operand (FILE *file, rtx x, int code)
          fprintf (file, "#%ld", ((-INTVAL (x)) & 0xff00) >> 8);
          break;
        default:
-         abort ();
+         gcc_unreachable ();
        }
       break;
     case 'G':
-      if (GET_CODE (x) != CONST_INT)
-       abort ();
+      gcc_assert (GET_CODE (x) == CONST_INT);
       fprintf (file, "#%ld", 0xff & (-INTVAL (x)));
       break;
     case 'S':
@@ -1426,14 +1425,12 @@ print_operand (FILE *file, rtx x, int code)
       break;
     case 'V':
       bitint = exact_log2 (INTVAL (x) & 0xff);
-      if (bitint == -1)
-       abort ();
+      gcc_assert (bitint >= 0);
       fprintf (file, "#%d", bitint);
       break;
     case 'W':
       bitint = exact_log2 ((~INTVAL (x)) & 0xff);
-      if (bitint == -1)
-       abort ();
+      gcc_assert (bitint >= 0);
       fprintf (file, "#%d", bitint);
       break;
     case 'R':
@@ -1444,8 +1441,7 @@ print_operand (FILE *file, rtx x, int code)
        goto def;
       break;
     case 'Y':
-      if (bitint == -1)
-       abort ();
+      gcc_assert (bitint >= 0);
       if (GET_CODE (x) == REG)
        fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
       else
@@ -1497,7 +1493,7 @@ print_operand (FILE *file, rtx x, int code)
            break;
          }
        default:
-         abort ();
+         gcc_unreachable ();
          break;
        }
       break;
@@ -1527,7 +1523,7 @@ print_operand (FILE *file, rtx x, int code)
            break;
          }
        default:
-         abort ();
+         gcc_unreachable ();
        }
       break;
     case 'j':
@@ -1537,16 +1533,24 @@ print_operand (FILE *file, rtx x, int code)
       fputs (cond_string (reverse_condition (GET_CODE (x))), file);
       break;
     case 'm':
-      if (GET_CODE (x) != CONST_INT)
-       abort ();
-      if (INTVAL (x) == 1)
-       fputs (".b", file);
-      else if (INTVAL (x) == 2)
-       fputs (".w", file);
-      else if (INTVAL (x) == 4)
-       fputs (".l", file);
-      else
-       abort ();
+      gcc_assert (GET_CODE (x) == CONST_INT);
+      switch (INTVAL (x))
+       {
+       case 1:
+         fputs (".b", file);
+         break;
+
+       case 2:
+         fputs (".w", file);
+         break;
+
+       case 4:
+         fputs (".l", file);
+         break;
+
+       default:
+         gcc_unreachable ();
+       }
       break;
     case 'o':
       print_operand_address (file, x);
@@ -1612,7 +1616,7 @@ print_operand (FILE *file, rtx x, int code)
              fprintf (file, "%s", names_extended[REGNO (x)]);
              break;
            default:
-             abort ();
+             gcc_unreachable ();
            }
          break;
 
@@ -1757,7 +1761,7 @@ print_operand_address (FILE *file, rtx addr)
 
     case CONST_INT:
       {
-       /* Since the H8/300 only has 16 bit pointers, negative values are also
+       /* Since the H8/300 only has 16-bit pointers, negative values are also
           those >= 32768.  This happens for example with pointer minus a
           constant.  We don't want to turn (char *p - 2) into
           (char *p + 65534) because loop unrolling can build upon this
@@ -1846,8 +1850,9 @@ h8300_initial_elimination_offset (int from, int to)
      pointer int account.  */
   saved_regs_size -= fp_size;
 
-  if (to == HARD_FRAME_POINTER_REGNUM)
+  switch (to)
     {
+    case HARD_FRAME_POINTER_REGNUM:
       switch (from)
        {
        case ARG_POINTER_REGNUM:
@@ -1857,11 +1862,10 @@ h8300_initial_elimination_offset (int from, int to)
        case FRAME_POINTER_REGNUM:
          return -saved_regs_size;
        default:
-         abort ();
+         gcc_unreachable ();
        }
-    }
-  else if (to == STACK_POINTER_REGNUM)
-    {
+      break;
+    case STACK_POINTER_REGNUM:
       switch (from)
        {
        case ARG_POINTER_REGNUM:
@@ -1871,11 +1875,13 @@ h8300_initial_elimination_offset (int from, int to)
        case FRAME_POINTER_REGNUM:
          return frame_size;
        default:
-         abort ();
+         gcc_unreachable ();
        }
+      break;
+    default:
+      gcc_unreachable ();
     }
-  else
-    abort ();
+  gcc_unreachable ();
 }
 
 /* Worker function for RETURN_ADDR_RTX.  */
@@ -2142,21 +2148,21 @@ h8300_displacement_length (rtx addr, int size)
   return h8300_constant_length (offset);
 }
 
-/* Store the class of operand OP in *CLASS and return the length of any
-   extra operand fields.  SIZE is the number of bytes in OP.  CLASS
+/* Store the class of operand OP in *OPCLASS and return the length of any
+   extra operand fields.  SIZE is the number of bytes in OP.  OPCLASS
    can be null if only the length is needed.  */
 
 static unsigned int
-h8300_classify_operand (rtx op, int size, enum h8300_operand_class *class)
+h8300_classify_operand (rtx op, int size, enum h8300_operand_class *opclass)
 {
   enum h8300_operand_class dummy;
 
-  if (class == 0)
-    class = &dummy;
+  if (opclass == 0)
+    opclass = &dummy;
 
   if (CONSTANT_P (op))
     {
-      *class = H8OP_IMMEDIATE;
+      *opclass = H8OP_IMMEDIATE;
 
       /* Byte-sized immediates are stored in the opcode fields.  */
       if (size == 1)
@@ -2177,31 +2183,28 @@ h8300_classify_operand (rtx op, int size, enum h8300_operand_class *class)
       op = XEXP (op, 0);
       if (CONSTANT_P (op))
        {
-         *class = H8OP_MEM_ABSOLUTE;
+         *opclass = H8OP_MEM_ABSOLUTE;
          return h8300_constant_length (op);
        }
       else if (GET_CODE (op) == PLUS && CONSTANT_P (XEXP (op, 1)))
        {
-         *class = H8OP_MEM_COMPLEX;
+         *opclass = H8OP_MEM_COMPLEX;
          return h8300_displacement_length (op, size);
        }
       else if (GET_RTX_CLASS (GET_CODE (op)) == RTX_AUTOINC)
        {
-         *class = H8OP_MEM_COMPLEX;
+         *opclass = H8OP_MEM_COMPLEX;
          return 0;
        }
       else if (register_operand (op, VOIDmode))
        {
-         *class = H8OP_MEM_BASE;
+         *opclass = H8OP_MEM_BASE;
          return 0;
        }
     }
-  else if (register_operand (op, VOIDmode))
-    {
-      *class = H8OP_REGISTER;
-      return 0;
-    }
-  abort ();
+  gcc_assert (register_operand (op, VOIDmode));
+  *opclass = H8OP_REGISTER;
+  return 0;
 }
 
 /* Return the length of the instruction described by TABLE given that
@@ -2226,12 +2229,12 @@ h8300_length_from_table (rtx op1, rtx op2, const h8300_length_table *table)
 unsigned int
 h8300_unary_length (rtx op)
 {
-  enum h8300_operand_class class;
+  enum h8300_operand_class opclass;
   unsigned int size, operand_length;
 
   size = GET_MODE_SIZE (GET_MODE (op));
-  operand_length = h8300_classify_operand (op, size, &class);
-  switch (class)
+  operand_length = h8300_classify_operand (op, size, &opclass);
+  switch (opclass)
     {
     case H8OP_REGISTER:
       return 2;
@@ -2246,7 +2249,7 @@ h8300_unary_length (rtx op)
       return operand_length + 6;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }
 
@@ -2255,13 +2258,13 @@ h8300_unary_length (rtx op)
 static unsigned int
 h8300_short_immediate_length (rtx op)
 {
-  enum h8300_operand_class class;
+  enum h8300_operand_class opclass;
   unsigned int size, operand_length;
 
   size = GET_MODE_SIZE (GET_MODE (op));
-  operand_length = h8300_classify_operand (op, size, &class);
+  operand_length = h8300_classify_operand (op, size, &opclass);
 
-  switch (class)
+  switch (opclass)
     {
     case H8OP_REGISTER:
       return 2;
@@ -2272,7 +2275,7 @@ h8300_short_immediate_length (rtx op)
       return 4 + operand_length;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }
 
@@ -2281,18 +2284,17 @@ h8300_short_immediate_length (rtx op)
 static unsigned int
 h8300_bitfield_length (rtx op, rtx op2)
 {
-  enum h8300_operand_class class;
+  enum h8300_operand_class opclass;
   unsigned int size, operand_length;
 
   if (GET_CODE (op) == REG)
     op = op2;
-  if (GET_CODE (op) == REG)
-    abort ();
+  gcc_assert (GET_CODE (op) != REG);
   
   size = GET_MODE_SIZE (GET_MODE (op));
-  operand_length = h8300_classify_operand (op, size, &class);
+  operand_length = h8300_classify_operand (op, size, &opclass);
 
-  switch (class)
+  switch (opclass)
     {
     case H8OP_MEM_BASE:
     case H8OP_MEM_ABSOLUTE:
@@ -2300,7 +2302,7 @@ h8300_bitfield_length (rtx op, rtx op2)
       return 4 + operand_length;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }
 
@@ -2312,18 +2314,18 @@ h8300_binary_length (rtx insn, const h8300_length_table *table)
   rtx set;
 
   set = single_set (insn);
-  if (set == 0)
-    abort ();
+  gcc_assert (set);
 
   if (BINARY_P (SET_SRC (set)))
     return h8300_length_from_table (XEXP (SET_SRC (set), 0),
                                    XEXP (SET_SRC (set), 1), table);
-  else if (GET_RTX_CLASS (GET_CODE (SET_SRC (set))) == RTX_TERNARY)
-    return h8300_length_from_table (XEXP (XEXP (SET_SRC (set), 1), 0),
-                                   XEXP (XEXP (SET_SRC (set), 1), 1),
-                                   table);
   else
-    abort ();
+    {
+      gcc_assert (GET_RTX_CLASS (GET_CODE (SET_SRC (set))) == RTX_TERNARY);
+      return h8300_length_from_table (XEXP (XEXP (SET_SRC (set), 1), 0),
+                                     XEXP (XEXP (SET_SRC (set), 1), 1),
+                                     table);
+    }
 }
 
 /* Subroutine of h8300_move_length.  Return true if OP is 1- or 2-byte
@@ -2401,7 +2403,7 @@ h8300_insn_length_from_table (rtx insn, rtx * operands)
   switch (get_attr_length_table (insn))
     {
     case LENGTH_TABLE_NONE:
-      abort ();
+      gcc_unreachable ();
 
     case LENGTH_TABLE_ADDB:
       return h8300_binary_length (insn, &addb_length_table);
@@ -2444,9 +2446,10 @@ h8300_insn_length_from_table (rtx insn, rtx * operands)
       
     case LENGTH_TABLE_BITBRANCH:
       return h8300_bitfield_length (operands[1], operands[2]) - 2;
-      
+
+    default:
+      gcc_unreachable ();
     }
-  abort ();
 }
 
 /* Return true if LHS and RHS are memory references that can be mapped
@@ -2711,7 +2714,7 @@ compute_mov_length (rtx *operands)
          break;
 
        default:
-         abort ();
+         gcc_unreachable ();
        }
 
       /* Adjust the length based on the addressing mode used.
@@ -2831,7 +2834,7 @@ compute_mov_length (rtx *operands)
          break;
 
        default:
-         abort ();
+         gcc_unreachable ();
        }
 
       /* Adjust the length based on the addressing mode used.
@@ -2875,8 +2878,7 @@ output_plussi (rtx *operands)
 {
   enum machine_mode mode = GET_MODE (operands[0]);
 
-  if (mode != SImode)
-    abort ();
+  gcc_assert (mode == SImode);
 
   if (TARGET_H8300)
     {
@@ -2960,8 +2962,7 @@ compute_plussi_length (rtx *operands)
 {
   enum machine_mode mode = GET_MODE (operands[0]);
 
-  if (mode != SImode)
-    abort ();
+  gcc_assert (mode == SImode);
 
   if (TARGET_H8300)
     {
@@ -3040,8 +3041,7 @@ compute_plussi_cc (rtx *operands)
 {
   enum machine_mode mode = GET_MODE (operands[0]);
 
-  if (mode != SImode)
-    abort ();
+  gcc_assert (mode == SImode);
 
   if (TARGET_H8300)
     {
@@ -3135,7 +3135,7 @@ output_logical_op (enum machine_mode mode, rtx *operands)
       opname = "xor";
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   switch (mode)
@@ -3267,7 +3267,7 @@ output_logical_op (enum machine_mode mode, rtx *operands)
        }
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
   return "";
 }
@@ -3413,7 +3413,7 @@ compute_logical_op_length (enum machine_mode mode, rtx *operands)
        }
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
   return length;
 }
@@ -3495,7 +3495,7 @@ compute_logical_op_cc (enum machine_mode mode, rtx *operands)
        }
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
   return cc;
 }
@@ -3633,7 +3633,7 @@ output_h8sx_shift (rtx *operands, int suffix, int optype)
       break;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
   if (operands[2] == const1_rtx)
     sprintf (buffer, "%s.%c\t%%%c0", stem, suffix, optype);
@@ -3660,7 +3660,7 @@ expand_a_shift (enum machine_mode mode, int code, rtx operands[])
       break;
     }
 
-  emit_move_insn (operands[0], operands[1]);
+  emit_move_insn (copy_rtx (operands[0]), operands[1]);
 
   /* Need a loop to get all the bits we want  - we generate the
      code at emit time, but need to allocate a scratch reg now.  */
@@ -3668,9 +3668,9 @@ expand_a_shift (enum machine_mode mode, int code, rtx operands[])
   emit_insn (gen_rtx_PARALLEL
             (VOIDmode,
              gen_rtvec (2,
-                        gen_rtx_SET (VOIDmode, operands[0],
+                        gen_rtx_SET (VOIDmode, copy_rtx (operands[0]),
                                      gen_rtx_fmt_ee (code, mode,
-                                                     operands[0], operands[2])),
+                                                     copy_rtx (operands[0]), operands[2])),
                         gen_rtx_CLOBBER (VOIDmode,
                                          gen_rtx_SCRATCH (QImode)))));
   return true;
@@ -3914,7 +3914,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
       break;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   /* Fill in INFO.  Return unless we have SHIFT_SPECIAL.  */
@@ -3953,12 +3953,9 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
     case QIshift:
       /* For ASHIFTRT by 7 bits, the sign bit is simply replicated
         through the entire value.  */
-      if (shift_type == SHIFT_ASHIFTRT && count == 7)
-       {
-         info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
-         goto end;
-       }
-      abort ();
+      gcc_assert (shift_type == SHIFT_ASHIFTRT && count == 7);
+      info->special = "shll\t%X0\n\tsubx\t%X0,%X0";
+      goto end;
 
     case HIshift:
       if (count == 7)
@@ -4040,7 +4037,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
                  info->cc_special = CC_SET_ZNV;
                }
              else /* TARGET_H8300S */
-               abort ();
+               gcc_unreachable ();
              goto end;
            }
        }
@@ -4059,7 +4056,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
              goto end;
            }
        }
-      abort ();
+      gcc_unreachable ();
 
     case SIshift:
       if (TARGET_H8300 && 8 <= count && count <= 9)
@@ -4100,7 +4097,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
          switch (shift_type)
            {
            case SHIFT_ASHIFT:
-             abort ();
+             gcc_unreachable ();
            case SHIFT_LSHIFTRT:
              info->special = "bld\t#7,%z0\n\tmov.w\t%e0,%f0\n\txor\t%y0,%y0\n\txor\t%z0,%z0\n\trotxl\t%w0\n\trotxl\t%x0\n\trotxl\t%y0";
              goto end;
@@ -4122,7 +4119,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
              info->cc_special = CC_SET_ZNV;
              goto end;
            case SHIFT_ASHIFTRT:
-             abort ();
+             gcc_unreachable ();
            }
        }
       else if ((TARGET_H8300 && 16 <= count && count <= 20)
@@ -4227,7 +4224,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
                info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t#2,%S0\n\textu.l\t%S0";
              goto end;
            case SHIFT_ASHIFTRT:
-             abort ();
+             gcc_unreachable ();
            }
        }
       else if (!TARGET_H8300 && count == 29)
@@ -4253,7 +4250,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
                }
              goto end;
            case SHIFT_ASHIFTRT:
-             abort ();
+             gcc_unreachable ();
            }
        }
       else if (!TARGET_H8300 && count == 30)
@@ -4273,7 +4270,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
                info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\textu.l\t%S0";
              goto end;
            case SHIFT_ASHIFTRT:
-             abort ();
+             gcc_unreachable ();
            }
        }
       else if (count == 31)
@@ -4312,10 +4309,10 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
                }
            }
        }
-      abort ();
+      gcc_unreachable ();
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
  end:
@@ -4365,7 +4362,7 @@ h8300_shift_needs_scratch_p (int count, enum machine_mode mode)
       break;
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   /* On H8/300H, count == 8 uses a scratch register.  */
@@ -4385,6 +4382,7 @@ output_a_shift (rtx *operands)
   enum shift_type shift_type;
   enum shift_mode shift_mode;
   struct shift_info info;
+  int n;
 
   loopend_lab++;
 
@@ -4400,7 +4398,7 @@ output_a_shift (rtx *operands)
       shift_mode = SIshift;
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   switch (code)
@@ -4415,127 +4413,129 @@ output_a_shift (rtx *operands)
       shift_type = SHIFT_ASHIFT;
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
-  if (GET_CODE (operands[2]) != CONST_INT)
-    {
-      /* This case must be taken care of by one of the two splitters
-        that convert a variable shift into a loop.  */
-      abort ();
-    }
-  else
+  /* This case must be taken care of by one of the two splitters
+     that convert a variable shift into a loop.  */
+  gcc_assert (GET_CODE (operands[2]) == CONST_INT);
+  
+  n = INTVAL (operands[2]);
+
+  /* If the count is negative, make it 0.  */
+  if (n < 0)
+    n = 0;
+  /* If the count is too big, truncate it.
+     ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
+     do the intuitive thing.  */
+  else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
+    n = GET_MODE_BITSIZE (mode);
+
+  get_shift_alg (shift_type, shift_mode, n, &info);
+  
+  switch (info.alg)
     {
-      int n = INTVAL (operands[2]);
-
-      /* If the count is negative, make it 0.  */
-      if (n < 0)
-       n = 0;
-      /* If the count is too big, truncate it.
-         ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
-        do the intuitive thing.  */
-      else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
-       n = GET_MODE_BITSIZE (mode);
+    case SHIFT_SPECIAL:
+      output_asm_insn (info.special, operands);
+      /* Fall through.  */
 
-      get_shift_alg (shift_type, shift_mode, n, &info);
+    case SHIFT_INLINE:
+      n = info.remainder;
 
-      switch (info.alg)
+      /* Emit two bit shifts first.  */
+      if (info.shift2 != NULL)
        {
-       case SHIFT_SPECIAL:
-         output_asm_insn (info.special, operands);
-         /* Fall through.  */
-
-       case SHIFT_INLINE:
-         n = info.remainder;
-
-         /* Emit two bit shifts first.  */
-         if (info.shift2 != NULL)
-           {
-             for (; n > 1; n -= 2)
-               output_asm_insn (info.shift2, operands);
-           }
-
-         /* Now emit one bit shifts for any residual.  */
-         for (; n > 0; n--)
-           output_asm_insn (info.shift1, operands);
-         return "";
+         for (; n > 1; n -= 2)
+           output_asm_insn (info.shift2, operands);
+       }
 
-       case SHIFT_ROT_AND:
+      /* Now emit one bit shifts for any residual.  */
+      for (; n > 0; n--)
+       output_asm_insn (info.shift1, operands);
+      return "";
+      
+    case SHIFT_ROT_AND:
+      {
+       int m = GET_MODE_BITSIZE (mode) - n;
+       const int mask = (shift_type == SHIFT_ASHIFT
+                         ? ((1 << m) - 1) << n
+                         : (1 << m) - 1);
+       char insn_buf[200];
+
+       /* Not all possibilities of rotate are supported.  They shouldn't
+          be generated, but let's watch for 'em.  */
+       gcc_assert (info.shift1);
+       
+       /* Emit two bit rotates first.  */
+       if (info.shift2 != NULL)
          {
-           int m = GET_MODE_BITSIZE (mode) - n;
-           const int mask = (shift_type == SHIFT_ASHIFT
-                             ? ((1 << m) - 1) << n
-                             : (1 << m) - 1);
-           char insn_buf[200];
-
-           /* Not all possibilities of rotate are supported.  They shouldn't
-              be generated, but let's watch for 'em.  */
-           if (info.shift1 == 0)
-             abort ();
-
-           /* Emit two bit rotates first.  */
-           if (info.shift2 != NULL)
-             {
-               for (; m > 1; m -= 2)
-                 output_asm_insn (info.shift2, operands);
-             }
+           for (; m > 1; m -= 2)
+             output_asm_insn (info.shift2, operands);
+         }
+       
+       /* Now single bit rotates for any residual.  */
+       for (; m > 0; m--)
+         output_asm_insn (info.shift1, operands);
+       
+       /* Now mask off the high bits.  */
+       switch (mode)
+         {
+         case QImode:
+           sprintf (insn_buf, "and\t#%d,%%X0", mask);
+           break;
 
-           /* Now single bit rotates for any residual.  */
-           for (; m > 0; m--)
-             output_asm_insn (info.shift1, operands);
+         case HImode:
+           gcc_assert (TARGET_H8300H || TARGET_H8300S);
+           sprintf (insn_buf, "and.w\t#%d,%%T0", mask);
+           break;
 
-           /* Now mask off the high bits.  */
-           if (mode == QImode)
-             sprintf (insn_buf, "and\t#%d,%%X0", mask);
-           else if (mode == HImode && (TARGET_H8300H || TARGET_H8300S))
-             sprintf (insn_buf, "and.w\t#%d,%%T0", mask);
-           else
-             abort ();
-
-           output_asm_insn (insn_buf, operands);
-           return "";
+         default:
+           gcc_unreachable ();
          }
 
-       case SHIFT_LOOP:
-         /* A loop to shift by a "large" constant value.
-            If we have shift-by-2 insns, use them.  */
-         if (info.shift2 != NULL)
-           {
-             fprintf (asm_out_file, "\tmov.b   #%d,%sl\n", n / 2,
-                      names_big[REGNO (operands[4])]);
-             fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
-             output_asm_insn (info.shift2, operands);
-             output_asm_insn ("add     #0xff,%X4", operands);
-             fprintf (asm_out_file, "\tbne     .Llt%d\n", loopend_lab);
-             if (n % 2)
-               output_asm_insn (info.shift1, operands);
-           }
-         else
-           {
-             fprintf (asm_out_file, "\tmov.b   #%d,%sl\n", n,
-                      names_big[REGNO (operands[4])]);
-             fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
-             output_asm_insn (info.shift1, operands);
-             output_asm_insn ("add     #0xff,%X4", operands);
-             fprintf (asm_out_file, "\tbne     .Llt%d\n", loopend_lab);
-           }
-         return "";
+       output_asm_insn (insn_buf, operands);
+       return "";
+      }
 
-       default:
-         abort ();
+    case SHIFT_LOOP:
+      /* A loop to shift by a "large" constant value.
+        If we have shift-by-2 insns, use them.  */
+      if (info.shift2 != NULL)
+       {
+         fprintf (asm_out_file, "\tmov.b       #%d,%sl\n", n / 2,
+                  names_big[REGNO (operands[4])]);
+         fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
+         output_asm_insn (info.shift2, operands);
+         output_asm_insn ("add #0xff,%X4", operands);
+         fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
+         if (n % 2)
+           output_asm_insn (info.shift1, operands);
        }
+      else
+       {
+         fprintf (asm_out_file, "\tmov.b       #%d,%sl\n", n,
+                  names_big[REGNO (operands[4])]);
+         fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
+         output_asm_insn (info.shift1, operands);
+         output_asm_insn ("add #0xff,%X4", operands);
+         fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab);
+       }
+      return "";
+      
+    default:
+      gcc_unreachable ();
     }
 }
 
-/* Count the number of assembly instructions in a string TEMPLATE.  */
+/* Count the number of assembly instructions in a string TEMPL.  */
 
 static unsigned int
-h8300_asm_insn_count (const char *template)
+h8300_asm_insn_count (const char *templ)
 {
   unsigned int count = 1;
 
-  for (; *template; template++)
-    if (*template == '\n')
+  for (; *templ; templ++)
+    if (*templ == '\n')
       count++;
 
   return count;
@@ -4566,7 +4566,7 @@ compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
       shift_mode = SIshift;
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   switch (code)
@@ -4581,7 +4581,7 @@ compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
       shift_type = SHIFT_ASHIFT;
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   if (GET_CODE (operands[2]) != CONST_INT)
@@ -4639,8 +4639,7 @@ compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
 
            /* Not all possibilities of rotate are supported.  They shouldn't
               be generated, but let's watch for 'em.  */
-           if (info.shift1 == 0)
-             abort ();
+           gcc_assert (info.shift1);
 
            if (info.shift2 != NULL)
              {
@@ -4660,12 +4659,11 @@ compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
                wlength += 2;
                break;
              case SImode:
-               if (TARGET_H8300)
-                 abort ();
+               gcc_assert (!TARGET_H8300);
                wlength += 3;
                break;
              default:
-               abort ();
+               gcc_unreachable ();
              }
            return 2 * wlength;
          }
@@ -4686,7 +4684,7 @@ compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
          return 2 * wlength;
 
        default:
-         abort ();
+         gcc_unreachable ();
        }
     }
 }
@@ -4702,7 +4700,8 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
   enum shift_type shift_type;
   enum shift_mode shift_mode;
   struct shift_info info;
-
+  int n;
+  
   switch (mode)
     {
     case QImode:
@@ -4715,7 +4714,7 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
       shift_mode = SIshift;
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   switch (code)
@@ -4730,58 +4729,53 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
       shift_type = SHIFT_ASHIFT;
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
-  if (GET_CODE (operands[2]) != CONST_INT)
-    {
-      /* This case must be taken care of by one of the two splitters
-        that convert a variable shift into a loop.  */
-      abort ();
-    }
-  else
+  /* This case must be taken care of by one of the two splitters
+     that convert a variable shift into a loop.  */
+  gcc_assert (GET_CODE (operands[2]) == CONST_INT);
+  
+  n = INTVAL (operands[2]);
+
+  /* If the count is negative, make it 0.  */
+  if (n < 0)
+    n = 0;
+  /* If the count is too big, truncate it.
+     ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
+     do the intuitive thing.  */
+  else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
+    n = GET_MODE_BITSIZE (mode);
+  
+  get_shift_alg (shift_type, shift_mode, n, &info);
+  
+  switch (info.alg)
     {
-      int n = INTVAL (operands[2]);
-
-      /* If the count is negative, make it 0.  */
-      if (n < 0)
-       n = 0;
-      /* If the count is too big, truncate it.
-         ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
-        do the intuitive thing.  */
-      else if ((unsigned int) n > GET_MODE_BITSIZE (mode))
-       n = GET_MODE_BITSIZE (mode);
+    case SHIFT_SPECIAL:
+      if (info.remainder == 0)
+       return info.cc_special;
 
-      get_shift_alg (shift_type, shift_mode, n, &info);
+      /* Fall through.  */
 
-      switch (info.alg)
+    case SHIFT_INLINE:
+      return info.cc_inline;
+      
+    case SHIFT_ROT_AND:
+      /* This case always ends with an and instruction.  */
+      return CC_SET_ZNV;
+      
+    case SHIFT_LOOP:
+      /* A loop to shift by a "large" constant value.
+        If we have shift-by-2 insns, use them.  */
+      if (info.shift2 != NULL)
        {
-       case SHIFT_SPECIAL:
-         if (info.remainder == 0)
-           return info.cc_special;
-
-         /* Fall through.  */
-
-       case SHIFT_INLINE:
-         return info.cc_inline;
-
-       case SHIFT_ROT_AND:
-         /* This case always ends with an and instruction.  */
-         return CC_SET_ZNV;
-
-       case SHIFT_LOOP:
-         /* A loop to shift by a "large" constant value.
-            If we have shift-by-2 insns, use them.  */
-         if (info.shift2 != NULL)
-           {
-             if (n % 2)
-               return info.cc_inline;
-           }
-         return CC_CLOBBER;
-
-       default:
-         abort ();
+         if (n % 2)
+           return info.cc_inline;
        }
+      return CC_CLOBBER;
+      
+    default:
+      gcc_unreachable ();
     }
 }
 \f
@@ -4833,7 +4827,7 @@ expand_a_rotate (rtx operands[])
          emit_insn (gen_rotlsi3_1 (dst, dst, const1_rtx));
          break;
        default:
-         abort ();
+         gcc_unreachable ();
        }
 
       /* Decrement the counter by 1.  */
@@ -4861,7 +4855,7 @@ expand_a_rotate (rtx operands[])
          emit_insn (gen_rotlsi3_1 (dst, dst, rotate_amount));
          break;
        default:
-         abort ();
+         gcc_unreachable ();
        }
     }
 
@@ -4882,8 +4876,7 @@ output_a_rotate (enum rtx_code code, rtx *operands)
   int amount;
   enum machine_mode mode = GET_MODE (dst);
 
-  if (GET_CODE (rotate_amount) != CONST_INT)
-    abort ();
+  gcc_assert (GET_CODE (rotate_amount) == CONST_INT);
 
   switch (mode)
     {
@@ -4897,7 +4890,7 @@ output_a_rotate (enum rtx_code code, rtx *operands)
       rotate_mode = SIshift;
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   switch (code)
@@ -4909,7 +4902,7 @@ output_a_rotate (enum rtx_code code, rtx *operands)
       rotate_type = SHIFT_LSHIFTRT;
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
 
   amount = INTVAL (rotate_amount);
@@ -4953,7 +4946,7 @@ output_a_rotate (enum rtx_code code, rtx *operands)
          break;
 
        default:
-         abort ();
+         gcc_unreachable ();
        }
 
       /* Adjust AMOUNT and flip the direction.  */
@@ -4988,8 +4981,7 @@ compute_a_rotate_length (rtx *operands)
   int amount;
   unsigned int length = 0;
 
-  if (GET_CODE (amount_rtx) != CONST_INT)
-    abort ();
+  gcc_assert (GET_CODE (amount_rtx) == CONST_INT);
 
   amount = INTVAL (amount_rtx);
 
@@ -5083,7 +5075,7 @@ fix_bit_operand (rtx *operands, enum rtx_code code)
        emit_insn (gen_xorqi3_1 (res, operands[1], operands[2]));
        break;
       default:
-       abort ();
+       gcc_unreachable ();
       }
     emit_insn (gen_movqi (operands[0], res));
   }
@@ -5264,7 +5256,7 @@ h8300_handle_fndecl_attribute (tree *node, tree name,
 {
   if (TREE_CODE (*node) != FUNCTION_DECL)
     {
-      warning ("%qs attribute only applies to functions",
+      warning (OPT_Wattributes, "%qs attribute only applies to functions",
               IDENTIFIER_POINTER (name));
       *no_add_attrs = true;
     }
@@ -5288,7 +5280,8 @@ h8300_handle_eightbit_data_attribute (tree *node, tree name,
     }
   else
     {
-      warning ("%qs attribute ignored", IDENTIFIER_POINTER (name));
+      warning (OPT_Wattributes, "%qs attribute ignored",
+              IDENTIFIER_POINTER (name));
       *no_add_attrs = true;
     }
 
@@ -5311,7 +5304,8 @@ h8300_handle_tiny_data_attribute (tree *node, tree name,
     }
   else
     {
-      warning ("%qs attribute ignored", IDENTIFIER_POINTER (name));
+      warning (OPT_Wattributes, "%qs attribute ignored",
+              IDENTIFIER_POINTER (name));
       *no_add_attrs = true;
     }
 
@@ -5598,9 +5592,9 @@ h8300_regs_ok_for_stm (int n, rtx operands[])
              && REGNO (operands[1]) == 1
              && REGNO (operands[2]) == 2
              && REGNO (operands[3]) == 3);
+    default:
+      gcc_unreachable ();
     }
-
-  abort ();
 }
 
 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG.  */
@@ -5614,12 +5608,26 @@ h8300_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
      call-clobbered.  */
 
   if (h8300_current_function_interrupt_function_p ()
-      && !regs_ever_live[new_reg])
+      && !df_regs_ever_live_p (new_reg))
     return 0;
 
   return 1;
 }
 
+/* Returns true if register REGNO is safe to be allocated as a scratch
+   register in the current function.  */
+
+static bool
+h8300_hard_regno_scratch_ok (unsigned int regno)
+{
+  if (h8300_current_function_interrupt_function_p ()
+      && ! WORD_REG_USED (regno))
+    return false;
+
+  return true;
+}
+
+
 /* Return nonzero if X is a legitimate constant.  */
 
 int
@@ -5714,7 +5722,7 @@ h8300_init_libfuncs (void)
 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
 
 static bool
-h8300_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
+h8300_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
 {
   return (TYPE_MODE (type) == BLKmode
          || GET_MODE_SIZE (TYPE_MODE (type)) > (TARGET_H8300 ? 4 : 8));
@@ -5753,4 +5761,10 @@ h8300_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
 #undef  TARGET_MACHINE_DEPENDENT_REORG
 #define TARGET_MACHINE_DEPENDENT_REORG h8300_reorg
 
+#undef TARGET_HARD_REGNO_SCRATCH_OK
+#define TARGET_HARD_REGNO_SCRATCH_OK h8300_hard_regno_scratch_ok
+
+#undef TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
+
 struct gcc_target targetm = TARGET_INITIALIZER;