aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Holsgrove <david.holsgrove@xilinx.com>2014-02-23 18:45:12 +0000
committerMichael Eager <eager@eagercon.com>2014-02-23 18:45:12 +0000
commit931a2968902012e47419969259796cafc5552a87 (patch)
treefc89ca7a058b0102a3f9f30067fa16c6fede683f
parenta387e9ae6d8b97554e1a180be7eac879d7d543f4 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-4_8-branch@208058 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/microblaze/microblaze.c73
2 files changed, 79 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 048144caa9c..871c9c5b1f2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
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.
* config/microblaze/microblaze.md: Add branch_compare instruction
which uses cmp_op predicate and emits cmp insn before branch.
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index d0aecae2b11..89793b05fe5 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -3071,6 +3071,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[])
{
@@ -3488,6 +3555,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