| diff -durN gcc-3.4.6.orig/gcc/config/sh/sh.c gcc-3.4.6/gcc/config/sh/sh.c |
| --- gcc-3.4.6.orig/gcc/config/sh/sh.c 2004-09-03 08:51:30.000000000 +0200 |
| +++ gcc-3.4.6/gcc/config/sh/sh.c 2007-08-15 23:01:48.000000000 +0200 |
| @@ -9107,6 +9107,15 @@ |
| } |
| 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 |
| @@ -9189,8 +9198,24 @@ |
| 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; |