From: Junxian Zhu This patch allows a function to request clearing of all instruction and execution hazards upon normal return via __attribute__ ((use_hazard_barrier_return)). 2017-04-25 Prachi Godbole gcc/ChangeLog: * config/mips/mips.h (machine_function): New variable use_hazard_barrier_return_p. * config/mips/mips.md (UNSPEC_JRHB): New unspec. (mips_hb_return_internal): New insn pattern. * config/mips/mips.c (mips_attribute_table): Add attribute use_hazard_barrier_return. (mips_use_hazard_barrier_return_p): New static function. (mips_function_attr_inlinable_p): Likewise. (mips_compute_frame_info): Set use_hazard_barrier_return_p. Emit error for unsupported architecture choice. (mips_function_ok_for_sibcall, mips_can_use_return_insn): Return false for use_hazard_barrier_return. (mips_expand_epilogue): Emit hazard barrier return. * doc/extend.texi: Document use_hazard_barrier_return. gcc/testsuite/ChangeLog: * gcc.target/mips/hazard-barrier-return-attribute.c: New test. Signed-off-by: Junxian Zhu --- (Dragan.Mladjenovic@mediatek.com): Rehash of original patch posted by Prachi with minimal changes. Tested against mips-mti-elf with mips32r2/-EB and mips32r2/-EB/-micromips. (zhujunxian@oss.cipunited.com): Rebase and set minimal requirement to R2 --- gcc/config/mips/mips.cc | 1 + gcc/config/mips/mips.h | 3 +++ gcc/config/mips/mips.md | 15 ++++++++++++++ gcc/doc/extend.texi | 6 ++++++ .../mips/hazard-barrier-return-attribute.c | 20 +++++++++++++++++++ 5 files changed, 45 insertions(+) create mode 100644 gcc/testsuite/gcc.target/mips/hazard-barrier-return-attribute.c diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc index 0b25db47a22..b066a2cda75 100644 --- a/gcc/config/mips/mips.cc +++ b/gcc/config/mips/mips.cc @@ -630,6 +630,7 @@ static const struct attribute_spec mips_attribute_table[] = { mips_handle_use_shadow_register_set_attr, NULL }, { "keep_interrupts_masked", 0, 0, false, true, true, false, NULL, NULL }, { "use_debug_exception_return", 0, 0, false, true, true, false, NULL, NULL }, + { "use_hazard_barrier_return", 0, 0, true, false, false, false, NULL, NULL }, { NULL, 0, 0, false, false, false, false, NULL, NULL } }; diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index fbb4372864f..f664d3044e1 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -3386,6 +3386,9 @@ struct GTY(()) machine_function { /* True if GCC stored callee saved registers in the frame header. */ bool use_frame_header_for_callee_saved_regs; + + /* True if the function should generate hazard barrier return. */ + bool use_hazard_barrier_return_p; }; #endif diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 10607a57efc..ac1d77afc7d 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -159,6 +159,7 @@ ;; The `.insn' pseudo-op. UNSPEC_INSN_PSEUDO + UNSPEC_JRHB ]) (define_constants @@ -6679,6 +6680,20 @@ [(set_attr "type" "jump") (set_attr "mode" "none")]) +;; Insn to clear execution and instruction hazards while returning. +;; However, it doesn't clear hazards created by the insn in its delay slot. +;; Thus, explicitly place a nop in its delay slot. + +(define_insn "mips_hb_return_internal" + [(return) + (unspec_volatile [(match_operand 0 "pmode_register_operand" "")] + UNSPEC_JRHB)] + "" + { + return "%(jr.hb\t$31%/%)"; + } + [(set_attr "insn_count" "2")]) + ;; Normal return. (define_insn "_internal" diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 1ae68b0f20a..11920d5f07e 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -5653,6 +5653,12 @@ On MIPS targets, you can use the @code{nocompression} function attribute to locally turn off MIPS16 and microMIPS code generation. This attribute overrides the @option{-mips16} and @option{-mmicromips} options on the command line (@pxref{MIPS Options}). + +@item use_hazard_barrier_return +@cindex @code{use_hazard_barrier_return} function attribute, MIPS +This function attribute instructs the compiler to generate a hazard barrier +return that clears all execution and instruction hazards while returning, +instead of generating a normal return instruction. @end table @node MSP430 Function Attributes diff --git a/gcc/testsuite/gcc.target/mips/hazard-barrier-return-attribute.c b/gcc/testsuite/gcc.target/mips/hazard-barrier-return-attribute.c new file mode 100644 index 00000000000..3575af44dcd --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/hazard-barrier-return-attribute.c @@ -0,0 +1,20 @@ +/* Test attribute for clearing hazards while returning. */ +/* { dg-do compile } */ +/* { dg-options "isa_rev>=2 -mno-mips16" } */ + +extern int bar (); + +static int __attribute__ ((use_hazard_barrier_return)) +foo0 () +{ + return bar (); +} + +int +foo1 () +{ + return foo0 (); +} + +/* { dg-final { scan-assembler "foo0:" } } */ +/* { dg-final { scan-assembler-times "\tjr.hb\t\\\$31\n\tnop\\n" 1 } } */ -- 2.39.1