/* Definitions of target machine for GNU compiler.
Motorola 68HC11 and 68HC12.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
- Contributed by Stephane Carrez (stcarrez@worldnet.fr)
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+ Contributed by Stephane Carrez (stcarrez@nerim.fr)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
/* Compile and assemble for a 68hc11 unless there is a -m68hc12 option. */
#ifndef ASM_SPEC
-#define ASM_SPEC "%{m68hc12:-m68hc12}%{!m68hc12:-m68hc11}"
+#define ASM_SPEC \
+"%{m68hc12:-m68hc12}" \
+"%{m68hcs12:-m68hcs12}" \
+"%{!m68hc12:%{!m68hcs12:-m68hc11}} " \
+"%{mshort:-mshort}%{!mshort:-mlong} " \
+"%{fshort-double:-mshort-double}%{!fshort-double:-mlong-double}"
#endif
/* We need to tell the linker the target elf format. Just pass an
- emulation option. This can be overriden by -Wl option of gcc. */
+ emulation option. This can be overridden by -Wl option of gcc. */
#ifndef LINK_SPEC
-#define LINK_SPEC "%{m68hc12:-m m68hc12elf}%{!m68hc12:-m m68hc11elf}"
+#define LINK_SPEC \
+"%{m68hc12:-m m68hc12elf}" \
+"%{m68hcs12:-m m68hc12elf}" \
+"%{!m68hc12:%{!m68hcs12:-m m68hc11elf}} " \
+"%{!mnorelax:%{!m68hc12:%{!m68hcs12:-relax}}}"
#endif
#ifndef LIB_SPEC
#ifndef CPP_SPEC
#define CPP_SPEC \
-"%{mshort:-D__HAVE_SHORT_INT__ -D__INT__=16 -D__INT_MAX__=32767}\
- %{!mshort:-D__INT__=32 -D__INT_MAX__=2147483647}\
+"%{mshort:-D__HAVE_SHORT_INT__ -D__INT__=16}\
+ %{!mshort:-D__INT__=32}\
%{m68hc12:-Dmc6812 -DMC6812 -Dmc68hc12}\
- %{!m68hc12:-Dmc6811 -DMC6811 -Dmc68hc11}\
- %{fshort-double:-D__HAVE_SHORT_DOUBLE__}"
+ %{m68hcs12:-Dmc6812 -DMC6812 -Dmc68hcs12}\
+ %{!m68hc12:%{!m68hcs12:-Dmc6811 -DMC6811 -Dmc68hc11}}\
+ %{fshort-double:-D__HAVE_SHORT_DOUBLE__}\
+ %{mlong-calls:-D__USE_RTC__}"
#endif
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "crt1%O%s"
/* Names to predefine in the preprocessor for this target machine. */
-#define CPP_PREDEFINES "-Dmc68hc1x"
+#define TARGET_CPU_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("mc68hc1x"); \
+ } \
+ while (0)
/* As an embedded target, we have no libc. */
-#define inhibit_libc
+#ifndef inhibit_libc
+# define inhibit_libc
+#endif
/* Forward type declaration for prototypes definitions.
rtx_ptr is equivalent to rtx. Can't use the same name. */
#define MASK_AUTO_INC_DEC 0004
#define MASK_M6811 0010
#define MASK_M6812 0020
+#define MASK_M68S12 0040
+#define MASK_NO_DIRECT_MODE 0100
+#define MASK_MIN_MAX 0200
+#define MASK_LONG_CALLS 0400
#define TARGET_OP_TIME (optimize && optimize_size == 0)
#define TARGET_SHORT (target_flags & MASK_SHORT)
#define TARGET_M6811 (target_flags & MASK_M6811)
#define TARGET_M6812 (target_flags & MASK_M6812)
+#define TARGET_M68S12 (target_flags & MASK_M68S12)
#define TARGET_AUTO_INC_DEC (target_flags & MASK_AUTO_INC_DEC)
+#define TARGET_MIN_MAX (target_flags & MASK_MIN_MAX)
+#define TARGET_NO_DIRECT_MODE (target_flags & MASK_NO_DIRECT_MODE)
+#define TARGET_RELAX (TARGET_NO_DIRECT_MODE)
+#define TARGET_LONG_CALLS (target_flags & MASK_LONG_CALLS)
/* Default target_flags if no switches specified. */
#ifndef TARGET_DEFAULT
N_("Auto pre/post decrement increment allowed")}, \
{ "noauto-incdec", - MASK_AUTO_INC_DEC, \
N_("Auto pre/post decrement increment not allowed")}, \
+ { "inmax", MASK_MIN_MAX, \
+ N_("Min/max instructions allowed")}, \
+ { "nominmax", - MASK_MIN_MAX, \
+ N_("Min/max instructions not allowed")}, \
+ { "long-calls", MASK_LONG_CALLS, \
+ N_("Use call and rtc for function calls and returns")}, \
+ { "nolong-calls", - MASK_LONG_CALLS, \
+ N_("Use jsr and rts for function calls and returns")}, \
+ { "relax", MASK_NO_DIRECT_MODE, \
+ N_("Do not use direct addressing mode for soft registers")},\
+ { "norelax", -MASK_NO_DIRECT_MODE, \
+ N_("Use direct addressing mode for soft registers")}, \
{ "68hc11", MASK_M6811, \
N_("Compile for a 68HC11")}, \
{ "68hc12", MASK_M6812, \
N_("Compile for a 68HC12")}, \
+ { "68hcs12", MASK_M6812 | MASK_M68S12, \
+ N_("Compile for a 68HCS12")}, \
{ "6811", MASK_M6811, \
N_("Compile for a 68HC11")}, \
{ "6812", MASK_M6812, \
N_("Compile for a 68HC12")}, \
+ { "68S12", MASK_M6812 | MASK_M68S12, \
+ N_("Compile for a 68HCS12")}, \
{ "", TARGET_DEFAULT, 0 }}
/* This macro is similar to `TARGET_SWITCHES' but defines names of
by appending `-m' to the specified name. */
#define TARGET_OPTIONS \
{ { "reg-alloc=", &m68hc11_reg_alloc_order, \
- N_("Specify the register allocation order")}, \
+ N_("Specify the register allocation order"), 0}, \
{ "soft-reg-count=", &m68hc11_soft_reg_count, \
- N_("Indicate the number of soft registers available") }, \
+ N_("Indicate the number of soft registers available"), 0}, \
SUBTARGET_OPTIONS \
}
#endif
/* Print subsidiary information on the compiler version in use. */
-#define TARGET_VERSION fprintf (stderr, " (MC68HC11/MC68HC12)")
+#define TARGET_VERSION fprintf (stderr, " (MC68HC11/MC68HC12/MC68HCS12)")
/* Sometimes certain combinations of command options do not make
sense on a particular target machine. You can define a macro
/* Define this if most significant word of a multiword number is numbered. */
#define WORDS_BIG_ENDIAN 1
-/* Number of bits in a word */
-#define BITS_PER_WORD 16
-
/* Width of a word, in units (bytes). */
-#define UNITS_PER_WORD (BITS_PER_WORD/8)
-
-/* Define if you don't want extended real, but do want to use the
- software floating point emulator for REAL_ARITHMETIC and
- decimal <-> binary conversion. */
-#define REAL_ARITHMETIC
-
-/* Width in bits of a pointer. See also the macro `Pmode' defined below. */
-#define POINTER_SIZE 16
+#define UNITS_PER_WORD 2
/* Definition of size_t. This is really an unsigned short as the
68hc11 only handles a 64K address space. */
this size or smaller can be used for structures and unions with the
appropriate sizes. */
#define MAX_FIXED_MODE_SIZE 64
-
-/* Floats are checked in a generic way. */
-/* #define CHECK_FLOAT_VALUE(MODE, D, OVERFLOW) */
-
-
\f
/* target machine storage layout */
/* Size (bits) of the type "long long" on target machine */
#define LONG_LONG_TYPE_SIZE 64
-/* Size (bits) of the type "char" on target machine */
-#define CHAR_TYPE_SIZE 8
-
/* A C expression for the size in bits of the type `float' on the
target machine. If you don't define this, the default is one word.
Don't use default: a word is only 16. */
/* Value is 1 if it is a good idea to tie two pseudo registers when one has
mode MODE1 and one has mode MODE2. If HARD_REGNO_MODE_OK could produce
different values for MODE1 and MODE2, for any hard reg, then this must be
- 0 for correct output. */
+ 0 for correct output.
+
+ All modes are tieable except QImode. */
#define MODES_TIEABLE_P(MODE1, MODE2) \
(((MODE1) == (MODE2)) \
- || ((MODE1) == SImode && (MODE2) == HImode) \
- || ((MODE1) == HImode && (MODE2) == SImode))
+ || ((MODE1) != QImode && (MODE2) != QImode))
\f
/* Define the classes of registers for register constraints in the
D_OR_S_REGS, /* 16-bit soft register or D register */
X_OR_S_REGS, /* 16-bit soft register or X register */
Y_OR_S_REGS, /* 16-bit soft register or Y register */
+ Z_OR_S_REGS, /* 16-bit soft register or Z register */
SP_OR_S_REGS, /* 16-bit soft register or SP register */
D_OR_X_OR_S_REGS, /* 16-bit soft register or D or X register */
D_OR_Y_OR_S_REGS, /* 16-bit soft register or D or Y register */
"D_OR_S_REGS", \
"X_OR_S_REGS", \
"Y_OR_S_REGS", \
+ "Z_OR_S_REGS", \
"SP_OR_S_REGS", \
"D_OR_X_OR_S_REGS", \
"D_OR_Y_OR_S_REGS", \
/* SP_REGS */ { 0x00000008, 0x00000000 }, /* SP */ \
/* DA_REGS */ { 0x00000020, 0x00000000 }, /* A */ \
/* DB_REGS */ { 0x00000040, 0x00000000 }, /* B */ \
-/* D8_REGS */ { 0x00000060, 0x00000000 }, /* A B */ \
/* Z_REGS */ { 0x00000100, 0x00000000 }, /* Z */ \
+/* D8_REGS */ { 0x00000060, 0x00000000 }, /* A B */ \
/* Q_REGS */ { 0x00000062, 0x00000000 }, /* A B D */ \
/* D_OR_X_REGS */ { 0x00000003, 0x00000000 }, /* D X */ \
/* D_OR_Y_REGS */ { 0x00000006, 0x00000000 }, /* D Y */ \
/* D_OR_S_REGS */ { 0xFFFFDE02, 0x00007FFF }, /* D _.D */ \
/* X_OR_S_REGS */ { 0xFFFFDE01, 0x00007FFF }, /* X _.D */ \
/* Y_OR_S_REGS */ { 0xFFFFDE04, 0x00007FFF }, /* Y _.D */ \
+/* Z_OR_S_REGS */ { 0xFFFFDF00, 0x00007FFF }, /* Z _.D */ \
/* SP_OR_S_REGS */ { 0xFFFFDE08, 0x00007FFF }, /* SP _.D */ \
/* D_OR_X_OR_S_REGS */ { 0xFFFFDE03, 0x00007FFF }, /* D X _.D */ \
/* D_OR_Y_OR_S_REGS */ { 0xFFFFDE06, 0x00007FFF }, /* D Y _.D */ \
#define SMALL_REGISTER_CLASSES 1
+/* A C expression that is nonzero if hard register number REGNO2 can be
+ considered for use as a rename register for REGNO1 */
+
+#define HARD_REGNO_RENAME_OK(REGNO1,REGNO2) \
+ m68hc11_hard_regno_rename_ok ((REGNO1), (REGNO2))
+
/* A C expression whose value is nonzero if pseudos that have been
assigned to registers of class CLASS would likely be spilled
because registers of CLASS are needed for spill registers.
C is the letter, and VALUE is a constant value.
Return 1 if VALUE is in the range specified by C.
+ `K' is for 0.
`L' is for range -65536 to 65536
`M' is for values whose 16-bit low part is 0
'N' is for +1 or -1.
'O' is for 16 (for rotate using swap).
'P' is for range -8 to 2 (used by addhi_sp)
- 'I', 'J', 'K' are not used. */
+ 'I', 'J' are not used. */
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'L' ? (VALUE) >= -65536 && (VALUE) <= 65535 : \
+ ((C) == 'K' ? (VALUE) == 0 : \
+ (C) == 'L' ? ((VALUE) >= -65536 && (VALUE) <= 65535) : \
(C) == 'M' ? ((VALUE) & 0x0ffffL) == 0 : \
- (C) == 'N' ? ((VALUE) == 1 || (VALUE) == -1): \
+ (C) == 'N' ? ((VALUE) == 1 || (VALUE) == -1) : \
+ (C) == 'I' ? ((VALUE) >= -2 && (VALUE) <= 2) : \
(C) == 'O' ? (VALUE) == 16 : \
- (C) == 'P' ? (VALUE) <= 2 && (VALUE) >= -8 : 0)
+ (C) == 'P' ? ((VALUE) <= 2 && (VALUE) >= -8) : 0)
/* Similar, but for floating constants, and defining letters G and H.
- No floating-point constants are valid on 68HC11. */
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
+
+ `G' is for 0.0. */
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
+ ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
+ && VALUE == CONST0_RTX (GET_MODE (VALUE))) : 0)
/* 'U' represents certain kind of memory indexed operand for 68HC12.
- and any memory operand for 68HC11. */
+ and any memory operand for 68HC11.
+ 'R' represents indexed addressing mode or access to page0 for 68HC11.
+ For 68HC12, it represents any memory operand. */
#define EXTRA_CONSTRAINT(OP, C) \
-((C) == 'U' ? m68hc11_small_indexed_indirect_p (OP, GET_MODE (OP)) : 0)
-
+((C) == 'U' ? m68hc11_small_indexed_indirect_p (OP, GET_MODE (OP)) \
+ : (C) == 'Q' ? m68hc11_symbolic_p (OP, GET_MODE (OP)) \
+ : (C) == 'R' ? m68hc11_indirect_p (OP, GET_MODE (OP)) \
+ : (C) == 'S' ? (memory_operand (OP, GET_MODE (OP)) \
+ && non_push_operand (OP, GET_MODE (OP))) : 0)
\f
/* Stack layout; function entry, exit and calling. */
followed by "to". Eliminations of the same "from" register are listed
in order of preference.
- We have two registers that are eliminated on the 6811. The psuedo arg
+ We have two registers that are eliminated on the 6811. The pseudo arg
pointer and pseudo frame pointer registers can always be eliminated;
they are replaced with either the stack or the real frame pointer. */
\f
/* Passing Function Arguments on the Stack. */
-/* When a prototype says `char' or `short', really pass an `int'. */
-/* #define PROMOTE_PROTOTYPES */
-
/* If we generate an insn to push BYTES bytes, this says how many the
stack pointer really advances by. No rounding or alignment needed
for MC6811. */
The standard MC6811 call, with arg count word, includes popping the
args as part of the call template. */
#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
-
-/* Nonzero if type TYPE should be returned in memory.
- Blocks and data types largers than 4 bytes cannot be returned
- in the register (D + X = 4). */
-#define RETURN_IN_MEMORY(TYPE) \
- ((TYPE_MODE (TYPE) == BLKmode) \
- ? (int_size_in_bytes (TYPE) > 4) \
- : (GET_MODE_SIZE (TYPE_MODE (TYPE)) > 4))
-
\f
/* Passing Arguments in Registers. */
int nregs;
} CUMULATIVE_ARGS;
-/* A C expression that indicates when an argument must be passed by reference.
- If nonzero for an argument, a copy of that argument is made in memory and a
- pointer to the argument is passed instead of the argument itself.
- The pointer is passed in whatever way is appropriate for passing a pointer
- to that type.
-
- 64-bit numbers are passed by reference. */
-#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
- m68hc11_function_arg_pass_by_reference (& (CUM), (MODE), (TYPE), (NAMED))
-
-
/* If defined, a C expression which determines whether, and in which direction,
to pad out an argument with extra space. The value should be of type
`enum direction': either `upward' to pad above the argument,
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
m68hc11_function_arg_padding ((MODE), (TYPE))
-/* A C expression that indicates when it is the called function's
- responsibility to make a copy of arguments passed by invisible
- reference. Normally, the caller makes a copy and passes the
- address of the copy to the routine being called. When
- FUNCTION_ARG_CALLEE_COPIES is defined and is nonzero, the caller
- does not make a copy. Instead, it passes a pointer to the "live"
- value. The called function must not modify this value. If it can
- be determined that the value won't be modified, it need not make a
- copy; otherwise a copy must be made. */
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
- ((NAMED) && FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED))
+#undef PAD_VARARGS_DOWN
+#define PAD_VARARGS_DOWN \
+ (m68hc11_function_arg_padding (TYPE_MODE (type), type) == downward)
/* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a
function whose data type is FNTYPE. For a library call, FNTYPE is 0. */
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
(m68hc11_init_cumulative_args (&CUM, FNTYPE, LIBNAME))
/* Update the data in CUM to advance over an argument of mode MODE and data
caller saving results in spill failure. */
#define CALLER_SAVE_PROFITABLE(REFS,CALLS) 0
-/* Implement `va_arg'. */
-#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \
- m68hc11_expand_builtin_va_start (stdarg, valist, nextarg)
-
-#define EXPAND_BUILTIN_VA_ARG(valist, type) \
- m68hc11_va_arg (valist, type)
-
-/* For an arg passed partly in registers and partly in memory,
- this is the number of registers used.
- For args passed entirely in registers or entirely in memory, zero.
-
- Passing an arg partly in register and memory does not work at all.
- Don't do that. */
-#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) (0)
-
/* 1 if N is a possible register number for function argument passing.
D is for 16-bit values, X is for 32-bit (X+D). */
#define FUNCTION_ARG_REGNO_P(N) \
The high part is passed in X and the low part in D.
For GCC, the register number must be HARD_X_REGNUM. */
#define FUNCTION_VALUE(VALTYPE, FUNC) \
- gen_rtx (REG, TYPE_MODE (VALTYPE), \
+ gen_rtx_REG (TYPE_MODE (VALTYPE), \
((TYPE_MODE (VALTYPE) == BLKmode \
|| GET_MODE_SIZE (TYPE_MODE (VALTYPE)) <= 2) \
? HARD_D_REGNUM : HARD_X_REGNUM))
#define LIBCALL_VALUE(MODE) \
- gen_rtx (REG, MODE, \
+ gen_rtx_REG (MODE, \
(((MODE) == BLKmode || GET_MODE_SIZE (MODE) <= 2) \
? HARD_D_REGNUM : HARD_X_REGNUM))
#define FUNCTION_VALUE_REGNO_P(N) \
((N) == HARD_D_REGNUM || (N) == HARD_X_REGNUM)
-/* Register in which address to store a structure value is passed to a
- function. */
-#define STRUCT_VALUE_REGNUM HARD_D_REGNUM
-
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
the stack pointer does not matter. The value is tested only in functions
that have frame pointers. No definition is equivalent to always zero. */
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
#define FUNCTION_PROFILER(FILE, LABELNO) \
- asm_fprintf (FILE, "\tldy\t.LP%d\n\tjsr mcount\n", (LABELNO))
+ fprintf (FILE, "\tldy\t.LP%d\n\tjsr mcount\n", (LABELNO))
/* Length in units of the trampoline for entering a nested function. */
#define TRAMPOLINE_SIZE (TARGET_M6811 ? 11 : 9)
m68hc11_initialize_trampoline ((TRAMP), (FNADDR), (CXT))
\f
-/* Define this macro if references to a symbol must be treated
- differently depending on something about the variable or function
- named by the symbol (such as what section it is in).
-
- For the 68HC11, we want to recognize trap handlers so that we
- handle calls to traps in a special manner (by issuing the trap).
- This information is stored in SYMBOL_REF_FLAG. */
-
-#define ENCODE_SECTION_INFO(DECL) m68hc11_encode_section_info (DECL)
-
-/* Override what GCC does for section info to let us recognize traps. */
-
-#define REDO_SECTION_INFO_P(DECL) 1
-
-/* `INIT_TARGET_OPTABS'
- Define this macro as a C statement that declares additional library
- routines renames existing ones. `init_optabs' calls this macro
- after initializing all the normal library routines.
-
- Overrides the memcpy */
-
-#define INIT_TARGET_OPTABS \
-do \
- { \
- memcpy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__memcpy"); \
- memcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__memcmp"); \
- memset_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__memset"); \
- } \
-while (0)
-
-\f
/* Addressing modes, and classification of registers for them. */
/* The 68HC12 has all the post/pre increment/decrement modes. */
a mode offset to access the lowest part of the data.
(For example, for an SImode, the last valid offset is 252.) */
#define VALID_CONSTANT_OFFSET_P(X,MODE) \
-((GET_CODE (X) == CONST_INT) && \
- ((INTVAL (X) >= VALID_MIN_OFFSET) \
- && ((INTVAL (X) <= VALID_MAX_OFFSET \
- - (HOST_WIDE_INT) (GET_MODE_SIZE (MODE) + 1)))))
+(((GET_CODE (X) == CONST_INT) && \
+ ((INTVAL (X) >= VALID_MIN_OFFSET) \
+ && ((INTVAL (X) <= VALID_MAX_OFFSET \
+ - (HOST_WIDE_INT) (GET_MODE_SIZE (MODE) + 1))))) \
+|| (TARGET_M6812 \
+ && ((GET_CODE (X) == SYMBOL_REF) \
+ || GET_CODE (X) == LABEL_REF \
+ || GET_CODE (X) == CONST)))
/* This is included to allow stack push/pop operations. Special hacks in the
md and m6811.c files exist to support this. */
#define NOTICE_UPDATE_CC(EXP, INSN) \
m68hc11_notice_update_cc ((EXP), (INSN))
-/* Compute the cost of computing a constant rtl expression RTX whose rtx-code
- is CODE. The body of this macro is a portion of a switch statement. If
- the code is computed here, return it with a return statement. Otherwise,
- break from the switch.
-
- Constants are cheap. Moving them in registers must be avoided
- because most instructions do not handle two register operands. */
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- /* Logical and arithmetic operations with a constant */ \
- /* operand are better because they are not supported */ \
- /* with two registers. */ \
- /* 'clr' is slow */ \
- if ((OUTER_CODE) == SET && (RTX) == const0_rtx) \
- /* After reload, the reload_cse pass checks the cost */ \
- /* to change a SET into a PLUS. Make const0 cheap. */ \
- return 1 - reload_completed; \
- else \
- return 0; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- if ((OUTER_CODE) == SET) \
- return 1 - reload_completed; \
- return 0; \
- case CONST_DOUBLE: \
- return 0;
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case ROTATE: \
- case ROTATERT: \
- case ASHIFT: \
- case LSHIFTRT: \
- case ASHIFTRT: \
- case MINUS: \
- case PLUS: \
- case AND: \
- case XOR: \
- case IOR: \
- case UDIV: \
- case DIV: \
- case MOD: \
- case MULT: \
- case NEG: \
- case SIGN_EXTEND: \
- case NOT: \
- case COMPARE: \
- case ZERO_EXTEND: \
- case IF_THEN_ELSE: \
- return m68hc11_rtx_costs (X, CODE, OUTER_CODE);
-
-/* An expression giving the cost of an addressing mode that contains
- ADDRESS. If not defined, the cost is computed from the ADDRESS
- expression and the `CONST_COSTS' values. */
-
-#define ADDRESS_COST(RTX) m68hc11_address_cost (RTX)
-
/* Move costs between classes of registers */
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
- (m68hc11_register_move_cost (CLASS1, CLASS2))
+ (m68hc11_register_move_cost (MODE, CLASS1, CLASS2))
/* Move cost between register and memory.
- Move to a 16-bit register is reasonable,
macro is used in only one place: `find_reloads_address' in reload.c.
For M68HC11, we handle large displacements of a base register
- by splitting the addend accors an addhi3 insn.
+ by splitting the addend across an addhi3 insn.
For M68HC12, the 64K offset range is available.
*/
#define TARGET_ASM_CONSTRUCTOR m68hc11_asm_out_constructor
#define TARGET_ASM_DESTRUCTOR m68hc11_asm_out_destructor
-/* This is how to begin an assembly language file. Most svr4 assemblers want
- at least a .file directive to come first, and some want to see a .version
- directive come right after that. Here we just establish a default
- which generates only the .file directive. If you need a .version
- directive for any specific target, you should override this definition
- in the target-specific file which includes this one. */
-
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- m68hc11_asm_file_start ((FILE), main_input_filename)
-
/* Comment character */
#define ASM_COMMENT_START ";"
no longer contain unusual constructs. */
#define ASM_APP_OFF "; End of inline assembler code\n#NO_APP\n"
-/* Output #ident as a .ident. */
-
-/* This is how to output the definition of a user-level label named NAME,
- such as the label on a static function or variable NAME. */
-
-#define ASM_OUTPUT_LABEL(FILE,NAME) \
- do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
-
+/* Write the extra assembler code needed to declare a function properly.
+ Some svr4 assemblers need to also have something extra said about the
+ function's return value. We allow for that here.
+
+ For 68HC12 we mark functions that return with 'rtc'. The linker
+ will ensure that a 'call' is really made (instead of 'jsr').
+ The debugger needs this information to correctly compute the stack frame.
+
+ For 68HC11/68HC12 we also mark interrupt handlers for gdb to
+ compute the correct stack frame. */
+
+#undef ASM_DECLARE_FUNCTION_NAME
+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
+ do \
+ { \
+ fprintf (FILE, "%s", TYPE_ASM_OP); \
+ assemble_name (FILE, NAME); \
+ putc (',', FILE); \
+ fprintf (FILE, TYPE_OPERAND_FMT, "function"); \
+ putc ('\n', FILE); \
+ \
+ if (current_function_far) \
+ { \
+ fprintf (FILE, "\t.far\t"); \
+ assemble_name (FILE, NAME); \
+ putc ('\n', FILE); \
+ } \
+ else if (current_function_interrupt \
+ || current_function_trap) \
+ { \
+ fprintf (FILE, "\t.interrupt\t"); \
+ assemble_name (FILE, NAME); \
+ putc ('\n', FILE); \
+ } \
+ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
+ ASM_OUTPUT_LABEL(FILE, NAME); \
+ } \
+ while (0)
-/* This is how to output a command to make the user-level label named NAME
- defined for reference from other files. */
-
-#define ASM_GLOBALIZE_LABEL(FILE,NAME) \
- do { fprintf (FILE, "%s", GLOBAL_ASM_OP); \
- assemble_name (FILE, NAME); \
- fputs ("\n", FILE);} while (0)
+/* Output #ident as a .ident. */
/* output external reference */
#define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME) \
assemble_name (FILE, NAME); \
fputs ("\n", FILE);}
-
-
-/* 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. */
-
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
-
/* How to refer to registers in assembler output. This sequence is indexed
by compiler's hard-register-number (see above). */
#define REGISTER_NAMES \
/* This is how to output an element of a case-vector that is relative. */
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
- asm_fprintf (FILE, "\t%s\tL%d-L%d\n", integer_asm_op (2, TRUE), VALUE, REL)
+ fprintf (FILE, "\t%s\tL%d-L%d\n", integer_asm_op (2, TRUE), VALUE, REL)
/* This is how to output an element of a case-vector that is absolute. */
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
- asm_fprintf (FILE, "\t%s\t.L%d\n", integer_asm_op (2, TRUE), VALUE)
+ fprintf (FILE, "\t%s\t.L%d\n", integer_asm_op (2, TRUE), VALUE)
/* This is how to output an assembler line that says to advance the
location counter to a multiple of 2**LOG bytes. */
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
do { \
if ((LOG) > 1) \
- asm_fprintf ((FILE), "%s\n", ALIGN_ASM_OP); \
+ fprintf ((FILE), "%s\n", ALIGN_ASM_OP); \
} while (0)
\f
/* Assembler Commands for Exception Regions. */
-/* Default values provided by GCC should be ok. Assumming that DWARF-2
+/* Default values provided by GCC should be ok. Assuming that DWARF-2
frame unwind info is ok for this platform. */
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+/* For the support of memory banks we need addresses that indicate
+ the page number. */
+#define DWARF2_ADDR_SIZE 4
+
+/* SCz 2003-07-08: Don't use as dwarf2 .file/.loc directives because
+ the linker is doing relaxation and it does not adjust the debug_line
+ sections when it shrinks the code. This results in invalid addresses
+ when debugging. This does not bless too much the HC11/HC12 as most
+ applications are embedded and small, hence a reasonable debug info.
+ This problem is known for binutils 2.13, 2.14 and mainline. */
+#undef HAVE_AS_DWARF2_DEBUG_LINE
+
/* The prefix for local labels. You should be able to define this as
an empty string, or any arbitrary string (such as ".", ".L%", etc)
without having to make any other changes to account for the specific
\f
/* Miscellaneous Parameters. */
-/* Define the codes that are matched by predicates in m68hc11.c. */
-#define PREDICATE_CODES \
-{"stack_register_operand", {SUBREG, REG}}, \
-{"d_register_operand", {SUBREG, REG}}, \
-{"hard_addr_reg_operand", {SUBREG, REG}}, \
-{"hard_reg_operand", {SUBREG, REG}}, \
-{"m68hc11_logical_operator", {AND, IOR, XOR}}, \
-{"m68hc11_arith_operator", {AND, IOR, XOR, PLUS, MINUS, \
- ASHIFT, ASHIFTRT, LSHIFTRT, \
- ROTATE, ROTATERT }}, \
-{"m68hc11_non_shift_operator", {AND, IOR, XOR, PLUS, MINUS}}, \
-{"m68hc11_unary_operator", {NEG, NOT, SIGN_EXTEND, ZERO_EXTEND}}, \
-{"non_push_operand", {SUBREG, REG, MEM}}, \
-{"reg_or_some_mem_operand", {SUBREG, REG, MEM}}, \
-{"tst_operand", {SUBREG, REG, MEM}}, \
-{"cmp_operand", {SUBREG, REG, MEM, SYMBOL_REF, LABEL_REF, \
- CONST_INT, CONST_DOUBLE}},
-
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */
#define CASE_VECTOR_MODE Pmode
purposes) so give the MEM rtx a byte's mode. */
#define FUNCTION_MODE QImode
-/* define SCCS_DIRECTIVE if SCCS directives should be ignored */
-#define SCCS_DIRECTIVE 1
-
-/* Allow $ in identifiers */
-#define DOLLARS_IN_IDENTIFIERS 1
-
-/* Machine-dependent reorg pass.
- Specific optimizations are defined here:
- - this pass changes the Z register into either X or Y
- (it preserves X/Y previous values in a memory slot in page0).
-
- When this pass is finished, the global variable
- 'z_replacement_completed' is set to 2. */
-#define MACHINE_DEPENDENT_REORG(X) m68hc11_reorg (X)
-
extern int debug_m6811;
extern int z_replacement_completed;
extern int current_function_interrupt;
extern int current_function_trap;
+extern int current_function_far;
+
+extern GTY(()) rtx m68hc11_compare_op0;
+extern GTY(()) rtx m68hc11_compare_op1;
+extern GTY(()) rtx m68hc11_soft_tmp_reg;
+extern GTY(()) rtx ix_reg;
+extern GTY(()) rtx iy_reg;
+extern GTY(()) rtx d_reg;