< prev index next >
src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
Print this page
*** 2068,2078 ****
void MacroAssembler::cmpxchgptr(Register oldv, Register newv, Register addr, Register tmp,
Label &succeed, Label *fail) {
// oldv holds comparison value
// newv holds value to write in exchange
// addr identifies memory word to compare against/update
! // tmp returns 0/1 for success/failure
Label retry_load, nope;
bind(retry_load);
// flush and load exclusive from the memory location
// and fail if it is not what we expect
--- 2068,2084 ----
void MacroAssembler::cmpxchgptr(Register oldv, Register newv, Register addr, Register tmp,
Label &succeed, Label *fail) {
// oldv holds comparison value
// newv holds value to write in exchange
// addr identifies memory word to compare against/update
! if (UseLSE) {
! mov(tmp, oldv);
! casal(Assembler::xword, oldv, newv, addr);
! cmp(tmp, oldv);
! br(Assembler::EQ, succeed);
! membar(AnyAny);
! } else {
Label retry_load, nope;
bind(retry_load);
// flush and load exclusive from the memory location
// and fail if it is not what we expect
*** 2087,2106 ****
--- 2093,2120 ----
b(retry_load);
// if the memory word differs we return it in oldv and signal a fail
bind(nope);
membar(AnyAny);
mov(oldv, tmp);
+ }
if (fail)
b(*fail);
}
void MacroAssembler::cmpxchgw(Register oldv, Register newv, Register addr, Register tmp,
Label &succeed, Label *fail) {
// oldv holds comparison value
// newv holds value to write in exchange
// addr identifies memory word to compare against/update
// tmp returns 0/1 for success/failure
+ if (UseLSE) {
+ mov(tmp, oldv);
+ casal(Assembler::word, oldv, newv, addr);
+ cmp(tmp, oldv);
+ br(Assembler::EQ, succeed);
+ membar(AnyAny);
+ } else {
Label retry_load, nope;
bind(retry_load);
// flush and load exclusive from the memory location
// and fail if it is not what we expect
*** 2115,2128 ****
--- 2129,2170 ----
b(retry_load);
// if the memory word differs we return it in oldv and signal a fail
bind(nope);
membar(AnyAny);
mov(oldv, tmp);
+ }
if (fail)
b(*fail);
}
+ // A generic CAS; success or failure is in the EQ flag.
+ void MacroAssembler::cmpxchg(Register addr, Register expected,
+ Register new_val,
+ enum operand_size size,
+ bool acquire, bool release,
+ Register tmp) {
+ if (UseLSE) {
+ mov(tmp, expected);
+ lse_cas(tmp, new_val, addr, size, acquire, release, /*not_pair*/ true);
+ cmp(tmp, expected);
+ } else {
+ BLOCK_COMMENT("cmpxchg {");
+ Label retry_load, done;
+ bind(retry_load);
+ load_exclusive(tmp, addr, size, acquire);
+ if (size == xword)
+ cmp(tmp, expected);
+ else
+ cmpw(tmp, expected);
+ br(Assembler::NE, done);
+ store_exclusive(tmp, new_val, addr, size, release);
+ cbnzw(tmp, retry_load);
+ bind(done);
+ BLOCK_COMMENT("} cmpxchg");
+ }
+ }
+
static bool different(Register a, RegisterOrConstant b, Register c) {
if (b.is_constant())
return a != c;
else
return a != b.as_register() && a != c && b.as_register() != c;
< prev index next >