< 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 >