s390.md: ("UNSPECV_MB", "UNSPECV_CAS"): New constants.

2005-06-07  Adrian Straetling  <straetling@de.ibm.com>

gcc/ChangeLog:
	* config/s390/s390.md: ("UNSPECV_MB", "UNSPECV_CAS"): New constants.
	("type"): Add "sem" to 'type' attribute.
	("memory_barrier", "*memory_barrier", "sync_compare_and_swapdi",
	"sync_compare_and_swapsi", "sync_compare_and_swap_ccdi",
	"sync_compare_and_swap_ccsi", "*sync_compare_and_swap_ccdi",
	"*sync_compare_and_swap_ccsi"): New patterns.
	* config/s390/2064.md: ("z_sem"): New insn_reservation.
	* config/s390/2084.md: ("x_sem"): New insn_reservation.
	* config/s390/s390.c: (s390_compare_emitted): New global variable.
	(s390_emit_compare): Do not emit comparison again after cas.
	* config/s390/s390.h (s390_compare_emitted): Declare.

libstdc++/ChangeLog:
	* config/cpu/s390/atomicity.h: (__exchange_and_add,
	__atomic_add): Use the builtins for atomic memory operations.

From-SVN: r100711
This commit is contained in:
Adrian Straetling 2005-06-07 16:35:27 +00:00 committed by Ulrich Weigand
parent b6e7e9af04
commit e0374221d9
8 changed files with 135 additions and 19 deletions

View File

@ -1,3 +1,17 @@
2005-06-07 Adrian Straetling <straetling@de.ibm.com>
* config/s390/s390.md: ("UNSPECV_MB", "UNSPECV_CAS"): New constants.
("type"): Add "sem" to 'type' attribute.
("memory_barrier", "*memory_barrier", "sync_compare_and_swapdi",
"sync_compare_and_swapsi", "sync_compare_and_swap_ccdi",
"sync_compare_and_swap_ccsi", "*sync_compare_and_swap_ccdi",
"*sync_compare_and_swap_ccsi"): New patterns.
* config/s390/2064.md: ("z_sem"): New insn_reservation.
* config/s390/2084.md: ("x_sem"): New insn_reservation.
* config/s390/s390.c: (s390_compare_emitted): New global variable.
(s390_emit_compare): Do not emit comparison again after cas.
* config/s390/s390.h (s390_compare_emitted): Declare.
2005-06-07 Kazu Hirata <kazu@codesourcery.com>
* sbitmap.h (sbitmap_iterator, sbitmap_iter_init,

View File

@ -67,6 +67,11 @@
(eq_attr "type" "store"))
"z_e1,z_wr")
(define_insn_reservation "z_sem" 2
(and (eq_attr "cpu" "z900,g5,g6")
(eq_attr "type" "sem"))
"z_e1*2,z_wr")
(define_insn_reservation "z_call" 5
(and (eq_attr "cpu" "z900,g5,g6")
(eq_attr "type" "jsr"))

View File

@ -123,6 +123,11 @@
(eq_attr "type" "idiv"))
"x-e1-np*10,x-wr-np")
(define_insn_reservation "x_sem" 17
(and (eq_attr "cpu" "z990")
(eq_attr "type" "sem"))
"x-e1-np+x-mem,x-e1-np*16,x-wr-st")
;;
;; Multicycle insns
;;

View File

@ -163,6 +163,10 @@ static int s390_sr_alias_set = 0;
emitted. */
rtx s390_compare_op0, s390_compare_op1;
/* Save the result of a compare_and_swap until the branch or scc is
emitted. */
rtx s390_compare_emitted = NULL_RTX;
/* Structure used to hold the components of a S/390 memory
address. A legitimate address on S/390 is of the general
form
@ -609,10 +613,21 @@ rtx
s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
{
enum machine_mode mode = s390_select_ccmode (code, op0, op1);
rtx cc = gen_rtx_REG (mode, CC_REGNUM);
rtx ret = NULL_RTX;
emit_insn (gen_rtx_SET (VOIDmode, cc, gen_rtx_COMPARE (mode, op0, op1)));
return gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
/* Do not output a redundant compare instruction if a compare_and_swap
pattern already computed the result and the machine modes match. */
if (s390_compare_emitted && GET_MODE (s390_compare_emitted) == mode)
ret = gen_rtx_fmt_ee (code, VOIDmode, s390_compare_emitted, const0_rtx);
else
{
rtx cc = gen_rtx_REG (mode, CC_REGNUM);
emit_insn (gen_rtx_SET (VOIDmode, cc, gen_rtx_COMPARE (mode, op0, op1)));
ret = gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
}
s390_compare_emitted = NULL_RTX;
return ret;
}
/* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an

View File

@ -799,7 +799,7 @@ do { \
/* Define the information needed to generate branch and scc insns. This is
stored from the compare operation. Note that we can't use "rtx" here
since it hasn't been defined! */
extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
extern struct rtx_def *s390_compare_op0, *s390_compare_op1, *s390_compare_emitted;
/* Relative costs of operations. */

View File

@ -146,6 +146,10 @@
; TLS support
(UNSPECV_SET_TP 500)
; Atomic Support
(UNSPECV_MB 700)
(UNSPECV_CAS 701)
])
;;
@ -177,7 +181,7 @@
;; Instruction type attribute used for scheduling.
(define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
cs,vs,store,idiv,
cs,vs,store,sem,idiv,
imulhi,imulsi,imuldi,
branch,jsr,fsimpdf,fsimpsf,
floaddf,floadsf,fstoredf,fstoresf,
@ -6691,6 +6695,86 @@
(set_attr "type" "jsr")
(set_attr "atype" "agen")])
;;
;;- Atomic operations
;;
;
; memory barrier pattern.
;
(define_expand "memory_barrier"
[(set (mem:BLK (match_dup 0))
(unspec_volatile:BLK [(mem:BLK (match_dup 0))] UNSPECV_MB))]
""
{
operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
MEM_VOLATILE_P (operands[0]) = 1;
})
(define_insn "*memory_barrier"
[(set (match_operand:BLK 0 "" "")
(unspec_volatile:BLK [(match_operand:BLK 1 "" "")] UNSPECV_MB))]
""
"bcr\t15,0"
[(set_attr "op_type" "RR")])
;
; 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:CCZ (match_dup 1) (match_dup 2)))])]
""
{
operands[4] = gen_rtx_REG (CCZmode, 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)
(unspec_volatile:GPR
[(match_dup 1)
(match_operand:GPR 2 "register_operand" "0")
(match_operand:GPR 3 "register_operand" "r")]
UNSPECV_CAS))
(set (reg:CCZ CC_REGNUM)
(compare:CCZ (match_dup 1) (match_dup 2)))]
""
"cs<g>\t%0,%3,%S1"
[(set_attr "op_type" "RS<E>")
(set_attr "type" "sem")])
;;
;;- Miscellaneous instructions.
;;

View File

@ -1,3 +1,8 @@
2005-06-07 Adrian Straetling <straetling@de.ibm.com>
* config/cpu/s390/atomicity.h: (__exchange_and_add,
__atomic_add): Use the builtins for atomic memory operations.
2005-06-06 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/21770 (cont: __gnu_debug::string)

View File

@ -34,22 +34,10 @@ namespace __gnu_cxx
_Atomic_word
__attribute__ ((__unused__))
__exchange_and_add(volatile _Atomic_word* __mem, int __val)
{
register _Atomic_word __old_val, __new_val;
__asm__ __volatile__ (" l %0,0(%3)\n"
"0: lr %1,%0\n"
" ar %1,%4\n"
" cs %0,%1,0(%3)\n"
" jl 0b"
: "=&d" (__old_val), "=&d" (__new_val), "=m" (*__mem)
: "a" (__mem), "d" (__val), "m" (*__mem)
: "cc", "memory");
return __old_val;
}
{ return __sync_fetch_and_add(__mem, __val); }
void
__attribute__ ((__unused__))
__atomic_add(volatile _Atomic_word* __mem, int __val)
{ __exchange_and_add(__mem, __val); }
{ __sync_fetch_and_add(__mem, __val); }
} // namespace __gnu_cxx