mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-11 22:30:27 +08:00
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:
parent
b6e7e9af04
commit
e0374221d9
@ -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,
|
||||
|
@ -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"))
|
||||
|
@ -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
|
||||
;;
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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.
|
||||
;;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user