aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc-4.9/gcc/config/aarch64/aarch64-protos.h2
-rw-r--r--gcc-4.9/gcc/config/aarch64/aarch64.c131
-rw-r--r--gcc-4.9/gcc/config/aarch64/aarch64.h9
-rw-r--r--gcc-4.9/gcc/config/aarch64/aarch64.opt4
-rwxr-xr-xgcc-4.9/gcc/configure28
-rw-r--r--gcc-4.9/gcc/configure.ac23
-rw-r--r--gcc-4.9/gcc/doc/install.texi10
-rw-r--r--gcc-4.9/gcc/doc/invoke.texi9
8 files changed, 216 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/config/aarch64/aarch64-protos.h b/gcc-4.9/gcc/config/aarch64/aarch64-protos.h
index 5542f023b..bef58bf71 100644
--- a/gcc-4.9/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc-4.9/gcc/config/aarch64/aarch64-protos.h
@@ -287,6 +287,8 @@ aarch64_builtin_vectorized_function (tree fndecl,
extern void aarch64_split_combinev16qi (rtx operands[3]);
extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
+extern bool aarch64_madd_needs_nop (rtx);
+extern void aarch64_final_prescan_insn (rtx);
extern bool
aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel);
#endif /* GCC_AARCH64_PROTOS_H */
diff --git a/gcc-4.9/gcc/config/aarch64/aarch64.c b/gcc-4.9/gcc/config/aarch64/aarch64.c
index 07430a48d..34986d7c6 100644
--- a/gcc-4.9/gcc/config/aarch64/aarch64.c
+++ b/gcc-4.9/gcc/config/aarch64/aarch64.c
@@ -5256,6 +5256,15 @@ aarch64_override_options (void)
aarch64_tune = selected_tune->core;
aarch64_tune_params = selected_tune->tune;
+ if (aarch64_fix_a53_err835769 == 2)
+ {
+#ifdef TARGET_FIX_ERR_A53_835769_DEFAULT
+ aarch64_fix_a53_err835769 = 1;
+#else
+ aarch64_fix_a53_err835769 = 0;
+#endif
+ }
+
aarch64_override_options_after_change ();
if (TARGET_ANDROID)
@@ -6466,6 +6475,128 @@ aarch64_mangle_type (const_tree type)
return NULL;
}
+static int
+is_mem_p (rtx *x, void *data ATTRIBUTE_UNUSED)
+{
+ return MEM_P (*x);
+}
+
+static bool
+is_memory_op (rtx mem_insn)
+{
+ rtx pattern = PATTERN (mem_insn);
+ return for_each_rtx (&pattern, is_mem_p, NULL);
+}
+
+/* Find the first rtx before insn that will generate an assembly
+ instruction. */
+
+static rtx
+aarch64_prev_real_insn (rtx insn)
+{
+ if (!insn)
+ return NULL;
+
+ do
+ {
+ insn = prev_real_insn (insn);
+ }
+ while (insn && recog_memoized (insn) < 0);
+
+ return insn;
+}
+
+static bool
+is_madd_op (enum attr_type t1)
+{
+ unsigned int i;
+ /* A number of these may be AArch32 only. */
+ enum attr_type mlatypes[] = {
+ TYPE_MLA, TYPE_MLAS, TYPE_SMLAD, TYPE_SMLADX, TYPE_SMLAL, TYPE_SMLALD,
+ TYPE_SMLALS, TYPE_SMLALXY, TYPE_SMLAWX, TYPE_SMLAWY, TYPE_SMLAXY,
+ TYPE_SMMLA, TYPE_UMLAL, TYPE_UMLALS,TYPE_SMLSD, TYPE_SMLSDX, TYPE_SMLSLD
+ };
+
+ for (i = 0; i < sizeof (mlatypes) / sizeof (enum attr_type); i++)
+ {
+ if (t1 == mlatypes[i])
+ return true;
+ }
+
+ return false;
+}
+
+/* Check if there is a register dependency between a load and the insn
+ for which we hold recog_data. */
+
+static bool
+dep_between_memop_and_curr (rtx memop)
+{
+ rtx load_reg;
+ int opno;
+
+ if (!memop)
+ return false;
+
+ if (!REG_P (SET_DEST (memop)))
+ return false;
+
+ load_reg = SET_DEST (memop);
+ for (opno = 0; opno < recog_data.n_operands; opno++)
+ {
+ rtx operand = recog_data.operand[opno];
+ if (REG_P (operand)
+ && reg_overlap_mentioned_p (load_reg, operand))
+ return true;
+
+ }
+ return false;
+}
+
+bool
+aarch64_madd_needs_nop (rtx insn)
+{
+ enum attr_type attr_type;
+ rtx prev;
+ rtx body;
+
+ if (!aarch64_fix_a53_err835769)
+ return false;
+
+ if (recog_memoized (insn) < 0)
+ return false;
+
+ attr_type = get_attr_type (insn);
+ if (!is_madd_op (attr_type))
+ return false;
+
+ prev = aarch64_prev_real_insn (insn);
+ if (!prev)
+ return false;
+
+ body = single_set (prev);
+
+ /* If the previous insn is a memory op and there is no dependency between
+ it and the madd, emit a nop between them. If we know the previous insn is
+ a memory op but body is NULL, emit the nop to be safe, it's probably a
+ load/store pair insn. */
+ if (is_memory_op (prev)
+ && GET_MODE (recog_data.operand[0]) == DImode
+ && (!dep_between_memop_and_curr (body)))
+ return true;
+
+ return false;
+
+}
+
+void
+aarch64_final_prescan_insn (rtx insn)
+{
+ if (aarch64_madd_needs_nop (insn))
+ fprintf (asm_out_file, "\tnop // between mem op and mult-accumulate\n");
+}
+
+
/* Return the equivalent letter for size. */
static char
sizetochar (int size)
diff --git a/gcc-4.9/gcc/config/aarch64/aarch64.h b/gcc-4.9/gcc/config/aarch64/aarch64.h
index 2fd6df4af..77b2bb9b4 100644
--- a/gcc-4.9/gcc/config/aarch64/aarch64.h
+++ b/gcc-4.9/gcc/config/aarch64/aarch64.h
@@ -481,6 +481,15 @@ enum target_cpus
(TARGET_CPU_generic | (AARCH64_CPU_DEFAULT_FLAGS << 6))
#endif
+/* If inserting NOP before a mult-accumulate insn remember to adjust the
+ length so that conditional branching code is updated appropriately. */
+#define ADJUST_INSN_LENGTH(insn, length) \
+ if (aarch64_madd_needs_nop (insn)) \
+ length += 4;
+
+#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
+ aarch64_final_prescan_insn (INSN); \
+
/* The processor for which instructions should be scheduled. */
extern enum aarch64_processor aarch64_tune;
diff --git a/gcc-4.9/gcc/config/aarch64/aarch64.opt b/gcc-4.9/gcc/config/aarch64/aarch64.opt
index f5a15b729..fc0307e28 100644
--- a/gcc-4.9/gcc/config/aarch64/aarch64.opt
+++ b/gcc-4.9/gcc/config/aarch64/aarch64.opt
@@ -67,6 +67,10 @@ mgeneral-regs-only
Target Report RejectNegative Mask(GENERAL_REGS_ONLY)
Generate code which uses only the general registers
+mfix-cortex-a53-835769
+Target Report Var(aarch64_fix_a53_err835769) Init(2)
+Workaround for ARM Cortex-A53 Erratum number 835769
+
mlittle-endian
Target Report RejectNegative InverseMask(BIG_END)
Assume target CPU is configured as little endian
diff --git a/gcc-4.9/gcc/configure b/gcc-4.9/gcc/configure
index f7edc71d1..1db5c2b80 100755
--- a/gcc-4.9/gcc/configure
+++ b/gcc-4.9/gcc/configure
@@ -921,6 +921,7 @@ with_plugin_ld
enable_gnu_indirect_function
enable_initfini_array
enable_comdat
+enable_fix_cortex_a53_835769
with_glibc_version
enable_gnu_unique_object
enable_eh_frame_hdr_for_static
@@ -1640,6 +1641,14 @@ Optional Features:
glibc systems
--enable-initfini-array use .init_array/.fini_array sections
--enable-comdat enable COMDAT group support
+
+ --enable-fix-cortex-a53-835769
+ enable workaround for AArch64 Cortex-A53 erratum
+ 835769 by default
+ --disable-fix-cortex-a53-835769
+ disable workaround for AArch64 Cortex-A53 erratum
+ 835769 by default
+
--enable-gnu-unique-object
enable the use of the @gnu_unique_object ELF
extension on glibc systems
@@ -24060,6 +24069,25 @@ $as_echo "#define HAVE_AS_MABI_OPTION 1" >>confdefs.h
done
fi
fi
+ # Enable default workaround for AArch64 Cortex-A53 erratum 835769.
+ # Check whether --enable-fix-cortex-a53-835769 was given.
+if test "${enable_fix_cortex_a53_835769+set}" = set; then :
+ enableval=$enable_fix_cortex_a53_835769;
+ case $enableval in
+ yes)
+ tm_defines="${tm_defines} TARGET_FIX_ERR_A53_835769_DEFAULT=1"
+ ;;
+ no)
+ ;;
+ *)
+ as_fn_error "'$enableval' is an invalid value for --enable-fix-cortex-a53-835769.\
+ Valid choices are 'yes' and 'no'." "$LINENO" 5
+ ;;
+
+ esac
+
+fi
+
;;
# All TARGET_ABI_OSF targets.
diff --git a/gcc-4.9/gcc/configure.ac b/gcc-4.9/gcc/configure.ac
index 309f068e2..7e545d74a 100644
--- a/gcc-4.9/gcc/configure.ac
+++ b/gcc-4.9/gcc/configure.ac
@@ -3562,6 +3562,29 @@ case "$target" in
done
fi
fi
+ # Enable default workaround for AArch64 Cortex-A53 erratum 835769.
+ AC_ARG_ENABLE(fix-cortex-a53-835769,
+ [
+AS_HELP_STRING([--enable-fix-cortex-a53-835769],
+ [enable workaround for AArch64 Cortex-A53 erratum 835769 by default])
+AS_HELP_STRING([--disable-fix-cortex-a53-835769],
+ [disable workaround for AArch64 Cortex-A53 erratum 835769 by default])
+ ],
+ [
+ case $enableval in
+ yes)
+ tm_defines="${tm_defines} TARGET_FIX_ERR_A53_835769_DEFAULT=1"
+ ;;
+ no)
+ ;;
+ *)
+ AC_MSG_ERROR(['$enableval' is an invalid value for --enable-fix-cortex-a53-835769.\
+ Valid choices are 'yes' and 'no'.])
+ ;;
+
+ esac
+ ],
+ [])
;;
# All TARGET_ABI_OSF targets.
diff --git a/gcc-4.9/gcc/doc/install.texi b/gcc-4.9/gcc/doc/install.texi
index 80cb0a90c..b298321be 100644
--- a/gcc-4.9/gcc/doc/install.texi
+++ b/gcc-4.9/gcc/doc/install.texi
@@ -3788,6 +3788,16 @@ Binutils pre 2.24 does not have support for selecting @option{-mabi} and
does not support ILP32. If it is used to build GCC 4.9 or later, GCC will
not support option @option{-mabi=ilp32}.
+To enable a workaround for the Cortex-A53 erratum number 835769 by default
+(for all CPUs regardless of -mcpu option given) at configure time use the
+@option{--enable-fix-cortex-a53-835769} option. This will enable the fix by
+default and can be explicitly disabled during during compilation by passing the
+@option{-mno-fix-cortex-a53-835769} option. Conversely,
+@option{--disable-fix-cortex-a53-835769} will disable the workaround by
+default. The workaround is disabled by default if neither of
+@option{--enable-fix-cortex-a53-835769} or
+@option{--disable-fix-cortex-a53-835769} is given at configure time.
+
@html
<hr />
<!-- rs6000-ibm-aix*, powerpc-ibm-aix* -->
diff --git a/gcc-4.9/gcc/doc/invoke.texi b/gcc-4.9/gcc/doc/invoke.texi
index 2fb008d42..ed64aae13 100644
--- a/gcc-4.9/gcc/doc/invoke.texi
+++ b/gcc-4.9/gcc/doc/invoke.texi
@@ -488,6 +488,7 @@ Objective-C and Objective-C++ Dialects}.
-mstrict-align @gol
-momit-leaf-frame-pointer -mno-omit-leaf-frame-pointer @gol
-mtls-dialect=desc -mtls-dialect=traditional @gol
+-mfix-cortex-a53-835769 -mno-fix-cortex-a53-835769 @gol
-march=@var{name} -mcpu=@var{name} -mtune=@var{name}}
@emph{Adapteva Epiphany Options}
@@ -11699,6 +11700,14 @@ of TLS variables. This is the default.
Use traditional TLS as the thread-local storage mechanism for dynamic accesses
of TLS variables.
+@item -mfix-cortex-a53-835769
+@itemx -mno-fix-cortex-a53-835769
+@opindex -mfix-cortex-a53-835769
+@opindex -mno-fix-cortex-a53-835769
+Enable or disable the workaround for the ARM Cortex-A53 erratum number 835769.
+This will involve inserting a NOP instruction between memory instructions and
+64-bit integer multiply-accumulate instructions.
+
@item -march=@var{name}
@opindex march
Specify the name of the target architecture, optionally suffixed by one or