aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJ"orn Rennecke <amylaar@cygnus.co.uk>2000-02-16 00:59:17 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2000-02-16 00:59:17 +0000
commita512fa978e301b90b450b0f1372eb3015fae0e24 (patch)
treed0e1afd85805618db1aa4741db829f2fb65e7afd /gcc
parent73d7c68909ac0094a2ab30f1f8dad3eac59c36ac (diff)
downloadgcc-a512fa978e301b90b450b0f1372eb3015fae0e24.zip
gcc-a512fa978e301b90b450b0f1372eb3015fae0e24.tar.gz
gcc-a512fa978e301b90b450b0f1372eb3015fae0e24.tar.bz2
sh.md (udivsi3_i1, [...]): Name.
* sh.md (udivsi3_i1, divsi3_i1, umulhisi3_i, mulhisi3_i): Name. (smulsi3_highpart_i): Name. (udivsi3): Wrap emitted insns in REG_LIBCALL / REG_RETVAL notes. (divsi3, mulhisi3, umulhisi3, mulsidi3, umulsidi3): Likewise. (smulsi3_highpart, umulsi3_highpart): Likewise. (mulsidi3_i, umulsidi3_i): Make rtl describe operation correctly independent of endianness. (mulsidi3, umulsidi3): Now define_insn. Hide details that confuse the optimizers. (mulsidi3+1, umulsidi3+1): New define_split. From-SVN: r31997
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/sh/sh.md213
2 files changed, 165 insertions, 62 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2638364..a9ad434 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+Wed Feb 16 00:58:06 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.md (udivsi3_i1, divsi3_i1, umulhisi3_i, mulhisi3_i): Name.
+ (smulsi3_highpart_i): Name.
+ (udivsi3): Wrap emitted insns in REG_LIBCALL / REG_RETVAL notes.
+ (divsi3, mulhisi3, umulhisi3, mulsidi3, umulsidi3): Likewise.
+ (smulsi3_highpart, umulsi3_highpart): Likewise.
+
+ (mulsidi3_i, umulsidi3_i): Make rtl describe operation
+ correctly independent of endianness.
+ (mulsidi3, umulsidi3): Now define_insn. Hide details that
+ confuse the optimizers.
+ (mulsidi3+1, umulsidi3+1): New define_split.
+
Tue Feb 15 23:22:26 2000 Andrew Haley <aph@cygnus.com>
* config/sh/sh.md: Guard insn splits against illegal registers.
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 61720e0..3a662cd 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -868,7 +868,7 @@
;; This reload would clobber the value in r0 we are trying to store.
;; If we let reload allocate r0, then this problem can never happen.
-(define_insn ""
+(define_insn "udivsi3_i1"
[(set (match_operand:SI 0 "register_operand" "=z")
(udiv:SI (reg:SI 4) (reg:SI 5)))
(clobber (reg:SI 18))
@@ -917,9 +917,9 @@
(set_attr "needs_delay_slot" "yes")])
(define_expand "udivsi3"
- [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
+ [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
+ (set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
(set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
- (set (match_dup 3) (symbol_ref:SI "__udivsi3"))
(parallel [(set (match_operand:SI 0 "register_operand" "")
(udiv:SI (reg:SI 4)
(reg:SI 5)))
@@ -930,22 +930,36 @@
""
"
{
+ rtx first, last;
+
operands[3] = gen_reg_rtx(SImode);
+ /* Emit the move of the address to a pseudo outside of the libcall. */
if (TARGET_HARD_SH4)
{
- emit_move_insn (gen_rtx (REG, SImode, 4), operands[1]);
- emit_move_insn (gen_rtx (REG, SImode, 5), operands[2]);
emit_move_insn (operands[3],
gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
if (TARGET_FPU_SINGLE)
- emit_insn (gen_udivsi3_i4_single (operands[0], operands[3]));
+ last = gen_udivsi3_i4_single (operands[0], operands[3]);
else
- emit_insn (gen_udivsi3_i4 (operands[0], operands[3]));
- DONE;
+ last = gen_udivsi3_i4 (operands[0], operands[3]);
+ }
+ else
+ {
+ emit_move_insn (operands[3],
+ gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
+ last = gen_udivsi3_i1 (operands[0], operands[3]);
}
+ first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
+ emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
+ last = emit_insn (last);
+ /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
+ invariant code motion can move it. */
+ REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
+ REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+ DONE;
}")
-(define_insn ""
+(define_insn "divsi3_i1"
[(set (match_operand:SI 0 "register_operand" "=z")
(div:SI (reg:SI 4) (reg:SI 5)))
(clobber (reg:SI 18))
@@ -987,9 +1001,9 @@
(set_attr "needs_delay_slot" "yes")])
(define_expand "divsi3"
- [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
+ [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
+ (set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
(set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
- (set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
(parallel [(set (match_operand:SI 0 "register_operand" "")
(div:SI (reg:SI 4)
(reg:SI 5)))
@@ -1002,26 +1016,39 @@
""
"
{
+ rtx first, last;
+
operands[3] = gen_reg_rtx(SImode);
+ /* Emit the move of the address to a pseudo outside of the libcall. */
if (TARGET_HARD_SH4)
{
- emit_move_insn (gen_rtx (REG, SImode, 4), operands[1]);
- emit_move_insn (gen_rtx (REG, SImode, 5), operands[2]);
emit_move_insn (operands[3],
gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
if (TARGET_FPU_SINGLE)
- emit_insn (gen_divsi3_i4_single (operands[0], operands[3]));
+ last = gen_divsi3_i4_single (operands[0], operands[3]);
else
- emit_insn (gen_divsi3_i4 (operands[0], operands[3]));
- DONE;
+ last = gen_divsi3_i4 (operands[0], operands[3]);
}
+ else
+ {
+ emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
+ last = gen_divsi3_i1 (operands[0], operands[3]);
+ }
+ first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
+ emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
+ last = emit_insn (last);
+ /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
+ invariant code motion can move it. */
+ REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
+ REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+ DONE;
}")
;; -------------------------------------------------------------------------
;; Multiplication instructions
;; -------------------------------------------------------------------------
-(define_insn ""
+(define_insn "umulhisi3_i"
[(set (reg:SI 21)
(mult:SI (zero_extend:SI (match_operand:HI 0 "arith_reg_operand" "r"))
(zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r"))))]
@@ -1029,7 +1056,7 @@
"mulu %1,%0"
[(set_attr "type" "smpy")])
-(define_insn ""
+(define_insn "mulhisi3_i"
[(set (reg:SI 21)
(mult:SI (sign_extend:SI
(match_operand:HI 0 "arith_reg_operand" "r"))
@@ -1048,7 +1075,18 @@
(set (match_operand:SI 0 "arith_reg_operand" "")
(reg:SI 21))]
""
- "")
+ "
+{
+ rtx first, last;
+
+ first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
+ last = emit_move_insn (operands[0], gen_rtx_REG (SImode, 21));
+ /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
+ invariant code motion can move it. */
+ REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
+ REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+ DONE;
+}")
(define_expand "umulhisi3"
[(set (reg:SI 21)
@@ -1059,7 +1097,18 @@
(set (match_operand:SI 0 "arith_reg_operand" "")
(reg:SI 21))]
""
- "")
+ "
+{
+ rtx first, last;
+
+ first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
+ last = emit_move_insn (operands[0], gen_rtx_REG (SImode, 21));
+ /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
+ invariant code motion can move it. */
+ REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
+ REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+ DONE;
+}")
;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
;; a call to a routine which clobbers known registers.
@@ -1142,72 +1191,90 @@
}")
(define_insn "mulsidi3_i"
- [(set (reg:DI 20)
- (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
- (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))))]
+ [(set (reg:SI 20)
+ (truncate:SI
+ (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
+ (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
+ (const_int 32))))
+ (set (reg:SI 21)
+ (mult:SI (match_dup 0)
+ (match_dup 1)))]
"TARGET_SH2"
"dmuls.l %1,%0"
[(set_attr "type" "dmpy")])
-(define_expand "mulsidi3"
- [(set (reg:DI 20)
+(define_insn "mulsidi3"
+ [(set (match_operand:DI 0 "arith_reg_operand" "=r")
+ (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
+ (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
+ (clobber (reg:DI 20))]
+ "TARGET_SH2"
+ "#")
+
+(define_split
+ [(set (match_operand:DI 0 "arith_reg_operand" "")
(mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
(sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
- (set (match_operand:DI 0 "arith_reg_operand" "")
- (reg:DI 20))]
+ (clobber (reg:DI 20))]
"TARGET_SH2"
+ [(const_int 0)]
"
{
- /* We must swap the two words when copying them from MACH/MACL to the
- output register. */
- if (TARGET_LITTLE_ENDIAN)
- {
- rtx low_dst = operand_subword (operands[0], 0, 1, DImode);
- rtx high_dst = operand_subword (operands[0], 1, 1, DImode);
+ rtx low_dst = gen_lowpart (SImode, operands[0]);
+ rtx high_dst = gen_highpart (SImode, operands[0]);
- emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
+ emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
- emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
- emit_move_insn (low_dst, gen_rtx_REG (SImode, 21));
- emit_move_insn (high_dst, gen_rtx_REG (SImode, 20));
- DONE;
- }
+ emit_move_insn (low_dst, gen_rtx_REG (SImode, 21));
+ emit_move_insn (high_dst, gen_rtx_REG (SImode, 20));
+ /* We need something to tag the possible REG_EQUAL notes on to. */
+ emit_move_insn (operands[0], operands[0]);
+ DONE;
}")
(define_insn "umulsidi3_i"
- [(set (reg:DI 20)
- (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
- (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))))]
+ [(set (reg:SI 20)
+ (truncate:SI
+ (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
+ (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
+ (const_int 32))))
+ (set (reg:SI 21)
+ (mult:SI (match_dup 0)
+ (match_dup 1)))]
"TARGET_SH2"
"dmulu.l %1,%0"
[(set_attr "type" "dmpy")])
-(define_expand "umulsidi3"
- [(set (reg:DI 20)
+(define_insn "umulsidi3"
+ [(set (match_operand:DI 0 "arith_reg_operand" "=r")
+ (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
+ (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
+ (clobber (reg:DI 20))]
+ "TARGET_SH2"
+ "#")
+
+(define_split
+ [(set (match_operand:DI 0 "arith_reg_operand" "")
(mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
(zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
- (set (match_operand:DI 0 "arith_reg_operand" "")
- (reg:DI 20))]
+ (clobber (reg:DI 20))]
"TARGET_SH2"
+ [(const_int 0)]
"
{
- /* We must swap the two words when copying them from MACH/MACL to the
- output register. */
- if (TARGET_LITTLE_ENDIAN)
- {
- rtx low_dst = operand_subword (operands[0], 0, 1, DImode);
- rtx high_dst = operand_subword (operands[0], 1, 1, DImode);
+ rtx low_dst = gen_lowpart (SImode, operands[0]);
+ rtx high_dst = gen_highpart (SImode, operands[0]);
- emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
+ emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
- emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
- emit_move_insn (low_dst, gen_rtx_REG (SImode, 21));
- emit_move_insn (high_dst, gen_rtx_REG (SImode, 20));
- DONE;
- }
+ emit_move_insn (low_dst, gen_rtx_REG (SImode, 21));
+ emit_move_insn (high_dst, gen_rtx_REG (SImode, 20));
+ /* We need something to tag the possible REG_EQUAL notes on to. */
+ emit_move_insn (operands[0], operands[0]);
+ DONE;
}")
-(define_insn ""
+(define_insn "smulsi3_highpart_i"
[(set (reg:SI 20)
(truncate:SI
(lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
@@ -1228,9 +1295,20 @@
(set (match_operand:SI 0 "arith_reg_operand" "")
(reg:SI 20))]
"TARGET_SH2"
- "")
+ "
+{
+ rtx first, last;
-(define_insn ""
+ first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
+ last = emit_move_insn (operands[0], gen_rtx_REG (SImode, 20));
+ /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
+ invariant code motion can move it. */
+ REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
+ REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+ DONE;
+}")
+
+(define_insn "umulsi3_highpart_i"
[(set (reg:SI 20)
(truncate:SI
(lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
@@ -1251,7 +1329,18 @@
(set (match_operand:SI 0 "arith_reg_operand" "")
(reg:SI 20))]
"TARGET_SH2"
- "")
+ "
+{
+ rtx first, last;
+
+ first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
+ last = emit_move_insn (operands[0], gen_rtx_REG (SImode, 20));
+ /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
+ invariant code motion can move it. */
+ REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
+ REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
+ DONE;
+}")
;; -------------------------------------------------------------------------
;; Logical operations