Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP3:GA
gcc8
riscv-builtin-eh-return.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File riscv-builtin-eh-return.patch of Package gcc8
2018-06-04 Jim Wilson <jimw@sifive.com> * config/riscv/riscv-protos.h (riscv_expand_epilogue): Change bool arg to int. * config/riscv/riscv.c (riscv_for_each_saved_reg): New args epilogue and maybe_eh_return. Change regno to unsigned int. Use new args to handle EH_RETURN_DATA_REGNO registers properly. (riscv_expand_prologue): Pass new args to riscv_for_each_saved_reg. (riscv_expand_epilogue): Update comment. Change argument name and type. Update code to use new name and type. Pass new args to riscv_for_each_saved_reg. Only use EH_RETURN_STACKADJ_RTX when EXCEPTION_RETURN. * config/riscv/riscv.md (NORMAL_RETURN): New. (SIBCALL_RETURN, EXCEPTION_RETURN): New. (epilogue, sibcall_epilogue): Update riscv_expand_epilogue arg. (eh_return): Call gen_eh_return_internal and emit barrier. (eh_return_internal): Call riscv_expand_epilogue. Index: gcc-8.0.1+r259636/gcc/config/riscv/riscv-protos.h =================================================================== --- gcc-8.0.1+r259636.orig/gcc/config/riscv/riscv-protos.h +++ gcc-8.0.1+r259636/gcc/config/riscv/riscv-protos.h @@ -66,7 +66,7 @@ extern bool riscv_expand_block_move (rtx extern rtx riscv_return_addr (int, rtx); extern HOST_WIDE_INT riscv_initial_elimination_offset (int, int); extern void riscv_expand_prologue (void); -extern void riscv_expand_epilogue (bool); +extern void riscv_expand_epilogue (int); extern bool riscv_can_use_return_insn (void); extern rtx riscv_function_value (const_tree, const_tree, enum machine_mode); extern bool riscv_expand_block_move (rtx, rtx, rtx); Index: gcc-8.0.1+r259636/gcc/config/riscv/riscv.c =================================================================== --- gcc-8.0.1+r259636.orig/gcc/config/riscv/riscv.c +++ gcc-8.0.1+r259636/gcc/config/riscv/riscv.c @@ -3433,23 +3433,45 @@ riscv_save_restore_reg (machine_mode mod of the frame. */ static void -riscv_for_each_saved_reg (HOST_WIDE_INT sp_offset, riscv_save_restore_fn fn) +riscv_for_each_saved_reg (HOST_WIDE_INT sp_offset, riscv_save_restore_fn fn, + bool epilogue, bool maybe_eh_return) { HOST_WIDE_INT offset; /* Save the link register and s-registers. */ offset = cfun->machine->frame.gp_sp_offset - sp_offset; - for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) + for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++) if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST)) { - riscv_save_restore_reg (word_mode, regno, offset, fn); + bool handle_reg = TRUE; + + /* If this is a normal return in a function that calls the eh_return + builtin, then do not restore the eh return data registers as that + would clobber the return value. But we do still need to save them + in the prologue, and restore them for an exception return, so we + need special handling here. */ + if (epilogue && !maybe_eh_return && crtl->calls_eh_return) + { + unsigned int i, regnum; + + for (i = 0; (regnum = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; + i++) + if (regno == regnum) + { + handle_reg = FALSE; + break; + } + } + + if (handle_reg) + riscv_save_restore_reg (word_mode, regno, offset, fn); offset -= UNITS_PER_WORD; } /* This loop must iterate over the same space as its companion in riscv_compute_frame_info. */ offset = cfun->machine->frame.fp_sp_offset - sp_offset; - for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) + for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST)) { machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode; @@ -3630,7 +3652,7 @@ riscv_expand_prologue (void) GEN_INT (-step1)); RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; size -= step1; - riscv_for_each_saved_reg (size, riscv_save_reg); + riscv_for_each_saved_reg (size, riscv_save_reg, false, false); } frame->mask = mask; /* Undo the above fib. */ @@ -3692,11 +3714,11 @@ riscv_adjust_libcall_cfi_epilogue () return dwarf; } -/* Expand an "epilogue" or "sibcall_epilogue" pattern; SIBCALL_P - says which. */ +/* Expand an "epilogue", "sibcall_epilogue", or "eh_return_internal" pattern; + style says which. */ void -riscv_expand_epilogue (bool sibcall_p) +riscv_expand_epilogue (int style) { /* Split the frame into two. STEP1 is the amount of stack we should deallocate before restoring the registers. STEP2 is the amount we @@ -3707,7 +3729,8 @@ riscv_expand_epilogue (bool sibcall_p) unsigned mask = frame->mask; HOST_WIDE_INT step1 = frame->total_size; HOST_WIDE_INT step2 = 0; - bool use_restore_libcall = !sibcall_p && riscv_use_save_libcall (frame); + bool use_restore_libcall = ((style == NORMAL_RETURN) + && riscv_use_save_libcall (frame)); rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); rtx insn; @@ -3717,14 +3740,14 @@ riscv_expand_epilogue (bool sibcall_p) if (cfun->machine->naked_p) { - gcc_assert (!sibcall_p); + gcc_assert (style == NORMAL_RETURN); emit_jump_insn (gen_return ()); return; } - if (!sibcall_p && riscv_can_use_return_insn ()) + if ((style == NORMAL_RETURN) && riscv_can_use_return_insn ()) { emit_jump_insn (gen_return ()); return; @@ -3799,7 +3822,8 @@ riscv_expand_epilogue (bool sibcall_p) frame->mask = 0; /* Temporarily fib that we need not save GPRs. */ /* Restore the registers. */ - riscv_for_each_saved_reg (frame->total_size - step2, riscv_restore_reg); + riscv_for_each_saved_reg (frame->total_size - step2, riscv_restore_reg, + true, style == EXCEPTION_RETURN); if (use_restore_libcall) { @@ -3838,11 +3862,11 @@ riscv_expand_epilogue (bool sibcall_p) } /* Add in the __builtin_eh_return stack adjustment. */ - if (crtl->calls_eh_return) + if ((style == EXCEPTION_RETURN) && crtl->calls_eh_return) emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, EH_RETURN_STACKADJ_RTX)); - if (!sibcall_p) + if (style != SIBCALL_RETURN) emit_jump_insn (gen_simple_return_internal (ra)); } Index: gcc-8.0.1+r259636/gcc/config/riscv/riscv.md =================================================================== --- gcc-8.0.1+r259636.orig/gcc/config/riscv/riscv.md +++ gcc-8.0.1+r259636/gcc/config/riscv/riscv.md @@ -69,6 +69,10 @@ (S0_REGNUM 8) (S1_REGNUM 9) (S2_REGNUM 18) + + (NORMAL_RETURN 0) + (SIBCALL_RETURN 1) + (EXCEPTION_RETURN 2) ]) (include "predicates.md") @@ -2032,7 +2036,7 @@ [(const_int 2)] "" { - riscv_expand_epilogue (false); + riscv_expand_epilogue (NORMAL_RETURN); DONE; }) @@ -2040,7 +2044,7 @@ [(const_int 2)] "" { - riscv_expand_epilogue (true); + riscv_expand_epilogue (SIBCALL_RETURN); DONE; }) @@ -2082,6 +2086,9 @@ emit_insn (gen_eh_set_lr_di (operands[0])); else emit_insn (gen_eh_set_lr_si (operands[0])); + + emit_jump_insn (gen_eh_return_internal ()); + emit_barrier (); DONE; }) @@ -2110,6 +2117,14 @@ DONE; }) +(define_insn_and_split "eh_return_internal" + [(eh_return)] + "" + "#" + "epilogue_completed" + [(const_int 0)] + "riscv_expand_epilogue (EXCEPTION_RETURN); DONE;") + ;; ;; .................... ;;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor