Re: [PATCH, GCC/ARM, stage4] Set mode for success result of atomic compare and swap

2017-05-03 Thread Kyrill Tkachov

Hi Thomas,

On 03/05/17 10:39, Thomas Preudhomme wrote:

Hi Kyrill,

On 19/04/17 14:34, Kyrill Tkachov wrote:

Hi Thomas,

On 12/04/17 09:59, Thomas Preudhomme wrote:

Hi,

Currently atomic_compare_and_swap_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 

* config/arm/iterators.md (CCSI): New mode iterator.
(arch): New mode attribute.
* config/arm/sync.md (atomic_compare_and_swap_1): Rename into ...
(atomic_compare_and_swap_1): This and ...
(atomic_compare_and_swap_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.



Thanks for fixing these warnings.
The code looks ok to me but
I'd like to make sure that the rest of the arm atomic targets are not adversely
affected,
so please also do a test run for ARMv7-A and ARMv8-A targets.
Also, a bootstrap is required as always.


Hi Kyrill,

Bootstrapped and ran the testsuite for both ARMv7-A and ARMv8-A in both ARM and Thumb mode without any regression. I've also verified that a number of atomic related testcases [1][2] get the same code generation for ARMv7-A in ARM and 
Thumb mode as well as ARMv8-M Baseline.


[1] For ARMv7-A ARM and Thumb mode, the following testcases were considered:

gcc/testsuite/gcc.dg/atomic-compare-exchange-1.c
gcc/testsuite/gcc.dg/atomic-compare-exchange-2.c
gcc/testsuite/gcc.dg/atomic-compare-exchange-3.c
gcc/testsuite/gcc.dg/atomic-exchange-1.c
gcc/testsuite/gcc.dg/atomic-exchange-2.c
gcc/testsuite/gcc.dg/atomic-exchange-3.c
gcc/testsuite/gcc.dg/atomic-fence.c
gcc/testsuite/gcc.dg/atomic-flag.c
gcc/testsuite/gcc.dg/atomic-generic.c
gcc/testsuite/gcc.dg/atomic-generic-aux.c
gcc/testsuite/gcc.dg/atomic-invalid-2.c
gcc/testsuite/gcc.dg/atomic-load-1.c
gcc/testsuite/gcc.dg/atomic-load-2.c
gcc/testsuite/gcc.dg/atomic-load-3.c
gcc/testsuite/gcc.dg/atomic-lockfree.c
gcc/testsuite/gcc.dg/atomic-lockfree-aux.c
gcc/testsuite/gcc.dg/atomic-noinline.c
gcc/testsuite/gcc.dg/atomic-noinline-aux.c
gcc/testsuite/gcc.dg/atomic-op-1.c
gcc/testsuite/gcc.dg/atomic-op-2.c
gcc/testsuite/gcc.dg/atomic-op-3.c
gcc/testsuite/gcc.dg/atomic-op-6.c
gcc/testsuite/gcc.dg/atomic-store-1.c
gcc/testsuite/gcc.dg/atomic-store-2.c
gcc/testsuite/gcc.dg/atomic-store-3.c
gcc/testsuite/g++.dg/ext/atomic-1.C
gcc/testsuite/g++.dg/ext/atomic-2.C
gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire-1.c
gcc/testsuite/gcc.target/arm/atomic-op-acq_rel-1.c
gcc/testsuite/gcc.target/arm/atomic-op-acquire-1.c
gcc/testsuite/gcc.target/arm/atomic-op-char-1.c
gcc/testsuite/gcc.target/arm/atomic-op-consume-1.c
gcc/testsuite/gcc.target/arm/atomic-op-int-1.c
gcc/testsuite/gcc.target/arm/atomic-op-relaxed-1.c
gcc/testsuite/gcc.target/arm/atomic-op-release-1.c
gcc/testsuite/gcc.target/arm/atomic-op-seq_cst-1.c
gcc/testsuite/gcc.target/arm/atomic-op-short-1.c
gcc/testsuite/gcc.target/arm/atomic_loaddi_1.c
gcc/testsuite/gcc.target/arm/atomic_loaddi_4.c
gcc/testsuite/gcc.target/arm/atomic_loaddi_7.c
gcc/testsuite/gcc.target/arm/sync-1.c
gcc/testsuite/gcc.target/arm/synchronize.c
gcc/testsuite/gcc.target/arm/armv8-sync-comp-swap.c
gcc/testsuite/gcc.target/arm/armv8-sync-op-acquire.c
gcc/testsuite/gcc.target/arm/armv8-sync-op-full.c
gcc/testsuite/gcc.target/arm/armv8-sync-op-release.c
libstdc++-v3/testsuite/29_atomics/atomic/60658.cc
libstdc++-v3/testsuite/29_atomics/atomic/62259.cc
libstdc++-v3/testsuite/29_atomics/atomic/64658.cc
libstdc++-v3/testsuite/29_atomics/atomic/65147.cc
libstdc++-v3/testsuite/29_atomics/atomic/65913.cc
libstdc++-v3/testsuite/29_atomics/atomic/70766.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/49445.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/constexpr.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/copy_list.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/default.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/direct_list.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/single_value.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/user_pod.cc
libstdc++-v3/testsuite/29_atomics/atomic/operators/51811.cc
libstdc++-v3/testsuite/29_atomics/atomic/operators/56011.cc

Re: [PATCH, GCC/ARM, stage4] Set mode for success result of atomic compare and swap

2017-05-03 Thread Thomas Preudhomme

Hi Kyrill,

On 19/04/17 14:34, Kyrill Tkachov wrote:

Hi Thomas,

On 12/04/17 09:59, Thomas Preudhomme wrote:

Hi,

Currently atomic_compare_and_swap_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  

* config/arm/iterators.md (CCSI): New mode iterator.
(arch): New mode attribute.
* config/arm/sync.md (atomic_compare_and_swap_1): Rename into ...
(atomic_compare_and_swap_1): This and ...
(atomic_compare_and_swap_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.



Thanks for fixing these warnings.
The code looks ok to me but
I'd like to make sure that the rest of the arm atomic targets are not adversely
affected,
so please also do a test run for ARMv7-A and ARMv8-A targets.
Also, a bootstrap is required as always.


Hi Kyrill,

Bootstrapped and ran the testsuite for both ARMv7-A and ARMv8-A in both ARM and 
Thumb mode without any regression. I've also verified that a number of atomic 
related testcases [1][2] get the same code generation for ARMv7-A in ARM and 
Thumb mode as well as ARMv8-M Baseline.


[1] For ARMv7-A ARM and Thumb mode, the following testcases were considered:

gcc/testsuite/gcc.dg/atomic-compare-exchange-1.c
gcc/testsuite/gcc.dg/atomic-compare-exchange-2.c
gcc/testsuite/gcc.dg/atomic-compare-exchange-3.c
gcc/testsuite/gcc.dg/atomic-exchange-1.c
gcc/testsuite/gcc.dg/atomic-exchange-2.c
gcc/testsuite/gcc.dg/atomic-exchange-3.c
gcc/testsuite/gcc.dg/atomic-fence.c
gcc/testsuite/gcc.dg/atomic-flag.c
gcc/testsuite/gcc.dg/atomic-generic.c
gcc/testsuite/gcc.dg/atomic-generic-aux.c
gcc/testsuite/gcc.dg/atomic-invalid-2.c
gcc/testsuite/gcc.dg/atomic-load-1.c
gcc/testsuite/gcc.dg/atomic-load-2.c
gcc/testsuite/gcc.dg/atomic-load-3.c
gcc/testsuite/gcc.dg/atomic-lockfree.c
gcc/testsuite/gcc.dg/atomic-lockfree-aux.c
gcc/testsuite/gcc.dg/atomic-noinline.c
gcc/testsuite/gcc.dg/atomic-noinline-aux.c
gcc/testsuite/gcc.dg/atomic-op-1.c
gcc/testsuite/gcc.dg/atomic-op-2.c
gcc/testsuite/gcc.dg/atomic-op-3.c
gcc/testsuite/gcc.dg/atomic-op-6.c
gcc/testsuite/gcc.dg/atomic-store-1.c
gcc/testsuite/gcc.dg/atomic-store-2.c
gcc/testsuite/gcc.dg/atomic-store-3.c
gcc/testsuite/g++.dg/ext/atomic-1.C
gcc/testsuite/g++.dg/ext/atomic-2.C
gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire-1.c
gcc/testsuite/gcc.target/arm/atomic-op-acq_rel-1.c
gcc/testsuite/gcc.target/arm/atomic-op-acquire-1.c
gcc/testsuite/gcc.target/arm/atomic-op-char-1.c
gcc/testsuite/gcc.target/arm/atomic-op-consume-1.c
gcc/testsuite/gcc.target/arm/atomic-op-int-1.c
gcc/testsuite/gcc.target/arm/atomic-op-relaxed-1.c
gcc/testsuite/gcc.target/arm/atomic-op-release-1.c
gcc/testsuite/gcc.target/arm/atomic-op-seq_cst-1.c
gcc/testsuite/gcc.target/arm/atomic-op-short-1.c
gcc/testsuite/gcc.target/arm/atomic_loaddi_1.c
gcc/testsuite/gcc.target/arm/atomic_loaddi_4.c
gcc/testsuite/gcc.target/arm/atomic_loaddi_7.c
gcc/testsuite/gcc.target/arm/sync-1.c
gcc/testsuite/gcc.target/arm/synchronize.c
gcc/testsuite/gcc.target/arm/armv8-sync-comp-swap.c
gcc/testsuite/gcc.target/arm/armv8-sync-op-acquire.c
gcc/testsuite/gcc.target/arm/armv8-sync-op-full.c
gcc/testsuite/gcc.target/arm/armv8-sync-op-release.c
libstdc++-v3/testsuite/29_atomics/atomic/60658.cc
libstdc++-v3/testsuite/29_atomics/atomic/62259.cc
libstdc++-v3/testsuite/29_atomics/atomic/64658.cc
libstdc++-v3/testsuite/29_atomics/atomic/65147.cc
libstdc++-v3/testsuite/29_atomics/atomic/65913.cc
libstdc++-v3/testsuite/29_atomics/atomic/70766.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/49445.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/constexpr.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/copy_list.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/default.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/direct_list.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/single_value.cc
libstdc++-v3/testsuite/29_atomics/atomic/cons/user_pod.cc
libstdc++-v3/testsuite/29_atomics/atomic/operators/51811.cc
libstdc++-v3/testsuite/29_atomics/atomic/operators/56011.cc
libstdc++-v3/testsuite/29_atomics/atomic/operators/integral_assignment.cc

Re: [PATCH, GCC/ARM, stage4] Set mode for success result of atomic compare and swap

2017-04-19 Thread Kyrill Tkachov

Hi Thomas,

On 12/04/17 09:59, Thomas Preudhomme wrote:

Hi,

Currently atomic_compare_and_swap_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  

* config/arm/iterators.md (CCSI): New mode iterator.
(arch): New mode attribute.
* config/arm/sync.md (atomic_compare_and_swap_1): Rename into ...
(atomic_compare_and_swap_1): This and ...
(atomic_compare_and_swap_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.



Thanks for fixing these warnings.
The code looks ok to me but
I'd like to make sure that the rest of the arm atomic targets are not adversely 
affected,
so please also do a test run for ARMv7-A and ARMv8-A targets.
Also, a bootstrap is required as always.

Ok with that testing.

Thanks,
Kyrill


Is this ok for stage4?

Best regards,

Thomas




Re: [PATCH, GCC/ARM, stage4] Set mode for success result of atomic compare and swap

2017-04-19 Thread Thomas Preudhomme

Stage 4 ping?

Best regards,

Thomas

On 12/04/17 09:59, Thomas Preudhomme wrote:

Hi,

Currently atomic_compare_and_swap_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  

* config/arm/iterators.md (CCSI): New mode iterator.
(arch): New mode attribute.
* config/arm/sync.md (atomic_compare_and_swap_1): Rename into ...
(atomic_compare_and_swap_1): This and ...
(atomic_compare_and_swap_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 b24143e32e2f10f3b150f7ed0df4fabb3cc8..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_1"
-  [(set (match_operand 0 "cc_register_operand" "=,,,")		;; bool out
-	(unspec_volatile:CC_Z [(const_int 0)] VUNSPEC_ATOMIC_CAS))
+(define_insn_and_split "atomic_compare_and_swap_1"
+  [(set (match_operand:CCSI 0 "cc_register_operand" "=,,,")	;; bool out
+	(unspec_volatile:CCSI [(const_int 0)] VUNSPEC_ATOMIC_CAS))
(set (match_operand:SI 1 "s_register_operand" "=,,&0,*h")	;; val out
 	(zero_extend:SI
 	  (match_operand:NARROW 2 "mem_noofs_operand" "+Ua,Ua,Ua,Ua")))	;; memory
@@ 

[PATCH, GCC/ARM, stage4] Set mode for success result of atomic compare and swap

2017-04-12 Thread Thomas Preudhomme

Hi,

Currently atomic_compare_and_swap_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  

* config/arm/iterators.md (CCSI): New mode iterator.
(arch): New mode attribute.
* config/arm/sync.md (atomic_compare_and_swap_1): Rename into ...
(atomic_compare_and_swap_1): This and ...
(atomic_compare_and_swap_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 b24143e32e2f10f3b150f7ed0df4fabb3cc8..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_1"
-  [(set (match_operand 0 "cc_register_operand" "=,,,")		;; bool out
-	(unspec_volatile:CC_Z [(const_int 0)] VUNSPEC_ATOMIC_CAS))
+(define_insn_and_split "atomic_compare_and_swap_1"
+  [(set (match_operand:CCSI 0 "cc_register_operand" "=,,,")	;; bool out
+	(unspec_volatile:CCSI [(const_int 0)] VUNSPEC_ATOMIC_CAS))
(set (match_operand:SI 1 "s_register_operand" "=,,&0,*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