[PATCH] S/390: Use TARGET_SECONDARY_RELOAD hook - take 2

Andreas Krebbel Andreas.Krebbel@de.ibm.com
Wed Mar 28 14:06:00 GMT 2007


Hi,

Ulrich reviewed my secondary reload patch and gave me off-list
feedback.

This is an updated version including two fixes:

- the old patch removed a TI mode splitter which is 
  still needed
- the "reload<mode>_nonoffmem_in" pattern used a wrong 
  constraint letter

I've started bootstrap for s390 and s390x.

OK for mainline given no testsuite regression occurs?

Bye,

-Andreas-


2007-03-28  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390/s390.c (s390_secondary_input_reload_class,
	s390_secondary_output_reload_class): Functions removed.
	(s390_secondary_reload): New function.
	(TARGET_SECONDARY_RELOAD): Target macro defined.
	* config/s390/s390.h (SECONDARY_INPUT_RELOAD_CLASS,
	SECONDARY_OUTPUT_RELOAD_CLASS): Macro definitions removed.
	* config/s390/s390.md ("reload_outti", "reload_outdi",
	"reload_indi", "reload_insi", "reload_out<mode>", "reload_in<mode>",
	"reload_out<mode>"): Expanders removed.
	("reload<mode>_plus", "reload<mode>_nonoffmem_in",
	"reload<mode>_nonoffmem_out"): Expanders added.


Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig	2007-03-28 15:33:31.000000000 +0200
--- gcc/config/s390/s390.c	2007-03-28 15:33:55.000000000 +0200
*************** s390_preferred_reload_class (rtx op, enu
*** 2638,2704 ****
    return class;
  }
  
! /* Return the register class of a scratch register needed to
!    load IN into a register of class CLASS in MODE.
! 
!    We need a temporary when loading a PLUS expression which
!    is not a legitimate operand of the LOAD ADDRESS instruction.  */
! 
! enum reg_class
! s390_secondary_input_reload_class (enum reg_class class,
! 				   enum machine_mode mode, rtx in)
! {
!   if (s390_plus_operand (in, mode))
!     return ADDR_REGS;
! 
!   if (reg_classes_intersect_p (FP_REGS, class)
!       && mode == TFmode
!       && GET_CODE (in) == MEM
!       && GET_CODE (XEXP (in, 0)) == PLUS
!       && GET_CODE (XEXP (XEXP (in, 0), 1)) == CONST_INT
!       && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (in, 0), 1))
! 			 + GET_MODE_SIZE (mode) - 1))
!     return ADDR_REGS;
! 
    if (reg_classes_intersect_p (CC_REGS, class))
      return GENERAL_REGS;
  
!   return NO_REGS;
! }
! 
! /* Return the register class of a scratch register needed to
!    store a register of class CLASS in MODE into OUT:
! 
!    We need a temporary when storing a double-word to a
!    non-offsettable memory address.  */
! 
! enum reg_class
! s390_secondary_output_reload_class (enum reg_class class,
! 				    enum machine_mode mode, rtx out)
! {
!   if ((TARGET_64BIT ? (mode == TImode || mode == TFmode)
!                     : (mode == DImode || mode == DFmode))
!       && reg_classes_intersect_p (GENERAL_REGS, class)
!       && GET_CODE (out) == MEM
!       && GET_CODE (XEXP (out, 0)) == PLUS
!       && GET_CODE (XEXP (XEXP (out, 0), 0)) == PLUS
!       && GET_CODE (XEXP (XEXP (out, 0), 1)) == CONST_INT
!       && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out, 0), 1))
  			 + GET_MODE_SIZE (mode) - 1))
!     return ADDR_REGS;
! 
!   if (reg_classes_intersect_p (FP_REGS, class)
!       && mode == TFmode
!       && GET_CODE (out) == MEM
!       && GET_CODE (XEXP (out, 0)) == PLUS
!       && GET_CODE (XEXP (XEXP (out, 0), 1)) == CONST_INT
!       && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out, 0), 1))
! 			 + GET_MODE_SIZE (mode) - 1))
!     return ADDR_REGS;
! 
!   if (reg_classes_intersect_p (CC_REGS, class))
!     return GENERAL_REGS;
  
    return NO_REGS;
  }
  
--- 2638,2694 ----
    return class;
  }
  
! /* Inform reload about cases where moving X with a mode MODE to a register in
!    CLASS requires an extra scratch or immediate register.  Return the class
!    needed for the immediate register.  */
! 
! static enum reg_class
! s390_secondary_reload (bool in_p, rtx x, enum reg_class class,
! 		       enum machine_mode mode, secondary_reload_info *sri)
! {
!   /* Intermediate register needed.  */
    if (reg_classes_intersect_p (CC_REGS, class))
      return GENERAL_REGS;
  
!   /* We need a scratch register when loading a PLUS expression which
!      is not a legitimate operand of the LOAD ADDRESS instruction.  */
!   if (in_p && s390_plus_operand (x, mode))
!     sri->icode = (TARGET_64BIT ?
! 		  CODE_FOR_reloaddi_plus : CODE_FOR_reloadsi_plus);
! 
!   /* Peforming a multiword move from or to memory we have to make sure the
!      second chunk in memory is addressable without causing a displacement
!      overflow.  If that would be the case we calculate the address in
!      a scratch register.  */
!   if (MEM_P (x)
!       && GET_CODE (XEXP (x, 0)) == PLUS
!       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
!       && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (x, 0), 1))
  			 + GET_MODE_SIZE (mode) - 1))
!     {
!       /* For GENERAL_REGS a displacement overflow is no problem if occuring
! 	 in a s_operand address since we may fallback to lm/stm.  So we only
! 	 have to care about overflows in the b+i+d case.  */
!       if ((reg_classes_intersect_p (GENERAL_REGS, class)
! 	   && s390_class_max_nregs (GENERAL_REGS, mode) > 1
! 	   && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS)
! 	  /* For FP_REGS no lm/stm is available so this check is triggered
! 	     for displacement overflows in b+i+d and b+d like addresses.  */
! 	  || (reg_classes_intersect_p (FP_REGS, class)
! 	      && s390_class_max_nregs (FP_REGS, mode) > 1))
! 	{
! 	  if (in_p)
! 	    sri->icode = (TARGET_64BIT ?
! 			  CODE_FOR_reloaddi_nonoffmem_in :
! 			  CODE_FOR_reloadsi_nonoffmem_in);
! 	  else
! 	    sri->icode = (TARGET_64BIT ?
! 			  CODE_FOR_reloaddi_nonoffmem_out :
! 			  CODE_FOR_reloadsi_nonoffmem_out);
! 	}
!     }
  
+   /* Either scratch or no register needed.  */
    return NO_REGS;
  }
  
*************** s390_reorg (void)
*** 9364,9369 ****
--- 9354,9362 ----
  #undef TARGET_SCALAR_MODE_SUPPORTED_P
  #define TARGET_SCALAR_MODE_SUPPORTED_P s390_scalar_mode_supported_p
  
+ #undef TARGET_SECONDARY_RELOAD
+ #define TARGET_SECONDARY_RELOAD s390_secondary_reload
+ 
  struct gcc_target targetm = TARGET_INITIALIZER;
  
  #include "gt-s390.h"
Index: gcc/config/s390/s390.h
===================================================================
*** gcc/config/s390/s390.h.orig	2007-03-28 15:33:31.000000000 +0200
--- gcc/config/s390/s390.h	2007-03-28 15:33:55.000000000 +0200
*************** extern const enum reg_class regclass_map
*** 464,479 ****
  #define PREFERRED_RELOAD_CLASS(X, CLASS)	\
    s390_preferred_reload_class ((X), (CLASS))
  
- /* We need a secondary reload when loading a PLUS which is
-    not a valid operand for LOAD ADDRESS.  */
- #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN)	\
-   s390_secondary_input_reload_class ((CLASS), (MODE), (IN))
- 
- /* We need a secondary reload when storing a double-word
-    to a non-offsettable memory address.  */
- #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, OUT)	\
-   s390_secondary_output_reload_class ((CLASS), (MODE), (OUT))
- 
  /* We need secondary memory to move data between GPRs and FPRs.  */
  #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
   ((CLASS1) != (CLASS2)                                \
--- 464,469 ----
Index: gcc/config/s390/s390.md
===================================================================
*** gcc/config/s390/s390.md.orig	2007-03-28 15:33:31.000000000 +0200
--- gcc/config/s390/s390.md	2007-03-28 15:35:25.000000000 +0200
***************
*** 893,903 ****
    operands[1] = replace_equiv_address (operands[1], addr);
  })
  
! (define_expand "reload_outti"
!   [(parallel [(match_operand:TI 0 "" "")
!               (match_operand:TI 1 "register_operand" "d")
!               (match_operand:DI 2 "register_operand" "=&a")])]
!   "TARGET_64BIT"
  {
    gcc_assert (MEM_P (operands[0]));
    s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
--- 893,935 ----
    operands[1] = replace_equiv_address (operands[1], addr);
  })
  
! 
! ;
! ; Patterns used for secondary reloads
! ;
! 
! ; Handles loading a PLUS (load address) expression
! 
! (define_expand "reload<mode>_plus"
!   [(parallel [(match_operand:P 0 "register_operand"  "=a")
!               (match_operand:P 1 "s390_plus_operand" "")
!               (match_operand:P 2 "register_operand"  "=&a")])]
!   ""
! {
!   s390_expand_plus_operand (operands[0], operands[1], operands[2]);
!   DONE;
! })
! 
! ; Handles assessing a non-offsetable memory address
! 
! (define_expand "reload<mode>_nonoffmem_in"
!   [(parallel [(match_operand 0   "register_operand" "")
!               (match_operand 1   "" "")
!               (match_operand:P 2 "register_operand" "=&a")])]
!   ""
! {
!   gcc_assert (MEM_P (operands[1]));
!   s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
!   operands[1] = replace_equiv_address (operands[1], operands[2]);
!   emit_move_insn (operands[0], operands[1]);
!   DONE;
! })
! 
! (define_expand "reload<mode>_nonoffmem_out"
!   [(parallel [(match_operand   0 "" "")
!               (match_operand   1 "register_operand" "")
!               (match_operand:P 2 "register_operand" "=&a")])]
!   ""
  {
    gcc_assert (MEM_P (operands[0]));
    s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
***************
*** 1130,1148 ****
    operands[1] = replace_equiv_address (operands[1], addr);
  })
  
- (define_expand "reload_outdi"
-   [(parallel [(match_operand:DI 0 "" "")
-               (match_operand:DI 1 "register_operand" "d")
-               (match_operand:SI 2 "register_operand" "=&a")])]
-   "!TARGET_64BIT"
- {
-   gcc_assert (MEM_P (operands[0]));
-   s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
-   operands[0] = replace_equiv_address (operands[0], operands[2]);
-   emit_move_insn (operands[0], operands[1]);
-   DONE;
- })
- 
  (define_peephole2
    [(set (match_operand:DI 0 "register_operand" "")
          (mem:DI (match_operand 1 "address_operand" "")))]
--- 1162,1167 ----
***************
*** 1189,1204 ****
    [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
    "")
  
- (define_expand "reload_indi"
-   [(parallel [(match_operand:DI 0 "register_operand" "=a")
-               (match_operand:DI 1 "s390_plus_operand" "")
-               (match_operand:DI 2 "register_operand" "=&a")])]
-   "TARGET_64BIT"
- {
-   s390_expand_plus_operand (operands[0], operands[1], operands[2]);
-   DONE;
- })
- 
  ;
  ; movsi instruction pattern(s).
  ;
--- 1208,1213 ----
***************
*** 1359,1374 ****
    [(set_attr "op_type"  "RX")
     (set_attr "type"     "la")])
  
- (define_expand "reload_insi"
-   [(parallel [(match_operand:SI 0 "register_operand" "=a")
-               (match_operand:SI 1 "s390_plus_operand" "")
-               (match_operand:SI 2 "register_operand" "=&a")])]
-   "!TARGET_64BIT"
- {
-   s390_expand_plus_operand (operands[0], operands[1], operands[2]);
-   DONE;
- })
- 
  ;
  ; movhi instruction pattern(s).
  ;
--- 1368,1373 ----
***************
*** 1625,1660 ****
                                       <MODE>mode, 8);
  })
  
- (define_expand "reload_out<mode>"
-   [(parallel [(match_operand:TD_TF 0 "" "")
-               (match_operand:TD_TF 1 "register_operand" "f")
-               (match_operand:SI 2    "register_operand" "=&a")])]
-   ""
- {
-   rtx addr = gen_lowpart (Pmode, operands[2]);
- 
-   gcc_assert (MEM_P (operands[0]));
-   s390_load_address (addr, find_replacement (&XEXP (operands[0], 0)));
-   operands[0] = replace_equiv_address (operands[0], addr);
-   emit_move_insn (operands[0], operands[1]);
-   DONE;
- })
- 
- (define_expand "reload_in<mode>"
-   [(parallel [(match_operand:TD_TF 0 "register_operand" "=f")
-               (match_operand:TD_TF 1 "" "")
-               (match_operand:SI 2    "register_operand" "=&a")])]
-   ""
- {
-   rtx addr = gen_lowpart (Pmode, operands[2]);
-  
-   gcc_assert (MEM_P (operands[1]));
-   s390_load_address (addr, find_replacement (&XEXP (operands[1], 0)));
-   operands[1] = replace_equiv_address (operands[1], addr);
-   emit_move_insn (operands[0], operands[1]);
-   DONE;
- })
- 
  ;
  ; mov(df|dd) instruction pattern(s).
  ;
--- 1624,1629 ----
***************
*** 1772,1790 ****
    operands[1] = replace_equiv_address (operands[1], addr);
  })
  
- (define_expand "reload_out<mode>"
-   [(parallel [(match_operand:DD_DF 0 "" "")
-               (match_operand:DD_DF 1 "register_operand" "d")
-               (match_operand:SI 2    "register_operand" "=&a")])]
-   "!TARGET_64BIT"
- {
-   gcc_assert (MEM_P (operands[0]));
-   s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
-   operands[0] = replace_equiv_address (operands[0], operands[2]);
-   emit_move_insn (operands[0], operands[1]);
-   DONE;
- })
- 
  ;
  ; mov(sf|sd) instruction pattern(s).
  ;
--- 1741,1746 ----



More information about the Gcc-patches mailing list