< prev index next >

src/cpu/aarch64/vm/assembler_aarch64.hpp

Print this page
rev 10278 : 8150394: aarch64: add support for 8.1 LSE CAS instructions
Reviewed-by: duke
Contributed-by: ananth.jasty@caviumnetworks.com, edward.nevill@gmail.com

*** 1167,1176 **** --- 1167,1230 ---- #undef INSN2 #undef INSN3 #undef INSN4 #undef INSN_FOO + // 8.1 Compare and swap extensions + void compare_and_swap(Register Rs, Register Rt, Register Rn, + enum operand_size sz, int op, int a, int r) { + starti; + f(sz, 31, 30), f(0b001000, 29, 24), f(1, 23), f(a, 22), f(1, 21); + rf(Rs, 16), f(r, 15), f(0b11111, 14, 10), rf(Rn, 5), rf(Rt, 0); + } + + // CAS + #define INSN(NAME, sz, a, r) \ + void NAME(Register Rs, Register Rt, Register Rn) { \ + assert(Rs != Rn && Rs != Rt, "unpredictable instruction"); \ + compare_and_swap(Rs, Rt, Rn, sz, 1, a, r); \ + } + INSN(casb, byte, 0, 0) + INSN(cash, halfword, 0, 0) + INSN(casw, word, 0, 0) + INSN(cas, xword, 0, 0) + INSN(casab, byte, 1, 0) + INSN(casah, halfword, 1, 0) + INSN(casaw, word, 1, 0) + INSN(casa, xword, 1, 0) + INSN(caslb, byte, 0, 1) + INSN(caslh, halfword, 0, 1) + INSN(caslw, word, 0, 1) + INSN(casl, xword, 0, 1) + INSN(casalb, byte, 1, 1) + INSN(casalh, halfword, 1, 1) + INSN(casalw, word, 1, 1) + INSN(casal, xword, 1, 1) + #undef INSN + + // CASP + #define INSN(NAME, sz, a, r) \ + void NAME(Register Rs, Register Rs1, \ + Register Rt, Register Rt1, Register Rn) { \ + assert((Rs->encoding() & 1) == 0 && (Rt->encoding() & 1) == 0 && \ + Rs->successor() == Rs1 && Rt->successor() == Rt1 && \ + Rs != Rn && Rs1 != Rn && Rs != Rt, "invalid registers"); \ + assert(sz == word || sz == xword, "invalid size"); \ + /* The size bit is in bit 30, not 31 as in ldx/stx above */ \ + compare_and_swap(Rs, Rt, Rn, \ + (operand_size)(sz == word ? 0b00:0b01), 0, a, r); \ + } + INSN(caspw, word, 0, 0) + INSN(casp, xword, 0, 0) + INSN(caspaw, word, 1, 0) + INSN(caspa, xword, 1, 0) + INSN(casplw, word, 0, 1) + INSN(caspl, xword, 0, 1) + INSN(caspalw, word, 1, 1) + INSN(caspal, xword, 1, 1) + #undef INSN + // Load register (literal) #define INSN(NAME, opc, V) \ void NAME(Register Rt, address dest) { \ long offset = (dest - pc()) >> 2; \ starti; \
< prev index next >