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]

rs6000.c 64-bit hosting


	This latter half of this patch probably is not necesasry for
gcc-3.0, but I think that there is a mistake in rs6000_emit_move().  The
current test for determining if a TOC entry should be created includes:

        else if (mode == Pmode
             && CONSTANT_P (operands[1])
             && (((HOST_BITS_PER_WIDE_INT != 32 
                   || GET_CODE (operands[1]) != CONST_INT)
                  && ! easy_fp_constant (operands[1], mode))
                 || (GET_CODE (operands[0]) == REG
                     && FP_REGNO_P (REGNO (operands[0]))))
               && GET_CODE (operands[1]) != HIGH
               && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
               && ! TOC_RELATIVE_EXPR_P (operands[1]))

Take the case of a 64-bit host, targeting 64-bits and mode == DImode
(which == Pmode and the common case) and the input operand is a constant,

	HOST_BITS_PER_WIDE_INT != 32
	A 64-bit constant is a CONST_INT
	easy_fp_constant() *ALWAYS* returns false for CONST_INT

If I understand this logic correctly, every constant will go into the TOC
when the host is 64-bits.

	In the case of CONST_INT, the test should call
num_insns_constant() directly as the patch below implements.

David


	* rs6000.c (rs6000_{init,free}machine_status): Declare prototypes.
	(rs6000_emit_move): Only emit TOC constant for hard constants.
	Merge special_constant_p test into the test just after.

Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.158
diff -c -p -r1.158 rs6000.c
*** rs6000.c	2001/01/09 19:38:25	1.158
--- rs6000.c	2001/01/17 20:33:09
*************** static int toc_hash_eq PARAMS ((const vo
*** 120,125 ****
--- 120,127 ----
  static int toc_hash_mark_entry PARAMS ((void **, void *));
  static void toc_hash_mark_table PARAMS ((void *));
  static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
+ static void rs6000_init_machine_status PARAMS ((struct function *p));
+ static void rs6000_free_machine_status PARAMS ((struct function *p));
  
  /* Default register names.  */
  char rs6000_reg_names[][8] =
*************** rs6000_emit_move (dest, source, mode)
*** 1679,1695 ****
  	}
        else if (mode == Pmode
  	       && CONSTANT_P (operands[1])
!  	       && (((HOST_BITS_PER_WIDE_INT != 32 
!  		     || GET_CODE (operands[1]) != CONST_INT)
!  		    && ! easy_fp_constant (operands[1], mode))
!  		   || (GET_CODE (operands[0]) == REG
!  		       && FP_REGNO_P (REGNO (operands[0]))))
  	       && GET_CODE (operands[1]) != HIGH
  	       && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
  	       && ! TOC_RELATIVE_EXPR_P (operands[1]))
  	{
- 	  int special_constant_p = 0;
- 
  	  /* Emit a USE operation so that the constant isn't deleted if
  	     expensive optimizations are turned on because nobody
  	     references it.  This should only be done for operands that
--- 1687,1702 ----
  	}
        else if (mode == Pmode
  	       && CONSTANT_P (operands[1])
! 	       && ((GET_CODE (operands[1]) != CONST_INT
! 		    && ! easy_fp_constant (operands[1], mode))
! 		   || (GET_CODE (operands[1]) == CONST_INT
! 		       && num_insns_constant (operands[1], mode) > 2)
! 		   || (GET_CODE (operands[0]) == REG
! 		       && FP_REGNO_P (REGNO (operands[0]))))
  	       && GET_CODE (operands[1]) != HIGH
  	       && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
  	       && ! TOC_RELATIVE_EXPR_P (operands[1]))
  	{
  	  /* Emit a USE operation so that the constant isn't deleted if
  	     expensive optimizations are turned on because nobody
  	     references it.  This should only be done for operands that
*************** rs6000_emit_move (dest, source, mode)
*** 1725,1742 ****
  	  operands[1] = force_const_mem (mode, operands[1]);
  
  	  if (TARGET_TOC 
! 	      && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0)))
! 	    {
! 	      rtx constant;
! 	      enum machine_mode cmode;
! 
! 	      constant = get_pool_constant (XEXP (operands[1], 0));
! 	      cmode = get_pool_mode (XEXP (operands[1], 0));
! 	      special_constant_p = 
! 		ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (constant, cmode);
! 	    }
! 
! 	  if (special_constant_p)
  	    {
  	      operands[1] = gen_rtx_MEM (mode,
  					 create_TOC_reference (XEXP (operands[1], 0)));
--- 1732,1741 ----
  	  operands[1] = force_const_mem (mode, operands[1]);
  
  	  if (TARGET_TOC 
! 	      && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
! 	      && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
! 			get_pool_constant (XEXP (operands[1], 0)),
! 			get_pool_mode (XEXP (operands[1], 0))))
  	    {
  	      operands[1] = gen_rtx_MEM (mode,
  					 create_TOC_reference (XEXP (operands[1], 0)));
*************** rs6000_emit_move (dest, source, mode)
*** 1774,1779 ****
--- 1773,1779 ----
  				  XEXP (operands[1], 0));
  
    emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
+   return;
  }
  
  /* Initialize a variable CUM of type CUMULATIVE_ARGS

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