12#define DASM_ARCH "arm"
15#define DASM_EXTERN(a,b,c,d) 0
30#define DASM_MAXSECPOS 25
33#define DASM_S_OK 0x00000000
34#define DASM_S_NOMEM 0x01000000
35#define DASM_S_PHASE 0x02000000
36#define DASM_S_MATCH_SEC 0x03000000
37#define DASM_S_RANGE_I 0x11000000
38#define DASM_S_RANGE_SEC 0x12000000
39#define DASM_S_RANGE_LG 0x13000000
40#define DASM_S_RANGE_PC 0x14000000
41#define DASM_S_RANGE_REL 0x15000000
42#define DASM_S_UNDEF_LG 0x21000000
43#define DASM_S_UNDEF_PC 0x22000000
46#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
47#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
48#define DASM_SEC2POS(sec) ((sec)<<24)
49#define DASM_POS2SEC(pos) ((pos)>>24)
50#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
82#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
99 D->maxsection = maxsection;
108 for (i = 0; i <
D->maxsection; i++)
109 if (
D->sections[i].buf)
121 DASM_M_GROW(Dst,
int,
D->lglabels,
D->lgsize, (10+maxgl)*
sizeof(
int));
128 size_t osz =
D->pcsize;
129 DASM_M_GROW(Dst,
int,
D->pclabels,
D->pcsize, maxpc*
sizeof(
int));
130 memset((
void *)(((
unsigned char *)
D->pclabels)+osz), 0,
D->pcsize-osz);
140 D->section = &
D->sections[0];
141 memset((
void *)
D->lglabels, 0,
D->lgsize);
142 if (
D->pclabels)
memset((
void *)
D->pclabels, 0,
D->pcsize);
143 for (i = 0; i <
D->maxsection; i++) {
145 D->sections[i].rbuf =
D->sections[i].buf -
D->sections[i].pos;
146 D->sections[i].ofs = 0;
154 D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
155#define CKPL(kind, st) \
156 do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
157 D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
159#define CK(x, st) ((void)0)
160#define CKPL(kind, st) ((void)0)
163static int dasm_imm12(
unsigned int n)
166 for (i = 0; i < 16; i++,
n = (
n << 2) | (
n >> 30))
167 if (
n <= 255)
return (
int)(
n + (i << 8));
193 unsigned int ins = *
p++;
194 unsigned int action = (ins >> 16);
198 int *pl,
n = action >=
DASM_REL_PC ? va_arg(ap,
int) : 0;
202 n = (ins & 255);
CK(
n < D->maxsection, RANGE_SEC);
203 D->section = &
D->sections[
n];
goto stop;
208 n = (ins & 2047) - 10; pl =
D->lglabels +
n;
210 if (
n >= 0) {
CK(
n>=10||*pl<0, RANGE_LG);
CKPL(lg,
LG);
goto putrel; }
215 pl =
D->pclabels +
n;
CKPL(pc, PC);
228 pl =
D->lglabels + (ins & 2047) - 10;
CKPL(lg,
LG);
goto putlabel;
230 pl =
D->pclabels +
n;
CKPL(pc, PC);
241 CK((
n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
243 CK(((
n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
245 CK((
n>>((ins>>5)&31)) == 0, RANGE_I);
250 CK((
n & 3) == 0, RANGE_I);
255 CK(
n >= 0 ? ((
n>>((ins>>5)&31)) == 0) :
256 (((-
n)>>((ins>>5)&31)) == 0), RANGE_I);
260 CK(dasm_imm12((
unsigned int)
n) != -1, RANGE_I);
285 for (pc = 0; pc*
sizeof(int) <
D->pcsize; pc++)
292 for (idx = 10; idx*
sizeof(int) <
D->lgsize; idx++) {
293 int n =
D->lglabels[idx];
300 for (secnum = 0; secnum <
D->maxsection; secnum++) {
304 int lastpos = sec->
pos;
306 while (
pos != lastpos) {
309 unsigned int ins = *
p++;
310 unsigned int action = (ins >> 16);
315 case DASM_ALIGN: ofs -= (b[
pos++] + ofs) & (ins & 255);
break;
334 do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)
336#define CK(x, st) ((void)0)
343 char *base = (
char *)
buffer;
344 unsigned int *
cp = (
unsigned int *)
buffer;
348 for (secnum = 0; secnum <
D->maxsection; secnum++) {
351 int *endb = sec->
rbuf + sec->
pos;
356 unsigned int ins = *
p++;
357 unsigned int action = (ins >> 16);
363 n =
DASM_EXTERN(Dst, (
unsigned char *)
cp, (ins&2047), !(ins&2048));
366 ins &= 255;
while ((((
char *)
cp - base) & ins)) *
cp++ = 0xe1a00000;
375 CK(
n >= 0, UNDEF_PC);
378 if ((ins & 0x800) == 0) {
379 CK((
n & 3) == 0 && ((
n+0x02000000) >> 26) == 0, RANGE_REL);
380 cp[-1] |= ((
n >> 2) & 0x00ffffff);
381 }
else if ((ins & 0x1000)) {
382 CK((
n & 3) == 0 && -256 <=
n &&
n <= 256, RANGE_REL);
384 }
else if ((ins & 0x2000) == 0) {
385 CK((
n & 3) == 0 && -4096 <=
n &&
n <= 4096, RANGE_REL);
388 CK((
n & 3) == 0 && -1020 <=
n &&
n <= 1020, RANGE_REL);
394 ins &= 2047;
if (ins >= 20)
D->globals[ins-20] = (
void *)(base +
n);
398 cp[-1] |= ((
n>>((ins>>10)&31)) & ((1<<((ins>>5)&31))-1)) << (ins&31);
401 cp[-1] |= dasm_imm12((
unsigned int)
n);
404 cp[-1] |= ((
n & 0xf000) << 4) | (
n & 0x0fff);
407 cp[-1] |=
n >= 0 ? (0x00800000 | (
n & 0x0f) | ((
n & 0xf0) << 4)) :
408 ((-
n & 0x0f) | ((-
n & 0xf0) << 4));
411 cp[-1] |=
n >= 0 ? (0x00800000 |
n) : (-
n);
413 default: *
cp++ = ins;
break;
420 if (base +
D->codesize != (
char *)
cp)
430 if (pc*
sizeof(
int) <
D->pcsize) {
431 int pos =
D->pclabels[pc];
433 if (
pos > 0)
return -1;
445 for (i = 1; i <= 9; i++) {
450 if (
D->status ==
DASM_S_OK && secmatch >= 0 &&
451 D->section != &
D->sections[secmatch])
void dasm_put(Dst_DECL, int start,...)
const unsigned int * dasm_ActList
void dasm_growpc(Dst_DECL, unsigned int maxpc)
int dasm_encode(Dst_DECL, void *buffer)
void dasm_init(Dst_DECL, int maxsection)
#define DASM_POS2PTR(D, pos)
#define DASM_POS2BIAS(pos)
#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)
#define dasm_checkstep(a, b)
#define DASM_M_FREE(ctx, p, sz)
#define DASM_M_GROW(ctx, t, p, sz, need)
const unsigned char * dasm_ActList
memset(ptr, 0, type->size)
unsigned const char * pos
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)