123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- /* GCC backend definitions for the Renesas RL78 processor.
- Copyright (C) 2011-2015 Free Software Foundation, Inc.
- Contributed by Red Hat.
- This file is part of GCC.
- 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 3, or (at your
- option) any later version.
- 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 GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
- #define RL78_MUL_NONE (rl78_mul_type == MUL_NONE)
- #define RL78_MUL_RL78 (rl78_mul_type == MUL_RL78)
- #define RL78_MUL_G13 (rl78_mul_type == MUL_G13)
- #define TARGET_CPU_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("__RL78__"); \
- builtin_assert ("cpu=RL78"); \
- if (RL78_MUL_RL78) \
- builtin_define ("__RL78_MUL_RL78__"); \
- if (RL78_MUL_G13) \
- builtin_define ("__RL78_MUL_G13__"); \
- if (TARGET_G10) \
- builtin_define ("__RL78_G10__"); \
- } \
- while (0)
- #undef STARTFILE_SPEC
- #define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:crt0.o%s} crtbegin.o%s"
- #undef ENDFILE_SPEC
- #define ENDFILE_SPEC "crtend.o%s crtn.o%s"
- #undef ASM_SPEC
- #define ASM_SPEC "\
- %{mrelax:-relax} \
- %{mg10} \
- "
- #undef LINK_SPEC
- #define LINK_SPEC "\
- %{mrelax:-relax} \
- %{!r:--gc-sections} \
- "
- #undef LIB_SPEC
- #define LIB_SPEC " \
- --start-group \
- -lc \
- -lsim \
- %{fprofile-arcs|fprofile-generate|coverage:-lgcov} \
- --end-group \
- %{!T*: %{msim:%Trl78-sim.ld}%{!msim:%Trl78.ld}} \
- "
- #define BITS_BIG_ENDIAN 0
- #define BYTES_BIG_ENDIAN 0
- #define WORDS_BIG_ENDIAN 0
- #ifdef IN_LIBGCC2
- /* This is to get correct SI and DI modes in libgcc2.c (32 and 64 bits). */
- #define UNITS_PER_WORD 4
- /* We have a problem with libgcc2. It only defines two versions of
- each function, one for "int" and one for "long long". Ie it assumes
- that "sizeof (int) == sizeof (long)". For the RL78 this is not true
- and we need a third set of functions. We explicitly define
- LIBGCC2_UNITS_PER_WORD here so that it is clear that we are expecting
- to get the SI and DI versions from the libgcc2.c sources, and we
- provide our own set of HI functions, which is why this
- definition is surrounded by #ifndef..#endif. */
- #ifndef LIBGCC2_UNITS_PER_WORD
- #define LIBGCC2_UNITS_PER_WORD 4
- #endif
- #else
- /* Actual width of a word, in units (bytes). */
- #define UNITS_PER_WORD 1
- #endif
- #define SHORT_TYPE_SIZE 16
- #define INT_TYPE_SIZE 16
- #define LONG_TYPE_SIZE 32
- #define LONG_LONG_TYPE_SIZE 64
- #define FLOAT_TYPE_SIZE 32
- #define DOUBLE_TYPE_SIZE 32 /*64*/
- #define LONG_DOUBLE_TYPE_SIZE 64 /*DOUBLE_TYPE_SIZE*/
- #define DEFAULT_SIGNED_CHAR 0
- #define STRICT_ALIGNMENT 1
- #define FUNCTION_BOUNDARY 8
- #define BIGGEST_ALIGNMENT 16
- #define STACK_BOUNDARY 16
- #define PARM_BOUNDARY 16
- #define STACK_GROWS_DOWNWARD 1
- #define FRAME_GROWS_DOWNWARD 1
- #define FIRST_PARM_OFFSET(FNDECL) 0
- #define MAX_REGS_PER_ADDRESS 1
- #define Pmode HImode
- #define POINTER_SIZE 16
- #undef SIZE_TYPE
- #define SIZE_TYPE "unsigned int"
- #undef PTRDIFF_TYPE
- #define PTRDIFF_TYPE "int"
- #undef WCHAR_TYPE
- #define WCHAR_TYPE "long int"
- #undef WCHAR_TYPE_SIZE
- #define WCHAR_TYPE_SIZE BITS_PER_WORD
- #define POINTERS_EXTEND_UNSIGNED 1
- #define FUNCTION_MODE HImode
- #define CASE_VECTOR_MODE Pmode
- #define WORD_REGISTER_OPERATIONS 0
- #define HAS_LONG_COND_BRANCH 0
- #define HAS_LONG_UNCOND_BRANCH 0
- #define MOVE_MAX 2
- #define STARTING_FRAME_OFFSET 0
- #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
- #define ADDR_SPACE_NEAR 1
- #define ADDR_SPACE_FAR 2
- #define HAVE_PRE_DECCREMENT 0
- #define HAVE_POST_INCREMENT 0
- #define MOVE_RATIO(SPEED) ((SPEED) ? 24 : 16)
- #define SLOW_BYTE_ACCESS 0
- #define STORE_FLAG_VALUE 1
- #define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
- /* The RL78 has four register banks. Normal operation uses RB0 as
- real registers, RB1 and RB2 as "virtual" registers (because we know
- they'll be there, and not used as variables), and RB3 is reserved
- for interrupt handlers. The virtual registers are accessed as
- SADDRs:
- FFEE0-FFEE7 RB0
- FFEE8-FFEEF RB1
- FFEF0-FFEF7 RB2
- FFEF8-FFEFF RB3
- */
- #define REGISTER_NAMES \
- { \
- "x", "a", "c", "b", "e", "d", "l", "h", \
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
- "sp", "ap", "psw", "es", "cs" \
- }
- #define ADDITIONAL_REGISTER_NAMES \
- { \
- { "ax", 0 }, \
- { "bc", 2 }, \
- { "de", 4 }, \
- { "hl", 6 }, \
- { "rp0", 0 }, \
- { "rp1", 2 }, \
- { "rp2", 4 }, \
- { "rp3", 6 }, \
- { "r0", 0 }, \
- { "r1", 1 }, \
- { "r2", 2 }, \
- { "r3", 3 }, \
- { "r4", 4 }, \
- { "r5", 5 }, \
- { "r6", 6 }, \
- { "r7", 7 }, \
- }
- enum reg_class
- {
- NO_REGS, /* No registers in set. */
- XREG,
- AREG,
- AXREG,
- CREG,
- BREG,
- BCREG,
- EREG,
- DREG,
- DEREG,
- LREG,
- HREG,
- HLREG,
- IDX_REGS,
- QI_REGS,
- SPREG,
- R8W_REGS,
- R10W_REGS,
- INT_REGS,
- V_REGS, /* Virtual registers. */
- GR_REGS, /* Integer registers. */
- PSWREG,
- ALL_REGS, /* All registers. */
- LIM_REG_CLASSES /* Max value + 1. */
- };
- #define REG_CLASS_NAMES \
- { \
- "NO_REGS", \
- "XREG", \
- "AREG", \
- "AXREG", \
- "CREG", \
- "BREG", \
- "BCREG", \
- "EREG", \
- "DREG", \
- "DEREG", \
- "LREG", \
- "HREG", \
- "HLREG", \
- "IDX_REGS", \
- "QI_REGS", \
- "SPREG", \
- "R8W_REGS", \
- "R10W_REGS", \
- "INT_REGS", \
- "V_REGS", \
- "GR_REGS", \
- "PSWREG", \
- "ALL_REGS" \
- }
- /* Note that no class may include the second register in $fp, because
- we treat $fp as a single HImode register. */
- #define REG_CLASS_CONTENTS \
- { \
- { 0x00000000, 0x00000000 }, /* No registers, */ \
- { 0x00000001, 0x00000000 }, \
- { 0x00000002, 0x00000000 }, \
- { 0x00000003, 0x00000000 }, \
- { 0x00000004, 0x00000000 }, \
- { 0x00000008, 0x00000000 }, \
- { 0x0000000c, 0x00000000 }, \
- { 0x00000010, 0x00000000 }, \
- { 0x00000020, 0x00000000 }, \
- { 0x00000030, 0x00000000 }, \
- { 0x00000040, 0x00000000 }, \
- { 0x00000080, 0x00000000 }, \
- { 0x000000c0, 0x00000000 }, \
- { 0x0000000c, 0x00000000 }, /* B and C - index regs. */ \
- { 0x000000ff, 0x00000000 }, /* all real registers. */ \
- { 0x00000000, 0x00000001 }, /* SP */ \
- { 0x00000300, 0x00000000 }, /* R8 - HImode */ \
- { 0x00000c00, 0x00000000 }, /* R10 - HImode */ \
- { 0xff000000, 0x00000000 }, /* INT - HImode */ \
- { 0xff7fff00, 0x00000000 }, /* Virtual registers. */ \
- { 0xff7fff00, 0x00000002 }, /* General registers. */ \
- { 0x04000000, 0x00000004 }, /* PSW. */ \
- { 0xff7fffff, 0x0000001f } /* All registers. */ \
- }
- #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
- #define N_REG_CLASSES (int) LIM_REG_CLASSES
- #define CLASS_MAX_NREGS(CLASS, MODE) ((GET_MODE_SIZE (MODE) \
- + UNITS_PER_WORD - 1) \
- / UNITS_PER_WORD)
- #define GENERAL_REGS GR_REGS
- #define BASE_REG_CLASS V_REGS
- #define INDEX_REG_CLASS V_REGS
- #define FIRST_PSEUDO_REGISTER 37
- #define REGNO_REG_CLASS(REGNO) ((REGNO) < FIRST_PSEUDO_REGISTER \
- ? GR_REGS : NO_REGS)
- #define FRAME_POINTER_REGNUM 22
- #define STACK_POINTER_REGNUM 32
- #define ARG_POINTER_REGNUM 33
- #define CC_REGNUM 34
- #define FUNC_RETURN_REGNUM 8
- #define STATIC_CHAIN_REGNUM 14
- /* Trampolines are implemented with a separate data stack. The memory
- on stack only holds the function pointer for the chosen stub.
- */
- #define TRAMPOLINE_SIZE 4
- #define TRAMPOLINE_ALIGNMENT 16
- #define ELIMINABLE_REGS \
- {{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
- { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \
- { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }}
- #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
- (OFFSET) = rl78_initial_elimination_offset ((FROM), (TO))
- #define FUNCTION_ARG_REGNO_P(N) 0
- #define FUNCTION_VALUE_REGNO_P(N) ((N) == 8)
- #define DEFAULT_PCC_STRUCT_RETURN 0
- #define FIXED_REGISTERS \
- { \
- 1,1,1,1, 1,1,1,1, \
- 0,0,0,0, 0,0,0,0, \
- 0,0,0,0, 0,0,1,1, \
- 1,1,1,1, 1,1,1,1, \
- 0, 1, 0, 1, 1 \
- }
- #define CALL_USED_REGISTERS \
- { \
- 1,1,1,1, 1,1,1,1, \
- 1,1,1,1, 1,1,1,1, \
- 0,0,0,0, 0,0,1,1, \
- 1,1,1,1, 1,1,1,1, \
- 0, 1, 1, 1, 1 \
- }
- #define LIBCALL_VALUE(MODE) \
- gen_rtx_REG ((MODE), \
- FUNC_RETURN_REGNUM)
- /* Order of allocation of registers. */
- #define REG_ALLOC_ORDER \
- { 8, 9, 10, 11, 12, 13, 14, 15, \
- 16, 17, 18, 19, 20, 21, 22, 23, \
- 0, 1, 6, 7, 2, 3, 4, 5, \
- 24, 25, 26, 27, 28, 29, 30, 31, \
- 32, 33, 34 \
- }
- #define REGNO_IN_RANGE(REGNO, MIN, MAX) \
- (IN_RANGE ((REGNO), (MIN), (MAX)) \
- || (reg_renumber != NULL \
- && reg_renumber[(REGNO)] >= (MIN) \
- && reg_renumber[(REGNO)] <= (MAX)))
- #ifdef REG_OK_STRICT
- #define REGNO_OK_FOR_BASE_P(regno) REGNO_IN_RANGE (regno, 16, 31)
- #else
- #define REGNO_OK_FOR_BASE_P(regno) 1
- #endif
- #define REGNO_OK_FOR_INDEX_P(regno) REGNO_OK_FOR_BASE_P (regno)
- #define REGNO_MODE_CODE_OK_FOR_BASE_P(regno, mode, address_space, outer_code, index_code) \
- rl78_regno_mode_code_ok_for_base_p (regno, mode, address_space, outer_code, index_code)
- #define MODE_CODE_BASE_REG_CLASS(mode, address_space, outer_code, index_code) \
- rl78_mode_code_base_reg_class (mode, address_space, outer_code, index_code)
- #define RETURN_ADDR_RTX(COUNT, FRAMEADDR) \
- ((COUNT) == 0 \
- ? gen_rtx_MEM (Pmode, gen_rtx_PLUS (HImode, arg_pointer_rtx, GEN_INT (-4))) \
- : NULL_RTX)
- #define INCOMING_RETURN_ADDR_RTX gen_rtx_MEM (Pmode, stack_pointer_rtx)
- #define ACCUMULATE_OUTGOING_ARGS 1
- typedef unsigned int CUMULATIVE_ARGS;
- #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
- (CUM) = 0
- /* FIXME */
- #define NO_PROFILE_COUNTERS 1
- #define PROFILE_BEFORE_PROLOGUE 1
- #define FUNCTION_PROFILER(FILE, LABELNO) \
- fprintf (FILE, "\tbsr\t__mcount\n");
- #define HARD_REGNO_NREGS(REGNO, MODE) \
- rl78_hard_regno_nregs (REGNO, MODE)
- #define HARD_REGNO_MODE_OK(REGNO, MODE) \
- rl78_hard_regno_mode_ok (REGNO, MODE)
- #define MODES_TIEABLE_P(MODE1, MODE2) \
- ( ( GET_MODE_CLASS (MODE1) == MODE_FLOAT \
- || GET_MODE_CLASS (MODE1) == MODE_COMPLEX_FLOAT) \
- == ( GET_MODE_CLASS (MODE2) == MODE_FLOAT \
- || GET_MODE_CLASS (MODE2) == MODE_COMPLEX_FLOAT))
- #define TEXT_SECTION_ASM_OP ".text"
- #define DATA_SECTION_ASM_OP ".data"
- #define BSS_SECTION_ASM_OP ".bss"
- #define CTORS_SECTION_ASM_OP ".section \".ctors\",\"a\""
- #define DTORS_SECTION_ASM_OP ".section \".dtors\",\"a\""
- #define ASM_COMMENT_START " ;"
- #define ASM_APP_ON ""
- #define ASM_APP_OFF ""
- #define LOCAL_LABEL_PREFIX ".L"
- #undef USER_LABEL_PREFIX
- #define USER_LABEL_PREFIX "_"
- #define GLOBAL_ASM_OP "\t.global\t"
- #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
- fprintf (FILE, "\t.long .L%d\n", VALUE)
- /* This is how to output an element of a case-vector that is relative.
- Note: The local label referenced by the "3b" below is emitted by
- the tablejump insn. */
- #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
- fprintf (FILE, "\t.long .L%d - 1b\n", VALUE)
- #define ASM_OUTPUT_SYMBOL_REF(FILE, SYM) rl78_output_symbol_ref ((FILE), (SYM))
- #define ASM_OUTPUT_LABELREF(FILE, SYM) rl78_output_labelref ((FILE), (SYM))
- #define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGNMENT) \
- rl78_output_aligned_common (STREAM, DECL, NAME, SIZE, ALIGNMENT, 1)
- #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGNMENT) \
- rl78_output_aligned_common (STREAM, DECL, NAME, SIZE, ALIGNMENT, 0)
- #define ASM_OUTPUT_ALIGN(STREAM, LOG) \
- do \
- { \
- if ((LOG) == 0) \
- break; \
- fprintf (STREAM, "\t.balign %d\n", 1 << (LOG)); \
- } \
- while (0)
- /* For PIC put jump tables into the text section so that the offsets that
- they contain are always computed between two same-section symbols. */
- #define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
- /* This is a version of REG_P that also returns TRUE for SUBREGs. */
- #define RL78_REG_P(rtl) (REG_P (rtl) || GET_CODE (rtl) == SUBREG)
- /* Like REG_P except that this macro is true for SET expressions. */
- #define SET_P(rtl) (GET_CODE (rtl) == SET)
- #undef PREFERRED_DEBUGGING_TYPE
- #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
- #undef DWARF2_ADDR_SIZE
- #define DWARF2_ADDR_SIZE 4
- #define DWARF2_ASM_LINE_DEBUG_INFO 1
- #define EXIT_IGNORE_STACK 0
- #define INCOMING_FRAME_SP_OFFSET 4
- #define BRANCH_COST(SPEED,PREDICT) 1
- #define REGISTER_MOVE_COST(MODE,FROM,TO) 2
- #define EH_RETURN_DATA_REGNO(N) (N < 2 ? (8+(N)*2) : INVALID_REGNUM)
- #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (HImode, 20)
- #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) DW_EH_PE_udata4
- /* NOTE: defined but zero means dwarf2 debugging, but sjlj EH. */
- #define DWARF2_UNWIND_INFO 0
- #define REGISTER_TARGET_PRAGMAS() rl78_register_pragmas()
|