diff gcc/config/stormy16/stormy16.c @ 67:f6334be47118

update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Tue, 22 Mar 2011 17:18:12 +0900
parents b7f97abdc517
children 04ced10e8804
line wrap: on
line diff
--- a/gcc/config/stormy16/stormy16.c	Tue May 25 18:58:51 2010 +0900
+++ b/gcc/config/stormy16/stormy16.c	Tue Mar 22 17:18:12 2011 +0900
@@ -1,6 +1,6 @@
 /* Xstormy16 target functions.
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+   2006, 2007, 2008, 2009, 2010, 2011  Free Software Foundation, Inc.
    Contributed by Red Hat, Inc.
 
    This file is part of GCC.
@@ -33,7 +33,7 @@
 #include "insn-attr.h"
 #include "flags.h"
 #include "recog.h"
-#include "toplev.h"
+#include "diagnostic-core.h"
 #include "obstack.h"
 #include "tree.h"
 #include "expr.h"
@@ -46,6 +46,7 @@
 #include "langhooks.h"
 #include "gimple.h"
 #include "df.h"
+#include "reload.h"
 #include "ggc.h"
 
 static rtx emit_addhi3_postreload (rtx, rtx, rtx);
@@ -103,11 +104,20 @@
 static int
 xstormy16_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED)
 {
-  return (GET_CODE (x) == CONST_INT ? 2
+  return (CONST_INT_P (x) ? 2
 	  : GET_CODE (x) == PLUS ? 7
 	  : 5);
 }
 
+/* Worker function for TARGET_MEMORY_MOVE_COST.  */
+
+static int
+xstormy16_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
+			    bool in)
+{
+  return (5 + memory_move_secondary_cost (mode, rclass, in));
+}
+
 /* Branches are handled as follows:
 
    1. HImode compare-and-branches.  The machine supports these
@@ -291,7 +301,7 @@
 
   code = GET_CODE (op);
 
-  if (GET_CODE (XEXP (op, 0)) != REG)
+  if (! REG_P (XEXP (op, 0)))
     {
       code = swap_condition (code);
       operands = "%3,%2";
@@ -376,7 +386,7 @@
       {
 	int regnum;
 
-	gcc_assert (GET_CODE (XEXP (op, 0)) == REG);
+	gcc_assert (REG_P (XEXP (op, 0)));
 
 	regnum = REGNO (XEXP (op, 0));
 	sprintf (prevop, "or %s,%s", reg_names[regnum], reg_names[regnum+1]);
@@ -454,13 +464,13 @@
 
 enum reg_class
 xstormy16_secondary_reload_class (enum reg_class rclass,
-				  enum machine_mode mode,
+				  enum machine_mode mode ATTRIBUTE_UNUSED,
 				  rtx x)
 {
   /* This chip has the interesting property that only the first eight
      registers can be moved to/from memory.  */
-  if ((GET_CODE (x) == MEM
-       || ((GET_CODE (x) == SUBREG || GET_CODE (x) == REG)
+  if ((MEM_P (x)
+       || ((GET_CODE (x) == SUBREG || REG_P (x))
 	   && (true_regnum (x) == -1
 	       || true_regnum (x) >= FIRST_PSEUDO_REGISTER)))
       && ! reg_class_subset_p (rclass, EIGHT_REGS))
@@ -469,11 +479,13 @@
   return NO_REGS;
 }
 
-enum reg_class
-xstormy16_preferred_reload_class (rtx x, enum reg_class rclass)
+/* Worker function for TARGET_PREFERRED_RELOAD_CLASS
+   and TARGET_PREFERRED_OUTPUT_RELOAD_CLASS.  */
+
+static reg_class_t
+xstormy16_preferred_reload_class (rtx x, reg_class_t rclass)
 {
-  if (rclass == GENERAL_REGS
-      && GET_CODE (x) == MEM)
+  if (rclass == GENERAL_REGS && MEM_P (x))
     return EIGHT_REGS;
 
   return rclass;
@@ -488,16 +500,16 @@
 {
   if (GET_CODE (x) == CONST)
     x = XEXP (x, 0);
-  if (GET_CODE (x) == PLUS
-      && GET_CODE (XEXP (x, 1)) == CONST_INT)
+  if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)))
     x = XEXP (x, 0);
 
   if (GET_CODE (x) == SYMBOL_REF)
     return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_XSTORMY16_BELOW100) != 0;
 
-  if (GET_CODE (x) == CONST_INT)
+  if (CONST_INT_P (x))
     {
       HOST_WIDE_INT i = INTVAL (x);
+
       if ((i >= 0x0000 && i <= 0x00ff)
 	  || (i >= 0x7f00 && i <= 0x7fff))
 	return 1;
@@ -511,7 +523,7 @@
 int
 xstormy16_splittable_below100_operand (rtx x, enum machine_mode mode)
 {
-  if (GET_CODE (x) == MEM && MEM_VOLATILE_P (x))
+  if (MEM_P (x) && MEM_VOLATILE_P (x))
     return 0;
   return xstormy16_below100_operand (x, mode);
 }
@@ -540,17 +552,19 @@
       return;
     }
 
-  if (GET_CODE (in) != REG)
+  if (! REG_P (in))
     in = copy_to_mode_reg (QImode, in);
-  if (GET_CODE (val) != REG
-      && GET_CODE (val) != CONST_INT)
+
+  if (! REG_P (val) && ! CONST_INT_P (val))
     val = copy_to_mode_reg (QImode, val);
-  if (GET_CODE (out) != REG)
+
+  if (! REG_P (out))
     out = gen_reg_rtx (QImode);
 
   in = simplify_gen_subreg (HImode, in, QImode, 0);
   outsub = simplify_gen_subreg (HImode, out, QImode, 0);
-  if (GET_CODE (val) != CONST_INT)
+
+  if (! CONST_INT_P (val))
     val = simplify_gen_subreg (HImode, val, QImode, 0);
 
   emit_insn (gen_iorhi3 (outsub, in, val));
@@ -583,17 +597,19 @@
       return;
     }
 
-  if (GET_CODE (in) != REG)
+  if (! REG_P (in))
     in = copy_to_mode_reg (QImode, in);
-  if (GET_CODE (val) != REG
-      && GET_CODE (val) != CONST_INT)
+
+  if (! REG_P (val) && ! CONST_INT_P (val))
     val = copy_to_mode_reg (QImode, val);
-  if (GET_CODE (out) != REG)
+
+  if (! REG_P (out))
     out = gen_reg_rtx (QImode);
 
   in = simplify_gen_subreg (HImode, in, QImode, 0);
   outsub = simplify_gen_subreg (HImode, out, QImode, 0);
-  if (GET_CODE (val) != CONST_INT)
+
+  if (! CONST_INT_P (val))
     val = simplify_gen_subreg (HImode, val, QImode, 0);
 
   emit_insn (gen_andhi3 (outsub, in, val));
@@ -603,137 +619,68 @@
 }
 
 #define LEGITIMATE_ADDRESS_INTEGER_P(X, OFFSET)				\
- (GET_CODE (X) == CONST_INT						\
+  (CONST_INT_P (X)							\
   && (unsigned HOST_WIDE_INT) (INTVAL (X) + (OFFSET) + 2048) < 4096)
 
 #define LEGITIMATE_ADDRESS_CONST_INT_P(X, OFFSET)			 \
- (GET_CODE (X) == CONST_INT						 \
+ (CONST_INT_P (X)							 \
   && INTVAL (X) + (OFFSET) >= 0						 \
   && INTVAL (X) + (OFFSET) < 0x8000					 \
   && (INTVAL (X) + (OFFSET) < 0x100 || INTVAL (X) + (OFFSET) >= 0x7F00))
 
-static bool
+bool
 xstormy16_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
 				rtx x, bool strict)
 {
   if (LEGITIMATE_ADDRESS_CONST_INT_P (x, 0))
-    return 1;
+    return true;
 
   if (GET_CODE (x) == PLUS
       && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (x, 1), 0))
     {
       x = XEXP (x, 0);
       /* PR 31232: Do not allow INT+INT as an address.  */
-      if (GET_CODE (x) == CONST_INT)
-	return 0;
+      if (CONST_INT_P (x))
+	return false;
     }
 
-  if ((GET_CODE (x) == PRE_MODIFY
-       && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT)
+  if ((GET_CODE (x) == PRE_MODIFY && CONST_INT_P (XEXP (XEXP (x, 1), 1)))
       || GET_CODE (x) == POST_INC
       || GET_CODE (x) == PRE_DEC)
     x = XEXP (x, 0);
 
-  if (GET_CODE (x) == REG && REGNO_OK_FOR_BASE_P (REGNO (x))
+  if (REG_P (x)
+      && REGNO_OK_FOR_BASE_P (REGNO (x))
       && (! strict || REGNO (x) < FIRST_PSEUDO_REGISTER))
-    return 1;
+    return true;
 
   if (xstormy16_below100_symbol (x, mode))
-    return 1;
-
-  return 0;
+    return true;
+
+  return false;
 }
 
-/* Return nonzero if memory address X (an RTX) can have different
-   meanings depending on the machine mode of the memory reference it
-   is used for or if the address is valid for some modes but not
-   others.
-
-   Autoincrement and autodecrement addresses typically have mode-dependent
-   effects because the amount of the increment or decrement is the size of the
-   operand being addressed.  Some machines have other mode-dependent addresses.
-   Many RISC machines have no mode-dependent addresses.
-
-   You may assume that ADDR is a valid address for the machine.
+/* Worker function for TARGET_MODE_DEPENDENT_ADDRESS_P.
 
    On this chip, this is true if the address is valid with an offset
    of 0 but not of 6, because in that case it cannot be used as an
    address for DImode or DFmode, or if the address is a post-increment
    or pre-decrement address.  */
 
-int
-xstormy16_mode_dependent_address_p (rtx x)
+static bool
+xstormy16_mode_dependent_address_p (const_rtx x)
 {
   if (LEGITIMATE_ADDRESS_CONST_INT_P (x, 0)
       && ! LEGITIMATE_ADDRESS_CONST_INT_P (x, 6))
-    return 1;
+    return true;
 
   if (GET_CODE (x) == PLUS
       && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (x, 1), 0)
       && ! LEGITIMATE_ADDRESS_INTEGER_P (XEXP (x, 1), 6))
-    return 1;
-
-  if (GET_CODE (x) == PLUS)
-    x = XEXP (x, 0);
+    return true;
 
   /* Auto-increment addresses are now treated generically in recog.c.  */
-  return 0;
-}
-
-/* A C expression that defines the optional machine-dependent constraint
-   letters (`Q', `R', `S', `T', `U') that can be used to segregate specific
-   types of operands, usually memory references, for the target machine.
-   Normally this macro will not be defined.  If it is required for a particular
-   target machine, it should return 1 if VALUE corresponds to the operand type
-   represented by the constraint letter C.  If C is not defined as an extra
-   constraint, the value returned should be 0 regardless of VALUE.  */
-
-int
-xstormy16_extra_constraint_p (rtx x, int c)
-{
-  switch (c)
-    {
-      /* 'Q' is for pushes.  */
-    case 'Q':
-      return (GET_CODE (x) == MEM
-	      && GET_CODE (XEXP (x, 0)) == POST_INC
-	      && XEXP (XEXP (x, 0), 0) == stack_pointer_rtx);
-
-      /* 'R' is for pops.  */
-    case 'R':
-      return (GET_CODE (x) == MEM
-	      && GET_CODE (XEXP (x, 0)) == PRE_DEC
-	      && XEXP (XEXP (x, 0), 0) == stack_pointer_rtx);
-
-      /* 'S' is for immediate memory addresses.  */
-    case 'S':
-      return (GET_CODE (x) == MEM
-	      && GET_CODE (XEXP (x, 0)) == CONST_INT
-	      && xstormy16_legitimate_address_p (VOIDmode, XEXP (x, 0), 0));
-
-      /* 'T' is for Rx.  */
-    case 'T':
-      /* Not implemented yet.  */
-      return 0;
-
-      /* 'U' is for CONST_INT values not between 2 and 15 inclusive,
-	 for allocating a scratch register for 32-bit shifts.  */
-    case 'U':
-      return (GET_CODE (x) == CONST_INT
-	      && (INTVAL (x) < 2 || INTVAL (x) > 15));
-
-      /* 'Z' is for CONST_INT value zero.  This is for adding zero to
-	 a register in addhi3, which would otherwise require a carry.  */
-    case 'Z':
-      return (GET_CODE (x) == CONST_INT
-	      && (INTVAL (x) == 0));
-
-    case 'W':
-      return xstormy16_below100_operand (x, GET_MODE (x));
-
-    default:
-      return 0;
-    }
+  return false;
 }
 
 int
@@ -769,7 +716,7 @@
 	      && general_operand (src, mode));
 
   /* This case is not supported below, and shouldn't be generated.  */
-  gcc_assert (GET_CODE (dest) != MEM || GET_CODE (src) != MEM);
+  gcc_assert (! MEM_P (dest) || ! MEM_P (src));
 
   /* This case is very very bad after reload, so trap it now.  */
   gcc_assert (GET_CODE (dest) != SUBREG && GET_CODE (src) != SUBREG);
@@ -784,7 +731,7 @@
      must be reversed.  */
   direction = 1;
 
-  if (GET_CODE (dest) == MEM)
+  if (MEM_P (dest))
     {
       mem_operand = XEXP (dest, 0);
       dest_modifies = side_effects_p (mem_operand);
@@ -797,7 +744,7 @@
 	  MEM_VOLATILE_P (dest) = 0;
 	}
     }
-  else if (GET_CODE (src) == MEM)
+  else if (MEM_P (src))
     {
       mem_operand = XEXP (src, 0);
       src_modifies = side_effects_p (mem_operand);
@@ -815,8 +762,8 @@
 
   if (mem_operand == NULL_RTX)
     {
-      if (GET_CODE (src) == REG
-	  && GET_CODE (dest) == REG
+      if (REG_P (src)
+	  && REG_P (dest)
 	  && reg_overlap_mentioned_p (dest, src)
 	  && REGNO (dest) > REGNO (src))
 	direction = -1;
@@ -825,12 +772,11 @@
       || (GET_CODE (mem_operand) == PLUS
 	  && GET_CODE (XEXP (mem_operand, 0)) == PRE_DEC))
     direction = -1;
-  else if (GET_CODE (src) == MEM
-	   && reg_overlap_mentioned_p (dest, src))
+  else if (MEM_P (src) && reg_overlap_mentioned_p (dest, src))
     {
       int regno;
 
-      gcc_assert (GET_CODE (dest) == REG);
+      gcc_assert (REG_P (dest));
       regno = REGNO (dest);
 
       gcc_assert (refers_to_regno_p (regno, regno + num_words,
@@ -886,7 +832,7 @@
 void
 xstormy16_expand_move (enum machine_mode mode, rtx dest, rtx src)
 {
-  if ((GET_CODE (dest) == MEM) && (GET_CODE (XEXP (dest, 0)) == PRE_MODIFY))
+  if (MEM_P (dest) && (GET_CODE (XEXP (dest, 0)) == PRE_MODIFY))
     {
       rtx pmv      = XEXP (dest, 0);
       rtx dest_reg = XEXP (pmv, 0);
@@ -897,7 +843,7 @@
       dest = gen_rtx_MEM (mode, dest_reg);
       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber)));
     }
-  else if ((GET_CODE (src) == MEM) && (GET_CODE (XEXP (src, 0)) == PRE_MODIFY))
+  else if (MEM_P (src) && (GET_CODE (XEXP (src, 0)) == PRE_MODIFY))
     {
       rtx pmv     = XEXP (src, 0);
       rtx src_reg = XEXP (pmv, 0);
@@ -912,11 +858,11 @@
   /* There are only limited immediate-to-memory move instructions.  */
   if (! reload_in_progress
       && ! reload_completed
-      && GET_CODE (dest) == MEM
-      && (GET_CODE (XEXP (dest, 0)) != CONST_INT
+      && MEM_P (dest)
+      && (! CONST_INT_P (XEXP (dest, 0))
 	  || ! xstormy16_legitimate_address_p (mode, XEXP (dest, 0), 0))
       && ! xstormy16_below100_operand (dest, mode)
-      && GET_CODE (src) != REG
+      && ! REG_P (src)
       && GET_CODE (src) != SUBREG)
     src = copy_to_mode_reg (mode, src);
 
@@ -1108,9 +1054,7 @@
 	XVECEXP (dwarf, 0, 1) = gen_rtx_SET (Pmode, stack_pointer_rtx,
 					     plus_constant (stack_pointer_rtx,
 							    GET_MODE_SIZE (Pmode)));
-	REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
-					      dwarf,
-					      REG_NOTES (insn));
+	add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
 	RTX_FRAME_RELATED_P (XVECEXP (dwarf, 0, 0)) = 1;
 	RTX_FRAME_RELATED_P (XVECEXP (dwarf, 0, 1)) = 1;
       }
@@ -1133,9 +1077,7 @@
 	XVECEXP (dwarf, 0, 1) = gen_rtx_SET (Pmode, stack_pointer_rtx,
 					     plus_constant (stack_pointer_rtx,
 							    GET_MODE_SIZE (Pmode)));
-	REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
-					      dwarf,
-					      REG_NOTES (insn));
+	add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
 	RTX_FRAME_RELATED_P (XVECEXP (dwarf, 0, 0)) = 1;
 	RTX_FRAME_RELATED_P (XVECEXP (dwarf, 0, 1)) = 1;
       }
@@ -1178,7 +1120,8 @@
 direct_return (void)
 {
   return (reload_completed
-	  && xstormy16_compute_stack_layout ().frame_size == 0);
+	  && xstormy16_compute_stack_layout ().frame_size == 0
+	  && ! xstormy16_interrupt_function_p ());
 }
 
 /* Called after register allocation to add any instructions needed for
@@ -1193,7 +1136,7 @@
 xstormy16_expand_epilogue (void)
 {
   struct xstormy16_stack_layout layout;
-  rtx mem_pop_rtx, insn;
+  rtx mem_pop_rtx;
   int regno;
   const int ifun = xstormy16_interrupt_function_p ();
 
@@ -1246,11 +1189,10 @@
   sorry ("function_profiler support");
 }
 
-/* Return an updated summarizer variable CUM to advance past an
-   argument in the argument list.  The values MODE, TYPE and NAMED
-   describe that argument.  Once this is done, the variable CUM is
-   suitable for analyzing the *following* argument with
-   `FUNCTION_ARG', etc.
+/* Update CUM to advance past an argument in the argument list.  The
+   values MODE, TYPE and NAMED describe that argument.  Once this is
+   done, the variable CUM is suitable for analyzing the *following*
+   argument with `TARGET_FUNCTION_ARG', etc.
 
    This function need not do anything if the argument in question was
    passed on the stack.  The compiler knows how to track the amount of
@@ -1258,32 +1200,30 @@
    it makes life easier for xstormy16_build_va_list if it does update
    the word count.  */
 
-CUMULATIVE_ARGS
-xstormy16_function_arg_advance (CUMULATIVE_ARGS cum, enum machine_mode mode,
-				tree type, int named ATTRIBUTE_UNUSED)
+static void
+xstormy16_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+				const_tree type, bool named ATTRIBUTE_UNUSED)
 {
   /* If an argument would otherwise be passed partially in registers,
      and partially on the stack, the whole of it is passed on the
      stack.  */
-  if (cum < NUM_ARGUMENT_REGISTERS
-      && cum + XSTORMY16_WORD_SIZE (type, mode) > NUM_ARGUMENT_REGISTERS)
-    cum = NUM_ARGUMENT_REGISTERS;
-
-  cum += XSTORMY16_WORD_SIZE (type, mode);
-
-  return cum;
+  if (*cum < NUM_ARGUMENT_REGISTERS
+      && *cum + XSTORMY16_WORD_SIZE (type, mode) > NUM_ARGUMENT_REGISTERS)
+    *cum = NUM_ARGUMENT_REGISTERS;
+
+  *cum += XSTORMY16_WORD_SIZE (type, mode);
 }
 
-rtx
-xstormy16_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode,
-			tree type, int named ATTRIBUTE_UNUSED)
+static rtx
+xstormy16_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+			const_tree type, bool named ATTRIBUTE_UNUSED)
 {
   if (mode == VOIDmode)
     return const0_rtx;
   if (targetm.calls.must_pass_in_stack (mode, type)
-      || cum + XSTORMY16_WORD_SIZE (type, mode) > NUM_ARGUMENT_REGISTERS)
+      || *cum + XSTORMY16_WORD_SIZE (type, mode) > NUM_ARGUMENT_REGISTERS)
     return NULL_RTX;
-  return gen_rtx_REG (mode, cum + 2);
+  return gen_rtx_REG (mode, *cum + FIRST_ARGUMENT_REGISTER);
 }
 
 /* Build the va_list type.
@@ -1313,10 +1253,10 @@
   DECL_FIELD_CONTEXT (f_1) = record;
   DECL_FIELD_CONTEXT (f_2) = record;
 
-  TREE_CHAIN (record) = type_decl;
+  TYPE_STUB_DECL (record) = type_decl;
   TYPE_NAME (record) = type_decl;
   TYPE_FIELDS (record) = f_1;
-  TREE_CHAIN (f_1) = f_2;
+  DECL_CHAIN (f_1) = f_2;
 
   layout_type (record);
 
@@ -1339,7 +1279,7 @@
     error ("cannot use va_start in interrupt function");
 
   f_base = TYPE_FIELDS (va_list_type_node);
-  f_count = TREE_CHAIN (f_base);
+  f_count = DECL_CHAIN (f_base);
 
   base = build3 (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base, NULL_TREE);
   count = build3 (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count,
@@ -1376,7 +1316,7 @@
   tree size_tree;
 
   f_base = TYPE_FIELDS (va_list_type_node);
-  f_count = TREE_CHAIN (f_base);
+  f_count = DECL_CHAIN (f_base);
 
   base = build3 (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base, NULL_TREE);
   count = build3 (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count,
@@ -1489,10 +1429,12 @@
   emit_move_insn (reg_addr_mem, reg_fnaddr);
 }
 
-/* Worker function for FUNCTION_VALUE.  */
-
-rtx
-xstormy16_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
+/* Worker function for TARGET_FUNCTION_VALUE.  */
+
+static rtx
+xstormy16_function_value (const_tree valtype,
+			  const_tree func ATTRIBUTE_UNUSED,
+			  bool outgoing ATTRIBUTE_UNUSED)
 {
   enum machine_mode mode;
   mode = TYPE_MODE (valtype);
@@ -1500,6 +1442,23 @@
   return gen_rtx_REG (mode, RETURN_VALUE_REGNUM);
 }
 
+/* Worker function for TARGET_LIBCALL_VALUE.  */
+
+static rtx
+xstormy16_libcall_value (enum machine_mode mode,
+			 const_rtx fun ATTRIBUTE_UNUSED)
+{
+  return gen_rtx_REG (mode, RETURN_VALUE_REGNUM);
+}
+
+/* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.  */
+
+static bool
+xstormy16_function_value_regno_p (const unsigned int regno)
+{
+  return (regno == RETURN_VALUE_REGNUM);
+}
+
 /* A C compound statement that outputs the assembler code for a thunk function,
    used to implement C++ virtual function calls with multiple inheritance.  The
    thunk acts as a wrapper around a virtual function, adjusting the implicit
@@ -1564,7 +1523,7 @@
   rtx symbol;
 
   if (mem != NULL_RTX
-      && GET_CODE (mem) == MEM
+      && MEM_P (mem)
       && GET_CODE (symbol = XEXP (mem, 0)) == SYMBOL_REF
       && SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_XSTORMY16_BELOW100)
     {
@@ -1683,22 +1642,24 @@
   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
 }
 
-/* Print a memory address as an operand to reference that memory location.  */
-
-void
+/* Worker function for TARGET_PRINT_OPERAND_ADDRESS.
+
+   Print a memory address as an operand to reference that memory location.  */
+
+static void
 xstormy16_print_operand_address (FILE *file, rtx address)
 {
   HOST_WIDE_INT offset;
   int pre_dec, post_inc;
 
   /* There are a few easy cases.  */
-  if (GET_CODE (address) == CONST_INT)
+  if (CONST_INT_P (address))
     {
       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (address) & 0xFFFF);
       return;
     }
 
-  if (CONSTANT_P (address) || GET_CODE (address) == CODE_LABEL)
+  if (CONSTANT_P (address) || LABEL_P (address))
     {
       output_addr_const (file, address);
       return;
@@ -1708,7 +1669,7 @@
      (plus:HI (pre_dec:HI (reg:HI ...)) (const_int ...)).  */
   if (GET_CODE (address) == PLUS)
     {
-      gcc_assert (GET_CODE (XEXP (address, 1)) == CONST_INT);
+      gcc_assert (CONST_INT_P (XEXP (address, 1)));
       offset = INTVAL (XEXP (address, 1));
       address = XEXP (address, 0);
     }
@@ -1720,7 +1681,7 @@
   if (pre_dec || post_inc)
     address = XEXP (address, 0);
 
-  gcc_assert (GET_CODE (address) == REG);
+  gcc_assert (REG_P (address));
 
   fputc ('(', file);
   if (pre_dec)
@@ -1733,9 +1694,11 @@
   fputc (')', file);
 }
 
-/* Print an operand to an assembler instruction.  */
-
-void
+/* Worker function for TARGET_PRINT_OPERAND.
+
+   Print an operand to an assembler instruction.  */
+
+static void
 xstormy16_print_operand (FILE *file, rtx x, int code)
 {
   switch (code)
@@ -1748,7 +1711,7 @@
 	HOST_WIDE_INT xx = 1;
 	HOST_WIDE_INT l;
 
-	if (GET_CODE (x) == CONST_INT)
+	if (CONST_INT_P (x))
 	  xx = INTVAL (x);
 	else
 	  output_operand_lossage ("'B' operand is not constant");
@@ -1788,7 +1751,7 @@
       /* Print the symbol without a surrounding @fptr().  */
       if (GET_CODE (x) == SYMBOL_REF)
 	assemble_name (file, XSTR (x, 0));
-      else if (GET_CODE (x) == LABEL_REF)
+      else if (LABEL_P (x))
 	output_asm_label (x);
       else
 	xstormy16_print_operand_address (file, x);
@@ -1801,7 +1764,7 @@
       {
 	HOST_WIDE_INT xx = 0;
 
-	if (GET_CODE (x) == CONST_INT)
+	if (CONST_INT_P (x))
 	  xx = INTVAL (x);
 	else
 	  output_operand_lossage ("'o' operand is not constant");
@@ -1819,7 +1782,7 @@
 	HOST_WIDE_INT xx = 1;
 	HOST_WIDE_INT l;
 
-	if (GET_CODE (x) == CONST_INT)
+	if (CONST_INT_P (x))
 	  xx = INTVAL (x);
 	else
 	  output_operand_lossage ("'B' operand is not constant");
@@ -1917,13 +1880,9 @@
 }
 
 /* Expander for the `call' patterns.
-   INDEX is the index of the switch statement.
-   LOWER_BOUND is a CONST_INT that is the value of INDEX corresponding
-     to the first table entry.
-   RANGE is the number of table entries.
-   TABLE is an ADDR_VEC that is the jump table.
-   DEFAULT_LABEL is the address to branch to if INDEX is outside the
-     range LOWER_BOUND to LOWER_BOUND + RANGE - 1.  */
+   RETVAL is the RTL for the return register or NULL for void functions.
+   DEST is the function to call, expressed as a MEM.
+   COUNTER is ignored.  */
 
 void
 xstormy16_expand_call (rtx retval, rtx dest, rtx counter)
@@ -1931,11 +1890,10 @@
   rtx call, temp;
   enum machine_mode mode;
 
-  gcc_assert (GET_CODE (dest) == MEM);
+  gcc_assert (MEM_P (dest));
   dest = XEXP (dest, 0);
 
-  if (! CONSTANT_P (dest)
-      && GET_CODE (dest) != REG)
+  if (! CONSTANT_P (dest) && ! REG_P (dest))
     dest = force_reg (Pmode, dest);
 
   if (retval == NULL)
@@ -1995,7 +1953,8 @@
 	{
 	case PLUS:
 	  if (firstloop
-	      && GET_CODE (w_src1) == CONST_INT && INTVAL (w_src1) == 0)
+	      && CONST_INT_P (w_src1)
+	      && INTVAL (w_src1) == 0)
 	    continue;
 
 	  if (firstloop)
@@ -2028,7 +1987,8 @@
 	    }
 	  else if (firstloop
 		   && code != COMPARE
-		   && GET_CODE (w_src1) == CONST_INT && INTVAL (w_src1) == 0)
+		   && CONST_INT_P (w_src1)
+		   && INTVAL (w_src1) == 0)
 	    continue;
 	  else if (firstloop)
 	    insn = gen_subchi4 (w_dest, w_src0, w_src1);
@@ -2039,7 +1999,7 @@
 	case IOR:
 	case XOR:
 	case AND:
-	  if (GET_CODE (w_src1) == CONST_INT
+	  if (CONST_INT_P (w_src1)
 	      && INTVAL (w_src1) == -(code == AND))
 	    continue;
 
@@ -2079,8 +2039,10 @@
   const char *r0, *r1, *rt;
   static char r[64];
 
-  gcc_assert (GET_CODE (size_r) == CONST_INT
-	      && GET_CODE (x) == REG && mode == SImode);
+  gcc_assert (CONST_INT_P (size_r)
+	      && REG_P (x)
+	      && mode == SImode);
+
   size = INTVAL (size_r) & (GET_MODE_BITSIZE (mode) - 1);
 
   if (size == 0)
@@ -2335,7 +2297,7 @@
 
   for (a = 0; a < 10 && argtree; a++)
     {
-      args[a] = expand_expr (TREE_VALUE (argtree), NULL_RTX, VOIDmode, 0);
+      args[a] = expand_normal (TREE_VALUE (argtree));
       argtree = TREE_CHAIN (argtree);
     }
 
@@ -2343,11 +2305,11 @@
     {
       char ao = s16builtins[i].arg_ops[o];
       char c = insn_data[code].operand[o].constraint[0];
-      int omode;
+      enum machine_mode omode;
 
       copyto[o] = 0;
 
-      omode = insn_data[code].operand[o].mode;
+      omode = (enum machine_mode) insn_data[code].operand[o].mode;
       if (ao == 'r')
 	op[o] = target ? target : gen_reg_rtx (omode);
       else if (ao == 't')
@@ -2394,7 +2356,7 @@
 {
   int insn_code, regno, need_extend;
   unsigned int mask;
-  rtx cond, reg, and, load, qireg, mem;
+  rtx cond, reg, and_insn, load, qireg, mem;
   enum machine_mode load_mode = QImode;
   enum machine_mode and_mode = QImode;
   rtx shift = NULL_RTX;
@@ -2422,7 +2384,7 @@
     }
 
   reg = XEXP (cond, 0);
-  if (GET_CODE (reg) != REG)
+  if (! REG_P (reg))
     return;
   regno = REGNO (reg);
   if (XEXP (cond, 1) != const0_rtx)
@@ -2435,50 +2397,52 @@
     {
       /* LT and GE conditionals should have a sign extend before
 	 them.  */
-      for (and = prev_real_insn (insn); and; and = prev_real_insn (and))
+      for (and_insn = prev_real_insn (insn); and_insn;
+	   and_insn = prev_real_insn (and_insn))
 	{
-	  int and_code = recog_memoized (and);
+	  int and_code = recog_memoized (and_insn);
 
 	  if (and_code == CODE_FOR_extendqihi2
-	      && rtx_equal_p (SET_DEST (PATTERN (and)), reg)
-	      && rtx_equal_p (XEXP (SET_SRC (PATTERN (and)), 0), qireg))
+	      && rtx_equal_p (SET_DEST (PATTERN (and_insn)), reg)
+	      && rtx_equal_p (XEXP (SET_SRC (PATTERN (and_insn)), 0), qireg))
 	    break;
 
 	  if (and_code == CODE_FOR_movhi_internal
-	      && rtx_equal_p (SET_DEST (PATTERN (and)), reg))
+	      && rtx_equal_p (SET_DEST (PATTERN (and_insn)), reg))
 	    {
 	      /* This is for testing bit 15.  */
-	      and = insn;
+	      and_insn = insn;
 	      break;
 	    }
 
-	  if (reg_mentioned_p (reg, and))
+	  if (reg_mentioned_p (reg, and_insn))
 	    return;
 
-	  if (GET_CODE (and) != NOTE
-	      && GET_CODE (and) != INSN)
+	  if (GET_CODE (and_insn) != NOTE
+	      && GET_CODE (and_insn) != INSN)
 	    return;
 	}
     }
   else
     {
       /* EQ and NE conditionals have an AND before them.  */
-      for (and = prev_real_insn (insn); and; and = prev_real_insn (and))
+      for (and_insn = prev_real_insn (insn); and_insn;
+	   and_insn = prev_real_insn (and_insn))
 	{
-	  if (recog_memoized (and) == CODE_FOR_andhi3
-	      && rtx_equal_p (SET_DEST (PATTERN (and)), reg)
-	      && rtx_equal_p (XEXP (SET_SRC (PATTERN (and)), 0), reg))
+	  if (recog_memoized (and_insn) == CODE_FOR_andhi3
+	      && rtx_equal_p (SET_DEST (PATTERN (and_insn)), reg)
+	      && rtx_equal_p (XEXP (SET_SRC (PATTERN (and_insn)), 0), reg))
 	    break;
 
-	  if (reg_mentioned_p (reg, and))
+	  if (reg_mentioned_p (reg, and_insn))
 	    return;
 
-	  if (GET_CODE (and) != NOTE
-	      && GET_CODE (and) != INSN)
+	  if (GET_CODE (and_insn) != NOTE
+	      && GET_CODE (and_insn) != INSN)
 	    return;
 	}
 
-      if (and)
+      if (and_insn)
 	{
 	  /* Some mis-optimizations by GCC can generate a RIGHT-SHIFT
 	     followed by an AND like this:
@@ -2489,7 +2453,8 @@
                (set (reg:HI r7) (and:HI (reg:HI r7) (const_int 1)))
 
 	     Attempt to detect this here.  */
-	  for (shift = prev_real_insn (and); shift; shift = prev_real_insn (shift))
+	  for (shift = prev_real_insn (and_insn); shift;
+	       shift = prev_real_insn (shift))
 	    {
 	      if (recog_memoized (shift) == CODE_FOR_lshrhi3
 		  && rtx_equal_p (SET_DEST (XVECEXP (PATTERN (shift), 0, 0)), reg)
@@ -2506,10 +2471,10 @@
 	    }
 	}
     }
-  if (!and)
+  if (!and_insn)
     return;
 
-  for (load = shift ? prev_real_insn (shift) : prev_real_insn (and);
+  for (load = shift ? prev_real_insn (shift) : prev_real_insn (and_insn);
        load;
        load = prev_real_insn (load))
     {
@@ -2565,10 +2530,11 @@
     }
   else
     {
-      if (!xstormy16_onebit_set_operand (XEXP (SET_SRC (PATTERN (and)), 1), load_mode))
+      if (!xstormy16_onebit_set_operand (XEXP (SET_SRC (PATTERN (and_insn)), 1),
+					 load_mode))
 	return;
 
-      mask = (int) INTVAL (XEXP (SET_SRC (PATTERN (and)), 1));
+      mask = (int) INTVAL (XEXP (SET_SRC (PATTERN (and_insn)), 1));
 
       if (shift)
 	mask <<= INTVAL (XEXP (SET_SRC (XVECEXP (PATTERN (shift), 0, 0)), 1));
@@ -2594,8 +2560,8 @@
   INSN_CODE (insn) = -1;
   delete_insn (load);
 
-  if (and != insn)
-    delete_insn (and);
+  if (and_insn != insn)
+    delete_insn (and_insn);
 
   if (shift != NULL_RTX)
     delete_insn (shift);
@@ -2623,6 +2589,13 @@
   return (size == -1 || size > UNITS_PER_WORD * NUM_ARGUMENT_REGISTERS);
 }
 
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options xstorym16_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 #undef  TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
 #undef  TARGET_ASM_ALIGNED_SI_OP
@@ -2639,6 +2612,13 @@
 #undef  TARGET_ASM_CAN_OUTPUT_MI_THUNK
 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
 
+#undef  TARGET_PRINT_OPERAND
+#define TARGET_PRINT_OPERAND xstormy16_print_operand
+#undef  TARGET_PRINT_OPERAND_ADDRESS
+#define TARGET_PRINT_OPERAND_ADDRESS xstormy16_print_operand_address
+
+#undef  TARGET_MEMORY_MOVE_COST
+#define TARGET_MEMORY_MOVE_COST xstormy16_memory_move_cost
 #undef  TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS xstormy16_rtx_costs
 #undef  TARGET_ADDRESS_COST
@@ -2656,14 +2636,32 @@
 #undef  TARGET_PROMOTE_PROTOTYPES
 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
 
+#undef  TARGET_FUNCTION_ARG
+#define TARGET_FUNCTION_ARG xstormy16_function_arg
+#undef  TARGET_FUNCTION_ARG_ADVANCE
+#define TARGET_FUNCTION_ARG_ADVANCE xstormy16_function_arg_advance
+
 #undef  TARGET_RETURN_IN_MEMORY
 #define TARGET_RETURN_IN_MEMORY xstormy16_return_in_memory
+#undef TARGET_FUNCTION_VALUE
+#define TARGET_FUNCTION_VALUE xstormy16_function_value
+#undef TARGET_LIBCALL_VALUE
+#define TARGET_LIBCALL_VALUE xstormy16_libcall_value
+#undef TARGET_FUNCTION_VALUE_REGNO_P
+#define TARGET_FUNCTION_VALUE_REGNO_P xstormy16_function_value_regno_p
 
 #undef  TARGET_MACHINE_DEPENDENT_REORG
 #define TARGET_MACHINE_DEPENDENT_REORG xstormy16_reorg
 
+#undef  TARGET_PREFERRED_RELOAD_CLASS
+#define TARGET_PREFERRED_RELOAD_CLASS xstormy16_preferred_reload_class
+#undef  TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
+#define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS xstormy16_preferred_reload_class
+
 #undef TARGET_LEGITIMATE_ADDRESS_P
 #define TARGET_LEGITIMATE_ADDRESS_P	xstormy16_legitimate_address_p
+#undef TARGET_MODE_DEPENDENT_ADDRESS_P
+#define TARGET_MODE_DEPENDENT_ADDRESS_P xstormy16_mode_dependent_address_p
 
 #undef TARGET_CAN_ELIMINATE
 #define TARGET_CAN_ELIMINATE xstormy16_can_eliminate
@@ -2671,6 +2669,9 @@
 #undef TARGET_TRAMPOLINE_INIT
 #define TARGET_TRAMPOLINE_INIT xstormy16_trampoline_init
 
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE xstorym16_option_optimization_table
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-stormy16.h"