< prev index next >
src/cpu/aarch64/vm/assembler_aarch64.hpp
Print this page
*** 970,980 ****
#undef INSN
// System
void system(int op0, int op1, int CRn, int CRm, int op2,
! Register rt = (Register)0b11111)
{
starti;
f(0b11010101000, 31, 21);
f(op0, 20, 19);
f(op1, 18, 16);
--- 970,980 ----
#undef INSN
// System
void system(int op0, int op1, int CRn, int CRm, int op2,
! Register rt = dummy_reg)
{
starti;
f(0b11010101000, 31, 21);
f(op0, 20, 19);
f(op1, 18, 16);
*** 1080,1090 ****
#undef INSN
#define INSN(NAME, opc) \
void NAME() { \
! branch_reg((Register)0b11111, opc); \
}
INSN(eret, 0b0100);
INSN(drps, 0b0101);
--- 1080,1090 ----
#undef INSN
#define INSN(NAME, opc) \
void NAME() { \
! branch_reg(dummy_reg, opc); \
}
INSN(eret, 0b0100);
INSN(drps, 0b0101);
*** 1092,1105 ****
// Load/store exclusive
enum operand_size { byte, halfword, word, xword };
void load_store_exclusive(Register Rs, Register Rt1, Register Rt2,
! Register Rn, enum operand_size sz, int op, int o0) {
starti;
f(sz, 31, 30), f(0b001000, 29, 24), f(op, 23, 21);
! rf(Rs, 16), f(o0, 15), rf(Rt2, 10), rf(Rn, 5), rf(Rt1, 0);
}
#define INSN4(NAME, sz, op, o0) /* Four registers */ \
void NAME(Register Rs, Register Rt1, Register Rt2, Register Rn) { \
guarantee(Rs != Rn && Rs != Rt1 && Rs != Rt2, "unpredictable instruction"); \
--- 1092,1117 ----
// Load/store exclusive
enum operand_size { byte, halfword, word, xword };
void load_store_exclusive(Register Rs, Register Rt1, Register Rt2,
! Register Rn, enum operand_size sz, int op, bool ordered) {
starti;
f(sz, 31, 30), f(0b001000, 29, 24), f(op, 23, 21);
! rf(Rs, 16), f(ordered, 15), rf(Rt2, 10), rf(Rn, 5), rf(Rt1, 0);
! }
!
! void load_exclusive(Register dst, Register addr,
! enum operand_size sz, bool ordered) {
! load_store_exclusive(dummy_reg, dst, dummy_reg, addr,
! sz, 0b010, ordered);
! }
!
! void store_exclusive(Register status, Register new_val, Register addr,
! enum operand_size sz, bool ordered) {
! load_store_exclusive(status, new_val, dummy_reg, addr,
! sz, 0b000, ordered);
}
#define INSN4(NAME, sz, op, o0) /* Four registers */ \
void NAME(Register Rs, Register Rt1, Register Rt2, Register Rn) { \
guarantee(Rs != Rn && Rs != Rt1 && Rs != Rt2, "unpredictable instruction"); \
*** 1107,1129 ****
}
#define INSN3(NAME, sz, op, o0) /* Three registers */ \
void NAME(Register Rs, Register Rt, Register Rn) { \
guarantee(Rs != Rn && Rs != Rt, "unpredictable instruction"); \
! load_store_exclusive(Rs, Rt, (Register)0b11111, Rn, sz, op, o0); \
}
#define INSN2(NAME, sz, op, o0) /* Two registers */ \
void NAME(Register Rt, Register Rn) { \
! load_store_exclusive((Register)0b11111, Rt, (Register)0b11111, \
Rn, sz, op, o0); \
}
#define INSN_FOO(NAME, sz, op, o0) /* Three registers, encoded differently */ \
void NAME(Register Rt1, Register Rt2, Register Rn) { \
guarantee(Rt1 != Rt2, "unpredictable instruction"); \
! load_store_exclusive((Register)0b11111, Rt1, Rt2, Rn, sz, op, o0); \
}
// bytes
INSN3(stxrb, byte, 0b000, 0);
INSN3(stlxrb, byte, 0b000, 1);
--- 1119,1141 ----
}
#define INSN3(NAME, sz, op, o0) /* Three registers */ \
void NAME(Register Rs, Register Rt, Register Rn) { \
guarantee(Rs != Rn && Rs != Rt, "unpredictable instruction"); \
! load_store_exclusive(Rs, Rt, dummy_reg, Rn, sz, op, o0); \
}
#define INSN2(NAME, sz, op, o0) /* Two registers */ \
void NAME(Register Rt, Register Rn) { \
! load_store_exclusive(dummy_reg, Rt, dummy_reg, \
Rn, sz, op, o0); \
}
#define INSN_FOO(NAME, sz, op, o0) /* Three registers, encoded differently */ \
void NAME(Register Rt1, Register Rt2, Register Rn) { \
guarantee(Rt1 != Rt2, "unpredictable instruction"); \
! load_store_exclusive(dummy_reg, Rt1, Rt2, Rn, sz, op, o0); \
}
// bytes
INSN3(stxrb, byte, 0b000, 0);
INSN3(stlxrb, byte, 0b000, 1);
*** 1167,1176 ****
--- 1179,1228 ----
#undef INSN2
#undef INSN3
#undef INSN4
#undef INSN_FOO
+ // 8.1 Compare and swap extensions
+ void lse_cas(Register Rs, Register Rt, Register Rn,
+ enum operand_size sz, bool a, bool r, bool not_pair) {
+ starti;
+ if (! not_pair) { // Pair
+ assert(sz == word || sz == xword, "invalid size");
+ /* The size bit is in bit 30, not 31 */
+ sz = (operand_size)(sz == word ? 0b00:0b01);
+ }
+ 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, a, r) \
+ void NAME(operand_size sz, Register Rs, Register Rt, Register Rn) { \
+ assert(Rs != Rn && Rs != Rt, "unpredictable instruction"); \
+ lse_cas(Rs, Rt, Rn, sz, a, r, true); \
+ }
+ INSN(cas, false, false)
+ INSN(casa, true, false)
+ INSN(casl, false, true)
+ INSN(casal, true, true)
+ #undef INSN
+
+ // CASP
+ #define INSN(NAME, a, r) \
+ void NAME(operand_size sz, 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"); \
+ lse_cas(Rs, Rt, Rn, sz, a, r, false); \
+ }
+ INSN(casp, false, false)
+ INSN(caspa, true, false)
+ INSN(caspl, false, true)
+ INSN(caspal, true, true)
+ #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 >