--- old/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp 2018-10-24 13:35:04.641868308 +0200 +++ new/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp 2018-10-24 13:34:55.881847972 +0200 @@ -2367,21 +2367,18 @@ bool weak, Register result) { if (result == noreg) result = rscratch1; + BLOCK_COMMENT("cmpxchg {"); if (UseLSE) { mov(result, expected); lse_cas(result, new_val, addr, size, acquire, release, /*not_pair*/ true); - cmp(result, expected); + compare_eq(result, expected, size); } else { - BLOCK_COMMENT("cmpxchg {"); Label retry_load, done; if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) prfm(Address(addr), PSTL1STRM); bind(retry_load); load_exclusive(result, addr, size, acquire); - if (size == xword) - cmp(result, expected); - else - cmpw(result, expected); + compare_eq(result, expected, size); br(Assembler::NE, done); store_exclusive(rscratch1, new_val, addr, size, release); if (weak) { @@ -2390,10 +2387,28 @@ cbnzw(rscratch1, retry_load); } bind(done); - BLOCK_COMMENT("} cmpxchg"); } + BLOCK_COMMENT("} cmpxchg"); } +// A generic comparison. Only compares for equality, clobbers rscratch1. +void MacroAssembler::compare_eq(Register rm, Register rn, enum operand_size size) { + if (size == xword) { + cmp(rm, rn); + } else if (size == word) { + cmpw(rm, rn); + } else if (size == halfword) { + eorw(rscratch1, rm, rn); + ands(zr, rscratch1, 0xffff); + } else if (size == byte) { + eorw(rscratch1, rm, rn); + ands(zr, rscratch1, 0xff); + } else { + ShouldNotReachHere(); + } +} + + static bool different(Register a, RegisterOrConstant b, Register c) { if (b.is_constant()) return a != c;