+2018-08-23 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/86951
+ * config/arm/arm-protos.h (arm_emit_speculation_barrier): New
+ prototype.
+ * config/arm/arm.c (speculation_barrier_libfunc): New static
+ variable.
+ (arm_init_libfuncs): Initialize it.
+ (arm_emit_speculation_barrier): New function.
+ * config/arm/arm.md (speculation_barrier): Call
+ arm_emit_speculation_barrier for architectures that do not have
+ DSB or ISB.
+ (speculation_barrier_insn): Only match on Armv7 or later.
+
2018-08-23 Richard Biener <rguenther@suse.de>
PR middle-end/87024
extern rtx arm_simd_vect_par_cnst_half (machine_mode mode, bool high);
extern bool arm_simd_check_vect_par_cnst_half_p (rtx op, machine_mode mode,
bool high);
+extern void arm_emit_speculation_barrier_function (void);
+
#ifdef RTX_CODE
extern void arm_gen_unlikely_cbranch (enum rtx_code, machine_mode cc_mode,
rtx label_ref);
set_conv_libfunc (optable, to, from, buffer);
}
-/* Set up library functions unique to ARM. */
+static GTY(()) rtx speculation_barrier_libfunc;
+/* Set up library functions unique to ARM. */
static void
arm_init_libfuncs (void)
{
if (TARGET_AAPCS_BASED)
synchronize_libfunc = init_one_libfunc ("__sync_synchronize");
+
+ speculation_barrier_libfunc = init_one_libfunc ("__speculation_barrier");
}
/* On AAPCS systems, this is the "struct __va_list". */
return align;
}
+/* Emit a speculation barrier on target architectures that do not have
+ DSB/ISB directly. Such systems probably don't need a barrier
+ themselves, but if the code is ever run on a later architecture, it
+ might become a problem. */
+void
+arm_emit_speculation_barrier_function ()
+{
+ emit_library_call (speculation_barrier_libfunc, LCT_NORMAL, VOIDmode);
+}
+
#if CHECKING_P
namespace selftest {
[(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
"TARGET_EITHER"
"
- /* Don't emit anything for Thumb1 and suppress the warning from the
- generic expansion. */
- if (!TARGET_32BIT)
- DONE;
+ /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
+ have a usable barrier (and probably don't need one in practice).
+ But to be safe if such code is run on later architectures, call a
+ helper function in libgcc that will do the thing for the active
+ system. */
+ if (!(arm_arch7 || arm_arch8))
+ {
+ arm_emit_speculation_barrier_function ();
+ DONE;
+ }
"
)
;; tracking.
(define_insn "*speculation_barrier_insn"
[(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
- "TARGET_32BIT"
+ "arm_arch7 || arm_arch8"
"isb\;dsb\\tsy"
[(set_attr "type" "block")
(set_attr "length" "8")]
+2018-08-23 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/86951
+ * config/arm/lib1funcs.asm (speculation_barrier): New function.
+ * config/arm/t-arm (LIB1ASMFUNCS): Add it to list of functions
+ to build.
+
2018-08-22 Iain Sandoe <iain@sandoe.co.uk>
* config/unwind-dw2-fde-darwin.c
#error "This is only for ARM EABI GNU/Linux"
#endif
#endif /* L_clear_cache */
+
+#ifdef L_speculation_barrier
+ FUNC_START speculation_barrier
+#if __ARM_ARCH >= 7
+ isb
+ dsb sy
+#elif defined __ARM_EABI__ && defined __linux__
+ /* We don't have a speculation barrier directly for this
+ platform/architecture variant. But we can use a kernel
+ clear_cache service routine which will emit such instructions
+ if run on a later version of the architecture. We don't
+ really want to flush the cache, but we must give it a valid
+ address, so just clear pc..pc+1. */
+#if defined __thumb__ && !defined __thumb2__
+ push {r7}
+ mov r7, #0xf
+ lsl r7, #16
+ add r7, #2
+ adr r0, . + 4
+ add r1, r0, #1
+ mov r2, #0
+ svc 0
+ pop {r7}
+#else
+ do_push {r7}
+#ifdef __ARM_ARCH_6T2__
+ movw r7, #2
+ movt r7, #0xf
+#else
+ mov r7, #0xf0000
+ add r7, r7, #2
+#endif
+ add r0, pc, #0 /* ADR. */
+ add r1, r0, #1
+ mov r2, #0
+ svc 0
+ do_pop {r7}
+#endif /* Thumb1 only */
+#else
+#warning "No speculation barrier defined for this platform"
+#endif
+ RET
+ FUNC_END speculation_barrier
+#endif
/* ------------------------------------------------------------------------ */
/* Dword shift operations. */
/* All the following Dword shift variants rely on the fact that
LIB1ASMSRC = arm/lib1funcs.S
LIB1ASMFUNCS = _thumb1_case_sqi _thumb1_case_uqi _thumb1_case_shi \
- _thumb1_case_uhi _thumb1_case_si
+ _thumb1_case_uhi _thumb1_case_si _speculation_barrier
HAVE_CMSE:=$(findstring __ARM_FEATURE_CMSE,$(shell $(gcc_compile_bare) -dM -E - </dev/null))
ifneq ($(shell $(gcc_compile_bare) -E -mcmse - </dev/null 2>/dev/null),)