12#define DASM_ARCH "arm64"
15#define DASM_EXTERN(a,b,c,d) 0
31#define DASM_MAXSECPOS 25
34#define DASM_S_OK 0x00000000
35#define DASM_S_NOMEM 0x01000000
36#define DASM_S_PHASE 0x02000000
37#define DASM_S_MATCH_SEC 0x03000000
38#define DASM_S_RANGE_I 0x11000000
39#define DASM_S_RANGE_SEC 0x12000000
40#define DASM_S_RANGE_LG 0x13000000
41#define DASM_S_RANGE_PC 0x14000000
42#define DASM_S_RANGE_REL 0x15000000
43#define DASM_S_RANGE_VREG 0x16000000
44#define DASM_S_UNDEF_LG 0x21000000
45#define DASM_S_UNDEF_PC 0x22000000
48#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
49#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
50#define DASM_SEC2POS(sec) ((sec)<<24)
51#define DASM_POS2SEC(pos) ((pos)>>24)
52#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
84#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
87#define DASM_PTR_SUB(p1, off) ((void *) ((uintptr_t) (p1) - sizeof(*p1) * (uintptr_t) (off)))
88#define DASM_PTR_ADD(p1, off) ((void *) ((uintptr_t) (p1) + sizeof(*p1) * (uintptr_t) (off)))
104 D->maxsection = maxsection;
113 for (i = 0; i <
D->maxsection; i++)
114 if (
D->sections[i].buf)
126 DASM_M_GROW(Dst,
int,
D->lglabels,
D->lgsize, (10+maxgl)*
sizeof(
int));
133 size_t osz =
D->pcsize;
134 DASM_M_GROW(Dst,
int,
D->pclabels,
D->pcsize, maxpc*
sizeof(
int));
135 memset((
void *)(((
unsigned char *)
D->pclabels)+osz), 0,
D->pcsize-osz);
145 D->section = &
D->sections[0];
146 memset((
void *)
D->lglabels, 0,
D->lgsize);
147 if (
D->pclabels)
memset((
void *)
D->pclabels, 0,
D->pcsize);
148 for (i = 0; i <
D->maxsection; i++) {
150 D->sections[i].rbuf =
DASM_PTR_SUB(
D->sections[i].buf,
D->sections[i].pos);
151 D->sections[i].ofs = 0;
159 D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)
160#define CKPL(kind, st) \
161 do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
162 D->status = DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)
164#define CK(x, st) ((void)0)
165#define CKPL(kind, st) ((void)0)
168static int dasm_imm12(
unsigned int n)
172 else if ((
n & 0xff000fff) == 0)
173 return (
n >> 12) | 0x1000;
178static int dasm_ffs(
unsigned long long x)
181 while (x) { x >>= 1;
n++; }
185static int dasm_imm13(
int lo,
int hi)
187 int inv = 0, w = 64,
s = 0xfff, xa, xb;
188 unsigned long long n = (((
unsigned long long)hi) << 32) | (
unsigned int)lo;
189 unsigned long long m = 1ULL,
a, b, c;
190 if (
n & 1) {
n =
~n; inv = 1; }
191 a =
n & (
unsigned long long)-(
long long)
n;
192 b = (
n+
a)&(
unsigned long long)-(
long long)(
n+
a);
193 c = (
n+
a-b)&(
unsigned long long)-(
long long)(
n+
a-b);
194 xa = dasm_ffs(
a); xb = dasm_ffs(b);
196 w = dasm_ffs(c) - xa;
197 if (w == 32) m = 0x0000000100000001UL;
198 else if (w == 16) m = 0x0001000100010001UL;
199 else if (w == 8) m = 0x0101010101010101UL;
200 else if (w == 4) m = 0x1111111111111111UL;
201 else if (w == 2) m = 0x5555555555555555UL;
203 s = (-2*w & 0x3f) - 1;
206 }
else if (xb == -1) {
209 if ((b-
a) * m !=
n)
return -1;
211 return ((w - xb) << 6) | (
s+w+xa-xb);
213 return ((w - xa) << 6) | (
s+xb-xa);
240 unsigned int ins = *
p++;
241 unsigned int action = (ins >> 16);
245 int *pl,
n = action >=
DASM_REL_PC ? va_arg(ap,
int) : 0;
249 n = (ins & 255);
CK(
n < D->maxsection, RANGE_SEC);
250 D->section = &
D->sections[
n];
goto stop;
255 n = (ins & 2047) - 10; pl =
D->lglabels +
n;
257 if (
n >= 0) {
CK(
n>=10||*pl<0, RANGE_LG);
CKPL(lg,
LG);
goto putrel; }
262 pl =
D->pclabels +
n;
CKPL(pc, PC);
273 if ((ins & 0x8000)) ofs += 8;
277 b[
pos++] = va_arg(ap,
int);
280 pl =
D->lglabels + (ins & 2047) - 10;
CKPL(lg,
LG);
goto putlabel;
282 pl =
D->pclabels +
n;
CKPL(pc, PC);
291 CK((
n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
292 n >>= ((ins>>10)&31);
295 CK(((
n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
297 CK((
n>>((ins>>5)&31)) == 0, RANGE_I);
302 CK((
n >> 6) == 0, RANGE_I);
306 CK(dasm_imm12((
unsigned int)
n) != -1, RANGE_I);
310 CK(dasm_imm13(
n,
n) != -1, RANGE_I);
314 int m = va_arg(ap,
int);
315 CK(dasm_imm13(
n, m) != -1, RANGE_I);
322 int scale = (ins & 3);
323 CK((!(
n & ((1<<scale)-1)) && (
unsigned int)(
n>>scale) < 4096) ||
324 (
unsigned int)(
n+256) < 512, RANGE_I);
334 CK(
n < 32, RANGE_VREG);
359 for (pc = 0; pc*
sizeof(int) <
D->pcsize; pc++)
366 for (idx = 10; idx*
sizeof(int) <
D->lgsize; idx++) {
367 int n =
D->lglabels[idx];
374 for (secnum = 0; secnum <
D->maxsection; secnum++) {
378 int lastpos = sec->
pos;
380 while (
pos != lastpos) {
383 unsigned int ins = *
p++;
384 unsigned int action = (ins >> 16);
389 case DASM_ALIGN: ofs -= (b[
pos++] + ofs) & (ins & 255);
break;
407#ifdef DASM_ADD_VENEER
408#define CK_REL(x, o) \
409 do { if (!(x) && !(n = DASM_ADD_VENEER(D, buffer, ins, b, cp, o))) \
410 return DASM_S_RANGE_REL|(p-D->actionlist-1); \
413#define CK_REL(x, o) CK(x, RANGE_REL)
418 do { if (!(x)) return DASM_S_##st|(int)(p-D->actionlist-1); } while (0)
420#define CK(x, st) ((void)0)
427 char *base = (
char *)
buffer;
428 unsigned int *
cp = (
unsigned int *)
buffer;
432 for (secnum = 0; secnum <
D->maxsection; secnum++) {
440 unsigned int ins = *
p++;
441 unsigned int action = (ins >> 16);
447 n =
DASM_EXTERN(Dst, (
unsigned char *)
cp, (ins&2047), !(ins&2048));
450 ins &= 255;
while ((((
char *)
cp - base) & ins)) *
cp++ = 0xd503201f;
461 CK(
n >= 0, UNDEF_PC);
464 if (!(ins & 0xf800)) {
465 CK_REL((
n & 3) == 0 && ((
n+0x08000000) >> 28) == 0,
n);
466 cp[-1] |= ((
n >> 2) & 0x03ffffff);
467 }
else if ((ins & 0x800)) {
468 CK_REL((
n & 3) == 0 && ((
n+0x00100000) >> 21) == 0,
n);
469 cp[-1] |= (((unsigned)
n << 3) & 0x00ffffe0);
470 }
else if ((ins & 0x3000) == 0x2000) {
471 CK_REL(((
n+0x00100000) >> 21) == 0,
n);
472 cp[-1] |= (((unsigned)
n << 3) & 0x00ffffe0) | ((
n & 3) << 29);
473 }
else if ((ins & 0x3000) == 0x3000) {
474 cp[-1] |= ((
n >> 9) & 0x00ffffe0) | (((
n >> 12) & 3) << 29);
475 }
else if ((ins & 0x1000)) {
476 CK_REL((
n & 3) == 0 && ((
n+0x00008000) >> 16) == 0,
n);
477 cp[-1] |= (((unsigned)
n << 3) & 0x0007ffe0);
478 }
else if ((ins & 0x8000)) {
486 if ((ins & 0x3000) == 0x3000) {
497 ins &= 2047;
if (ins >= 20)
D->globals[ins-20] = (
void *)(base +
n);
501 cp[-1] |= (
n & ((1<<((ins>>5)&31))-1)) << (ins&31);
504 cp[-1] |= ((
n&31) << 19) | ((
n&32) << 26);
507 cp[-1] |= (dasm_imm12((
unsigned int)
n) << 10);
510 cp[-1] |= (dasm_imm13(
n,
n) << 10);
513 cp[-1] |= (dasm_imm13(
n, *b++) << 10);
516 int scale = (ins & 3);
517 cp[-1] |= (!(
n & ((1<<scale)-1)) && (
unsigned int)(
n>>scale) < 4096) ?
518 ((
n << (10-scale)) | 0x01000000) : ((
n & 511) << 12);
525 cp[-1] |= (
n & 0x1f) << (ins & 0x1f);
527 default: *
cp++ = ins;
break;
534 if (base +
D->codesize != (
char *)
cp)
544 if (pc*
sizeof(
int) <
D->pcsize) {
545 int pos =
D->pclabels[pc];
547 if (
pos > 0)
return -1;
559 for (i = 1; i <= 9; i++) {
564 if (
D->status ==
DASM_S_OK && secmatch >= 0 &&
565 D->section != &
D->sections[secmatch])
void dasm_put(Dst_DECL, int start,...)
void dasm_growpc(Dst_DECL, unsigned int maxpc)
int dasm_encode(Dst_DECL, void *buffer)
#define DASM_PTR_ADD(p1, off)
void dasm_init(Dst_DECL, int maxsection)
#define DASM_POS2PTR(D, pos)
#define DASM_POS2BIAS(pos)
#define DASM_PTR_SUB(p1, off)
#define DASM_EXTERN(a, b, c, d)
void dasm_setup(Dst_DECL, const void *actionlist)
int dasm_getpclabel(Dst_DECL, unsigned int pc)
int dasm_link(Dst_DECL, size_t *szp)
#define DASM_SEC2POS(sec)
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
const unsigned int * dasm_ActList
#define dasm_checkstep(a, b)
#define DASM_M_FREE(ctx, p, sz)
#define DASM_M_GROW(ctx, t, p, sz, need)
struct dasm_Section dasm_Section
const unsigned char * dasm_ActList
memset(ptr, 0, type->size)
zend_ffi_ctype_name_buf buf
unsigned const char * pos
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)