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]

Re: [PATCH,i386][4.3][RFC] PIC Generation on windows/cygwin


On 1/27/07, Andrew Pinski <pinskia@physics.uc.edu> wrote:
>
> *** gcc/config/i386/i386.c    (revision 121238)
> --- gcc/config/i386/i386.c    (working copy)
> *************** static void x86_64_elf_unique_section (t
> *** 1404,1409 ****
> --- 1404,1421 ----
>   static section *x86_64_elf_select_section (tree decl, int reloc,
>                                          unsigned HOST_WIDE_INT align)
>                                            ATTRIBUTE_UNUSED;
> + #if TARGET_CYGMING
> + /* Support for position independent code on target cygming.
> +    In position independent mode, references to static and global
> +    symbols are generated as offsets relative to a base label. The same
> +    base label is used for computing relative offsets of labels
> +    in the address diff vector for a switch statement. There is
> +    one base label in each function. */
> +
> + /* The base label used for all relative offsets in pic mode. */
> + static rtx base_label;
> + #endif

This is not really GC safe.
Thanks for pointing this out. (Also changed base_label to pic_base_label).

> + #if ! TARGET_CYGMING > xops[1] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME); > + #endif

Use:
if (!TARGET_CYGMING)

instead.
Done.

> + #if ! TARGET_CYGMING > if (!flag_pic || TARGET_DEEP_BRANCH_PREDICTION) > output_asm_insn ("add{l}\t{%1, %0|%0, %1}", xops); > else > output_asm_insn ("add{l}\t{%1+[.-%a2], %0|%0, %1+(.-%a2)}", xops); > + #else > + base_label = xops[2]; > + #endif

Likewise.
Done.

> + #if TARGET_CYGMING > + addr = i386_pe_generate_imported_symbol_ref(addr); > + new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF); > + #else > new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT); > + #endif

This one needs to stay #if because it uses a function from a non x86 generic
file.

> + #if ! TARGET_CYGMING
>         fputs ("@GOTOFF", file);
> + #else
> +       /* On target CYGMING, we interpret GOTOFF of a symbol
> +          as the offset of the symbol from the PIC base label. */
> +       putc ('-', file);
> +       output_pic_addr_const (file, base_label, code);
> + #endif

Again if(!TARGET_CYGMING)
Done.

> + #if TARGET_CYGMING > + else if (TARGET_CYGMING) > + { > + fprintf (file, "%s%s%d-%s%d\n", > + ASM_LONG, LPREFIX, value, LPREFIX, > + CODE_LABEL_NUMBER(XEXP(base_label,0))); > + } > + #endif

Don't need "#if TARGET_CYGMING" really.
It is needed because base_label is conditionally declared only CYGMING.
Without the #if, it will not compile on linux.

> ! #if TARGET_CYGMING > ! { > ! /* On target CYGMING, there is no PLT. Convert > ! the function address to a PIC reference. */ > ! rtx reg; > ! reg = legitimize_pic_address (XEXP (fnaddr, 0), 0); > ! XEXP (fnaddr, 0) = reg; > ! } > ! #endif

Again if (TARGET_CYGMING)
Done.

Thanks, Andrew Pinski


I have attached the new patch. I have started bootstrap/test again with these changes and will report back once it is complete. Thanks Murali

=================================================================
Index: gcc/config/i386/i386.h
===================================================================
*** gcc/config/i386/i386.h	(revision 121377)
--- gcc/config/i386/i386.h	(working copy)
*************** extern int x86_prefetch_sse, x86_cmpxchg
*** 294,299 ****
--- 294,302 ----
    redefines this to 1.  */
 #define TARGET_MACHO 0

+ /* Default value for TARGET_CYGMING. cygming.h redefines this to 1. */
+ #define TARGET_CYGMING 0
+
 /* Subtargets may reset this to 1 in order to enable 96-bit long double
    with the rounding mode forced to 53 bits.  */
 #define TARGET_96_ROUND_53_LONG_DOUBLE 0
Index: gcc/config/i386/cygming.h
===================================================================
*** gcc/config/i386/cygming.h	(revision 121377)
--- gcc/config/i386/cygming.h	(working copy)
*************** Boston, MA 02110-1301, USA.  */
*** 49,54 ****
--- 49,58 ----

#define TARGET_EXECUTABLE_SUFFIX ".exe"

+ /* support for position independent code on cygming */
+ #undef TARGET_CYGMING
+ #define TARGET_CYGMING 1
+
 #include <stdio.h>

 #define MAYBE_UWIN_CPP_BUILTINS() /* Nothing.  */
*************** union tree_node;
*** 117,136 ****
    Explicitly set data flag with 'd'.  */
 #define READONLY_DATA_SECTION_ASM_OP "\t.section .rdata,\"dr\""

- /* Don't allow flag_pic to propagate since gas may produce invalid code
-    otherwise.  */
-
- #undef  SUBTARGET_OVERRIDE_OPTIONS
- #define SUBTARGET_OVERRIDE_OPTIONS					\
- do {									\
-   if (flag_pic)								\
-     {									\
-       warning (0, "-f%s ignored for target (all code is position
independent)",\
- 	       (flag_pic > 1) ? "PIC" : "pic");				\
-       flag_pic = 0;							\
-     }									\
- } while (0)								\
-
 /* Define this macro if references to a symbol must be treated
    differently depending on something about the variable or
    function named by the symbol (such as what section it is in).
--- 121,126 ----
*************** extern void i386_pe_record_exported_symb
*** 297,302 ****
--- 287,293 ----
 extern void i386_pe_file_end (void);
 extern int i386_pe_dllexport_name_p (const char *);
 extern int i386_pe_dllimport_name_p (const char *);
+ extern rtx i386_pe_generate_imported_symbol_ref (rtx addr);

 /* For Win32 ABI compatibility */
 #undef DEFAULT_PCC_STRUCT_RETURN
Index: gcc/config/i386/predicates.md
===================================================================
*** gcc/config/i386/predicates.md	(revision 121377)
--- gcc/config/i386/predicates.md	(working copy)
*************** (define_predicate "local_symbolic_operan
*** 456,461 ****
--- 456,473 ----
   return 0;
 })

+ ;; Return true if OP is a imported symbolic operand
+ ;; (using the dllimport storage-class attribute).
+ (define_predicate "imported_symbolic_operand"
+   (match_code "symbol_ref")
+ {
+ #if TARGET_CYGMING
+   if (i386_pe_dllimport_name_p(XSTR (op, 0)))
+     return 1;
+ #endif
+   return 0;
+ })
+
 ;; Test for various thread-local symbols.
 (define_predicate "tls_symbolic_operand"
   (and (match_code "symbol_ref")
Index: gcc/config/i386/winnt.c
===================================================================
*** gcc/config/i386/winnt.c	(revision 121377)
--- gcc/config/i386/winnt.c	(working copy)
*************** i386_pe_file_end (void)
*** 733,736 ****
--- 733,761 ----
     }
 }

+ /* Given an RTX of type symbol_ref, generate and return an RTX
+    of type symbol_ref whose name is prefixed with DLL_IMPORT_PREFIX.
+ */
+
+ rtx i386_pe_generate_imported_symbol_ref (rtx addr)
+ {
+   const char *oldname;
+   char  *newname;
+   tree idp;
+   rtx symref;
+
+   gcc_assert (GET_CODE (addr) == SYMBOL_REF);
+   oldname = XSTR (addr, 0);
+   gcc_assert(! i386_pe_dllimport_name_p (oldname));
+   /* strip dllexport prefix, if any. */
+   oldname = i386_pe_strip_name_encoding(oldname);
+   newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
+   sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
+
+   idp = get_identifier (newname);
+
+   symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
+   return symref;
+ }
+
 #include "gt-winnt.h"
Index: gcc/config/i386/i386.c
===================================================================
*** gcc/config/i386/i386.c	(revision 121377)
--- gcc/config/i386/i386.c	(working copy)
*************** static void x86_64_elf_unique_section (t
*** 1404,1409 ****
--- 1404,1421 ----
 static section *x86_64_elf_select_section (tree decl, int reloc,
 					   unsigned HOST_WIDE_INT align)
 					     ATTRIBUTE_UNUSED;
+ #if TARGET_CYGMING
+ /* Support for position independent code on target cygming.
+    In position independent mode, references to static and global
+    symbols are generated as offsets relative to a base label. The same
+    base label is used for computing relative offsets of labels
+    in the address diff vector for a switch statement. There is
+    one base label in each function. */
+
+ /* The base label used for all relative offsets in pic mode. */
+ static GTY(()) rtx pic_base_label;
+ #endif
+
 
 /* Initialize the GCC target structure.  */
 #undef TARGET_ATTRIBUTE_TABLE
*************** output_set_got (rtx dest, rtx label ATTR
*** 5091,5100 ****
   rtx xops[3];

   xops[0] = dest;
   xops[1] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);

!   if (! TARGET_DEEP_BRANCH_PREDICTION || !flag_pic)
     {
       xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());

       if (!flag_pic)
--- 5103,5117 ----
   rtx xops[3];

   xops[0] = dest;
+ #if (!TARGET_CYGMING)
   xops[1] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
+ #endif

!   if (TARGET_CYGMING || ! TARGET_DEEP_BRANCH_PREDICTION || !flag_pic)
     {
+       /* On target CYGMING, references to static and global symbols and
+ 	 entries in address diff vector for a switch statement are
+ 	 generated as displacements from the following base label. */
       xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());

       if (!flag_pic)
*************** output_set_got (rtx dest, rtx label ATTR
*** 5138,5147 ****
--- 5155,5168 ----
   if (TARGET_MACHO)
     return "";

+ #if (!TARGET_CYGMING)
   if (!flag_pic || TARGET_DEEP_BRANCH_PREDICTION)
     output_asm_insn ("add{l}\t{%1, %0|%0, %1}", xops);
   else
     output_asm_insn ("add{l}\t{%1+[.-%a2], %0|%0, %1+(.-%a2)}", xops);
+ #else
+   pic_base_label = xops[2];
+ #endif

   return "";
 }
*************** legitimate_pic_address_disp_p (rtx disp)
*** 6463,6472 ****
       /* Refuse GOTOFF in 64bit mode since it is always 64bit when used.
 	 While ABI specify also 32bit relocation but we don't produce it in
 	 small PIC model at all.  */
       if ((GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
 	   || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
 	  && !TARGET_64BIT)
!         return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
       return false;
     case UNSPEC_GOTTPOFF:
     case UNSPEC_GOTNTPOFF:
--- 6484,6498 ----
       /* Refuse GOTOFF in 64bit mode since it is always 64bit when used.
 	 While ABI specify also 32bit relocation but we don't produce it in
 	 small PIC model at all.  */
+       /* On target CYGMING, a reference to the slot in Import Address
+ 	 Table corresponding to a dllimport'ed symbol is
+ 	 generated as a displacement from the PIC base label (@GOTOFF)
+ 	 just like a local symbolic operand. */
       if ((GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
 	   || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
 	  && !TARGET_64BIT)
!         return (local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode)
! 		|| imported_symbolic_operand (XVECEXP (disp, 0, 0), Pmode));
       return false;
     case UNSPEC_GOTTPOFF:
     case UNSPEC_GOTNTPOFF:
*************** legitimize_pic_address (rtx orig, rtx re
*** 6819,6829 ****
 	}
       else new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg);
     }
!   else if (!TARGET_64BIT && local_symbolic_operand (addr, Pmode))
     {
       /* This symbol may be referenced via a displacement from the PIC
 	 base address (@GOTOFF).  */
!
       if (reload_in_progress)
 	regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
       if (GET_CODE (addr) == CONST)
--- 6845,6862 ----
 	}
       else new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg);
     }
!   else if (!TARGET_64BIT && (local_symbolic_operand (addr, Pmode)
! 			     || imported_symbolic_operand (addr, Pmode)))
     {
       /* This symbol may be referenced via a displacement from the PIC
 	 base address (@GOTOFF).  */
!       /* On target CYGMING, dllimport'ed symbols are referenced via a load
! 	 from the Import Address Table (IAT). For each dllimport'ed symbol
! 	 <sym>, there is a slot in IAT which is referenced by the symbol
! 	 __imp_<sym>. The symbol __imp_<sym> will be at a
! 	 known (at link time) fixed displacement from the PIC base label.
! 	 Hence, the symbol __imp_<sym> may be referenced via a
! 	 displacement from the PIC base label (@GOTOFF). */
       if (reload_in_progress)
 	regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
       if (GET_CODE (addr) == CONST)
*************** legitimize_pic_address (rtx orig, rtx re
*** 6865,6874 ****
 	{
 	  /* This symbol must be referenced via a load from the
 	     Global Offset Table (@GOT).  */
!
 	  if (reload_in_progress)
 	    regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
 	  new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
 	  new = gen_rtx_CONST (Pmode, new);
 	  new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
 	  new = gen_const_mem (Pmode, new);
--- 6898,6925 ----
 	{
 	  /* This symbol must be referenced via a load from the
 	     Global Offset Table (@GOT).  */
! 	  /* On CYGMING, we do not know at compile time whether
! 	     a global symbol which is not explicitly imported
! 	     (through __declspec(dllimport) will be resolved
! 	     within the same DLL or will be imported from another
! 	     DLL. This will be known only at link time. We
! 	     assume that such a symbol <sym> is dllimport'ed and
! 	     reference it via a load from IAT. That means, a symbol
! 	     <sym> is referenced as *__imp_<sym> where __imp_<sym>
! 	     itself is accessed via a displacement from the PIC
! 	     base label (@GOTOFF). At link time, if it turns out
! 	     that the symbol is defined within the same DLL,
! 	     the linker will provide a symbol definition for
! 	     __imp_<sym> in the .data segment and load it with
! 	     the symbol address for <sym>. */
 	  if (reload_in_progress)
 	    regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+ #if TARGET_CYGMING
+ 	  addr = i386_pe_generate_imported_symbol_ref(addr);
+ 	  new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
+ #else
 	  new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
+ #endif
 	  new = gen_rtx_CONST (Pmode, new);
 	  new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
 	  new = gen_const_mem (Pmode, new);
*************** legitimize_pic_address (rtx orig, rtx re
*** 6912,6918 ****

 	  /* Check first to see if this is a constant offset from a @GOTOFF
 	     symbol reference.  */
! 	  if (local_symbolic_operand (op0, Pmode)
 	      && CONST_INT_P (op1))
 	    {
 	      if (!TARGET_64BIT)
--- 6963,6972 ----

 	  /* Check first to see if this is a constant offset from a @GOTOFF
 	     symbol reference.  */
! 	  /* On target CYGMING, a reference to a IAT slot can be generated
! 	     as a fixed displacement from the PIC base label (@GOTOFF).*/
! 	  if ((local_symbolic_operand (op0, Pmode) ||
! 	      imported_symbolic_operand (op0, Pmode))
 	      && CONST_INT_P (op1))
 	    {
 	      if (!TARGET_64BIT)
*************** output_pic_addr_const (FILE *file, rtx x
*** 7355,7361 ****

     case SYMBOL_REF:
       output_addr_const (file, x);
!       if (!TARGET_MACHO && code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
 	fputs ("@PLT", file);
       break;

--- 7409,7420 ----

     case SYMBOL_REF:
       output_addr_const (file, x);
!       /* On target CYGMING, there is no PLT.
! 	 In ix86_expand_call(), we call legitimize_pic_address()
! 	 to convert the address of a direct, non-local function
! 	 to a PIC reference. */
!       if (!TARGET_MACHO && code == 'P' &&
! 	  ! (TARGET_CYGMING || SYMBOL_REF_LOCAL_P (x)))
 	fputs ("@PLT", file);
       break;

*************** output_pic_addr_const (FILE *file, rtx x
*** 7430,7436 ****
--- 7489,7502 ----
 	  fputs ("@GOT", file);
 	  break;
 	case UNSPEC_GOTOFF:
+ #if (!TARGET_CYGMING)
 	  fputs ("@GOTOFF", file);
+ #else
+ 	  /* On target CYGMING, we interpret GOTOFF of a symbol
+ 	     as the offset of the symbol from the PIC base label. */
+ 	  putc ('-', file);
+ 	  output_pic_addr_const (file, pic_base_label, code);
+ #endif
 	  break;
 	case UNSPEC_GOTPCREL:
 	  fputs ("@GOTPCREL(%rip)", file);
*************** ix86_output_addr_diff_elt (FILE *file, i
*** 9049,9054 ****
--- 9115,9130 ----
   if (TARGET_64BIT)
     fprintf (file, "%s%s%d-%s%d\n",
 	     ASM_LONG, LPREFIX, value, LPREFIX, rel);
+   /* On cygming, GOTOFF of a label is the offset of the label
+      from the PIC base label. */
+ #if TARGET_CYGMING
+   else if (TARGET_CYGMING)
+     {
+       fprintf (file, "%s%s%d-%s%d\n",
+ 	       ASM_LONG, LPREFIX, value, LPREFIX,
+ 	       CODE_LABEL_NUMBER(XEXP(pic_base_label,0)));
+     }
+ #endif
   else if (HAVE_AS_GOTOFF_IN_DATA)
     fprintf (file, "%s%s%d@GOTOFF\n", ASM_LONG, LPREFIX, value);
 #if TARGET_MACHO
*************** ix86_expand_call (rtx retval, rtx fnaddr
*** 14391,14397 ****
       if (! TARGET_64BIT && flag_pic
 	  && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
 	  && ! SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))
! 	use_reg (&use, pic_offset_table_rtx);
     }

   if (TARGET_64BIT && INTVAL (callarg2) >= 0)
--- 14467,14484 ----
       if (! TARGET_64BIT && flag_pic
 	  && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
 	  && ! SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))
! 	{
! 	  use_reg (&use, pic_offset_table_rtx);
! #if (TARGET_CYGMING)
! 	  {
! 	    /* On target CYGMING, there is no PLT. Convert
! 	       the function address to a PIC reference. */
! 	    rtx reg;
! 	    reg = legitimize_pic_address (XEXP (fnaddr, 0), 0);
! 	    XEXP (fnaddr, 0) = reg;
! 	  }
! #endif
! 	}
     }

if (TARGET_64BIT && INTVAL (callarg2) >= 0)


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