diff options
author | Wilco Dijkstra <wilco.dijkstra@arm.com> | 2024-07-02 17:37:04 +0100 |
---|---|---|
committer | Wilco Dijkstra <wilco.dijkstra@arm.com> | 2024-07-05 13:03:35 +0100 |
commit | 100d353e545564931efaac90a089a4e8f3d42e6e (patch) | |
tree | e7b73450450e04b4c784e4fe14428cc7c71911b1 | |
parent | 9f5620aed3976716e20e13c285dade56578d5bab (diff) | |
download | gcc-100d353e545564931efaac90a089a4e8f3d42e6e.zip gcc-100d353e545564931efaac90a089a4e8f3d42e6e.tar.gz gcc-100d353e545564931efaac90a089a4e8f3d42e6e.tar.bz2 |
Arm: Fix disassembly error in Thumb-1 relaxed load/store [PR115188]
A Thumb-1 memory operand allows single-register LDMIA/STMIA. This doesn't get
printed as LDR/STR with writeback in unified syntax, resulting in strange
assembler errors if writeback is selected. To work around this, use the 'Uw'
constraint that blocks writeback. Also use a new 'mem_and_no_t1_wback_op'
which is a general memory operand that disallows writeback in Thumb-1.
A few other patterns were using 'm' for Thumb-1 in a similar way, update these
to also use 'mem_and_no_t1_wback_op' and 'Uw'.
gcc:
PR target/115188
* config/arm/arm.md (unaligned_loadsi): Use 'Uw' constraint and
'mem_and_no_t1_wback_op'.
(unaligned_loadhiu): Likewise.
(unaligned_storesi): Likewise.
(unaligned_storehi): Likewise.
* config/arm/predicates.md (mem_and_no_t1_wback_op): Add new predicate.
* config/arm/sync.md (arm_atomic_load<mode>): Use 'Uw' constraint.
(arm_atomic_store<mode>): Likewise.
gcc/testsuite:
PR target/115188
* gcc.target/arm/pr115188.c: Add new test.
(cherry picked from commit d04c5537f5ae4a3acd3f5135347d7e2d8c218811)
-rw-r--r-- | gcc/config/arm/arm.md | 8 | ||||
-rw-r--r-- | gcc/config/arm/predicates.md | 5 | ||||
-rw-r--r-- | gcc/config/arm/sync.md | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/pr115188.c | 10 |
4 files changed, 21 insertions, 6 deletions
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 1fd0014..13a8fbf 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -5011,7 +5011,7 @@ (define_insn "unaligned_loadsi" [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") - (unspec:SI [(match_operand:SI 1 "memory_operand" "m,Uw,m")] + (unspec:SI [(match_operand:SI 1 "mem_and_no_t1_wback_op" "Uw,Uw,m")] UNSPEC_UNALIGNED_LOAD))] "unaligned_access" "@ @@ -5041,7 +5041,7 @@ (define_insn "unaligned_loadhiu" [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") (zero_extend:SI - (unspec:HI [(match_operand:HI 1 "memory_operand" "m,Uw,m")] + (unspec:HI [(match_operand:HI 1 "mem_and_no_t1_wback_op" "Uw,Uw,m")] UNSPEC_UNALIGNED_LOAD)))] "unaligned_access" "@ @@ -5066,7 +5066,7 @@ (set_attr "type" "store_8")]) (define_insn "unaligned_storesi" - [(set (match_operand:SI 0 "memory_operand" "=m,Uw,m") + [(set (match_operand:SI 0 "mem_and_no_t1_wback_op" "=Uw,Uw,m") (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,l,r")] UNSPEC_UNALIGNED_STORE))] "unaligned_access" @@ -5081,7 +5081,7 @@ (set_attr "type" "store_4")]) (define_insn "unaligned_storehi" - [(set (match_operand:HI 0 "memory_operand" "=m,Uw,m") + [(set (match_operand:HI 0 "mem_and_no_t1_wback_op" "=Uw,Uw,m") (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,l,r")] UNSPEC_UNALIGNED_STORE))] "unaligned_access" diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index 4994c0c..197054b 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -907,3 +907,8 @@ ;; A special predicate that doesn't match a particular mode. (define_special_predicate "arm_any_register_operand" (match_code "reg")) + +;; General memory operand that disallows Thumb-1 POST_INC. +(define_predicate "mem_and_no_t1_wback_op" + (and (match_operand 0 "memory_operand") + (match_test "!(TARGET_THUMB1 && GET_CODE (XEXP (op, 0)) == POST_INC)"))) diff --git a/gcc/config/arm/sync.md b/gcc/config/arm/sync.md index df8dbe1..0a8347f 100644 --- a/gcc/config/arm/sync.md +++ b/gcc/config/arm/sync.md @@ -65,7 +65,7 @@ (define_insn "arm_atomic_load<mode>" [(set (match_operand:QHSI 0 "register_operand" "=r,l") (unspec_volatile:QHSI - [(match_operand:QHSI 1 "memory_operand" "m,m")] + [(match_operand:QHSI 1 "mem_and_no_t1_wback_op" "m,Uw")] VUNSPEC_LDR))] "" "ldr<sync_sfx>\t%0, %1" @@ -81,7 +81,7 @@ ) (define_insn "arm_atomic_store<mode>" - [(set (match_operand:QHSI 0 "memory_operand" "=m,m") + [(set (match_operand:QHSI 0 "mem_and_no_t1_wback_op" "=m,Uw") (unspec_volatile:QHSI [(match_operand:QHSI 1 "register_operand" "r,l")] VUNSPEC_STR))] diff --git a/gcc/testsuite/gcc.target/arm/pr115188.c b/gcc/testsuite/gcc.target/arm/pr115188.c new file mode 100644 index 0000000..9a4022b --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr115188.c @@ -0,0 +1,10 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_arch_v6m_ok } +/* { dg-options "-O2" } */ +/* { dg-add-options arm_arch_v6m } */ + +void init (int *p, int n) +{ + for (int i = 0; i < n; i++) + __atomic_store_4 (p + i, 0, __ATOMIC_RELAXED); +} |