aboutsummaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorQuentin Carbonneaux <[email protected]>2024-04-08 15:30:07 +0200
committerQuentin Carbonneaux <[email protected]>2024-04-09 21:47:16 +0200
commit2d046a0ac61e5e3b6a43ce0faf54cc0994bfe5af (patch)
tree05a1b9d6119e9cf250aba21f8fdf402d183992e4 /util.c
parenta609527752b5c96d28b492eac3165a14c9794104 (diff)
use mgen in amd64/isel.c
Diffstat (limited to 'util.c')
-rw-r--r--util.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/util.c b/util.c
index 362fa98..b3401f2 100644
--- a/util.c
+++ b/util.c
@@ -594,3 +594,57 @@ dumpts(BSet *bs, Tmp *tmp, FILE *f)
fprintf(f, " %s", tmp[t].name);
fprintf(f, " ]\n");
}
+
+void
+runmatch(uchar *code, Num *tn, Ref ref, Ref *var)
+{
+ Ref stkbuf[20], *stk;
+ uchar *s, *pc;
+ int bc, i;
+ int n, nl, nr;
+
+ assert(rtype(ref) == RTmp);
+ stk = stkbuf;
+ pc = code;
+ while ((bc = *pc))
+ switch (bc) {
+ case 1: /* pushsym */
+ case 2: /* push */
+ assert(stk < &stkbuf[20]);
+ assert(rtype(ref) == RTmp);
+ nl = tn[ref.val].nl;
+ nr = tn[ref.val].nr;
+ if (bc == 1 && nl > nr) {
+ *stk++ = tn[ref.val].l;
+ ref = tn[ref.val].r;
+ } else {
+ *stk++ = tn[ref.val].r;
+ ref = tn[ref.val].l;
+ }
+ pc++;
+ break;
+ case 3: /* set */
+ var[*++pc] = ref;
+ if (*(pc + 1) == 0)
+ return;
+ /* fall through */
+ case 4: /* pop */
+ assert(stk > &stkbuf[0]);
+ ref = *--stk;
+ pc++;
+ break;
+ case 5: /* switch */
+ assert(rtype(ref) == RTmp);
+ n = tn[ref.val].n;
+ s = pc + 1;
+ for (i=*s++; i>0; i--, s++)
+ if (n == *s++)
+ break;
+ pc += *s;
+ break;
+ default: /* jump */
+ assert(bc >= 10);
+ pc = code + (bc - 10);
+ break;
+ }
+}