* Claudiu Zissulescu <claz...@gmail.com> [2018-11-12 13:25:11 +0200]:
> Our ABI says the blink is pushed first on stack followed by an unknown > number of register saves, and finally by fp. Hence we cannot use the > EH_RETURN_ADDRESS macro as the stack is not finalized at that moment. > The alternative is to use the eh_return pattern and to initialize all > the bits after register allocation when the stack layout is finalized. > > gcc/ > xxxx-xx-xx Claudiu Zissulescu <claz...@synopsys.com> > > * config/arc/arc.c (arc_eh_return_address_location): Repurpose it > to fit the eh_return pattern. > * config/arc/arc.md (eh_return): Define. > (VUNSPEC_ARC_EH_RETURN): Likewise. > * config/arc/arc-protos.h (arc_eh_return_address_location): Match > new implementation. > * config/arc/arc.h (EH_RETURN_HANDLER_RTX): Remove it. Looks good. Thanks, Andrew > > testsuite/ > xxxx-xx-xx Claudiu Zissulescu <claz...@synopsys.com> > > * gcc.target/arc/builtin_eh.c: New test. > --- > gcc/config/arc/arc-protos.h | 2 +- > gcc/config/arc/arc.c | 13 ++++++++----- > gcc/config/arc/arc.h | 2 -- > gcc/config/arc/arc.md | 15 +++++++++++++++ > gcc/testsuite/gcc.target/arc/builtin_eh.c | 22 ++++++++++++++++++++++ > 5 files changed, 46 insertions(+), 8 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/arc/builtin_eh.c > > diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h > index 6450b6a014e..4f72a06e3dc 100644 > --- a/gcc/config/arc/arc-protos.h > +++ b/gcc/config/arc/arc-protos.h > @@ -110,7 +110,7 @@ extern bool arc_legitimize_reload_address (rtx *, > machine_mode, int, int); > extern void arc_secondary_reload_conv (rtx, rtx, rtx, bool); > extern void arc_cpu_cpp_builtins (cpp_reader *); > extern bool arc_store_addr_hazard_p (rtx_insn *, rtx_insn *); > -extern rtx arc_eh_return_address_location (void); > +extern void arc_eh_return_address_location (rtx); > extern bool arc_is_jli_call_p (rtx); > extern void arc_file_end (void); > extern bool arc_is_secure_call_p (rtx); > diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c > index 6802ca66554..a92456b457d 100644 > --- a/gcc/config/arc/arc.c > +++ b/gcc/config/arc/arc.c > @@ -3858,10 +3858,13 @@ arc_check_multi (rtx op, bool push_p) > /* Return rtx for the location of the return address on the stack, > suitable for use in __builtin_eh_return. The new return address > will be written to this location in order to redirect the return to > - the exception handler. */ > + the exception handler. Our ABI says the blink is pushed first on > + stack followed by an unknown number of register saves, and finally > + by fp. Hence we cannot use the EH_RETURN_ADDRESS macro as the > + stack is not finalized. */ > > -rtx > -arc_eh_return_address_location (void) > +void > +arc_eh_return_address_location (rtx source) > { > rtx mem; > int offset; > @@ -3889,8 +3892,8 @@ arc_eh_return_address_location (void) > remove this store seems perfectly sensible. Marking the memory > address as volatile obviously has the effect of preventing DSE > from removing the store. */ > - MEM_VOLATILE_P (mem) = 1; > - return mem; > + MEM_VOLATILE_P (mem) = true; > + emit_move_insn (mem, source); > } > > /* PIC */ > diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h > index afd6d7681cf..a0a84900917 100644 > --- a/gcc/config/arc/arc.h > +++ b/gcc/config/arc/arc.h > @@ -1355,8 +1355,6 @@ do { \ > > #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 2) > > -#define EH_RETURN_HANDLER_RTX arc_eh_return_address_location () > - > /* Turn off splitting of long stabs. */ > #define DBX_CONTIN_LENGTH 0 > > diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md > index a28c67ac184..a6bac0e8bee 100644 > --- a/gcc/config/arc/arc.md > +++ b/gcc/config/arc/arc.md > @@ -163,6 +163,7 @@ > VUNSPEC_ARC_SC > VUNSPEC_ARC_LL > VUNSPEC_ARC_BLOCKAGE > + VUNSPEC_ARC_EH_RETURN > ]) > > (define_constants > @@ -6627,6 +6628,20 @@ core_3, archs4x, archs4xd, archs4xd_slow" > [(set_attr "type" "call_no_delay_slot") > (set_attr "length" "2")]) > > +;; Patterns for exception handling > +(define_insn_and_split "eh_return" > + [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] > + VUNSPEC_ARC_EH_RETURN)] > + "" > + "#" > + "reload_completed" > + [(const_int 0)] > + " > + { > + arc_eh_return_address_location (operands[0]); > + DONE; > + }" > +) > ;; include the arc-FPX instructions > (include "fpx.md") > > diff --git a/gcc/testsuite/gcc.target/arc/builtin_eh.c > b/gcc/testsuite/gcc.target/arc/builtin_eh.c > new file mode 100644 > index 00000000000..717a54bb084 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arc/builtin_eh.c > @@ -0,0 +1,22 @@ > +/* Check if we have the right offset for @bar function. */ > +/* { dg-options "-O1" } */ > + > +void bar (void); > + > +void > +foo (int x) > +{ > + __builtin_unwind_init (); > + __builtin_eh_return (x, bar); > +} > + > +/* { dg-final { scan-assembler "r24" } } */ > +/* { dg-final { scan-assembler "r22" } } */ > +/* { dg-final { scan-assembler "r20" } } */ > +/* { dg-final { scan-assembler "r18" } } */ > +/* { dg-final { scan-assembler "r16" } } */ > +/* { dg-final { scan-assembler "r14" } } */ > +/* { dg-final { scan-assembler "r13" } } */ > +/* { dg-final { scan-assembler "r0" } } */ > +/* { dg-final { scan-assembler "fp" } } */ > +/* { dg-final { scan-assembler "fp,64" } } */ > -- > 2.19.1 >