X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=gcc%2Fconfig%2Fxtensa%2Fxtensa.c;h=ee5612441e25d7a48502234ab2188e3abfd2315f;hb=6c552ff765c1b02d3ec9094f92c1ce58f8cda14b;hp=60e50296d349342162f4ca474bebf72dc7c86898;hpb=ad7b10a21746a784e7e8edeb606cc99cf2853e21;p=thirdparty%2Fgcc.git diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index 60e50296d349..ee5612441e25 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -1,5 +1,5 @@ /* Subroutines for insn-output.c for Tensilica's Xtensa architecture. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2019 Free Software Foundation, Inc. Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica. This file is part of GCC. @@ -18,6 +18,8 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ +#define IN_TARGET_CODE 1 + #include "config.h" #include "system.h" #include "coretypes.h" @@ -31,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "memmodel.h" #include "tm_p.h" #include "stringpool.h" +#include "attribs.h" #include "optabs.h" #include "regs.h" #include "emit-rtl.h" @@ -77,12 +80,8 @@ enum internal_test /* Array giving truth value on whether or not a given hard register can support a given mode. */ -char xtensa_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER]; - -/* Current frame size calculated by compute_frame_size. */ -unsigned xtensa_current_frame_size; -/* Callee-save area size in the current frame calculated by compute_frame_size. */ -int xtensa_callee_save_size; +static char xtensa_hard_regno_mode_ok_p + [(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER]; /* Largest block move to handle in-line. */ #define LARGEST_MOVE_RATIO 15 @@ -95,6 +94,13 @@ struct GTY(()) machine_function bool vararg_a7; rtx vararg_a7_copy; rtx_insn *set_frame_ptr_insn; + /* Current frame size calculated by compute_frame_size. */ + unsigned current_frame_size; + /* Callee-save area size in the current frame calculated by + compute_frame_size. */ + int callee_save_size; + bool frame_laid_out; + bool epilogue_done; }; /* Vector, indexed by hard register number, which contains 1 for a @@ -174,6 +180,12 @@ static bool xtensa_member_type_forces_blk (const_tree, machine_mode mode); static void xtensa_conditional_register_usage (void); +static unsigned int xtensa_hard_regno_nregs (unsigned int, machine_mode); +static bool xtensa_hard_regno_mode_ok (unsigned int, machine_mode); +static bool xtensa_modes_tieable_p (machine_mode, machine_mode); +static HOST_WIDE_INT xtensa_constant_alignment (const_tree, HOST_WIDE_INT); +static HOST_WIDE_INT xtensa_starting_frame_offset (void); +static unsigned HOST_WIDE_INT xtensa_asan_shadow_offset (void); @@ -302,6 +314,26 @@ static void xtensa_conditional_register_usage (void); #undef TARGET_CONDITIONAL_REGISTER_USAGE #define TARGET_CONDITIONAL_REGISTER_USAGE xtensa_conditional_register_usage +#undef TARGET_HARD_REGNO_NREGS +#define TARGET_HARD_REGNO_NREGS xtensa_hard_regno_nregs +#undef TARGET_HARD_REGNO_MODE_OK +#define TARGET_HARD_REGNO_MODE_OK xtensa_hard_regno_mode_ok + +#undef TARGET_MODES_TIEABLE_P +#define TARGET_MODES_TIEABLE_P xtensa_modes_tieable_p + +#undef TARGET_CONSTANT_ALIGNMENT +#define TARGET_CONSTANT_ALIGNMENT xtensa_constant_alignment + +#undef TARGET_STARTING_FRAME_OFFSET +#define TARGET_STARTING_FRAME_OFFSET xtensa_starting_frame_offset + +#undef TARGET_ASAN_SHADOW_OFFSET +#define TARGET_ASAN_SHADOW_OFFSET xtensa_asan_shadow_offset + +#undef TARGET_HAVE_SPECULATION_SAFE_VALUE +#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed + struct gcc_target targetm = TARGET_INITIALIZER; @@ -588,7 +620,7 @@ xtensa_mem_offset (unsigned v, machine_mode mode) { switch (mode) { - case BLKmode: + case E_BLKmode: /* Handle the worst case for block moves. See xtensa_expand_block_move where we emit an optimized block move operation if the block can be moved in < "move_ratio" pieces. The worst case is when the block is @@ -597,13 +629,14 @@ xtensa_mem_offset (unsigned v, machine_mode mode) return (xtensa_uimm8 (v) && xtensa_uimm8 (v + MOVE_MAX * LARGEST_MOVE_RATIO)); - case QImode: + case E_QImode: return xtensa_uimm8 (v); - case HImode: + case E_HImode: return xtensa_uimm8x2 (v); - case DFmode: + case E_DImode: + case E_DFmode: return (xtensa_uimm8x4 (v) && xtensa_uimm8x4 (v + 4)); default: @@ -799,16 +832,16 @@ xtensa_expand_conditional_branch (rtx *operands, machine_mode mode) switch (mode) { - case DFmode: + case E_DFmode: default: fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1)); - case SImode: + case E_SImode: invert = FALSE; cmp = gen_int_relational (test_code, cmp0, cmp1, &invert); break; - case SFmode: + case E_SFmode: if (!TARGET_HARD_FLOAT) fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1)); @@ -1142,11 +1175,11 @@ xtensa_copy_incoming_a7 (rtx opnd) } if (GET_CODE (reg) != REG || REGNO (reg) > A7_REG - || REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) <= A7_REG) + || REGNO (reg) + hard_regno_nregs (A7_REG, mode) <= A7_REG) return opnd; /* 1-word args will always be in a7; 2-word args in a6/a7. */ - gcc_assert (REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) - 1 == A7_REG); + gcc_assert (REGNO (reg) + hard_regno_nregs (A7_REG, mode) - 1 == A7_REG); cfun->machine->need_a7_copy = false; @@ -1158,8 +1191,8 @@ xtensa_copy_incoming_a7 (rtx opnd) switch (mode) { - case DFmode: - case DImode: + case E_DFmode: + case E_DImode: /* Copy the value out of A7 here but keep the first word in A6 until after the set_frame_ptr insn. Otherwise, the register allocator may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming @@ -1167,16 +1200,16 @@ xtensa_copy_incoming_a7 (rtx opnd) emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 4), gen_raw_REG (SImode, A7_REG))); break; - case SFmode: + case E_SFmode: emit_insn (gen_movsf_internal (tmp, gen_raw_REG (mode, A7_REG))); break; - case SImode: + case E_SImode: emit_insn (gen_movsi_internal (tmp, gen_raw_REG (mode, A7_REG))); break; - case HImode: + case E_HImode: emit_insn (gen_movhi_internal (tmp, gen_raw_REG (mode, A7_REG))); break; - case QImode: + case E_QImode: emit_insn (gen_movqi_internal (tmp, gen_raw_REG (mode, A7_REG))); break; default: @@ -1340,7 +1373,7 @@ xtensa_expand_nonlocal_goto (rtx *operands) containing_fp = force_reg (Pmode, containing_fp); emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_nonlocal_goto"), - LCT_NORMAL, VOIDmode, 2, + LCT_NORMAL, VOIDmode, containing_fp, Pmode, goto_handler, Pmode); } @@ -1584,9 +1617,9 @@ xtensa_expand_atomic (enum rtx_code code, rtx target, rtx mem, rtx val, break; case MULT: /* NAND */ - tmp = expand_simple_binop (SImode, XOR, old, ac.modemask, + tmp = expand_simple_binop (SImode, AND, old, val, NULL_RTX, 1, OPTAB_DIRECT); - tmp = expand_simple_binop (SImode, AND, tmp, val, + tmp = expand_simple_binop (SImode, XOR, tmp, ac.modemask, new_rtx, 1, OPTAB_DIRECT); break; @@ -1620,7 +1653,7 @@ xtensa_setup_frame_addresses (void) if (TARGET_WINDOWED_ABI) emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"), - LCT_NORMAL, VOIDmode, 0); + LCT_NORMAL, VOIDmode); } @@ -1778,7 +1811,8 @@ xtensa_emit_call (int callop, rtx *operands) rtx tgt = operands[callop]; if (GET_CODE (tgt) == CONST_INT) - sprintf (result, "call%d\t0x%lx", WINDOW_SIZE, INTVAL (tgt)); + sprintf (result, "call%d\t" HOST_WIDE_INT_PRINT_HEX, + WINDOW_SIZE, INTVAL (tgt)); else if (register_operand (tgt, VOIDmode)) sprintf (result, "callx%d\t%%%d", WINDOW_SIZE, callop); else @@ -2179,6 +2213,13 @@ xtensa_option_override (void) int regno; machine_mode mode; + /* Use CONST16 in the absence of L32R. + Set it in the TARGET_OPTION_OVERRIDE to avoid dependency on xtensa + configuration in the xtensa-common.c */ + + if (!TARGET_L32R) + target_flags |= MASK_CONST16; + if (!TARGET_BOOLEANS && TARGET_HARD_FLOAT) error ("boolean registers required for the floating-point option"); @@ -2206,7 +2247,7 @@ xtensa_option_override (void) else temp = FALSE; - xtensa_hard_regno_mode_ok[(int) mode][regno] = temp; + xtensa_hard_regno_mode_ok_p[(int) mode][regno] = temp; } } @@ -2215,7 +2256,7 @@ xtensa_option_override (void) /* Check PIC settings. PIC is only supported when using L32R instructions, and some targets need to always use PIC. */ if (flag_pic && TARGET_CONST16) - error ("-f%s is not supported with CONST16 instructions", + error ("%<-f%s%> is not supported with CONST16 instructions", (flag_pic > 1 ? "PIC" : "pic")); else if (TARGET_FORCE_NO_PIC) flag_pic = 0; @@ -2241,6 +2282,35 @@ xtensa_option_override (void) } } +/* Implement TARGET_HARD_REGNO_NREGS. */ + +static unsigned int +xtensa_hard_regno_nregs (unsigned int regno, machine_mode mode) +{ + if (FP_REG_P (regno)) + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_FPREG); + return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD); +} + +/* Implement TARGET_HARD_REGNO_MODE_OK. */ + +static bool +xtensa_hard_regno_mode_ok (unsigned int regno, machine_mode mode) +{ + return xtensa_hard_regno_mode_ok_p[mode][regno]; +} + +/* Implement TARGET_MODES_TIEABLE_P. */ + +static bool +xtensa_modes_tieable_p (machine_mode mode1, machine_mode mode2) +{ + return ((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)); +} + /* A C compound statement to output to stdio stream STREAM the assembler syntax for an instruction operand X. X is an RTL expression. @@ -2321,7 +2391,8 @@ print_operand (FILE *file, rtx x, int letter) if (GET_CODE (x) == MEM && (GET_MODE (x) == DFmode || GET_MODE (x) == DImode)) { - x = adjust_address (x, GET_MODE (x) == DFmode ? SFmode : SImode, 4); + x = adjust_address (x, GET_MODE (x) == DFmode ? E_SFmode : E_SImode, + 4); output_address (GET_MODE (x), XEXP (x, 0)); } else @@ -2349,14 +2420,14 @@ print_operand (FILE *file, rtx x, int letter) case 'L': if (GET_CODE (x) == CONST_INT) - fprintf (file, "%ld", (32 - INTVAL (x)) & 0x1f); + fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INTVAL (x)) & 0x1f); else output_operand_lossage ("invalid %%L value"); break; case 'R': if (GET_CODE (x) == CONST_INT) - fprintf (file, "%ld", INTVAL (x) & 0x1f); + fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0x1f); else output_operand_lossage ("invalid %%R value"); break; @@ -2370,7 +2441,7 @@ print_operand (FILE *file, rtx x, int letter) case 'd': if (GET_CODE (x) == CONST_INT) - fprintf (file, "%ld", INTVAL (x)); + fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); else output_operand_lossage ("invalid %%d value"); break; @@ -2435,7 +2506,7 @@ print_operand (FILE *file, rtx x, int letter) else if (GET_CODE (x) == MEM) output_address (GET_MODE (x), XEXP (x, 0)); else if (GET_CODE (x) == CONST_INT) - fprintf (file, "%ld", INTVAL (x)); + fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); else output_addr_const (file, x); } @@ -2533,13 +2604,32 @@ xtensa_output_addr_const_extra (FILE *fp, rtx x) return false; } +static void +xtensa_output_integer_literal_parts (FILE *file, rtx x, int size) +{ + if (size > 4 && !(size & (size - 1))) + { + rtx first, second; + + split_double (x, &first, &second); + xtensa_output_integer_literal_parts (file, first, size / 2); + fputs (", ", file); + xtensa_output_integer_literal_parts (file, second, size / 2); + } + else if (size == 4) + { + output_addr_const (file, x); + } + else + { + gcc_unreachable(); + } +} void xtensa_output_literal (FILE *file, rtx x, machine_mode mode, int labelno) { long value_long[2]; - int size; - rtx first, second; fprintf (file, "\t.literal .LC%u, ", (unsigned) labelno); @@ -2550,7 +2640,7 @@ xtensa_output_literal (FILE *file, rtx x, machine_mode mode, int labelno) switch (mode) { - case SFmode: + case E_SFmode: REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), value_long[0]); if (HOST_BITS_PER_LONG > 32) @@ -2558,7 +2648,7 @@ xtensa_output_literal (FILE *file, rtx x, machine_mode mode, int labelno) fprintf (file, "0x%08lx\n", value_long[0]); break; - case DFmode: + case E_DFmode: REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), value_long); if (HOST_BITS_PER_LONG > 32) @@ -2578,25 +2668,8 @@ xtensa_output_literal (FILE *file, rtx x, machine_mode mode, int labelno) case MODE_INT: case MODE_PARTIAL_INT: - size = GET_MODE_SIZE (mode); - switch (size) - { - case 4: - output_addr_const (file, x); - fputs ("\n", file); - break; - - case 8: - split_double (x, &first, &second); - output_addr_const (file, first); - fputs (", ", file); - output_addr_const (file, second); - fputs ("\n", file); - break; - - default: - gcc_unreachable (); - } + xtensa_output_integer_literal_parts (file, x, GET_MODE_SIZE (mode)); + fputs ("\n", file); break; default: @@ -2628,28 +2701,33 @@ xtensa_call_save_reg(int regno) #define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1)) long -compute_frame_size (int size) +compute_frame_size (poly_int64 size) { int regno; + if (reload_completed && cfun->machine->frame_laid_out) + return cfun->machine->current_frame_size; + /* Add space for the incoming static chain value. */ if (cfun->static_chain_decl != NULL) size += (1 * UNITS_PER_WORD); - xtensa_callee_save_size = 0; + cfun->machine->callee_save_size = 0; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno) { if (xtensa_call_save_reg(regno)) - xtensa_callee_save_size += UNITS_PER_WORD; + cfun->machine->callee_save_size += UNITS_PER_WORD; } - xtensa_current_frame_size = + cfun->machine->current_frame_size = XTENSA_STACK_ALIGN (size - + xtensa_callee_save_size + + cfun->machine->callee_save_size + crtl->outgoing_args_size + (WINDOW_SIZE * UNITS_PER_WORD)); - xtensa_callee_save_size = XTENSA_STACK_ALIGN (xtensa_callee_save_size); - return xtensa_current_frame_size; + cfun->machine->callee_save_size = + XTENSA_STACK_ALIGN (cfun->machine->callee_save_size); + cfun->machine->frame_laid_out = true; + return cfun->machine->current_frame_size; } @@ -2667,6 +2745,30 @@ xtensa_frame_pointer_required (void) return false; } +HOST_WIDE_INT +xtensa_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED) +{ + long frame_size = compute_frame_size (get_frame_size ()); + HOST_WIDE_INT offset; + + switch (from) + { + case FRAME_POINTER_REGNUM: + if (FRAME_GROWS_DOWNWARD) + offset = frame_size - (WINDOW_SIZE * UNITS_PER_WORD) + - cfun->machine->callee_save_size; + else + offset = 0; + break; + case ARG_POINTER_REGNUM: + offset = frame_size; + break; + default: + gcc_unreachable (); + } + + return offset; +} /* minimum frame = reg save area (4 words) plus static chain (1 word) and the total number of words must be a multiple of 128 bits. */ @@ -2703,6 +2805,7 @@ xtensa_expand_prologue (void) { int regno; HOST_WIDE_INT offset = 0; + int callee_save_size = cfun->machine->callee_save_size; /* -128 is a limit of single addi instruction. */ if (total_size > 0 && total_size <= 128) @@ -2716,7 +2819,7 @@ xtensa_expand_prologue (void) add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); offset = total_size - UNITS_PER_WORD; } - else if (xtensa_callee_save_size) + else if (callee_save_size) { /* 1020 is maximal s32i offset, if the frame is bigger than that * we move sp to the end of callee-saved save area, save and then @@ -2724,13 +2827,13 @@ xtensa_expand_prologue (void) if (total_size > 1024) { insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (-xtensa_callee_save_size))); + GEN_INT (-callee_save_size))); RTX_FRAME_RELATED_P (insn) = 1; note_rtx = gen_rtx_SET (stack_pointer_rtx, plus_constant (Pmode, stack_pointer_rtx, - -xtensa_callee_save_size)); + -callee_save_size)); add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); - offset = xtensa_callee_save_size - UNITS_PER_WORD; + offset = callee_save_size - UNITS_PER_WORD; } else { @@ -2762,17 +2865,18 @@ xtensa_expand_prologue (void) gen_rtx_SET (mem, reg)); } } - if (total_size > 1024) + if (total_size > 1024 + || (!callee_save_size && total_size > 128)) { rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); emit_move_insn (tmp_reg, GEN_INT (total_size - - xtensa_callee_save_size)); + callee_save_size)); insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp_reg)); RTX_FRAME_RELATED_P (insn) = 1; note_rtx = gen_rtx_SET (stack_pointer_rtx, plus_constant (Pmode, stack_pointer_rtx, - xtensa_callee_save_size - + callee_save_size - total_size)); add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx); } @@ -2840,21 +2944,21 @@ xtensa_expand_epilogue (void) int regno; HOST_WIDE_INT offset; - if (xtensa_current_frame_size > (frame_pointer_needed ? 127 : 1024)) + if (cfun->machine->current_frame_size > (frame_pointer_needed ? 127 : 1024)) { rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); - emit_move_insn (tmp_reg, GEN_INT (xtensa_current_frame_size - - xtensa_callee_save_size)); + emit_move_insn (tmp_reg, GEN_INT (cfun->machine->current_frame_size - + cfun->machine->callee_save_size)); emit_insn (gen_addsi3 (stack_pointer_rtx, frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx, tmp_reg)); - offset = xtensa_callee_save_size - UNITS_PER_WORD; + offset = cfun->machine->callee_save_size - UNITS_PER_WORD; } else { if (frame_pointer_needed) emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx); - offset = xtensa_current_frame_size - UNITS_PER_WORD; + offset = cfun->machine->current_frame_size - UNITS_PER_WORD; } /* Prevent reordering of saved a0 update and loading it back from @@ -2874,16 +2978,16 @@ xtensa_expand_epilogue (void) } } - if (xtensa_current_frame_size > 0) + if (cfun->machine->current_frame_size > 0) { if (frame_pointer_needed || /* always reachable with addi */ - xtensa_current_frame_size > 1024 || - xtensa_current_frame_size <= 127) + cfun->machine->current_frame_size > 1024 || + cfun->machine->current_frame_size <= 127) { - if (xtensa_current_frame_size <= 127) - offset = xtensa_current_frame_size; + if (cfun->machine->current_frame_size <= 127) + offset = cfun->machine->current_frame_size; else - offset = xtensa_callee_save_size; + offset = cfun->machine->callee_save_size; emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, @@ -2892,7 +2996,8 @@ xtensa_expand_epilogue (void) else { rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG); - emit_move_insn (tmp_reg, GEN_INT (xtensa_current_frame_size)); + emit_move_insn (tmp_reg, + GEN_INT (cfun->machine->current_frame_size)); emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp_reg)); } @@ -2903,11 +3008,22 @@ xtensa_expand_epilogue (void) stack_pointer_rtx, EH_RETURN_STACKADJ_RTX)); } - xtensa_current_frame_size = 0; - xtensa_callee_save_size = 0; + cfun->machine->epilogue_done = true; emit_jump_insn (gen_return ()); } +bool +xtensa_use_return_instruction_p (void) +{ + if (!reload_completed) + return false; + if (TARGET_WINDOWED_ABI) + return true; + if (compute_frame_size (get_frame_size ()) == 0) + return true; + return cfun->machine->epilogue_done; +} + void xtensa_set_return_address (rtx address, rtx scratch) { @@ -3989,7 +4105,7 @@ xtensa_trampoline_init (rtx m_tramp, tree fndecl, rtx chain) emit_move_insn (adjust_address (m_tramp, SImode, chain_off), chain); emit_move_insn (adjust_address (m_tramp, SImode, func_off), func); emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_sync_caches"), - LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode); + LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode); } /* Implement TARGET_LEGITIMATE_CONSTANT_P. */ @@ -4031,8 +4147,6 @@ xtensa_invalid_within_doloop (const rtx_insn *insn) /* Optimize LOOP. */ -#if TARGET_LOOPS - static bool hwloop_optimize (hwloop_info loop) { @@ -4145,7 +4259,7 @@ hwloop_optimize (hwloop_info loop) entry_after = BB_END (entry_bb); while (DEBUG_INSN_P (entry_after) || (NOTE_P (entry_after) - && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK)) + && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK)) entry_after = PREV_INSN (entry_after); emit_insn_after (seq, entry_after); @@ -4216,14 +4330,9 @@ static struct hw_doloop_hooks xtensa_doloop_hooks = static void xtensa_reorg_loops (void) { - reorg_loops (false, &xtensa_doloop_hooks); -} -#else -static inline void -xtensa_reorg_loops (void) -{ + if (TARGET_LOOPS) + reorg_loops (false, &xtensa_doloop_hooks); } -#endif /* Implement the TARGET_MACHINE_DEPENDENT_REORG pass. */ @@ -4286,4 +4395,37 @@ enum reg_class xtensa_regno_to_class (int regno) return regno_to_class[regno]; } +/* Implement TARGET_CONSTANT_ALIGNMENT. Align string constants and + constructors to at least a word boundary. The typical use of this + macro is to increase alignment for string constants to be word + aligned so that 'strcpy' calls that copy constants can be done + inline. */ + +static HOST_WIDE_INT +xtensa_constant_alignment (const_tree exp, HOST_WIDE_INT align) +{ + if ((TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR) + && !optimize_size) + return MAX (align, BITS_PER_WORD); + return align; +} + +/* Implement TARGET_STARTING_FRAME_OFFSET. */ + +static HOST_WIDE_INT +xtensa_starting_frame_offset (void) +{ + if (FRAME_GROWS_DOWNWARD) + return 0; + return crtl->outgoing_args_size; +} + +/* Implement TARGET_ASAN_SHADOW_OFFSET. */ + +static unsigned HOST_WIDE_INT +xtensa_asan_shadow_offset (void) +{ + return HOST_WIDE_INT_UC (0x10000000); +} + #include "gt-xtensa.h"