Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DWARF2 unwind support #3

Merged
merged 2 commits into from Jan 23, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 31 additions & 0 deletions gcc/ChangeLog.or1k
@@ -1,3 +1,34 @@
2013-01-22 Christian Svensson <blue@cmd.nu>

* common/config/or1k/or1k-common.c:
(TARGET_EXCEPT_UNWIND_INFO) define.
(or1k_except_unwind_info) use DWARF2 unwind info as default
but support SJLJ if forced with --enable-sjlj-exceptions.
* config/or1k/or1k-protos.h:
(or1k_expand_pic_symbol_ref) removed unneeded ATTRIBUTE_UNUSED.
(or1k_eh_return_handler_rtx) defined prototype (body in or1k.c).
(or1k_return_addr_rtx) defined prototype (body in or1k.c).
* config/or1k/or1k.c:
(or1k_save_reg_p) save stack pointer when frame pointer is not saved.
(or1k_save_reg_p) save registers used with eh_return.
(or1k_expand_epilogue) do not restore link register if we are
returning from eh_return.
(or1k_expand_epilogue) apply EH stack adjustment to stack pointer.
(or1k_eh_return_handler_rtx) eh_return should write to the link register.
(or1k_return_addr_rtx) in the case of GOT the link register cannot be read
after the prologue. in this case, use the stored link register from the
stack frame.
(or1k_frame_pointer_required) require FP in eh_return and
when alloca is used.
(TARGET_FRAME_POINTER_REQUIRED) define.
* config/or1k/or1k.h:
(INITIAL_FRAME_POINTER_OFFSET) not used, removed.
(RETURN_ADDR_RTX) define.
(EH_RETURN_REGNUM) define. use reg 23.
(EH_RETURN_DATA_REGNO) define. use reg 25, 27, 29 and 31.
(EH_RETURN_STACKADJ_RTX) define.
(EH_RETURN_HANDLER_RTX) define.

2012-12-29 Christian Svensson <blue@cmd.nu>

* config.gcc: Use GNU userspace link options when compiling for Linux.
Expand Down
20 changes: 18 additions & 2 deletions gcc/common/config/or1k/or1k-common.c
Expand Up @@ -33,8 +33,24 @@ static const struct default_options or1k_option_optimization_table[] =
{ OPT_LEVELS_NONE, 0, NULL, 0 }
};

#undef TARGET_EXCEPT_UNWIND_INFO
#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
/* Implement TARGET_EXCEPT_UNWIND_INFO. */
static enum unwind_info_type
or1k_except_unwind_info (struct gcc_options *opts)
{
/* Honor the --enable-sjlj-exceptions configure switch. */
#ifdef CONFIG_SJLJ_EXCEPTIONS
if (CONFIG_SJLJ_EXCEPTIONS)
return UI_SJLJ;
#endif

if (DWARF2_UNWIND_INFO)
return UI_DWARF2;

return UI_SJLJ;
}

#undef TARGET_EXCEPT_UNWIND_INFO
#define TARGET_EXCEPT_UNWIND_INFO or1k_except_unwind_info

#undef TARGET_OPTION_OPTIMIZATION_TABLE
#define TARGET_OPTION_OPTIMIZATION_TABLE or1k_option_optimization_table
Expand Down
4 changes: 3 additions & 1 deletion gcc/config/or1k/or1k-protos.h
Expand Up @@ -41,7 +41,7 @@ extern const char *or1k_output_bf (rtx * operands);
extern const char *or1k_output_cmov (rtx * operands);
extern void or1k_emit_set_const32 (rtx op0,
rtx op1);
extern bool or1k_expand_pic_symbol_ref (enum machine_mode mode ATTRIBUTE_UNUSED,
extern bool or1k_expand_pic_symbol_ref (enum machine_mode mode,
rtx operands[]);
#endif

Expand All @@ -52,6 +52,8 @@ extern int or1k_data_alignment (tree, int);
extern int or1k_initial_elimination_offset (int, int);
extern bool or1k_save_reg_p_cached (int regno);
extern void or1k_print_jump_restore (rtx jump_address);
extern rtx or1k_eh_return_handler_rtx (void);
extern rtx or1k_return_addr_rtx (int, rtx);

extern int or1k_legitimate_pic_operand_p (rtx x);

Expand Down
61 changes: 60 additions & 1 deletion gcc/config/or1k/or1k.c
Expand Up @@ -125,12 +125,28 @@ or1k_save_reg_p (int regno)
if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
return true;

/* Save the stack pointer for DWARF2 for now.
* AFAIK, DWARF should be able to unwind using only the current stack
* register and the CFA offset, but I never got that to work. */
if (regno == STACK_POINTER_REGNUM && !frame_pointer_needed)
return true;

/* We need to save the incoming return address if it is ever clobbered
within the function. */
if (regno == LINK_REGNUM
&& (df_regs_ever_live_p(regno) || crtl->uses_pic_offset_table))
return true;

if(crtl->calls_eh_return)
{
unsigned int i;
for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; i++)
{
if ((unsigned int)regno == EH_RETURN_DATA_REGNO (i))
return true;
}
}

return false;

} /* or1k_save_reg_p () */
Expand Down Expand Up @@ -931,7 +947,8 @@ or1k_expand_epilogue (void)
emit_insn (gen_frame_dealloc_sp (value_rtx));
}

if (frame_info.save_lr_p)
/* eh_return sets the LR, do not overwrite it */
if (frame_info.save_lr_p && !crtl->calls_eh_return)
{
emit_insn
(gen_rtx_SET (Pmode, gen_rtx_REG (Pmode, LINK_REGNUM),
Expand All @@ -956,6 +973,9 @@ or1k_expand_epilogue (void)
}
}

if (crtl->calls_eh_return)
emit_insn (gen_add2_insn (stack_pointer_rtx, EH_RETURN_STACKADJ_RTX));

if (frame_info.gpr_frame)
emit_insn (gen_add2_insn (stack_pointer_rtx,
GEN_INT (frame_info.gpr_frame)));
Expand Down Expand Up @@ -2086,5 +2106,44 @@ or1k_asm_file_start(void)
}
}

/* Implement EH_RETURN_HANDLER_RTX.
* Make eh_return use the link register. Epilogue LR restore
* is suppressed for eh_return. */
rtx
or1k_eh_return_handler_rtx (void)
{
return INCOMING_RETURN_ADDR_RTX;
}

/* Implement RETURN_ADDR_RTX.
* We do not support moving back to a previous frame. */
rtx
or1k_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
{
if (count != 0)
return const0_rtx;

or1k_compute_frame_size (get_frame_size ());

/* If we clobber the LR register, we should have saved it.
* If we didn't save it - assume it's still in LR */
if (frame_info.save_lr_p)
return gen_rtx_MEM (Pmode, plus_constant (Pmode, arg_pointer_rtx,
frame_info.lr_save_offset));
else
return get_hard_reg_initial_val (Pmode, LINK_REGNUM);
}

/* Implement TARGET_FRAME_POINTER_REQUIRED.
* We want frame pointer in eh_return and when alloca is used */
static bool
or1k_frame_pointer_required (void)
{
return crtl->calls_eh_return || cfun->calls_alloca;
}

#undef TARGET_FRAME_POINTER_REQUIRED
#define TARGET_FRAME_POINTER_REQUIRED or1k_frame_pointer_required

/* Initialize the GCC target structure. */
struct gcc_target targetm = TARGET_INITIALIZER;
33 changes: 8 additions & 25 deletions gcc/config/or1k/or1k.h
Expand Up @@ -350,29 +350,6 @@ Boston, MA 02111-1307, USA. */
/* Link register. */
#define LINK_REGNUM 9

/* This function computes the initial size of the frame (difference between SP
and FP) after the function prologue. */
#define INITIAL_FRAME_POINTER_OFFSET(depth) \
{ \
int regno; \
int offset = 0; \
\
for (regno=0; regno < FIRST_PSEUDO_REGISTER; regno++) \
{ \
if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) \
{ \
offset += 4; \
} \
} \
\
(depth) = ((!current_function_is_leaf \
|| df_regs_ever_live_p (LINK_REGNUM)) ? 4 : 0) \
+ (frame_pointer_needed ? 4 : 0) \
+ offset \
+ OR1K_ALIGN (crtl->outgoing_args_size, 4) \
+ OR1K_ALIGN (get_frame_size(), 4); \
}

/* Register in which static-chain is passed to a function. */

#define STATIC_CHAIN_REGNUM 11
Expand Down Expand Up @@ -708,8 +685,7 @@ enum reg_class
the stack. */
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNUM)

#define RETURN_ADDR_RTX(COUNT, FP) \
((COUNT) ? NULL_RTX : get_hard_reg_initial_val (Pmode, LINK_REGNUM))
#define RETURN_ADDR_RTX or1k_return_addr_rtx

/* Addressing modes, and classification of registers for them. */

Expand Down Expand Up @@ -1206,4 +1182,11 @@ enum reg_class
For the OR1K, there is no need for anything other than word alignment. */
#define TRAMPOLINE_ALIGNMENT 32

/* Describe how we implement __builtin_eh_return. */
#define EH_RETURN_REGNUM 23
/* Use r25, r27, r29 and r31 (clobber regs) for exception data */
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (25 + ((N)<<1)) : INVALID_REGNUM)
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, EH_RETURN_REGNUM)
#define EH_RETURN_HANDLER_RTX or1k_eh_return_handler_rtx ()

#endif /* _OR1K_H_ */