diff options
Diffstat (limited to 'dynasm/dasm_arm64.h')
-rw-r--r-- | dynasm/dasm_arm64.h | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/dynasm/dasm_arm64.h b/dynasm/dasm_arm64.h index 5ff4414c..8d1d9a96 100644 --- a/dynasm/dasm_arm64.h +++ b/dynasm/dasm_arm64.h | |||
@@ -21,9 +21,9 @@ enum { | |||
21 | /* The following actions need a buffer position. */ | 21 | /* The following actions need a buffer position. */ |
22 | DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG, | 22 | DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG, |
23 | /* The following actions also have an argument. */ | 23 | /* The following actions also have an argument. */ |
24 | DASM_REL_PC, DASM_LABEL_PC, | 24 | DASM_REL_PC, DASM_LABEL_PC, DASM_REL_A, |
25 | DASM_IMM, DASM_IMM6, DASM_IMM12, DASM_IMM13W, DASM_IMM13X, DASM_IMML, | 25 | DASM_IMM, DASM_IMM6, DASM_IMM12, DASM_IMM13W, DASM_IMM13X, DASM_IMML, |
26 | DASM_VREG, | 26 | DASM_IMMV, DASM_VREG, |
27 | DASM__MAX | 27 | DASM__MAX |
28 | }; | 28 | }; |
29 | 29 | ||
@@ -249,7 +249,7 @@ void dasm_put(Dst_DECL, int start, ...) | |||
249 | n = (ins & 255); CK(n < D->maxsection, RANGE_SEC); | 249 | n = (ins & 255); CK(n < D->maxsection, RANGE_SEC); |
250 | D->section = &D->sections[n]; goto stop; | 250 | D->section = &D->sections[n]; goto stop; |
251 | case DASM_ESC: p++; ofs += 4; break; | 251 | case DASM_ESC: p++; ofs += 4; break; |
252 | case DASM_REL_EXT: break; | 252 | case DASM_REL_EXT: if ((ins & 0x8000)) ofs += 8; break; |
253 | case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break; | 253 | case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break; |
254 | case DASM_REL_LG: | 254 | case DASM_REL_LG: |
255 | n = (ins & 2047) - 10; pl = D->lglabels + n; | 255 | n = (ins & 2047) - 10; pl = D->lglabels + n; |
@@ -270,6 +270,11 @@ void dasm_put(Dst_DECL, int start, ...) | |||
270 | *pl = pos; | 270 | *pl = pos; |
271 | } | 271 | } |
272 | pos++; | 272 | pos++; |
273 | if ((ins & 0x8000)) ofs += 8; | ||
274 | break; | ||
275 | case DASM_REL_A: | ||
276 | b[pos++] = n; | ||
277 | b[pos++] = va_arg(ap, int); | ||
273 | break; | 278 | break; |
274 | case DASM_LABEL_LG: | 279 | case DASM_LABEL_LG: |
275 | pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel; | 280 | pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel; |
@@ -321,6 +326,10 @@ void dasm_put(Dst_DECL, int start, ...) | |||
321 | b[pos++] = n; | 326 | b[pos++] = n; |
322 | break; | 327 | break; |
323 | } | 328 | } |
329 | case DASM_IMMV: | ||
330 | ofs += 4; | ||
331 | b[pos++] = n; | ||
332 | break; | ||
324 | case DASM_VREG: | 333 | case DASM_VREG: |
325 | CK(n < 32, RANGE_VREG); | 334 | CK(n < 32, RANGE_VREG); |
326 | b[pos++] = n; | 335 | b[pos++] = n; |
@@ -381,8 +390,8 @@ int dasm_link(Dst_DECL, size_t *szp) | |||
381 | case DASM_REL_LG: case DASM_REL_PC: pos++; break; | 390 | case DASM_REL_LG: case DASM_REL_PC: pos++; break; |
382 | case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break; | 391 | case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break; |
383 | case DASM_IMM: case DASM_IMM6: case DASM_IMM12: case DASM_IMM13W: | 392 | case DASM_IMM: case DASM_IMM6: case DASM_IMM12: case DASM_IMM13W: |
384 | case DASM_IMML: case DASM_VREG: pos++; break; | 393 | case DASM_IMML: case DASM_IMMV: case DASM_VREG: pos++; break; |
385 | case DASM_IMM13X: pos += 2; break; | 394 | case DASM_IMM13X: case DASM_REL_A: pos += 2; break; |
386 | } | 395 | } |
387 | } | 396 | } |
388 | stop: (void)0; | 397 | stop: (void)0; |
@@ -433,7 +442,9 @@ int dasm_encode(Dst_DECL, void *buffer) | |||
433 | break; | 442 | break; |
434 | case DASM_REL_LG: | 443 | case DASM_REL_LG: |
435 | if (n < 0) { | 444 | if (n < 0) { |
436 | n = (int)((ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp + 4); | 445 | ptrdiff_t na = (ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp + 4; |
446 | n = (int)na; | ||
447 | CK((ptrdiff_t)n == na, RANGE_REL); | ||
437 | goto patchrel; | 448 | goto patchrel; |
438 | } | 449 | } |
439 | /* fallthrough */ | 450 | /* fallthrough */ |
@@ -455,8 +466,18 @@ int dasm_encode(Dst_DECL, void *buffer) | |||
455 | } else if ((ins & 0x1000)) { /* TBZ, TBNZ */ | 466 | } else if ((ins & 0x1000)) { /* TBZ, TBNZ */ |
456 | CK((n & 3) == 0 && ((n+0x00008000) >> 16) == 0, RANGE_REL); | 467 | CK((n & 3) == 0 && ((n+0x00008000) >> 16) == 0, RANGE_REL); |
457 | cp[-1] |= ((n << 3) & 0x0007ffe0); | 468 | cp[-1] |= ((n << 3) & 0x0007ffe0); |
469 | } else if ((ins & 0x8000)) { /* absolute */ | ||
470 | cp[0] = (unsigned int)((ptrdiff_t)cp - 4 + n); | ||
471 | cp[1] = (unsigned int)(((ptrdiff_t)cp - 4 + n) >> 32); | ||
472 | cp += 2; | ||
458 | } | 473 | } |
459 | break; | 474 | break; |
475 | case DASM_REL_A: { | ||
476 | ptrdiff_t na = (((ptrdiff_t)(*b++) << 32) | (unsigned int)n) - (ptrdiff_t)cp + 4; | ||
477 | n = (int)na; | ||
478 | CK((ptrdiff_t)n == na, RANGE_REL); | ||
479 | goto patchrel; | ||
480 | } | ||
460 | case DASM_LABEL_LG: | 481 | case DASM_LABEL_LG: |
461 | ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n); | 482 | ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n); |
462 | break; | 483 | break; |
@@ -482,6 +503,9 @@ int dasm_encode(Dst_DECL, void *buffer) | |||
482 | ((n << (10-scale)) | 0x01000000) : ((n & 511) << 12); | 503 | ((n << (10-scale)) | 0x01000000) : ((n & 511) << 12); |
483 | break; | 504 | break; |
484 | } | 505 | } |
506 | case DASM_IMMV: | ||
507 | *cp++ = n; | ||
508 | break; | ||
485 | case DASM_VREG: | 509 | case DASM_VREG: |
486 | cp[-1] |= (n & 0x1f) << (ins & 0x1f); | 510 | cp[-1] |= (n & 0x1f) << (ins & 0x1f); |
487 | break; | 511 | break; |