Merge pull request #218 from saper/build-fixes
[envytools.git] / envydis / core-as.c
blob553fbf4a50889f912c49525ddc0def784ffb61ef
1 /*
2 * Copyright (C) 2009-2011 Marcelina Koƛcielnicka <mwk@0x04.net>
3 * All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
25 #include "dis-intern.h"
26 #include "envyas.h"
27 #include <assert.h>
29 struct iasctx {
30 const struct disisa *isa;
31 struct varinfo *varinfo;
32 struct litem **atoms;
33 int atomsnum;
34 int atomsmax;
37 struct matches *emptymatches() {
38 struct matches *res = calloc(sizeof *res, 1);
39 return res;
42 struct matches *alwaysmatches(int lpos) {
43 struct matches *res = calloc(sizeof *res, 1);
44 struct match m = { .lpos = lpos };
45 ADDARRAY(res->m, m);
46 return res;
49 struct matches *catmatches(struct matches *a, struct matches *b) {
50 int i;
51 for (i = 0; i < b->mnum; i++)
52 ADDARRAY(a->m, b->m[i]);
53 free(b->m);
54 free(b);
55 return a;
58 struct matches *mergematches(struct match a, struct matches *b) {
59 struct matches *res = emptymatches();
60 int i, j;
61 for (i = 0; i < b->mnum; i++) {
62 for (j = 0; j < MAXOPLEN; j++) {
63 ull cmask = a.m[j] & b->m[i].m[j];
64 if ((a.a[j] & cmask) != (b->m[i].a[j] & cmask))
65 break;
67 if (j == MAXOPLEN) {
68 struct match nm = b->m[i];
69 if (!nm.oplen)
70 nm.oplen = a.oplen;
71 for (j = 0; j < MAXOPLEN; j++) {
72 nm.a[j] |= a.a[j];
73 nm.m[j] |= a.m[j];
75 int j;
76 assert (a.nrelocs + nm.nrelocs <= 8);
77 for (j = 0; j < a.nrelocs; j++)
78 nm.relocs[nm.nrelocs + j] = a.relocs[j];
79 nm.nrelocs += a.nrelocs;
80 ADDARRAY(res->m, nm);
83 free(b->m);
84 free(b);
85 return res;
88 static inline ull bf_(int s, int l, ull *a, ull *m) {
89 int idx = s / 0x40;
90 int bit = s % 0x40;
91 ull res = 0;
92 ull m0 = (((1ull << l) - 1) << bit);
93 m[idx] |= m0;
94 res |= (a[idx] & m0) >> bit;
95 if (bit + l > 0x40) {
96 ull m1 = (((1ull << l) - 1) >> (0x40 - bit));
97 m[idx+1] |= m1;
98 res |= (a[idx+1] & m1) << (0x40 - bit);
100 return res;
102 #define BF(s, l) bf_(s, l, a, m)
104 ull getrbf_as(const struct rbitfield *bf, ull *a, ull *m, ull cpos) {
105 ull res = 0;
106 int pos = bf->shr;
107 int i;
108 for (i = 0; i < sizeof(bf->sbf) / sizeof(bf->sbf[0]); i++) {
109 res |= BF(bf->sbf[i].pos, bf->sbf[i].len) << pos;
110 pos += bf->sbf[i].len;
112 switch (bf->mode) {
113 case RBF_UNSIGNED:
114 break;
115 case RBF_SIGNED:
116 if (res & 1ull << (pos - 1))
117 res -= 1ull << pos;
118 break;
119 case RBF_SLIGHTLY_SIGNED:
120 if (res & 1ull << (pos - 1) && res & 1ull << (pos - 2))
121 res -= 1ull << pos;
122 break;
123 case RBF_ULTRASIGNED:
124 res -= 1ull << pos;
125 break;
127 if (bf->pcrel) {
128 // <3 xtensa.
129 res += (cpos + bf->pospreadd) & -(1ull << bf->shr);
131 res += bf->addend;
132 return res;
135 ull getbf_as(const struct bitfield *bf, ull *a, ull *m) {
136 ull res = 0;
137 int pos = bf->shr;
138 int i;
139 for (i = 0; i < sizeof(bf->sbf) / sizeof(bf->sbf[0]); i++) {
140 res |= BF(bf->sbf[i].pos, bf->sbf[i].len) << pos;
141 pos += bf->sbf[i].len;
143 switch (bf->mode) {
144 case BF_UNSIGNED:
145 break;
146 case BF_SIGNED:
147 if (res & 1ull << (pos - 1))
148 res -= 1ull << pos;
149 break;
150 case BF_SLIGHTLY_SIGNED:
151 if (res & 1ull << (pos - 1) && res & 1ull << (pos - 2))
152 res -= 1ull << pos;
153 break;
154 case BF_ULTRASIGNED:
155 res -= 1ull << pos;
156 break;
157 case BF_LUT:
158 res = bf->lut[res];
159 break;
161 res ^= bf->xorend;
162 res += bf->addend;
163 return res;
166 int setsbf (struct match *res, int pos, int len, ull num) {
167 if (!len)
168 return 1;
169 int idx = pos / 0x40;
170 pos %= 0x40;
171 ull m = ((1ull << len) - 1) << pos;
172 ull a = (num << pos) & m;
173 if ((a & m & res->m[idx]) == (res->a[idx] & m & res->m[idx])) {
174 res->a[idx] |= a;
175 res->m[idx] |= m;
176 } else {
177 return 0;
179 if (pos + len > 0x40) {
180 ull m1 = (((1ull << len) - 1) >> (0x40 - pos));
181 ull a1 = (num >> (0x40 - pos)) & m1;
182 if ((a1 & m1 & res->m[idx+1]) == (res->a[idx+1] & m1 & res->m[idx+1])) {
183 res->a[idx+1] |= a1;
184 res->m[idx+1] |= m1;
185 } else {
186 return 0;
189 return 1;
192 static int setrbf (struct match *res, const struct rbitfield *bf, struct easm_expr *expr) {
193 if (!easm_isimm(expr))
194 return 0;
195 if (expr->type != EASM_EXPR_NUM || bf->pcrel) {
196 assert (res->nrelocs != 8);
197 res->relocs[res->nrelocs].bf = bf;
198 res->relocs[res->nrelocs].expr = expr;
199 res->nrelocs++;
200 return 1;
202 ull num = expr->num - bf->addend;
203 num >>= bf->shr;
204 setsbf(res, bf->sbf[0].pos, bf->sbf[0].len, num);
205 num >>= bf->sbf[0].len;
206 setsbf(res, bf->sbf[1].pos, bf->sbf[1].len, num);
207 ull mask = ~0ull;
208 ull totalsz = bf->shr + bf->sbf[0].len + bf->sbf[1].len;
209 if (bf->wrapok && totalsz < 64)
210 mask = (1ull << totalsz) - 1;
211 return (getrbf_as(bf, res->a, res->m, 0) & mask) == (expr->num & mask);
214 static int setbf (struct match *res, const struct bitfield *bf, ull num) {
215 ull onum = num;
216 num = (num - bf->addend) ^ bf->xorend;
217 if (bf->lut) {
218 int max = 1 << (bf->sbf[0].len + bf->sbf[1].len);
219 int j = 0;
220 for (j = 0; j < max; j++)
221 if (bf->lut[j] == num)
222 break;
223 if (j == max)
224 return 0;
225 num = j;
227 num >>= bf->shr;
228 setsbf(res, bf->sbf[0].pos, bf->sbf[0].len, num);
229 num >>= bf->sbf[0].len;
230 setsbf(res, bf->sbf[1].pos, bf->sbf[1].len, num);
231 ull mask = ~0ull;
232 return (getbf_as(bf, res->a, res->m) & mask) == (onum & mask);
235 struct matches *tabdesc (struct iasctx *ctx, struct match m, const struct atom *atoms) {
236 if (!atoms->fun_as) {
237 struct matches *res = emptymatches();
238 ADDARRAY(res->m, m);
239 return res;
241 struct matches *ms = atoms->fun_as(ctx, atoms->arg, m.lpos);
242 if (!ms)
243 return 0;
244 ms = mergematches(m, ms);
245 atoms++;
246 if (!atoms->fun_as)
247 return ms;
248 struct matches *res = emptymatches();
249 int i;
250 for (i = 0; i < ms->mnum; i++) {
251 struct matches *tmp = tabdesc(ctx, ms->m[i], atoms);
252 if (tmp)
253 res = catmatches(res, tmp);
255 free(ms->m);
256 free(ms);
257 return res;
260 struct matches *atomtab_a APROTO {
261 const struct insn *tab = v;
262 struct matches *res = emptymatches();
263 int i;
264 for (i = 0; ; i++) {
265 if (var_ok(tab[i].fmask, tab[i].ptype, ctx->varinfo)) {
266 struct match sm = { 0, .a = {tab[i].val}, .m = {tab[i].mask}, .lpos = spos };
267 struct matches *subm = tabdesc(ctx, sm, tab[i].atoms);
268 if (subm)
269 res = catmatches(res, subm);
271 if (!tab[i].mask && !tab[i].fmask && !tab[i].ptype) break;
273 return res;
276 struct matches *atomopl_a APROTO {
277 struct matches *res = alwaysmatches(spos);
278 res->m[0].oplen = *(int*)v;
279 return res;
282 struct matches *atomsestart_a APROTO {
283 struct litem *li = ctx->atoms[spos];
284 if (li->type == LITEM_SESTART)
285 return alwaysmatches(spos+1);
286 else
287 return 0;
290 struct matches *atomseend_a APROTO {
291 struct litem *li = ctx->atoms[spos];
292 if (li->type == LITEM_SEEND)
293 return alwaysmatches(spos+1);
294 else
295 return 0;
298 struct matches *atomname_a APROTO {
299 if (spos == ctx->atomsnum)
300 return 0;
301 struct litem *li = ctx->atoms[spos];
302 if (li->type == LITEM_NAME && !strcmp(li->str, v))
303 return alwaysmatches(spos+1);
304 else
305 return 0;
308 struct matches *atomcmd_a APROTO {
309 if (spos == ctx->atomsnum || ctx->atoms[spos]->type != LITEM_EXPR)
310 return 0;
311 struct easm_expr *e = ctx->atoms[spos]->expr;
312 if (e->type == EASM_EXPR_LABEL && !strcmp(e->str, v))
313 return alwaysmatches(spos+1);
314 else
315 return 0;
318 struct matches *atomunk_a APROTO {
319 return 0;
322 struct matches *atomimm_a APROTO {
323 const struct bitfield *bf = v;
324 if (spos == ctx->atomsnum || ctx->atoms[spos]->type != LITEM_EXPR)
325 return 0;
326 struct matches *res = alwaysmatches(spos+1);
327 struct easm_expr *expr = ctx->atoms[spos]->expr;
328 if (expr->type == EASM_EXPR_NUM && setbf(res->m, bf, expr->num))
329 return res;
330 else {
331 free(res->m);
332 free(res);
333 return 0;
337 struct matches *atomrimm_a APROTO {
338 const struct rbitfield *bf = v;
339 if (spos == ctx->atomsnum || ctx->atoms[spos]->type != LITEM_EXPR)
340 return 0;
341 struct matches *res = alwaysmatches(spos+1);
342 if (setrbf(res->m, bf, ctx->atoms[spos]->expr))
343 return res;
344 else {
345 free(res->m);
346 free(res);
347 return 0;
351 struct matches *atomnop_a APROTO {
352 return alwaysmatches(spos);
355 int matchreg (struct match *res, const struct reg *reg, const struct easm_expr *expr, struct iasctx *ctx) {
356 if (reg->specials) {
357 int i = 0;
358 for (i = 0; reg->specials[i].num != -1; i++) {
359 if (!var_ok(reg->specials[i].fmask, 0, ctx->varinfo))
360 continue;
361 switch (reg->specials[i].mode) {
362 case SR_NAMED:
363 if (expr->type == EASM_EXPR_REG && !strcmp(expr->str, reg->specials[i].name))
364 return setbf(res, reg->bf, reg->specials[i].num);
365 break;
366 case SR_ZERO:
367 if (expr->type == EASM_EXPR_NUM && expr->num == 0)
368 return setbf(res, reg->bf, reg->specials[i].num);
369 break;
370 case SR_ONE:
371 if (expr->type == EASM_EXPR_NUM && expr->num == 1)
372 return setbf(res, reg->bf, reg->specials[i].num);
373 break;
374 case SR_DISCARD:
375 if (expr->type == EASM_EXPR_DISCARD)
376 return setbf(res, reg->bf, reg->specials[i].num);
377 break;
381 if (expr->type != EASM_EXPR_REG)
382 return 0;
383 if (strncmp(expr->str, reg->name, strlen(reg->name)))
384 return 0;
385 const char *str = expr->str + strlen(reg->name);
386 char *end;
387 ull num = strtoull(str, &end, 10);
388 if (!reg->hilo) {
389 if (strcmp(end, (reg->suffix?reg->suffix:"")))
390 return 0;
391 } else {
392 if (strlen(end) != 1)
393 return 0;
394 if (*end != 'h' && *end != 'l')
395 return 0;
396 num <<= 1;
397 if (*end == 'h')
398 num |= 1;
400 if (reg->bf)
401 return setbf(res, reg->bf, num);
402 else
403 return !num;
406 int matchshreg (struct match *res, const struct reg *reg, const struct easm_expr *expr, int shl, struct iasctx *ctx) {
407 ull sh = 0;
408 while (1) {
409 if (expr->type == EASM_EXPR_SHL && expr->e2->type == EASM_EXPR_NUM) {
410 sh += expr->e2->num;
411 expr = expr->e1;
412 } else if (expr->type == EASM_EXPR_MUL && expr->e2->type == EASM_EXPR_NUM) {
413 ull num = expr->e2->num;
414 if (!num || (num & (num-1)))
415 return 0;
416 while (num != 1)
417 num >>= 1, sh++;
418 expr = expr->e1;
419 } else if (expr->type == EASM_EXPR_MUL && expr->e1->type == EASM_EXPR_NUM) {
420 ull num = expr->e1->num;
421 if (!num || (num & (num-1)))
422 return 0;
423 while (num != 1)
424 num >>= 1, sh++;
425 expr = expr->e2;
426 } else {
427 break;
430 if (sh != shl)
431 return 0;
432 return matchreg(res, reg, expr, ctx);
435 struct matches *atomreg_a APROTO {
436 const struct reg *reg = v;
437 if (spos == ctx->atomsnum || ctx->atoms[spos]->type != LITEM_EXPR)
438 return 0;
439 struct easm_expr *e = ctx->atoms[spos]->expr;
440 struct matches *res = alwaysmatches(spos+1);
441 if (matchreg(res->m, reg, e, ctx))
442 return res;
443 else {
444 free(res->m);
445 free(res);
446 return 0;
450 struct matches *atomdiscard_a APROTO {
451 if (spos == ctx->atomsnum || ctx->atoms[spos]->type != LITEM_EXPR)
452 return 0;
453 struct easm_expr *e = ctx->atoms[spos]->expr;
454 if (e->type == EASM_EXPR_DISCARD) {
455 return alwaysmatches(spos+1);
456 } else {
457 return 0;
461 int addexpr (struct easm_expr **iex, struct easm_expr *expr, int flip) {
462 if (flip) {
463 if (!*iex)
464 *iex = easm_expr_un(EASM_EXPR_NEG, expr);
465 else
466 *iex = easm_expr_bin(EASM_EXPR_SUB, *iex, expr);
467 } else {
468 if (!*iex)
469 *iex = expr;
470 else
471 *iex = easm_expr_bin(EASM_EXPR_ADD, *iex, expr);
473 return 1;
476 int matchmemaddr(struct easm_expr **iex, struct easm_expr **niex1, struct easm_expr **niex2, struct easm_expr *expr, int flip) {
477 if (easm_isimm(expr))
478 return addexpr(iex, expr, flip);
479 if (expr->type == EASM_EXPR_ADD)
480 return matchmemaddr(iex, niex1, niex2, expr->e1, flip) && matchmemaddr(iex, niex1, niex2, expr->e2, flip);
481 if (expr->type == EASM_EXPR_SUB)
482 return matchmemaddr(iex, niex1, niex2, expr->e1, flip) && matchmemaddr(iex, niex1, niex2, expr->e2, !flip);
483 if (expr->type == EASM_EXPR_NEG)
484 return matchmemaddr(iex, niex1, niex2, expr->e1, !flip);
485 if (flip)
486 return 0;
487 if (niex1 && !*niex1)
488 *niex1 = expr;
489 else if (niex2 && !*niex2)
490 *niex2 = expr;
491 else
492 return 0;
493 return 1;
496 struct matches *atommem_a APROTO {
497 const struct mem *mem = v;
498 if (spos == ctx->atomsnum || ctx->atoms[spos]->type != LITEM_EXPR)
499 return 0;
500 struct easm_expr *expr = ctx->atoms[spos]->expr;
501 struct easm_expr *pexpr = 0;
502 struct match res = { 0, .lpos = spos+1 };
503 int ismem = expr->type >= EASM_EXPR_MEM && expr->type <= EASM_EXPR_MEMME;
504 if (ismem && !mem->name)
505 return 0;
506 if (!ismem && mem->name)
507 return 0;
508 if (ismem) {
509 if (strncmp(expr->str, mem->name, strlen(mem->name)))
510 return 0;
511 if (mem->idx) {
512 const char *str = expr->str + strlen(mem->name);
513 if (!*str)
514 return 0;
515 char *end;
516 ull num = strtoull(str, &end, 10);
517 if (*end)
518 return 0;
519 if (!setbf(&res, mem->idx, num))
520 return 0;
521 } else {
522 if (strlen(expr->str) != strlen(mem->name))
523 return 0;
525 if (expr->type == EASM_EXPR_MEMPP)
526 addexpr(&pexpr, expr->e2, 0);
527 else if (expr->type == EASM_EXPR_MEMMM)
528 addexpr(&pexpr, expr->e2, 1);
529 else if (expr->type != EASM_EXPR_MEM)
530 return 0;
531 expr = expr->e1;
533 struct easm_expr *iex = 0;
534 struct easm_expr *niex1 = 0;
535 struct easm_expr *niex2 = 0;
536 matchmemaddr(&iex, &niex1, &niex2, expr, 0);
537 if (mem->imm) {
538 if (mem->postincr) {
539 if (!pexpr || iex)
540 return 0;
541 if (!setrbf(&res, mem->imm, pexpr))
542 return 0;
543 } else {
544 if (pexpr)
545 return 0;
546 if (iex) {
547 if (!setrbf(&res, mem->imm, iex))
548 return 0;
549 } else {
550 if (!setrbf(&res, mem->imm, easm_expr_num(EASM_EXPR_NUM, 0)))
551 return 0;
554 } else {
555 if (iex || pexpr)
556 return 0;
558 if (mem->reg && mem->reg2) {
559 if (!niex1)
560 niex1 = easm_expr_num(EASM_EXPR_NUM, 0);
561 if (!niex2)
562 niex2 = easm_expr_num(EASM_EXPR_NUM, 0);
563 struct match sres = res;
564 if (!matchreg(&res, mem->reg, niex1, ctx) || !matchshreg(&res, mem->reg2, niex2, mem->reg2shr, ctx)) {
565 res = sres;
566 if (!matchreg(&res, mem->reg, niex2, ctx) || !matchshreg(&res, mem->reg2, niex1, mem->reg2shr, ctx))
567 return 0;
569 } else if (mem->reg) {
570 if (niex2)
571 return 0;
572 if (!niex1)
573 niex1 = easm_expr_num(EASM_EXPR_NUM, 0);
574 if (!matchreg(&res, mem->reg, niex1, ctx))
575 return 0;
576 } else if (mem->reg2) {
577 if (niex2)
578 return 0;
579 if (!niex1)
580 niex1 = easm_expr_num(EASM_EXPR_NUM, 0);
581 if (!matchshreg(&res, mem->reg2, niex1, mem->reg2shr, ctx))
582 return 0;
583 } else {
584 if (niex1 || niex2)
585 return 0;
587 struct matches *rres = emptymatches();
588 ADDARRAY(rres->m, res);
589 return rres;
592 struct matches *atomvec_a APROTO {
593 const struct vec *vec = v;
594 if (spos == ctx->atomsnum || ctx->atoms[spos]->type != LITEM_EXPR)
595 return 0;
596 struct match res = { 0, .lpos = spos+1 };
597 const struct easm_expr *expr = ctx->atoms[spos]->expr;
598 const struct easm_expr **vexprs = 0;
599 int vexprsnum = 0;
600 int vexprsmax = 0;
601 if (expr->type != EASM_EXPR_ZVEC) {
602 while (expr->type == EASM_EXPR_VEC) {
603 ADDARRAY(vexprs, expr->e2);
604 expr = expr->e1;
606 ADDARRAY(vexprs, expr);
608 int i;
609 for (i = 0; i < vexprsnum/2; i++) {
610 const struct easm_expr *tmp = vexprs[i];
611 vexprs[i] = vexprs[vexprsnum-1-i];
612 vexprs[vexprsnum-1-i] = tmp;
614 ull start = 0, cnt = vexprsnum, mask = 0, cur = 0;
615 for (i = 0; i < cnt; i++) {
616 const struct easm_expr *e = vexprs[i];
617 if (e->type == EASM_EXPR_DISCARD) {
618 } else if (e->type == EASM_EXPR_REG) {
619 if (strncmp(e->str, vec->name, strlen(vec->name)))
620 return 0;
621 char *end;
622 ull num = strtoull(e->str + strlen(vec->name), &end, 10);
623 if (*end)
624 return 0;
625 if (mask) {
626 if (num != cur)
627 return 0;
628 cur++;
629 } else {
630 start = num;
631 cur = num + 1;
633 mask |= 1ull << i;
634 } else {
635 return 0;
638 if (!setbf(&res, vec->bf, start))
639 return 0;
640 if (!setbf(&res, vec->cnt, cnt))
641 return 0;
642 if (vec->mask) {
643 if (!setbf(&res, vec->mask, mask))
644 return 0;
645 } else {
646 if (mask != (1ull << cnt) - 1)
647 return 0;
649 struct matches *rres = emptymatches();
650 ADDARRAY(rres->m, res);
651 return rres;
654 struct matches *atombf_a APROTO {
655 const struct bitfield *bf = v;
656 if (spos == ctx->atomsnum || ctx->atoms[spos]->type != LITEM_EXPR)
657 return 0;
658 struct match res = { 0, .lpos = spos+1 };
659 const struct easm_expr *expr = ctx->atoms[spos]->expr;
660 if (expr->type != EASM_EXPR_VEC || expr->e1->type != EASM_EXPR_NUM || expr->e2->type != EASM_EXPR_NUM)
661 return 0;
662 uint64_t a = expr->e1->num;
663 uint64_t b = expr->e2->num - a;
664 if (!setbf(&res, &bf[0], a))
665 return 0;
666 if (!setbf(&res, &bf[1], b))
667 return 0;
668 struct matches *rres = emptymatches();
669 ADDARRAY(rres->m, res);
670 return rres;
673 void convert_expr_top(struct iasctx *ctx, struct easm_expr *expr);
675 void convert_mods(struct iasctx *ctx, struct easm_mods *mods) {
676 int i;
677 for (i = 0; i < mods->modsnum; i++) {
678 struct litem *li = calloc(sizeof *li, 1);
679 li->type = LITEM_NAME;
680 li->str = mods->mods[i]->str;
681 ADDARRAY(ctx->atoms, li);
685 void convert_operand(struct iasctx *ctx, struct easm_operand *operand) {
686 int i;
687 convert_mods(ctx, operand->mods);
688 for (i = 0; i < operand->exprsnum; i++) {
689 /* XXX */
690 convert_expr_top(ctx, operand->exprs[i]);
694 void convert_sinsn(struct iasctx *ctx, struct easm_sinsn *sinsn) {
695 int i;
696 struct litem *li = calloc(sizeof *li, 1);
697 li->type = LITEM_NAME;
698 li->str = sinsn->str;
699 ADDARRAY(ctx->atoms, li);
700 for (i = 0; i < sinsn->operandsnum; i++) {
701 convert_operand(ctx, sinsn->operands[i]);
703 convert_mods(ctx, sinsn->mods);
706 void convert_subinsn(struct iasctx *ctx, struct easm_subinsn *subinsn) {
707 int i;
708 for (i = 0; i < subinsn->prefsnum; i++) {
709 convert_expr_top(ctx, subinsn->prefs[i]);
711 convert_sinsn(ctx, subinsn->sinsn);
714 void convert_expr_top(struct iasctx *ctx, struct easm_expr *expr) {
715 if (expr->type == EASM_EXPR_SINSN) {
716 struct litem *ses = calloc(sizeof *ses, 1);
717 struct litem *see = calloc(sizeof *see, 1);
718 ses->type = LITEM_SESTART;
719 see->type = LITEM_SEEND;
720 ADDARRAY(ctx->atoms, ses);
721 convert_sinsn(ctx, expr->sinsn);
722 ADDARRAY(ctx->atoms, see);
723 } else {
724 struct litem *li = calloc(sizeof *li, 1);
725 li->type = LITEM_EXPR;
726 li->expr = expr;
727 ADDARRAY(ctx->atoms, li);
731 void convert_insn(struct iasctx *ctx, struct easm_insn *insn) {
732 int i;
733 for (i = 0; i < insn->subinsnsnum; i++) {
734 /* XXX */
735 convert_subinsn(ctx, insn->subinsns[i]);
739 struct matches *do_as(const struct disisa *isa, struct varinfo *varinfo, struct easm_insn *insn) {
740 struct matches *res = calloc(sizeof *res, 1);
741 struct iasctx c = { isa, varinfo };
742 struct iasctx *ctx = &c;
743 convert_insn(ctx, insn);
744 const struct insn *root = isa->trootas ? isa->trootas : isa->troot;
745 struct matches *m = atomtab_a(ctx, root, 0);
746 int i;
747 for (i = 0; i < m->mnum; i++)
748 if (m->m[i].lpos == ctx->atomsnum) {
749 ADDARRAY(res->m, m->m[i]);
751 return res;