This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]