microblaze.c: Add microblaze_asm_output_mi_thunk and define TARGET_ASM_OUTPUT_MI_THUNK and...

2014-02-23  David Holsgrove <david.holsgrove@xilinx.com>

	* /config/microblaze/microblaze.c: Add microblaze_asm_output_mi_thunk
	and define TARGET_ASM_OUTPUT_MI_THUNK and
	TARGET_ASM_CAN_OUTPUT_MI_THUNK.

From-SVN: r208057
This commit is contained in:
David Holsgrove 2014-02-23 18:44:27 +00:00 committed by Michael Eager
parent d5a19af1be
commit c332c7df48
2 changed files with 79 additions and 0 deletions

View file

@ -1,3 +1,9 @@
2014-02-23 David Holsgrove <david.holsgrove@xilinx.com>
* /config/microblaze/microblaze.c: Add microblaze_asm_output_mi_thunk
and define TARGET_ASM_OUTPUT_MI_THUNK and
TARGET_ASM_CAN_OUTPUT_MI_THUNK.
2014-02-23 David Holsgrove <david.holsgrove@xilinx.com>
* config/microblaze/predicates.md: Add cmp_op predicate.

View file

@ -3087,6 +3087,73 @@ expand_pic_symbol_ref (enum machine_mode mode ATTRIBUTE_UNUSED, rtx op)
return result;
}
static void
microblaze_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
tree function)
{
rtx this_rtx, insn, funexp;
reload_completed = 1;
epilogue_completed = 1;
/* Mark the end of the (empty) prologue. */
emit_note (NOTE_INSN_PROLOGUE_END);
/* Find the "this" pointer. If the function returns a structure,
the structure return pointer is in MB_ABI_FIRST_ARG_REGNUM. */
if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
this_rtx = gen_rtx_REG (Pmode, (MB_ABI_FIRST_ARG_REGNUM + 1));
else
this_rtx = gen_rtx_REG (Pmode, MB_ABI_FIRST_ARG_REGNUM);
/* Apply the constant offset, if required. */
if (delta)
emit_insn (gen_addsi3 (this_rtx, this_rtx, GEN_INT (delta)));
/* Apply the offset from the vtable, if required. */
if (vcall_offset)
{
rtx vcall_offset_rtx = GEN_INT (vcall_offset);
rtx temp1 = gen_rtx_REG (Pmode, MB_ABI_TEMP1_REGNUM);
emit_move_insn (temp1, gen_rtx_MEM (Pmode, this_rtx));
rtx loc = gen_rtx_PLUS (Pmode, temp1, vcall_offset_rtx);
emit_move_insn (temp1, gen_rtx_MEM (Pmode, loc));
emit_insn (gen_addsi3 (this_rtx, this_rtx, temp1));
}
/* Generate a tail call to the target function. */
if (!TREE_USED (function))
{
assemble_external (function);
TREE_USED (function) = 1;
}
funexp = XEXP (DECL_RTL (function), 0);
rtx temp2 = gen_rtx_REG (Pmode, MB_ABI_TEMP2_REGNUM);
if (flag_pic)
emit_move_insn (temp2, expand_pic_symbol_ref (Pmode, funexp));
else
emit_move_insn (temp2, funexp);
emit_insn (gen_indirect_jump (temp2));
/* Run just enough of rest_of_compilation. This sequence was
"borrowed" from rs6000.c. */
insn = get_insns ();
shorten_branches (insn);
final_start_function (insn, file, 1);
final (insn, file, 1);
final_end_function ();
reload_completed = 0;
epilogue_completed = 0;
}
bool
microblaze_expand_move (enum machine_mode mode, rtx operands[])
{
@ -3504,6 +3571,12 @@ microblaze_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD microblaze_secondary_reload
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK microblaze_asm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST microblaze_adjust_cost