/* Definitions of target machine for GNU compiler, Synopsys DesignWare ARC cpu.
- Copyright (C) 1994-2018 Free Software Foundation, Inc.
+ Copyright (C) 1994-2020 Free Software Foundation, Inc.
This file is part of GCC.
#undef ASM_SPEC
#define ASM_SPEC "%{mbig-endian|EB:-EB} %{EL} " \
- "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda}"
+ "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} " \
+ "%{mfpu=fpuda*:-mfpuda} %{mcode-density}"
#define OPTION_DEFAULT_SPECS \
{"cpu", "%{!mcpu=*:%{!mARC*:%{!marc*:%{!mA7:%{!mA6:-mcpu=%(VALUE)}}}}}" }
/* On the ARC the lower address bits are masked to 0 as necessary. The chip
won't croak when given an unaligned address, but the insn will still fail
to produce the correct result. */
-#define STRICT_ALIGNMENT (!unaligned_access && !TARGET_HS)
+#define STRICT_ALIGNMENT (!unaligned_access)
/* Layout of source language data types. */
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
-#define PROGRAM_COUNTER_REGNO 63
-
/* Standard register usage. */
/* Number of actual hardware registers.
argument pointer. */
/* r63 is pc, r64-r127 = simd vregs, r128-r143 = simd dma config regs
- r144, r145 = lp_start, lp_end
+ r144, r145 = ARG_POINTER, FRAME_POINTER
and therefore the pseudo registers start from r146. */
#define FIRST_PSEUDO_REGISTER 146
By default, the extension registers are not available. */
/* Present implementations only have VR0-VR23 only. */
-/* ??? FIXME: r27 and r31 should not be fixed registers. */
#define FIXED_REGISTERS \
{ 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, \
+ 0, 0, 1, 0, 1, 1, 1, 1, \
\
1, 1, 1, 1, 1, 1, 1, 1, \
0, 0, 0, 0, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 0, 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, \
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, 1, 1, 1, 1, 1, 1, \
+ 0, 0, 1, 0, 1, 1, 1, 1, \
\
1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, \
/* If defined, an initializer for a vector of integers, containing the
numbers of hard registers in the order in which GCC should
prefer to use them (from most preferred to least). */
-#define REG_ALLOC_ORDER \
-{ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, \
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, \
+#define REG_ALLOC_ORDER \
+{ \
+ /* General registers. */ \
+ 2, 3, 12, 13, 14, 15, 1, 0, 4, 5, 6, 7, 8, 9, 10, 11, \
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 30, \
+ /* Extension core registers. */ \
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, \
- 27, 28, 29, 30, 31, 63}
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, \
+ /* VR regs. */ \
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, \
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, \
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, \
+ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, \
+ 124, 125, 126, 127, \
+ /* DMA registers. */ \
+ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, \
+ 142, 143, \
+ /* Register not used for general use. */ \
+ 62, FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM, \
+ SP_REG, ILINK1_REG, RETURN_ADDR_REGNUM, LP_COUNT, CC_REG, PCL_REG \
+}
+
+/* Use different register alloc ordering for Thumb. */
+#define ADJUST_REG_ALLOC_ORDER arc_adjust_reg_alloc_order ()
+
+/* Tell IRA to use the order we define rather than messing it up with its
+ own cost calculations. */
+#define HONOR_REG_ALLOC_ORDER 1
/* Internal macros to classify a register number as to whether it's a
general purpose register for compact insns (r0-r3,r12-r15), or
{
NO_REGS,
R0_REGS, /* 'x' */
- GP_REG, /* 'Rgp' */
- FP_REG, /* 'f' */
- SP_REGS, /* 'b' */
- LPCOUNT_REG, /* 'l' */
- LINK_REGS, /* 'k' */
- DOUBLE_REGS, /* D0, D1 */
- SIMD_VR_REGS, /* VR00-VR63 */
- SIMD_DMA_CONFIG_REGS, /* DI0-DI7,DO0-DO7 */
+ R0R1_CD_REGS, /* 'Rsd' */
+ R0R3_CD_REGS, /* 'Rcd' */
ARCOMPACT16_REGS, /* 'q' */
- AC16_BASE_REGS, /* 'e' */
SIBCALL_REGS, /* "Rsc" */
- GENERAL_REGS, /* 'r' */
- MPY_WRITABLE_CORE_REGS, /* 'W' */
- WRITABLE_CORE_REGS, /* 'w' */
- CHEAP_CORE_REGS, /* 'c' */
- ALL_CORE_REGS, /* 'Rac' */
- R0R3_CD_REGS, /* 'Rcd' */
- R0R1_CD_REGS, /* 'Rsd' */
AC16_H_REGS, /* 'h' */
+ DOUBLE_REGS, /* 'D' */
+ GENERAL_REGS, /* 'r' */
+ SIMD_VR_REGS, /* 'v' */
+ SIMD_DMA_CONFIG_REGS, /* 'd' */
ALL_REGS,
LIM_REG_CLASSES
};
/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
-{ \
- "NO_REGS", \
- "R0_REGS", \
- "GP_REG", \
- "FP_REG", \
- "SP_REGS", \
- "LPCOUNT_REG", \
- "LINK_REGS", \
- "DOUBLE_REGS", \
- "SIMD_VR_REGS", \
- "SIMD_DMA_CONFIG_REGS", \
- "ARCOMPACT16_REGS", \
- "AC16_BASE_REGS", \
+{ \
+ "NO_REGS", \
+ "R0_REGS", \
+ "R0R1_CD_REGS", \
+ "R0R3_CD_REGS", \
+ "ARCOMPACT16_REGS", \
"SIBCALL_REGS", \
- "GENERAL_REGS", \
- "MPY_WRITABLE_CORE_REGS", \
- "WRITABLE_CORE_REGS", \
- "CHEAP_CORE_REGS", \
- "R0R3_CD_REGS", \
- "R0R1_CD_REGS", \
- "AC16_H_REGS", \
- "ALL_CORE_REGS", \
- "ALL_REGS" \
+ "AC16_H_REGS", \
+ "DOUBLE_REGS", \
+ "GENERAL_REGS", \
+ "SIMD_VR_REGS", \
+ "SIMD_DMA_CONFIG_REGS", \
+ "ALL_REGS" \
}
/* Define which registers fit in which classes.
of length N_REG_CLASSES. */
#define REG_CLASS_CONTENTS \
-{ \
- {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* No Registers */ \
- {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'x', r0 register , r0 */ \
- {0x04000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rgp', Global Pointer, r26 */ \
- {0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'f', Frame Pointer, r27 */ \
- {0x10000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'b', Stack Pointer, r28 */ \
- {0x00000000, 0x10000000, 0x00000000, 0x00000000, 0x00000000}, /* 'l', LPCOUNT Register, r60 */ \
- {0xe0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'k', LINK Registers, r29-r31 */ \
- {0x00000000, 0x00000f00, 0x00000000, 0x00000000, 0x00000000}, /* 'D', D1, D2 Registers */ \
- {0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000}, /* 'V', VR00-VR63 Registers */ \
- {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000ffff}, /* 'V', DI0-7,DO0-7 Registers */ \
- {0x0000f00f, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'q', r0-r3, r12-r15 */ \
- {0x1000f00f, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'e', r0-r3, r12-r15, sp */ \
- {0x1c001fff, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* "Rsc", r0-r12 */ \
- {0x9fffffff, 0x80000000, 0x00000000, 0x00000000, 0x00000000}, /* 'r', r0-r28, blink, ap and pcl */ \
- {0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'W', r0-r31 */ \
- /* Include ap / pcl in WRITABLE_CORE_REGS for sake of symmetry. As these \
- registers are fixed, it does not affect the literal meaning of the \
- constraints, but it makes it a superset of GENERAL_REGS, thus \
- enabling some operations that would otherwise not be possible. */ \
- {0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'w', r0-r31, r60 */ \
- {0xffffffff, 0x9fffffff, 0x00000000, 0x00000000, 0x00000000}, /* 'c', r0-r60, ap, pcl */ \
- {0xffffffff, 0x9fffffff, 0x00000000, 0x00000000, 0x00000000}, /* 'Rac', r0-r60, ap, pcl */ \
- {0x0000000f, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rcd', r0-r3 */ \
- {0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rsd', r0-r1 */ \
- {0x9fffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'h', r0-28, r30 */ \
- {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0003ffff} /* All Registers */ \
+{ \
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* NO_REGS. */\
+ {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'x'. */ \
+ {0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rsd'. */ \
+ {0x0000000f, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rcd'. */ \
+ {0x0000f00f, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'q'. */ \
+ {0x00001fff, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rsc'. */ \
+ {0x9fffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'h'. */ \
+ {0x00000000, 0x00000f00, 0x00000000, 0x00000000, 0x00000000}, /* 'D'. */ \
+ {0xffffffff, 0x8fffffff, 0x00000000, 0x00000000, 0x00030000}, /* 'r'. */ \
+ {0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000}, /* 'v'. */ \
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000ffff}, /* 'd'. */ \
+ {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0003ffff} /* ALL_REGS. */\
}
/* Local macros to mark the first and last regs of different classes. */
/* The class value for valid base registers. A base register is one used in
an address which is the register value plus a displacement. */
-#define BASE_REG_CLASS (TARGET_MIXED_CODE ? AC16_BASE_REGS : GENERAL_REGS)
+#define BASE_REG_CLASS GENERAL_REGS
/* These assume that REGNO is a hard or pseudo reg number.
They give nonzero only if REGNO is a hard reg of the suitable class
Since they use reg_renumber, they are safe only once reg_renumber
has been allocated, which happens in local-alloc.c. */
#define REGNO_OK_FOR_BASE_P(REGNO) \
- ((REGNO) < 29 || ((REGNO) == ARG_POINTER_REGNUM) || ((REGNO) == 63) \
+ ((REGNO) < 29 \
+ || ((REGNO) == ARG_POINTER_REGNUM) \
+ || ((REGNO) == FRAME_POINTER_REGNUM) \
+ || ((REGNO) == PCL_REG) \
|| ((unsigned) reg_renumber[REGNO] < 29) \
|| ((unsigned) (REGNO) == (unsigned) arc_tp_regno) \
|| (fixed_regs[REGNO] == 0 && IN_RANGE (REGNO, 32, 59)) \
- || ((REGNO) == 30 && fixed_regs[REGNO] == 0))
+ || (fixed_regs[REGNO] == 0 && (REGNO) == R30_REG))
#define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_BASE_P(REGNO)
#define STACK_POINTER_REGNUM 28
/* Base register for access to local variables of the function. */
-#define FRAME_POINTER_REGNUM 27
+#define FRAME_POINTER_REGNUM 145
+#define HARD_FRAME_POINTER_REGNUM 27
/* Base register for access to arguments of the function. This register
will be eliminated into either fp or sp. */
-#define ARG_POINTER_REGNUM 62
+#define ARG_POINTER_REGNUM 144
#define RETURN_ADDR_REGNUM 31
#define ELIMINABLE_REGS \
{{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
- {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
- {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
+ {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
+ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+ {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
/* Define the offset between two registers, one to be eliminated, and the other
its replacement, at the start of a routine. */
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
(OFFSET) = arc_initial_elimination_offset ((FROM), (TO))
-/* Output assembler code to FILE to increment profiler label # LABELNO
- for profiling a function entry. */
-#define FUNCTION_PROFILER(FILE, LABELNO) \
- do { \
- if (flag_pic) \
- fprintf (FILE, "\tbl\t__mcount@plt\n"); \
- else \
- fprintf (FILE, "\tbl\t__mcount\n"); \
- } while (0)
+/* All the work done in PROFILE_HOOK, but still required. */
+#undef FUNCTION_PROFILER
+#define FUNCTION_PROFILER(STREAM, LABELNO) do { } while (0)
#define NO_PROFILE_COUNTERS 1
/* Costs. */
-/* Compute extra cost of moving data between one register class
- and another. */
-#define REGISTER_MOVE_COST(MODE, CLASS, TO_CLASS) \
- arc_register_move_cost ((MODE), (CLASS), (TO_CLASS))
-
-/* Compute the cost of moving data between registers and memory. */
-/* Memory is 3 times as expensive as registers.
- ??? Is that the right way to look at it? */
-#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
-(GET_MODE_SIZE (MODE) <= UNITS_PER_WORD ? 6 : 12)
-
/* The cost of a branch insn. */
/* ??? What's the right value here? Branches are certainly more
expensive than reg->reg moves. */
"r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", \
"d1", "d1", "d2", "d2", "r44", "r45", "r46", "r47", \
"r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", \
- rname56,rname57,rname58,rname59,"lp_count", "cc", "ap", "pcl", \
+ rname56,rname57,rname58,rname59,"lp_count", "cc", "limm", "pcl", \
"vr0", "vr1", "vr2", "vr3", "vr4", "vr5", "vr6", "vr7", \
"vr8", "vr9", "vr10", "vr11", "vr12", "vr13", "vr14", "vr15", \
"vr16", "vr17", "vr18", "vr19", "vr20", "vr21", "vr22", "vr23", \
"vr56", "vr57", "vr58", "vr59", "vr60", "vr61", "vr62", "vr63", \
"dr0", "dr1", "dr2", "dr3", "dr4", "dr5", "dr6", "dr7", \
"dr0", "dr1", "dr2", "dr3", "dr4", "dr5", "dr6", "dr7", \
- "lp_start", "lp_end" \
+ "arg", "frame" \
}
#define ADDITIONAL_REGISTER_NAMES \
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 2)
-#define EH_RETURN_HANDLER_RTX arc_eh_return_address_location ()
-
/* Turn off splitting of long stabs. */
#define DBX_CONTIN_LENGTH 0
in one reasonably fast instruction. */
#define MOVE_MAX 4
-/* Undo the effects of the movmem pattern presence on STORE_BY_PIECES_P . */
+/* Undo the effects of the cpymem pattern presence on STORE_BY_PIECES_P . */
#define MOVE_RATIO(SPEED) ((SPEED) ? 15 : 3)
/* Define this to be nonzero if shift instructions ignore all but the
(((MODE) == CC_FP_GTmode || (MODE) == CC_FP_GEmode \
|| (MODE) == CC_FP_UNEQmode || (MODE) == CC_FP_ORDmode \
|| (MODE) == CC_FPXmode || (MODE) == CC_FPU_UNEQmode \
- || (MODE) == CC_FPUmode) \
+ || (MODE) == CC_FPUmode || (MODE) == CC_FPUEmode) \
? reverse_condition_maybe_unordered ((CODE)) \
: reverse_condition ((CODE)))
/* The default option for BI/BIH instructions. */
#define DEFAULT_BRANCH_INDEX 0
+#ifndef TARGET_LRA
+#define TARGET_LRA arc_lra_p()
+#endif
+
#endif /* GCC_ARC_H */