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