212 uint32_t uval = extract(val, msb, lsb);
213 return extend(uval, msb - lsb);
214 }
215
216 static ALWAYSINLINE void patch(address a, int msb, int lsb, uint64_t val) {
217 int nbits = msb - lsb + 1;
218 guarantee(val < (1ULL << nbits), "Field too big for insn");
219 assert_cond(msb >= lsb);
220 unsigned mask = checked_cast<unsigned>(right_n_bits(nbits));
221 val <<= lsb;
222 mask <<= lsb;
223 unsigned target = *(unsigned *)a;
224 target &= ~mask;
225 target |= (unsigned)val;
226 *(unsigned *)a = target;
227 }
228
229 static void spatch(address a, int msb, int lsb, int64_t val) {
230 int nbits = msb - lsb + 1;
231 int64_t chk = val >> (nbits - 1);
232 guarantee (chk == -1 || chk == 0, "Field too big for insn at " INTPTR_FORMAT, p2i(a));
233 uint64_t uval = val;
234 unsigned mask = checked_cast<unsigned>(right_n_bits(nbits));
235 uval &= mask;
236 uval <<= lsb;
237 mask <<= lsb;
238 unsigned target = *(unsigned *)a;
239 target &= ~mask;
240 target |= (unsigned)uval;
241 *(unsigned *)a = target;
242 }
243
244 void f(unsigned val, int msb, int lsb) {
245 int nbits = msb - lsb + 1;
246 guarantee(val < (1ULL << nbits), "Field too big for insn");
247 assert_cond(msb >= lsb);
248 val <<= lsb;
249 insn |= val;
250 #ifdef ASSERT
251 unsigned mask = checked_cast<unsigned>(right_n_bits(nbits));
252 mask <<= lsb;
253 assert_cond((bits & mask) == 0);
254 bits |= mask;
255 #endif
256 }
257
258 void f(unsigned val, int bit) {
259 f(val, bit, bit);
260 }
261
262 void sf(int64_t val, int msb, int lsb) {
263 int nbits = msb - lsb + 1;
264 int64_t chk = val >> (nbits - 1);
265 guarantee (chk == -1 || chk == 0, "Field too big for insn");
266 uint64_t uval = val;
267 unsigned mask = checked_cast<unsigned>(right_n_bits(nbits));
268 uval &= mask;
269 f((unsigned)uval, lsb + nbits - 1, lsb);
270 }
271
272 void rf(Register r, int lsb) {
273 f(r->raw_encoding(), lsb + 4, lsb);
274 }
275
276 // reg|ZR
277 void zrf(Register r, int lsb) {
278 f(r->raw_encoding() - (r == zr), lsb + 4, lsb);
279 }
280
281 // reg|SP
282 void srf(Register r, int lsb) {
283 f(r == sp ? 31 : r->raw_encoding(), lsb + 4, lsb);
284 }
285
|
212 uint32_t uval = extract(val, msb, lsb);
213 return extend(uval, msb - lsb);
214 }
215
216 static ALWAYSINLINE void patch(address a, int msb, int lsb, uint64_t val) {
217 int nbits = msb - lsb + 1;
218 guarantee(val < (1ULL << nbits), "Field too big for insn");
219 assert_cond(msb >= lsb);
220 unsigned mask = checked_cast<unsigned>(right_n_bits(nbits));
221 val <<= lsb;
222 mask <<= lsb;
223 unsigned target = *(unsigned *)a;
224 target &= ~mask;
225 target |= (unsigned)val;
226 *(unsigned *)a = target;
227 }
228
229 static void spatch(address a, int msb, int lsb, int64_t val) {
230 int nbits = msb - lsb + 1;
231 int64_t chk = val >> (nbits - 1);
232 guarantee (chk == -1 || chk == 0, "Field " INT64_FORMAT_X_0 " too big (nbits: %d) for insn at " INTPTR_FORMAT, val, nbits, p2i(a));
233 uint64_t uval = val;
234 unsigned mask = checked_cast<unsigned>(right_n_bits(nbits));
235 uval &= mask;
236 uval <<= lsb;
237 mask <<= lsb;
238 unsigned target = *(unsigned *)a;
239 target &= ~mask;
240 target |= (unsigned)uval;
241 *(unsigned *)a = target;
242 }
243
244 void f(unsigned val, int msb, int lsb) {
245 int nbits = msb - lsb + 1;
246 guarantee(val < (1ULL << nbits), "Field too big for insn");
247 assert_cond(msb >= lsb);
248 val <<= lsb;
249 insn |= val;
250 #ifdef ASSERT
251 unsigned mask = checked_cast<unsigned>(right_n_bits(nbits));
252 mask <<= lsb;
253 assert_cond((bits & mask) == 0);
254 bits |= mask;
255 #endif
256 }
257
258 void f(unsigned val, int bit) {
259 f(val, bit, bit);
260 }
261
262 void sf(int64_t val, int msb, int lsb) {
263 int nbits = msb - lsb + 1;
264 int64_t chk = val >> (nbits - 1);
265 guarantee (chk == -1 || chk == 0, "Field " INT64_FORMAT_X_0 " too big (nbits: %d) for insn", val, nbits);
266 uint64_t uval = val;
267 unsigned mask = checked_cast<unsigned>(right_n_bits(nbits));
268 uval &= mask;
269 f((unsigned)uval, lsb + nbits - 1, lsb);
270 }
271
272 void rf(Register r, int lsb) {
273 f(r->raw_encoding(), lsb + 4, lsb);
274 }
275
276 // reg|ZR
277 void zrf(Register r, int lsb) {
278 f(r->raw_encoding() - (r == zr), lsb + 4, lsb);
279 }
280
281 // reg|SP
282 void srf(Register r, int lsb) {
283 f(r == sp ? 31 : r->raw_encoding(), lsb + 4, lsb);
284 }
285
|