aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2025-03-25 11:50:30 +0000
committerRichard Earnshaw <rearnsha@arm.com>2025-03-25 12:06:22 +0000
commita86891525d200c1ae81d9f5f441a5b8e24b647ca (patch)
tree99bdc75422ab92a716eb7a1cc8494a03fe666f76 /gcc
parent7679b826840c58343d72d05922355b646db4bdcc (diff)
downloadgcc-a86891525d200c1ae81d9f5f441a5b8e24b647ca.zip
gcc-a86891525d200c1ae81d9f5f441a5b8e24b647ca.tar.gz
gcc-a86891525d200c1ae81d9f5f441a5b8e24b647ca.tar.bz2
arm: add commutative alternatives to <US>mull pattern.
Prior to Armv6, the SMULL and UMULL instructions, which have the form UMULL Rdlo, Rdhi, Rm, Rs had an operand restriction such that Rdlo, Rdhi and Rm must all be different registers. Rs, however can overlap either of the destination registers. Add some register-tie alternatives to allow the register allocator to find these forms without having to use additional register moves. In addition to this, the test is pretty meaningless on Thumb-1 targets as the S/UMULL instructions do not exist in a 16-bit encoding. So skip the test in this case. gcc/ChangeLog: * config/arm/arm.md (<US>mull): Add alternatives that allow Rs to be tied to either Rdlo or Rdhi. gcc/testsuite/ChangeLog: * gcc.target/arm/pr42575.c: Skip test if thumb1.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/arm/arm.md10
-rw-r--r--gcc/testsuite/gcc.target/arm/pr42575.c1
2 files changed, 6 insertions, 5 deletions
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 442d86b..597ef67 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -2432,11 +2432,11 @@
)
(define_insn "<US>mull"
- [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
+ [(set (match_operand:SI 0 "s_register_operand" "=r,&r,&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")
+ (match_operand:SI 2 "s_register_operand" "%r,r,r,r")
+ (match_operand:SI 3 "s_register_operand" "r,r,0,1")))
+ (set (match_operand:SI 1 "s_register_operand" "=r,&r,&r,&r")
(truncate:SI
(lshiftrt:DI
(mult:DI (SE:DI (match_dup 2)) (SE:DI (match_dup 3)))
@@ -2445,7 +2445,7 @@
"<US>mull%?\\t%0, %1, %2, %3"
[(set_attr "type" "umull")
(set_attr "predicable" "yes")
- (set_attr "arch" "v6,nov6")]
+ (set_attr "arch" "v6,nov6,nov6,nov6")]
)
(define_expand "<Us>maddsidi4"
diff --git a/gcc/testsuite/gcc.target/arm/pr42575.c b/gcc/testsuite/gcc.target/arm/pr42575.c
index 1998e32..3906c77 100644
--- a/gcc/testsuite/gcc.target/arm/pr42575.c
+++ b/gcc/testsuite/gcc.target/arm/pr42575.c
@@ -1,4 +1,5 @@
/* { dg-options "-O2" } */
+/* { dg-skip-if "Thumb1 lacks UMULL" { arm_thumb1 } } */
/* Make sure RA does good job allocating registers and avoids
unnecessary moves. */
/* { dg-final { scan-assembler-not "mov" } } */