aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mips
diff options
context:
space:
mode:
authorYunQiang Su <yunqiang.su@cipunited.com>2023-06-01 10:14:24 +0800
committerYunQiang Su <yunqiang.su@cipunited.com>2023-06-05 11:22:00 +0800
commit29b74545531f6afbee9fc38c267524326dbfbedf (patch)
tree620a0208b1198e972d3b2aa50a3e5909cbae38f1 /gcc/config/mips
parentc7fe7ad612bb6aac1d078d215d5700ec4ef70e3c (diff)
downloadgcc-29b74545531f6afbee9fc38c267524326dbfbedf.zip
gcc-29b74545531f6afbee9fc38c267524326dbfbedf.tar.gz
gcc-29b74545531f6afbee9fc38c267524326dbfbedf.tar.bz2
MIPS: Add speculation_barrier support
speculation_barrier for MIPS needs sync+jr.hb (r2+), so we implement __speculation_barrier in libgcc, like arm32 does. gcc/ChangeLog: * config/mips/mips-protos.h (mips_emit_speculation_barrier): New prototype. * config/mips/mips.cc (speculation_barrier_libfunc): New static variable. (mips_init_libfuncs): Initialize it. (mips_emit_speculation_barrier): New function. * config/mips/mips.md (speculation_barrier): Call mips_emit_speculation_barrier. libgcc/ChangeLog: * config/mips/lib1funcs.S: New file. define __speculation_barrier and include mips16.S. * config/mips/t-mips: define LIB1ASMSRC as mips/lib1funcs.S. define LIB1ASMFUNCS as _speculation_barrier. set version info for __speculation_barrier. * config/mips/libgcc-mips.ver: New file. * config/mips/t-mips16: don't define LIB1ASMSRC as mips16.S included in lib1funcs.S now.
Diffstat (limited to 'gcc/config/mips')
-rw-r--r--gcc/config/mips/mips-protos.h2
-rw-r--r--gcc/config/mips/mips.cc12
-rw-r--r--gcc/config/mips/mips.md12
3 files changed, 26 insertions, 0 deletions
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 2048346..da7902c 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -388,4 +388,6 @@ extern void mips_register_frame_header_opt (void);
extern void mips_expand_vec_cond_expr (machine_mode, machine_mode, rtx *);
extern void mips_expand_vec_cmp_expr (rtx *);
+extern void mips_emit_speculation_barrier_function (void);
+
#endif /* ! GCC_MIPS_PROTOS_H */
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index ca491b9..c1d1691 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -13611,6 +13611,9 @@ mips_autovectorize_vector_modes (vector_modes *modes, bool)
return 0;
}
+
+static GTY (()) rtx speculation_barrier_libfunc;
+
/* Implement TARGET_INIT_LIBFUNCS. */
static void
@@ -13680,6 +13683,7 @@ mips_init_libfuncs (void)
synchronize_libfunc = init_one_libfunc ("__sync_synchronize");
init_sync_libfuncs (UNITS_PER_WORD);
}
+ speculation_barrier_libfunc = init_one_libfunc ("__speculation_barrier");
}
/* Build up a multi-insn sequence that loads label TARGET into $AT. */
@@ -19092,6 +19096,14 @@ mips_avoid_hazard (rtx_insn *after, rtx_insn *insn, int *hilo_delay,
}
}
+/* Emit a speculation barrier.
+ JR.HB is needed, so we put speculation_barrier_libfunc in libgcc. */
+void
+mips_emit_speculation_barrier_function ()
+{
+ emit_library_call (speculation_barrier_libfunc, LCT_NORMAL, VOIDmode);
+}
+
/* A SEQUENCE is breakable iff the branch inside it has a compact form
and the target has compact branches. */
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index ac1d77a..5d04ac5 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -160,6 +160,8 @@
;; The `.insn' pseudo-op.
UNSPEC_INSN_PSEUDO
UNSPEC_JRHB
+
+ VUNSPEC_SPECULATION_BARRIER
])
(define_constants
@@ -7455,6 +7457,16 @@
mips_expand_conditional_move (operands);
DONE;
})
+
+(define_expand "speculation_barrier"
+ [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
+ ""
+ "
+ mips_emit_speculation_barrier_function ();
+ DONE;
+ "
+)
+
;;
;; ....................