/* Definitions of target machine for GNU compiler,
for ATMEL AVR at90s8515, ATmega103/103L, ATmega603/603L microcontrollers.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 1998-2020 Free Software Foundation, Inc.
Contributed by Denis Chertykov (chertykov@gmail.com)
This file is part of GCC.
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
-/* Names to predefine in the preprocessor for this target machine. */
-
-struct base_arch_s {
- /* Assembler only. */
- int asm_only;
-
- /* Core have 'MUL*' instructions. */
- int have_mul;
-
- /* Core have 'CALL' and 'JMP' instructions. */
- int have_jmp_call;
-
- /* Core have 'MOVW' and 'LPM Rx,Z' instructions. */
- int have_movw_lpmx;
-
- /* Core have 'ELPM' instructions. */
- int have_elpm;
-
- /* Core have 'ELPM Rx,Z' instructions. */
- int have_elpmx;
-
- /* Core have 'EICALL' and 'EIJMP' instructions. */
- int have_eijmp_eicall;
-
- /* Reserved for xmega architecture. */
- int reserved;
-
- /* Reserved for xmega architecture. */
- int reserved2;
-
- /* Default start of data section address for architecture. */
- int default_data_section_start;
-
- const char *const macro;
-
- /* Architecture name. */
- const char *const arch_name;
-};
-
-/* These names are used as the index into the avr_arch_types[] table
- above. */
-
-enum avr_arch
+typedef struct
{
- ARCH_UNKNOWN,
- ARCH_AVR1,
- ARCH_AVR2,
- ARCH_AVR25,
- ARCH_AVR3,
- ARCH_AVR31,
- ARCH_AVR35,
- ARCH_AVR4,
- ARCH_AVR5,
- ARCH_AVR51,
- ARCH_AVR6
-};
+ /* Id of the address space as used in c_register_addr_space */
+ unsigned char id;
-struct mcu_type_s {
- /* Device name. */
- const char *const name;
-
- /* Index in avr_arch_types[]. */
- int arch;
-
- /* Must lie outside user's namespace. NULL == no macro. */
- const char *const macro;
-
- /* 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.
+ /* Flavour of memory: 0 = RAM, 1 = Flash */
+ int memory_class;
- A support ticket from Atmel returned the following information:
+ /* Width of pointer (in bytes) */
+ int pointer_size;
- 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)
+ /* Name of the address space as visible to the user */
+ const char *name;
- This errata exists only in AT90S8515 and ATmega103 devices.
+ /* Segment (i.e. 64k memory chunk) number. */
+ int segment;
- 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 */
+ /* Section prefix, e.g. ".progmem1.data" */
+ const char *section_name;
+} avr_addrspace_t;
- /* Core Erratum: Must not skip 2-word instruction. */
- int errata_skip;
-
- /* Start of data section. */
- int data_section_start;
-
- /* Name of device library. */
- const char *const library_name;
-};
+extern const avr_addrspace_t avr_addrspace[];
-/* Preprocessor macros to define depending on MCU type. */
-extern const char *avr_extra_arch_macro;
-extern const struct base_arch_s *avr_current_arch;
-extern const struct mcu_type_s *avr_current_device;
-extern const struct mcu_type_s avr_mcu_types[];
-extern const struct base_arch_s avr_arch_types[];
+/* 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_EIJMP_EICALL (avr_current_arch->have_eijmp_eicall)
-#define AVR_HAVE_8BIT_SP (avr_current_device->short_sp || TARGET_TINY_STACK)
+#define AVR_SHORT_CALLS (TARGET_SHORT_CALLS \
+ && avr_arch == &avr_arch_types[ARCH_AVRXMEGA3])
+#define AVR_HAVE_JMP_CALL (avr_arch->have_jmp_call && ! AVR_SHORT_CALLS)
+#define AVR_HAVE_MUL (avr_arch->have_mul)
+#define AVR_HAVE_MOVW (avr_arch->have_movw_lpmx)
+#define AVR_HAVE_LPM (!AVR_TINY)
+#define AVR_HAVE_LPMX (avr_arch->have_movw_lpmx)
+#define AVR_HAVE_ELPM (avr_arch->have_elpm)
+#define AVR_HAVE_ELPMX (avr_arch->have_elpmx)
+#define AVR_HAVE_RAMPD (avr_arch->have_rampd)
+#define AVR_HAVE_RAMPX (avr_arch->have_rampd)
+#define AVR_HAVE_RAMPY (avr_arch->have_rampd)
+#define AVR_HAVE_RAMPZ (avr_arch->have_elpm \
+ || avr_arch->have_rampd)
+#define AVR_HAVE_EIJMP_EICALL (avr_arch->have_eijmp_eicall)
+
+/* Handling of 8-bit SP versus 16-bit SP is as follows:
+
+FIXME: DRIVER_SELF_SPECS has changed.
+ -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 \
+ (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 AVR_XMEGA (avr_arch->xmega_p)
+#define AVR_TINY (avr_arch->tiny_p)
+
#define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 0
#define WORDS_BIG_ENDIAN 0
#define LONG_TYPE_SIZE (INT_TYPE_SIZE == 8 ? 16 : 32)
#define LONG_LONG_TYPE_SIZE (INT_TYPE_SIZE == 8 ? 32 : 64)
#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE 32
-#define LONG_DOUBLE_TYPE_SIZE 32
+#define DOUBLE_TYPE_SIZE (avr_double)
+#define LONG_DOUBLE_TYPE_SIZE (avr_long_double)
+
+#define LONG_LONG_ACCUM_TYPE_SIZE 64
#define DEFAULT_SIGNED_CHAR 1
#define FIRST_PSEUDO_REGISTER 36
+#define GENERAL_REGNO_P(N) IN_RANGE (N, 2, 31)
+#define GENERAL_REG_P(X) (REG_P (X) && GENERAL_REGNO_P (REGNO (X)))
+
#define FIXED_REGISTERS {\
1,1,/* r0 r1 */\
0,0,/* r2 r3 */\
32,33,34,35 \
}
-#define ADJUST_REG_ALLOC_ORDER order_regs_for_local_alloc ()
-
-
-#define HARD_REGNO_NREGS(REGNO, MODE) ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
-#define HARD_REGNO_MODE_OK(REGNO, MODE) avr_hard_regno_mode_ok(REGNO, MODE)
+#define ADJUST_REG_ALLOC_ORDER avr_adjust_reg_alloc_order()
-#define MODES_TIEABLE_P(MODE1, MODE2) 1
enum reg_class {
NO_REGS,
#define REG_CLASS_CONTENTS { \
{0x00000000,0x00000000}, /* NO_REGS */ \
{0x00000001,0x00000000}, /* R0_REG */ \
- {3 << REG_X,0x00000000}, /* POINTER_X_REGS, r26 - r27 */ \
- {3 << REG_Y,0x00000000}, /* POINTER_Y_REGS, r28 - r29 */ \
- {3 << REG_Z,0x00000000}, /* POINTER_Z_REGS, r30 - r31 */ \
+ {3u << REG_X,0x00000000}, /* POINTER_X_REGS, r26 - r27 */ \
+ {3u << REG_Y,0x00000000}, /* POINTER_Y_REGS, r28 - r29 */ \
+ {3u << REG_Z,0x00000000}, /* POINTER_Z_REGS, r30 - r31 */ \
{0x00000000,0x00000003}, /* STACK_REG, STACK */ \
- {(3 << REG_Y) | (3 << REG_Z), \
+ {(3u << REG_Y) | (3u << REG_Z), \
0x00000000}, /* BASE_POINTER_REGS, r28 - r31 */ \
- {(3 << REG_X) | (3 << REG_Y) | (3 << REG_Z), \
+ {(3u << REG_X) | (3u << REG_Y) | (3u << REG_Z), \
0x00000000}, /* POINTER_REGS, r26 - r31 */ \
- {(3 << REG_X) | (3 << REG_Y) | (3 << REG_Z) | (3 << REG_W), \
+ {(3u << REG_X) | (3u << REG_Y) | (3u << REG_Z) | (3u << REG_W), \
0x00000000}, /* ADDW_REGS, r24 - r31 */ \
{0x00ff0000,0x00000000}, /* SIMPLE_LD_REGS r16 - r23 */ \
- {(3 << REG_X)|(3 << REG_Y)|(3 << REG_Z)|(3 << REG_W)|(0xff << 16), \
+ {(3u << REG_X)|(3u << REG_Y)|(3u << REG_Z)|(3u << REG_W)|(0xffu << 16),\
0x00000000}, /* LD_REGS, r16 - r31 */ \
{0x0000ffff,0x00000000}, /* NO_LD_REGS r0 - r15 */ \
{0xffffffff,0x00000000}, /* GENERAL_REGS, r0 - r31 */ \
#define REGNO_REG_CLASS(R) avr_regno_reg_class(R)
-#define MODE_CODE_BASE_REG_CLASS(mode, outer_code, index_code) \
- avr_mode_code_base_reg_class (mode, outer_code, index_code)
+#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_MODE_CODE_OK_FOR_BASE_P(num, mode, outer_code, index_code) \
- avr_regno_mode_code_ok_for_base_p (num, mode, outer_code, index_code)
+#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 STACK_PUSH_CODE POST_DEC
-#define STACK_GROWS_DOWNWARD
-
-#define STARTING_FRAME_OFFSET 1
+#define STACK_GROWS_DOWNWARD 1
#define STACK_POINTER_OFFSET 1
#define ARG_POINTER_REGNUM 34
-#define STATIC_CHAIN_REGNUM 2
+#define STATIC_CHAIN_REGNUM ((AVR_TINY) ? 18 :2)
#define ELIMINABLE_REGS { \
- {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
- {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
- ,{FRAME_POINTER_REGNUM+1,STACK_POINTER_REGNUM+1}}
+ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
+ { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
+ { FRAME_POINTER_REGNUM + 1, STACK_POINTER_REGNUM + 1 } }
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
OFFSET = avr_initial_elimination_offset (FROM, TO)
for POST_DEC targets (PR27386). */
/*#define PUSH_ROUNDING(NPUSHED) (NPUSHED)*/
-typedef struct avr_args {
- int nregs; /* # registers available for passing */
- int regno; /* next available register number */
+typedef struct avr_args
+{
+ /* # Registers available for passing */
+ int nregs;
+
+ /* Next available register number */
+ int regno;
} CUMULATIVE_ARGS;
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
- init_cumulative_args (&(CUM), FNTYPE, LIBNAME, FNDECL)
+ avr_init_cumulative_args (&(CUM), FNTYPE, LIBNAME, FNDECL)
-#define FUNCTION_ARG_REGNO_P(r) function_arg_regno_p(r)
+#define FUNCTION_ARG_REGNO_P(r) avr_function_arg_regno_p(r)
#define DEFAULT_PCC_STRUCT_RETURN 0
} \
} while (0)
-#define BRANCH_COST(speed_p, predictable_p) 0
+/* We increase branch costs after reload in order to keep basic-block
+ reordering from introducing out-of-line jumps and to prefer fall-through
+ edges instead. The default branch costs are 0, mainly because otherwise
+ do_store_flag might come up with bloated code. */
+#define BRANCH_COST(speed_p, predictable_p) \
+ (avr_branch_cost + (reload_completed ? 4 : 0))
#define SLOW_BYTE_ACCESS 0
-#define NO_FUNCTION_CSE
+#define NO_FUNCTION_CSE 1
+
+#define REGISTER_TARGET_PRAGMAS() \
+ do { \
+ avr_register_target_pragmas(); \
+ } while (0)
#define TEXT_SECTION_ASM_OP "\t.text"
#define SUPPORTS_INIT_PRIORITY 0
-#define JUMP_TABLES_IN_TEXT_SECTION 0
+/* We pretend jump tables are in text section because otherwise,
+ final.c will switch to .rodata before jump tables and thereby
+ triggers __do_copy_data. As we implement ASM_OUTPUT_ADDR_VEC,
+ we still have full control over the jump tables themselves. */
+#define JUMP_TABLES_IN_TEXT_SECTION 1
#define ASM_COMMENT_START " ; "
avr_asm_output_aligned_decl_common (STREAM, DECL, NAME, SIZE, ALIGN, false)
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
- asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
+ avr_asm_asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN, \
+ asm_output_aligned_bss)
#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGN) \
avr_asm_output_aligned_decl_common (STREAM, DECL, NAME, SIZE, ALIGN, true)
"r24","r25","r26","r27","r28","r29","r30","r31", \
"__SP_L__","__SP_H__","argL","argH"}
-#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 FINAL_PRESCAN_INSN(insn, operand, nop) \
+ avr_final_prescan_insn (insn, operand,nop)
#define ASM_OUTPUT_REG_PUSH(STREAM, REGNO) \
{ \
fprintf (STREAM, "\tpop\tr%d", REGNO); \
}
-#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
- avr_output_addr_vec_elt(STREAM, VALUE)
+#define ASM_OUTPUT_ADDR_VEC(TLABEL, TDATA) \
+ avr_output_addr_vec (TLABEL, TDATA)
-#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 CASE_VECTOR_MODE HImode
#undef WORD_REGISTER_OPERATIONS
-#define MOVE_MAX 4
+/* Can move only a single byte from memory to reg in a
+ single instruction. */
+
+#define MOVE_MAX 1
+
+/* Allow upto two bytes moves to occur using by_pieces
+ infrastructure */
+
+#define MOVE_MAX_PIECES 2
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
+/* Set MOVE_RATIO to 3 to allow memory moves upto 4 bytes to happen
+ by pieces when optimizing for speed, like it did when MOVE_MAX_PIECES
+ was 4. When optimizing for size, allow memory moves upto 2 bytes.
+ Also see avr_use_by_pieces_infrastructure_p. */
+
+#define MOVE_RATIO(speed) ((speed) ? 3 : 2)
#define Pmode HImode
after execution of an instruction whose pattern is EXP.
Do not alter them if the instruction would not alter the cc's. */
-#define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc(EXP, INSN)
+#define NOTICE_UPDATE_CC(EXP, INSN) avr_notice_update_cc (EXP, INSN)
/* The add insns don't set overflow in a usable way. */
#define CC_OVERFLOW_UNUSABLE 01000
#define FUNCTION_PROFILER(FILE, LABELNO) \
fprintf (FILE, "/* profiler %d */", (LABELNO))
-#define ADJUST_INSN_LENGTH(INSN, LENGTH) (LENGTH =\
- adjust_insn_length (INSN, LENGTH))
-
-extern const char *avr_device_to_arch (int argc, const char **argv);
-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);
-
-#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 },
+#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
+ (LENGTH = avr_adjust_insn_length (INSN, LENGTH))
-#define CPP_SPEC ""
+extern const char *avr_devicespecs_file (int, const char**);
+extern const char *avr_double_lib (int, const char**);
-#define CC1_SPEC ""
+#define EXTRA_SPEC_FUNCTIONS \
+ { "double-lib", avr_double_lib }, \
+ { "device-specs-file", avr_devicespecs_file },
-#define CC1PLUS_SPEC "%{!frtti:-fno-rtti} \
- %{!fenforce-eh-specs:-fno-enforce-eh-specs} \
- %{!fexceptions:-fno-exceptions}"
-/* A C string constant that tells the GCC driver program options to
- pass to `cc1plus'. */
+/* Driver self specs has lmited functionality w.r.t. '%s' for dynamic specs.
+ Apply '%s' to a static string to inflate the file (directory) name which
+ is used to diagnose problems with reading the specs file. */
-#define ASM_SPEC "%{mmcu=avr25:-mmcu=avr2;mmcu=avr35:-mmcu=avr3;mmcu=avr31:-mmcu=avr3;mmcu=avr51:-mmcu=avr5;\
-mmcu=*:-mmcu=%*}"
+#undef DRIVER_SELF_SPECS
+#define DRIVER_SELF_SPECS \
+ " %:double-lib(%{m*:m%*})" \
+ " %:device-specs-file(device-specs%s %{mmcu=*:%*})"
-#define LINK_SPEC "\
-%{mrelax:--relax\
- %{mpmem-wrap-around:%{mmcu=at90usb8*:--pmem-wrap-around=8k}\
- %{mmcu=atmega16*:--pmem-wrap-around=16k}\
- %{mmcu=atmega32*|\
- mmcu=at90can32*:--pmem-wrap-around=32k}\
- %{mmcu=atmega64*|\
- mmcu=at90can64*|\
- mmcu=at90usb64*:--pmem-wrap-around=64k}}}\
-%:device_to_arch(%{mmcu=*:%*})\
-%:device_to_data_start(%{mmcu=*:%*})"
-
-#define LIB_SPEC \
- "%{!mmcu=at90s1*:%{!mmcu=attiny11:%{!mmcu=attiny12:%{!mmcu=attiny15:%{!mmcu=attiny28: -lc }}}}}"
-
-#define LIBSTDCXX "gcc"
/* No libstdc++ for now. Empty string doesn't work. */
+#define LIBSTDCXX "gcc"
-#define LIBGCC_SPEC \
- "%{!mmcu=at90s1*:%{!mmcu=attiny11:%{!mmcu=attiny12:%{!mmcu=attiny15:%{!mmcu=attiny28: -lgcc }}}}}"
-
-#define STARTFILE_SPEC "%:device_to_startfile(%{mmcu=*:%*})"
-
-#define ENDFILE_SPEC ""
-
-/* This is the default without any -mmcu=* option (AT90S*). */
-#define MULTILIB_DEFAULTS { "mmcu=avr2" }
+/* This is the default without any -mmcu=* option. */
+#define MULTILIB_DEFAULTS { "mmcu=" AVR_MMCU_DEFAULT }
#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 DWARF2_ADDR_SIZE 4
/* '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;
+
+ /* 'true' - if current function shall not use '__gcc_isr' pseudo
+ instructions as specified by the "no_gccisr" attribute. */
+ int is_no_gccisr;
+
+ /* Used for `__gcc_isr' pseudo instruction handling of
+ non-naked ISR prologue / epilogue(s). */
+ struct
+ {
+ /* 'true' if this function actually uses "*gasisr" insns. */
+ int yes;
+ /* 'true' if this function is allowed to use "*gasisr" insns. */
+ int maybe;
+ /* The register numer as printed by the Done chunk. */
+ int regno;
+ } gasisr;
+
+ /* 'true' if this function references .L__stack_usage like with
+ __builtin_return_address. */
+ int use_L__stack_usage;
};
-/* AVR does not round pushes, but the existance of this macro is
+/* AVR does not round pushes, but the existence 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()
+
+/* Flags used for io and address attributes. */
+#define SYMBOL_FLAG_IO_LOW (SYMBOL_FLAG_MACH_DEP << 4)
+#define SYMBOL_FLAG_IO (SYMBOL_FLAG_MACH_DEP << 5)
+#define SYMBOL_FLAG_ADDRESS (SYMBOL_FLAG_MACH_DEP << 6)