sh.c (print_operand, case 'N'): Allow zero vector.

Tue Jul  2 18:45:45 2002  J"orn Rennecke <joern.rennecke@superh.com>

	* sh.c (print_operand, case 'N'): Allow zero vector.
	(arith_reg_or_0_operand): Likewise.
	(zero_vec_operand): Check for CONST_VECTOR, not PARALLEL.
	* sh.h (CONST_COSTS): 0 has 0 cost.  Check OUTER_CODE for
	IOR, XOR, PLUS and SET and take their respective constant
	ranges into account.
	(PREDICATE_CODES, arith_reg_or_0_operand): Can be CONST_VECTOR.
	* sh.md (subdi3, subdi3_media): Allow zero operand.
	(movv8qi_i+3): Only vector that is not split is the zero vector.
	Fix operand 3 to simplify_subreg.
	(movv2si_i): Split alternative 1.
	(mshfhi_l_di_rev+1): New splitter.

Index: config/sh/sh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.c,v
retrieving revision 1.155
diff -p -r1.155 sh.c
*** config/sh/sh.c	2 Jul 2002 04:01:04 -0000	1.155
--- config/sh/sh.c	2 Jul 2002 17:45:37 -0000
*************** print_operand (stream, x, code)
*** 434,440 ****
        break;

      case 'N':
!       if (x == const0_rtx)
  	{
  	  fprintf ((stream), "r63");
  	  break;
--- 434,441 ----
        break;

      case 'N':
!       if (x == const0_rtx
! 	  || (GET_CODE (x) == CONST_VECTOR && zero_vec_operand (x, VOIDmode)))
  	{
  	  fprintf ((stream), "r63");
  	  break;
*************** arith_reg_or_0_operand (op, mode)
*** 5940,5946 ****
    if (arith_reg_operand (op, mode))
      return 1;

!   if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_N (INTVAL (op)))
      return 1;

    return 0;
--- 5941,5947 ----
    if (arith_reg_operand (op, mode))
      return 1;

!   if (EXTRA_CONSTRAINT_U (op))
      return 1;

    return 0;
*************** zero_vec_operand (v, mode)
*** 6222,6228 ****
  {
    int i;

!   if (GET_CODE (v) != PARALLEL
        || (GET_MODE (v) != mode && mode != VOIDmode))
      return 0;
    for (i = XVECLEN (v, 0) - 1; i >= 0; i--)
--- 6223,6229 ----
  {
    int i;

!   if (GET_CODE (v) != CONST_VECTOR
        || (GET_MODE (v) != mode && mode != VOIDmode))
      return 0;
    for (i = XVECLEN (v, 0) - 1; i >= 0; i--)
Index: config/sh/sh.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.h,v
retrieving revision 1.154
diff -p -r1.154 sh.h
*** config/sh/sh.h	1 Jul 2002 19:41:53 -0000	1.154
--- config/sh/sh.h	2 Jul 2002 17:45:37 -0000
*************** while (0)
*** 2689,2698 ****
    case CONST_INT:				\
      if (TARGET_SHMEDIA)				\
        {						\
  	if ((OUTER_CODE) == AND && and_operand ((RTX), DImode)) \
  	  return 0;				\
  	if (CONST_OK_FOR_J (INTVAL (RTX)))	\
!           return COSTS_N_INSNS (1);		\
  	else if (CONST_OK_FOR_J (INTVAL (RTX) >> 16)) \
  	  return COSTS_N_INSNS (2);		\
  	else if (CONST_OK_FOR_J ((INTVAL (RTX) >> 16) >> 16)) \
--- 2689,2704 ----
    case CONST_INT:				\
      if (TARGET_SHMEDIA)				\
        {						\
+ 	if (INTVAL (RTX) == 0)			\
+ 	  return 0;				\
  	if ((OUTER_CODE) == AND && and_operand ((RTX), DImode)) \
  	  return 0;				\
+ 	if (((OUTER_CODE) == IOR || (OUTER_CODE) == XOR \
+ 	     || (OUTER_CODE) == PLUS) \
+ 	    && CONST_OK_FOR_P (INTVAL (RTX)))	\
+ 	  return 0;				\
  	if (CONST_OK_FOR_J (INTVAL (RTX)))	\
!           return COSTS_N_INSNS ((OUTER_CODE) != SET);		\
  	else if (CONST_OK_FOR_J (INTVAL (RTX) >> 16)) \
  	  return COSTS_N_INSNS (2);		\
  	else if (CONST_OK_FOR_J ((INTVAL (RTX) >> 16) >> 16)) \
*************** extern int rtx_equal_function_value_matt
*** 3225,3231 ****
    {"arith_operand", {SUBREG, REG, CONST_INT}},				\
    {"arith_reg_dest", {SUBREG, REG}},					\
    {"arith_reg_operand", {SUBREG, REG}},					\
!   {"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT}},			\
    {"binary_float_operator", {PLUS, MULT}},				\
    {"commutative_float_operator", {PLUS, MULT}},				\
    {"extend_reg_operand", {SUBREG, REG, TRUNCATE}},			\
--- 3231,3237 ----
    {"arith_operand", {SUBREG, REG, CONST_INT}},				\
    {"arith_reg_dest", {SUBREG, REG}},					\
    {"arith_reg_operand", {SUBREG, REG}},					\
!   {"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_VECTOR}},	\
    {"binary_float_operator", {PLUS, MULT}},				\
    {"commutative_float_operator", {PLUS, MULT}},				\
    {"extend_reg_operand", {SUBREG, REG, TRUNCATE}},			\
Index: config/sh/sh.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.md,v
retrieving revision 1.107
diff -p -r1.107 sh.md
*** config/sh/sh.md	1 Jul 2002 19:41:54 -0000	1.107
--- config/sh/sh.md	2 Jul 2002 17:45:38 -0000
***************
*** 546,552 ****
  ;; There is no way to model this with gcc's function units.  This problem is
  ;; actually mentioned in md.texi.  Tackling this problem requires first that
  ;; it is possible to speak about the target in an open discussion.
! ;;
  ;; However, simple double-precision operations always conflict.

  (define_function_unit "fp"    1 0
--- 546,552 ----
  ;; There is no way to model this with gcc's function units.  This problem is
  ;; actually mentioned in md.texi.  Tackling this problem requires first that
  ;; it is possible to speak about the target in an open discussion.
! ;;
  ;; However, simple double-precision operations always conflict.

  (define_function_unit "fp"    1 0
***************
*** 1048,1054 ****
    "@
  	addz.l	%1, %2, %0
  	addz.l	%1, r63, %0")
!
  (define_insn "adddi3_compact"
    [(set (match_operand:DI 0 "arith_reg_operand" "=r")
  	(plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
--- 1048,1054 ----
    "@
  	addz.l	%1, %2, %0
  	addz.l	%1, r63, %0")
!
  (define_insn "adddi3_compact"
    [(set (match_operand:DI 0 "arith_reg_operand" "=r")
  	(plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
***************
*** 1122,1128 ****
    "@
  	add.l	%1, %2, %0
  	addi.l	%1, %2, %0")
!
  (define_insn "*addsi3_compact"
    [(set (match_operand:SI 0 "arith_reg_operand" "=r")
  	(plus:SI (match_operand:SI 1 "arith_operand" "%0")
--- 1122,1128 ----
    "@
  	add.l	%1, %2, %0
  	addi.l	%1, %2, %0")
!
  (define_insn "*addsi3_compact"
    [(set (match_operand:SI 0 "arith_reg_operand" "=r")
  	(plus:SI (match_operand:SI 1 "arith_operand" "%0")
***************
*** 1138,1162 ****

  (define_expand "subdi3"
    [(set (match_operand:DI 0 "arith_reg_operand" "")
! 	(minus:DI (match_operand:DI 1 "arith_reg_operand" "")
  		  (match_operand:DI 2 "arith_reg_operand" "")))]
    ""
    "
  {
    if (TARGET_SH1)
      {
        emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
        DONE;
      }
  }")
!
  (define_insn "*subdi3_media"
    [(set (match_operand:DI 0 "arith_reg_operand" "=r")
! 	(minus:DI (match_operand:DI 1 "arith_reg_operand" "r")
  		  (match_operand:DI 2 "arith_reg_operand" "r")))]
    "TARGET_SHMEDIA"
!   "sub	%1, %2, %0")
!
  (define_insn "subdi3_compact"
    [(set (match_operand:DI 0 "arith_reg_operand" "=r")
  	(minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
--- 1138,1163 ----

  (define_expand "subdi3"
    [(set (match_operand:DI 0 "arith_reg_operand" "")
! 	(minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
  		  (match_operand:DI 2 "arith_reg_operand" "")))]
    ""
    "
  {
    if (TARGET_SH1)
      {
+       operands[1] = force_reg (DImode, operands[1]);
        emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
        DONE;
      }
  }")
!
  (define_insn "*subdi3_media"
    [(set (match_operand:DI 0 "arith_reg_operand" "=r")
! 	(minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
  		  (match_operand:DI 2 "arith_reg_operand" "r")))]
    "TARGET_SHMEDIA"
!   "sub	%N1, %2, %0")
!
  (define_insn "subdi3_compact"
    [(set (match_operand:DI 0 "arith_reg_operand" "=r")
  	(minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
***************
*** 1558,1564 ****
  					   : \"__sdivsi3\")));

        if (TARGET_SHMEDIA)
! 	last = gen_divsi3_i1_media (operands[0],
  				    Pmode == DImode
  				    ? operands[3]
  				    : gen_rtx_SUBREG (DImode, operands[3],
--- 1559,1565 ----
  					   : \"__sdivsi3\")));

        if (TARGET_SHMEDIA)
! 	last = gen_divsi3_i1_media (operands[0],
  				    Pmode == DImode
  				    ? operands[3]
  				    : gen_rtx_SUBREG (DImode, operands[3],
***************
*** 1771,1777 ****
  		 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
    "TARGET_SHMEDIA"
    "muls.l	%1, %2, %0")
!
  (define_insn "mulsidi3_compact"
    [(set (match_operand:DI 0 "arith_reg_operand" "=r")
  	(mult:DI
--- 1772,1778 ----
  		 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
    "TARGET_SHMEDIA"
    "muls.l	%1, %2, %0")
!
  (define_insn "mulsidi3_compact"
    [(set (match_operand:DI 0 "arith_reg_operand" "=r")
  	(mult:DI
***************
*** 1841,1847 ****
  		 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
    "TARGET_SHMEDIA"
    "mulu.l	%1, %2, %0")
!
  (define_insn "umulsidi3_compact"
    [(set (match_operand:DI 0 "arith_reg_operand" "=r")
  	(mult:DI
--- 1842,1848 ----
  		 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
    "TARGET_SHMEDIA"
    "mulu.l	%1, %2, %0")
!
  (define_insn "umulsidi3_compact"
    [(set (match_operand:DI 0 "arith_reg_operand" "=r")
  	(mult:DI
***************
*** 3440,3446 ****
     (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])

  ;; If the output is a register and the input is memory or a register, we have
! ;; to be careful and see which word needs to be loaded first.

  (define_split
    [(set (match_operand:DI 0 "general_movdst_operand" "")
--- 3441,3447 ----
     (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])

  ;; If the output is a register and the input is memory or a register, we have
! ;; to be careful and see which word needs to be loaded first.

  (define_split
    [(set (match_operand:DI 0 "general_movdst_operand" "")
***************
*** 4195,4201 ****
  }")

  ;; If the output is a register and the input is memory or a register, we have
! ;; to be careful and see which word needs to be loaded first.

  (define_split
    [(set (match_operand:DF 0 "general_movdst_operand" "")
--- 4196,4202 ----
  }")

  ;; If the output is a register and the input is memory or a register, we have
! ;; to be careful and see which word needs to be loaded first.

  (define_split
    [(set (match_operand:DF 0 "general_movdst_operand" "")
***************
*** 4392,4398 ****
    DONE;
  }"
    [(set_attr "length" "8")])
!
  (define_expand "movv4sf"
    [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
  	(match_operand:V4SF 1 "nonimmediate_operand" "f,m,f"))]
--- 4393,4399 ----
    DONE;
  }"
    [(set_attr "length" "8")])
!
  (define_expand "movv4sf"
    [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
  	(match_operand:V4SF 1 "nonimmediate_operand" "f,m,f"))]
***************
*** 4444,4450 ****
    DONE;
  }"
    [(set_attr "length" "32")])
!
  (define_expand "movv16sf"
    [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
  	(match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
--- 4445,4451 ----
    DONE;
  }"
    [(set_attr "length" "32")])
!
  (define_expand "movv16sf"
    [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
  	(match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
***************
*** 4499,4505 ****
    REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
    REAL_VALUE_TO_TARGET_SINGLE (value, values);
    operands[2] = GEN_INT (values);
!
    operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
  }")

--- 4500,4506 ----
    REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
    REAL_VALUE_TO_TARGET_SINGLE (value, values);
    operands[2] = GEN_INT (values);
!
    operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
  }")

***************
*** 5410,5416 ****
  	  if (! SYMBOL_REF_FLAG (operands[0]))
  	    {
  	      rtx reg = gen_reg_rtx (Pmode);
!
  	      emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
  	      operands[0] = reg;
  	    }
--- 5411,5417 ----
  	  if (! SYMBOL_REF_FLAG (operands[0]))
  	    {
  	      rtx reg = gen_reg_rtx (Pmode);
!
  	      emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
  	      operands[0] = reg;
  	    }
***************
*** 5634,5640 ****
  	  if (! SYMBOL_REF_FLAG (operands[1]))
  	    {
  	      rtx reg = gen_reg_rtx (Pmode);
!
  	      emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
  	      operands[1] = reg;
  	    }
--- 5635,5641 ----
  	  if (! SYMBOL_REF_FLAG (operands[1]))
  	    {
  	      rtx reg = gen_reg_rtx (Pmode);
!
  	      emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
  	      operands[1] = reg;
  	    }
***************
*** 5841,5847 ****
  	  if (! SYMBOL_REF_FLAG (operands[0]))
  	    {
  	      rtx reg = gen_reg_rtx (Pmode);
!
  	      /* We must not use GOTPLT for sibcalls, because PIC_REG
  		 must be restored before the PLT code gets to run.  */
  	      emit_insn (gen_symGOT2reg (reg, operands[0]));
--- 5842,5848 ----
  	  if (! SYMBOL_REF_FLAG (operands[0]))
  	    {
  	      rtx reg = gen_reg_rtx (Pmode);
!
  	      /* We must not use GOTPLT for sibcalls, because PIC_REG
  		 must be restored before the PLT code gets to run.  */
  	      emit_insn (gen_symGOT2reg (reg, operands[0]));
***************
*** 6167,6173 ****
     (use (label_ref (match_operand 1 "" "")))]
    "TARGET_SHMEDIA"
    "blink	%0, r63")
!
  ;; Call subroutine returning any type.
  ;; ??? This probably doesn't work.

--- 6168,6174 ----
     (use (label_ref (match_operand 1 "" "")))]
    "TARGET_SHMEDIA"
    "blink	%0, r63")
!
  ;; Call subroutine returning any type.
  ;; ??? This probably doesn't work.

***************
*** 6284,6290 ****
  	tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);

        insn = emit_move_insn (operands[0], tr);
!
        REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
  					    REG_NOTES (insn));

--- 6285,6291 ----
  	tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);

        insn = emit_move_insn (operands[0], tr);
!
        REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
  					    REG_NOTES (insn));

***************
*** 6370,6379 ****
    if (TARGET_SHMEDIA)
      {
        rtx reg = operands[2];
!
        if (GET_MODE (reg) != DImode)
  	reg = gen_rtx_SUBREG (DImode, reg, 0);
!
        if (flag_pic > 1)
  	emit_insn (gen_movdi_const_32bit (reg, operands[1]));
        else
--- 6371,6380 ----
    if (TARGET_SHMEDIA)
      {
        rtx reg = operands[2];
!
        if (GET_MODE (reg) != DImode)
  	reg = gen_rtx_SUBREG (DImode, reg, 0);
!
        if (flag_pic > 1)
  	emit_insn (gen_movdi_const_32bit (reg, operands[1]));
        else
***************
*** 6391,6397 ****
    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
  								  0), 0, 0),
  					REG_NOTES (insn));
!
    DONE;
  }")

--- 6392,6398 ----
    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
  								  0), 0, 0),
  					REG_NOTES (insn));
!
    DONE;
  }")

***************
*** 7231,7237 ****
  				    (match_dup 2))))
  	      (set (reg:SI T_REG)
  		   (ne:SI (ior:SI (match_dup 1) (match_dup 2))
! 			  (const_int 0)))])]
    ""
    "
  {
--- 7232,7238 ----
  				    (match_dup 2))))
  	      (set (reg:SI T_REG)
  		   (ne:SI (ior:SI (match_dup 1) (match_dup 2))
! 			  (const_int 0)))])]
    ""
    "
  {
***************
*** 7282,7288 ****
  				    (match_dup 2))))
  	      (set (reg:SI T_REG)
  		   (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
! 			  (const_int 0)))])]
    "TARGET_SH1"
    "operands[2] = gen_reg_rtx (SImode);")

--- 7283,7289 ----
  				    (match_dup 2))))
  	      (set (reg:SI T_REG)
  		   (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
! 			  (const_int 0)))])]
    "TARGET_SH1"
    "operands[2] = gen_reg_rtx (SImode);")

***************
*** 8279,8285 ****
  ;;   "#"
  ;;   [(set_attr "length" "4")
  ;;    (set_attr "fp_mode" "double")])
! ;;
  ;; (define_split
  ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
  ;; 	(fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
--- 8280,8286 ----
  ;;   "#"
  ;;   [(set_attr "length" "4")
  ;;    (set_attr "fp_mode" "double")])
! ;;
  ;; (define_split
  ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
  ;; 	(fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
***************
*** 8320,8326 ****
    "* return output_ieee_ccmpeq (insn, operands);"
    [(set_attr "length" "4")
     (set_attr "fp_mode" "double")])
!
  (define_insn "cmpeqdf_media"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
--- 8321,8327 ----
    "* return output_ieee_ccmpeq (insn, operands);"
    [(set_attr "length" "4")
     (set_attr "fp_mode" "double")])
!
  (define_insn "cmpeqdf_media"
    [(set (match_operand:DI 0 "register_operand" "=r")
  	(eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
***************
*** 8806,8815 ****
    "TARGET_SHMEDIA && reload_completed
     && GET_MODE (operands[0]) == GET_MODE (operands[1])
     && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
!    && XVECEXP (operands[1], 0, 0) != const0_rtx
!    && (HOST_BITS_PER_WIDE_INT >= 64
!        || HOST_BITS_PER_WIDE_INT >= GET_MODE_BITSIZE (GET_MODE (operands[0]))
!        || sh_1el_vec (operands[1], VOIDmode))"
    [(set (match_dup 0) (match_dup 1))]
    "
  {
--- 8807,8813 ----
    "TARGET_SHMEDIA && reload_completed
     && GET_MODE (operands[0]) == GET_MODE (operands[1])
     && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
!    && ! zero_vec_operand (operands[1], VOIDmode)"
    [(set (match_dup 0) (match_dup 1))]
    "
  {
***************
*** 8819,8825 ****

    operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
    operands[1]
!     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[0]), 0);
  }")

  (define_expand "movv2hi"
--- 8817,8823 ----

    operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
    operands[1]
!     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
  }")

  (define_expand "movv2hi"
***************
*** 8878,8884 ****
         || register_operand (operands[1], V2SImode))"
    "@
  	add	%1, r63, %0
! 	movi	%1, %0
  	#
  	ld%M1.q	%m1, %0
  	st%M0.q	%m0, %1"
--- 8876,8882 ----
         || register_operand (operands[1], V2SImode))"
    "@
  	add	%1, r63, %0
! 	#
  	#
  	ld%M1.q	%m1, %0
  	st%M0.q	%m0, %1"
***************
*** 9641,9647 ****
  /* These are useful to expand ANDs and as combiner patterns.  */
  (define_insn "mshfhi_l_di"
    [(set (match_operand:DI 0 "arith_reg_dest" "=r")
! 	(ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
                               (const_int 32))
  		(and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
  			(const_int -4294967296))))]
--- 9639,9645 ----
  /* These are useful to expand ANDs and as combiner patterns.  */
  (define_insn "mshfhi_l_di"
    [(set (match_operand:DI 0 "arith_reg_dest" "=r")
! 	(ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
                               (const_int 32))
  		(and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
  			(const_int -4294967296))))]
***************
*** 9653,9663 ****
    [(set (match_operand:DI 0 "arith_reg_dest" "=r")
  	(ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
  			(const_int -4294967296))
! 		(lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
                               (const_int 32))))]
    "TARGET_SHMEDIA"
    "mshfhi.l	%N2, %N1, %0"
    [(set_attr "type" "arith_media")])

  (define_insn "mshflo_l_di"
    [(set (match_operand:DI 0 "arith_reg_dest" "=r")
--- 9651,9680 ----
    [(set (match_operand:DI 0 "arith_reg_dest" "=r")
  	(ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
  			(const_int -4294967296))
! 		(lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
                               (const_int 32))))]
    "TARGET_SHMEDIA"
    "mshfhi.l	%N2, %N1, %0"
    [(set_attr "type" "arith_media")])
+
+ (define_split
+   [(set (match_operand:DI 0 "arith_reg_dest" "")
+ 	(ior:DI (zero_extend:DI (match_operand:SI 1
+ 					      "extend_reg_or_0_operand" ""))
+ 		(and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
+ 			(const_int -4294967296))))
+    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
+   "TARGET_SHMEDIA"
+   [(const_int 0)]
+   "
+ {
+   emit_insn (gen_ashldi3_media (operands[3],
+ 				simplify_gen_subreg (DImode, operands[1],
+ 						     SImode, 0),
+ 				GEN_INT (32)));
+   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
+   DONE;
+ }")

  (define_insn "mshflo_l_di"
    [(set (match_operand:DI 0 "arith_reg_dest" "=r")

From-SVN: r55189
This commit is contained in:
J"orn Rennecke 2002-07-02 18:45:49 +00:00 committed by Joern Rennecke
parent d16ecaec1d
commit 52702ae16e
4 changed files with 80 additions and 41 deletions

View file

@ -1,3 +1,18 @@
Tue Jul 2 18:45:45 2002 J"orn Rennecke <joern.rennecke@superh.com>
* sh.c (print_operand, case 'N'): Allow zero vector.
(arith_reg_or_0_operand): Likewise.
(zero_vec_operand): Check for CONST_VECTOR, not PARALLEL.
* sh.h (CONST_COSTS): 0 has 0 cost. Check OUTER_CODE for
IOR, XOR, PLUS and SET and take their respective constant
ranges into account.
(PREDICATE_CODES, arith_reg_or_0_operand): Can be CONST_VECTOR.
* sh.md (subdi3, subdi3_media): Allow zero operand.
(movv8qi_i+3): Only vector that is not split is the zero vector.
Fix operand 3 to simplify_subreg.
(movv2si_i): Split alternative 1.
(mshfhi_l_di_rev+1): New splitter.
2002-07-02 Neil Booth <neil@daikokuya.co.uk>
* cppinit.c (cpp_handle_option): Suppress warnings with an

View file

@ -434,7 +434,8 @@ print_operand (stream, x, code)
break;
case 'N':
if (x == const0_rtx)
if (x == const0_rtx
|| (GET_CODE (x) == CONST_VECTOR && zero_vec_operand (x, VOIDmode)))
{
fprintf ((stream), "r63");
break;
@ -5940,7 +5941,7 @@ arith_reg_or_0_operand (op, mode)
if (arith_reg_operand (op, mode))
return 1;
if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_N (INTVAL (op)))
if (EXTRA_CONSTRAINT_U (op))
return 1;
return 0;
@ -6222,7 +6223,7 @@ zero_vec_operand (v, mode)
{
int i;
if (GET_CODE (v) != PARALLEL
if (GET_CODE (v) != CONST_VECTOR
|| (GET_MODE (v) != mode && mode != VOIDmode))
return 0;
for (i = XVECLEN (v, 0) - 1; i >= 0; i--)

View file

@ -2689,10 +2689,16 @@ while (0)
case CONST_INT: \
if (TARGET_SHMEDIA) \
{ \
if (INTVAL (RTX) == 0) \
return 0; \
if ((OUTER_CODE) == AND && and_operand ((RTX), DImode)) \
return 0; \
if (((OUTER_CODE) == IOR || (OUTER_CODE) == XOR \
|| (OUTER_CODE) == PLUS) \
&& CONST_OK_FOR_P (INTVAL (RTX))) \
return 0; \
if (CONST_OK_FOR_J (INTVAL (RTX))) \
return COSTS_N_INSNS (1); \
return COSTS_N_INSNS ((OUTER_CODE) != SET); \
else if (CONST_OK_FOR_J (INTVAL (RTX) >> 16)) \
return COSTS_N_INSNS (2); \
else if (CONST_OK_FOR_J ((INTVAL (RTX) >> 16) >> 16)) \
@ -3225,7 +3231,7 @@ extern int rtx_equal_function_value_matters;
{"arith_operand", {SUBREG, REG, CONST_INT}}, \
{"arith_reg_dest", {SUBREG, REG}}, \
{"arith_reg_operand", {SUBREG, REG}}, \
{"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
{"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_VECTOR}}, \
{"binary_float_operator", {PLUS, MULT}}, \
{"commutative_float_operator", {PLUS, MULT}}, \
{"extend_reg_operand", {SUBREG, REG, TRUNCATE}}, \

View file

@ -546,7 +546,7 @@
;; There is no way to model this with gcc's function units. This problem is
;; actually mentioned in md.texi. Tackling this problem requires first that
;; it is possible to speak about the target in an open discussion.
;;
;;
;; However, simple double-precision operations always conflict.
(define_function_unit "fp" 1 0
@ -1048,7 +1048,7 @@
"@
addz.l %1, %2, %0
addz.l %1, r63, %0")
(define_insn "adddi3_compact"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
(plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
@ -1122,7 +1122,7 @@
"@
add.l %1, %2, %0
addi.l %1, %2, %0")
(define_insn "*addsi3_compact"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
(plus:SI (match_operand:SI 1 "arith_operand" "%0")
@ -1138,25 +1138,26 @@
(define_expand "subdi3"
[(set (match_operand:DI 0 "arith_reg_operand" "")
(minus:DI (match_operand:DI 1 "arith_reg_operand" "")
(minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
(match_operand:DI 2 "arith_reg_operand" "")))]
""
"
{
if (TARGET_SH1)
{
operands[1] = force_reg (DImode, operands[1]);
emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
DONE;
}
}")
(define_insn "*subdi3_media"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
(minus:DI (match_operand:DI 1 "arith_reg_operand" "r")
(minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
(match_operand:DI 2 "arith_reg_operand" "r")))]
"TARGET_SHMEDIA"
"sub %1, %2, %0")
"sub %N1, %2, %0")
(define_insn "subdi3_compact"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
(minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
@ -1558,7 +1559,7 @@
: \"__sdivsi3\")));
if (TARGET_SHMEDIA)
last = gen_divsi3_i1_media (operands[0],
last = gen_divsi3_i1_media (operands[0],
Pmode == DImode
? operands[3]
: gen_rtx_SUBREG (DImode, operands[3],
@ -1771,7 +1772,7 @@
(sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
"TARGET_SHMEDIA"
"muls.l %1, %2, %0")
(define_insn "mulsidi3_compact"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
(mult:DI
@ -1841,7 +1842,7 @@
(zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
"TARGET_SHMEDIA"
"mulu.l %1, %2, %0")
(define_insn "umulsidi3_compact"
[(set (match_operand:DI 0 "arith_reg_operand" "=r")
(mult:DI
@ -3440,7 +3441,7 @@
(set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
;; If the output is a register and the input is memory or a register, we have
;; to be careful and see which word needs to be loaded first.
;; to be careful and see which word needs to be loaded first.
(define_split
[(set (match_operand:DI 0 "general_movdst_operand" "")
@ -4195,7 +4196,7 @@
}")
;; If the output is a register and the input is memory or a register, we have
;; to be careful and see which word needs to be loaded first.
;; to be careful and see which word needs to be loaded first.
(define_split
[(set (match_operand:DF 0 "general_movdst_operand" "")
@ -4392,7 +4393,7 @@
DONE;
}"
[(set_attr "length" "8")])
(define_expand "movv4sf"
[(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
(match_operand:V4SF 1 "nonimmediate_operand" "f,m,f"))]
@ -4444,7 +4445,7 @@
DONE;
}"
[(set_attr "length" "32")])
(define_expand "movv16sf"
[(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
(match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
@ -4499,7 +4500,7 @@
REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
REAL_VALUE_TO_TARGET_SINGLE (value, values);
operands[2] = GEN_INT (values);
operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
}")
@ -5410,7 +5411,7 @@
if (! SYMBOL_REF_FLAG (operands[0]))
{
rtx reg = gen_reg_rtx (Pmode);
emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
operands[0] = reg;
}
@ -5634,7 +5635,7 @@
if (! SYMBOL_REF_FLAG (operands[1]))
{
rtx reg = gen_reg_rtx (Pmode);
emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
operands[1] = reg;
}
@ -5841,7 +5842,7 @@
if (! SYMBOL_REF_FLAG (operands[0]))
{
rtx reg = gen_reg_rtx (Pmode);
/* We must not use GOTPLT for sibcalls, because PIC_REG
must be restored before the PLT code gets to run. */
emit_insn (gen_symGOT2reg (reg, operands[0]));
@ -6167,7 +6168,7 @@
(use (label_ref (match_operand 1 "" "")))]
"TARGET_SHMEDIA"
"blink %0, r63")
;; Call subroutine returning any type.
;; ??? This probably doesn't work.
@ -6284,7 +6285,7 @@
tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
insn = emit_move_insn (operands[0], tr);
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
REG_NOTES (insn));
@ -6370,10 +6371,10 @@
if (TARGET_SHMEDIA)
{
rtx reg = operands[2];
if (GET_MODE (reg) != DImode)
reg = gen_rtx_SUBREG (DImode, reg, 0);
if (flag_pic > 1)
emit_insn (gen_movdi_const_32bit (reg, operands[1]));
else
@ -6391,7 +6392,7 @@
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
0), 0, 0),
REG_NOTES (insn));
DONE;
}")
@ -7231,7 +7232,7 @@
(match_dup 2))))
(set (reg:SI T_REG)
(ne:SI (ior:SI (match_dup 1) (match_dup 2))
(const_int 0)))])]
(const_int 0)))])]
""
"
{
@ -7282,7 +7283,7 @@
(match_dup 2))))
(set (reg:SI T_REG)
(ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
(const_int 0)))])]
(const_int 0)))])]
"TARGET_SH1"
"operands[2] = gen_reg_rtx (SImode);")
@ -8279,7 +8280,7 @@
;; "#"
;; [(set_attr "length" "4")
;; (set_attr "fp_mode" "double")])
;;
;;
;; (define_split
;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
@ -8320,7 +8321,7 @@
"* return output_ieee_ccmpeq (insn, operands);"
[(set_attr "length" "4")
(set_attr "fp_mode" "double")])
(define_insn "cmpeqdf_media"
[(set (match_operand:DI 0 "register_operand" "=r")
(eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
@ -8806,10 +8807,7 @@
"TARGET_SHMEDIA && reload_completed
&& GET_MODE (operands[0]) == GET_MODE (operands[1])
&& VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
&& XVECEXP (operands[1], 0, 0) != const0_rtx
&& (HOST_BITS_PER_WIDE_INT >= 64
|| HOST_BITS_PER_WIDE_INT >= GET_MODE_BITSIZE (GET_MODE (operands[0]))
|| sh_1el_vec (operands[1], VOIDmode))"
&& ! zero_vec_operand (operands[1], VOIDmode)"
[(set (match_dup 0) (match_dup 1))]
"
{
@ -8819,7 +8817,7 @@
operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
operands[1]
= simplify_subreg (new_mode, operands[1], GET_MODE (operands[0]), 0);
= simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
}")
(define_expand "movv2hi"
@ -8878,7 +8876,7 @@
|| register_operand (operands[1], V2SImode))"
"@
add %1, r63, %0
movi %1, %0
#
#
ld%M1.q %m1, %0
st%M0.q %m0, %1"
@ -9641,7 +9639,7 @@
/* These are useful to expand ANDs and as combiner patterns. */
(define_insn "mshfhi_l_di"
[(set (match_operand:DI 0 "arith_reg_dest" "=r")
(ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
(ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
(const_int 32))
(and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
(const_int -4294967296))))]
@ -9653,12 +9651,31 @@
[(set (match_operand:DI 0 "arith_reg_dest" "=r")
(ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
(const_int -4294967296))
(lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
(lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
(const_int 32))))]
"TARGET_SHMEDIA"
"mshfhi.l %N2, %N1, %0"
[(set_attr "type" "arith_media")])
(define_split
[(set (match_operand:DI 0 "arith_reg_dest" "")
(ior:DI (zero_extend:DI (match_operand:SI 1
"extend_reg_or_0_operand" ""))
(and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
(const_int -4294967296))))
(clobber (match_operand:DI 3 "arith_reg_dest" ""))]
"TARGET_SHMEDIA"
[(const_int 0)]
"
{
emit_insn (gen_ashldi3_media (operands[3],
simplify_gen_subreg (DImode, operands[1],
SImode, 0),
GEN_INT (32)));
emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
DONE;
}")
(define_insn "mshflo_l_di"
[(set (match_operand:DI 0 "arith_reg_dest" "=r")
(ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")