This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
S/390: Improve handling of mult and div
- From: "Ulrich Weigand" <weigand at i1 dot informatik dot uni-erlangen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 29 Aug 2003 02:42:07 +0200 (CEST)
- Subject: S/390: Improve handling of mult and div
Hello,
this patch improves the handling of mult and div by:
- using mixed-mode matching constraints where appropriate
(now that those actually work!) to simplify the md file
as well as the generated code
- adding support for the ML(R) and DL(R) insns in 31-bit
on z900 and above
- adding support for MH (which was simply missing ...)
Bootstrapped/regtested on s390-ibm-linux, s390x-ibm-linux,
and s390-ibm-linux --with-arch=z900.
Bye,
Ulrich
ChangeLog:
* config/s390/s390.md ("*mulsi3_sign"): New insn.
("mulsidi3" expander, "mulsi_6432" insn): Remove, replace by ...
("mulsidi3"): ... this new insn.
("umulsidi3"): New insn.
("divmoddi3", "divmodtidi3", "divmodtisi3"): Simplify by using
mixed-mode matching constraints.
("udivmodsi4", "udivmoddisi3"): New insns.
("udivsi3", "umodsi3"): Use only in ESA/390 mode.
Index: gcc/config/s390/s390.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.md,v
retrieving revision 1.74
diff -c -p -r1.74 s390.md
*** gcc/config/s390/s390.md 28 Aug 2003 12:28:40 -0000 1.74
--- gcc/config/s390/s390.md 28 Aug 2003 23:44:45 -0000
***************
*** 4023,4029 ****
[(set_attr "op_type" "RRE,RXY")
(set_attr "type" "imul")])
-
(define_insn "muldi3"
[(set (match_operand:DI 0 "register_operand" "=d,d,d")
(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
--- 4023,4028 ----
***************
*** 4040,4045 ****
--- 4039,4053 ----
; mulsi3 instruction pattern(s).
;
+ (define_insn "*mulsi3_sign"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R"))
+ (match_operand:SI 1 "register_operand" "0")))]
+ ""
+ "mh\t%0,%2"
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "imul")])
+
(define_insn "mulsi3"
[(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
***************
*** 4057,4093 ****
; mulsidi3 instruction pattern(s).
;
! (define_expand "mulsidi3"
! [(set (match_operand:DI 0 "register_operand" "")
! (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" ""))
! (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" ""))))]
"!TARGET_64BIT"
! {
! rtx insn;
!
! emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
! insn = emit_insn (gen_mulsi_6432 (operands[0], operands[0], operands[2]));
! REG_NOTES (insn) =
! gen_rtx_EXPR_LIST (REG_EQUAL,
! gen_rtx_MULT (DImode,
! gen_rtx_SIGN_EXTEND (DImode, operands[1]),
! gen_rtx_SIGN_EXTEND (DImode, operands[2])),
! REG_NOTES (insn));
! DONE;
! })
! (define_insn "mulsi_6432"
! [(set (match_operand:DI 0 "register_operand" "=d,d")
! (mult:DI (sign_extend:DI
! (truncate:SI (match_operand:DI 1 "register_operand" "0,0")))
! (sign_extend:DI
! (match_operand:SI 2 "nonimmediate_operand" "d,R"))))]
! "!TARGET_64BIT"
! "@
! mr\t%0,%2
! m\t%0,%2"
! [(set_attr "op_type" "RR,RX")
(set_attr "type" "imul")])
;
--- 4065,4098 ----
; mulsidi3 instruction pattern(s).
;
! (define_insn "mulsidi3"
! [(set (match_operand:DI 0 "register_operand" "=d,d")
! (mult:DI (sign_extend:DI
! (match_operand:SI 1 "register_operand" "%0,0"))
! (sign_extend:DI
! (match_operand:SI 2 "nonimmediate_operand" "d,R"))))]
"!TARGET_64BIT"
! "@
! mr\t%0,%2
! m\t%0,%2"
! [(set_attr "op_type" "RR,RX")
! (set_attr "type" "imul")])
! ;
! ; umulsidi3 instruction pattern(s).
! ;
! (define_insn "umulsidi3"
! [(set (match_operand:DI 0 "register_operand" "=d,d")
! (mult:DI (zero_extend:DI
! (match_operand:SI 1 "register_operand" "%0,0"))
! (zero_extend:DI
! (match_operand:SI 2 "nonimmediate_operand" "d,m"))))]
! "!TARGET_64BIT && TARGET_CPU_ZARCH"
! "@
! mlr\t%0,%2
! ml\t%0,%2"
! [(set_attr "op_type" "RRE,RXY")
(set_attr "type" "imul")])
;
***************
*** 4222,4251 ****
(define_expand "divmoddi4"
[(parallel [(set (match_operand:DI 0 "general_operand" "")
! (div:DI (match_operand:DI 1 "general_operand" "")
(match_operand:DI 2 "general_operand" "")))
(set (match_operand:DI 3 "general_operand" "")
(mod:DI (match_dup 1) (match_dup 2)))])
(clobber (match_dup 4))]
"TARGET_64BIT"
{
! rtx insn, div_equal, mod_equal, equal;
div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
- equal = gen_rtx_IOR (TImode,
- gen_rtx_ZERO_EXTEND (TImode, div_equal),
- gen_rtx_ASHIFT (TImode,
- gen_rtx_ZERO_EXTEND (TImode, mod_equal),
- GEN_INT (64)));
operands[4] = gen_reg_rtx(TImode);
! emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
! emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
! emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
! insn = emit_insn (gen_divmodtidi3 (operands[4], operands[4], operands[2]));
! REG_NOTES (insn) =
! gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
REG_NOTES (insn) =
--- 4227,4246 ----
(define_expand "divmoddi4"
[(parallel [(set (match_operand:DI 0 "general_operand" "")
! (div:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "general_operand" "")))
(set (match_operand:DI 3 "general_operand" "")
(mod:DI (match_dup 1) (match_dup 2)))])
(clobber (match_dup 4))]
"TARGET_64BIT"
{
! rtx insn, div_equal, mod_equal;
div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
operands[4] = gen_reg_rtx(TImode);
! emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
REG_NOTES (insn) =
***************
*** 4262,4272 ****
[(set (match_operand:TI 0 "register_operand" "=d,d")
(ior:TI
(zero_extend:TI
! (div:DI (truncate:DI (match_operand:TI 1 "register_operand" "0,0"))
(match_operand:DI 2 "general_operand" "d,m")))
(ashift:TI
(zero_extend:TI
! (mod:DI (truncate:DI (match_dup 1))
(match_dup 2)))
(const_int 64))))]
"TARGET_64BIT"
--- 4257,4267 ----
[(set (match_operand:TI 0 "register_operand" "=d,d")
(ior:TI
(zero_extend:TI
! (div:DI (match_operand:DI 1 "register_operand" "0,0")
(match_operand:DI 2 "general_operand" "d,m")))
(ashift:TI
(zero_extend:TI
! (mod:DI (match_dup 1)
(match_dup 2)))
(const_int 64))))]
"TARGET_64BIT"
***************
*** 4280,4290 ****
[(set (match_operand:TI 0 "register_operand" "=d,d")
(ior:TI
(zero_extend:TI
! (div:DI (truncate:DI (match_operand:TI 1 "register_operand" "0,0"))
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "d,m"))))
(ashift:TI
(zero_extend:TI
! (mod:DI (truncate:DI (match_dup 1))
(sign_extend:DI (match_dup 2))))
(const_int 64))))]
"TARGET_64BIT"
--- 4275,4285 ----
[(set (match_operand:TI 0 "register_operand" "=d,d")
(ior:TI
(zero_extend:TI
! (div:DI (match_operand:DI 1 "register_operand" "0,0")
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "d,m"))))
(ashift:TI
(zero_extend:TI
! (mod:DI (match_dup 1)
(sign_extend:DI (match_dup 2))))
(const_int 64))))]
"TARGET_64BIT"
***************
*** 4418,4430 ****
; udivsi3 and umodsi3 instruction pattern(s).
;
(define_expand "udivsi3"
[(set (match_operand:SI 0 "register_operand" "=d")
(udiv:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))
(clobber (match_dup 3))]
! "!TARGET_64BIT"
{
rtx insn, udiv_equal, umod_equal, equal;
--- 4413,4481 ----
; udivsi3 and umodsi3 instruction pattern(s).
;
+ (define_expand "udivmodsi4"
+ [(parallel [(set (match_operand:SI 0 "general_operand" "")
+ (udiv:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "nonimmediate_operand" "")))
+ (set (match_operand:SI 3 "general_operand" "")
+ (umod:SI (match_dup 1) (match_dup 2)))])
+ (clobber (match_dup 4))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ {
+ rtx insn, div_equal, mod_equal, equal;
+
+ div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
+ mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
+ equal = gen_rtx_IOR (DImode,
+ gen_rtx_ZERO_EXTEND (DImode, div_equal),
+ gen_rtx_ASHIFT (DImode,
+ gen_rtx_ZERO_EXTEND (DImode, mod_equal),
+ GEN_INT (32)));
+
+ operands[4] = gen_reg_rtx(DImode);
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
+ emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
+ emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
+ insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
+
+ DONE;
+ })
+
+ (define_insn "udivmoddisi3"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (ior:DI (zero_extend:DI
+ (truncate:SI
+ (udiv:DI (match_operand:DI 1 "register_operand" "0,0")
+ (zero_extend:DI
+ (match_operand:SI 2 "nonimmediate_operand" "d,m")))))
+ (ashift:DI
+ (zero_extend:DI
+ (truncate:SI
+ (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
+ (const_int 32))))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ "@
+ dlr\t%0,%2
+ dl\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")
+ (set_attr "type" "idiv")])
(define_expand "udivsi3"
[(set (match_operand:SI 0 "register_operand" "=d")
(udiv:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))
(clobber (match_dup 3))]
! "!TARGET_64BIT && !TARGET_CPU_ZARCH"
{
rtx insn, udiv_equal, umod_equal, equal;
***************
*** 4515,4521 ****
(umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
(match_operand:SI 2 "nonimmediate_operand" "")))
(clobber (match_dup 3))]
! "!TARGET_64BIT"
{
rtx insn, udiv_equal, umod_equal, equal;
--- 4566,4572 ----
(umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
(match_operand:SI 2 "nonimmediate_operand" "")))
(clobber (match_dup 3))]
! "!TARGET_64BIT && !TARGET_CPU_ZARCH"
{
rtx insn, udiv_equal, umod_equal, equal;
--
Dr. Ulrich Weigand
weigand@informatik.uni-erlangen.de