diff options
author | Jim Wilson <wilson@gcc.gnu.org> | 1994-12-28 18:46:10 -0800 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1994-12-28 18:46:10 -0800 |
commit | a67f7692fff13fd2d1ac6ed819692e01348aae4a (patch) | |
tree | bc35620b69fb3ac009dd873c97da01a2339c94a6 /gcc | |
parent | 8c2977e27dc94cd658658ca9bc48875019c434fc (diff) | |
download | gcc-a67f7692fff13fd2d1ac6ed819692e01348aae4a.zip gcc-a67f7692fff13fd2d1ac6ed819692e01348aae4a.tar.gz gcc-a67f7692fff13fd2d1ac6ed819692e01348aae4a.tar.bz2 |
(truncdiqi2+[123]): Add patterns to optimize DImode to
SImode truncation.
From-SVN: r8699
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/mips/mips.md | 77 |
1 files changed, 72 insertions, 5 deletions
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 99782b9..0a42a59 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -1945,11 +1945,6 @@ move\\t%0,%z4\\n\\ (set_attr "mode" "SF") (set_attr "length" "1")]) -;; ??? This should be a define expand. -;; See the zero_extendsidi2 pattern. -;; ??? We tried define expands, but they did not work. Too many shift -;; instructions were optimized away. Perhaps add combiner patterns to -;; recognize cases where shifts and truncates can be combined. (define_insn "truncdisi2" [(set (match_operand:SI 0 "register_operand" "=d") (truncate:SI (match_operand:DI 1 "register_operand" "d")))] @@ -1976,6 +1971,78 @@ move\\t%0,%z4\\n\\ [(set_attr "type" "darith") (set_attr "mode" "QI") (set_attr "length" "1")]) + +;; Combiner patterns to optimize shift/truncate combinations. +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=d") + (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "small_int" "I"))))] + "TARGET_64BIT" + "* +{ + int shift_amt = INTVAL (operands[2]) & 0x3f; + + if (shift_amt < 32) + { + operands[2] = GEN_INT (32 - shift_amt); + return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\"; + } + else + { + operands[2] = GEN_INT (shift_amt); + return \"dsra\\t%0,%1,%2\"; + } +}" + [(set_attr "type" "darith") + (set_attr "mode" "SI") + (set_attr "length" "2")]) + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=d") + (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "small_int" "I"))))] + "TARGET_64BIT" + "* +{ + int shift_amt = INTVAL (operands[2]) & 0x3f; + + if (shift_amt < 32) + { + operands[2] = GEN_INT (32 - shift_amt); + return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\"; + } + else if (shift_amt == 32) + return \"dsra\\t%0,%1,32\"; + else + { + operands[2] = GEN_INT (shift_amt); + return \"dsrl\\t%0,%1,%2\"; + } +}" + [(set_attr "type" "darith") + (set_attr "mode" "SI") + (set_attr "length" "2")]) + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=d") + (truncate:SI (ashift:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "small_int" "I"))))] + "TARGET_64BIT" + "* +{ + int shift_amt = INTVAL (operands[2]) & 0x3f; + + if (shift_amt < 32) + { + operands[2] = GEN_INT (32 + shift_amt); + return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\"; + } + else + return \"move\\t%0,%.\"; +}" + [(set_attr "type" "darith") + (set_attr "mode" "SI") + (set_attr "length" "2")]) ;; ;; .................... |