|
@@ -0,0 +1,43 @@
|
|
|
+--- gcc/gcc/config/sh/sh.c
|
|
|
++++ gcc/gcc/config/sh/sh.c
|
|
|
+@@ -9106,6 +9106,15 @@ sh_output_mi_thunk (FILE *file, tree thu
|
|
|
+ }
|
|
|
+ this = FUNCTION_ARG (cum, Pmode, ptr_type_node, 1);
|
|
|
+
|
|
|
++ /* In PIC case, we set PIC register to compute the target address. We
|
|
|
++ can use a scratch register to save and restore the original value
|
|
|
++ except for SHcompact. For SHcompact, use stack. */
|
|
|
++ if (flag_pic && TARGET_SHCOMPACT)
|
|
|
++ {
|
|
|
++ push (PIC_OFFSET_TABLE_REGNUM);
|
|
|
++ emit_insn (gen_GOTaddr2picreg ());
|
|
|
++ }
|
|
|
++
|
|
|
+ /* For SHcompact, we only have r0 for a scratch register: r1 is the
|
|
|
+ static chain pointer (even if you can't have nested virtual functions
|
|
|
+ right now, someone might implement them sometime), and the rest of the
|
|
|
+@@ -9188,8 +9197,24 @@ sh_output_mi_thunk (FILE *file, tree thu
|
|
|
+ assemble_external (function);
|
|
|
+ TREE_USED (function) = 1;
|
|
|
+ }
|
|
|
++ /* We can use scratch1 to save and restore the original value of
|
|
|
++ PIC register except for SHcompact. */
|
|
|
++ if (flag_pic && ! TARGET_SHCOMPACT)
|
|
|
++ {
|
|
|
++ emit_move_insn (scratch1,
|
|
|
++ gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM));
|
|
|
++ emit_insn (gen_GOTaddr2picreg ());
|
|
|
++ }
|
|
|
+ funexp = XEXP (DECL_RTL (function), 0);
|
|
|
+ emit_move_insn (scratch2, funexp);
|
|
|
++ if (flag_pic)
|
|
|
++ {
|
|
|
++ if (! TARGET_SHCOMPACT)
|
|
|
++ emit_move_insn (gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM),
|
|
|
++ scratch1);
|
|
|
++ else
|
|
|
++ pop (PIC_OFFSET_TABLE_REGNUM);
|
|
|
++ }
|
|
|
+ funexp = gen_rtx_MEM (FUNCTION_MODE, scratch2);
|
|
|
+ sibcall = emit_call_insn (gen_sibcall (funexp, const0_rtx, NULL_RTX));
|
|
|
+ SIBLING_CALL_P (sibcall) = 1;
|