On 27/08/15 15:07, Marcus Shawcroft wrote: > On 27 July 2015 at 15:33, Ramana Radhakrishnan > <ramana.radhakrish...@foss.arm.com> wrote: > >> <DATE> Ramana Radhakrishnan <ramana.radhakrish...@arm.com> >> >> PR target/63304 >> * config/aarch64/aarch64.c (aarch64_expand_mov_immediate): Handle >> nopcrelative_literal_loads. >> (aarch64_classify_address): Likewise. >> (aarch64_constant_pool_reload_icode): Define. >> (aarch64_secondary_reload): Handle secondary reloads for >> literal pools. >> (aarch64_override_options): Handle nopcrelative_literal_loads. >> (aarch64_classify_symbol): Handle nopcrelative_literal_loads. >> * config/aarch64/aarch64.md >> (aarch64_reload_movcp<ALLTF:mode><P:mode>): >> Define. >> (aarch64_reload_movcp<VALL:mode><P:mode>): Likewise. >> * config/aarch64/aarch64.opt: New option mnopc-relative-literal-loads >> * config/aarch64/predicates.md (aarch64_constant_pool_symref): New >> predicate. >> * doc/invoke.texi (mnopc-relative-literal-loads): Document. > > This looks OK to me. It needs rebasing, but OK if the rebase is > trival. Default on is fine. Hold off on the back ports for a couple > of weeks. > Cheers > /Marcus >
This is what I applied. I'll give it a week or so on trunk before backporting to the release branches. Since we handle literal pools > 1MiB away on by default, this final rebased version switches the option name to the positive form (mpc-relative-literal-loads) and handles it accordingly. Tested on aarch64-none-elf , no regressions. Applied to trunk. Thanks, Ramana 2015-09-14 Ramana Radhakrishnan <ramana.radhakrish...@arm.com> PR target/63304 * config/aarch64/aarch64.c (aarch64_expand_mov_immediate): Handle nopcrelative_literal_loads. (aarch64_classify_address): Likewise. (aarch64_constant_pool_reload_icode): Define. (aarch64_secondary_reload): Handle secondary reloads for literal pools. (aarch64_override_options): Handle nopcrelative_literal_loads. (aarch64_classify_symbol): Handle nopcrelative_literal_loads. * config/aarch64/aarch64.md (aarch64_reload_movcp<GPF_TF:mode><P:mode>): Define. (aarch64_reload_movcp<VALL:mode><P:mode>): Likewise. * config/aarch64/aarch64.opt (mpc-relative-literal-loads): New option. * config/aarch64/predicates.md (aarch64_constant_pool_symref): New predicate. * doc/invoke.texi (mpc-relative-literal-loads): Document.
Index: gcc/ChangeLog =================================================================== --- gcc/ChangeLog (revision 227737) +++ gcc/ChangeLog (working copy) @@ -1,3 +1,22 @@ +2015-09-14 Ramana Radhakrishnan <ramana.radhakrish...@arm.com> + + PR target/63304 + * config/aarch64/aarch64.c (aarch64_expand_mov_immediate): Handle + nopcrelative_literal_loads. + (aarch64_classify_address): Likewise. + (aarch64_constant_pool_reload_icode): Define. + (aarch64_secondary_reload): Handle secondary reloads for + literal pools. + (aarch64_override_options): Handle nopcrelative_literal_loads. + (aarch64_classify_symbol): Handle nopcrelative_literal_loads. + * config/aarch64/aarch64.md (aarch64_reload_movcp<GPF_TF:mode><P:mode>): + Define. + (aarch64_reload_movcp<VALL:mode><P:mode>): Likewise. + * config/aarch64/aarch64.opt (mpc-relative-literal-loads): New option. + * config/aarch64/predicates.md (aarch64_constant_pool_symref): New + predicate. + * doc/invoke.texi (mpc-relative-literal-loads): Document. + 2015-09-13 Olivier Hainque <hain...@adacore.com> Eric Botcazou <ebotca...@adacore.com> Index: gcc/config/aarch64/aarch64.c =================================================================== --- gcc/config/aarch64/aarch64.c (revision 227737) +++ gcc/config/aarch64/aarch64.c (working copy) @@ -1734,11 +1734,27 @@ aarch64_emit_move (dest, base); return; } + mem = force_const_mem (ptr_mode, imm); gcc_assert (mem); + + /* If we aren't generating PC relative literals, then + we need to expand the literal pool access carefully. + This is something that needs to be done in a number + of places, so could well live as a separate function. */ + if (nopcrelative_literal_loads) + { + gcc_assert (can_create_pseudo_p ()); + base = gen_reg_rtx (ptr_mode); + aarch64_expand_mov_immediate (base, XEXP (mem, 0)); + mem = gen_rtx_MEM (ptr_mode, base); + } + if (mode != ptr_mode) mem = gen_rtx_ZERO_EXTEND (mode, mem); + emit_insn (gen_rtx_SET (dest, mem)); + return; case SYMBOL_SMALL_TLSGD: @@ -3854,9 +3870,10 @@ rtx sym, addend; split_const (x, &sym, &addend); - return (GET_CODE (sym) == LABEL_REF - || (GET_CODE (sym) == SYMBOL_REF - && CONSTANT_POOL_ADDRESS_P (sym))); + return ((GET_CODE (sym) == LABEL_REF + || (GET_CODE (sym) == SYMBOL_REF + && CONSTANT_POOL_ADDRESS_P (sym) + && !nopcrelative_literal_loads))); } return false; @@ -5039,6 +5056,51 @@ } +/* Return the reload icode required for a constant pool in mode. */ +static enum insn_code +aarch64_constant_pool_reload_icode (machine_mode mode) +{ + switch (mode) + { + case SFmode: + return CODE_FOR_aarch64_reload_movcpsfdi; + + case DFmode: + return CODE_FOR_aarch64_reload_movcpdfdi; + + case TFmode: + return CODE_FOR_aarch64_reload_movcptfdi; + + case V8QImode: + return CODE_FOR_aarch64_reload_movcpv8qidi; + + case V16QImode: + return CODE_FOR_aarch64_reload_movcpv16qidi; + + case V4HImode: + return CODE_FOR_aarch64_reload_movcpv4hidi; + + case V8HImode: + return CODE_FOR_aarch64_reload_movcpv8hidi; + + case V2SImode: + return CODE_FOR_aarch64_reload_movcpv2sidi; + + case V4SImode: + return CODE_FOR_aarch64_reload_movcpv4sidi; + + case V2DImode: + return CODE_FOR_aarch64_reload_movcpv2didi; + + case V2DFmode: + return CODE_FOR_aarch64_reload_movcpv2dfdi; + + default: + gcc_unreachable (); + } + + gcc_unreachable (); +} static reg_class_t aarch64_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x, reg_class_t rclass, @@ -5045,6 +5107,18 @@ machine_mode mode, secondary_reload_info *sri) { + + /* If we have to disable direct literal pool loads and stores because the + function is too big, then we need a scratch register. */ + if (MEM_P (x) && GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x) + && (SCALAR_FLOAT_MODE_P (GET_MODE (x)) + || targetm.vector_mode_supported_p (GET_MODE (x))) + && nopcrelative_literal_loads) + { + sri->icode = aarch64_constant_pool_reload_icode (mode); + return NO_REGS; + } + /* Without the TARGET_SIMD instructions we cannot move a Q register to a Q register directly. We need a scratch. */ if (REG_P (x) && (mode == TFmode || mode == TImode) && mode == GET_MODE (x) @@ -7693,6 +7767,24 @@ if (opts->x_align_functions <= 0) opts->x_align_functions = aarch64_tune_params.function_align; } + + /* If nopcrelative_literal_loads is set on the command line, this + implies that the user asked for PC relative literal loads. */ + if (nopcrelative_literal_loads == 1) + nopcrelative_literal_loads = 0; + + /* If it is not set on the command line, we default to no + pc relative literal loads. */ + if (nopcrelative_literal_loads == 2) + nopcrelative_literal_loads = 1; + + /* In the tiny memory model it makes no sense + to disallow non PC relative literal pool loads + as many other things will break anyway. */ + if (nopcrelative_literal_loads + && (aarch64_cmodel == AARCH64_CMODEL_TINY + || aarch64_cmodel == AARCH64_CMODEL_TINY_PIC)) + nopcrelative_literal_loads = 0; } /* 'Unpack' up the internal tuning structs and update the options @@ -8884,7 +8976,16 @@ if (GET_CODE (x) == SYMBOL_REF) { if (aarch64_cmodel == AARCH64_CMODEL_LARGE) - return SYMBOL_FORCE_TO_MEM; + { + /* This is alright even in PIC code as the constant + pool reference is always PC relative and within + the same translation unit. */ + if (nopcrelative_literal_loads + && CONSTANT_POOL_ADDRESS_P (x)) + return SYMBOL_SMALL_ABSOLUTE; + else + return SYMBOL_FORCE_TO_MEM; + } if (aarch64_tls_symbol_p (x)) return aarch64_classify_tls_symbol (x); Index: gcc/config/aarch64/aarch64.md =================================================================== --- gcc/config/aarch64/aarch64.md (revision 227737) +++ gcc/config/aarch64/aarch64.md (working copy) @@ -4415,7 +4415,33 @@ ;; ------------------------------------------------------------------- ;; Reload support ;; ------------------------------------------------------------------- +;; Reload Scalar Floating point modes from constant pool. +;; The AArch64 port doesn't have __int128 constant move support. +(define_expand "aarch64_reload_movcp<GPF_TF:mode><P:mode>" + [(set (match_operand:GPF_TF 0 "register_operand" "=w") + (mem:GPF_TF (match_operand 1 "aarch64_constant_pool_symref" "S"))) + (clobber (match_operand:P 2 "register_operand" "=&r"))] + "TARGET_FLOAT && nopcrelative_literal_loads" + { + aarch64_expand_mov_immediate (operands[2], XEXP (operands[1], 0)); + emit_move_insn (operands[0], gen_rtx_MEM (<GPF_TF:MODE>mode, operands[2])); + DONE; + } +) +;; Reload Vector modes from constant pool. +(define_expand "aarch64_reload_movcp<VALL:mode><P:mode>" + [(set (match_operand:VALL 0 "register_operand" "=w") + (mem:VALL (match_operand 1 "aarch64_constant_pool_symref" "S"))) + (clobber (match_operand:P 2 "register_operand" "=&r"))] + "TARGET_FLOAT && nopcrelative_literal_loads" + { + aarch64_expand_mov_immediate (operands[2], XEXP (operands[1], 0)); + emit_move_insn (operands[0], gen_rtx_MEM (<VALL:MODE>mode, operands[2])); + DONE; + } +) + (define_expand "aarch64_reload_mov<mode>" [(set (match_operand:TX 0 "register_operand" "=w") (match_operand:TX 1 "register_operand" "w")) Index: gcc/config/aarch64/aarch64.opt =================================================================== --- gcc/config/aarch64/aarch64.opt (revision 227737) +++ gcc/config/aarch64/aarch64.opt (working copy) @@ -144,3 +144,7 @@ EnumValue Enum(aarch64_abi) String(lp64) Value(AARCH64_ABI_LP64) + +mpc-relative-literal-loads +Target Report Save Var(nopcrelative_literal_loads) Init(2) Save +PC relative literal loads. Index: gcc/config/aarch64/iterators.md =================================================================== --- gcc/config/aarch64/iterators.md (revision 227737) +++ gcc/config/aarch64/iterators.md (working copy) @@ -44,6 +44,9 @@ ;; Double vector modes. (define_mode_iterator VDF [V2SF V4HF]) +;; Iterator for all scalar floating point modes (SF, DF and TF) +(define_mode_iterator GPF_TF [SF DF TF]) + ;; Integer vector modes. (define_mode_iterator VDQ_I [V8QI V16QI V4HI V8HI V2SI V4SI V2DI]) Index: gcc/config/aarch64/predicates.md =================================================================== --- gcc/config/aarch64/predicates.md (revision 227737) +++ gcc/config/aarch64/predicates.md (working copy) @@ -362,3 +362,7 @@ (define_predicate "aarch64_simd_shift_imm_bitsize_di" (and (match_code "const_int") (match_test "IN_RANGE (INTVAL (op), 0, 64)"))) + +(define_predicate "aarch64_constant_pool_symref" + (and (match_code "symbol_ref") + (match_test "CONSTANT_POOL_ADDRESS_P (op)"))) Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 227737) +++ gcc/doc/invoke.texi (working copy) @@ -12437,6 +12437,14 @@ across releases. This option is only intended to be useful when developing GCC. + +@item -mpc-relative-literal-loads +@opindex mpcrelativeliteralloads +Enable PC relative literal loads. If this option is used, literal +pools are assumed to have a range of up to 1MiB and an appropriate +instruction sequence is used. This option has no impact when used +with @option{-mcmodel=tiny}. + @end table @subsubsection @option{-march} and @option{-mcpu} Feature Modifiers