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
|