This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, GCC/ARM, stage4] Set mode for success result of atomic compare and swap
- From: Thomas Preudhomme <thomas dot preudhomme at foss dot arm dot com>
- To: Kyrill Tkachov <kyrylo dot tkachov at arm dot com>, Ramana Radhakrishnan <ramana dot radhakrishnan at arm dot com>, Richard Earnshaw <richard dot earnshaw at arm dot com>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 19 Apr 2017 10:21:48 +0100
- Subject: Re: [PATCH, GCC/ARM, stage4] Set mode for success result of atomic compare and swap
- Authentication-results: sourceware.org; auth=none
- References: <b2c3d30d-7b2b-6b6d-32f4-55c2df02bdbf@foss.arm.com>
Stage 4 ping?
Best regards,
Thomas
On 12/04/17 09:59, Thomas Preudhomme wrote:
Hi,
Currently atomic_compare_and_swap<mode>_1 define_insn do not have a mode
set for the destination of the set indicating the success result of the
instruction. This is because the operand can be either a CC_Z register
(for 32-bit targets) or a SI register (for 16-bit Thumb targets). This
result in lack of checking for the mode.
This commit use a new CCSI iterator to solve this issue while avoiding
duplication of the patterns. The insn name are kept unique by using
attributes tied to the iterator (SIDI:mode and CCSI:arch) instead of
usign the builtin mode attribute. Expander arm_expand_compare_and_swap
is also adapted accordingly.
ChangeLog entry is as follows:
*** gcc/ChangeLog ***
2017-04-11 Thomas Preud'homme <thomas.preudhomme@arm.com>
* config/arm/iterators.md (CCSI): New mode iterator.
(arch): New mode attribute.
* config/arm/sync.md (atomic_compare_and_swap<mode>_1): Rename into ...
(atomic_compare_and_swap<CCSI:arch><NARROW:mode>_1): This and ...
(atomic_compare_and_swap<CCSI:arch><SIDI:mode>_1): This. Use CCSI
code iterator for success result mode.
* config/arm/arm.c (arm_expand_compare_and_swap): Adapt code to use
the corresponding new insn generators.
Testing: arm-none-eabi cross-compiler built successfully for ARMv8-M
Mainline and Baseline without the lack of destination mode warning in
sync.md. Testsuite show no regression.
Is this ok for stage4?
Best regards,
Thomas
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index b24143e32e2f100000f3b150f7ed0df4fabb3cc8..cf628714507efd2b5a5ab5de97ef32fd45987d1f 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -28190,17 +28190,32 @@ arm_expand_compare_and_swap (rtx operands[])
gcc_unreachable ();
}
- switch (mode)
+ if (TARGET_THUMB1)
{
- case QImode: gen = gen_atomic_compare_and_swapqi_1; break;
- case HImode: gen = gen_atomic_compare_and_swaphi_1; break;
- case SImode: gen = gen_atomic_compare_and_swapsi_1; break;
- case DImode: gen = gen_atomic_compare_and_swapdi_1; break;
- default:
- gcc_unreachable ();
+ switch (mode)
+ {
+ case QImode: gen = gen_atomic_compare_and_swapt1qi_1; break;
+ case HImode: gen = gen_atomic_compare_and_swapt1hi_1; break;
+ case SImode: gen = gen_atomic_compare_and_swapt1si_1; break;
+ case DImode: gen = gen_atomic_compare_and_swapt1di_1; break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else
+ {
+ switch (mode)
+ {
+ case QImode: gen = gen_atomic_compare_and_swap32qi_1; break;
+ case HImode: gen = gen_atomic_compare_and_swap32hi_1; break;
+ case SImode: gen = gen_atomic_compare_and_swap32si_1; break;
+ case DImode: gen = gen_atomic_compare_and_swap32di_1; break;
+ default:
+ gcc_unreachable ();
+ }
}
- bdst = TARGET_THUMB1 ? bval : gen_rtx_REG (CCmode, CC_REGNUM);
+ bdst = TARGET_THUMB1 ? bval : gen_rtx_REG (CC_Zmode, CC_REGNUM);
emit_insn (gen (bdst, rval, mem, oldval, newval, is_weak, mod_s, mod_f));
if (mode == QImode || mode == HImode)
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index e2e588688eb04c158d1c146bca12d84cfb5ff130..48992879a8eecc66eba913c2b9a7c5989c5c7bc6 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -45,6 +45,9 @@
;; A list of the 32bit and 64bit integer modes
(define_mode_iterator SIDI [SI DI])
+;; A list of atomic compare and swap success return modes
+(define_mode_iterator CCSI [(CC_Z "TARGET_32BIT") (SI "TARGET_THUMB1")])
+
;; A list of modes which the VFP unit can handle
(define_mode_iterator SDF [(SF "") (DF "TARGET_VFP_DOUBLE")])
@@ -411,6 +414,10 @@
;; Mode attributes
;;----------------------------------------------------------------------------
+;; Determine name of atomic compare and swap from success result mode. This
+;; distinguishes between 16-bit Thumb and 32-bit Thumb/ARM.
+(define_mode_attr arch [(CC_Z "32") (SI "t1")])
+
;; Determine element size suffix from vector mode.
(define_mode_attr MMX_char [(V8QI "b") (V4HI "h") (V2SI "w") (DI "d")])
diff --git a/gcc/config/arm/sync.md b/gcc/config/arm/sync.md
index 1f91b7364d5689145a10bbb193d54a0677b2fd36..b4b4f2e6815e7c31c9874c19af31e908107e6a62 100644
--- a/gcc/config/arm/sync.md
+++ b/gcc/config/arm/sync.md
@@ -191,9 +191,9 @@
;; Constraints of this pattern must be at least as strict as those of the
;; cbranchsi operations in thumb1.md and aim to be as permissive.
-(define_insn_and_split "atomic_compare_and_swap<mode>_1"
- [(set (match_operand 0 "cc_register_operand" "=&c,&l,&l,&l") ;; bool out
- (unspec_volatile:CC_Z [(const_int 0)] VUNSPEC_ATOMIC_CAS))
+(define_insn_and_split "atomic_compare_and_swap<CCSI:arch><NARROW:mode>_1"
+ [(set (match_operand:CCSI 0 "cc_register_operand" "=&c,&l,&l,&l") ;; bool out
+ (unspec_volatile:CCSI [(const_int 0)] VUNSPEC_ATOMIC_CAS))
(set (match_operand:SI 1 "s_register_operand" "=&r,&l,&0,&l*h") ;; val out
(zero_extend:SI
(match_operand:NARROW 2 "mem_noofs_operand" "+Ua,Ua,Ua,Ua"))) ;; memory
@@ -223,9 +223,9 @@
;; Constraints of this pattern must be at least as strict as those of the
;; cbranchsi operations in thumb1.md and aim to be as permissive.
-(define_insn_and_split "atomic_compare_and_swap<mode>_1"
- [(set (match_operand 0 "cc_register_operand" "=&c,&l,&l,&l") ;; bool out
- (unspec_volatile:CC_Z [(const_int 0)] VUNSPEC_ATOMIC_CAS))
+(define_insn_and_split "atomic_compare_and_swap<CCSI:arch><SIDI:mode>_1"
+ [(set (match_operand:CCSI 0 "cc_register_operand" "=&c,&l,&l,&l") ;; bool out
+ (unspec_volatile:CCSI [(const_int 0)] VUNSPEC_ATOMIC_CAS))
(set (match_operand:SIDI 1 "s_register_operand" "=&r,&l,&0,&l*h") ;; val out
(match_operand:SIDI 2 "mem_noofs_operand" "+Ua,Ua,Ua,Ua")) ;; memory
(set (match_dup 2)