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]

[PATCH] S/390: Fix bootstrap failure


Hello,

the S/390 back end run into trouble with the recent reload changes done by:
http://gcc.gnu.org/ml/gcc-patches/2006-03/msg01311.html

The problem occurred with the change of REG_MODE_OK_FOR_BASE_P (which 
refered to REG_OK_FOR_BASE_P) to regno_ok_for_base_p in find_reloads_address.

In REG_OK_FOR_BASE_P we did a check whether mode is Pmode but in the REGNO_OK.. versions
this check lacked. This caused reload to break a shift count operand like
(reg:SI + CONST_INT) on s390x (where Pmode == DImode) by issuing an input 
reload for the CONST_INT.

However, this patch take the opportunity to get rid of the REG_OK_* macros as
Bernd Schmidt proposed in his patch description and fixes bootstrap on s390 and
s390x. The patch explicitly allows SImode regs as index and base registers in
s390_decompose_address even on 64bit. This prevents reload from trying to fix 
something.

Bootstrapped on s390 and s390x.

I've got an offline approval for this patch from Ulrich.

Applied to mainline.

Bye,

-Andreas-



2006-03-24  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390/s390.c (s390_decompose_address): Allow SImode for
	index and base register.
	(s390_expand_plug_operand, legitimate_address_p, preferred_la_operand_p,
	print_operand_address, print_operand): Replaced REG_OK_FOR_BASE_STRICT_P
	with REGNO_OK_FOR_BASE_P and REG_OK_FOR_INDEX_STRICT_P with
	REGNO_OK_FOR_INDEX_P.
	* config/s390/s390.h (REGNO_OK_FOR_INDEX_P): Replaced check with
	ADDR_REGNO_P.
	(REG_OK_FOR_INDEX_NONSTRICT_P, REG_OK_FOR_BASE_NONSTRICT_P,
	REG_OK_FOR_INDEX_STRICT_P, REG_OK_FOR_BASE_STRICT_P, REG_OK_FOR_INDEX_P,
	REG_OK_FOR_BASE_P): Definitions removed.


Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig	2006-03-23 13:28:37.000000000 +0100
--- gcc/config/s390/s390.c	2006-03-24 15:41:59.000000000 +0100
*************** s390_decompose_address (rtx addr, struct
*** 1617,1623 ****
  	    return false;
  	  }
  
!       if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
  	return false;
  
        if (REGNO (base) == STACK_POINTER_REGNUM
--- 1617,1625 ----
  	    return false;
  	  }
  
!       if (!REG_P (base) 
! 	  || (GET_MODE (base) != SImode 
! 	      && GET_MODE (base) != Pmode))
  	return false;
  
        if (REGNO (base) == STACK_POINTER_REGNUM
*************** s390_decompose_address (rtx addr, struct
*** 1663,1669 ****
  	    return false;
  	  }
  
!       if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
  	return false;
  
        if (REGNO (indx) == STACK_POINTER_REGNUM
--- 1665,1673 ----
  	    return false;
  	  }
  
!       if (!REG_P (indx) 
! 	  || (GET_MODE (indx) != SImode
! 	      && GET_MODE (indx) != Pmode))
  	return false;
  
        if (REGNO (indx) == STACK_POINTER_REGNUM
*************** s390_expand_plus_operand (rtx target, rt
*** 2678,2685 ****
  
    /* If the address is already strictly valid, there's nothing to do.  */
    if (!s390_decompose_address (src, &ad)
!       || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
!       || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
      {
        /* Otherwise, one of the operands cannot be an address register;
           we reload its value into the scratch register.  */
--- 2682,2689 ----
  
    /* If the address is already strictly valid, there's nothing to do.  */
    if (!s390_decompose_address (src, &ad)
!       || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
!       || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
      {
        /* Otherwise, one of the operands cannot be an address register;
           we reload its value into the scratch register.  */
*************** legitimate_address_p (enum machine_mode 
*** 2727,2745 ****
  
    if (strict)
      {
!       if (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
  	return false;
!       if (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx))
  	return false;
      }
    else
      {
!       if (ad.base && !REG_OK_FOR_BASE_NONSTRICT_P (ad.base))
! 	return false;
!       if (ad.indx && !REG_OK_FOR_INDEX_NONSTRICT_P (ad.indx))
  	return false;
      }
- 
    return true;
  }
  
--- 2731,2754 ----
  
    if (strict)
      {
!       if (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
  	return false;
! 
!       if (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx)))
  	return false;
      }
    else
      {
!       if (ad.base 
! 	  && !(REGNO (ad.base) >= FIRST_PSEUDO_REGISTER
! 	       || REGNO_REG_CLASS (REGNO (ad.base)) == ADDR_REGS))
  	return false;
+       
+       if (ad.indx
+ 	  && !(REGNO (ad.indx) >= FIRST_PSEUDO_REGISTER
+ 	       || REGNO_REG_CLASS (REGNO (ad.indx)) == ADDR_REGS))
+ 	  return false;
      }
    return true;
  }
  
*************** preferred_la_operand_p (rtx op1, rtx op2
*** 2770,2778 ****
  
    if (!s390_decompose_address (op1, &addr))
      return false;
!   if (addr.base && !REG_OK_FOR_BASE_STRICT_P (addr.base))
      return false;
!   if (addr.indx && !REG_OK_FOR_INDEX_STRICT_P (addr.indx))
      return false;
  
    if (!TARGET_64BIT && !addr.pointer)
--- 2779,2787 ----
  
    if (!s390_decompose_address (op1, &addr))
      return false;
!   if (addr.base && !REGNO_OK_FOR_BASE_P (REGNO (addr.base)))
      return false;
!   if (addr.indx && !REGNO_OK_FOR_INDEX_P (REGNO (addr.indx)))
      return false;
  
    if (!TARGET_64BIT && !addr.pointer)
*************** print_operand_address (FILE *file, rtx a
*** 4500,4507 ****
    struct s390_address ad;
  
    if (!s390_decompose_address (addr, &ad)
!       || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
!       || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
      output_operand_lossage ("cannot decompose address");
  
    if (ad.disp)
--- 4509,4516 ----
    struct s390_address ad;
  
    if (!s390_decompose_address (addr, &ad)
!       || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base)))
!       || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx))))
      output_operand_lossage ("cannot decompose address");
  
    if (ad.disp)
*************** print_operand (FILE *file, rtx x, int co
*** 4585,4591 ****
          gcc_assert (GET_CODE (x) == MEM);
  	ret = s390_decompose_address (XEXP (x, 0), &ad);
  	gcc_assert (ret);
! 	gcc_assert (!ad.base || REG_OK_FOR_BASE_STRICT_P (ad.base));
  	gcc_assert (!ad.indx);
  
          if (ad.disp)
--- 4594,4600 ----
          gcc_assert (GET_CODE (x) == MEM);
  	ret = s390_decompose_address (XEXP (x, 0), &ad);
  	gcc_assert (ret);
! 	gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
  	gcc_assert (!ad.indx);
  
          if (ad.disp)
*************** print_operand (FILE *file, rtx x, int co
*** 4603,4609 ****
          gcc_assert (GET_CODE (x) == MEM);
  	ret = s390_decompose_address (XEXP (x, 0), &ad);
  	gcc_assert (ret);
! 	gcc_assert (!ad.base || REG_OK_FOR_BASE_STRICT_P (ad.base));
  	gcc_assert (!ad.indx);
  
          if (ad.base)
--- 4612,4618 ----
          gcc_assert (GET_CODE (x) == MEM);
  	ret = s390_decompose_address (XEXP (x, 0), &ad);
  	gcc_assert (ret);
! 	gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
  	gcc_assert (!ad.indx);
  
          if (ad.base)
*************** print_operand (FILE *file, rtx x, int co
*** 4621,4627 ****
          gcc_assert (GET_CODE (x) == MEM);
  	ret = s390_decompose_address (XEXP (x, 0), &ad);
  	gcc_assert (ret);
! 	gcc_assert (!ad.base || REG_OK_FOR_BASE_STRICT_P (ad.base));
  	gcc_assert (!ad.indx);
  
  	if (ad.disp)
--- 4630,4636 ----
          gcc_assert (GET_CODE (x) == MEM);
  	ret = s390_decompose_address (XEXP (x, 0), &ad);
  	gcc_assert (ret);
! 	gcc_assert (!ad.base || REGNO_OK_FOR_BASE_P (REGNO (ad.base)));
  	gcc_assert (!ad.indx);
  
  	if (ad.disp)
Index: gcc/config/s390/s390.h
===================================================================
*** gcc/config/s390/s390.h.orig	2006-03-23 13:28:37.000000000 +0100
--- gcc/config/s390/s390.h	2006-03-24 14:34:43.000000000 +0100
*************** extern const enum reg_class regclass_map
*** 476,483 ****
     or a pseudo register currently allocated to one such.  */
  #define REGNO_OK_FOR_INDEX_P(REGNO)					\
      (((REGNO) < FIRST_PSEUDO_REGISTER 					\
!      && REGNO_REG_CLASS ((REGNO)) == ADDR_REGS) 			\
!     || (reg_renumber[REGNO] > 0 && reg_renumber[REGNO] < 16))
  #define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_INDEX_P (REGNO)
  
  
--- 476,483 ----
     or a pseudo register currently allocated to one such.  */
  #define REGNO_OK_FOR_INDEX_P(REGNO)					\
      (((REGNO) < FIRST_PSEUDO_REGISTER 					\
!       && REGNO_REG_CLASS ((REGNO)) == ADDR_REGS) 			\
!      || ADDR_REGNO_P (reg_renumber[REGNO]))
  #define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_INDEX_P (REGNO)
  
  
*************** CUMULATIVE_ARGS;
*** 729,766 ****
  /* Maximum number of registers that can appear in a valid memory address.  */
  #define MAX_REGS_PER_ADDRESS 2
  
- /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check
-    its validity for a certain class.  We have two alternate definitions
-    for each of them.  The usual definition accepts all pseudo regs; the
-    other rejects them all.  The symbol REG_OK_STRICT causes the latter
-    definition to be used.
- 
-    Most source files want to accept pseudo regs in the hope that they will
-    get allocated to the class that the insn wants them to be in.
-    Some source files that are used after register allocation
-    need to be strict.  */
- 
- #define REG_OK_FOR_INDEX_NONSTRICT_P(X)   	\
- ((GET_MODE (X) == Pmode) &&			\
-  ((REGNO (X) >= FIRST_PSEUDO_REGISTER) 		\
-   || REGNO_REG_CLASS (REGNO (X)) == ADDR_REGS))
- 
- #define REG_OK_FOR_BASE_NONSTRICT_P(X)    REG_OK_FOR_INDEX_NONSTRICT_P (X)
- 
- #define REG_OK_FOR_INDEX_STRICT_P(X) 				\
- ((GET_MODE (X) == Pmode) && (REGNO_OK_FOR_INDEX_P (REGNO (X))))
- 
- #define REG_OK_FOR_BASE_STRICT_P(X)				\
- ((GET_MODE (X) == Pmode) && (REGNO_OK_FOR_BASE_P (REGNO (X))))
- 
- #ifndef REG_OK_STRICT
- #define REG_OK_FOR_INDEX_P(X)  REG_OK_FOR_INDEX_NONSTRICT_P(X)
- #define REG_OK_FOR_BASE_P(X)   REG_OK_FOR_BASE_NONSTRICT_P(X)
- #else
- #define REG_OK_FOR_INDEX_P(X)  REG_OK_FOR_INDEX_STRICT_P(X)
- #define REG_OK_FOR_BASE_P(X)   REG_OK_FOR_BASE_STRICT_P(X)
- #endif
- 
  /* S/390 has no mode dependent addresses.  */
  #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
  
--- 729,734 ----


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