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]

Re: x86_64 merger part 37 take II - PIC code


> Jan
> 
> Your change log is missing the change to i386.h
Oops, I forgot to add it while updating the patch to current compiler.
> 
> Also where has this been bootstrapped and tested?
Bootstrapped regtested i586.

Honza
> 
> Graham

Hi,
here is updated patch for x86_64 PIC support as we would like to finish
merging soon and close our internal tree.

Honza

Wed Sep 19 15:16:33 CEST 2001  Jan Hubicka  <jh@suse.cz>

	* i386.md (indirect_jump): Allow Pmode operand.
	(tablejump): LIkewise; perform expansion to 64bit mode.
	* i386.c (symbolic_operand): Allow 64bit PIC references.
	(pic_symbolic_operand): Likewise.
	(ix86_find_base_term): Strip the 64bit PIC references.
	(legitimate_pic_address_disp_p): Handle 64bit PIC.
	(legitimize_pic_address): Likewise.
	(i386_simplify_dwarf_addr): Strip down the 64bit PIC references.
	* i386.h (CASE_VECTOR_MODE): Set to SImode for 64bit PIC compilation.

Index: gcc/config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.304
diff -c -3 -p -r1.304 i386.c
*** i386.c	2001/09/14 17:19:04	1.304
--- i386.c	2001/09/19 13:07:48
*************** symbolic_operand (op, mode)
*** 1495,1502 ****
        if (GET_CODE (op) == SYMBOL_REF
  	  || GET_CODE (op) == LABEL_REF
  	  || (GET_CODE (op) == UNSPEC
! 	      && XINT (op, 1) >= 6
! 	      && XINT (op, 1) <= 7))
  	return 1;
        if (GET_CODE (op) != PLUS
  	  || GET_CODE (XEXP (op, 1)) != CONST_INT)
--- 1514,1522 ----
        if (GET_CODE (op) == SYMBOL_REF
  	  || GET_CODE (op) == LABEL_REF
  	  || (GET_CODE (op) == UNSPEC
! 	      && (XINT (op, 1) == 6
! 		  || XINT (op, 1) == 7
! 		  || XINT (op, 1) == 15)))
  	return 1;
        if (GET_CODE (op) != PLUS
  	  || GET_CODE (XEXP (op, 1)) != CONST_INT)
*************** pic_symbolic_operand (op, mode)
*** 1529,1537 ****
       register rtx op;
       enum machine_mode mode ATTRIBUTE_UNUSED;
  {
!   if (GET_CODE (op) == CONST)
      {
!       op = XEXP (op, 0);
        if (GET_CODE (op) == UNSPEC)
  	return 1;
        if (GET_CODE (op) != PLUS
--- 1549,1564 ----
       register rtx op;
       enum machine_mode mode ATTRIBUTE_UNUSED;
  {
!   if (GET_CODE (op) != CONST)
!     return 0;
!   op = XEXP (op, 0);
!   if (TARGET_64BIT)
      {
!       if (GET_CODE (XEXP (op, 0)) == UNSPEC)
! 	return 1;
!     }
!   else 
!     {
        if (GET_CODE (op) == UNSPEC)
  	return 1;
        if (GET_CODE (op) != PLUS
*************** ix86_find_base_term (x)
*** 3220,3225 ****
--- 3247,3275 ----
  {
    rtx term;
  
+   if (TARGET_64BIT)
+     {
+       if (GET_CODE (x) != CONST)
+ 	return x;
+       term = XEXP (x, 0);
+       if (GET_CODE (term) == PLUS
+ 	  && (GET_CODE (XEXP (term, 1)) == CONST_INT
+ 	      || GET_CODE (XEXP (term, 1)) == CONST_DOUBLE))
+ 	term = XEXP (term, 0);
+       if (GET_CODE (term) != UNSPEC
+ 	  || XVECLEN (term, 0) != 1
+ 	  || XINT (term, 1) !=  15)
+ 	return x;
+ 
+       term = XVECEXP (term, 0, 0);
+ 
+       if (GET_CODE (term) != SYMBOL_REF
+ 	  && GET_CODE (term) != LABEL_REF)
+ 	return x;
+ 
+       return term;
+     }
+ 
    if (GET_CODE (x) != PLUS
        || XEXP (x, 0) != pic_offset_table_rtx
        || GET_CODE (XEXP (x, 1)) != CONST)
*************** int
*** 3251,3260 ****
--- 3301,3345 ----
  legitimate_pic_address_disp_p (disp)
       register rtx disp;
  {
+   /* In 64bit mode we can allow direct addresses of symbols and labels
+      when they are not dynamic symbols.  */
+   if (TARGET_64BIT)
+     {
+       rtx x = disp;
+       if (GET_CODE (disp) == CONST)
+ 	x = XEXP (disp, 0);
+       /* ??? Handle PIC code models */
+       if (GET_CODE (x) == PLUS
+ 	  && (GET_CODE (XEXP (x, 1)) == CONST_INT
+ 	      && ix86_cmodel == CM_SMALL_PIC
+ 	      && INTVAL (XEXP (x, 1)) < 1024*1024*1024
+ 	      && INTVAL (XEXP (x, 1)) > -1024*1024*1024))
+ 	x = XEXP (x, 0);
+       if (GET_CODE (x) == LABEL_REF
+ 	  || (GET_CODE (x) == SYMBOL_REF
+ 	      && (CONSTANT_POOL_ADDRESS_P (x)
+ 	          || SYMBOL_REF_FLAG (x))))
+ 	return 1;
+     }
    if (GET_CODE (disp) != CONST)
      return 0;
    disp = XEXP (disp, 0);
  
+   if (TARGET_64BIT)
+     {
+       /* We are unsafe to allow PLUS expressions.  This limit allowed distance
+          of GOT tables.  We should not need these anyway.  */
+       if (GET_CODE (disp) != UNSPEC
+ 	  || XVECLEN (disp, 0) != 1
+ 	  || XINT (disp, 1) != 15)
+ 	return 0;
+ 
+       if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
+ 	  && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF)
+ 	return 0;
+       return 1;
+     }
+ 
    if (GET_CODE (disp) == PLUS)
      {
        if (GET_CODE (XEXP (disp, 1)) != CONST_INT)
*************** legitimize_pic_address (orig, reg)
*** 3576,3591 ****
  	  if (local_symbolic_operand (op0, Pmode)
  	      && GET_CODE (op1) == CONST_INT)
  	    {
! 	      current_function_uses_pic_offset_table = 1;
! 	      new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), 7);
! 	      new = gen_rtx_PLUS (Pmode, new, op1);
! 	      new = gen_rtx_CONST (Pmode, new);
! 	      new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
  
! 	      if (reg != 0)
  		{
! 		  emit_move_insn (reg, new);
! 		  new = reg;
  		}
  	    }
  	  else
--- 3661,3683 ----
  	  if (local_symbolic_operand (op0, Pmode)
  	      && GET_CODE (op1) == CONST_INT)
  	    {
! 	      if (!TARGET_64BIT)
! 		{
! 		  current_function_uses_pic_offset_table = 1;
! 		  new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), 7);
! 		  new = gen_rtx_PLUS (Pmode, new, op1);
! 		  new = gen_rtx_CONST (Pmode, new);
! 		  new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
  
! 		  if (reg != 0)
! 		    {
! 		      emit_move_insn (reg, new);
! 		      new = reg;
! 		    }
! 		}
! 	      else
  		{
! 		  /* ??? We need to limit offsets here.  */
  		}
  	    }
  	  else
*************** output_pic_addr_const (file, x, code)
*** 3900,3905 ****
--- 3992,4000 ----
  	case 8:
  	  fputs ("@PLT", file);
  	  break;
+ 	case 15:
+ 	  fputs ("@GOTPCREL(%RIP)", file);
+ 	  break;
  	default:
  	  output_operand_lossage ("invalid UNSPEC as operand");
  	  break;
*************** i386_simplify_dwarf_addr (orig_x)
*** 3936,3941 ****
--- 4031,4045 ----
       rtx orig_x;
  {
    rtx x = orig_x;
+ 
+   if (TARGET_64BIT)
+     {
+       if (GET_CODE (x) != CONST
+ 	  || GET_CODE (XEXP (x, 0)) != UNSPEC
+ 	  || XINT (XEXP (x, 0), 1) != 15)
+ 	return orig_x;
+       return XVECEXP (XEXP (x, 0), 0, 0);
+     }
  
    if (GET_CODE (x) != PLUS
        || GET_CODE (XEXP (x, 0)) != REG
Index: gcc/config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.h,v
retrieving revision 1.202
diff -c -3 -p -r1.202 i386.h
*** i386.h	2001/09/13 14:37:27	1.202
--- i386.h	2001/09/19 13:07:49
*************** while (0)
*** 2244,2250 ****
  
  /* Specify the machine mode that this machine uses
     for the index in the tablejump instruction.  */
! #define CASE_VECTOR_MODE Pmode
  
  /* Define as C expression which evaluates to nonzero if the tablejump
     instruction expects the table to contain offsets from the address of the
--- 2245,2251 ----
  
  /* Specify the machine mode that this machine uses
     for the index in the tablejump instruction.  */
! #define CASE_VECTOR_MODE (!TARGET_64BIT || flag_pic ? SImode : DImode)
  
  /* Define as C expression which evaluates to nonzero if the tablejump
     instruction expects the table to contain offsets from the address of the
Index: gcc/config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.293
diff -c -3 -p -r1.293 i386.md
*** i386.md	2001/08/24 15:28:54	1.293
--- i386.md	2001/09/19 13:07:54
***************
*** 12948,12961 ****
    [(set_attr "type" "ibr")])
  
  (define_insn "indirect_jump"
!   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
    ""
    "jmp\t%A0"
    [(set_attr "type" "ibr")
     (set_attr "length_immediate" "0")])
  
  (define_expand "tablejump"
!   [(parallel [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
  	      (use (label_ref (match_operand 1 "" "")))])]
    ""
  {
--- 12948,12961 ----
    [(set_attr "type" "ibr")])
  
  (define_insn "indirect_jump"
!   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
    ""
    "jmp\t%A0"
    [(set_attr "type" "ibr")
     (set_attr "length_immediate" "0")])
  
  (define_expand "tablejump"
!   [(parallel [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
  	      (use (label_ref (match_operand 1 "" "")))])]
    ""
  {
***************
*** 12963,12972 ****
       the relative address to an absolute address.  */
    if (flag_pic)
      {
!       operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
! 					 operands[0], NULL_RTX, 1,
! 					 OPTAB_DIRECT);
!       current_function_uses_pic_offset_table = 1;
      }
  })
  
--- 12963,12979 ----
       the relative address to an absolute address.  */
    if (flag_pic)
      {
!       if (TARGET_64BIT)
! 	operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
! 					   operands[1], NULL_RTX, 0,
! 					   OPTAB_DIRECT);
!       else
! 	{
! 	  operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
! 					     operands[0], NULL_RTX, 1,
! 					     OPTAB_DIRECT);
! 	  current_function_uses_pic_offset_table = 1;
! 	}
      }
  })
  


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