OSDN Git Service

* m32r.c: Include toplev.h.
[pf3gnuchains/gcc-fork.git] / gcc / config / m32r / m32r.h
index 79233e5..4e11838 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler, Mitsubishi M32R cpu.
-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -38,6 +38,7 @@ Boston, MA 02111-1307, USA.  */
 /* Print subsidiary information on the compiler version in use.  */
 #define TARGET_VERSION fprintf (stderr, " (m32r)")
 
+
 /* Switch  Recognition by gcc.c.  Add -G xx support */
 
 #undef SWITCH_TAKES_ARG
@@ -48,17 +49,18 @@ Boston, MA 02111-1307, USA.  */
 /* __M32R__ is defined by the existing compiler so we use that.  */
 #define CPP_PREDEFINES "-Acpu(m32r) -Amachine(m32r) -D__M32R__"
 
-/* Additional flags for the preprocessor.  */
-#define CPP_SPEC ""
 
 #define CC1_SPEC "%{G*}"
 
-#undef ASM_SPEC
+/* Options to pass on to the assembler.  */
+#undef  ASM_SPEC
+#define ASM_SPEC "%{v}"
+
 #if 0 /* not supported yet */
+#undef  ASM_SPEC
 #define ASM_SPEC "%{v} %{mrelax:-relax}"
-#else
-#define ASM_SPEC "%{v}"
 #endif
+     
 
 #undef ASM_FINAL_SPEC
 
@@ -70,11 +72,13 @@ Boston, MA 02111-1307, USA.  */
 #endif
 
 #undef STARTFILE_SPEC
-#define STARTFILE_SPEC "%{!shared:crt0.o%s crtsysc.o%s} crtinit.o%s"
+#define STARTFILE_SPEC "%{!shared:crt0.o%s} crtinit.o%s"
+
 
 #undef ENDFILE_SPEC
-#define ENDFILE_SPEC "crtfini.o%s"
+#define ENDFILE_SPEC "-lgloss crtfini.o%s"
 
+     
 #undef LIB_SPEC
 \f
 /* Run-time compilation parameters selecting different hardware subsets.  */
@@ -105,6 +109,10 @@ extern int target_flags;
 #define TARGET_OLD_COMPARE_MASK 8
 #define TARGET_OLD_COMPARE (target_flags & TARGET_OLD_COMPARE_MASK)
 
+/* Target machine to compile for.  */
+#define TARGET_M32R 1
+
+
 /* Macro to define tables used to set the flags.
    This is a list in braces of pairs in braces,
    each pair being { "NAME", VALUE }
@@ -147,6 +155,8 @@ extern int target_flags;
 
 extern char *m32r_model_string;
 extern char *m32r_sdata_string;
+
+
 #define TARGET_OPTIONS \
 {                                              \
   { "model=",  &m32r_model_string      },      \
@@ -239,10 +249,10 @@ extern enum m32r_sdata m32r_sdata;
 #define M32R_SDATA_DEFAULT "none"
 
 /* Define this macro as a C expression for the initializer of an array of
-   string to tell the driver program which options are defaults for this
+   strings to tell the driver program which options are defaults for this
    target and thus do not need to be handled specially when using
    `MULTILIB_OPTIONS'.  */
-#define MULTILIB_DEFAULTS { "mmodel=small" }
+#define MULTILIB_DEFAULTS { "mmodel=small", "m32r" }
 
 /* Sometimes certain combinations of command options do not make
    sense on a particular target machine.  You can define a macro
@@ -253,8 +263,6 @@ extern enum m32r_sdata m32r_sdata;
    Don't use this macro to turn on various extra optimizations for
    `-O'.  That is what `OPTIMIZATION_OPTIONS' is for.  */
 
-extern void m32r_init ();
-
 #define OVERRIDE_OPTIONS \
 do {                           \
   /* These need to be done at start up.  It's convenient to do them here.  */ \
@@ -404,7 +412,7 @@ if (GET_MODE_CLASS (MODE) == MODE_INT               \
    All registers that the compiler knows about must be given numbers,
    even those that are not normally considered general registers.  */
 #define FIRST_PSEUDO_REGISTER 18
-
+       
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.
 
@@ -420,12 +428,14 @@ if (GET_MODE_CLASS (MODE) == MODE_INT             \
    16    - arg pointer
    17    - carry flag
 
+   
    By default, the extension registers are not available.  */
 
 #define FIXED_REGISTERS \
 { 0, 0, 0, 0, 0, 0, 0, 0,      \
   0, 0, 0, 0, 0, 0, 0, 1,      \
-  1, 0 }
+  1, 1 }
+
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -439,6 +449,7 @@ if (GET_MODE_CLASS (MODE) == MODE_INT               \
   0, 0, 0, 0, 0, 0, 1, 1,      \
   1, 1 }
 
+
 /* Zero or more C statements that may conditionally modify two variables
    `fixed_regs' and `call_used_regs' (both of type `char []') after they
    have been initialized from the two preceding macros.
@@ -531,11 +542,12 @@ enum reg_class {
 #define REG_CLASS_CONTENTS \
 { {0}, {0x20000}, {0x1ffff}, {0x3ffff} }
 
+
 /* The same information, inverted:
    Return the class number of the smallest class containing
    reg number REGNO.  This could be a conditional expression
    or could index an array.  */
-extern enum reg_class m32r_regno_reg_class[];
+extern enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER];
 #define REGNO_REG_CLASS(REGNO) \
 (m32r_regno_reg_class[REGNO])
 
@@ -585,25 +597,29 @@ extern enum reg_class m32r_regno_reg_class[];
        (values in the range -32767 to +32768).  */
 
 /* local to this file */
-#define INT8_P(X) ((unsigned) ((X) + 0x80) < 0x100)
-#define INT16_P(X) ((unsigned) ((X) + 0x8000) < 0x10000)
-#define CMP_INT16_P(X) ((unsigned) ((X) - 1 + 0x8000) < 0x10000)
-#define UINT16_P(X) ((unsigned) (X) < 0x10000)
-#define UPPER16_P(X) (((X) & ~0xffff0000) == 0)
-#define UINT24_P(X) ((unsigned) (X) < 0x1000000)
-#define INT32_P(X) ((X) >= (-(HOST_WIDE_INT) 0x7fffffff - 1) \
-                   && (X) <= (unsigned HOST_WIDE_INT) 0xffffffff)
-#define UINT5_P(X) ((unsigned) (X) < 32)
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C) \
-((C) == 'I' ? INT8_P (VALUE)           \
- : (C) == 'J' ? INT16_P (VALUE)        \
- : (C) == 'K' ? UINT16_P (VALUE)       \
- : (C) == 'L' ? UPPER16_P (VALUE)      \
- : (C) == 'M' ? UINT24_P (VALUE)       \
- : (C) == 'N' ? INT32_P (VALUE)                \
- : (C) == 'O' ? UINT5_P (VALUE)                \
- : (C) == 'P' ? CMP_INT16_P (VALUE)    \
+#define INT8_P(X) ((X) >= -0x80 && (X) <= 0x7f)
+#define INT16_P(X) ((X) >= -0x8000 && (X) <= 0x7fff)
+#define CMP_INT16_P(X) ((X) >= -0x7fff && (X) <= 0x8000)
+#define UINT16_P(X) ((X) >= 0 && (X) <= 0xffff)
+#define UPPER16_P(X) (((X) & 0xffff) == 0                              \
+                     && ((X) >> 16) >= -0x8000                         \
+                     && ((X) >> 16) <= 0x7fff)
+#define UINT24_P(X) ((X) >= 0 && (X) < 0x1000000)
+#define INT32_P(X) (((X) >= -(HOST_WIDE_INT) 0x80000000                        \
+                    && (X) <= (HOST_WIDE_INT) 0x7fffffff)              \
+                   || (unsigned HOST_WIDE_INT) (X) <= 0xffffffff)
+#define UINT5_P(X) ((X) >= 0 && (X) < 32)
+#define INVERTED_SIGNED_8BIT(VAL) ((VAL) >= -127 && (VAL) <= 128)
+
+#define CONST_OK_FOR_LETTER_P(VALUE, C)                                        \
+((C) == 'I' ? INT8_P (VALUE)                                           \
+ : (C) == 'J' ? INT16_P (VALUE)                                                \
+ : (C) == 'K' ? UINT16_P (VALUE)                                       \
+ : (C) == 'L' ? UPPER16_P (VALUE)                                      \
+ : (C) == 'M' ? UINT24_P (VALUE)                                       \
+ : (C) == 'N' ? INVERTED_SIGNED_8BIT (VALUE)                           \
+ : (C) == 'O' ? UINT5_P (VALUE)                                                \
+ : (C) == 'P' ? CMP_INT16_P (VALUE)                                    \
  : 0)
 
 /* Similar, but for floating constants, and defining letters G and H.
@@ -611,8 +627,8 @@ extern enum reg_class m32r_regno_reg_class[];
    For the m32r, handle a few constants inline.
    ??? We needn't treat DI and DF modes differently, but for now we do.  */
 #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
-((C) == 'G' ? easy_di_const (VALUE) \
- : (C) == 'H' ? easy_df_const (VALUE) \
+((C) == 'G' ? easy_di_const (VALUE)                                    \
+ : (C) == 'H' ? easy_df_const (VALUE)                                  \
  : 0)
 
 /* A C expression that defines the optional machine-dependent constraint
@@ -622,14 +638,26 @@ extern enum reg_class m32r_regno_reg_class[];
    C.  If C is not defined as an extra constraint, the value returned should
    be 0 regardless of VALUE.  */
 /* Q is for symbolic addresses loadable with ld24.
-   R is for symbolic addresses when ld24 can't be used.  */
-#define EXTRA_CONSTRAINT(VALUE, C) \
-((C) == 'Q' \
- ? ((TARGET_ADDR24 && GET_CODE (VALUE) == LABEL_REF) \
-    || addr24_operand (VALUE, VOIDmode)) \
- : (C) == 'R' \
- ? ((TARGET_ADDR32 && GET_CODE (VALUE) == LABEL_REF) \
-    || addr32_operand (VALUE, VOIDmode)) \
+   R is for symbolic addresses when ld24 can't be used.
+   S is unused.
+   T is for indirect of a pointer.
+   U is for pushes and pops of the stack pointer.  */
+
+#define EXTRA_CONSTRAINT(VALUE, C)                                     \
+((C) == 'Q'                                                            \
+ ? ((TARGET_ADDR24 && GET_CODE (VALUE) == LABEL_REF)                   \
+    || addr24_operand (VALUE, VOIDmode))                               \
+ : (C) == 'R'                                                          \
+ ? ((TARGET_ADDR32 && GET_CODE (VALUE) == LABEL_REF)                   \
+    || addr32_operand (VALUE, VOIDmode))                               \
+ : (C) == 'S'                                                          \
+ ? 0                                                                   \
+ : (C) == 'T'                                                          \
+ ?  (GET_CODE (VALUE) == MEM                                           \
+     && memreg_operand (VALUE, GET_MODE (VALUE)))                      \
+ : (C) == 'U'                                                          \
+ ?  (GET_CODE (VALUE) == MEM                                           \
+     && PUSH_POP_P (GET_MODE (VALUE), XEXP (VALUE, 0)))                        \
  : 0)
 \f
 /* Stack layout and stack pointer usage.  */
@@ -678,10 +706,12 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size)
 /* The current return address is in r14.  */
 #if 0 /* The default value should work.  */
 #define RETURN_ADDR_RTX(COUNT, FRAME) \
-(((COUNT) == -1)                               \
- ? gen_rtx (REG, Pmode, 14)                    \
- : copy_to_reg (gen_rtx (MEM, Pmode,           \
-                        memory_address (Pmode, plus_constant ((FRAME), UNITS_PER_WORD)))))
+(((COUNT) == -1)                                                       \
+ ? gen_rtx_REG (Pmode, 14)                                             \
+ : copy_to_reg (gen_rtx_MEM (Pmode,                                    \
+                            memory_address (Pmode,                     \
+                                            plus_constant ((FRAME),    \
+                                                           UNITS_PER_WORD)))))
 #endif
 
 /* Register to use for pushing function arguments.  */
@@ -717,6 +747,7 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size)
 #define CARRY_REGNUM 17
 #define M32R_MAX_INT_REGS 16
 
+     
 #define GPR_P(REGNO) ((unsigned) (REGNO) < M32R_MAX_INT_REGS)
 \f
 /* Eliminating the frame and arg pointers.  */
@@ -784,7 +815,7 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size)
 /* Function argument passing.  */
 
 /* When a prototype says `char' or `short', really pass an `int'.  */
-#define PROMOTE_PROTOTYPES
+#define PROMOTE_PROTOTYPES 1
 
 /* If defined, the maximum amount of space required for outgoing
    arguments will be computed and placed into the variable
@@ -817,6 +848,12 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size)
    SIZE is the number of bytes of arguments passed on the stack.  */
 #define RETURN_POPS_ARGS(DECL, FUNTYPE, SIZE) 0
 
+/* Nonzero if we do not know how to pass TYPE solely in registers. */
+#define MUST_PASS_IN_STACK(MODE,TYPE)                  \
+  ((TYPE) != 0                                         \
+   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST     \
+       || TREE_ADDRESSABLE (TYPE)))
+
 /* Define a data type for recording info about an argument list
    during the scan of that argument list.  This data type should
    hold all necessary information about the function itself
@@ -883,14 +920,14 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size)
    and the rest are pushed.  */
 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
 (PASS_IN_REG_P ((CUM), (MODE), (TYPE), (NAMED))                                \
- ? gen_rtx (REG, (MODE), ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE)))    \
+ ? gen_rtx_REG ((MODE), ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE)))     \
  : 0)
 
 /* ??? Quick hack to try to get varargs working the normal way.  */
 #define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
 (((! current_function_varargs || (NAMED))                              \
   && PASS_IN_REG_P ((CUM), (MODE), (TYPE), (NAMED)))                   \
- ? gen_rtx (REG, (MODE), ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE)))    \
+ ? gen_rtx_REG ((MODE), ROUND_ADVANCE_CUM ((CUM), (MODE), (TYPE)))     \
  : 0)
 
 /* A C expression for the number of words, at the beginning of an
@@ -907,7 +944,7 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size)
    compiler when this occurs, and how many of the words should go in
    registers.  */
 #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
-  function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
+  function_arg_partial_nregs (&CUM, (int)MODE, TYPE, NAMED)
 
 /* A C expression that indicates when an argument must be passed by
    reference.  If nonzero for an argument, a copy of that argument is
@@ -936,22 +973,6 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size)
  : 2 * PARM_BOUNDARY)
 #endif
 
-#if 0
-/* If defined, is a C expression that produces the machine-specific
-   code for a call to `__builtin_saveregs'.  This code will be moved
-   to the very beginning of the function, before any parameter access
-   are made.  The return value of this function should be an RTX that
-   contains the value to use as the return of `__builtin_saveregs'.
-
-   The argument ARGS is a `tree_list' containing the arguments that
-   were passed to `__builtin_saveregs'.
-
-   If this macro is not defined, the compiler will output an ordinary
-   call to the library function `__builtin_saveregs'.  */
-extern struct rtx *m32r_expand_builtin_savergs ();
-#define EXPAND_BUILTIN_SAVEREGS(ARGS) m32r_expand_builtin_saveregs (ARGS)
-#endif
-
 /* This macro offers an alternative
    to using `__builtin_saveregs' and defining the macro
    `EXPAND_BUILTIN_SAVEREGS'.  Use it to store the anonymous register
@@ -981,6 +1002,10 @@ extern struct rtx *m32r_expand_builtin_savergs ();
 
 #define SETUP_INCOMING_VARARGS(ARGS_SO_FAR, MODE, TYPE, PRETEND_SIZE, NO_RTL) \
 m32r_setup_incoming_varargs (&ARGS_SO_FAR, MODE, TYPE, &PRETEND_SIZE, NO_RTL)
+
+/* Implement `va_arg'.  */
+#define EXPAND_BUILTIN_VA_ARG(valist, type) \
+  m32r_va_arg (valist, type)
 \f
 /* Function results.  */
 
@@ -988,11 +1013,11 @@ m32r_setup_incoming_varargs (&ARGS_SO_FAR, MODE, TYPE, &PRETEND_SIZE, NO_RTL)
    VALTYPE is the data type of the value (as a tree).
    If the precise function being called is known, FUNC is its FUNCTION_DECL;
    otherwise, FUNC is 0.  */
-#define FUNCTION_VALUE(VALTYPE, FUNC) gen_rtx (REG, TYPE_MODE (VALTYPE), 0)
+#define FUNCTION_VALUE(VALTYPE, FUNC) gen_rtx_REG (TYPE_MODE (VALTYPE), 0)
 
 /* Define how to find the value returned by a library function
    assuming the value has mode MODE.  */
-#define LIBCALL_VALUE(MODE) gen_rtx (REG, MODE, 0)
+#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, 0)
 
 /* 1 if N is a possible register number for a function value
    as seen by the caller.  */
@@ -1050,7 +1075,7 @@ m32r_output_function_epilogue (FILE, SIZE)
 
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */
-#define FUNCTION_PROFILER(FILE, LABELNO)
+#define FUNCTION_PROFILER(FILE, LABELNO) abort ()
 \f
 /* Trampolines.  */
 
@@ -1072,13 +1097,13 @@ m32r_output_function_epilogue (FILE, SIZE)
    CXT is an RTX for the static chain value for the function.  */
 #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
 do { \
-  emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 0)), \
+  emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 0)), \
                  plus_constant ((CXT), 0xe7000000)); \
-  emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 4)), \
+  emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 4)), \
                  plus_constant ((FNADDR), 0xe6000000)); \
-  emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 8)), \
+  emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 8)), \
                  GEN_INT (0x1fc67000)); \
-  emit_insn (gen_flush_icache (validize_mem (gen_rtx (MEM, SImode, TRAMP)))); \
+  emit_insn (gen_flush_icache (validize_mem (gen_rtx_MEM (SImode, TRAMP)))); \
 } while (0)
 \f
 /* Library calls.  */
@@ -1094,9 +1119,9 @@ do { \
 /* We have post-inc load and pre-dec,pre-inc store,
    but only for 4 byte vals.  */
 #if 0
-#define HAVE_PRE_DECREMENT
-#define HAVE_PRE_INCREMENT
-#define HAVE_POST_INCREMENT
+#define HAVE_PRE_DECREMENT 1
+#define HAVE_PRE_INCREMENT 1
+#define HAVE_POST_INCREMENT 1
 #endif
 
 /* Recognize any constant value that is a valid address.  */
@@ -1165,24 +1190,37 @@ do { \
 (GET_CODE (X) == CONST_INT && INT16_P (INTVAL (X)))
 
 /* local to this file */
-#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X) \
-(GET_CODE (X) == PLUS                          \
- && RTX_OK_FOR_BASE_P (XEXP (X, 0))            \
+#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X)                           \
+(GET_CODE (X) == PLUS                                                  \
+ && RTX_OK_FOR_BASE_P (XEXP (X, 0))                                    \
  && RTX_OK_FOR_OFFSET_P (XEXP (X, 1)))
 
 /* local to this file */
-#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X) \
-(GET_CODE (X) == LO_SUM                                \
- && RTX_OK_FOR_BASE_P (XEXP (X, 0))            \
+/* For LO_SUM addresses, do not allow them if the MODE is > 1 word,
+   since more than one instruction will be required.  */
+#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X)                           \
+(GET_CODE (X) == LO_SUM                                                        \
+ && (MODE != BLKmode && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)                \
+ && RTX_OK_FOR_BASE_P (XEXP (X, 0))                                    \
  && CONSTANT_P (XEXP (X, 1)))
 
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ if (RTX_OK_FOR_BASE_P (X))                           \
-    goto ADDR;                                         \
-  if (LEGITIMATE_OFFSET_ADDRESS_P ((MODE), (X)))       \
-    goto ADDR;                                         \
-  if (LEGITIMATE_LO_SUM_ADDRESS_P ((MODE), (X)))       \
-    goto ADDR;                                         \
+/* local to this file */
+/* Memory address that is a push/pop of the stack pointer.  */
+#define PUSH_POP_P(MODE, X)                                            \
+((MODE) == SImode                                                      \
+ && (GET_CODE (X) == POST_INC                                          \
+     || GET_CODE (X) == PRE_INC                                                \
+     || GET_CODE (X) == PRE_DEC))
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                                \
+{ if (RTX_OK_FOR_BASE_P (X))                                           \
+    goto ADDR;                                                         \
+  if (LEGITIMATE_OFFSET_ADDRESS_P ((MODE), (X)))                       \
+    goto ADDR;                                                         \
+  if (LEGITIMATE_LO_SUM_ADDRESS_P ((MODE), (X)))                       \
+    goto ADDR;                                                         \
+  if (PUSH_POP_P ((MODE), (X)))                                                \
+    goto ADDR;                                                         \
 }
 
 /* Try machine-dependent ways of modifying an illegitimate address
@@ -1204,23 +1242,21 @@ do { \
 
 /* Go to LABEL if ADDR (a legitimate address expression)
    has an effect that depends on the machine mode it is used for.  */
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
-do {                                   \
-  if (GET_CODE (ADDR) == PRE_DEC)      \
-    goto LABEL;                                \
-  if (GET_CODE (ADDR) == PRE_INC)      \
-    goto LABEL;                                \
-  if (GET_CODE (ADDR) == POST_INC)     \
-    goto LABEL;                                \
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)                      \
+do {                                                                   \
+  if (GET_CODE (ADDR) == PRE_DEC                                       \
+      || GET_CODE (ADDR) == PRE_INC                                    \
+      || GET_CODE (ADDR) == POST_INC                                   \
+      || GET_CODE (ADDR) == LO_SUM)                                    \
+    goto LABEL;                                                                \
 } while (0)
 \f
 /* Condition code usage.  */
 
 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
    return the mode to be used for the comparison.  */
-extern enum machine_mode m32r_select_cc_mode ();
 #define SELECT_CC_MODE(OP, X, Y) \
-m32r_select_cc_mode (OP, X, Y)
+((enum machine_mode)m32r_select_cc_mode ((int)OP, X, Y))
 
 /* Return non-zero if SELECT_CC_MODE will never return MODE for a
    floating point inequality comparison.  */
@@ -1268,7 +1304,7 @@ m32r_select_cc_mode (OP, X, Y)
 /* Compute the cost of moving data between registers and memory.  */
 /* Memory is 3 times as expensive as registers.
    ??? Is that the right way to look at it?  */
-#define MEMORY_MOVE_COST(MODE) \
+#define MEMORY_MOVE_COST(MODE,CLASS,IN_P) \
 (GET_MODE_SIZE (MODE) <= UNITS_PER_WORD ? 6 : 12)
 
 /* The cost of a branch insn.  */
@@ -1313,6 +1349,41 @@ m32r_select_cc_mode (OP, X, Y)
    the improvement wasn't significant and in a couple of cases caused a
    significant de-optimization.  */
 /* #define ENABLE_REGMOVE_PASS */
+
+/* A C statement (sans semicolon) to update the integer variable COST based on
+   the relationship between INSN that is dependent on DEP_INSN through the
+   dependence LINK.  The default is to make no adjustment to COST.  This can be
+   used for example to specify to the scheduler that an output- or
+   anti-dependence does not incur the same cost as a data-dependence.  */
+
+/* #define ADJUST_COST(INSN,LINK,DEP_INSN,COST)                                \
+  (COST) = m32r_adjust_cost (INSN, LINK, DEP_INSN, COST) */
+
+/* A C statement (sans semicolon) to update the integer scheduling
+   priority `INSN_PRIORITY(INSN)'.  Reduce the priority to execute
+   the INSN earlier, increase the priority to execute INSN later.
+   Do not define this macro if you do not need to adjust the
+   scheduling priorities of insns.  */
+/* #define ADJUST_PRIORITY (INSN) */
+
+/* Macro to determine whether the Haifa scheduler is used.  */
+#ifdef HAIFA
+#define HAIFA_P 1
+#else
+#define HAIFA_P 0
+#endif
+
+/* Indicate how many instructions can be issued at the same time.
+   This is 1/2 of a lie.  The m32r can issue only 1 long insn at
+   once, but 2.  However doing so allows the scheduler to group
+   the two short insns together.  */
+#define ISSUE_RATE 2
+
+/* When the `length' insn attribute is used, this macro specifies the
+   value to be assigned to the address of the first insn in a
+   function.  If not specified, 0 is used.  */
+#define FIRST_INSN_ADDRESS m32r_first_insn_address ()
+
 \f
 /* Section selection.  */
 
@@ -1344,7 +1415,7 @@ DTORS_SECTION_FUNCTION \
 SDATA_SECTION_FUNCTION \
 SBSS_SECTION_FUNCTION
 
-#define SDATA_SECTION_FUNCTION \
+#define SDATA_SECTION_FUNCTION                                         \
 void                                                                   \
 sdata_section ()                                                       \
 {                                                                      \
@@ -1355,7 +1426,7 @@ sdata_section ()                                                  \
     }                                                                  \
 }                                                                      \
 
-#define SBSS_SECTION_FUNCTION \
+#define SBSS_SECTION_FUNCTION                                          \
 void                                                                   \
 sbss_section ()                                                                \
 {                                                                      \
@@ -1429,7 +1500,6 @@ extern void m32r_select_section ();
  || MEDIUM_NAME_P (SYMBOL_NAME) \
  || LARGE_NAME_P (SYMBOL_NAME))
 
-extern void m32r_encode_section_info ();
 #define ENCODE_SECTION_INFO(DECL) m32r_encode_section_info (DECL)
 
 /* Decode SYM_NAME and store the real name part in VAR, sans
@@ -1487,7 +1557,6 @@ do {                                                      \
 /* Control the assembler format that we output.  */
 
 /* Output at beginning of assembler file.  */
-extern void m32r_asm_file_start ();
 #define ASM_FILE_START(FILE) m32r_asm_file_start (FILE)
 
 /* A C string constant describing how to begin a comment in the target
@@ -1582,11 +1651,37 @@ do {                            \
 #undef ASM_OUTPUT_LABELREF
 #define ASM_OUTPUT_LABELREF(FILE, NAME) \
 do {                                                   \
-  char *real_name;                                     \
+  const char * real_name;                              \
   STRIP_NAME_ENCODING (real_name, (NAME));             \
-  fprintf (FILE, "%s%s", USER_LABEL_PREFIX, real_name);        \
+  asm_fprintf (FILE, "%U%s", real_name);               \
 } while (0)           
 
+/* If -Os, don't force line number labels to begin at the beginning of
+   the word; we still want the assembler to try to put things in parallel,
+   should that be possible.
+   For m32r/d, instructions are never in parallel (other than with a nop)
+   and the simulator and stub both handle a breakpoint in the middle of
+   a word so don't ever force line number labels to begin at the beginning
+   of a word.  */
+
+#undef ASM_OUTPUT_SOURCE_LINE
+#define ASM_OUTPUT_SOURCE_LINE(file, line)                             \
+do                                                                     \
+  {                                                                    \
+    static int sym_lineno = 1;                                         \
+    fprintf (file, ".stabn 68,0,%d,.LM%d-",                            \
+            line, sym_lineno);                                         \
+    assemble_name (file,                                               \
+                  XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
+    fprintf (file,                                                     \
+            (optimize_size || TARGET_M32R)                             \
+            ? "\n\t.debugsym .LM%d\n"                                  \
+            : "\n.LM%d:\n",                                            \
+            sym_lineno);                                               \
+    sym_lineno += 1;                                                   \
+  }                                                                    \
+while (0)
+
 /* Store in OUTPUT a string (made with alloca) containing
    an assembler-name for a local static variable named NAME.
    LABELNO is an integer which is different for each call.  */
@@ -1713,8 +1808,6 @@ do {                                                                      \
    handling the required alignment of the variable.  The alignment is
    specified as the number of bits.  */
 
-extern void sbss_section ();
-
 #undef ASM_OUTPUT_ALIGNED_LOCAL
 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
 do {                                                                   \
@@ -1823,7 +1916,7 @@ do {                                                                      \
    After generation of rtl, the compiler makes no further distinction
    between pointers and any other objects of this machine mode.  */
 /* ??? The M32R doesn't have full 32 bit pointers, but making this PSImode has
-   it's own problems (you have to add extendpsisi2 and truncsipsi2).
+   its own problems (you have to add extendpsisi2 and truncsipsi2).
    Try to avoid it.  */
 #define Pmode SImode
 
@@ -1833,35 +1926,143 @@ do {                                                                   \
 /* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
    is a valid machine specific attribute for DECL.
    The attributes in ATTRIBUTES have previously been assigned to TYPE.  */
-extern int m32r_valid_machine_attribute ();
 #define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
 m32r_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
 
 /* A C expression that returns zero if the attributes on TYPE1 and TYPE2 are
    incompatible, one if they are compatible, and two if they are
    nearly compatible (which causes a warning to be generated).  */
-extern int m32r_comp_type_attributes ();
 #define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
 m32r_comp_type_attributes (TYPE1, TYPE2)
 
 /* Give newly defined TYPE some default attributes.  */
-extern void m32r_set_default_type_attributes ();
 #define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \
 m32r_set_default_type_attributes (TYPE)
 \f
 /* Define the information needed to generate branch and scc insns.  This is
    stored from the compare operation.  Note that we can't use "rtx" here
    since it hasn't been defined!  */
-extern struct rtx_def *m32r_compare_op0, *m32r_compare_op1;
-
-/* Define the function that build the compare insn for scc and bcc.  */
-extern struct rtx_def *gen_compare ();
+extern struct rtx_def * m32r_compare_op0;
+extern struct rtx_def * m32r_compare_op1;
 
 /* M32R function types.   */
-enum m32r_function_type {
+enum m32r_function_type
+{
   M32R_FUNCTION_UNKNOWN, M32R_FUNCTION_NORMAL, M32R_FUNCTION_INTERRUPT
 };
 #define M32R_INTERRUPT_P(TYPE) \
 ((TYPE) == M32R_FUNCTION_INTERRUPT)
-/* Compute the type of a function from its DECL.  */
-enum m32r_function_type m32r_compute_function_type ();
+
+/* Define this if you have defined special-purpose predicates in the
+   file `MACHINE.c'.  This macro is called within an initializer of an
+   array of structures.  The first field in the structure is the name
+   of a predicate and the second field is an array of rtl codes.  For
+   each predicate, list all rtl codes that can be in expressions
+   matched by the predicate.  The list should have a trailing comma.  */
+
+#define PREDICATE_CODES                                                        \
+{ "conditional_move_operand",  { REG, SUBREG, CONST_INT }},            \
+{ "carry_compare_operand",     { EQ, NE }},                            \
+{ "eqne_comparison_operator",  { EQ, NE }},                            \
+{ "signed_comparison_operator", { EQ, NE, LT, LE, GT, GE }},           \
+{ "move_dest_operand",         { REG, SUBREG, MEM }},                  \
+{ "move_src_operand",          { REG, SUBREG, MEM, CONST_INT,          \
+                                 CONST_DOUBLE, LABEL_REF, CONST,       \
+                                 SYMBOL_REF }},                        \
+{ "move_double_src_operand",   { REG, SUBREG, MEM, CONST_INT,          \
+                                 CONST_DOUBLE }},                      \
+{ "two_insn_const_operand",    { CONST_INT }},                         \
+{ "symbolic_operand",          { SYMBOL_REF, LABEL_REF, CONST }},      \
+{ "reg_or_int16_operand",      { REG, SUBREG, CONST_INT }},            \
+{ "reg_or_uint16_operand",     { REG, SUBREG, CONST_INT }},            \
+{ "reg_or_cmp_int16_operand",  { REG, SUBREG, CONST_INT }},            \
+{ "reg_or_zero_operand",       { REG, SUBREG, CONST_INT }},            \
+{ "cmp_int16_operand",         { CONST_INT }},                         \
+{ "call_address_operand",      { SYMBOL_REF, LABEL_REF, CONST }},      \
+{ "small_insn_p",              { INSN, CALL_INSN, JUMP_INSN }},        \
+{ "m32r_block_immediate_operand",{ CONST_INT }},                       \
+{ "large_insn_p",              { INSN, CALL_INSN, JUMP_INSN }},
+
+/* Functions declared in m32r.c */
+#define XPROTO(ARGS) ()
+#define STDIO_XPROTO(ARGS) ()
+
+#ifndef TREE_CODE
+union tree_node;
+#define Tree union tree_node *
+#else
+#define Tree tree
+#endif
+
+#ifndef RTX_CODE
+struct rtx_def;
+#define Rtx struct rtx_def *
+#else
+#define Rtx rtx
+#endif
+
+extern void sbss_section                       XPROTO((void));
+extern void sdata_section                      XPROTO((void));
+extern void m32r_init                          XPROTO((void));
+extern int  m32r_valid_machine_decl_attribute  XPROTO((Tree, Tree, Tree, Tree));
+extern int  m32r_comp_type_attributes          XPROTO((Tree, Tree));
+extern void m32r_select_section                        XPROTO((Tree, int));
+extern void m32r_encode_section_info           XPROTO((Tree));
+extern void m32r_init_expanders                        XPROTO((void));
+extern int  call_address_operand               XPROTO((Rtx, enum machine_mode));
+extern int  call_operand                       XPROTO((Rtx, enum machine_mode));
+extern int  symbolic_operand                   XPROTO((Rtx, enum machine_mode));
+extern int  small_data_operand                 XPROTO((Rtx, enum machine_mode));
+extern int  addr24_operand                     XPROTO((Rtx, enum machine_mode));
+extern int  addr32_operand                     XPROTO((Rtx, enum machine_mode));
+extern int  call26_operand                     XPROTO((Rtx, enum machine_mode));
+extern int  seth_add3_operand                  XPROTO((Rtx, enum machine_mode));
+extern int  cmp_int16_operand                  XPROTO((Rtx, enum machine_mode));
+extern int  uint16_operand                     XPROTO((Rtx, enum machine_mode));
+extern int  reg_or_int16_operand               XPROTO((Rtx, enum machine_mode));
+extern int  reg_or_uint16_operand              XPROTO((Rtx, enum machine_mode));
+extern int  reg_or_cmp_nt16_operand            XPROTO((Rtx, enum machine_mode));
+extern int  two_insn_const_operand             XPROTO((Rtx, enum machine_mode));
+extern int  move_src_operand                   XPROTO((Rtx, enum machine_mode));
+extern int  move_double_src_operand            XPROTO((Rtx, enum machine_mode));
+extern int  move_dest_operand                  XPROTO((Rtx, enum machine_mode));
+extern int  easy_di_const                      XPROTO((Rtx));
+extern int  easy_df_const                      XPROTO((Rtx));
+extern int  eqne_comparison_operator           XPROTO((Rtx, enum machine_mode));
+extern int  signed_comparison_operator         XPROTO((Rtx, enum machine_mode));
+extern int  memreg_operand                     XPROTO((Rtx, enum machine_mode));
+extern int  small_insn_p                       XPROTO((Rtx, enum machine_mode));
+extern int  large_insn_p                       XPROTO((Rtx, enum machine_mode));
+extern int  m32r_select_cc_mode                        XPROTO((int, Rtx, Rtx));
+extern Rtx  gen_compare                                XPROTO((int, Rtx, Rtx, int));
+extern Rtx  gen_split_move_double              XPROTO((Rtx *));
+extern int  function_arg_partial_nregs         XPROTO((CUMULATIVE_ARGS *,
+                                                      int, Tree, int));
+extern void m32r_setup_incoming_varargs                XPROTO((CUMULATIVE_ARGS *,
+                                                      int, Tree, int *,
+                                                      int));
+extern struct rtx_def *m32r_va_arg             XPROTO((Tree, Tree));
+extern int  m32r_address_code                  XPROTO((Rtx));
+extern enum m32r_function_type m32r_compute_function_type
+                                               XPROTO((Tree));
+extern unsigned m32r_compute_frame_size                XPROTO((int));
+extern int  m32r_first_insn_address            XPROTO((void));
+extern void m32r_expand_prologue               XPROTO((void));
+extern void m32r_output_function_prologue      STDIO_XPROTO((FILE *, int));
+extern void m32r_output_function_epilogue      STDIO_XPROTO((FILE *, int));
+extern void m32r_finalize_pic                  XPROTO((void));
+extern void m32r_initialize_trampoline         XPROTO((Rtx, Rtx, Rtx));
+extern void m32r_asm_file_start                        STDIO_XPROTO((FILE *));
+extern void m32r_print_operand                 STDIO_XPROTO((FILE *, Rtx, int));
+extern void m32r_print_operand_address         STDIO_XPROTO((FILE *, Rtx));
+extern int  zero_and_one                       XPROTO((Rtx, Rtx));
+extern int  conditional_move_operand           XPROTO((Rtx, enum machine_mode));
+extern int  carry_compare_operand              XPROTO((Rtx, enum machine_mode));
+extern char *emit_cond_move                    XPROTO((Rtx *, Rtx));
+
+extern char * m32r_output_block_move XPROTO((Rtx, Rtx *));
+extern int    m32r_block_immediate_operand XPROTO((Rtx, enum machine_mode));
+extern void   m32r_expand_block_move XPROTO((Rtx *));
+
+#undef XPROTO
+#undef STDIO_XPROTO