aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/xtensa/xtensa.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/xtensa/xtensa.h')
-rw-r--r--gcc/config/xtensa/xtensa.h43
1 files changed, 28 insertions, 15 deletions
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index 16fd3d6..0cce663 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -61,6 +61,7 @@ extern unsigned xtensa_current_frame_size;
#define MASK_HARD_FLOAT_RSQRT 0x00004000 /* floating-point recip sqrt */
#define MASK_NO_FUSED_MADD 0x00008000 /* avoid f-p mul/add */
#define MASK_SERIALIZE_VOLATILE 0x00010000 /* serialize volatile refs */
+#define MASK_CONST16 0x00020000 /* use CONST16 instruction */
/* Macros used in the machine description to test the flags. */
@@ -81,12 +82,14 @@ extern unsigned xtensa_current_frame_size;
#define TARGET_HARD_FLOAT_RSQRT (target_flags & MASK_HARD_FLOAT_RSQRT)
#define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD)
#define TARGET_SERIALIZE_VOLATILE (target_flags & MASK_SERIALIZE_VOLATILE)
+#define TARGET_CONST16 (target_flags & MASK_CONST16)
/* Default target_flags if no switches are specified */
#define TARGET_DEFAULT ( \
(XCHAL_HAVE_BE ? MASK_BIG_ENDIAN : 0) | \
(XCHAL_HAVE_DENSITY ? MASK_DENSITY : 0) | \
+ (XCHAL_HAVE_L32R ? 0 : MASK_CONST16) | \
(XCHAL_HAVE_MAC16 ? MASK_MAC16 : 0) | \
(XCHAL_HAVE_MUL16 ? MASK_MUL16 : 0) | \
(XCHAL_HAVE_MUL32 ? MASK_MUL32 : 0) | \
@@ -114,6 +117,10 @@ extern unsigned xtensa_current_frame_size;
N_("Use the Xtensa code density option")}, \
{"no-density", -MASK_DENSITY, \
N_("Do not use the Xtensa code density option")}, \
+ {"const16", MASK_CONST16, \
+ N_("Use CONST16 instruction to load constants")}, \
+ {"no-const16", -MASK_CONST16, \
+ N_("Use PC-relative L32R instruction to load constants")}, \
{"mac16", MASK_MAC16, \
N_("Use the Xtensa MAC16 option")}, \
{"no-mac16", -MASK_MAC16, \
@@ -629,6 +636,7 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
'A' MAC16 accumulator (only if MAC16 option enabled)
'B' general-purpose registers (only if sext instruction enabled)
'C' general-purpose registers (only if mul16 option enabled)
+ 'W' general-purpose registers (only if const16 option enabled)
'b' coprocessor boolean registers
'f' floating-point registers
*/
@@ -699,7 +707,7 @@ extern enum reg_class xtensa_char_to_class[256];
&& REGNO (OP) >= FIRST_PSEUDO_REGISTER) \
: ((CODE) == 'R') ? smalloffset_mem_p (OP) \
: ((CODE) == 'S') ? smalloffset_double_mem_p (OP) \
- : ((CODE) == 'T') ? constantpool_mem_p (OP) \
+ : ((CODE) == 'T') ? !TARGET_CONST16 && constantpool_mem_p (OP) \
: ((CODE) == 'U') ? !constantpool_mem_p (OP) \
: FALSE)
@@ -968,24 +976,27 @@ typedef struct xtensa_args {
fprintf (STREAM, "\t.begin no-generics\n"); \
fprintf (STREAM, "\tentry\tsp, %d\n", MIN_FRAME_SIZE); \
\
- /* GCC isn't prepared to deal with data at the beginning of the \
- trampoline, and the Xtensa l32r instruction requires that the \
- constant pool be located before the code. We put the constant \
- pool in the middle of the trampoline and jump around it. */ \
+ /* save the return address */ \
+ fprintf (STREAM, "\tmov\ta10, a0\n"); \
\
- fprintf (STREAM, "\tj\t.Lskipconsts\n"); \
+ /* Use a CALL0 instruction to skip past the constants and in the \
+ process get the PC into A0. This allows PC-relative access to \
+ the constants without relying on L32R, which may not always be \
+ available. */ \
+ \
+ fprintf (STREAM, "\tcall0\t.Lskipconsts\n"); \
fprintf (STREAM, "\t.align\t4\n"); \
- fprintf (STREAM, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE)); \
fprintf (STREAM, ".Lchainval:%s0\n", integer_asm_op (4, TRUE)); \
+ fprintf (STREAM, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE)); \
fprintf (STREAM, ".Lskipconsts:\n"); \
\
/* store the static chain */ \
- fprintf (STREAM, "\tl32r\ta8, .Lchainval\n"); \
- fprintf (STREAM, "\ts32i\ta8, sp, %d\n", \
- MIN_FRAME_SIZE - (5 * UNITS_PER_WORD)); \
+ fprintf (STREAM, "\taddi\ta0, a0, 3\n"); \
+ fprintf (STREAM, "\tl32i\ta8, a0, 0\n"); \
+ fprintf (STREAM, "\ts32i\ta8, sp, %d\n", MIN_FRAME_SIZE - 20); \
\
/* set the proper stack pointer value */ \
- fprintf (STREAM, "\tl32r\ta8, .Lfnaddr\n"); \
+ fprintf (STREAM, "\tl32i\ta8, a0, 4\n"); \
fprintf (STREAM, "\tl32i\ta9, a8, 0\n"); \
fprintf (STREAM, "\textui\ta9, a9, %d, 12\n", \
TARGET_BIG_ENDIAN ? 8 : 12); \
@@ -994,6 +1005,9 @@ typedef struct xtensa_args {
fprintf (STREAM, "\tsub\ta9, sp, a9\n"); \
fprintf (STREAM, "\tmovsp\tsp, a9\n"); \
\
+ /* restore the return address */ \
+ fprintf (STREAM, "\tmov\ta0, a10\n"); \
+ \
/* jump to the instruction following the entry */ \
fprintf (STREAM, "\taddi\ta8, a8, 3\n"); \
fprintf (STREAM, "\tjx\ta8\n"); \
@@ -1001,7 +1015,7 @@ typedef struct xtensa_args {
} while (0)
/* Size in bytes of the trampoline, as an integer. */
-#define TRAMPOLINE_SIZE 49
+#define TRAMPOLINE_SIZE 59
/* Alignment required for trampolines, in bits. */
#define TRAMPOLINE_ALIGNMENT (32)
@@ -1010,8 +1024,8 @@ typedef struct xtensa_args {
#define INITIALIZE_TRAMPOLINE(ADDR, FUNC, CHAIN) \
do { \
rtx addr = ADDR; \
- emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, 8)), FUNC); \
emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, 12)), CHAIN); \
+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, 16)), FUNC); \
emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__xtensa_sync_caches"), \
0, VOIDmode, 1, addr, Pmode); \
} while (0)
@@ -1128,7 +1142,7 @@ typedef struct xtensa_args {
\
/* allow constant pool addresses */ \
if ((MODE) != BLKmode && GET_MODE_SIZE (MODE) >= UNITS_PER_WORD \
- && constantpool_address_p (xinsn)) \
+ && !TARGET_CONST16 && constantpool_address_p (xinsn)) \
goto LABEL; \
\
while (GET_CODE (xinsn) == SUBREG) \
@@ -1330,7 +1344,6 @@ typedef struct xtensa_args {
{"call_insn_operand", { CONST_INT, CONST, SYMBOL_REF, REG }}, \
{"move_operand", { REG, SUBREG, MEM, CONST_INT, CONST_DOUBLE, \
CONST, SYMBOL_REF, LABEL_REF }}, \
- {"non_const_move_operand", { REG, SUBREG, MEM }}, \
{"const_float_1_operand", { CONST_DOUBLE }}, \
{"branch_operator", { EQ, NE, LT, GE }}, \
{"ubranch_operator", { LTU, GEU }}, \