aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYvan Roux <yvan.roux@linaro.org>2015-11-30 11:01:17 +0100
committerYvan Roux <yvan.roux@linaro.org>2015-11-30 11:02:59 +0100
commit6997dd683bb3e21b4b9480c163fb015b105f5d8e (patch)
tree860626d65f46e069422e90229629182b1badb90a
parentd8f1cc7e34db47ee20a043acc5143f17d49f37f7 (diff)
gcc/
Backport from trunk r227748. 2015-09-14 Ramana Radhakrishnan <ramana.radhakrishnan@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. gcc/ Backport from trunk r229160. 2015-10-22 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> PR target/63304 * config/aarch64/aarch64.c (aarch64_nopcrelative_literal_loads): New. (aarch64_expand_mov_immediate): Use aarch64_nopcrelative_literal_loads. (aarch64_classify_address): Likewise. (aarch64_secondary_reload): Likewise. (aarch64_override_options_after_change_1): Adjust. * config/aarch64/aarch64.md (aarch64_reload_movcp<GPF_TF:mode><P:mode>): Use aarch64_nopcrelative_literal_loads. (aarch64_reload_movcp<VALL:mode><P:mode>): Likewise. * config/aarch64/aarch64-protos.h (aarch64_nopcrelative_literal_loads): Declare gcc/testsuite/ Backport from trunk r229160. 2015-10-22 Jiong Wang <jiong.wang@arm.com> Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> PR target/63304 * gcc.target/aarch64/pr63304_1.c: New test. gcc/testsuite/ Backport from trunk r229161. 2015-10-22 Andre Vieira <andre.simoesdiasvieira@arm.com> PR testsuite/67948 * gcc.target/arm/xor-and.c: Adjust test to check for eor instead of orr. Change-Id: I939fdc89b6a545d8f60971f4bbfb1f5f901c20b6
-rw-r--r--gcc/config/aarch64/aarch64-protos.h1
-rw-r--r--gcc/config/aarch64/aarch64.c114
-rw-r--r--gcc/config/aarch64/aarch64.md26
-rw-r--r--gcc/config/aarch64/aarch64.opt4
-rw-r--r--gcc/config/aarch64/iterators.md3
-rw-r--r--gcc/config/aarch64/predicates.md4
-rw-r--r--gcc/doc/invoke.texi8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr63304_1.c47
-rw-r--r--gcc/testsuite/gcc.target/arm/xor-and.c2
9 files changed, 203 insertions, 6 deletions
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 3c46222d659..75c0161a870 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -401,4 +401,5 @@ int aarch64_ccmp_mode_to_code (enum machine_mode mode);
bool extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset);
bool aarch64_operands_ok_for_ldpstp (rtx *, bool, enum machine_mode);
bool aarch64_operands_adjust_ok_for_ldpstp (rtx *, bool, enum machine_mode);
+extern bool aarch64_nopcrelative_literal_loads;
#endif /* GCC_AARCH64_PROTOS_H */
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 0eba6a9372e..7a5a2312201 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -183,6 +183,9 @@ enum aarch64_processor aarch64_tune = cortexa53;
/* Mask to specify which instruction scheduling options should be used. */
unsigned long aarch64_tune_flags = 0;
+/* Global flag for PC relative loads. */
+bool aarch64_nopcrelative_literal_loads;
+
/* Support for command line parsing of boolean flags in the tuning
structures. */
struct aarch64_flag_desc
@@ -1566,11 +1569,27 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
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 (aarch64_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 (VOIDmode, dest, mem));
+
return;
case SYMBOL_SMALL_TLSGD:
@@ -3681,9 +3700,10 @@ aarch64_classify_address (struct aarch64_address_info *info,
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)
+ && !aarch64_nopcrelative_literal_loads)));
}
return false;
@@ -4864,12 +4884,69 @@ aarch64_legitimize_reload_address (rtx *x_p,
}
+/* 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,
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)))
+ && aarch64_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)
@@ -7511,7 +7588,7 @@ aarch64_override_options_after_change_1 (struct gcc_options *opts)
else if (opts->x_flag_omit_leaf_frame_pointer)
opts->x_flag_omit_frame_pointer = true;
- /* If not opzimizing for size, set the default
+ /* If not optimizing for size, set the default
alignment to what the target wants. */
if (!opts->x_optimize_size)
{
@@ -7522,6 +7599,24 @@ aarch64_override_options_after_change_1 (struct gcc_options *opts)
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 (opts->x_nopcrelative_literal_loads == 1)
+ aarch64_nopcrelative_literal_loads = false;
+
+ /* If it is not set on the command line, we default to no
+ pc relative literal loads. */
+ if (opts->x_nopcrelative_literal_loads == 2)
+ aarch64_nopcrelative_literal_loads = true;
+
+ /* 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 (opts->x_nopcrelative_literal_loads
+ && (aarch64_cmodel == AARCH64_CMODEL_TINY
+ || aarch64_cmodel == AARCH64_CMODEL_TINY_PIC))
+ aarch64_nopcrelative_literal_loads = false;
}
/* 'Unpack' up the internal tuning structs and update the options
@@ -8710,7 +8805,16 @@ aarch64_classify_symbol (rtx x, rtx offset)
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);
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 9751999ccfc..7503cfd4dd4 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4485,6 +4485,32 @@
;; -------------------------------------------------------------------
;; 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 && aarch64_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 && aarch64_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")
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index 8642bdb74f3..a1ce58d4ea8 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -144,3 +144,7 @@ Enum(aarch64_abi) String(ilp32) Value(AARCH64_ABI_ILP32)
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.
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 9232e8e7b92..964f8f1af68 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -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])
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index ee16dc88bd0..7841378a5da 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -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)")))
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 8d27c3ffe52..3996518204f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -12412,6 +12412,14 @@ for @var{string} in this option are not guaranteed to be consistent
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
diff --git a/gcc/testsuite/gcc.target/aarch64/pr63304_1.c b/gcc/testsuite/gcc.target/aarch64/pr63304_1.c
new file mode 100644
index 00000000000..fa0fb56d9e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr63304_1.c
@@ -0,0 +1,47 @@
+/* { dg-do assemble } */
+/* { dg-options "-O1 --save-temps" } */
+#pragma GCC push_options
+#pragma GCC target ("+nothing+simd, cmodel=small")
+
+int
+cal (float a)
+{
+ float b = 1.2;
+ float c = 2.2;
+ if ((a + b) != c)
+ return 0;
+ else
+ return 1;
+}
+
+#pragma GCC push_options
+
+#pragma GCC target ("cmodel=large")
+
+int
+cal2 (float a)
+{
+
+ float b = 1.2;
+ float c = 2.2;
+ if ((a + b) != c)
+ return 0;
+ else
+ return 1;
+}
+
+#pragma GCC pop_options
+
+int
+cal3 (float a)
+{
+
+ float b = 1.2;
+ float c = 2.2;
+ if ((a + b) != c)
+ return 0;
+ else
+ return 1;
+}
+
+/* { dg-final { scan-assembler-times "adrp" 6 } } */
diff --git a/gcc/testsuite/gcc.target/arm/xor-and.c b/gcc/testsuite/gcc.target/arm/xor-and.c
index 53dff85f8f7..3715530cd7b 100644
--- a/gcc/testsuite/gcc.target/arm/xor-and.c
+++ b/gcc/testsuite/gcc.target/arm/xor-and.c
@@ -10,6 +10,6 @@ unsigned short foo (unsigned short x)
return x;
}
-/* { dg-final { scan-assembler "orr" } } */
+/* { dg-final { scan-assembler "eor" } } */
/* { dg-final { scan-assembler-not "mvn" } } */
/* { dg-final { scan-assembler-not "uxth" } } */