This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] s390: support for dword_mode compare_and_swap
- From: Adrian Straetling <straetling at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org, uweigand at de dot ibm dot com
- Date: Fri, 30 Sep 2005 15:06:20 +0200
- Subject: [patch] s390: support for dword_mode compare_and_swap
Hi,
this patch enables hardware support for the __sync_compare_and_swap for
DImode on s390 and TImode on s390x.
Successfully bootstrapped and regtested on s390 and s390x.
Ok for 4.1?
bye,
Adrian
2005-09-30 Adrian Straetling <straetling@de.ibm.com>
* config/s390/s390.md ("TDSI","DP"): New mode macros.
("TE","tg"): New mode attributes.
("sync_compare_and_swap<mode>"): Replace with a define_expand.
("sync_compare_and_swap<mode>_cc"): Replace GPR with TDSI.
("*sync_compare_and_swap<mode>_cc"): Replace with one pattern for
dword_mode and one for GPRmode.
Index: gcc/config/s390/s390.md
===================================================================
*** gcc/config/s390/s390.md.orig 2005-08-30 22:29:36.000000000 +0200
--- gcc/config/s390/s390.md 2005-09-06 20:29:55.673160285 +0200
***************
*** 279,284 ****
--- 279,288 ----
;; 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])
***************
*** 286,291 ****
--- 290,296 ----
;; 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
***************
*** 328,337 ****
--- 333,350 ----
;; 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")])
***************
*** 7139,7180 ****
; 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_cc<mode>"
[(parallel
! [(set (match_operand:GPR 0 "register_operand" "")
! (match_operand:GPR 1 "memory_operand" ""))
(set (match_dup 1)
! (unspec_volatile:GPR
[(match_dup 1)
! (match_operand:GPR 2 "register_operand" "")
! (match_operand:GPR 3 "register_operand" "")]
UNSPECV_CAS))
(set (match_dup 4)
(compare:CCZ1 (match_dup 1) (match_dup 2)))])]
""
{
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>"
[(set (match_operand:GPR 0 "register_operand" "=r")
(match_operand:GPR 1 "memory_operand" "+Q"))
(set (match_dup 1)
--- 7152,7209 ----
; compare and swap patterns.
;
! (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: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 (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<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)