8344010: RISC-V: Zacas do not work with LW locking
Reviewed-by: fyang, mli
This commit is contained in:
parent
e2f8f1aded
commit
ea7e722ca0
@ -3466,6 +3466,17 @@ void MacroAssembler::cmpxchg(Register addr, Register expected,
|
|||||||
assert_different_registers(expected, t0);
|
assert_different_registers(expected, t0);
|
||||||
assert_different_registers(new_val, t0);
|
assert_different_registers(new_val, t0);
|
||||||
|
|
||||||
|
// NOTE:
|
||||||
|
// Register _result_ may be the same register as _new_val_ or _expected_.
|
||||||
|
// Hence do NOT use _result_ until after 'cas'.
|
||||||
|
//
|
||||||
|
// Register _expected_ may be the same register as _new_val_ and is assumed to be preserved.
|
||||||
|
// Hence do NOT change _expected_ or _new_val_.
|
||||||
|
//
|
||||||
|
// Having _expected_ and _new_val_ being the same register is a very puzzling cas.
|
||||||
|
//
|
||||||
|
// TODO: Address these issues.
|
||||||
|
|
||||||
if (UseZacas) {
|
if (UseZacas) {
|
||||||
if (result_as_bool) {
|
if (result_as_bool) {
|
||||||
mv(t0, expected);
|
mv(t0, expected);
|
||||||
@ -3473,8 +3484,9 @@ void MacroAssembler::cmpxchg(Register addr, Register expected,
|
|||||||
xorr(t0, t0, expected);
|
xorr(t0, t0, expected);
|
||||||
seqz(result, t0);
|
seqz(result, t0);
|
||||||
} else {
|
} else {
|
||||||
mv(result, expected);
|
mv(t0, expected);
|
||||||
atomic_cas(result, new_val, addr, size, acquire, release);
|
atomic_cas(t0, new_val, addr, size, acquire, release);
|
||||||
|
mv(result, t0);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3510,15 +3522,16 @@ void MacroAssembler::cmpxchg_weak(Register addr, Register expected,
|
|||||||
enum operand_size size,
|
enum operand_size size,
|
||||||
Assembler::Aqrl acquire, Assembler::Aqrl release,
|
Assembler::Aqrl acquire, Assembler::Aqrl release,
|
||||||
Register result) {
|
Register result) {
|
||||||
if (UseZacas) {
|
|
||||||
cmpxchg(addr, expected, new_val, size, acquire, release, result, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_different_registers(addr, t0);
|
assert_different_registers(addr, t0);
|
||||||
assert_different_registers(expected, t0);
|
assert_different_registers(expected, t0);
|
||||||
assert_different_registers(new_val, t0);
|
assert_different_registers(new_val, t0);
|
||||||
|
|
||||||
|
if (UseZacas) {
|
||||||
|
cmpxchg(addr, expected, new_val, size, acquire, release, result, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Label fail, done;
|
Label fail, done;
|
||||||
load_reserved(t0, addr, size, acquire);
|
load_reserved(t0, addr, size, acquire);
|
||||||
bne(t0, expected, fail);
|
bne(t0, expected, fail);
|
||||||
@ -3581,83 +3594,18 @@ ATOMIC_XCHGU(xchgalwu, xchgalw)
|
|||||||
|
|
||||||
#undef ATOMIC_XCHGU
|
#undef ATOMIC_XCHGU
|
||||||
|
|
||||||
#define ATOMIC_CAS(OP, AOP, ACQUIRE, RELEASE) \
|
void MacroAssembler::atomic_cas(Register prev, Register newv, Register addr,
|
||||||
void MacroAssembler::atomic_##OP(Register prev, Register newv, Register addr) { \
|
enum operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release) {
|
||||||
assert(UseZacas, "invariant"); \
|
|
||||||
prev = prev->is_valid() ? prev : zr; \
|
|
||||||
AOP(prev, addr, newv, (Assembler::Aqrl)(ACQUIRE | RELEASE)); \
|
|
||||||
return; \
|
|
||||||
}
|
|
||||||
|
|
||||||
ATOMIC_CAS(cas, amocas_d, Assembler::relaxed, Assembler::relaxed)
|
|
||||||
ATOMIC_CAS(casw, amocas_w, Assembler::relaxed, Assembler::relaxed)
|
|
||||||
ATOMIC_CAS(casl, amocas_d, Assembler::relaxed, Assembler::rl)
|
|
||||||
ATOMIC_CAS(caslw, amocas_w, Assembler::relaxed, Assembler::rl)
|
|
||||||
ATOMIC_CAS(casal, amocas_d, Assembler::aq, Assembler::rl)
|
|
||||||
ATOMIC_CAS(casalw, amocas_w, Assembler::aq, Assembler::rl)
|
|
||||||
|
|
||||||
#undef ATOMIC_CAS
|
|
||||||
|
|
||||||
#define ATOMIC_CASU(OP1, OP2) \
|
|
||||||
void MacroAssembler::atomic_##OP1(Register prev, Register newv, Register addr) { \
|
|
||||||
atomic_##OP2(prev, newv, addr); \
|
|
||||||
zero_extend(prev, prev, 32); \
|
|
||||||
return; \
|
|
||||||
}
|
|
||||||
|
|
||||||
ATOMIC_CASU(caswu, casw)
|
|
||||||
ATOMIC_CASU(caslwu, caslw)
|
|
||||||
ATOMIC_CASU(casalwu, casalw)
|
|
||||||
|
|
||||||
#undef ATOMIC_CASU
|
|
||||||
|
|
||||||
void MacroAssembler::atomic_cas(
|
|
||||||
Register prev, Register newv, Register addr, enum operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release) {
|
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case int64:
|
case int64:
|
||||||
switch ((Assembler::Aqrl)(acquire | release)) {
|
amocas_d(prev, addr, newv, (Assembler::Aqrl)(acquire | release));
|
||||||
case Assembler::relaxed:
|
|
||||||
atomic_cas(prev, newv, addr);
|
|
||||||
break;
|
|
||||||
case Assembler::rl:
|
|
||||||
atomic_casl(prev, newv, addr);
|
|
||||||
break;
|
|
||||||
case Assembler::aqrl:
|
|
||||||
atomic_casal(prev, newv, addr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ShouldNotReachHere();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case int32:
|
case int32:
|
||||||
switch ((Assembler::Aqrl)(acquire | release)) {
|
amocas_w(prev, addr, newv, (Assembler::Aqrl)(acquire | release));
|
||||||
case Assembler::relaxed:
|
|
||||||
atomic_casw(prev, newv, addr);
|
|
||||||
break;
|
|
||||||
case Assembler::rl:
|
|
||||||
atomic_caslw(prev, newv, addr);
|
|
||||||
break;
|
|
||||||
case Assembler::aqrl:
|
|
||||||
atomic_casalw(prev, newv, addr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ShouldNotReachHere();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case uint32:
|
case uint32:
|
||||||
switch ((Assembler::Aqrl)(acquire | release)) {
|
amocas_w(prev, addr, newv, (Assembler::Aqrl)(acquire | release));
|
||||||
case Assembler::relaxed:
|
zero_extend(prev, prev, 32);
|
||||||
atomic_caswu(prev, newv, addr);
|
|
||||||
break;
|
|
||||||
case Assembler::rl:
|
|
||||||
atomic_caslwu(prev, newv, addr);
|
|
||||||
break;
|
|
||||||
case Assembler::aqrl:
|
|
||||||
atomic_casalwu(prev, newv, addr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ShouldNotReachHere();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
|
@ -1175,16 +1175,6 @@ public:
|
|||||||
void atomic_xchgwu(Register prev, Register newv, Register addr);
|
void atomic_xchgwu(Register prev, Register newv, Register addr);
|
||||||
void atomic_xchgalwu(Register prev, Register newv, Register addr);
|
void atomic_xchgalwu(Register prev, Register newv, Register addr);
|
||||||
|
|
||||||
void atomic_cas(Register prev, Register newv, Register addr);
|
|
||||||
void atomic_casw(Register prev, Register newv, Register addr);
|
|
||||||
void atomic_casl(Register prev, Register newv, Register addr);
|
|
||||||
void atomic_caslw(Register prev, Register newv, Register addr);
|
|
||||||
void atomic_casal(Register prev, Register newv, Register addr);
|
|
||||||
void atomic_casalw(Register prev, Register newv, Register addr);
|
|
||||||
void atomic_caswu(Register prev, Register newv, Register addr);
|
|
||||||
void atomic_caslwu(Register prev, Register newv, Register addr);
|
|
||||||
void atomic_casalwu(Register prev, Register newv, Register addr);
|
|
||||||
|
|
||||||
void atomic_cas(Register prev, Register newv, Register addr, enum operand_size size,
|
void atomic_cas(Register prev, Register newv, Register addr, enum operand_size size,
|
||||||
Assembler::Aqrl acquire = Assembler::relaxed, Assembler::Aqrl release = Assembler::relaxed);
|
Assembler::Aqrl acquire = Assembler::relaxed, Assembler::Aqrl release = Assembler::relaxed);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user