summaryrefslogtreecommitdiff
path: root/patches/gcc/3.4.6/710-all_sh-pr16665-fix.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/gcc/3.4.6/710-all_sh-pr16665-fix.patch')
-rw-r--r--patches/gcc/3.4.6/710-all_sh-pr16665-fix.patch44
1 files changed, 44 insertions, 0 deletions
diff --git a/patches/gcc/3.4.6/710-all_sh-pr16665-fix.patch b/patches/gcc/3.4.6/710-all_sh-pr16665-fix.patch
new file mode 100644
index 0000000..7297fca
--- /dev/null
+++ b/patches/gcc/3.4.6/710-all_sh-pr16665-fix.patch
@@ -0,0 +1,44 @@
+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;