aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/sh/sh.c7
-rw-r--r--gcc/config/sh/sh.h10
-rw-r--r--gcc/config/sh/sh.md89
4 files changed, 80 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 654fd39..e7a81de 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 6ab45d2..1acdc96 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -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--)
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index abf9945..1a25849 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -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}}, \
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 8303c96..4265de2 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -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")