Commit d0ce2326 by Oleg Endo

sh.md (udivsi3, [...]): Simplify.

gcc/
	* config/sh/sh.md (udivsi3, divsi3, mulsi3): Simplify.
	(mulhisi3, umulhisi3, (smulsi3_highpart, umulsi3_highpart): Convert to
	define_insn_and_split.
	(mulsi3_i): New define_insn_and_split.
	(mulsi3_call): Convert to define_insn.
	(mulsidi3, mulsidi3_compact, umulsidi3, umulsidi3_compact):
	Remove constraints.

From-SVN: r235803
parent 1d793c34
2016-05-03 Oleg Endo <olegendo@gcc.gnu.org>
* config/sh/sh.md (udivsi3, divsi3, mulsi3): Simplify.
(mulhisi3, umulhisi3, (smulsi3_highpart, umulsi3_highpart): Convert to
define_insn_and_split.
(mulsi3_i): New define_insn_and_split.
(mulsi3_call): Convert to define_insn.
(mulsidi3, mulsidi3_compact, umulsidi3, umulsidi3_compact):
Remove constraints.
2016-05-02 Michael Meissner <meissner@linux.vnet.ibm.com> 2016-05-02 Michael Meissner <meissner@linux.vnet.ibm.com>
* machmode.h (mode_complex): Add support to give the complex mode * machmode.h (mode_complex): Add support to give the complex mode
......
...@@ -2244,16 +2244,9 @@ ...@@ -2244,16 +2244,9 @@
(define_expand "udivsi3" (define_expand "udivsi3"
[(set (match_dup 3) (symbol_ref:SI "__udivsi3")) [(set (match_operand:SI 0 "register_operand")
(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" "")) (udiv:SI (match_operand:SI 1 "general_operand")
(set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" "")) (match_operand:SI 2 "general_operand")))]
(parallel [(set (match_operand:SI 0 "register_operand" "")
(udiv:SI (reg:SI R4_REG)
(reg:SI R5_REG)))
(clobber (reg:SI T_REG))
(clobber (reg:SI PR_REG))
(clobber (reg:SI R4_REG))
(use (match_dup 3))])]
"" ""
{ {
rtx last; rtx last;
...@@ -2379,18 +2372,9 @@ ...@@ -2379,18 +2372,9 @@
(set_attr "needs_delay_slot" "yes")]) (set_attr "needs_delay_slot" "yes")])
(define_expand "divsi3" (define_expand "divsi3"
[(set (match_dup 3) (symbol_ref:SI "__sdivsi3")) [(set (match_operand:SI 0 "register_operand")
(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" "")) (div:SI (match_operand:SI 1 "general_operand")
(set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" "")) (match_operand:SI 2 "general_operand")))]
(parallel [(set (match_operand:SI 0 "register_operand" "")
(div:SI (reg:SI R4_REG)
(reg:SI R5_REG)))
(clobber (reg:SI T_REG))
(clobber (reg:SI PR_REG))
(clobber (reg:SI R1_REG))
(clobber (reg:SI R2_REG))
(clobber (reg:SI R3_REG))
(use (match_dup 3))])]
"" ""
{ {
rtx last; rtx last;
...@@ -2434,6 +2418,30 @@ ...@@ -2434,6 +2418,30 @@
;; Multiplication instructions ;; Multiplication instructions
;; ------------------------------------------------------------------------- ;; -------------------------------------------------------------------------
(define_insn_and_split "mulhisi3"
[(set (match_operand:SI 0 "arith_reg_dest")
(mult:SI (sign_extend:SI (match_operand:HI 1 "arith_reg_operand"))
(sign_extend:SI (match_operand:HI 2 "arith_reg_operand"))))
(clobber (reg:SI MACL_REG))]
"TARGET_SH1 && can_create_pseudo_p ()"
"#"
"&& 1"
[(set (reg:SI MACL_REG) (mult:SI (sign_extend:SI (match_dup 1))
(sign_extend:SI (match_dup 2))))
(set (match_dup 0) (reg:SI MACL_REG))])
(define_insn_and_split "umulhisi3"
[(set (match_operand:SI 0 "arith_reg_dest")
(mult:SI (zero_extend:SI (match_operand:HI 1 "arith_reg_operand"))
(zero_extend:SI (match_operand:HI 2 "arith_reg_operand"))))
(clobber (reg:SI MACL_REG))]
"TARGET_SH1 && can_create_pseudo_p ()"
"#"
"&& 1"
[(set (reg:SI MACL_REG) (mult:SI (zero_extend:SI (match_dup 1))
(zero_extend:SI (match_dup 2))))
(set (match_dup 0) (reg:SI MACL_REG))])
(define_insn "umulhisi3_i" (define_insn "umulhisi3_i"
[(set (reg:SI MACL_REG) [(set (reg:SI MACL_REG)
(mult:SI (zero_extend:SI (mult:SI (zero_extend:SI
...@@ -2454,69 +2462,10 @@ ...@@ -2454,69 +2462,10 @@
"muls.w %1,%0" "muls.w %1,%0"
[(set_attr "type" "smpy")]) [(set_attr "type" "smpy")])
(define_expand "mulhisi3"
[(set (reg:SI MACL_REG)
(mult:SI (sign_extend:SI
(match_operand:HI 1 "arith_reg_operand" ""))
(sign_extend:SI
(match_operand:HI 2 "arith_reg_operand" ""))))
(set (match_operand:SI 0 "arith_reg_operand" "")
(reg:SI MACL_REG))]
"TARGET_SH1"
{
rtx_insn *insn;
rtx macl;
macl = gen_rtx_REG (SImode, MACL_REG);
start_sequence ();
emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
insn = get_insns ();
end_sequence ();
/* expand_binop can't find a suitable code in umul_widen_optab to
make a REG_EQUAL note from, so make one here.
See also smulsi3_highpart.
??? Alternatively, we could put this at the calling site of expand_binop,
i.e. expand_expr. */
/* Use emit_libcall_block for loop invariant code motion and to make
a REG_EQUAL note. */
emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
DONE;
})
(define_expand "umulhisi3"
[(set (reg:SI MACL_REG)
(mult:SI (zero_extend:SI
(match_operand:HI 1 "arith_reg_operand" ""))
(zero_extend:SI
(match_operand:HI 2 "arith_reg_operand" ""))))
(set (match_operand:SI 0 "arith_reg_operand" "")
(reg:SI MACL_REG))]
"TARGET_SH1"
{
rtx_insn *insn;
rtx macl;
macl = gen_rtx_REG (SImode, MACL_REG);
start_sequence ();
emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
insn = get_insns ();
end_sequence ();
/* expand_binop can't find a suitable code in umul_widen_optab to
make a REG_EQUAL note from, so make one here.
See also smulsi3_highpart.
??? Alternatively, we could put this at the calling site of expand_binop,
i.e. expand_expr. */
/* Use emit_libcall_block for loop invariant code motion and to make
a REG_EQUAL note. */
emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
DONE;
})
;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
;; a call to a routine which clobbers known registers. ;; a call to a routine which clobbers known registers.
(define_insn "" (define_insn "mulsi3_call"
[(set (match_operand:SI 1 "register_operand" "=z") [(set (match_operand:SI 1 "register_operand" "=z")
(mult:SI (reg:SI R4_REG) (reg:SI R5_REG))) (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
(clobber (reg:SI MACL_REG)) (clobber (reg:SI MACL_REG))
...@@ -2531,22 +2480,6 @@ ...@@ -2531,22 +2480,6 @@
[(set_attr "type" "sfunc") [(set_attr "type" "sfunc")
(set_attr "needs_delay_slot" "yes")]) (set_attr "needs_delay_slot" "yes")])
(define_expand "mulsi3_call"
[(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
(set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
(parallel[(set (match_operand:SI 0 "register_operand" "")
(mult:SI (reg:SI R4_REG)
(reg:SI R5_REG)))
(clobber (reg:SI MACL_REG))
(clobber (reg:SI T_REG))
(clobber (reg:SI PR_REG))
(clobber (reg:SI R3_REG))
(clobber (reg:SI R2_REG))
(clobber (reg:SI R1_REG))
(use (match_operand:SI 3 "register_operand" ""))])]
"TARGET_SH1"
"")
(define_insn "mul_r" (define_insn "mul_r"
[(set (match_operand:SI 0 "arith_reg_dest" "=r") [(set (match_operand:SI 0 "arith_reg_dest" "=r")
(mult:SI (match_operand:SI 1 "arith_reg_operand" "0") (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
...@@ -2563,33 +2496,44 @@ ...@@ -2563,33 +2496,44 @@
"mul.l %1,%0" "mul.l %1,%0"
[(set_attr "type" "dmpy")]) [(set_attr "type" "dmpy")])
(define_insn_and_split "mulsi3_i"
[(set (match_operand:SI 0 "arith_reg_dest")
(mult:SI (match_operand:SI 1 "arith_reg_operand")
(match_operand:SI 2 "arith_reg_operand")))
(clobber (reg:SI MACL_REG))]
"TARGET_SH2 && can_create_pseudo_p ()"
"#"
"&& 1"
[(set (reg:SI MACL_REG) (mult:SI (match_dup 1) (match_dup 2)))
(set (match_dup 0) (reg:SI MACL_REG))])
(define_expand "mulsi3" (define_expand "mulsi3"
[(set (reg:SI MACL_REG) [(set (match_operand:SI 0 "arith_reg_dest")
(mult:SI (match_operand:SI 1 "arith_reg_operand" "") (mult:SI (match_operand:SI 1 "arith_reg_operand")
(match_operand:SI 2 "arith_reg_operand" ""))) (match_operand:SI 2 "arith_reg_operand")))]
(set (match_operand:SI 0 "arith_reg_operand" "")
(reg:SI MACL_REG))]
"TARGET_SH1" "TARGET_SH1"
{ {
if (!TARGET_SH2) if (!TARGET_SH2)
{ {
/* The address must be set outside the libcall, emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
since it goes into a pseudo. */ emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC).sym; rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC).sym;
rtx addr = force_reg (SImode, sym);
rtx insns = gen_mulsi3_call (operands[0], operands[1], emit_insn (gen_mulsi3_call (force_reg (SImode, sym), operands[0]));
operands[2], addr);
emit_insn (insns);
} }
else else
{ {
rtx macl = gen_rtx_REG (SImode, MACL_REG); /* FIXME: For some reason, expanding the mul_l insn and the macl store
insn early gives slightly better code. In particular it prevents
the decrement-test loop type to be used in some cases which saves
one multiplication in the loop setup code.
emit_insn (gen_mulsi3_i (operands[0], operands[1], operands[2]));
*/
emit_insn (gen_mul_l (operands[1], operands[2])); emit_insn (gen_mul_l (operands[1], operands[2]));
/* consec_sets_giv can only recognize the first insn that sets a emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
giv as the giv insn. So we must tag this also with a REG_EQUAL
note. */
emit_insn (gen_movsi_i ((operands[0]), macl));
} }
DONE; DONE;
}) })
...@@ -2610,9 +2554,9 @@ ...@@ -2610,9 +2554,9 @@
[(set_attr "type" "dmpy")]) [(set_attr "type" "dmpy")])
(define_expand "mulsidi3" (define_expand "mulsidi3"
[(set (match_operand:DI 0 "arith_reg_dest" "") [(set (match_operand:DI 0 "arith_reg_dest")
(mult:DI (sign_extend:DI (match_operand:SI 1 "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" ""))))] (sign_extend:DI (match_operand:SI 2 "arith_reg_operand"))))]
"TARGET_SH2" "TARGET_SH2"
{ {
emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2])); emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2]));
...@@ -2620,13 +2564,12 @@ ...@@ -2620,13 +2564,12 @@
}) })
(define_insn_and_split "mulsidi3_compact" (define_insn_and_split "mulsidi3_compact"
[(set (match_operand:DI 0 "arith_reg_dest" "=r") [(set (match_operand:DI 0 "arith_reg_dest")
(mult:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand"))
(sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) (sign_extend:DI (match_operand:SI 2 "arith_reg_operand"))))
(sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
(clobber (reg:SI MACH_REG)) (clobber (reg:SI MACH_REG))
(clobber (reg:SI MACL_REG))] (clobber (reg:SI MACL_REG))]
"TARGET_SH2" "TARGET_SH2 && can_create_pseudo_p ()"
"#" "#"
"&& 1" "&& 1"
[(const_int 0)] [(const_int 0)]
...@@ -2659,9 +2602,9 @@ ...@@ -2659,9 +2602,9 @@
[(set_attr "type" "dmpy")]) [(set_attr "type" "dmpy")])
(define_expand "umulsidi3" (define_expand "umulsidi3"
[(set (match_operand:DI 0 "arith_reg_dest" "") [(set (match_operand:DI 0 "arith_reg_dest")
(mult:DI (zero_extend:DI (match_operand:SI 1 "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" ""))))] (zero_extend:DI (match_operand:SI 2 "arith_reg_operand"))))]
"TARGET_SH2" "TARGET_SH2"
{ {
emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2])); emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2]));
...@@ -2669,13 +2612,12 @@ ...@@ -2669,13 +2612,12 @@
}) })
(define_insn_and_split "umulsidi3_compact" (define_insn_and_split "umulsidi3_compact"
[(set (match_operand:DI 0 "arith_reg_dest" "=r") [(set (match_operand:DI 0 "arith_reg_dest")
(mult:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand"))
(zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) (zero_extend:DI (match_operand:SI 2 "arith_reg_operand"))))
(zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
(clobber (reg:SI MACH_REG)) (clobber (reg:SI MACH_REG))
(clobber (reg:SI MACL_REG))] (clobber (reg:SI MACL_REG))]
"TARGET_SH2" "TARGET_SH2 && can_create_pseudo_p ()"
"#" "#"
"&& 1" "&& 1"
[(const_int 0)] [(const_int 0)]
...@@ -2705,38 +2647,23 @@ ...@@ -2705,38 +2647,23 @@
"dmuls.l %1,%0" "dmuls.l %1,%0"
[(set_attr "type" "dmpy")]) [(set_attr "type" "dmpy")])
(define_expand "smulsi3_highpart" (define_insn_and_split "smulsi3_highpart"
[(parallel [(set (match_operand:SI 0 "arith_reg_dest")
[(set (reg:SI MACH_REG) (truncate:SI
(truncate:SI (lshiftrt:DI
(lshiftrt:DI
(mult:DI (mult:DI
(sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "")) (sign_extend:DI (match_operand:SI 1 "arith_reg_operand"))
(sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))) (sign_extend:DI (match_operand:SI 2 "arith_reg_operand")))
(const_int 32)))) (const_int 32))))
(clobber (reg:SI MACL_REG))]) (clobber (reg:SI MACL_REG))
(set (match_operand:SI 0 "arith_reg_operand" "") (clobber (reg:SI MACH_REG))]
(reg:SI MACH_REG))] "TARGET_SH2 && can_create_pseudo_p ()"
"TARGET_SH2" "#"
"&& 1"
[(const_int 0)]
{ {
rtx_insn *insn;
rtx mach;
mach = gen_rtx_REG (SImode, MACH_REG);
start_sequence ();
emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2])); emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
insn = get_insns (); emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
end_sequence ();
/* expand_binop can't find a suitable code in mul_highpart_optab to
make a REG_EQUAL note from, so make one here.
See also {,u}mulhisi.
??? Alternatively, we could put this at the calling site of expand_binop,
i.e. expand_mult_highpart. */
/* Use emit_libcall_block for loop invariant code motion and to make
a REG_EQUAL note. */
emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
DONE;
}) })
(define_insn "umulsi3_highpart_i" (define_insn "umulsi3_highpart_i"
...@@ -2752,33 +2679,22 @@ ...@@ -2752,33 +2679,22 @@
"dmulu.l %1,%0" "dmulu.l %1,%0"
[(set_attr "type" "dmpy")]) [(set_attr "type" "dmpy")])
(define_expand "umulsi3_highpart" (define_insn_and_split "umulsi3_highpart"
[(parallel [(set (match_operand:SI 0 "arith_reg_dest")
[(set (reg:SI MACH_REG) (truncate:SI
(truncate:SI (lshiftrt:DI
(lshiftrt:DI
(mult:DI (mult:DI
(zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "")) (zero_extend:DI (match_operand:SI 1 "arith_reg_operand"))
(zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))) (zero_extend:DI (match_operand:SI 2 "arith_reg_operand")))
(const_int 32)))) (const_int 32))))
(clobber (reg:SI MACL_REG))]) (clobber (reg:SI MACL_REG))]
(set (match_operand:SI 0 "arith_reg_operand" "") "TARGET_SH2 && can_create_pseudo_p ()"
(reg:SI MACH_REG))] "#"
"TARGET_SH2" "&& 1"
[(const_int 0)]
{ {
rtx_insn *insn;
rtx mach;
mach = gen_rtx_REG (SImode, MACH_REG);
start_sequence ();
emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2])); emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
insn = get_insns (); emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
end_sequence ();
/* Use emit_libcall_block for loop invariant code motion and to make
a REG_EQUAL note. */
emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
DONE;
}) })
;; ------------------------------------------------------------------------- ;; -------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment