diff gcc/config/iq2000/iq2000.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
line wrap: on
line diff
--- a/gcc/config/iq2000/iq2000.c	Sun Aug 21 07:07:55 2011 +0900
+++ b/gcc/config/iq2000/iq2000.c	Fri Oct 27 22:46:09 2017 +0900
@@ -1,6 +1,5 @@
 /* Subroutines used for code generation on Vitesse IQ2000 processors
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -21,30 +20,32 @@
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
+#include "backend.h"
+#include "target.h"
+#include "rtl.h"
 #include "tree.h"
-#include "rtl.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "df.h"
+#include "memmodel.h"
+#include "tm_p.h"
+#include "optabs.h"
 #include "regs.h"
-#include "hard-reg-set.h"
-#include "insn-config.h"
-#include "conditions.h"
+#include "emit-rtl.h"
+#include "recog.h"
+#include "diagnostic-core.h"
+#include "stor-layout.h"
+#include "calls.h"
+#include "varasm.h"
 #include "output.h"
 #include "insn-attr.h"
-#include "flags.h"
-#include "function.h"
+#include "explow.h"
 #include "expr.h"
-#include "optabs.h"
-#include "libfuncs.h"
-#include "recog.h"
-#include "diagnostic-core.h"
-#include "reload.h"
-#include "ggc.h"
-#include "tm_p.h"
-#include "debug.h"
-#include "target.h"
+#include "langhooks.h"
+#include "builtins.h"
+
+/* This file should be included last.  */
 #include "target-def.h"
-#include "langhooks.h"
-#include "df.h"
 
 /* Enumeration for all of the relational tests, so that we can build
    arrays indexed by the test type, and not worry about the order
@@ -111,9 +112,6 @@
 /* List of all IQ2000 punctuation characters used by iq2000_print_operand.  */
 static char iq2000_print_operand_punct[256];
 
-/* The target cpu for optimization and scheduling.  */
-enum processor_type iq2000_tune;
-
 /* Which instruction set architecture to use.  */
 int iq2000_isa;
 
@@ -140,52 +138,50 @@
 static rtx iq2000_load_reg4;
 
 /* Mode used for saving/restoring general purpose registers.  */
-static enum machine_mode gpr_mode;
+static machine_mode gpr_mode;
 
 
 /* Initialize the GCC target structure.  */
 static struct machine_function* iq2000_init_machine_status (void);
-static bool iq2000_handle_option      (size_t, const char *, int);
 static void iq2000_option_override    (void);
-static section *iq2000_select_rtx_section (enum machine_mode, rtx,
+static section *iq2000_select_rtx_section (machine_mode, rtx,
 					   unsigned HOST_WIDE_INT);
 static void iq2000_init_builtins      (void);
-static rtx  iq2000_expand_builtin     (tree, rtx, rtx, enum machine_mode, int);
+static rtx  iq2000_expand_builtin     (tree, rtx, rtx, machine_mode, int);
 static bool iq2000_return_in_memory   (const_tree, const_tree);
-static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *,
-					   enum machine_mode, tree, int *,
+static void iq2000_setup_incoming_varargs (cumulative_args_t,
+					   machine_mode, tree, int *,
 					   int);
-static bool iq2000_rtx_costs          (rtx, int, int, int *, bool);
-static int  iq2000_address_cost       (rtx, bool);
+static bool iq2000_rtx_costs          (rtx, machine_mode, int, int, int *, bool);
+static int  iq2000_address_cost       (rtx, machine_mode, addr_space_t,
+				       bool);
 static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
-static rtx  iq2000_legitimize_address (rtx, rtx, enum machine_mode);
-static bool iq2000_pass_by_reference  (CUMULATIVE_ARGS *, enum machine_mode,
+static rtx  iq2000_legitimize_address (rtx, rtx, machine_mode);
+static bool iq2000_pass_by_reference  (cumulative_args_t, machine_mode,
 				       const_tree, bool);
-static int  iq2000_arg_partial_bytes  (CUMULATIVE_ARGS *, enum machine_mode,
+static int  iq2000_arg_partial_bytes  (cumulative_args_t, machine_mode,
 				       tree, bool);
-static rtx iq2000_function_arg	      (CUMULATIVE_ARGS *,
-				       enum machine_mode, const_tree, bool);
-static void iq2000_function_arg_advance (CUMULATIVE_ARGS *,
-					 enum machine_mode, const_tree, bool);
-static unsigned int iq2000_function_arg_boundary (enum machine_mode,
+static rtx iq2000_function_arg	      (cumulative_args_t,
+				       machine_mode, const_tree, bool);
+static void iq2000_function_arg_advance (cumulative_args_t,
+					 machine_mode, const_tree, bool);
+static pad_direction iq2000_function_arg_padding (machine_mode, const_tree);
+static unsigned int iq2000_function_arg_boundary (machine_mode,
 						  const_tree);
 static void iq2000_va_start	      (tree, rtx);
-static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool);
+static bool iq2000_legitimate_address_p (machine_mode, rtx, bool);
 static bool iq2000_can_eliminate      (const int, const int);
 static void iq2000_asm_trampoline_template (FILE *);
 static void iq2000_trampoline_init    (rtx, tree, rtx);
 static rtx iq2000_function_value      (const_tree, const_tree, bool);
-static rtx iq2000_libcall_value       (enum machine_mode, const_rtx);
+static rtx iq2000_libcall_value       (machine_mode, const_rtx);
 static void iq2000_print_operand      (FILE *, rtx, int);
-static void iq2000_print_operand_address (FILE *, rtx);
+static void iq2000_print_operand_address (FILE *, machine_mode, rtx);
 static bool iq2000_print_operand_punct_valid_p (unsigned char code);
-
-/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
-static const struct default_options iq2000_option_optimization_table[] =
-  {
-    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
-    { OPT_LEVELS_NONE, 0, NULL, 0 }
-  };
+static bool iq2000_hard_regno_mode_ok (unsigned int, machine_mode);
+static bool iq2000_modes_tieable_p (machine_mode, machine_mode);
+static HOST_WIDE_INT iq2000_constant_alignment (const_tree, HOST_WIDE_INT);
+static HOST_WIDE_INT iq2000_starting_frame_offset (void);
 
 #undef  TARGET_INIT_BUILTINS
 #define TARGET_INIT_BUILTINS 		iq2000_init_builtins
@@ -193,12 +189,8 @@
 #define TARGET_EXPAND_BUILTIN 		iq2000_expand_builtin
 #undef  TARGET_ASM_SELECT_RTX_SECTION
 #define TARGET_ASM_SELECT_RTX_SECTION	iq2000_select_rtx_section
-#undef  TARGET_HANDLE_OPTION
-#define TARGET_HANDLE_OPTION		iq2000_handle_option
 #undef  TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE		iq2000_option_override
-#undef  TARGET_OPTION_OPTIMIZATION_TABLE
-#define TARGET_OPTION_OPTIMIZATION_TABLE iq2000_option_optimization_table
 #undef  TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS		iq2000_rtx_costs
 #undef  TARGET_ADDRESS_COST
@@ -242,6 +234,8 @@
 #define TARGET_FUNCTION_ARG		iq2000_function_arg
 #undef  TARGET_FUNCTION_ARG_ADVANCE
 #define TARGET_FUNCTION_ARG_ADVANCE	iq2000_function_arg_advance
+#undef  TARGET_FUNCTION_ARG_PADDING
+#define TARGET_FUNCTION_ARG_PADDING	iq2000_function_arg_padding
 #undef  TARGET_FUNCTION_ARG_BOUNDARY
 #define TARGET_FUNCTION_ARG_BOUNDARY	iq2000_function_arg_boundary
 
@@ -253,6 +247,9 @@
 #undef	TARGET_EXPAND_BUILTIN_VA_START
 #define	TARGET_EXPAND_BUILTIN_VA_START	iq2000_va_start
 
+#undef TARGET_LRA_P
+#define TARGET_LRA_P hook_bool_void_false
+
 #undef TARGET_LEGITIMATE_ADDRESS_P
 #define TARGET_LEGITIMATE_ADDRESS_P	iq2000_legitimate_address_p
 
@@ -264,12 +261,23 @@
 #undef  TARGET_TRAMPOLINE_INIT
 #define TARGET_TRAMPOLINE_INIT		iq2000_trampoline_init
 
+#undef  TARGET_HARD_REGNO_MODE_OK
+#define TARGET_HARD_REGNO_MODE_OK	iq2000_hard_regno_mode_ok
+#undef  TARGET_MODES_TIEABLE_P
+#define TARGET_MODES_TIEABLE_P		iq2000_modes_tieable_p
+
+#undef  TARGET_CONSTANT_ALIGNMENT
+#define TARGET_CONSTANT_ALIGNMENT	iq2000_constant_alignment
+
+#undef  TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET	iq2000_starting_frame_offset
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Return nonzero if we split the address into high and low parts.  */
 
 int
-iq2000_check_split (rtx address, enum machine_mode mode)
+iq2000_check_split (rtx address, machine_mode mode)
 {
   /* This is the same check used in simple_memory_operand.
      We use it here because LO_SUM is not offsettable.  */
@@ -289,7 +297,7 @@
 
 int
 iq2000_reg_mode_ok_for_base_p (rtx reg,
-			       enum machine_mode mode ATTRIBUTE_UNUSED,
+			       machine_mode mode ATTRIBUTE_UNUSED,
 			       int strict)
 {
   return (strict
@@ -302,7 +310,7 @@
    function is called during reload.  */
 
 bool
-iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, bool strict)
+iq2000_legitimate_address_p (machine_mode mode, rtx xinsn, bool strict)
 {
   if (TARGET_DEBUG_A_MODE)
     {
@@ -363,7 +371,7 @@
     }
 
   if (TARGET_DEBUG_A_MODE)
-    GO_PRINTF ("Not a enum machine_mode mode, legitimate address\n");
+    GO_PRINTF ("Not a machine_mode mode, legitimate address\n");
 
   /* The address was not legitimate.  */
   return 0;
@@ -380,11 +388,11 @@
 
 const char *
 iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[],
-			rtx cur_insn)
+			rtx_insn *cur_insn)
 {
   rtx set_reg;
-  enum machine_mode mode;
-  rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX;
+  machine_mode mode;
+  rtx_insn *next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL;
   int num_nops;
 
   if (type == DELAY_LOAD || type == DELAY_FCMP)
@@ -396,8 +404,7 @@
   /* Make sure that we don't put nop's after labels.  */
   next_insn = NEXT_INSN (cur_insn);
   while (next_insn != 0
-	 && (GET_CODE (next_insn) == NOTE
-	     || GET_CODE (next_insn) == CODE_LABEL))
+	 && (NOTE_P (next_insn) || LABEL_P (next_insn)))
     next_insn = NEXT_INSN (next_insn);
 
   dslots_load_total += num_nops;
@@ -406,7 +413,7 @@
       || operands == 0
       || cur_insn == 0
       || next_insn == 0
-      || GET_CODE (next_insn) == CODE_LABEL
+      || LABEL_P (next_insn)
       || (set_reg = operands[0]) == 0)
     {
       dslots_number_nops = 0;
@@ -564,14 +571,14 @@
 /* Return the appropriate instructions to move one operand to another.  */
 
 const char *
-iq2000_move_1word (rtx operands[], rtx insn, int unsignedp)
+iq2000_move_1word (rtx operands[], rtx_insn *insn, int unsignedp)
 {
   const char *ret = 0;
   rtx op0 = operands[0];
   rtx op1 = operands[1];
   enum rtx_code code0 = GET_CODE (op0);
   enum rtx_code code1 = GET_CODE (op1);
-  enum machine_mode mode = GET_MODE (op0);
+  machine_mode mode = GET_MODE (op0);
   int subreg_offset0 = 0;
   int subreg_offset1 = 0;
   enum delay_type delay = DELAY_NONE;
@@ -635,17 +642,17 @@
 		{
 		default:
 		  break;
-		case SFmode:
+		case E_SFmode:
 		  ret = "lw\t%0,%1";
 		  break;
-		case SImode:
-		case CCmode:
+		case E_SImode:
+		case E_CCmode:
 		  ret = "lw\t%0,%1";
 		  break;
-		case HImode:
+		case E_HImode:
 		  ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1";
 		  break;
-		case QImode:
+		case E_QImode:
 		  ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1";
 		  break;
 		}
@@ -745,10 +752,10 @@
 	    {
 	      switch (mode)
 		{
-		case SFmode: ret = "sw\t%1,%0"; break;
-		case SImode: ret = "sw\t%1,%0"; break;
-		case HImode: ret = "sh\t%1,%0"; break;
-		case QImode: ret = "sb\t%1,%0"; break;
+		case E_SFmode: ret = "sw\t%1,%0"; break;
+		case E_SImode: ret = "sw\t%1,%0"; break;
+		case E_HImode: ret = "sh\t%1,%0"; break;
+		case E_QImode: ret = "sb\t%1,%0"; break;
 		default: break;
 		}
 	    }
@@ -758,10 +765,10 @@
 	{
 	  switch (mode)
 	    {
-	    case SFmode: ret = "sw\t%z1,%0"; break;
-	    case SImode: ret = "sw\t%z1,%0"; break;
-	    case HImode: ret = "sh\t%z1,%0"; break;
-	    case QImode: ret = "sb\t%z1,%0"; break;
+	    case E_SFmode: ret = "sw\t%z1,%0"; break;
+	    case E_SImode: ret = "sw\t%z1,%0"; break;
+	    case E_HImode: ret = "sh\t%z1,%0"; break;
+	    case E_QImode: ret = "sb\t%z1,%0"; break;
 	    default: break;
 	    }
 	}
@@ -770,10 +777,10 @@
 	{
 	  switch (mode)
 	    {
-	    case SFmode: ret = "sw\t%.,%0"; break;
-	    case SImode: ret = "sw\t%.,%0"; break;
-	    case HImode: ret = "sh\t%.,%0"; break;
-	    case QImode: ret = "sb\t%.,%0"; break;
+	    case E_SFmode: ret = "sw\t%.,%0"; break;
+	    case E_SImode: ret = "sw\t%.,%0"; break;
+	    case E_HImode: ret = "sh\t%.,%0"; break;
+	    case E_QImode: ret = "sb\t%.,%0"; break;
 	    default: break;
 	    }
 	}
@@ -794,7 +801,8 @@
 /* Provide the costs of an addressing mode that contains ADDR.  */
 
 static int
-iq2000_address_cost (rtx addr, bool speed)
+iq2000_address_cost (rtx addr, machine_mode mode, addr_space_t as,
+		     bool speed)
 {
   switch (GET_CODE (addr))
     {
@@ -845,7 +853,7 @@
 	  case LABEL_REF:
 	  case HIGH:
 	  case LO_SUM:
-	    return iq2000_address_cost (plus1, speed) + 1;
+	    return iq2000_address_cost (plus1, mode, as, speed) + 1;
 
 	  default:
 	    break;
@@ -921,7 +929,7 @@
   };
 
   enum internal_test test;
-  enum machine_mode mode;
+  machine_mode mode;
   struct cmp_info *p_info;
   int branch_p;
   int eqne_p;
@@ -1055,7 +1063,7 @@
    The comparison operands are saved away by cmp{si,di,sf,df}.  */
 
 void
-gen_conditional_branch (rtx operands[], enum machine_mode mode)
+gen_conditional_branch (rtx operands[], machine_mode mode)
 {
   enum rtx_code test_code = GET_CODE (operands[0]);
   rtx cmp0 = operands[1];
@@ -1088,10 +1096,10 @@
       label1 = pc_rtx;
     }
 
-  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
+  emit_jump_insn (gen_rtx_SET (pc_rtx,
 			       gen_rtx_IF_THEN_ELSE (VOIDmode,
 						     gen_rtx_fmt_ee (test_code,
-								     mode,
+								     VOIDmode,
 								     cmp0, cmp1),
 						     label1, label2)));
 }
@@ -1119,8 +1127,8 @@
 	  tree ret_type = TREE_TYPE (fntype);
 
 	  fprintf (stderr, ", fntype code = %s, ret code = %s\n",
-		   tree_code_name[(int)TREE_CODE (fntype)],
-		   tree_code_name[(int)TREE_CODE (ret_type)]);
+		   get_tree_code_name (TREE_CODE (fntype)),
+		   get_tree_code_name (TREE_CODE (ret_type)));
 	}
     }
 
@@ -1144,23 +1152,25 @@
    position in CUM.  */
 
 static void
-iq2000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+iq2000_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
 			     const_tree type, bool named)
 {
+  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+
   if (TARGET_DEBUG_D_MODE)
     {
       fprintf (stderr,
 	       "function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, ",
 	       cum->gp_reg_found, cum->arg_number, cum->arg_words,
 	       GET_MODE_NAME (mode));
-      fprintf (stderr, "%p", CONST_CAST2 (void *, const_tree,  type));
+      fprintf (stderr, "%p", (const void *) type);
       fprintf (stderr, ", %d )\n\n", named);
     }
 
   cum->arg_number++;
   switch (mode)
     {
-    case VOIDmode:
+    case E_VOIDmode:
       break;
 
     default:
@@ -1172,37 +1182,37 @@
 			 / UNITS_PER_WORD);
       break;
 
-    case BLKmode:
+    case E_BLKmode:
       cum->gp_reg_found = 1;
       cum->arg_words += ((int_size_in_bytes (type) + UNITS_PER_WORD - 1)
 			 / UNITS_PER_WORD);
       break;
 
-    case SFmode:
+    case E_SFmode:
       cum->arg_words ++;
       if (! cum->gp_reg_found && cum->arg_number <= 2)
 	cum->fp_code += 1 << ((cum->arg_number - 1) * 2);
       break;
 
-    case DFmode:
+    case E_DFmode:
       cum->arg_words += 2;
       if (! cum->gp_reg_found && cum->arg_number <= 2)
 	cum->fp_code += 2 << ((cum->arg_number - 1) * 2);
       break;
 
-    case DImode:
+    case E_DImode:
       cum->gp_reg_found = 1;
       cum->arg_words += 2;
       break;
 
-    case TImode:
+    case E_TImode:
       cum->gp_reg_found = 1;
       cum->arg_words += 4;
       break;
 
-    case QImode:
-    case HImode:
-    case SImode:
+    case E_QImode:
+    case E_HImode:
+    case E_SImode:
       cum->gp_reg_found = 1;
       cum->arg_words ++;
       break;
@@ -1213,9 +1223,10 @@
    and type TYPE in CUM, or 0 if the argument is to be passed on the stack.  */
 
 static rtx
-iq2000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+iq2000_function_arg (cumulative_args_t cum_v, machine_mode mode,
 		     const_tree type, bool named)
 {
+  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   rtx ret;
   int regbase = -1;
   int bias = 0;
@@ -1239,11 +1250,11 @@
   cum->last_arg_fp = 0;
   switch (mode)
     {
-    case SFmode:
+    case E_SFmode:
       regbase = GP_ARG_FIRST;
       break;
 
-    case DFmode:
+    case E_DFmode:
       cum->arg_words += cum->arg_words & 1;
 
       regbase = GP_ARG_FIRST;
@@ -1253,26 +1264,26 @@
       gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
 		  || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
 
-      /* Drops through.  */
-    case BLKmode:
+      /* FALLTHRU */
+    case E_BLKmode:
       if (type != NULL_TREE && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD)
 	cum->arg_words += (cum->arg_words & 1);
       regbase = GP_ARG_FIRST;
       break;
 
-    case VOIDmode:
-    case QImode:
-    case HImode:
-    case SImode:
+    case E_VOIDmode:
+    case E_QImode:
+    case E_HImode:
+    case E_SImode:
       regbase = GP_ARG_FIRST;
       break;
 
-    case DImode:
+    case E_DImode:
       cum->arg_words += (cum->arg_words & 1);
       regbase = GP_ARG_FIRST;
       break;
 
-    case TImode:
+    case E_TImode:
       cum->arg_words += (cum->arg_words & 3);
       regbase = GP_ARG_FIRST;
       break;
@@ -1291,7 +1302,7 @@
 
       if (! type || TREE_CODE (type) != RECORD_TYPE
 	  || ! named  || ! TYPE_SIZE_UNIT (type)
-	  || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
+	  || ! tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
 	ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
       else
 	{
@@ -1301,7 +1312,7 @@
 	    if (TREE_CODE (field) == FIELD_DECL
 		&& TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
 		&& TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
-		&& host_integerp (bit_position (field), 0)
+		&& tree_fits_shwi_p (bit_position (field))
 		&& int_bit_position (field) % BITS_PER_WORD == 0)
 	      break;
 
@@ -1319,7 +1330,7 @@
 	      /* ??? If this is a packed structure, then the last hunk won't
 		 be 64 bits.  */
 	      chunks
-		= tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
+		= tree_to_uhwi (TYPE_SIZE_UNIT (type)) / UNITS_PER_WORD;
 	      if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)
 		chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
 
@@ -1369,15 +1380,31 @@
   if (mode == VOIDmode)
     {
       if (cum->num_adjusts > 0)
-	ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
+	ret = gen_rtx_PARALLEL ((machine_mode) cum->fp_code,
 		       gen_rtvec_v (cum->num_adjusts, cum->adjust));
     }
 
   return ret;
 }
 
+/* Implement TARGET_FUNCTION_ARG_PADDING.  */
+
+static pad_direction
+iq2000_function_arg_padding (machine_mode mode, const_tree type)
+{
+  return (! BYTES_BIG_ENDIAN
+	  ? PAD_UPWARD
+	  : ((mode == BLKmode
+	      ? (type
+		 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
+		 && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
+	      : (GET_MODE_BITSIZE (mode) < PARM_BOUNDARY
+		 && GET_MODE_CLASS (mode) == MODE_INT))
+	     ? PAD_DOWNWARD : PAD_UPWARD));
+}
+
 static unsigned int
-iq2000_function_arg_boundary (enum machine_mode mode, const_tree type)
+iq2000_function_arg_boundary (machine_mode mode, const_tree type)
 {
   return (type != NULL_TREE
 	  ? (TYPE_ALIGN (type) <= PARM_BOUNDARY
@@ -1389,10 +1416,12 @@
 }
 
 static int
-iq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+iq2000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
 			  tree type ATTRIBUTE_UNUSED,
 			  bool named ATTRIBUTE_UNUSED)
 {
+  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+
   if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)
     {
       if (TARGET_DEBUG_D_MODE)
@@ -1422,7 +1451,7 @@
 
   /* Everything is in the GPR save area, or in the overflow
      area which is contiguous with it.  */
-  nextarg = plus_constant (nextarg, - gpr_save_area_size);
+  nextarg = plus_constant (Pmode, nextarg, - gpr_save_area_size);
   std_expand_builtin_va_start (valist, nextarg);
 }
 
@@ -1431,34 +1460,7 @@
 static struct machine_function *
 iq2000_init_machine_status (void)
 {
-  return ggc_alloc_cleared_machine_function ();
-}
-
-/* Implement TARGET_HANDLE_OPTION.  */
-
-static bool
-iq2000_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
-{
-  switch (code)
-    {
-    case OPT_mcpu_:
-      if (strcmp (arg, "iq10") == 0)
-	iq2000_tune = PROCESSOR_IQ10;
-      else if (strcmp (arg, "iq2000") == 0)
-	iq2000_tune = PROCESSOR_IQ2000;
-      else
-	return false;
-      return true;
-
-    case OPT_march_:
-      /* This option has no effect at the moment.  */
-      return (strcmp (arg, "default") == 0
-	      || strcmp (arg, "DEFAULT") == 0
-	      || strcmp (arg, "iq2000") == 0);
-
-    default:
-      return true;
-    }
+  return ggc_cleared_alloc<machine_function> ();
 }
 
 /* Detect any conflicts in the switches.  */
@@ -1540,7 +1542,7 @@
    of load delays, and also to update the delay slot statistics.  */
 
 void
-final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,
+final_prescan_insn (rtx_insn *insn, rtx opvec[] ATTRIBUTE_UNUSED,
 		    int noperands ATTRIBUTE_UNUSED)
 {
   if (dslots_number_nops > 0)
@@ -1569,18 +1571,23 @@
       iq2000_load_reg4 = 0;
     }
 
-  if (   (GET_CODE (insn) == JUMP_INSN
-       || GET_CODE (insn) == CALL_INSN
+  if (   (JUMP_P (insn)
+       || CALL_P (insn)
        || (GET_CODE (PATTERN (insn)) == RETURN))
 	   && NEXT_INSN (PREV_INSN (insn)) == insn)
     {
-      rtx nop_insn = emit_insn_after (gen_nop (), insn);
-
+      rtx_insn *tmp = insn;
+      while (NEXT_INSN (tmp)
+	     && NOTE_P (NEXT_INSN (tmp))
+	     && NOTE_KIND (NEXT_INSN (tmp)) == NOTE_INSN_CALL_ARG_LOCATION)
+	tmp = NEXT_INSN (tmp);
+
+      rtx_insn *nop_insn = emit_insn_after (gen_nop (), tmp);
       INSN_ADDRESSES_NEW (nop_insn, -1);
     }
   
   if (TARGET_STATS
-      && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))
+      && (JUMP_P (insn) || CALL_P (insn)))
     dslots_jump_total ++;
 }
 
@@ -1806,7 +1813,7 @@
    operation DWARF_PATTERN.  */
 
 static void
-iq2000_annotate_frame_insn (rtx insn, rtx dwarf_pattern)
+iq2000_annotate_frame_insn (rtx_insn *insn, rtx dwarf_pattern)
 {
   RTX_FRAME_RELATED_P (insn) = 1;
   REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
@@ -1820,11 +1827,11 @@
 static void
 iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset)
 {
-  rtx dwarf_address = plus_constant (stack_pointer_rtx, offset);
+  rtx dwarf_address = plus_constant (Pmode, stack_pointer_rtx, offset);
   rtx dwarf_mem = gen_rtx_MEM (GET_MODE (reg), dwarf_address);
 
   iq2000_annotate_frame_insn (emit_move_insn (mem, reg),
-			    gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg));
+			      gen_rtx_SET (dwarf_mem, reg));
 }
 
 /* Emit instructions to save/restore registers, as determined by STORE_P.  */
@@ -1921,7 +1928,8 @@
   int i;
   tree next_arg;
   tree cur_arg;
-  CUMULATIVE_ARGS args_so_far;
+  CUMULATIVE_ARGS args_so_far_v;
+  cumulative_args_t args_so_far;
   int store_args_on_stack = (iq2000_can_use_return_insn ());
 
   /* If struct value address is treated as the first argument.  */
@@ -1945,13 +1953,14 @@
      variable arguments.
 
      This is only needed if store_args_on_stack is true.  */
-  INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0, 0);
+  INIT_CUMULATIVE_ARGS (args_so_far_v, fntype, NULL_RTX, 0, 0);
+  args_so_far = pack_cumulative_args (&args_so_far_v);
   regno = GP_ARG_FIRST;
 
   for (cur_arg = fnargs; cur_arg != 0; cur_arg = next_arg)
     {
       tree passed_type = DECL_ARG_TYPE (cur_arg);
-      enum machine_mode passed_mode = TYPE_MODE (passed_type);
+      machine_mode passed_mode = TYPE_MODE (passed_type);
       rtx entry_parm;
 
       if (TREE_ADDRESSABLE (passed_type))
@@ -1960,10 +1969,10 @@
 	  passed_mode = Pmode;
 	}
 
-      entry_parm = iq2000_function_arg (&args_so_far, passed_mode,
+      entry_parm = iq2000_function_arg (args_so_far, passed_mode,
 					passed_type, true);
 
-      iq2000_function_arg_advance (&args_so_far, passed_mode,
+      iq2000_function_arg_advance (args_so_far, passed_mode,
 				   passed_type, true);
       next_arg = DECL_CHAIN (cur_arg);
 
@@ -2006,7 +2015,7 @@
      iq2000_unction_arg has encoded a PARALLEL rtx, holding a vector of
      adjustments to be made as the next_arg_reg variable, so we split up
      the insns, and emit them separately.  */
-  next_arg_reg = iq2000_function_arg (&args_so_far, VOIDmode,
+  next_arg_reg = iq2000_function_arg (args_so_far, VOIDmode,
 				      void_type_node, true);
   if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
     {
@@ -2052,7 +2061,8 @@
   if (tsize > 0)
     {
       rtx tsize_rtx = GEN_INT (tsize);
-      rtx adjustment_rtx, insn, dwarf_pattern;
+      rtx adjustment_rtx, dwarf_pattern;
+      rtx_insn *insn;
 
       if (tsize > 32767)
 	{
@@ -2065,8 +2075,9 @@
       insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
 				    adjustment_rtx));
 
-      dwarf_pattern = gen_rtx_SET (Pmode, stack_pointer_rtx,
-				   plus_constant (stack_pointer_rtx, -tsize));
+      dwarf_pattern = gen_rtx_SET (stack_pointer_rtx,
+				   plus_constant (Pmode, stack_pointer_rtx,
+						  -tsize));
 
       iq2000_annotate_frame_insn (insn, dwarf_pattern);
 
@@ -2074,7 +2085,7 @@
 
       if (frame_pointer_needed)
 	{
-	  rtx insn = 0;
+	  rtx_insn *insn = 0;
 
 	  insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
 				       stack_pointer_rtx));
@@ -2084,6 +2095,9 @@
 	}
     }
 
+  if (flag_stack_usage_info)
+    current_function_static_stack_size = cfun->machine->total_size;
+
   emit_insn (gen_blockage ());
 }
 
@@ -2155,7 +2169,7 @@
   HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset;
   rtx scratch;
 
-  scratch = plus_constant (stack_pointer_rtx, gp_offset);
+  scratch = plus_constant (Pmode, stack_pointer_rtx, gp_offset);
   emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address);
 }
 
@@ -2182,7 +2196,7 @@
    mode MODE.  */
 
 static section *
-iq2000_select_rtx_section (enum machine_mode mode, rtx x ATTRIBUTE_UNUSED,
+iq2000_select_rtx_section (machine_mode mode, rtx x ATTRIBUTE_UNUSED,
 			   unsigned HOST_WIDE_INT align)
 {
   /* For embedded applications, always put constants in read-only data,
@@ -2241,7 +2255,7 @@
 		       bool outgoing ATTRIBUTE_UNUSED)
 {
   int reg = GP_RETURN;
-  enum machine_mode mode = TYPE_MODE (valtype);
+  machine_mode mode = TYPE_MODE (valtype);
   int unsignedp = TYPE_UNSIGNED (valtype);
   const_tree func = fn_decl_or_type;
 
@@ -2258,7 +2272,7 @@
 /* Worker function for TARGET_LIBCALL_VALUE.  */
 
 static rtx
-iq2000_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
+iq2000_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
 {
   return gen_rtx_REG (((GET_MODE_CLASS (mode) != MODE_INT
 	                || GET_MODE_SIZE (mode) >= 4)
@@ -2280,9 +2294,10 @@
 /* Return true when an argument must be passed by reference.  */
 
 static bool
-iq2000_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+iq2000_pass_by_reference (cumulative_args_t cum_v, machine_mode mode,
 			  const_tree type, bool named ATTRIBUTE_UNUSED)
 {
+  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   int size;
 
   /* We must pass by reference if we would be both passing in registers
@@ -2296,7 +2311,8 @@
        CUMULATIVE_ARGS temp;
 
        temp = *cum;
-       if (iq2000_function_arg (&temp, mode, type, named) != 0)
+       if (iq2000_function_arg (pack_cumulative_args (&temp), mode, type, named)
+	   != 0)
 	 return 1;
      }
 
@@ -2311,13 +2327,13 @@
    attributes in the machine-description file.  */
 
 int
-iq2000_adjust_insn_length (rtx insn, int length)
+iq2000_adjust_insn_length (rtx_insn *insn, int length)
 {
   /* A unconditional jump has an unfilled delay slot if it is not part
      of a sequence.  A conditional jump normally has a delay slot.  */
   if (simplejump_p (insn)
-      || (   (GET_CODE (insn) == JUMP_INSN
-	   || GET_CODE (insn) == CALL_INSN)))
+      || (   (JUMP_P (insn)
+	   || CALL_P (insn))))
     length += 4;
 
   return length;
@@ -2339,8 +2355,9 @@
    reversed conditional branch around a `jr' instruction.  */
 
 char *
-iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p,
-				  int float_p, int inverted_p, int length)
+iq2000_output_conditional_branch (rtx_insn *insn, rtx * operands,
+				  int two_operands_p, int float_p,
+				  int inverted_p, int length)
 {
   static char buffer[200];
   /* The kind of comparison we are doing.  */
@@ -2499,7 +2516,6 @@
 static void
 iq2000_init_builtins (void)
 {
-  tree endlink = void_list_node;
   tree void_ftype, void_ftype_int, void_ftype_int_int;
   tree void_ftype_int_int_int;
   tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
@@ -2507,76 +2523,55 @@
 
   /* func () */
   void_ftype
-    = build_function_type (void_type_node,
-			   tree_cons (NULL_TREE, void_type_node, endlink));
+    = build_function_type_list (void_type_node, NULL_TREE);
 
   /* func (int) */
   void_ftype_int
-    = build_function_type (void_type_node,
-			   tree_cons (NULL_TREE, integer_type_node, endlink));
+    = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
 
   /* void func (int, int) */
   void_ftype_int_int
-    = build_function_type (void_type_node,
-                           tree_cons (NULL_TREE, integer_type_node,
-                                      tree_cons (NULL_TREE, integer_type_node,
-                                                 endlink)));
+    = build_function_type_list (void_type_node,
+                                integer_type_node,
+                                integer_type_node,
+                                NULL_TREE);
 
   /* int func (int) */
   int_ftype_int
-    = build_function_type (integer_type_node,
-                           tree_cons (NULL_TREE, integer_type_node, endlink));
+    = build_function_type_list (integer_type_node,
+                                integer_type_node, NULL_TREE);
 
   /* int func (int, int) */
   int_ftype_int_int
-    = build_function_type (integer_type_node,
-                           tree_cons (NULL_TREE, integer_type_node,
-                                      tree_cons (NULL_TREE, integer_type_node,
-                                                 endlink)));
+    = build_function_type_list (integer_type_node,
+                                integer_type_node,
+                                integer_type_node,
+                                NULL_TREE);
 
   /* void func (int, int, int) */
-void_ftype_int_int_int
-    = build_function_type
-    (void_type_node,
-     tree_cons (NULL_TREE, integer_type_node,
-		tree_cons (NULL_TREE, integer_type_node,
-			   tree_cons (NULL_TREE,
-				      integer_type_node,
-				      endlink))));
+  void_ftype_int_int_int
+    = build_function_type_list (void_type_node,
+                                integer_type_node,
+                                integer_type_node,
+                                integer_type_node,
+                                NULL_TREE);
+
+  /* int func (int, int, int) */
+  int_ftype_int_int_int
+    = build_function_type_list (integer_type_node,
+                                integer_type_node,
+                                integer_type_node,
+                                integer_type_node,
+                                NULL_TREE);
 
   /* int func (int, int, int, int) */
   int_ftype_int_int_int_int
-    = build_function_type
-    (integer_type_node,
-     tree_cons (NULL_TREE, integer_type_node,
-		tree_cons (NULL_TREE, integer_type_node,
-			   tree_cons (NULL_TREE,
-				      integer_type_node,
-				      tree_cons (NULL_TREE,
-						 integer_type_node,
-						 endlink)))));
-
-  /* int func (int, int, int) */
-  int_ftype_int_int_int
-    = build_function_type
-    (integer_type_node,
-     tree_cons (NULL_TREE, integer_type_node,
-		tree_cons (NULL_TREE, integer_type_node,
-			   tree_cons (NULL_TREE,
-				      integer_type_node,
-				      endlink))));
-
-  /* int func (int, int, int, int) */
-  int_ftype_int_int_int_int
-    = build_function_type
-    (integer_type_node,
-     tree_cons (NULL_TREE, integer_type_node,
-		tree_cons (NULL_TREE, integer_type_node,
-			   tree_cons (NULL_TREE,
-				      integer_type_node,
-				      tree_cons (NULL_TREE,
-						 integer_type_node,
-						 endlink)))));
+    = build_function_type_list (integer_type_node,
+                                integer_type_node,
+                                integer_type_node,
+                                integer_type_node,
+                                integer_type_node,
+                                NULL_TREE);
 
   def_builtin ("__builtin_ado16", int_ftype_int_int, IQ2000_BUILTIN_ADO16);
   def_builtin ("__builtin_ram", int_ftype_int_int_int_int, IQ2000_BUILTIN_RAM);
@@ -2636,7 +2631,7 @@
   rtx pat;
   tree arg [5];
   rtx op [5];
-  enum machine_mode mode [5];
+  machine_mode mode [5];
   int i;
 
   mode[0] = insn_data[icode].operand[0].mode;
@@ -2666,6 +2661,7 @@
     {
     case 0:
 	pat = GEN_FCN (icode) (target);
+	break;
     case 1:
       if (target)
 	pat = GEN_FCN (icode) (target, op[0]);
@@ -2708,7 +2704,7 @@
 
 static rtx
 iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
-		       enum machine_mode mode ATTRIBUTE_UNUSED,
+		       machine_mode mode ATTRIBUTE_UNUSED,
 		       int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
@@ -2899,11 +2895,12 @@
 /* Worker function for TARGET_SETUP_INCOMING_VARARGS.  */
 
 static void
-iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
-			       enum machine_mode mode ATTRIBUTE_UNUSED,
+iq2000_setup_incoming_varargs (cumulative_args_t cum_v,
+			       machine_mode mode ATTRIBUTE_UNUSED,
 			       tree type ATTRIBUTE_UNUSED, int * pretend_size,
 			       int no_rtl)
 {
+  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   unsigned int iq2000_off = ! cum->last_arg_fp; 
   unsigned int iq2000_fp_off = cum->last_arg_fp; 
 
@@ -2927,9 +2924,9 @@
 	  if (cum->arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off) 
 	    {
 	      rtx ptr, mem; 
-	      ptr = plus_constant (virtual_incoming_args_rtx, 
-				   - (iq2000_save_gp_regs 
-				      * UNITS_PER_WORD)); 
+	      ptr = plus_constant (Pmode, virtual_incoming_args_rtx,
+				   - (iq2000_save_gp_regs
+				      * UNITS_PER_WORD));
 	      mem = gen_rtx_MEM (BLKmode, ptr); 
 	      move_block_from_reg 
 		(cum->arg_words + GP_ARG_FIRST + iq2000_off, 
@@ -2945,7 +2942,7 @@
    reference whose address is ADDR.  ADDR is an RTL expression.  */
 
 static void
-iq2000_print_operand_address (FILE * file, rtx addr)
+iq2000_print_operand_address (FILE * file, machine_mode mode, rtx addr)
 {
   if (!addr)
     error ("PRINT_OPERAND_ADDRESS, null pointer");
@@ -2970,7 +2967,7 @@
 			     "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
 
 	  fprintf (file, "%%lo(");
-	  iq2000_print_operand_address (file, arg1);
+	  iq2000_print_operand_address (file, mode, arg1);
 	  fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
 	}
 	break;
@@ -3218,10 +3215,12 @@
 
   else if (code == MEM)
     {
+      machine_mode mode = GET_MODE (op);
+
       if (letter == 'D')
-	output_address (plus_constant (XEXP (op, 0), 4));
+	output_address (mode, plus_constant (Pmode, XEXP (op, 0), 4));
       else
-	output_address (XEXP (op, 0));
+	output_address (mode, XEXP (op, 0));
     }
 
   else if (code == CONST_DOUBLE
@@ -3283,7 +3282,7 @@
 
 rtx
 iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED,
-			   enum machine_mode mode)
+			   machine_mode mode)
 {
   if (TARGET_DEBUG_B_MODE)
     {
@@ -3323,11 +3322,10 @@
           emit_move_insn (int_reg,
                           GEN_INT (INTVAL (xplus1) & ~ 0x7fff));
 
-          emit_insn (gen_rtx_SET (VOIDmode,
-                                  ptr_reg,
+          emit_insn (gen_rtx_SET (ptr_reg,
                                   gen_rtx_PLUS (Pmode, xplus0, int_reg)));
 
-          return plus_constant (ptr_reg, INTVAL (xplus1) & 0x7fff);
+          return plus_constant (Pmode, ptr_reg, INTVAL (xplus1) & 0x7fff);
         }
     }
 
@@ -3339,10 +3337,11 @@
 
 
 static bool
-iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total,
+iq2000_rtx_costs (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
+		  int opno ATTRIBUTE_UNUSED, int * total,
 		  bool speed ATTRIBUTE_UNUSED)
 {
-  enum machine_mode mode = GET_MODE (x);
+  int code = GET_CODE (x);
 
   switch (code)
     {
@@ -3351,7 +3350,7 @@
 	int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
 
 	if (simple_memory_operand (x, mode))
-	  return COSTS_N_INSNS (num_words);
+	  return COSTS_N_INSNS (num_words) != 0;
 
 	* total = COSTS_N_INSNS (2 * num_words);
 	break;
@@ -3520,4 +3519,43 @@
   emit_move_insn (mem, chain_value);
 }
 
+/* Implement TARGET_HARD_REGNO_MODE_OK.  */
+
+static bool
+iq2000_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
+{
+  return (REGNO_REG_CLASS (regno) == GR_REGS
+	  ? (regno & 1) == 0 || GET_MODE_SIZE (mode) <= 4
+	  : (regno & 1) == 0 || GET_MODE_SIZE (mode) == 4);
+}
+
+/* Implement TARGET_MODES_TIEABLE_P.  */
+
+static bool
+iq2000_modes_tieable_p (machine_mode mode1, machine_mode mode2)
+{
+  return ((GET_MODE_CLASS (mode1) == MODE_FLOAT
+	   || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT)
+	  == (GET_MODE_CLASS (mode2) == MODE_FLOAT
+	      || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
+}
+
+/* Implement TARGET_CONSTANT_ALIGNMENT.  */
+
+static HOST_WIDE_INT
+iq2000_constant_alignment (const_tree exp, HOST_WIDE_INT align)
+{
+  if (TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR)
+    return MAX (align, BITS_PER_WORD);
+  return align;
+}
+
+/* Implement TARGET_STARTING_FRAME_OFFSET.  */
+
+static HOST_WIDE_INT
+iq2000_starting_frame_offset (void)
+{
+  return crtl->outgoing_args_size;
+}
+
 #include "gt-iq2000.h"