commit c16c967c7d8223c4c9a9562d71a06f97a1b1707e
parent c8b9cb6418720b32f6b2911fa4132501ea35b4f3
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Thu, 9 Mar 2023 14:20:05 -0500
HAL: change operand structure
At this level, we can't just do like in the i386 assembler and have number
banks (we could, but too complex), but by limiting immediates to the 2GB memory
space and displacements to 29 bits, we can fit the operand in a single PS item
in all cases.
Diffstat:
3 files changed, 80 insertions(+), 49 deletions(-)
diff --git a/fs/doc/hal.txt b/fs/doc/hal.txt
@@ -0,0 +1,39 @@
+# Harmonized Assembly Layer
+
+## Kernel
+
+Operand structure:
+b1:0 type (0=W, 1=A, 2=PSP, 3=RSP)
+b30:2 displacement
+b31 immediate? If set, the rest of the structure is ignored and b30:0
+ represent an absolute address.
+
+Operand words:
+
+W) -- op
+A) -- op
+PSP) -- op
+RSP) -- op
+i) addr -- op
++) op disp -- op
+
+Compiler words:
+
+ps+, n --
+rs+, n --
+W+n, n --
+A+n, n --
+W>A, --
+A>W, --
+W<>A, --
+
+Width-aware compiler words:
+
+@, op --
+!, op --
+@!, op --
++, op --
+[@], op --
+[!], op --
+[+n], n op --
+lea, op -- (width aware, but has the same behavior in all widths)
diff --git a/fs/xcomp/bootlo.fs b/fs/xcomp/bootlo.fs
@@ -1,10 +1,13 @@
code : ] code ] ;
: noop ;
-: W) 0 ; : A) 1 ; : PSP) 2 ; : RSP) 3 ; : i) $c ;
+: W) 0 ; : A) 1 ; : PSP) 2 ; : RSP) 3 ;
: dup, -4 ps+, PSP) !, ;
code dup dup, exit,
code swap PSP) @!, exit,
-: +) swap $08 or ;
+code << 1 <<n, exit,
+code >> 1 >>n, exit,
+: i) $80000000 or ;
+: +) $1fffffff and << << or ;
: drop, PSP) @, 4 ps+, ;
code drop drop, exit,
: 2drop, PSP) 4 +) @, 8 ps+, ;
@@ -127,7 +130,7 @@ code (does) r> W>A, W) @, W<>A, CELLSZ W+n, branchA,
: _!, !, drop, ; _to to ! _!,
: _+!, dup +, _!, ; _to to+ +! _+!,
: _lea, dup, lea, ; _to to' noop _lea,
-: _toexec ( a -- ) compiling if LIT>A, A) then toptr@ execute ;
+: _toexec ( a -- ) compiling if i) then toptr@ execute ;
: value doer , immediate does> _toexec ;
: here HERE _toexec ; immediate
here dbg bye
diff --git a/posix/vm.c b/posix/vm.c
@@ -29,8 +29,7 @@
#define OPA 1
#define OPPSP 2
#define OPRSP 3
-#define OPIMM 4
-#define OPDISP 0x08
+#define OPIMM 0x80000000
#define EMETA_8B 0x10
#define EMETA_16B 0x11
@@ -123,29 +122,24 @@ static void dwrite(dword d) {
static void retwr() { cwrite(0x02); }
static void psaddwr(dword n) { cwrite(0x08); dwrite(n); }
-static void wopwr(byte opcode, byte operand, dword disp) {
- cwrite(opcode);
- if (disp) operand |= OPDISP;
- cwrite(operand);
- if (operand & OPDISP) dwrite(disp);
-}
-static void wfetchwr(byte op, dword disp) { wopwr(0x10, op, disp); }
-static void wstorewr(byte op, dword disp) { wopwr(0x11, op, disp); }
-static void maddnwr(byte op, dword disp, dword n) { wopwr(0x13, op, disp); dwrite(n); }
-static void wistorewr(byte op, dword disp) { wopwr(0x16, op, disp); }
-static void wistorewr8(byte op, dword disp) { wopwr(0x26, op, disp); }
-static void dupwr() { psaddwr(0xfffffffc); wstorewr(OPPSP, 0); }
+static void wopwr(byte opcode, dword operand) { cwrite(opcode); dwrite(operand); }
+static void wfetchwr(dword op) { wopwr(0x10, op); }
+static void wstorewr(dword op) { wopwr(0x11, op); }
+static void maddnwr(dword op, dword n) { wopwr(0x13, op); dwrite(n); }
+static void wistorewr(dword op) { wopwr(0x16, op); }
+static void wistorewr8(dword op) { wopwr(0x26, op); }
+static void dupwr() { psaddwr(0xfffffffc); wstorewr(OPPSP); }
static void nipwr() { psaddwr(4); }
-static void dropwr() { wfetchwr(OPPSP, 0); nipwr(); }
+static void dropwr() { wfetchwr(OPPSP); nipwr(); }
static void wlitwr(dword n) { cwrite(0x0a); dwrite(n); }
static void alitwr(dword n) { cwrite(0x0b); dwrite(n); }
static void litwr(dword n) { dupwr(); wlitwr(n); }
static void callwr(dword a) { cwrite(0x01); dwrite(a); }
static void brwr(dword a) { cwrite(0x00); dwrite(a); }
-static void writewr() { alitwr(HERE); wistorewr(OPA, 0); maddnwr(OPA, 0, 4); dropwr(); }
-static void cwritewr() { alitwr(HERE); wistorewr8(OPA, 0); maddnwr(OPA, 0, 1); dropwr(); }
-static void compopwr(byte opcode) { litwr(opcode); cwrite(0x3e); }
-static void storewr() { cwrite(0x0e); dropwr(); wstorewr(OPA, 0); dropwr(); }
+static void writewr() { alitwr(HERE); wistorewr(OPA); maddnwr(OPA, 4); dropwr(); }
+static void cwritewr() { alitwr(HERE); wistorewr8(OPA); maddnwr(OPA, 1); dropwr(); }
+static void compopwr(byte opcode) { litwr(opcode); cwritewr(); writewr(); }
+static void storewr() { cwrite(0x0e); dropwr(); wstorewr(OPA); dropwr(); }
static void callword(dword addr); // forward declaration
static void _entry(dword dict, byte *name, byte slen) {
@@ -180,22 +174,19 @@ static void AADDN() { vm.A += gpc(); }
static void W2A() { vm.A = vm.W; }
static void WSWAPA() { dword n = vm.A; vm.A = vm.W; vm.W = n; }
-static dword readop() { // 1b optype 4b displacement
- byte op = gpcb();
- dword addr;
- switch (op & 7) {
- case OPW: addr = vm.W; break;
- case OPA: addr = vm.A; break;
- case OPPSP: addr = vm.PSP; break;
- case OPRSP: addr = vm.RSP; break;
- case OPIMM: addr = 0; break;
- default:
- printf("Illegal readop %02x at PC %08x\n", op, vm.PC-1);
- vmabort();
- return 0;
+static dword readop() {
+ dword op = gpc();
+ dword disp;
+ if (op & OPIMM) { return op & 0x7fffffff; }
+ disp = op >> 2;
+ if (op & 0x10000000) /* sign extend */ op |= 0xe0000000;
+ switch (op & 3) {
+ case OPW: return vm.W + disp;
+ case OPA: return vm.A + disp;
+ case OPPSP: return vm.PSP + disp;
+ case OPRSP: return vm.RSP + disp;
}
- if (op & OPDISP) addr += gpc();
- return addr;
+ return 0;
}
static void WFETCH() { vm.W = gd(readop()); } // 0x10
static void WSTORE() { sd(readop(), vm.W); }
@@ -370,14 +361,6 @@ static void RUNWORD() {
static void COMPILING() { ppush(vm.compiling); }
static void STARTCOMP() { vm.compiling = 1; }
static void STOPCOMP() { vm.compiling = 0; }
-// ( ?disp Woperand opcode -- )
-static void COMPOP() {
- dword opcode = ppop();
- dword operand = ppop();
- dword disp = 0;
- if (operand & OPDISP) disp = ppop();
- wopwr(opcode, operand, disp);
-}
static void ALIGN4() { // 0x40
dword n = ppop();
@@ -432,7 +415,10 @@ static void DBG() {
printf("W %08x A %08x PC %08x PSP %08x RSP %08x MOD %08x\n", vm.W, vm.A, vm.PC, vm.PSP, vm.RSP, gd(MOD));
}
-#define OPCNT 0x60
+static void SHLN() { vm.W <<= gpcb(); } // 0x60
+static void SHRN() { vm.W >>= gpcb(); }
+
+#define OPCNT 0x68
static void (*ops[OPCNT])() = {
BR, CALL, RET, BRA, CBR, BRWR, BRZ, NULL,
PSADD, RSADD, WLIT, ALIT, WADDN, AADDN, W2A, WSWAPA,
@@ -441,11 +427,12 @@ static void (*ops[OPCNT])() = {
WFETCH8, WSTORE8, WSWAP8, MADDN8, WLEA, WIFETCH8, WISTORE8, WADD8,
BOOTRD, STDOUT, MAYBEKEY, NULL, NULL, NULL, NULL, NULL,
MAYBEWORD, WORD, PARSE, FIND, WNF, FINDMOD, NULL, NULL,
- STACKCHK, COMPWORD, RUNWORD, COMPILING, STARTCOMP, STOPCOMP, COMPOP, NULL,
+ STACKCHK, COMPWORD, RUNWORD, COMPILING, STARTCOMP, STOPCOMP, NULL, NULL,
ALIGN4, ENTRY, CODE, CODE16, CODE8, NULL, NULL, NULL,
ADD, SUB, MUL, DIVMOD, LT, NULL, NULL, NULL,
AND, OR, XOR, BOOL, NOT, NULL, NULL, NULL,
BYE, BYEFAIL, QUIT, ABORT_, DBG, NULL, NULL, NULL,
+ SHLN, SHRN, NULL, NULL, NULL, NULL, NULL, NULL,
};
static void oprun1() { // run next op
@@ -542,6 +529,8 @@ static void buildsysdict() {
entry("+,"); compopwr(0x17); retwr();
CODE16(); compopwr(0x1f); retwr();
CODE8(); compopwr(0x27); retwr();
+ entry("<<n,"); compileop(0x60); cwritewr(); retwr();
+ entry(">>n,"); compileop(0x61); cwritewr(); retwr();
entry("exit,"); compileop(0x02); retwr();
entry("execute,"); compileop(0x01); writewr(); retwr();
entry("branchA,"); compileop(0x03); retwr();
@@ -550,8 +539,8 @@ static void buildsysdict() {
entry("branchz,"); litwr(0x06); cwrite(0x05); retwr();
entry("branch!"); storewr(); retwr();
entry(";"); compileop(0x02); cwrite(0x3d); retwr(); makeimm();
- entry("16b"); litwr(EMETA_16B); alitwr(MOD); wstorewr(OPA, 0); dropwr(); retwr(); makeimm();
- entry("8b"); litwr(EMETA_8B); alitwr(MOD); wstorewr(OPA, 0); dropwr(); retwr(); makeimm();
+ entry("16b"); litwr(EMETA_16B); alitwr(MOD); wstorewr(OPA); dropwr(); retwr(); makeimm();
+ entry("8b"); litwr(EMETA_8B); alitwr(MOD); wstorewr(OPA); dropwr(); retwr(); makeimm();
sysalias("in<", "boot<");
inrdaddr = find("in<");
mainaddr = here();