commit 53e1d3dc2db0ab0485b5f31e30bfa85979c2bda8
parent 6896016e056e8dc2747cf7c6855c514743829dd5
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Thu, 30 Mar 2023 15:15:41 -0400
posix: add a bunch of indirections
I hope I know where I'm going...
Diffstat:
M | posix/vm.c | | | 143 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
1 file changed, 79 insertions(+), 64 deletions(-)
diff --git a/posix/vm.c b/posix/vm.c
@@ -233,20 +233,23 @@ static void entry(char *name) {
_entry(SYSDICT, (byte*)name, strlen(name));
}
-/* Binary Operations */
-typedef dword (*BinOp)(dword, dword);
-
-#define BINOP(name, op) static dword name(dword dst, dword src) { return dst op src; }
-BINOP(BADD, +) BINOP(BSUB, -) BINOP(BMUL, *) BINOP(BDIV, /) BINOP(BMOD, %)
-BINOP(BSHL, <<) BINOP(BSHR, >>)
-BINOP(BAND, &) BINOP(BOR, |) BINOP(BXOR, ^)
-#define BINOPCNT 0x10
-static BinOp binops[BINOPCNT] = {
- BADD, BSUB, BMUL, BDIV, BMOD, BSHL, BSHR, NULL,
- BAND, BOR, BXOR, NULL, NULL, NULL, NULL, NULL,
-};
-
/* Operations */
+static dword opsaddr; // src addr
+static dword opdaddr; // dst addr
+static dword (*mget)(dword a);
+static void (*mset)(dword a, dword val);
+static dword mget16(dword a) { return (dword)gw(a); }
+static dword mget8(dword a) { return (dword)gb(a); }
+static void mset16(dword a, dword val) { sw(a, (word)val); }
+static void mset8(dword a, dword val) { sb(a, (byte)val); }
+#define M32B mget = gdr; mset = sdr
+#define M16B mget = mget16; mset = mset16
+#define M8B mget = mget8; mset = mset8
+static dword opdget() { return gdr(opdaddr); } // dst get
+static void opdset(dword val) { sdr(opdaddr, val); } // dst set
+static dword opsget() { return mget(opsaddr); } // src get
+static void opsset(dword val) { mset(opsaddr, val); } // src set
+
static void BR() { vm.PC = gpc(); } // 0x00
static void CALL() { dword n = gpc(); rpush(vm.PC); vm.PC = n; }
static void RET() { vm.PC = rpop(); }
@@ -277,51 +280,56 @@ static void AADDN() { vm.A += gpc(); vm.Z = vm.A == 0;}
static void W2A() { vm.A = vm.W; }
static void WSWAPA() { dword n = vm.A; vm.A = vm.W; vm.W = n; }
-static dword readop() {
+static void readop() {
byte op = gpcb();
- vm.dst = &vm.W;
- dword addr = 0;
+ opdaddr = WREG;
+ opsaddr = 0;
switch (op & 0x17) {
- case OPW: addr = vm.W; break;
- case OPW|OPDIRECT: addr = WREG; break;
- case OPA: addr = vm.A; break;
- case OPA|OPDIRECT: addr = AREG; break;
- case OPPSP: addr = vm.PSP; break;
- case OPRSP: addr = vm.RSP; break;
- case OPIMM: addr = vm.PC; vm.PC += 4; return addr;
- }
- if (op & OPHASDISP) addr += gpc();
- if (op & OPADEST) vm.dst = &vm.A;
- return addr;
-}
-#define GETA dword a = readop()
-static void WFETCH() { GETA; *vm.dst = gdr(a); } // 0x10
-static void WSTORE() { GETA; sdr(a, *vm.dst); }
-static void WSWAP() { GETA; dword n; n = gdr(a); sdr(a, *vm.dst); *vm.dst = n; }
-static void MADDN() { GETA; dword n=gpc(); n += gdr(a); sdr(a, n); vm.Z = n == 0; }
+ case OPW: opsaddr = vm.W; break;
+ case OPW|OPDIRECT: opsaddr = WREG; break;
+ case OPA: opsaddr = vm.A; break;
+ case OPA|OPDIRECT: opsaddr = AREG; break;
+ case OPPSP: opsaddr = vm.PSP; break;
+ case OPRSP: opsaddr = vm.RSP; break;
+ case OPIMM: opsaddr = vm.PC; vm.PC += 4; return;
+ }
+ if (op & OPHASDISP) opsaddr += gpc();
+ if (op & OPADEST) opdaddr = AREG;
+}
+static void _wfetch() { readop(); opdset(opsget()); }
+static void _wstore() { readop(); opsset(opdget()); }
+static void _wswap() { readop(); dword n; n = opsget(); opsset(opdget()); opdset(n); }
+static void _maddn() { readop(); dword n=gpc(); n += opsget(); opsset(n); vm.Z = n == 0; }
+static void _wifetch() { readop(); opdset(mget(gdr(opsaddr))); }
+static void _wistore() { readop(); mset(gdr(opsaddr), opdget()); }
+
+static void WFETCH() { M32B; _wfetch(); } // 0x10
+static void WSTORE() { M32B; _wstore(); }
+static void WSWAP() { M32B; _wswap(); }
+static void MADDN() { M32B; _maddn(); }
static void WCMP() {
- GETA; dword n = gdr(a);
- vm.Z = n == *vm.dst; vm.C = *vm.dst < n;
- vm.SC = (*vm.dst+0x80000000) < (n+0x80000000); }
-static void WIFETCH() { GETA; *vm.dst = gd(gdr(a)); }
-static void WISTORE() { GETA; sdr(gdr(a), *vm.dst); }
-static void WLEA() { GETA; *vm.dst = a; }
-
-static void WFETCH16() { GETA; *vm.dst = gw(a); } // 0x18
-static void WSTORE16() { GETA; sw(a, *vm.dst); }
-static void WSWAP16() { GETA; dword n; n = gw(a); sw(a, *vm.dst); *vm.dst = n; }
-static void MADDN16() { GETA; dword n=gpc(); n += gw(a); sw(a, n); vm.Z = (n&0xffff) == 0; }
-static void WCMP16() { GETA; vm.Z = gw(a) == (*vm.dst & 0xffff); }
-static void WIFETCH16() { GETA; *vm.dst = gw(gdr(a)); }
-static void WISTORE16() { GETA; sw(gdr(a), *vm.dst); }
-
-static void WFETCH8() { GETA; *vm.dst = gb(a); } // 0x20
-static void WSTORE8() { GETA; sb(a, *vm.dst); }
-static void WSWAP8() { GETA; dword n; n = gb(a); sb(a, *vm.dst); *vm.dst = n; }
-static void MADDN8() { GETA; dword n=gpc(); n += gb(a); sb(a, n); vm.Z = (n&0xff) == 0; }
-static void WCMP8() { GETA; vm.Z = gb(a) == (*vm.dst & 0xff); }
-static void WIFETCH8() { GETA; *vm.dst = gb(gdr(a)); }
-static void WISTORE8() { GETA; sb(gdr(a), *vm.dst); }
+ readop(); dword n = gdr(opsaddr); dword ref = opdget();
+ vm.Z = n == ref; vm.C = ref < n;
+ vm.SC = (ref+0x80000000) < (n+0x80000000); }
+static void WIFETCH() { M32B; _wifetch(); }
+static void WISTORE() { M32B; _wistore(); }
+static void WLEA() { readop(); opdset(opsaddr); }
+
+static void WFETCH16() { M16B; _wfetch(); } // 0x18
+static void WSTORE16() { M16B; _wstore(); }
+static void WSWAP16() { M16B; _wswap(); }
+static void MADDN16() { M16B; _maddn(); }
+static void WCMP16() { readop(); vm.Z = opsget() == (opdget() & 0xffff); }
+static void WIFETCH16() { M16B; _wifetch(); }
+static void WISTORE16() { M16B; _wistore(); }
+
+static void WFETCH8() { M8B; _wfetch(); } // 0x20
+static void WSTORE8() { M8B; _wstore(); }
+static void WSWAP8() { M8B; _wswap(); }
+static void MADDN8() { M8B; _maddn(); }
+static void WCMP8() { readop(); vm.Z = opsget() == (opdget() & 0xff); }
+static void WIFETCH8() { M8B; _wifetch(); }
+static void WISTORE8() { M8B; _wistore(); }
// 0x28
static void BOOTRD() { ppush(fgetc(fp)); }
@@ -514,15 +522,22 @@ static void COMPBINOP() {
dword binopidx = ppop(); dword operand = ppop();
binopwr(binopidx, operand); }
-static void WBINOP() { // 0x48
- byte binopidx = gpcb(); GETA;
- *vm.dst = binops[binopidx](*vm.dst, gdr(a)); }
-static void WBINOP16() {
- byte binopidx = gpcb(); GETA;
- *vm.dst = binops[binopidx](*vm.dst, gw(a)); }
-static void WBINOP8() {
- byte binopidx = gpcb(); GETA;
- *vm.dst = binops[binopidx](*vm.dst, gb(a)); }
+typedef dword (*BinOp)(dword, dword);
+#define BINOP(name, op) static dword name(dword dst, dword src) { return dst op src; }
+BINOP(BADD, +) BINOP(BSUB, -) BINOP(BMUL, *) BINOP(BDIV, /) BINOP(BMOD, %)
+BINOP(BSHL, <<) BINOP(BSHR, >>)
+BINOP(BAND, &) BINOP(BOR, |) BINOP(BXOR, ^)
+#define BINOPCNT 0x10
+static BinOp binops[BINOPCNT] = {
+ BADD, BSUB, BMUL, BDIV, BMOD, BSHL, BSHR, NULL,
+ BAND, BOR, BXOR, NULL, NULL, NULL, NULL, NULL,
+};
+static void _binop() {
+ byte binopidx = gpcb(); readop();
+ opdset(binops[binopidx](opdget(), opsget())); }
+static void WBINOP() { M32B; _binop(); } // 0x48
+static void WBINOP16() { M16B; _binop(); }
+static void WBINOP8() { M8B; _binop(); }
static void DIVMOD() { dword b = vm.W; dword a = pnip(); vm.W = a % b; ppush(a / b); }
static void LT() { vm.W = pnip() < vm.W; }
static void NEG() { vm.W = -vm.W; }