diff options
Diffstat (limited to 'gcc-4.9/gcc/config/rl78/rl78.h')
-rw-r--r-- | gcc-4.9/gcc/config/rl78/rl78.h | 473 |
1 files changed, 473 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/config/rl78/rl78.h b/gcc-4.9/gcc/config/rl78/rl78.h new file mode 100644 index 000000000..8dee92be9 --- /dev/null +++ b/gcc-4.9/gcc/config/rl78/rl78.h @@ -0,0 +1,473 @@ +/* GCC backend definitions for the Renesas RL78 processor. + Copyright (C) 2011-2014 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 LIBGCC2_HAS_DF_MODE 1 +#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64 + +#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_FAR 1 + +#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 +#define SHORT_IMMEDIATES_SIGN_EXTEND 0 + + +/* 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" \ +} + +#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. */ \ + { 0xff7fffff, 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_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() |