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:
parent
7e1fdc3c74
commit
43eb93d243
49
gnu/dist/gcc4/gcc/config/m68k/m68k.md
vendored
49
gnu/dist/gcc4/gcc/config/m68k/m68k.md
vendored
@ -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)))
|
||||
|
Loading…
Reference in New Issue
Block a user