This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH/RFA] PR target/16665: SH thunk with -fPIC


Hi,

The attached patch is to fix PR target/16665 which is a problem for
the thunk routine in PIC case.  For PIC, sh_output_mi_thunk outputs
a jmp to .LTHUNK*@GOTOFF which assumes that the PIC register is set
to GOT.  The patch does it and restore & save the original value of
the PIC register.

BTW, the testcase given in PR causes an ICE for sh64-elf with -fPIC:

lib.cxx:3: error: insn does not satisfy its constraints:
(insn 5 4 6 (set (reg:SI 128 tr0)
        (const:SI (unspec [
                    (symbol_ref:SI ("*.LTHUNK0") [flags 0x3] <function_decl 0x402154d8 *.LTHUNK0>)
                ] 8))) 126 {*movsi_media} (nil)
    (nil))
lib.cxx:3: internal compiler error: in extract_constrain_insn_cached, at recog.c:1985

and the if (flag_pic && TARGET_SHMEDIA) part of the patch below is
for this ICE.  It'd be better to send this hunk as a separated one,
though it's required to fix the PR in SHmedia PIC case anyway.

The patch is tested with bootstrap and regtest on the mainline for
native sh4-unknown-linux-gnu.  It's also regtested on the mainline
for x86 cross sh64-elf.

Regards,
	kaz
--
2004-07-31  Kaz Kojima  <kkojima@gcc.gnu.org>

	PR target/16665
	* config/sh/sh.c (sh_output_mi_thunk): Load GOT to the PIC
	register temporary for PIC case.  Use one more intermediate
	scrach register to load an UNSPEC_GOTOFF expression for
	SHmedia PIC case.

diff -up ORIG/gcc/gcc/config/sh/sh.c LOCAL/gcc/gcc/config/sh/sh.c
--- ORIG/gcc/gcc/config/sh/sh.c	2004-07-27 06:56:55.000000000 +0900
+++ LOCAL/gcc/gcc/config/sh/sh.c	2004-07-27 08:40:48.000000000 +0900
@@ -9564,6 +9564,15 @@ sh_output_mi_thunk (FILE *file, tree thu
     }
   this = FUNCTION_ARG (cum, Pmode, ptr_type_node, 1);
 
+  /* In PIC case, we need GOT address to get the target address.  We
+     can use a scratch register to save and restore the original value  
+     of PIC register 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
@@ -9646,8 +9655,35 @@ sh_output_mi_thunk (FILE *file, tree thu
       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 && TARGET_SHMEDIA)
+    {
+      /* When generating PIC, the following first emit_move_insn might
+	 call gen_symGOT_load which expects its first operand is a general
+	 purpose register so to use it as an index register at no_new_pseudos
+	 period.  So take one more scratch GPR.  */
+      rtx scratch = gen_rtx_REG (ptr_mode, 22);
+      emit_move_insn (scratch, funexp);
+      emit_move_insn (scratch2, scratch);
+    }
+  else
+    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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]