HP-UX IA64 ILP32 patch

Steve Ellcey sje@cup.hp.com
Fri Jun 21 10:05:00 GMT 2002


Here is a resubmition of my HP-UX IA64 ILP32 patch.  I addressed the
issues that Richard brought up (which helped simplify the patch a lot)
and fixes a typo in movdi_symbolic which I had copied into the new
movsi_symbolic insn.

Steve Ellcey
sje@cup.hp.com


2002-06-14  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): Remove 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 19 16:34:09 2002
*************** struct gcc_target targetm = TARGET_INITI
*** 248,258 ****
  int
  call_operand (op, mode)
       rtx op;
!      enum machine_mode mode;
  {
-   if (mode != GET_MODE (op))
-     return 0;
- 
    return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG
  	  || (GET_CODE (op) == SUBREG && GET_CODE (XEXP (op, 0)) == REG));
  }
--- 248,255 ----
  int
  call_operand (op, mode)
       rtx op;
!      enum machine_mode mode ATTRIBUTE_UNUSED;
  {
    return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG
  	  || (GET_CODE (op) == SUBREG && GET_CODE (XEXP (op, 0)) == 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;
  
--- 989,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))
!     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
--- 1003,1011 ----
      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;
--- 1040,1050 ----
      }
  
    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)))
--- 1079,1085 ----
    if (!reload_in_progress && !reload_completed && !ia64_move_ok (op0, op1))
      op1 = force_reg (mode, op1);
  
!   if ((mode == DImode) || (mode == SImode))
      {
        enum tls_model tls_kind;
        if ((tls_kind = tls_symbolic_operand (op1, Pmode)))
*************** ia64_expand_move (op0, op1)
*** 1213,1218 ****
--- 1219,1239 ----
  	    ia64_expand_load_address (op0, op1, NULL_RTX);
  	  return NULL_RTX;
  	}
+       else if (!TARGET_NO_PIC && symbolic_operand (op1, SImode))
+ 	{
+ 	  /* See above comments about DImode symbolic_operand.  */
+ 
+ 	  if (rtx_equal_function_value_matters
+ 	      && GET_CODE (op1) != LABEL_REF
+ 	      && ! (GET_CODE (op1) == SYMBOL_REF
+ 		    && (SYMBOL_REF_FLAG (op1)
+ 			|| CONSTANT_POOL_ADDRESS_P (op1)
+ 			|| STRING_POOL_ADDRESS_P (op1))))
+ 	    emit_insn (gen_movsi_symbolic (op0, op1));
+ 	  else
+ 	    ia64_expand_load_address (op0, op1, NULL_RTX);
+ 	  return NULL_RTX;
+ 	}
      }
  
    return op1;
*************** 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;
--- 2878,2893 ----
       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 ****
--- 7690,7699 ----
    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 ****
--- 7771,7781 ----
    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))
--- 7839,7849 ----
    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);
--- 7888,7897 ----
  
    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);
--- 7922,7930 ----
    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