aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorWilco Dijkstra <wdijkstr@arm.com>2019-09-18 18:33:30 +0000
committerWilco Dijkstra <wilco@gcc.gnu.org>2019-09-18 18:33:30 +0000
commit22a8ab772c37dc6250f2b22afe1e91b55fda41f5 (patch)
treec04409ce3b927ff6abffcd3e7af20269c209f6b4 /gcc
parent0800e23ecf42b8323c226041f3982cd7856061c9 (diff)
downloadgcc-22a8ab772c37dc6250f2b22afe1e91b55fda41f5.zip
gcc-22a8ab772c37dc6250f2b22afe1e91b55fda41f5.tar.gz
gcc-22a8ab772c37dc6250f2b22afe1e91b55fda41f5.tar.bz2
[ARM] Cleanup 64-bit multiplies
Cleanup 64-bit multiplies. Combine the expanders using iterators. Merge the signed/unsigned multiplies as well as the pre-Armv6 and Armv6 variants. Split DImode operands early into parallel sets inside the MULL/MLAL instructions - this improves register allocation and avoids subreg issues due to other DImode operations splitting early. gcc/ * config/arm/arm.md (maddsidi4): Remove expander. (mulsidi3adddi): Remove pattern. (mulsidi3adddi_v6): Likewise. (mulsidi3_nov6): Likewise. (mulsidi3_v6): Likewise. (umulsidi3): Remove expander. (umulsidi3_nov6): Remove pattern. (umulsidi3_v6): Likewise. (umulsidi3adddi): Likewise. (umulsidi3adddi_v6): Likewise. (<Us>mulsidi3): Add combined expander. (<Us>maddsidi4): Likewise. (<US>mull): Add combined umull and smull pattern. (<US>mlal): Likewise. * config/arm/iterators.md (Us): Add new iterator. From-SVN: r275901
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/config/arm/arm.md174
-rw-r--r--gcc/config/arm/iterators.md1
3 files changed, 74 insertions, 119 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8b76a62..6be55cd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+2019-09-18 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * config/arm/arm.md (maddsidi4): Remove expander.
+ (mulsidi3adddi): Remove pattern.
+ (mulsidi3adddi_v6): Likewise.
+ (mulsidi3_nov6): Likewise.
+ (mulsidi3_v6): Likewise.
+ (umulsidi3): Remove expander.
+ (umulsidi3_nov6): Remove pattern.
+ (umulsidi3_v6): Likewise.
+ (umulsidi3adddi): Likewise.
+ (umulsidi3adddi_v6): Likewise.
+ (<Us>mulsidi3): Add combined expander.
+ (<Us>maddsidi4): Likewise.
+ (<US>mull): Add combined umull and smull pattern.
+ (<US>mlal): Likewise.
+ * config/arm/iterators.md (Us): Add new iterator.
+
2019-09-18 Richard Biener <rguenther@suse.de>
* tree-vect-loop.c (vect_is_simple_reduction): Remove operand
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index b47e196..0054ed4 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -1755,144 +1755,80 @@
(set_attr "type" "mlas")]
)
-(define_expand "maddsidi4"
- [(set (match_operand:DI 0 "s_register_operand")
- (plus:DI
- (mult:DI
- (sign_extend:DI (match_operand:SI 1 "s_register_operand"))
- (sign_extend:DI (match_operand:SI 2 "s_register_operand")))
- (match_operand:DI 3 "s_register_operand")))]
- "TARGET_32BIT"
- "")
-
-(define_insn "*mulsidi3adddi"
- [(set (match_operand:DI 0 "s_register_operand" "=&r")
- (plus:DI
- (mult:DI
- (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
- (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
- (match_operand:DI 1 "s_register_operand" "0")))]
- "TARGET_32BIT && !arm_arch6"
- "smlal%?\\t%Q0, %R0, %3, %2"
- [(set_attr "type" "smlal")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*mulsidi3adddi_v6"
- [(set (match_operand:DI 0 "s_register_operand" "=r")
- (plus:DI
- (mult:DI
- (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
- (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
- (match_operand:DI 1 "s_register_operand" "0")))]
- "TARGET_32BIT && arm_arch6"
- "smlal%?\\t%Q0, %R0, %3, %2"
- [(set_attr "type" "smlal")
- (set_attr "predicable" "yes")]
-)
-
;; 32x32->64 widening multiply.
-;; As with mulsi3, the only difference between the v3-5 and v6+
-;; versions of these patterns is the requirement that the output not
-;; overlap the inputs, but that still means we have to have a named
-;; expander and two different starred insns.
+;; The only difference between the v3-5 and v6+ versions is the requirement
+;; that the output does not overlap with either input.
-(define_expand "mulsidi3"
+(define_expand "<Us>mulsidi3"
[(set (match_operand:DI 0 "s_register_operand")
(mult:DI
- (sign_extend:DI (match_operand:SI 1 "s_register_operand"))
- (sign_extend:DI (match_operand:SI 2 "s_register_operand"))))]
+ (SE:DI (match_operand:SI 1 "s_register_operand"))
+ (SE:DI (match_operand:SI 2 "s_register_operand"))))]
"TARGET_32BIT"
- ""
-)
-
-(define_insn "*mulsidi3_nov6"
- [(set (match_operand:DI 0 "s_register_operand" "=&r")
- (mult:DI
- (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
- (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
- "TARGET_32BIT && !arm_arch6"
- "smull%?\\t%Q0, %R0, %1, %2"
- [(set_attr "type" "smull")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*mulsidi3_v6"
- [(set (match_operand:DI 0 "s_register_operand" "=r")
- (mult:DI
- (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
- (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
- "TARGET_32BIT && arm_arch6"
- "smull%?\\t%Q0, %R0, %1, %2"
- [(set_attr "type" "smull")
- (set_attr "predicable" "yes")]
+ {
+ emit_insn (gen_<US>mull (gen_lowpart (SImode, operands[0]),
+ gen_highpart (SImode, operands[0]),
+ operands[1], operands[2]));
+ DONE;
+ }
)
-(define_expand "umulsidi3"
- [(set (match_operand:DI 0 "s_register_operand")
- (mult:DI
- (zero_extend:DI (match_operand:SI 1 "s_register_operand"))
- (zero_extend:DI (match_operand:SI 2 "s_register_operand"))))]
+(define_insn "<US>mull"
+ [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
+ (mult:SI
+ (match_operand:SI 2 "s_register_operand" "%r,r")
+ (match_operand:SI 3 "s_register_operand" "r,r")))
+ (set (match_operand:SI 1 "s_register_operand" "=r,&r")
+ (truncate:SI
+ (lshiftrt:DI
+ (mult:DI (SE:DI (match_dup 2)) (SE:DI (match_dup 3)))
+ (const_int 32))))]
"TARGET_32BIT"
- ""
-)
-
-(define_insn "*umulsidi3_nov6"
- [(set (match_operand:DI 0 "s_register_operand" "=&r")
- (mult:DI
- (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
- (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
- "TARGET_32BIT && !arm_arch6"
- "umull%?\\t%Q0, %R0, %1, %2"
- [(set_attr "type" "umull")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*umulsidi3_v6"
- [(set (match_operand:DI 0 "s_register_operand" "=r")
- (mult:DI
- (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
- (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
- "TARGET_32BIT && arm_arch6"
- "umull%?\\t%Q0, %R0, %1, %2"
+ "<US>mull%?\\t%0, %1, %2, %3"
[(set_attr "type" "umull")
- (set_attr "predicable" "yes")]
+ (set_attr "predicable" "yes")
+ (set_attr "arch" "v6,nov6")]
)
-(define_expand "umaddsidi4"
+(define_expand "<Us>maddsidi4"
[(set (match_operand:DI 0 "s_register_operand")
(plus:DI
(mult:DI
- (zero_extend:DI (match_operand:SI 1 "s_register_operand"))
- (zero_extend:DI (match_operand:SI 2 "s_register_operand")))
+ (SE:DI (match_operand:SI 1 "s_register_operand"))
+ (SE:DI (match_operand:SI 2 "s_register_operand")))
(match_operand:DI 3 "s_register_operand")))]
"TARGET_32BIT"
- "")
-
-(define_insn "*umulsidi3adddi"
- [(set (match_operand:DI 0 "s_register_operand" "=&r")
- (plus:DI
- (mult:DI
- (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
- (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
- (match_operand:DI 1 "s_register_operand" "0")))]
- "TARGET_32BIT && !arm_arch6"
- "umlal%?\\t%Q0, %R0, %3, %2"
- [(set_attr "type" "umlal")
- (set_attr "predicable" "yes")]
+ {
+ emit_insn (gen_<US>mlal (gen_lowpart (SImode, operands[0]),
+ gen_lowpart (SImode, operands[3]),
+ gen_highpart (SImode, operands[0]),
+ gen_highpart (SImode, operands[3]),
+ operands[1], operands[2]));
+ DONE;
+ }
)
-(define_insn "*umulsidi3adddi_v6"
- [(set (match_operand:DI 0 "s_register_operand" "=r")
- (plus:DI
- (mult:DI
- (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
- (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
- (match_operand:DI 1 "s_register_operand" "0")))]
- "TARGET_32BIT && arm_arch6"
- "umlal%?\\t%Q0, %R0, %3, %2"
+(define_insn "<US>mlal"
+ [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
+ (plus:SI
+ (mult:SI
+ (SE:DI (match_operand:SI 4 "s_register_operand" "%r,r"))
+ (SE:DI (match_operand:SI 5 "s_register_operand" "r,r")))
+ (match_operand:SI 1 "s_register_operand" "0,0")))
+ (set (match_operand:SI 2 "s_register_operand" "=r,&r")
+ (plus:SI
+ (truncate:SI
+ (lshiftrt:DI
+ (plus:DI
+ (mult:DI (SE:DI (match_dup 4)) (SE:DI (match_dup 5)))
+ (zero_extend:DI (match_dup 1)))
+ (const_int 32)))
+ (match_operand:SI 3 "s_register_operand" "2,2")))]
+ "TARGET_32BIT"
+ "<US>mlal%?\\t%0, %2, %4, %5"
[(set_attr "type" "umlal")
- (set_attr "predicable" "yes")]
+ (set_attr "predicable" "yes")
+ (set_attr "arch" "v6,nov6")]
)
(define_expand "<US>mulsi3_highpart"
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index fa6f0c0..c29897a 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -796,6 +796,7 @@
;; Assembler mnemonics for signedness of widening operations.
(define_code_attr US [(sign_extend "s") (zero_extend "u")])
+(define_code_attr Us [(sign_extend "") (zero_extend "u")])
;; Signedness suffix for float->fixed conversions. Empty for signed
;; conversion.