diff options
Diffstat (limited to 'recipes-devtools/gcc/files/0004-Patch-microblaze-Add-TARGET_ASM_OUTPUT_MI_THUNK-to-s.patch')
| -rw-r--r-- | recipes-devtools/gcc/files/0004-Patch-microblaze-Add-TARGET_ASM_OUTPUT_MI_THUNK-to-s.patch | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/recipes-devtools/gcc/files/0004-Patch-microblaze-Add-TARGET_ASM_OUTPUT_MI_THUNK-to-s.patch b/recipes-devtools/gcc/files/0004-Patch-microblaze-Add-TARGET_ASM_OUTPUT_MI_THUNK-to-s.patch new file mode 100644 index 00000000..5d2665eb --- /dev/null +++ b/recipes-devtools/gcc/files/0004-Patch-microblaze-Add-TARGET_ASM_OUTPUT_MI_THUNK-to-s.patch | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | From: David Holsgrove <david.holsgrove@xilinx.com> | ||
| 2 | Subject: [PATCH 4/8] [Patch, microblaze]: Add TARGET_ASM_OUTPUT_MI_THUNK to | ||
| 3 | support varargs thunk | ||
| 4 | |||
| 5 | Without this macro, generic gcc generates a less efficient thunk | ||
| 6 | that calls function instead of jumping to it. The generic code | ||
| 7 | does not support varargs and produces an error message on compilation; | ||
| 8 | |||
| 9 | error: generic thunk code fails for method | ||
| 10 | 'virtual void C::f(const char*, ...)' which uses '...' | ||
| 11 | |||
| 12 | Changelog | ||
| 13 | |||
| 14 | 2013-03-18 David Holsgrove <david.holsgrove@xilinx.com> | ||
| 15 | |||
| 16 | * gcc/config/microblaze/microblaze.c: Add microblaze_asm_output_mi_thunk | ||
| 17 | and define TARGET_ASM_OUTPUT_MI_THUNK and TARGET_ASM_CAN_OUTPUT_MI_THUNK | ||
| 18 | |||
| 19 | Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com> | ||
| 20 | Upstream-Status: Pending | ||
| 21 | |||
| 22 | diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c | ||
| 23 | index 1562e60..7418e49 100644 | ||
| 24 | --- a/gcc/config/microblaze/microblaze.c | ||
| 25 | +++ b/gcc/config/microblaze/microblaze.c | ||
| 26 | @@ -3005,6 +3005,74 @@ microblaze_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, | ||
| 27 | } | ||
| 28 | |||
| 29 | static void | ||
| 30 | +microblaze_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, | ||
| 31 | + HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, | ||
| 32 | + tree function) | ||
| 33 | +{ | ||
| 34 | + rtx this_rtx, insn, funexp; | ||
| 35 | + | ||
| 36 | + reload_completed = 1; | ||
| 37 | + epilogue_completed = 1; | ||
| 38 | + | ||
| 39 | + /* Mark the end of the (empty) prologue. */ | ||
| 40 | + emit_note (NOTE_INSN_PROLOGUE_END); | ||
| 41 | + | ||
| 42 | + /* Find the "this" pointer. If the function returns a structure, | ||
| 43 | + the structure return pointer is in MB_ABI_FIRST_ARG_REGNUM. */ | ||
| 44 | + if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)) | ||
| 45 | + this_rtx = gen_rtx_REG (Pmode, (MB_ABI_FIRST_ARG_REGNUM + 1)); | ||
| 46 | + else | ||
| 47 | + this_rtx = gen_rtx_REG (Pmode, MB_ABI_FIRST_ARG_REGNUM); | ||
| 48 | + | ||
| 49 | + /* Apply the constant offset, if required. */ | ||
| 50 | + if (delta) | ||
| 51 | + emit_insn (gen_addsi3 (this_rtx, this_rtx, GEN_INT (delta))); | ||
| 52 | + | ||
| 53 | + /* Apply the offset from the vtable, if required. */ | ||
| 54 | + if (vcall_offset) | ||
| 55 | + { | ||
| 56 | + rtx vcall_offset_rtx = GEN_INT (vcall_offset); | ||
| 57 | + rtx tmp = gen_rtx_REG (Pmode, MB_ABI_TEMP1_REGNUM); | ||
| 58 | + | ||
| 59 | + emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx)); | ||
| 60 | + | ||
| 61 | + rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx); | ||
| 62 | + emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc)); | ||
| 63 | + | ||
| 64 | + emit_insn (gen_addsi3 (this_rtx, this_rtx, tmp)); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + /* Generate a tail call to the target function. */ | ||
| 68 | + if (!TREE_USED (function)) | ||
| 69 | + { | ||
| 70 | + assemble_external (function); | ||
| 71 | + TREE_USED (function) = 1; | ||
| 72 | + } | ||
| 73 | + funexp = XEXP (DECL_RTL (function), 0); | ||
| 74 | + | ||
| 75 | + if (flag_pic) | ||
| 76 | + { | ||
| 77 | + rtx scratch = gen_rtx_REG (Pmode, MB_ABI_TEMP2_REGNUM); | ||
| 78 | + rtx reg = microblaze_legitimize_address(funexp, scratch, FUNCTION_MODE); | ||
| 79 | + emit_move_insn (scratch, reg); | ||
| 80 | + funexp = scratch; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + emit_insn (gen_jump (funexp)); | ||
| 84 | + | ||
| 85 | + /* Run just enough of rest_of_compilation. This sequence was | ||
| 86 | + "borrowed" from rs6000.c. */ | ||
| 87 | + insn = get_insns (); | ||
| 88 | + shorten_branches (insn); | ||
| 89 | + final_start_function (insn, file, 1); | ||
| 90 | + final (insn, file, 1); | ||
| 91 | + final_end_function (); | ||
| 92 | + | ||
| 93 | + reload_completed = 0; | ||
| 94 | + epilogue_completed = 0; | ||
| 95 | +} | ||
| 96 | + | ||
| 97 | +static void | ||
| 98 | microblaze_globalize_label (FILE * stream, const char *name) | ||
| 99 | { | ||
| 100 | fputs ("\t.globl\t", stream); | ||
| 101 | @@ -3532,6 +3600,12 @@ microblaze_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x | ||
| 102 | #undef TARGET_SECONDARY_RELOAD | ||
| 103 | #define TARGET_SECONDARY_RELOAD microblaze_secondary_reload | ||
| 104 | |||
| 105 | +#undef TARGET_ASM_OUTPUT_MI_THUNK | ||
| 106 | +#define TARGET_ASM_OUTPUT_MI_THUNK microblaze_asm_output_mi_thunk | ||
| 107 | + | ||
| 108 | +#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK | ||
| 109 | +#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true | ||
| 110 | + | ||
| 111 | #undef TARGET_SCHED_ADJUST_COST | ||
| 112 | #define TARGET_SCHED_ADJUST_COST microblaze_adjust_cost | ||
| 113 | |||
| 114 | -- | ||
| 115 | 1.7.5.4 | ||
| 116 | |||
