aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/common/config/microblaze/microblaze-common.c3
-rw-r--r--gcc/config/microblaze/microblaze-protos.h1
-rw-r--r--gcc/config/microblaze/microblaze.c27
-rw-r--r--gcc/config/microblaze/microblaze.h16
-rw-r--r--gcc/config/microblaze/microblaze.md10
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")