< 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,11 +2068,17 @@
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
+ 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,20 +2093,27 @@
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,14 +2128,45 @@
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 >