< prev index next >

src/cpu/aarch64/vm/assembler_aarch64.hpp

Print this page
rev 10437 : 8151775: aarch64: add support for 8.1 LSE atomic operations
Reviewed-by: aph


1204   INSN(casa,   true,  false)
1205   INSN(casl,   false, true)
1206   INSN(casal,  true,  true)
1207 #undef INSN
1208 
1209   // CASP
1210 #define INSN(NAME, a, r)                                                \
1211   void NAME(operand_size sz, Register Rs, Register Rs1,                 \
1212             Register Rt, Register Rt1, Register Rn) {                   \
1213     assert((Rs->encoding() & 1) == 0 && (Rt->encoding() & 1) == 0 &&    \
1214            Rs->successor() == Rs1 && Rt->successor() == Rt1 &&          \
1215            Rs != Rn && Rs1 != Rn && Rs != Rt, "invalid registers");     \
1216     lse_cas(Rs, Rt, Rn, sz, a, r, false);                               \
1217   }
1218   INSN(casp,    false, false)
1219   INSN(caspa,   true,  false)
1220   INSN(caspl,   false, true)
1221   INSN(caspal,  true,  true)
1222 #undef INSN
1223 
































1224   // Load register (literal)
1225 #define INSN(NAME, opc, V)                                              \
1226   void NAME(Register Rt, address dest) {                                \
1227     long offset = (dest - pc()) >> 2;                                   \
1228     starti;                                                             \
1229     f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24),        \
1230       sf(offset, 23, 5);                                                \
1231     rf(Rt, 0);                                                          \
1232   }                                                                     \
1233   void NAME(Register Rt, address dest, relocInfo::relocType rtype) {    \
1234     InstructionMark im(this);                                           \
1235     guarantee(rtype == relocInfo::internal_word_type,                   \
1236               "only internal_word_type relocs make sense here");        \
1237     code_section()->relocate(inst_mark(), InternalAddress(dest).rspec()); \
1238     NAME(Rt, dest);                                                     \
1239   }                                                                     \
1240   void NAME(Register Rt, Label &L) {                                    \
1241     wrap_label(Rt, L, &Assembler::NAME);                                \
1242   }
1243 




1204   INSN(casa,   true,  false)
1205   INSN(casl,   false, true)
1206   INSN(casal,  true,  true)
1207 #undef INSN
1208 
1209   // CASP
1210 #define INSN(NAME, a, r)                                                \
1211   void NAME(operand_size sz, Register Rs, Register Rs1,                 \
1212             Register Rt, Register Rt1, Register Rn) {                   \
1213     assert((Rs->encoding() & 1) == 0 && (Rt->encoding() & 1) == 0 &&    \
1214            Rs->successor() == Rs1 && Rt->successor() == Rt1 &&          \
1215            Rs != Rn && Rs1 != Rn && Rs != Rt, "invalid registers");     \
1216     lse_cas(Rs, Rt, Rn, sz, a, r, false);                               \
1217   }
1218   INSN(casp,    false, false)
1219   INSN(caspa,   true,  false)
1220   INSN(caspl,   false, true)
1221   INSN(caspal,  true,  true)
1222 #undef INSN
1223 
1224   // 8.1 Atomic operations
1225   void lse_atomic(Register Rs, Register Rt, Register Rn,
1226                   enum operand_size sz, int op1, int op2, bool a, bool r) {
1227     starti;
1228     f(sz, 31, 30), f(0b111000, 29, 24), f(a, 23), f(r, 22), f(1, 21);
1229     rf(Rs, 16), f(op1, 15), f(op2, 14, 12), f(0, 11, 10), rf(Rn, 5), rf(Rt, 0);
1230   }
1231 
1232 #define INSN(NAME, NAME_A, NAME_L, NAME_AL, op1, op2)                   \
1233   void NAME(operand_size sz, Register Rs, Register Rt, Register Rn) {   \
1234     lse_atomic(Rs, Rt, Rn, sz, op1, op2, false, false);                 \
1235   }                                                                     \
1236   void NAME_A(operand_size sz, Register Rs, Register Rt, Register Rn) { \
1237     lse_atomic(Rs, Rt, Rn, sz, op1, op2, true, false);                  \
1238   }                                                                     \
1239   void NAME_L(operand_size sz, Register Rs, Register Rt, Register Rn) { \
1240     lse_atomic(Rs, Rt, Rn, sz, op1, op2, false, true);                  \
1241   }                                                                     \
1242   void NAME_AL(operand_size sz, Register Rs, Register Rt, Register Rn) {\
1243     lse_atomic(Rs, Rt, Rn, sz, op1, op2, true, true);                   \
1244   }
1245   INSN(ldadd,  ldadda,  ldaddl,  ldaddal,  0, 0b000);
1246   INSN(ldbic,  ldbica,  ldbicl,  ldbical,  0, 0b001);
1247   INSN(ldeor,  ldeora,  ldeorl,  ldeoral,  0, 0b010);
1248   INSN(ldorr,  ldorra,  ldorrl,  ldorral,  0, 0b011);
1249   INSN(ldsmax, ldsmaxa, ldsmaxl, ldsmaxal, 0, 0b100);
1250   INSN(ldsmin, ldsmina, ldsminl, ldsminal, 0, 0b101);
1251   INSN(ldumax, ldumaxa, ldumaxl, ldumaxal, 0, 0b110);
1252   INSN(ldumin, ldumina, lduminl, lduminal, 0, 0b111);
1253   INSN(swp,    swpa,    swpl,    swpal,    1, 0b000);
1254 #undef INSN
1255 
1256   // Load register (literal)
1257 #define INSN(NAME, opc, V)                                              \
1258   void NAME(Register Rt, address dest) {                                \
1259     long offset = (dest - pc()) >> 2;                                   \
1260     starti;                                                             \
1261     f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24),        \
1262       sf(offset, 23, 5);                                                \
1263     rf(Rt, 0);                                                          \
1264   }                                                                     \
1265   void NAME(Register Rt, address dest, relocInfo::relocType rtype) {    \
1266     InstructionMark im(this);                                           \
1267     guarantee(rtype == relocInfo::internal_word_type,                   \
1268               "only internal_word_type relocs make sense here");        \
1269     code_section()->relocate(inst_mark(), InternalAddress(dest).rspec()); \
1270     NAME(Rt, dest);                                                     \
1271   }                                                                     \
1272   void NAME(Register Rt, Label &L) {                                    \
1273     wrap_label(Rt, L, &Assembler::NAME);                                \
1274   }
1275 


< prev index next >