diff options
Diffstat (limited to 'gcc-4.9')
-rw-r--r-- | gcc-4.9/gcc/config/aarch64/aarch64-protos.h | 2 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/aarch64/aarch64.c | 131 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/aarch64/aarch64.h | 9 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/aarch64/aarch64.opt | 4 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/i386/gnu-user.h | 2 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/i386/gnu-user64.h | 2 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/linux.c | 2 | ||||
-rwxr-xr-x | gcc-4.9/gcc/configure | 28 | ||||
-rw-r--r-- | gcc-4.9/gcc/configure.ac | 23 | ||||
-rw-r--r-- | gcc-4.9/gcc/doc/install.texi | 10 | ||||
-rw-r--r-- | gcc-4.9/gcc/doc/invoke.texi | 9 |
11 files changed, 219 insertions, 3 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/config/i386/gnu-user.h b/gcc-4.9/gcc/config/i386/gnu-user.h index d4a16e470..7f59c0b23 100644 --- a/gcc-4.9/gcc/config/i386/gnu-user.h +++ b/gcc-4.9/gcc/config/i386/gnu-user.h @@ -67,7 +67,7 @@ along with GCC; see the file COPYING3. If not see #undef ANDROID_TARGET_CC1_SPEC #define ANDROID_TARGET_CC1_SPEC \ - " -mstackrealign -mssse3 -fno-short-enums " \ + " -mssse3 -fno-short-enums " \ #undef ASM_SPEC #define ASM_SPEC \ diff --git a/gcc-4.9/gcc/config/i386/gnu-user64.h b/gcc-4.9/gcc/config/i386/gnu-user64.h index 0333b5c26..39d13d1d1 100644 --- a/gcc-4.9/gcc/config/i386/gnu-user64.h +++ b/gcc-4.9/gcc/config/i386/gnu-user64.h @@ -48,7 +48,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #undef ANDROID_TARGET_CC1_SPEC #define ANDROID_TARGET_CC1_SPEC \ - "%{m32:-mstackrealign -mssse3 -fno-short-enums}" \ + "%{m32:-mssse3 -fno-short-enums}" \ "%{!m32:-msse4.2 -mpopcnt}" #undef ASM_SPEC diff --git a/gcc-4.9/gcc/config/linux.c b/gcc-4.9/gcc/config/linux.c index 2f1cd8e63..7c3c5a461 100644 --- a/gcc-4.9/gcc/config/linux.c +++ b/gcc-4.9/gcc/config/linux.c @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see bool linux_has_ifunc_p (void) { - return OPTION_BIONIC ? false : HAVE_GNU_INDIRECT_FUNCTION; + return HAVE_GNU_INDIRECT_FUNCTION; } bool 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 |