/* 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.
/* 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
/* __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
#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. */
#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 }
extern char *m32r_model_string;
extern char *m32r_sdata_string;
+
+
#define TARGET_OPTIONS \
{ \
{ "model=", &m32r_model_string }, \
#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
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. */ \
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.
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
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.
#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])
(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.
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
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. */
/* 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. */
#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. */
/* 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
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
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
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
: 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
#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. */
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. */
/* 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. */
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. */
/* 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. */
(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
/* 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. */
/* 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. */
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. */
SDATA_SECTION_FUNCTION \
SBSS_SECTION_FUNCTION
-#define SDATA_SECTION_FUNCTION \
+#define SDATA_SECTION_FUNCTION \
void \
sdata_section () \
{ \
} \
} \
-#define SBSS_SECTION_FUNCTION \
+#define SBSS_SECTION_FUNCTION \
void \
sbss_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
/* 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
#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. */
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 { \
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
/* 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