;; same template.
(define_mode_macro FPR [DF SF])
+;; These mode macros allow 31-bit and 64-bit TDSI patterns to be generated
+;; from the same template.
+(define_mode_macro TDSI [(TI "TARGET_64BIT") DI SI])
+
;; These mode macros allow 31-bit and 64-bit GPR patterns to be generated
;; from the same template.
(define_mode_macro GPR [(DI "TARGET_64BIT") SI])
;; This mode macro allows :P to be used for patterns that operate on
;; pointer-sized quantities. Exactly one of the two alternatives will match.
+(define_mode_macro DP [(TI "TARGET_64BIT") (DI "!TARGET_64BIT")])
(define_mode_macro P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
;; This mode macro allows the QI and HI patterns to be defined from
;; in "RRE" for DImode and "RR" for SImode.
(define_mode_attr E [(DI "E") (SI "")])
+;; This attribute handles differences in the instruction 'type' and will result
+;; in "RSE" for TImode and "RS" for DImode.
+(define_mode_attr TE [(TI "E") (DI "")])
+
;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
;; and "lcr" in SImode.
(define_mode_attr g [(DI "g") (SI "")])
+;; In DP templates, a string like "cds<g>" will expand to "cdsg" in TImode
+;; and "cds" in DImode.
+(define_mode_attr tg [(TI "g") (DI "")])
+
;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
;; and "cfdbr" in SImode.
(define_mode_attr gf [(DI "g") (SI "f")])
; compare and swap patterns.
;
-(define_insn "sync_compare_and_swap<mode>"
- [(set (match_operand:GPR 0 "register_operand" "=r")
- (match_operand:GPR 1 "memory_operand" "+Q"))
- (set (match_dup 1)
- (unspec_volatile:GPR
- [(match_dup 1)
- (match_operand:GPR 2 "register_operand" "0")
- (match_operand:GPR 3 "register_operand" "r")]
- UNSPECV_CAS))
- (clobber (reg:CC CC_REGNUM))]
- ""
- "cs<g>\t%0,%3,%S1"
- [(set_attr "op_type" "RS<E>")
- (set_attr "type" "sem")])
+(define_expand "sync_compare_and_swap<mode>"
+ [(parallel
+ [(set (match_operand:TDSI 0 "register_operand" "")
+ (match_operand:TDSI 1 "memory_operand" ""))
+ (set (match_dup 1)
+ (unspec_volatile:TDSI
+ [(match_dup 1)
+ (match_operand:TDSI 2 "register_operand" "")
+ (match_operand:TDSI 3 "register_operand" "")]
+ UNSPECV_CAS))
+ (set (reg:CCZ1 CC_REGNUM)
+ (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
+ "")
(define_expand "sync_compare_and_swap_cc<mode>"
[(parallel
- [(set (match_operand:GPR 0 "register_operand" "")
- (match_operand:GPR 1 "memory_operand" ""))
+ [(set (match_operand:TDSI 0 "register_operand" "")
+ (match_operand:TDSI 1 "memory_operand" ""))
(set (match_dup 1)
- (unspec_volatile:GPR
+ (unspec_volatile:TDSI
[(match_dup 1)
- (match_operand:GPR 2 "register_operand" "")
- (match_operand:GPR 3 "register_operand" "")]
+ (match_operand:TDSI 2 "register_operand" "")
+ (match_operand:TDSI 3 "register_operand" "")]
UNSPECV_CAS))
(set (match_dup 4)
(compare:CCZ1 (match_dup 1) (match_dup 2)))])]
""
{
+ /* Emulate compare. */
operands[4] = gen_rtx_REG (CCZ1mode, CC_REGNUM);
s390_compare_op0 = operands[1];
s390_compare_op1 = operands[2];
s390_compare_emitted = operands[4];
})
-(define_insn "*sync_compare_and_swap_cc<mode>"
+(define_insn "*sync_compare_and_swap<mode>"
+ [(set (match_operand:DP 0 "register_operand" "=r")
+ (match_operand:DP 1 "memory_operand" "+Q"))
+ (set (match_dup 1)
+ (unspec_volatile:DP
+ [(match_dup 1)
+ (match_operand:DP 2 "register_operand" "0")
+ (match_operand:DP 3 "register_operand" "r")]
+ UNSPECV_CAS))
+ (set (reg:CCZ1 CC_REGNUM)
+ (compare:CCZ1 (match_dup 1) (match_dup 2)))]
+ ""
+ "cds<tg>\t%0,%3,%S1"
+ [(set_attr "op_type" "RS<TE>")
+ (set_attr "type" "sem")])
+
+(define_insn "*sync_compare_and_swap<mode>"
[(set (match_operand:GPR 0 "register_operand" "=r")
(match_operand:GPR 1 "memory_operand" "+Q"))
(set (match_dup 1)