From a512fa978e301b90b450b0f1372eb3015fae0e24 Mon Sep 17 00:00:00 2001 From: "J\"orn Rennecke" Date: Wed, 16 Feb 2000 00:59:17 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 14 ++++ gcc/config/sh/sh.md | 213 +++++++++++++++++++++++++++++++++++++--------------- 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 + + * 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 * 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 -- 2.7.4