diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/common/config/microblaze/microblaze-common.c | 3 | ||||
-rw-r--r-- | gcc/config/microblaze/microblaze-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/microblaze/microblaze.c | 27 | ||||
-rw-r--r-- | gcc/config/microblaze/microblaze.h | 16 | ||||
-rw-r--r-- | gcc/config/microblaze/microblaze.md | 10 |
6 files changed, 66 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9600c43..88cc61b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2017-01-06 Edgar E. Iglesias <edgar.iglesias@xilinx.com> + David Holsgrove <david.holsgrove@xilinx.com> + + * common/config/microblaze/microblaze-common.c + (TARGET_EXCEPT_UNWIND_INFO): Remove. + * config/microblaze/microblaze-protos.h (microblaze_eh_return): + New prototype. + * config/microblaze/microblaze.c (microblaze_must_save_register) + (microblaze_expand_epilogue, microblaze_return_addr): Handle + calls_eh_return. + (microblaze_eh_return): New function. + * config/microblaze/microblaze.h (RETURN_ADDR_OFFSET) + (EH_RETURN_DATA_REGNO, MB_EH_STACKADJ_REGNUM) + (EH_RETURN_STACKADJ_RTX, ASM_PREFERRED_EH_DATA_FORMAT): New macros. + * config/microblaze/microblaze.md (eh_return): New pattern. + 2017-01-06 Jakub Jelinek <jakub@redhat.com> * system.h (GCC_DIAGNOSTIC_PUSH_IGNORED, GCC_DIAGNOSTIC_POP, diff --git a/gcc/common/config/microblaze/microblaze-common.c b/gcc/common/config/microblaze/microblaze-common.c index 57a3099..4975663 100644 --- a/gcc/common/config/microblaze/microblaze-common.c +++ b/gcc/common/config/microblaze/microblaze-common.c @@ -37,7 +37,4 @@ static const struct default_options microblaze_option_optimization_table[] = #undef TARGET_OPTION_OPTIMIZATION_TABLE #define TARGET_OPTION_OPTIMIZATION_TABLE microblaze_option_optimization_table -#undef TARGET_EXCEPT_UNWIND_INFO -#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info - struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h index 6fb3066..9ba8f2d 100644 --- a/gcc/config/microblaze/microblaze-protos.h +++ b/gcc/config/microblaze/microblaze-protos.h @@ -57,6 +57,7 @@ extern bool microblaze_tls_referenced_p (rtx); extern int symbol_mentioned_p (rtx); extern int label_mentioned_p (rtx); extern bool microblaze_cannot_force_const_mem (machine_mode, rtx); +extern void microblaze_eh_return (rtx op0); #endif /* RTX_CODE */ /* Declare functions in microblaze-c.c. */ diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c index 03b70e1..746bef1 100644 --- a/gcc/config/microblaze/microblaze.c +++ b/gcc/config/microblaze/microblaze.c @@ -1926,6 +1926,10 @@ microblaze_must_save_register (int regno) if (frame_pointer_needed && (regno == HARD_FRAME_POINTER_REGNUM)) return 1; + if (crtl->calls_eh_return + && regno == MB_ABI_SUB_RETURN_ADDR_REGNUM) + return 1; + if (!crtl->is_leaf) { if (regno == MB_ABI_SUB_RETURN_ADDR_REGNUM) @@ -1953,6 +1957,11 @@ microblaze_must_save_register (int regno) return 1; } + if (crtl->calls_eh_return + && (regno == EH_RETURN_DATA_REGNO (0) + || regno == EH_RETURN_DATA_REGNO (1))) + return 1; + return 0; } @@ -3029,6 +3038,12 @@ microblaze_expand_epilogue (void) emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, fsiz_rtx)); } + if (crtl->calls_eh_return) + emit_insn (gen_addsi3 (stack_pointer_rtx, + stack_pointer_rtx, + gen_raw_REG (SImode, + MB_EH_STACKADJ_REGNUM))); + emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM))); } @@ -3326,10 +3341,14 @@ microblaze_return_addr (int count, rtx frame ATTRIBUTE_UNUSED) if (count != 0) return NULL_RTX; - return gen_rtx_PLUS (Pmode, - get_hard_reg_initial_val (Pmode, - MB_ABI_SUB_RETURN_ADDR_REGNUM), - GEN_INT (8)); + return get_hard_reg_initial_val (Pmode, + MB_ABI_SUB_RETURN_ADDR_REGNUM); +} + +void +microblaze_eh_return (rtx op0) +{ + emit_insn (gen_movsi (gen_rtx_MEM (Pmode, stack_pointer_rtx), op0)); } /* Queue an .ident string in the queue of top-level asm statements. diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h index 527f4d3..8fdadbf 100644 --- a/gcc/config/microblaze/microblaze.h +++ b/gcc/config/microblaze/microblaze.h @@ -184,6 +184,22 @@ extern enum pipeline_type microblaze_pipe; #define INCOMING_RETURN_ADDR_RTX \ gen_rtx_REG (Pmode, GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM) +/* Specifies the offset from INCOMING_RETURN_ADDR_RTX and the actual return PC. */ +#define RETURN_ADDR_OFFSET (8) + +/* Describe how we implement __builtin_eh_return. */ +#define EH_RETURN_DATA_REGNO(N) \ + (((N) < 2) ? MB_ABI_FIRST_ARG_REGNUM + (N) : INVALID_REGNUM) + +#define MB_EH_STACKADJ_REGNUM MB_ABI_INT_RETURN_VAL2_REGNUM +#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, MB_EH_STACKADJ_REGNUM) + +/* Select a format to encode pointers in exception handling data. CODE + is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is + true if the symbol may be affected by dynamic relocations. */ +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \ + ((flag_pic || GLOBAL) ? DW_EH_PE_aligned : DW_EH_PE_absptr) + /* Use DWARF 2 debugging information by default. */ #define DWARF2_DEBUGGING_INFO #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md index 8f83daa..66ebc1e 100644 --- a/gcc/config/microblaze/microblaze.md +++ b/gcc/config/microblaze/microblaze.md @@ -2324,4 +2324,14 @@ (set_attr "mode" "SI") (set_attr "length" "4")]) +; This is used in compiling the unwind routines. +(define_expand "eh_return" + [(use (match_operand 0 "general_operand" ""))] + "" + " +{ + microblaze_eh_return (operands[0]); + DONE; +}") + (include "sync.md") |