HP-UX IA64 ILP32 patch

Steve Ellcey sje@cup.hp.com
Wed Jun 26 15:34:00 GMT 2002


Here is another reworking of my HP-UX IA64 ILP32 patch, it address the
issues Richard raised in the last patch.  The only thing I couldn't do
is replace some checks for DImode or SImode with a check on ptr_mode
because in ILP32 bit mode you can have ptr_mode (32 bit) symbols and
Pmode (64 bit) symbols.  I did change the check to look for Pmode or
ptr_mode instead of DImode or SImode so that in LP64 mode only 64 bit
symbols are allowed and in 32 bit mode either is allowed.

(Only the ia64.c code changed from the last time, ia64.md and explow.c
are the same as before.)

Steve Ellcey
sje@cup.hp.com


2002-06-26  Steve Ellcey  <sje@cup.hp.com>
	* gcc/explow.c (convert_memory_address): Remove special handling
	when POINTERS_EXTEND_UNSIGNED < 0.
	* gcc/config/ia64.md (movsi_symbolic): New instruction for ILP32
	mode.
	(movedi_symbolic): Fix typo.
	(load_fptr): Remove mode restriction so it works for SI and DI.
	(load_fptr_internal1): Ditto.
	(load_gprel): Ditto.
	(load_symptr_internal1): Ditto.
	(call_pic): Ditto.
	* gcc/config/ia64.c (call_operand): Modify mode check.
	(ia64_expand_load_address): Handle DI and SI addresses and symbols.
	(ia64_expand_move): Ditto.
	(ia64_assemble_integer): Handle SImode function pointers.
	(ia64_expand_fetch_and_op): Handle SImode mem addresses.
	(ia64_expand_op_and_fetch): Ditto.
	(ia64_expand_compare_and_swap): Ditto.
	(ia64_expand_lock_test_and_set): Ditto.
	(ia64_expand_lock_release): Ditto.


*** gcc.orig/gcc/explow.c	Thu Jun 13 13:03:54 2002
--- gcc/gcc/explow.c	Thu Jun 13 13:04:54 2002
*************** convert_memory_address (to_mode, x)
*** 363,398 ****
        return x;
  
      case SUBREG:
!       if (POINTERS_EXTEND_UNSIGNED >= 0
! 	  && (SUBREG_PROMOTED_VAR_P (x) || REG_POINTER (SUBREG_REG (x)))
  	  && GET_MODE (SUBREG_REG (x)) == to_mode)
  	return SUBREG_REG (x);
        break;
  
      case LABEL_REF:
!       if (POINTERS_EXTEND_UNSIGNED >= 0)
! 	{
! 	  temp = gen_rtx_LABEL_REF (to_mode, XEXP (x, 0));
! 	  LABEL_REF_NONLOCAL_P (temp) = LABEL_REF_NONLOCAL_P (x);
! 	  return temp;
! 	}
        break;
  
      case SYMBOL_REF:
!       if (POINTERS_EXTEND_UNSIGNED >= 0)
! 	{
! 	  temp = gen_rtx_SYMBOL_REF (to_mode, XSTR (x, 0));
! 	  SYMBOL_REF_FLAG (temp) = SYMBOL_REF_FLAG (x);
! 	  CONSTANT_POOL_ADDRESS_P (temp) = CONSTANT_POOL_ADDRESS_P (x);
! 	  STRING_POOL_ADDRESS_P (temp) = STRING_POOL_ADDRESS_P (x);
! 	  return temp;
! 	}
        break;
  
      case CONST:
!       if (POINTERS_EXTEND_UNSIGNED >= 0)
! 	return gen_rtx_CONST (to_mode,
! 			      convert_memory_address (to_mode, XEXP (x, 0)));
        break;
  
      case PLUS:
--- 363,390 ----
        return x;
  
      case SUBREG:
!       if ((SUBREG_PROMOTED_VAR_P (x) || REG_POINTER (SUBREG_REG (x)))
  	  && GET_MODE (SUBREG_REG (x)) == to_mode)
  	return SUBREG_REG (x);
        break;
  
      case LABEL_REF:
!       temp = gen_rtx_LABEL_REF (to_mode, XEXP (x, 0));
!       LABEL_REF_NONLOCAL_P (temp) = LABEL_REF_NONLOCAL_P (x);
!       return temp;
        break;
  
      case SYMBOL_REF:
!       temp = gen_rtx_SYMBOL_REF (to_mode, XSTR (x, 0));
!       SYMBOL_REF_FLAG (temp) = SYMBOL_REF_FLAG (x);
!       CONSTANT_POOL_ADDRESS_P (temp) = CONSTANT_POOL_ADDRESS_P (x);
!       STRING_POOL_ADDRESS_P (temp) = STRING_POOL_ADDRESS_P (x);
!       return temp;
        break;
  
      case CONST:
!       return gen_rtx_CONST (to_mode,
! 			    convert_memory_address (to_mode, XEXP (x, 0)));
        break;
  
      case PLUS:
*************** convert_memory_address (to_mode, x)
*** 401,408 ****
  	 permute the conversion and addition operation.  We can always safely
  	 permute them if we are making the address narrower.  In addition,
  	 always permute the operations if this is a constant.  */
!       if (POINTERS_EXTEND_UNSIGNED >= 0
! 	  && (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
  	      || (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT
  		  && (INTVAL (XEXP (x, 1)) + 20000 < 40000
  		      || CONSTANT_P (XEXP (x, 0))))))
--- 393,399 ----
  	 permute the conversion and addition operation.  We can always safely
  	 permute them if we are making the address narrower.  In addition,
  	 always permute the operations if this is a constant.  */
!       if ((GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
  	      || (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT
  		  && (INTVAL (XEXP (x, 1)) + 20000 < 40000
  		      || CONSTANT_P (XEXP (x, 0))))))
*** gcc.orig/gcc/config/ia64/ia64.md	Thu Jun 13 13:07:36 2002
--- gcc/gcc/config/ia64/ia64.md	Wed Jun 19 16:25:22 2002
***************
*** 340,345 ****
--- 340,368 ----
    operands[1] = op1;
  })
  
+ ;; This is used during early compilation to delay the decision on
+ ;; how to refer to a variable as long as possible.  This is especially
+ ;; important between initial rtl generation and optimization for
+ ;; deferred functions, since we may acquire additional information
+ ;; on the variables used in the meantime.
+ 
+ (define_insn_and_split "movsi_symbolic"
+   [(set (match_operand:SI 0 "register_operand" "=r")
+ 	(match_operand:SI 1 "symbolic_operand" "s"))
+    (clobber (match_scratch:DI 2 "=r"))
+    (use (reg:DI 1))]
+   ""
+   "* abort ();"
+   "!no_new_pseudos || reload_completed"
+   [(const_int 0)]
+ {
+   rtx scratch = operands[2];
+   if (!reload_completed)
+     scratch = gen_reg_rtx (Pmode);
+   ia64_expand_load_address (operands[0], operands[1], scratch); 
+   DONE;
+ })
+ 
  (define_insn "*movsi_internal"
    [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
  	(match_operand:SI 1 "move_operand"        "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
***************
*** 387,393 ****
  {
    rtx scratch = operands[2];
    if (!reload_completed)
!     gen_reg_rtx (Pmode);
    ia64_expand_load_address (operands[0], operands[1], scratch); 
    DONE;
  })
--- 410,416 ----
  {
    rtx scratch = operands[2];
    if (!reload_completed)
!     scratch = gen_reg_rtx (Pmode);
    ia64_expand_load_address (operands[0], operands[1], scratch); 
    DONE;
  })
***************
*** 440,446 ****
  
  (define_expand "load_fptr"
    [(set (match_dup 2)
! 	(plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "")))
     (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
    ""
  {
--- 463,469 ----
  
  (define_expand "load_fptr"
    [(set (match_dup 2)
! 	(plus:DI (reg:DI 1) (match_operand 1 "function_operand" "")))
     (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
    ""
  {
***************
*** 451,464 ****
  
  (define_insn "*load_fptr_internal1"
    [(set (match_operand:DI 0 "register_operand" "=r")
! 	(plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "s")))]
    ""
    "addl %0 = @ltoff(@fptr(%1)), gp"
    [(set_attr "itanium_class" "ialu")])
  
  (define_insn "load_gprel"
    [(set (match_operand:DI 0 "register_operand" "=r")
! 	(plus:DI (reg:DI 1) (match_operand:DI 1 "sdata_symbolic_operand" "s")))]
    ""
    "addl %0 = @gprel(%1), gp"
    [(set_attr "itanium_class" "ialu")])
--- 474,487 ----
  
  (define_insn "*load_fptr_internal1"
    [(set (match_operand:DI 0 "register_operand" "=r")
! 	(plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))]
    ""
    "addl %0 = @ltoff(@fptr(%1)), gp"
    [(set_attr "itanium_class" "ialu")])
  
  (define_insn "load_gprel"
    [(set (match_operand:DI 0 "register_operand" "=r")
! 	(plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))]
    ""
    "addl %0 = @gprel(%1), gp"
    [(set_attr "itanium_class" "ialu")])
***************
*** 494,500 ****
  
  (define_insn "*load_symptr_internal1"
    [(set (match_operand:DI 0 "register_operand" "=r")
! 	(plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "s")))]
    ""
    "addl %0 = @ltoff(%1), gp"
    [(set_attr "itanium_class" "ialu")])
--- 517,523 ----
  
  (define_insn "*load_symptr_internal1"
    [(set (match_operand:DI 0 "register_operand" "=r")
! 	(plus:DI (reg:DI 1) (match_operand 1 "got_symbolic_operand" "s")))]
    ""
    "addl %0 = @ltoff(%1), gp"
    [(set_attr "itanium_class" "ialu")])
***************
*** 4749,4755 ****
    [(set_attr "itanium_class" "br,scall")])
  
  (define_insn "call_pic"
!   [(call (mem:DI (match_operand:DI 0 "call_operand" "b,i"))
  	 (match_operand 1 "" ""))
     (use (unspec [(reg:DI 1)] UNSPEC_PIC_CALL))
     (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
--- 4772,4778 ----
    [(set_attr "itanium_class" "br,scall")])
  
  (define_insn "call_pic"
!   [(call (mem (match_operand 0 "call_operand" "b,i"))
  	 (match_operand 1 "" ""))
     (use (unspec [(reg:DI 1)] UNSPEC_PIC_CALL))
     (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
*** gcc.orig/gcc/config/ia64/ia64.c	Thu Jun 13 13:07:41 2002
--- gcc/gcc/config/ia64/ia64.c	Wed Jun 26 12:47:01 2002
*************** call_operand (op, mode)
*** 250,256 ****
       rtx op;
       enum machine_mode mode;
  {
!   if (mode != GET_MODE (op))
      return 0;
  
    return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG
--- 250,256 ----
       rtx op;
       enum machine_mode mode;
  {
!   if (mode != GET_MODE (op) && mode != VOIDmode)
      return 0;
  
    return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG
*************** ia64_expand_load_address (dest, src, scr
*** 992,998 ****
    /* The destination could be a MEM during initial rtl generation,
       which isn't a valid destination for the PIC load address patterns.  */
    if (! register_operand (dest, DImode))
!     temp = gen_reg_rtx (DImode);
    else
      temp = dest;
  
--- 992,1001 ----
    /* The destination could be a MEM during initial rtl generation,
       which isn't a valid destination for the PIC load address patterns.  */
    if (! register_operand (dest, DImode))
!     if (! scratch || ! register_operand (scratch, DImode))
!       temp = gen_reg_rtx (DImode);
!     else
!       temp = scratch;
    else
      temp = dest;
  
*************** ia64_expand_load_address (dest, src, scr
*** 1003,1009 ****
      emit_insn (gen_load_gprel64 (temp, src));
    else if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_FLAG (src))
      emit_insn (gen_load_fptr (temp, src));
!   else if (sdata_symbolic_operand (src, DImode))
      emit_insn (gen_load_gprel (temp, src));
    else if (GET_CODE (src) == CONST
  	   && GET_CODE (XEXP (src, 0)) == PLUS
--- 1006,1014 ----
      emit_insn (gen_load_gprel64 (temp, src));
    else if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_FLAG (src))
      emit_insn (gen_load_fptr (temp, src));
!   else if (((GET_MODE (src) == DImode) ||
! 	    (GET_MODE (src) == SImode)) &&
! 	   sdata_symbolic_operand (src, VOIDmode))
      emit_insn (gen_load_gprel (temp, src));
    else if (GET_CODE (src) == CONST
  	   && GET_CODE (XEXP (src, 0)) == PLUS
*************** ia64_expand_load_address (dest, src, scr
*** 1038,1044 ****
      }
  
    if (temp != dest)
!     emit_move_insn (dest, temp);
  }
  
  static GTY(()) rtx gen_tls_tga;
--- 1043,1053 ----
      }
  
    if (temp != dest)
!     {
!       if (GET_MODE (dest) != GET_MODE (temp))
! 	temp = convert_to_mode (GET_MODE (dest), temp, 0);
!       emit_move_insn (dest, temp);
!     }
  }
  
  static GTY(()) rtx gen_tls_tga;
*************** ia64_expand_move (op0, op1)
*** 1073,1079 ****
    if (!reload_in_progress && !reload_completed && !ia64_move_ok (op0, op1))
      op1 = force_reg (mode, op1);
  
!   if (mode == Pmode)
      {
        enum tls_model tls_kind;
        if ((tls_kind = tls_symbolic_operand (op1, Pmode)))
--- 1082,1088 ----
    if (!reload_in_progress && !reload_completed && !ia64_move_ok (op0, op1))
      op1 = force_reg (mode, op1);
  
!   if ((mode == Pmode) || (mode == ptr_mode))
      {
        enum tls_model tls_kind;
        if ((tls_kind = tls_symbolic_operand (op1, Pmode)))
*************** ia64_expand_move (op0, op1)
*** 1184,1190 ****
  	      abort ();
  	    }
  	}
!       else if (!TARGET_NO_PIC && symbolic_operand (op1, DImode))
  	{
  	  /* Before optimization starts, delay committing to any particular
  	     type of PIC address load.  If this function gets deferred, we
--- 1193,1201 ----
  	      abort ();
  	    }
  	}
!       else if (!TARGET_NO_PIC &&
! 	       (symbolic_operand (op1, Pmode) ||
! 		symbolic_operand (op1, ptr_mode)))
  	{
  	  /* Before optimization starts, delay committing to any particular
  	     type of PIC address load.  If this function gets deferred, we
*************** ia64_expand_move (op0, op1)
*** 1208,1214 ****
  		    && (SYMBOL_REF_FLAG (op1)
  			|| CONSTANT_POOL_ADDRESS_P (op1)
  			|| STRING_POOL_ADDRESS_P (op1))))
! 	    emit_insn (gen_movdi_symbolic (op0, op1));
  	  else
  	    ia64_expand_load_address (op0, op1, NULL_RTX);
  	  return NULL_RTX;
--- 1219,1228 ----
  		    && (SYMBOL_REF_FLAG (op1)
  			|| CONSTANT_POOL_ADDRESS_P (op1)
  			|| STRING_POOL_ADDRESS_P (op1))))
! 	    if (GET_MODE (op1) == DImode)
! 	      emit_insn (gen_movdi_symbolic (op0, op1));
! 	    else
! 	      emit_insn (gen_movsi_symbolic (op0, op1));
  	  else
  	    ia64_expand_load_address (op0, op1, NULL_RTX);
  	  return NULL_RTX;
*************** ia64_assemble_integer (x, size, aligned_
*** 2857,2868 ****
       unsigned int size;
       int aligned_p;
  {
!   if (size == UNITS_PER_WORD && aligned_p
        && !(TARGET_NO_PIC || TARGET_AUTO_PIC)
        && GET_CODE (x) == SYMBOL_REF
        && SYMBOL_REF_FLAG (x))
      {
!       fputs ("\tdata8\t@fptr(", asm_out_file);
        output_addr_const (asm_out_file, x);
        fputs (")\n", asm_out_file);
        return true;
--- 2871,2886 ----
       unsigned int size;
       int aligned_p;
  {
!   if (size == (TARGET_ILP32 ? 4 : 8)
!       && aligned_p
        && !(TARGET_NO_PIC || TARGET_AUTO_PIC)
        && GET_CODE (x) == SYMBOL_REF
        && SYMBOL_REF_FLAG (x))
      {
!       if (TARGET_ILP32)
! 	fputs ("\tdata4\t@fptr(", asm_out_file);
!       else
! 	fputs ("\tdata8\t@fptr(", asm_out_file);
        output_addr_const (asm_out_file, x);
        fputs (")\n", asm_out_file);
        return true;
*************** ia64_expand_fetch_and_op (binoptab, mode
*** 7665,7670 ****
--- 7683,7692 ----
    arg0 = TREE_VALUE (arglist);
    arg1 = TREE_VALUE (TREE_CHAIN (arglist));
    mem = expand_expr (arg0, NULL_RTX, Pmode, 0);
+ #ifdef POINTERS_EXTEND_UNSIGNED
+   if (GET_MODE(mem) != Pmode)
+     mem = convert_memory_address (Pmode, mem);
+ #endif
    value = expand_expr (arg1, NULL_RTX, mode, 0);
  
    mem = gen_rtx_MEM (mode, force_reg (Pmode, mem));
*************** ia64_expand_op_and_fetch (binoptab, mode
*** 7742,7747 ****
--- 7764,7774 ----
    arg0 = TREE_VALUE (arglist);
    arg1 = TREE_VALUE (TREE_CHAIN (arglist));
    mem = expand_expr (arg0, NULL_RTX, Pmode, 0);
+ #ifdef POINTERS_EXTEND_UNSIGNED
+   if (GET_MODE(mem) != Pmode)
+     mem = convert_memory_address (Pmode, mem);
+ #endif
+ 
    value = expand_expr (arg1, NULL_RTX, mode, 0);
  
    mem = gen_rtx_MEM (mode, force_reg (Pmode, mem));
*************** ia64_expand_compare_and_swap (mode, bool
*** 7805,7815 ****
    arg0 = TREE_VALUE (arglist);
    arg1 = TREE_VALUE (TREE_CHAIN (arglist));
    arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
!   mem = expand_expr (arg0, NULL_RTX, Pmode, 0);
    old = expand_expr (arg1, NULL_RTX, mode, 0);
    new = expand_expr (arg2, NULL_RTX, mode, 0);
  
!   mem = gen_rtx_MEM (mode, force_reg (Pmode, mem));
    MEM_VOLATILE_P (mem) = 1;
  
    if (! register_operand (old, mode))
--- 7832,7842 ----
    arg0 = TREE_VALUE (arglist);
    arg1 = TREE_VALUE (TREE_CHAIN (arglist));
    arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
!   mem = expand_expr (arg0, NULL_RTX, ptr_mode, 0);
    old = expand_expr (arg1, NULL_RTX, mode, 0);
    new = expand_expr (arg2, NULL_RTX, mode, 0);
  
!   mem = gen_rtx_MEM (mode, force_reg (ptr_mode, mem));
    MEM_VOLATILE_P (mem) = 1;
  
    if (! register_operand (old, mode))
*************** ia64_expand_lock_test_and_set (mode, arg
*** 7854,7863 ****
  
    arg0 = TREE_VALUE (arglist);
    arg1 = TREE_VALUE (TREE_CHAIN (arglist));
!   mem = expand_expr (arg0, NULL_RTX, Pmode, 0);
    new = expand_expr (arg1, NULL_RTX, mode, 0);
  
!   mem = gen_rtx_MEM (mode, force_reg (Pmode, mem));
    MEM_VOLATILE_P (mem) = 1;
    if (! register_operand (new, mode))
      new = copy_to_mode_reg (mode, new);
--- 7881,7890 ----
  
    arg0 = TREE_VALUE (arglist);
    arg1 = TREE_VALUE (TREE_CHAIN (arglist));
!   mem = expand_expr (arg0, NULL_RTX, ptr_mode, 0);
    new = expand_expr (arg1, NULL_RTX, mode, 0);
  
!   mem = gen_rtx_MEM (mode, force_reg (ptr_mode, mem));
    MEM_VOLATILE_P (mem) = 1;
    if (! register_operand (new, mode))
      new = copy_to_mode_reg (mode, new);
*************** ia64_expand_lock_release (mode, arglist,
*** 7888,7896 ****
    rtx mem;
  
    arg0 = TREE_VALUE (arglist);
!   mem = expand_expr (arg0, NULL_RTX, Pmode, 0);
  
!   mem = gen_rtx_MEM (mode, force_reg (Pmode, mem));
    MEM_VOLATILE_P (mem) = 1;
  
    emit_move_insn (mem, const0_rtx);
--- 7915,7923 ----
    rtx mem;
  
    arg0 = TREE_VALUE (arglist);
!   mem = expand_expr (arg0, NULL_RTX, ptr_mode, 0);
  
!   mem = gen_rtx_MEM (mode, force_reg (ptr_mode, mem));
    MEM_VOLATILE_P (mem) = 1;
  
    emit_move_insn (mem, const0_rtx);



More information about the Gcc-patches mailing list