yann@402: diff -durN gcc-3.4.6.orig/gcc/config/sh/sh.c gcc-3.4.6/gcc/config/sh/sh.c yann@402: --- gcc-3.4.6.orig/gcc/config/sh/sh.c 2004-09-03 08:51:30.000000000 +0200 yann@402: +++ gcc-3.4.6/gcc/config/sh/sh.c 2007-08-15 23:01:48.000000000 +0200 yann@402: @@ -9107,6 +9107,15 @@ yann@402: } yann@402: this = FUNCTION_ARG (cum, Pmode, ptr_type_node, 1); yann@402: yann@402: + /* In PIC case, we set PIC register to compute the target address. We yann@402: + can use a scratch register to save and restore the original value yann@402: + except for SHcompact. For SHcompact, use stack. */ yann@402: + if (flag_pic && TARGET_SHCOMPACT) yann@402: + { yann@402: + push (PIC_OFFSET_TABLE_REGNUM); yann@402: + emit_insn (gen_GOTaddr2picreg ()); yann@402: + } yann@402: + yann@402: /* For SHcompact, we only have r0 for a scratch register: r1 is the yann@402: static chain pointer (even if you can't have nested virtual functions yann@402: right now, someone might implement them sometime), and the rest of the yann@402: @@ -9189,8 +9198,24 @@ yann@402: assemble_external (function); yann@402: TREE_USED (function) = 1; yann@402: } yann@402: + /* We can use scratch1 to save and restore the original value of yann@402: + PIC register except for SHcompact. */ yann@402: + if (flag_pic && ! TARGET_SHCOMPACT) yann@402: + { yann@402: + emit_move_insn (scratch1, yann@402: + gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)); yann@402: + emit_insn (gen_GOTaddr2picreg ()); yann@402: + } yann@402: funexp = XEXP (DECL_RTL (function), 0); yann@402: emit_move_insn (scratch2, funexp); yann@402: + if (flag_pic) yann@402: + { yann@402: + if (! TARGET_SHCOMPACT) yann@402: + emit_move_insn (gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM), yann@402: + scratch1); yann@402: + else yann@402: + pop (PIC_OFFSET_TABLE_REGNUM); yann@402: + } yann@402: funexp = gen_rtx_MEM (FUNCTION_MODE, scratch2); yann@402: sibcall = emit_call_insn (gen_sibcall (funexp, const0_rtx, NULL_RTX)); yann@402: SIBLING_CALL_P (sibcall) = 1;