aboutsummaryrefslogtreecommitdiff
path: root/dynasm/dasm_arm64.h
diff options
context:
space:
mode:
Diffstat (limited to 'dynasm/dasm_arm64.h')
-rw-r--r--dynasm/dasm_arm64.h36
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;