< prev index next >
src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
Print this page
rev 10243 : 8150394: aarch64: add support for 8.1 LSE CAS instructions
Reviewed-by: aph
Contributed-by: ananth.jasty@caviumnetworks.com, edward.nevill@linaro.org
*** 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 ****
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
Label retry_load, nope;
bind(retry_load);
// flush and load exclusive from the memory location
// and fail if it is not what we expect
--- 2093,2119 ----
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
! 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 ****
--- 2128,2172 ----
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::cmpxchg(operand_size sz,
+ Register oldv, Register newv, Register addr,
+ bool acquire, bool release,
+ Register tmp)
+ {
+ // oldv holds comparison value
+ // newv holds value to write in exchange
+ // addr identifies memory word to compare against/update
+ // returns EQ == success, NE == failure
+ if (UseLSE) {
+ mov(tmp, oldv);
+ compare_and_swap(tmp, newv, addr, sz, acquire?1:0, release?1:0);
+ cmp(tmp, oldv);
+ } else {
+ Label retry_load, done;
+
+ bind(retry_load);
+ // flush and load exclusive from the memory location
+ // and fail if it is not what we expect
+ cas_load(sz, tmp, addr, acquire?1:0);
+ cmp(tmp, oldv);
+ br(Assembler::NE, done);
+ // if we store+flush with no intervening write tmp wil be zero
+ cas_store(sz, tmp, newv, addr, release?1:0);
+ cbnzw(tmp, retry_load);
+ // if the memory word differs we return it in oldv and signal a fail
+ bind(done);
+ }
+ }
+
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 >