< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Print this page




2350     bind(nope);
2351     membar(AnyAny);
2352     mov(oldv, tmp);
2353   }
2354   if (fail)
2355     b(*fail);
2356 }
2357 
2358 // A generic CAS; success or failure is in the EQ flag.  A weak CAS
2359 // doesn't retry and may fail spuriously.  If the oldval is wanted,
2360 // Pass a register for the result, otherwise pass noreg.
2361 
2362 // Clobbers rscratch1
2363 void MacroAssembler::cmpxchg(Register addr, Register expected,
2364                              Register new_val,
2365                              enum operand_size size,
2366                              bool acquire, bool release,
2367                              bool weak,
2368                              Register result) {
2369   if (result == noreg)  result = rscratch1;

2370   if (UseLSE) {
2371     mov(result, expected);
2372     lse_cas(result, new_val, addr, size, acquire, release, /*not_pair*/ true);
2373     cmp(result, expected);
2374   } else {
2375     BLOCK_COMMENT("cmpxchg {");
2376     Label retry_load, done;
2377     if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
2378       prfm(Address(addr), PSTL1STRM);
2379     bind(retry_load);
2380     load_exclusive(result, addr, size, acquire);
2381     if (size == xword)
2382       cmp(result, expected);
2383     else
2384       cmpw(result, expected);
2385     br(Assembler::NE, done);
2386     store_exclusive(rscratch1, new_val, addr, size, release);
2387     if (weak) {
2388       cmpw(rscratch1, 0u);  // If the store fails, return NE to our caller.
2389     } else {
2390       cbnzw(rscratch1, retry_load);
2391     }
2392     bind(done);

2393     BLOCK_COMMENT("} cmpxchg");
















2394   }
2395 }

2396 
2397 static bool different(Register a, RegisterOrConstant b, Register c) {
2398   if (b.is_constant())
2399     return a != c;
2400   else
2401     return a != b.as_register() && a != c && b.as_register() != c;
2402 }
2403 
2404 #define ATOMIC_OP(NAME, LDXR, OP, IOP, AOP, STXR, sz)                   \
2405 void MacroAssembler::atomic_##NAME(Register prev, RegisterOrConstant incr, Register addr) { \
2406   if (UseLSE) {                                                         \
2407     prev = prev->is_valid() ? prev : zr;                                \
2408     if (incr.is_register()) {                                           \
2409       AOP(sz, incr.as_register(), prev, addr);                          \
2410     } else {                                                            \
2411       mov(rscratch2, incr.as_constant());                               \
2412       AOP(sz, rscratch2, prev, addr);                                   \
2413     }                                                                   \
2414     return;                                                             \
2415   }                                                                     \




2350     bind(nope);
2351     membar(AnyAny);
2352     mov(oldv, tmp);
2353   }
2354   if (fail)
2355     b(*fail);
2356 }
2357 
2358 // A generic CAS; success or failure is in the EQ flag.  A weak CAS
2359 // doesn't retry and may fail spuriously.  If the oldval is wanted,
2360 // Pass a register for the result, otherwise pass noreg.
2361 
2362 // Clobbers rscratch1
2363 void MacroAssembler::cmpxchg(Register addr, Register expected,
2364                              Register new_val,
2365                              enum operand_size size,
2366                              bool acquire, bool release,
2367                              bool weak,
2368                              Register result) {
2369   if (result == noreg)  result = rscratch1;
2370   BLOCK_COMMENT("cmpxchg {");
2371   if (UseLSE) {
2372     mov(result, expected);
2373     lse_cas(result, new_val, addr, size, acquire, release, /*not_pair*/ true);
2374     compare_eq(result, expected, size);
2375   } else {

2376     Label retry_load, done;
2377     if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
2378       prfm(Address(addr), PSTL1STRM);
2379     bind(retry_load);
2380     load_exclusive(result, addr, size, acquire);
2381     compare_eq(result, expected, size);



2382     br(Assembler::NE, done);
2383     store_exclusive(rscratch1, new_val, addr, size, release);
2384     if (weak) {
2385       cmpw(rscratch1, 0u);  // If the store fails, return NE to our caller.
2386     } else {
2387       cbnzw(rscratch1, retry_load);
2388     }
2389     bind(done);
2390   }
2391   BLOCK_COMMENT("} cmpxchg");
2392 }
2393 
2394 // A generic comparison. Only compares for equality, clobbers rscratch1.
2395 void MacroAssembler::compare_eq(Register rm, Register rn, enum operand_size size) {
2396   if (size == xword) {
2397     cmp(rm, rn);
2398   } else if (size == word) {
2399     cmpw(rm, rn);
2400   } else if (size == halfword) {
2401     eorw(rscratch1, rm, rn);
2402     ands(zr, rscratch1, 0xffff);
2403   } else if (size == byte) {
2404     eorw(rscratch1, rm, rn);
2405     ands(zr, rscratch1, 0xff);
2406   } else {
2407     ShouldNotReachHere();
2408   }
2409 }
2410 
2411 
2412 static bool different(Register a, RegisterOrConstant b, Register c) {
2413   if (b.is_constant())
2414     return a != c;
2415   else
2416     return a != b.as_register() && a != c && b.as_register() != c;
2417 }
2418 
2419 #define ATOMIC_OP(NAME, LDXR, OP, IOP, AOP, STXR, sz)                   \
2420 void MacroAssembler::atomic_##NAME(Register prev, RegisterOrConstant incr, Register addr) { \
2421   if (UseLSE) {                                                         \
2422     prev = prev->is_valid() ? prev : zr;                                \
2423     if (incr.is_register()) {                                           \
2424       AOP(sz, incr.as_register(), prev, addr);                          \
2425     } else {                                                            \
2426       mov(rscratch2, incr.as_constant());                               \
2427       AOP(sz, rscratch2, prev, addr);                                   \
2428     }                                                                   \
2429     return;                                                             \
2430   }                                                                     \


< prev index next >