@@ -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)
@@ -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")])
@@ -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)