S/390: More tweaks

Ulrich Weigand weigand@i1.informatik.uni-erlangen.de
Fri Oct 24 17:33:00 GMT 2003


Hello,

these are another couple of minor tweaks I noticed while experimenting
with improved TARGET_ZARCH support:

- allow both SImode (LM/STM) and DImode (LMG/STMG) load_multiple
  and store_multiple instructions in 64-bit mode.
- try to always zero-extend QImode loads in all z/Architecture
  modes, not just if TARGET_64BIT.
- remove predicates and constraint strings from the function return
  value operands of the call_value patterns -- other platforms don't
  have those either, and they even appear to cause reload to generate
  slightly less efficient code
- fix an incorrect stack temp size in the IBM floating point
  converters

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux,
applied to CVS head.

Bye,
Ulrich

ChangeLog:

	* config/s390/s390.c (load_multiple_operation): Allow both SImode
	and DImode if word_mode is DImode.
	(store_multiple_operation): Likewise.
	* config/s390/s390.md ("load_multiple", "store_multiple"): Likewise.
	("*load_multiple_di"): Allow only if word_mode == DImode.
	("movqi"): Use LLGC whenever TARGET_ZARCH.
	("fix_truncdfsi2"): Fix incorrect temporary size.
	("fix_truncsfsi2"): Likewise.
	("*bras_r", "*brasl_r", "*basr_r"): Remove predicate and constraint
	string for function return value operand.
	("*bras_tls", "*brasl_tls", "*basr_tls"): Likewise.

Index: gcc/config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.116
diff -c -p -r1.116 s390.c
*** gcc/config/s390/s390.c	18 Oct 2003 22:24:37 -0000	1.116
--- gcc/config/s390/s390.c	21 Oct 2003 22:20:02 -0000
*************** tls_symbolic_operand (register rtx op)
*** 1555,1560 ****
--- 1555,1561 ----
  int
  load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
  {
+   enum machine_mode elt_mode;
    int count = XVECLEN (op, 0);
    unsigned int dest_regno;
    rtx src_addr;
*************** load_multiple_operation (rtx op, enum ma
*** 1570,1575 ****
--- 1571,1577 ----
  
    dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
    src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
+   elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0)));
  
    /* Check, is base, or base + displacement.  */
  
*************** load_multiple_operation (rtx op, enum ma
*** 1594,1608 ****
  
        if (GET_CODE (elt) != SET
  	  || GET_CODE (SET_DEST (elt)) != REG
! 	  || GET_MODE (SET_DEST (elt)) != Pmode
  	  || REGNO (SET_DEST (elt)) != dest_regno + i
  	  || GET_CODE (SET_SRC (elt)) != MEM
! 	  || GET_MODE (SET_SRC (elt)) != Pmode
  	  || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
  	  || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
  	  || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
  	  || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1))
! 	     != off + i * UNITS_PER_WORD)
  	return 0;
      }
  
--- 1596,1610 ----
  
        if (GET_CODE (elt) != SET
  	  || GET_CODE (SET_DEST (elt)) != REG
! 	  || GET_MODE (SET_DEST (elt)) != elt_mode
  	  || REGNO (SET_DEST (elt)) != dest_regno + i
  	  || GET_CODE (SET_SRC (elt)) != MEM
! 	  || GET_MODE (SET_SRC (elt)) != elt_mode
  	  || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
  	  || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
  	  || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
  	  || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1))
! 	     != off + i * GET_MODE_SIZE (elt_mode))
  	return 0;
      }
  
*************** load_multiple_operation (rtx op, enum ma
*** 1617,1622 ****
--- 1619,1625 ----
  int
  store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
  {
+   enum machine_mode elt_mode;
    int count = XVECLEN (op, 0);
    unsigned int src_regno;
    rtx dest_addr;
*************** store_multiple_operation (rtx op, enum m
*** 1631,1636 ****
--- 1634,1640 ----
  
    src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
    dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
+   elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0)));
  
    /* Check, is base, or base + displacement.  */
  
*************** store_multiple_operation (rtx op, enum m
*** 1655,1669 ****
  
        if (GET_CODE (elt) != SET
  	  || GET_CODE (SET_SRC (elt)) != REG
! 	  || GET_MODE (SET_SRC (elt)) != Pmode
  	  || REGNO (SET_SRC (elt)) != src_regno + i
  	  || GET_CODE (SET_DEST (elt)) != MEM
! 	  || GET_MODE (SET_DEST (elt)) != Pmode
  	  || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
  	  || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
  	  || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
  	  || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
! 	     != off + i * UNITS_PER_WORD)
  	return 0;
      }
    return 1;
--- 1659,1673 ----
  
        if (GET_CODE (elt) != SET
  	  || GET_CODE (SET_SRC (elt)) != REG
! 	  || GET_MODE (SET_SRC (elt)) != elt_mode
  	  || REGNO (SET_SRC (elt)) != src_regno + i
  	  || GET_CODE (SET_DEST (elt)) != MEM
! 	  || GET_MODE (SET_DEST (elt)) != elt_mode
  	  || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
  	  || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
  	  || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
  	  || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
! 	     != off + i * GET_MODE_SIZE (elt_mode))
  	return 0;
      }
    return 1;
Index: gcc/config/s390/s390.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.md,v
retrieving revision 1.81
diff -c -p -r1.81 s390.md
*** gcc/config/s390/s390.md	18 Oct 2003 22:24:37 -0000	1.81
--- gcc/config/s390/s390.md	21 Oct 2003 22:20:08 -0000
***************
*** 1356,1369 ****
          (match_operand:QI 1 "general_operand" ""))]
    ""
  {
!   /* On 64-bit, zero-extending from memory to register
       is just as fast as a QImode load.  */
!   if (TARGET_64BIT && optimize && !no_new_pseudos
        && register_operand (operands[0], VOIDmode)
        && memory_operand (operands[1], VOIDmode))
      {
!       rtx tmp = gen_reg_rtx (DImode);
!       rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
        emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
        operands[1] = gen_lowpart (QImode, tmp);
      }
--- 1359,1372 ----
          (match_operand:QI 1 "general_operand" ""))]
    ""
  {
!   /* On z/Architecture, zero-extending from memory to register
       is just as fast as a QImode load.  */
!   if (TARGET_ZARCH && optimize && !no_new_pseudos
        && register_operand (operands[0], VOIDmode)
        && memory_operand (operands[1], VOIDmode))
      {
!       rtx tmp = gen_reg_rtx (word_mode);
!       rtx ext = gen_rtx_ZERO_EXTEND (word_mode, operands[1]);
        emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
        operands[1] = gen_lowpart (QImode, tmp);
      }
***************
*** 1587,1592 ****
--- 1590,1596 ----
  		     (use (match_operand 2 "" ""))])]
    ""
  {
+   enum machine_mode mode;
    int regno;
    int count;
    rtx from;
***************
*** 1604,1609 ****
--- 1608,1616 ----
  
    count = INTVAL (operands[2]);
    regno = REGNO (operands[0]);
+   mode = GET_MODE (operands[0]);
+   if (mode != SImode && mode != word_mode)
+     FAIL;
  
    operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
    if (no_new_pseudos)
***************
*** 1634,1650 ****
  
    for (i = 0; i < count; i++)
      XVECEXP (operands[3], 0, i)
!       = gen_rtx_SET (VOIDmode, gen_rtx_REG (Pmode, regno + i),
! 		     change_address (operands[1], Pmode,
! 				     plus_constant (from,
! 						    off + i * UNITS_PER_WORD)));
  })
  
  (define_insn "*load_multiple_di"
    [(match_parallel 0 "load_multiple_operation"
  		   [(set (match_operand:DI 1 "register_operand" "=r")
  			 (match_operand:DI 2 "s_operand" "QS"))])]
!   ""
  {
    int words = XVECLEN (operands[0], 0);
    operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
--- 1641,1656 ----
  
    for (i = 0; i < count; i++)
      XVECEXP (operands[3], 0, i)
!       = gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, regno + i),
! 		     change_address (operands[1], mode,
! 		       plus_constant (from, off + i * GET_MODE_SIZE (mode))));
  })
  
  (define_insn "*load_multiple_di"
    [(match_parallel 0 "load_multiple_operation"
  		   [(set (match_operand:DI 1 "register_operand" "=r")
  			 (match_operand:DI 2 "s_operand" "QS"))])]
!   "word_mode == DImode"
  {
    int words = XVECLEN (operands[0], 0);
    operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
***************
*** 1676,1681 ****
--- 1682,1688 ----
  		     (use (match_operand 2 "" ""))])]
    ""
  {
+   enum machine_mode mode;
    int regno;
    int count;
    rtx to;
***************
*** 1693,1698 ****
--- 1700,1708 ----
  
    count = INTVAL (operands[2]);
    regno = REGNO (operands[1]);
+   mode = GET_MODE (operands[1]);
+   if (mode != SImode && mode != word_mode)
+     FAIL;
  
    operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
  
***************
*** 1725,1741 ****
    for (i = 0; i < count; i++)
      XVECEXP (operands[3], 0, i)
        = gen_rtx_SET (VOIDmode,
! 		     change_address (operands[0], Pmode,
! 				     plus_constant (to,
! 						    off + i * UNITS_PER_WORD)),
! 		     gen_rtx_REG (Pmode, regno + i));
  })
  
  (define_insn "*store_multiple_di"
    [(match_parallel 0 "store_multiple_operation"
  		   [(set (match_operand:DI 1 "s_operand" "=QS")
  			 (match_operand:DI 2 "register_operand" "r"))])]
!   ""
  {
    int words = XVECLEN (operands[0], 0);
    operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
--- 1735,1750 ----
    for (i = 0; i < count; i++)
      XVECEXP (operands[3], 0, i)
        = gen_rtx_SET (VOIDmode,
! 		     change_address (operands[0], mode,
! 		       plus_constant (to, off + i * GET_MODE_SIZE (mode))),
! 		     gen_rtx_REG (mode, regno + i));
  })
  
  (define_insn "*store_multiple_di"
    [(match_parallel 0 "store_multiple_operation"
  		   [(set (match_operand:DI 1 "s_operand" "=QS")
  			 (match_operand:DI 2 "register_operand" "r"))])]
!   "word_mode == DImode"
  {
    int words = XVECLEN (operands[0], 0);
    operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
***************
*** 2748,2754 ****
      {
        /* This is the algorithm from POP chapter A.5.7.2.  */
  
!       rtx temp   = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
        rtx two31r = s390_gen_rtx_const_DI (0x4f000000, 0x08000000);
        rtx two32  = s390_gen_rtx_const_DI (0x4e000001, 0x00000000);
  
--- 2757,2763 ----
      {
        /* This is the algorithm from POP chapter A.5.7.2.  */
  
!       rtx temp   = assign_stack_local (BLKmode, 8, BITS_PER_WORD);
        rtx two31r = s390_gen_rtx_const_DI (0x4f000000, 0x08000000);
        rtx two32  = s390_gen_rtx_const_DI (0x4e000001, 0x00000000);
  
***************
*** 2948,2954 ****
      {
        /* This is the algorithm from POP chapter A.5.7.1.  */
  
!       rtx temp  = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
        rtx two31 = s390_gen_rtx_const_DI (0x4e000000, 0x80000000);
  
        emit_insn (gen_floatsidf2_ibm (operands[0], operands[1], two31, temp));
--- 2957,2963 ----
      {
        /* This is the algorithm from POP chapter A.5.7.1.  */
  
!       rtx temp  = assign_stack_local (BLKmode, 8, BITS_PER_WORD);
        rtx two31 = s390_gen_rtx_const_DI (0x4e000000, 0x80000000);
  
        emit_insn (gen_floatsidf2_ibm (operands[0], operands[1], two31, temp));
***************
*** 7003,7009 ****
    "")
  
  (define_insn "*bras_r"
!   [(set (match_operand 0 "register_operand" "=df")
          (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
                (match_operand:SI 2 "const_int_operand" "n")))
     (clobber (match_operand 3 "register_operand" "=r"))]
--- 7012,7018 ----
    "")
  
  (define_insn "*bras_r"
!   [(set (match_operand 0 "" "")
          (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
                (match_operand:SI 2 "const_int_operand" "n")))
     (clobber (match_operand 3 "register_operand" "=r"))]
***************
*** 7013,7019 ****
     (set_attr "type"    "jsr")])
  
  (define_insn "*brasl_r"
!   [(set (match_operand 0 "register_operand" "=df")
          (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
                (match_operand 2 "const_int_operand" "n")))
     (clobber (match_operand 3 "register_operand" "=r"))]
--- 7022,7028 ----
     (set_attr "type"    "jsr")])
  
  (define_insn "*brasl_r"
!   [(set (match_operand 0 "" "")
          (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
                (match_operand 2 "const_int_operand" "n")))
     (clobber (match_operand 3 "register_operand" "=r"))]
***************
*** 7023,7029 ****
     (set_attr "type"    "jsr")])
  
  (define_insn "*basr_r"
!   [(set (match_operand 0 "register_operand" "=df")
          (call (mem:QI (match_operand 1 "address_operand" "U"))
                (match_operand 2 "const_int_operand" "n")))
     (clobber (match_operand 3 "register_operand" "=r"))]
--- 7032,7038 ----
     (set_attr "type"    "jsr")])
  
  (define_insn "*basr_r"
!   [(set (match_operand 0 "" "")
          (call (mem:QI (match_operand 1 "address_operand" "U"))
                (match_operand 2 "const_int_operand" "n")))
     (clobber (match_operand 3 "register_operand" "=r"))]
***************
*** 7157,7163 ****
    "")
  
  (define_insn "*bras_tls"
!   [(set (match_operand 0 "register_operand" "=df")
          (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
                (match_operand 2 "const_int_operand" "n")))
     (clobber (match_operand 3 "register_operand" "=r"))
--- 7166,7172 ----
    "")
  
  (define_insn "*bras_tls"
!   [(set (match_operand 0 "" "")
          (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
                (match_operand 2 "const_int_operand" "n")))
     (clobber (match_operand 3 "register_operand" "=r"))
***************
*** 7168,7174 ****
     (set_attr "type"    "jsr")])
  
  (define_insn "*brasl_tls"
!   [(set (match_operand 0 "register_operand" "=df")
          (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
                (match_operand 2 "const_int_operand" "n")))
     (clobber (match_operand 3 "register_operand" "=r"))
--- 7177,7183 ----
     (set_attr "type"    "jsr")])
  
  (define_insn "*brasl_tls"
!   [(set (match_operand 0 "" "")
          (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
                (match_operand 2 "const_int_operand" "n")))
     (clobber (match_operand 3 "register_operand" "=r"))
***************
*** 7179,7185 ****
     (set_attr "type"    "jsr")])
  
  (define_insn "*basr_tls"
!   [(set (match_operand 0 "register_operand" "=df")
          (call (mem:QI (match_operand 1 "address_operand" "U"))
                (match_operand 2 "const_int_operand" "n")))
     (clobber (match_operand 3 "register_operand" "=r"))
--- 7188,7194 ----
     (set_attr "type"    "jsr")])
  
  (define_insn "*basr_tls"
!   [(set (match_operand 0 "" "")
          (call (mem:QI (match_operand 1 "address_operand" "U"))
                (match_operand 2 "const_int_operand" "n")))
     (clobber (match_operand 3 "register_operand" "=r"))
-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de



More information about the Gcc-patches mailing list