commit 44405ca5549259ad500cdd9da84cb6d838588e8f
parent a5a4a8cfc5917807d98ecef04ba158a8ef7a2b7d
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Fri, 23 Jun 2023 16:46:07 -0400
posix: make VM "host native endian" rather than little endian
My recent simplification of the posix VM code broke big endian. I was looking
into fixing it, but I realized that it was already broken in some cases: opdst
can point to an address in memory, in which case memory corruption will occur
under a BE machine in the few cases it happens.
Making the whole thing properly little endian was quite complicated, so I asked
myself: why do I want this VM to be little endian again? There's no reason.
Well, at least I can't think of one. I haven't tested the VM on any big endian
host yet. Some day...
Bonus: the VM is much faster.
Diffstat:
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/posix/vm.c b/posix/vm.c
@@ -1,7 +1,11 @@
/* Dusk VM for POSIX platforms
-The VM is little endian, has a read-only file system and is pretty slow. It's
-enough, however, to generate native binary images for any supported target.
+The VM has the same endianness as the host. This code was written on a little
+endian machine. It's very probably broken on big endian hosts, but in
+principle, it's only a matter of fixing kinks here and there.
+
+It also has a read-only file system and is pretty slow. It's enough, however,
+to generate native binary images for any supported target.
HAL argument structure:
b2:0 type 0=W 1=A 2=PSP 3=RSP 4=memory/immediate
@@ -118,13 +122,12 @@ static dword memchkmut(dword a) {
} else { return a; }
}
static byte gb(dword addr) { return vm.mem[memchk(addr)]; }
-static word gw(dword addr) { return gb(addr) | (gb(addr+1)<<8); }
-static dword gd(dword addr) { return gw(addr) | (gw(addr+2)<<16); }
+static dword gd(dword addr) { return *(dword*)&vm.mem[memchk(addr)]; }
static dword gpc() { dword n = gd(vm.PC); vm.PC += 4; return n; }
static byte gpcb() { dword n = gb(vm.PC); vm.PC++; return n; }
static void sb(dword addr, byte b) { vm.mem[memchkmut(addr)] = b; }
-static void sw(dword addr, word w) { sb(addr, w); sb(addr+1, w>>8); }
-static void sd(dword addr, dword d) { sw(addr, d); sw(addr+2, d>>16); }
+static void sd(dword addr, dword d) {
+ dword *a = (dword*)&vm.mem[memchkmut(addr)]; *a = d; }
static dword pnip() { dword n = gd(vm.PSP); vm.PSP += 4; return n; }
static dword ppop() { dword n = vm.W; vm.W = gd(vm.PSP); vm.PSP += 4; return n; }
static void ppush(dword n) { vm.PSP -= 4; sd(vm.PSP, vm.W); vm.W = n; }