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