summaryrefslogtreecommitdiff
path: root/patches/gcc/3.4.6/710-all_sh-pr16665-fix.patch
blob: 7297fca5189b3609d19cc5c0a564970de8e8e7ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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;