1152 INSN2(stlrw, word, 0b100, 1);
1153 INSN2(ldarw, word, 0b110, 1);
1154
1155 // xwords
1156 INSN3(stxr, xword, 0b000, 0);
1157 INSN3(stlxr, xword, 0b000, 1);
1158 INSN4(stxp, xword, 0b001, 0);
1159 INSN4(stlxp, xword, 0b001, 1);
1160 INSN2(ldxr, xword, 0b010, 0);
1161 INSN2(ldaxr, xword, 0b010, 1);
1162 INSN_FOO(ldxp, xword, 0b011, 0);
1163 INSN_FOO(ldaxp, xword, 0b011, 1);
1164 INSN2(stlr, xword, 0b100, 1);
1165 INSN2(ldar, xword, 0b110, 1);
1166
1167 #undef INSN2
1168 #undef INSN3
1169 #undef INSN4
1170 #undef INSN_FOO
1171
1172 // Load register (literal)
1173 #define INSN(NAME, opc, V) \
1174 void NAME(Register Rt, address dest) { \
1175 long offset = (dest - pc()) >> 2; \
1176 starti; \
1177 f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24), \
1178 sf(offset, 23, 5); \
1179 rf(Rt, 0); \
1180 } \
1181 void NAME(Register Rt, address dest, relocInfo::relocType rtype) { \
1182 InstructionMark im(this); \
1183 guarantee(rtype == relocInfo::internal_word_type, \
1184 "only internal_word_type relocs make sense here"); \
1185 code_section()->relocate(inst_mark(), InternalAddress(dest).rspec()); \
1186 NAME(Rt, dest); \
1187 } \
1188 void NAME(Register Rt, Label &L) { \
1189 wrap_label(Rt, L, &Assembler::NAME); \
1190 }
1191
|
1152 INSN2(stlrw, word, 0b100, 1);
1153 INSN2(ldarw, word, 0b110, 1);
1154
1155 // xwords
1156 INSN3(stxr, xword, 0b000, 0);
1157 INSN3(stlxr, xword, 0b000, 1);
1158 INSN4(stxp, xword, 0b001, 0);
1159 INSN4(stlxp, xword, 0b001, 1);
1160 INSN2(ldxr, xword, 0b010, 0);
1161 INSN2(ldaxr, xword, 0b010, 1);
1162 INSN_FOO(ldxp, xword, 0b011, 0);
1163 INSN_FOO(ldaxp, xword, 0b011, 1);
1164 INSN2(stlr, xword, 0b100, 1);
1165 INSN2(ldar, xword, 0b110, 1);
1166
1167 #undef INSN2
1168 #undef INSN3
1169 #undef INSN4
1170 #undef INSN_FOO
1171
1172 // 8.1 Compare and swap extensions
1173 void compare_and_swap(Register Rs, Register Rt, Register Rn,
1174 enum operand_size sz, int op, int a, int r) {
1175 starti;
1176 f(sz, 31, 30), f(0b001000, 29, 24), f(1, 23), f(a, 22), f(1, 21);
1177 rf(Rs, 16), f(r, 15), f(0b11111, 14, 10), rf(Rn, 5), rf(Rt, 0);
1178 }
1179
1180 // CAS
1181 #define INSN(NAME, sz, a, r) \
1182 void NAME(Register Rs, Register Rt, Register Rn) { \
1183 assert(Rs != Rn && Rs != Rt, "unpredictable instruction"); \
1184 compare_and_swap(Rs, Rt, Rn, sz, 1, a, r); \
1185 }
1186 INSN(casb, byte, 0, 0)
1187 INSN(cash, halfword, 0, 0)
1188 INSN(casw, word, 0, 0)
1189 INSN(cas, xword, 0, 0)
1190 INSN(casab, byte, 1, 0)
1191 INSN(casah, halfword, 1, 0)
1192 INSN(casaw, word, 1, 0)
1193 INSN(casa, xword, 1, 0)
1194 INSN(caslb, byte, 0, 1)
1195 INSN(caslh, halfword, 0, 1)
1196 INSN(caslw, word, 0, 1)
1197 INSN(casl, xword, 0, 1)
1198 INSN(casalb, byte, 1, 1)
1199 INSN(casalh, halfword, 1, 1)
1200 INSN(casalw, word, 1, 1)
1201 INSN(casal, xword, 1, 1)
1202 #undef INSN
1203
1204 // CASP
1205 #define INSN(NAME, sz, a, r) \
1206 void NAME(Register Rs, Register Rs1, \
1207 Register Rt, Register Rt1, Register Rn) { \
1208 assert((Rs->encoding() & 1) == 0 && (Rt->encoding() & 1) == 0 && \
1209 Rs->successor() == Rs1 && Rt->successor() == Rt1 && \
1210 Rs != Rn && Rs1 != Rn && Rs != Rt, "invalid registers"); \
1211 assert(sz == word || sz == xword, "invalid size"); \
1212 /* The size bit is in bit 30, not 31 as in ldx/stx above */ \
1213 compare_and_swap(Rs, Rt, Rn, \
1214 (operand_size)(sz == word ? 0b00:0b01), 0, a, r); \
1215 }
1216 INSN(caspw, word, 0, 0)
1217 INSN(casp, xword, 0, 0)
1218 INSN(caspaw, word, 1, 0)
1219 INSN(caspa, xword, 1, 0)
1220 INSN(casplw, word, 0, 1)
1221 INSN(caspl, xword, 0, 1)
1222 INSN(caspalw, word, 1, 1)
1223 INSN(caspal, xword, 1, 1)
1224 #undef INSN
1225
1226 // Load register (literal)
1227 #define INSN(NAME, opc, V) \
1228 void NAME(Register Rt, address dest) { \
1229 long offset = (dest - pc()) >> 2; \
1230 starti; \
1231 f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24), \
1232 sf(offset, 23, 5); \
1233 rf(Rt, 0); \
1234 } \
1235 void NAME(Register Rt, address dest, relocInfo::relocType rtype) { \
1236 InstructionMark im(this); \
1237 guarantee(rtype == relocInfo::internal_word_type, \
1238 "only internal_word_type relocs make sense here"); \
1239 code_section()->relocate(inst_mark(), InternalAddress(dest).rspec()); \
1240 NAME(Rt, dest); \
1241 } \
1242 void NAME(Register Rt, Label &L) { \
1243 wrap_label(Rt, L, &Assembler::NAME); \
1244 }
1245
|