/* Names to predefine in the preprocessor for this target machine. */
-struct base_arch_s {
+struct base_arch_s
+{
/* Assembler only. */
int asm_only;
/* Core have 'EICALL' and 'EIJMP' instructions. */
int have_eijmp_eicall;
- /* Reserved for xmega architecture. */
- int reserved;
+ /* This is an XMEGA core. */
+ int xmega_p;
- /* Reserved for xmega architecture. */
- int reserved2;
+ /* This core has the RAMPD special function register
+ and thus also the RAMPX, RAMPY and RAMPZ registers. */
+ int have_rampd;
/* Default start of data section address for architecture. */
int default_data_section_start;
+ /* Offset between SFR address and RAM address:
+ SFR-address = RAM-address - sfr_offset */
+ int sfr_offset;
+
+ /* Architecture id to built-in define __AVR_ARCH__ (NULL -> no macro) */
const char *const macro;
/* Architecture name. */
ARCH_AVR4,
ARCH_AVR5,
ARCH_AVR51,
- ARCH_AVR6
+ ARCH_AVR6,
+ ARCH_AVRXMEGA2,
+ ARCH_AVRXMEGA4,
+ ARCH_AVRXMEGA5,
+ ARCH_AVRXMEGA6,
+ ARCH_AVRXMEGA7
};
struct mcu_type_s {
/* Stack pointer have 8 bits width. */
int short_sp;
+ /* Some AVR devices have a core erratum when skipping a 2-word instruction.
+ Skip instructions are: SBRC, SBRS, SBIC, SBIS, CPSE.
+ Problems will occur with return address is IRQ executes during the
+ skip sequence.
+
+ A support ticket from Atmel returned the following information:
+
+ Subject: (ATTicket:644469) On AVR skip-bug core Erratum
+ From: avr@atmel.com Date: 2011-07-27
+ (Please keep the subject when replying to this mail)
+
+ This errata exists only in AT90S8515 and ATmega103 devices.
+
+ For information please refer the following respective errata links
+ http://www.atmel.com/dyn/resources/prod_documents/doc2494.pdf
+ http://www.atmel.com/dyn/resources/prod_documents/doc1436.pdf */
+
+ /* Core Erratum: Must not skip 2-word instruction. */
+ int errata_skip;
+
/* Start of data section. */
int data_section_start;
+ /* Number of 64k segments in the flash. */
+ int n_flash;
+
/* Name of device library. */
const char *const library_name;
};
extern const struct mcu_type_s avr_mcu_types[];
extern const struct base_arch_s avr_arch_types[];
-#define TARGET_CPU_CPP_BUILTINS() avr_cpu_cpp_builtins (pfile)
+typedef struct
+{
+ /* Id of the address space as used in c_register_addr_space */
+ unsigned char id;
-#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)
-extern GTY(()) section *progmem_section;
-#endif
+ /* Flavour of memory: 0 = RAM, 1 = Flash */
+ int memory_class;
+
+ /* Width of pointer (in bytes) */
+ int pointer_size;
+
+ /* Name of the address space as visible to the user */
+ const char *name;
+
+ /* Segment (i.e. 64k memory chunk) number. */
+ int segment;
+
+ /* Section prefix, e.g. ".progmem1.data" */
+ const char *section_name;
+} avr_addrspace_t;
+
+extern const avr_addrspace_t avr_addrspace[];
+
+/* Known address spaces */
+
+enum
+ {
+ ADDR_SPACE_RAM, /* ADDR_SPACE_GENERIC */
+ ADDR_SPACE_FLASH,
+ ADDR_SPACE_FLASH1,
+ ADDR_SPACE_FLASH2,
+ ADDR_SPACE_FLASH3,
+ ADDR_SPACE_FLASH4,
+ ADDR_SPACE_FLASH5,
+ ADDR_SPACE_MEMX,
+ /* Sentinel */
+ ADDR_SPACE_COUNT
+ };
+
+#define TARGET_CPU_CPP_BUILTINS() avr_cpu_cpp_builtins (pfile)
#define AVR_HAVE_JMP_CALL (avr_current_arch->have_jmp_call && !TARGET_SHORT_CALLS)
#define AVR_HAVE_MUL (avr_current_arch->have_mul)
#define AVR_HAVE_MOVW (avr_current_arch->have_movw_lpmx)
#define AVR_HAVE_LPMX (avr_current_arch->have_movw_lpmx)
-#define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm)
+#define AVR_HAVE_ELPM (avr_current_arch->have_elpm)
+#define AVR_HAVE_ELPMX (avr_current_arch->have_elpmx)
+#define AVR_HAVE_RAMPD (avr_current_arch->have_rampd)
+#define AVR_HAVE_RAMPX (avr_current_arch->have_rampd)
+#define AVR_HAVE_RAMPY (avr_current_arch->have_rampd)
+#define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm \
+ || avr_current_arch->have_rampd)
#define AVR_HAVE_EIJMP_EICALL (avr_current_arch->have_eijmp_eicall)
-#define AVR_HAVE_8BIT_SP (avr_current_device->short_sp || TARGET_TINY_STACK)
+
+/* Handling of 8-bit SP versus 16-bit SP is as follows:
+
+ -msp8 is used internally to select the right multilib for targets with
+ 8-bit SP. -msp8 is set automatically by DRIVER_SELF_SPECS for devices
+ with 8-bit SP or by multilib generation machinery. If a frame pointer is
+ needed and SP is only 8 bits wide, SP is zero-extended to get FP.
+
+ TARGET_TINY_STACK is triggered by -mtiny-stack which is a user option.
+ This option has no effect on multilib selection. It serves to save some
+ bytes on 16-bit SP devices by only changing SP_L and leaving SP_H alone.
+
+ These two properties are reflected by built-in macros __AVR_SP8__ resp.
+ __AVR_HAVE_8BIT_SP__ and __AVR_HAVE_16BIT_SP__. During multilib generation
+ there is always __AVR_SP8__ == __AVR_HAVE_8BIT_SP__. */
+
+#define AVR_HAVE_8BIT_SP \
+ (avr_current_device->short_sp || TARGET_TINY_STACK || avr_sp8)
+
+#define AVR_HAVE_SPH (!avr_sp8)
#define AVR_2_BYTE_PC (!AVR_HAVE_EIJMP_EICALL)
#define AVR_3_BYTE_PC (AVR_HAVE_EIJMP_EICALL)
-#define TARGET_VERSION fprintf (stderr, " (GNU assembler syntax)");
+#define AVR_XMEGA (avr_current_arch->xmega_p)
#define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 0
/* No data type wants to be aligned rounder than this. */
#define BIGGEST_ALIGNMENT 8
-#define MAX_OFILE_ALIGNMENT (32768 * 8)
-
#define TARGET_VTABLE_ENTRY_ALIGN 8
#define STRICT_ALIGNMENT 0
#define REGNO_REG_CLASS(R) avr_regno_reg_class(R)
-/* The following macro defines cover classes for Integrated Register
- Allocator. Cover classes is a set of non-intersected register
- classes covering all hard registers used for register allocation
- purpose. Any move between two registers of a cover class should be
- cheaper than load or store of the registers. The macro value is
- array of register classes with LIM_REG_CLASSES used as the end
- marker. */
-
-#define IRA_COVER_CLASSES \
-{ \
- GENERAL_REGS, LIM_REG_CLASSES \
-}
-
-#define BASE_REG_CLASS (reload_completed ? BASE_POINTER_REGS : POINTER_REGS)
+#define MODE_CODE_BASE_REG_CLASS(mode, as, outer_code, index_code) \
+ avr_mode_code_base_reg_class (mode, as, outer_code, index_code)
#define INDEX_REG_CLASS NO_REGS
-#define REGNO_OK_FOR_BASE_P(r) (((r) < FIRST_PSEUDO_REGISTER \
- && ((r) == REG_X \
- || (r) == REG_Y \
- || (r) == REG_Z \
- || (r) == ARG_POINTER_REGNUM)) \
- || (reg_renumber \
- && (reg_renumber[r] == REG_X \
- || reg_renumber[r] == REG_Y \
- || reg_renumber[r] == REG_Z \
- || (reg_renumber[r] \
- == ARG_POINTER_REGNUM))))
+#define REGNO_MODE_CODE_OK_FOR_BASE_P(num, mode, as, outer_code, index_code) \
+ avr_regno_mode_code_ok_for_base_p (num, mode, as, outer_code, index_code)
#define REGNO_OK_FOR_INDEX_P(NUM) 0
-#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
+#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
+ avr_hard_regno_call_part_clobbered (REGNO, MODE)
-#define CLASS_MAX_NREGS(CLASS, MODE) class_max_nregs (CLASS, MODE)
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
#define STACK_PUSH_CODE POST_DEC
#define STACK_GROWS_DOWNWARD
-#define STARTING_FRAME_OFFSET 1
+#define STARTING_FRAME_OFFSET avr_starting_frame_offset()
#define STACK_POINTER_OFFSET 1
#define FUNCTION_ARG_REGNO_P(r) function_arg_regno_p(r)
-extern int avr_reg_order[];
-
-#define RET_REGISTER avr_ret_register ()
-
-#define LIBCALL_VALUE(MODE) avr_libcall_value (MODE)
-
-#define FUNCTION_VALUE_REGNO_P(N) ((int) (N) == RET_REGISTER)
-
#define DEFAULT_PCC_STRUCT_RETURN 0
#define EPILOGUE_USES(REGNO) avr_epilogue_uses(REGNO)
#define MAX_REGS_PER_ADDRESS 1
-#define REG_OK_FOR_BASE_NOSTRICT_P(X) \
- (REGNO (X) >= FIRST_PSEUDO_REGISTER || REG_OK_FOR_BASE_STRICT_P(X))
-
-#define REG_OK_FOR_BASE_STRICT_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
-
-/* LEGITIMIZE_RELOAD_ADDRESS will allow register R26/27 to be used, where it
- is no worse than normal base pointers R28/29 and R30/31. For example:
- If base offset is greater than 63 bytes or for R++ or --R addressing. */
-
-#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_LEVELS, WIN) \
-do { \
- if (1&&(GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC)) \
- { \
- push_reload (XEXP (X,0), XEXP (X,0), &XEXP (X,0), &XEXP (X,0), \
- POINTER_REGS, GET_MODE (X),GET_MODE (X) , 0, 0, \
- OPNUM, RELOAD_OTHER); \
- goto WIN; \
- } \
- if (GET_CODE (X) == PLUS \
- && REG_P (XEXP (X, 0)) \
- && reg_equiv_constant[REGNO (XEXP (X, 0))] == 0 \
- && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && INTVAL (XEXP (X, 1)) >= 1) \
- { \
- int fit = INTVAL (XEXP (X, 1)) <= (64 - GET_MODE_SIZE (MODE)); \
- if (fit) \
- { \
- if (reg_equiv_address[REGNO (XEXP (X, 0))] != 0) \
- { \
- int regno = REGNO (XEXP (X, 0)); \
- rtx mem = make_memloc (X, regno); \
- push_reload (XEXP (mem,0), NULL, &XEXP (mem,0), NULL, \
- POINTER_REGS, Pmode, VOIDmode, 0, 0, \
- 1, ADDR_TYPE (TYPE)); \
- push_reload (mem, NULL_RTX, &XEXP (X, 0), NULL, \
- BASE_POINTER_REGS, GET_MODE (X), VOIDmode, 0, 0, \
- OPNUM, TYPE); \
- goto WIN; \
- } \
- } \
- else if (! (frame_pointer_needed && XEXP (X,0) == frame_pointer_rtx)) \
- { \
- push_reload (X, NULL_RTX, &X, NULL, \
- POINTER_REGS, GET_MODE (X), VOIDmode, 0, 0, \
- OPNUM, TYPE); \
- goto WIN; \
- } \
- } \
-} while(0)
-
-#define LEGITIMATE_CONSTANT_P(X) 1
-
-#define BRANCH_COST(speed_p, predictable_p) 0
+#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_L,WIN) \
+ do { \
+ rtx new_x = avr_legitimize_reload_address (&(X), MODE, OPNUM, TYPE, \
+ ADDR_TYPE (TYPE), \
+ IND_L, make_memloc); \
+ if (new_x) \
+ { \
+ X = new_x; \
+ goto WIN; \
+ } \
+ } while (0)
+
+#define BRANCH_COST(speed_p, predictable_p) avr_branch_cost
#define SLOW_BYTE_ACCESS 0
#define NO_FUNCTION_CSE
+#define REGISTER_TARGET_PRAGMAS() \
+ do { \
+ avr_register_target_pragmas(); \
+ } while (0)
+
#define TEXT_SECTION_ASM_OP "\t.text"
#define DATA_SECTION_ASM_OP "\t.data"
#define ASM_APP_OFF "/* #NOAPP */\n"
-/* Switch into a generic section. */
-#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
-#define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
-
-#define ASM_OUTPUT_ASCII(FILE, P, SIZE) gas_output_ascii (FILE,P,SIZE)
-
#define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == '\n' || ((C) == '$'))
-#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
-do { \
- fputs ("\t.comm ", (STREAM)); \
- assemble_name ((STREAM), (NAME)); \
- fprintf ((STREAM), ",%lu,1\n", (unsigned long)(SIZE)); \
-} while (0)
-
-#define ASM_OUTPUT_BSS(FILE, DECL, NAME, SIZE, ROUNDED) \
- asm_output_bss ((FILE), (DECL), (NAME), (SIZE), (ROUNDED))
-
-#define ASM_OUTPUT_LOCAL(STREAM, NAME, SIZE, ROUNDED) \
-do { \
- fputs ("\t.lcomm ", (STREAM)); \
- assemble_name ((STREAM), (NAME)); \
- fprintf ((STREAM), ",%d\n", (int)(SIZE)); \
-} while (0)
-
-#undef TYPE_ASM_OP
-#undef SIZE_ASM_OP
-#undef WEAK_ASM_OP
-#define TYPE_ASM_OP "\t.type\t"
-#define SIZE_ASM_OP "\t.size\t"
-#define WEAK_ASM_OP "\t.weak\t"
-/* Define the strings used for the special svr4 .type and .size directives.
- These strings generally do not vary from one system running svr4 to
- another, but if a given system (e.g. m88k running svr) needs to use
- different pseudo-op names for these, they may be overridden in the
- file which includes this one. */
-
-
-#undef TYPE_OPERAND_FMT
-#define TYPE_OPERAND_FMT "@%s"
-/* The following macro defines the format used to output the second
- operand of the .type assembler directive. Different svr4 assemblers
- expect various different forms for this operand. The one given here
- is just a default. You may need to override it in your machine-
- specific tm.h file (depending upon the particulars of your assembler). */
-
-#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
-avr_asm_declare_function_name ((FILE), (NAME), (DECL))
-
-#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
- do { \
- if (!flag_inhibit_size_directive) \
- ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \
- } while (0)
+#define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGN) \
+ avr_asm_output_aligned_decl_common (STREAM, DECL, NAME, SIZE, ALIGN, false)
-#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
-do { \
- ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
- size_directive_output = 0; \
- if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \
- { \
- size_directive_output = 1; \
- ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, \
- int_size_in_bytes (TREE_TYPE (DECL))); \
- } \
- ASM_OUTPUT_LABEL(FILE, NAME); \
-} while (0)
-
-#undef ASM_FINISH_DECLARE_OBJECT
-#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
-do { \
- const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
- HOST_WIDE_INT size; \
- if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \
- && ! AT_END && TOP_LEVEL \
- && DECL_INITIAL (DECL) == error_mark_node \
- && !size_directive_output) \
- { \
- size_directive_output = 1; \
- size = int_size_in_bytes (TREE_TYPE (DECL)); \
- ASM_OUTPUT_SIZE_DIRECTIVE (FILE, name, size); \
- } \
- } while (0)
-
-
-#define ESCAPES \
-"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
-\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\
-\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
-\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
-\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
-\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"
-/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
- ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
- corresponds to a particular byte value [0..255]. For any
- given byte value, if the value in the corresponding table
- position is zero, the given character can be output directly.
- If the table value is 1, the byte must be output as a \ooo
- octal escape. If the tables value is anything else, then the
- byte value should be output as a \ followed by the value
- in the table. Note that we can use standard UN*X escape
- sequences for many control characters, but we don't use
- \a to represent BEL because some svr4 assemblers (e.g. on
- the i386) don't know about that. Also, we don't use \v
- since some versions of gas, such as 2.2 did not accept it. */
-
-#define STRING_LIMIT ((unsigned) 64)
-#define STRING_ASM_OP "\t.string\t"
-/* Some svr4 assemblers have a limit on the number of characters which
- can appear in the operand of a .string directive. If your assembler
- has such a limitation, you should define STRING_LIMIT to reflect that
- limit. Note that at least some svr4 assemblers have a limit on the
- actual number of bytes in the double-quoted string, and that they
- count each character in an escape sequence as one byte. Thus, an
- escape sequence like \377 would count as four bytes.
-
- If your target assembler doesn't support the .string directive, you
- should define this to zero. */
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+ asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
+
+#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGN) \
+ avr_asm_output_aligned_decl_common (STREAM, DECL, NAME, SIZE, ALIGN, true)
/* Globalizing directive for a label. */
#define GLOBAL_ASM_OP ".global\t"
-#define SET_ASM_OP "\t.set\t"
-
-#define ASM_WEAKEN_LABEL(FILE, NAME) \
- do \
- { \
- fputs ("\t.weak\t", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputc ('\n', (FILE)); \
- } \
- while (0)
-
#define SUPPORTS_WEAK 1
-#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
-sprintf (STRING, "*.%s%lu", PREFIX, (unsigned long)(NUM))
-
#define HAS_INIT_SECTION 1
#define REGISTER_NAMES { \
#define FINAL_PRESCAN_INSN(insn, operand, nop) final_prescan_insn (insn, operand,nop)
-#define PRINT_OPERAND(STREAM, X, CODE) print_operand (STREAM, X, CODE)
-
-#define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '~' || (CODE) == '!')
-
-#define PRINT_OPERAND_ADDRESS(STREAM, X) print_operand_address(STREAM, X)
-
-#define USER_LABEL_PREFIX ""
-
-#define ASSEMBLER_DIALECT AVR_HAVE_MOVW
-
#define ASM_OUTPUT_REG_PUSH(STREAM, REGNO) \
{ \
gcc_assert (REGNO < 32); \
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
avr_output_addr_vec_elt(STREAM, VALUE)
-#define ASM_OUTPUT_CASE_LABEL(STREAM, PREFIX, NUM, TABLE) \
- (switch_to_section (progmem_section), \
- (*targetm.asm_out.internal_label) (STREAM, PREFIX, NUM))
-
-#define ASM_OUTPUT_SKIP(STREAM, N) \
-fprintf (STREAM, "\t.skip %lu,0\n", (unsigned long)(N))
-
-#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
- do { \
- if ((POWER) > 1) \
- fprintf (STREAM, "\t.p2align\t%d\n", POWER); \
+#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
+ do { \
+ if ((POWER) > 0) \
+ fprintf (STREAM, "\t.p2align\t%d\n", POWER); \
} while (0)
-#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
- default_elf_asm_output_external (FILE, DECL, NAME)
-
#define CASE_VECTOR_MODE HImode
#undef WORD_REGISTER_OPERATIONS
#define DOLLARS_IN_IDENTIFIERS 0
-#define NO_DOLLAR_IN_LABEL 1
-
#define TRAMPOLINE_SIZE 4
/* Store in cc_status the expressions
extern const char *avr_device_to_data_start (int argc, const char **argv);
extern const char *avr_device_to_startfiles (int argc, const char **argv);
extern const char *avr_device_to_devicelib (int argc, const char **argv);
+extern const char *avr_device_to_sp8 (int argc, const char **argv);
-#define EXTRA_SPEC_FUNCTIONS \
- { "device_to_arch", avr_device_to_arch }, \
+#define EXTRA_SPEC_FUNCTIONS \
+ { "device_to_arch", avr_device_to_arch }, \
{ "device_to_data_start", avr_device_to_data_start }, \
- { "device_to_startfile", avr_device_to_startfiles }, \
- { "device_to_devicelib", avr_device_to_devicelib },
+ { "device_to_startfile", avr_device_to_startfiles }, \
+ { "device_to_devicelib", avr_device_to_devicelib }, \
+ { "device_to_sp8", avr_device_to_sp8 },
+#define DRIVER_SELF_SPECS " %:device_to_sp8(%{mmcu=*:%*}) "
#define CPP_SPEC ""
#define CC1_SPEC ""
pass to `cc1plus'. */
#define ASM_SPEC "%{mmcu=avr25:-mmcu=avr2;mmcu=avr35:-mmcu=avr3;mmcu=avr31:-mmcu=avr3;mmcu=avr51:-mmcu=avr5;\
-mmcu=*:-mmcu=%*}"
+mmcu=*:-mmcu=%*} \
+%{mmcu=*:%{!mmcu=avr2:%{!mmcu=at90s8515:%{!mmcu=avr31:%{!mmcu=atmega103:\
+-mno-skip-bug}}}}}"
#define LINK_SPEC "\
%{mrelax:--relax\
#define TEST_HARD_REG_CLASS(CLASS, REGNO) \
TEST_HARD_REG_BIT (reg_class_contents[ (int) (CLASS)], REGNO)
-/* Note that the other files fail to use these
- in some of the places where they should. */
-
-#if defined(__STDC__) || defined(ALMOST_STDC)
-#define AS2(a,b,c) #a " " #b "," #c
-#define AS2C(b,c) " " #b "," #c
-#define AS3(a,b,c,d) #a " " #b "," #c "," #d
-#define AS1(a,b) #a " " #b
-#else
-#define AS1(a,b) "a b"
-#define AS2(a,b,c) "a b,c"
-#define AS2C(b,c) " b,c"
-#define AS3(a,b,c,d) "a b,c,d"
-#endif
-#define OUT_AS1(a,b) output_asm_insn (AS1(a,b), operands)
-#define OUT_AS2(a,b,c) output_asm_insn (AS2(a,b,c), operands)
#define CR_TAB "\n\t"
-#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-
-#define DWARF2_DEBUGGING_INFO 1
-
#define DWARF2_ADDR_SIZE 4
-#define OBJECT_FORMAT_ELF
+#define INCOMING_RETURN_ADDR_RTX avr_incoming_return_addr_rtx ()
+#define INCOMING_FRAME_SP_OFFSET (AVR_3_BYTE_PC ? 3 : 2)
+
+/* The caller's stack pointer value immediately before the call
+ is one byte below the first argument. */
+#define ARG_POINTER_CFA_OFFSET(FNDECL) -1
#define INCOMING_RETURN_ADDR_RTX avr_incoming_return_addr_rtx ()
#define INCOMING_FRAME_SP_OFFSET (AVR_3_BYTE_PC ? 3 : 2)
/* Current function stack size. */
int stack_usage;
+
+ /* 'true' if a callee might be tail called */
+ int sibcall_fails;
+
+ /* 'true' if the above is_foo predicates are sanity-checked to avoid
+ multiple diagnose for the same function. */
+ int attributes_checked_p;
};
+
+/* AVR does not round pushes, but the existance of this macro is
+ required in order for pushes to be generated. */
+#define PUSH_ROUNDING(X) (X)
+
+/* Define prototype here to avoid build warning. Some files using
+ ACCUMULATE_OUTGOING_ARGS (directly or indirectly) include
+ tm.h but not tm_p.h. */
+extern int avr_accumulate_outgoing_args (void);
+#define ACCUMULATE_OUTGOING_ARGS avr_accumulate_outgoing_args()
+
+#define INIT_EXPANDERS avr_init_expanders()