pull across from the GCC3 tree:

>revision 1.2
>date: 2003/10/29 21:25:03;  author: mycroft;  state: Exp;  lines: +40 -11
>As seen on tech-toolchain:
>
>So the problem is thus:
>
>* The {u,}mulsidi3 generate two parallel sets which modify the upper and lower
>halves of the target register.
>
>* life_analysis() does not track subregister modifications -- if you don't
>modify the whole register with a single set, it considers the register
>unused.
>
>The simple, if klugy, solution to this is to stick an explicit clobber in.  It
>seems to work.
>
>While doing this, I noticed that constant folding was not happening for
>32x32->64 multiplies.  This is because the parallel set generated by
>{u,}mulsidi3 cannot be folded at all.  To solve this, I first expand to a
>normal multiply, and then use a define_insn_and_split to convert it to the
>parallel set after CSE and constant folding.
>
>This patch has also been submitted to GCC bugzilla, but who knows if I'll get
>a reply to that.
This commit is contained in:
mrg 2006-05-12 00:46:33 +00:00
parent 7e1fdc3c74
commit 43eb93d243

View File

@ -2492,11 +2492,29 @@
;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the
;; proper matching constraint. This is because the matching is between
;; the high-numbered word of the DImode operand[0] and operand[1].
;;
;; Note: life_analysis() does not keep track of the individual halves of the
;; DImode register. To prevent spurious liveness before the u?mulsidi3 insn
;; (which causes "uninitialized variable" warnings), we explicitly clobber
;; the DImode register.
(define_expand "umulsidi3"
[(parallel
[(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
(mult:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "register_operand" "")))
[(set (match_operand:DI 0 "register_operand" "")
(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
(zero_extend:DI (match_operand:SI 2 "register_operand" ""))))]
"TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"")
(define_insn_and_split "*umulsidi3_split"
[(set (match_operand:DI 0 "register_operand" "")
(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
(zero_extend:DI (match_operand:SI 2 "register_operand" ""))))]
"TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"#"
"TARGET_68020 && !TARGET_68060 && !TARGET_5200"
[(clobber (match_dup 0))
(parallel
[(set (subreg:SI (match_dup 0) 4)
(mult:SI (match_dup 1) (match_dup 2)))
(set (subreg:SI (match_dup 0) 0)
(truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
(zero_extend:DI (match_dup 2)))
@ -2507,7 +2525,7 @@
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=d")
(mult:SI (match_operand:SI 1 "register_operand" "%0")
(match_operand:SI 2 "nonimmediate_operand" "dm")))
(match_operand:SI 2 "nonimmediate_operand" "dm")))
(set (match_operand:SI 3 "register_operand" "=d")
(truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
(zero_extend:DI (match_dup 2)))
@ -2532,10 +2550,23 @@
"mulu%.l %2,%3:%0")
(define_expand "mulsidi3"
[(parallel
[(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
(mult:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "register_operand" "")))
[(set (match_operand:DI 0 "register_operand" "")
(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
(sign_extend:DI (match_operand:SI 2 "register_operand" ""))))]
"TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"")
(define_insn_and_split "*mulsidi3_split"
[(set (match_operand:DI 0 "register_operand" "")
(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
(sign_extend:DI (match_operand:SI 2 "register_operand" ""))))]
"TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"#"
"TARGET_68020 && !TARGET_68060 && !TARGET_5200"
[(clobber (match_dup 0))
(parallel
[(set (subreg:SI (match_dup 0) 4)
(mult:SI (match_dup 1) (match_dup 2)))
(set (subreg:SI (match_dup 0) 0)
(truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
(sign_extend:DI (match_dup 2)))