duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit b629358f0a479c9cd824fa6108bd02293c04d879
parent 3b916d7d2bd5bcf9e645f624cc167c63d66ecc6d
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Thu, 29 Jun 2023 21:35:12 -0400

hal: merge /, and %, into /mod,

The idea is that whatever work must be done to compute a division is the work
done to compute the remainder, and vice versa. Having these two operations
separate is wasteful when both results are needed (which is often).

The drawback of this is that the arithmetic API becomes irregular with the A
register being monopolized for this operation. For now, it doesn't cause
troubles, but maybe it will come and bite me later...

Diffstat:
Mfs/comp/c/egen.fs | 8++++----
Mfs/comp/c/expr.fs | 2+-
Mfs/doc/hal.txt | 4++--
Mfs/xcomp/arm/rpi/kernel.fs | 67++++++++++++++++++++++++++++++++++++-------------------------------
Mfs/xcomp/bootlo.fs | 1+
Mfs/xcomp/i386/kernel.fs | 17++++++-----------
Mposix/vm.c | 14++++++--------
7 files changed, 56 insertions(+), 57 deletions(-)

diff --git a/fs/comp/c/egen.fs b/fs/comp/c/egen.fs @@ -70,8 +70,8 @@ UOPSCNT wordtbl uoptbl ( eop -- eop ) \ ops that can't freely swap their operands : _prep ( left right -- left halop ) ExprOp :?freeCurrentW over ExprOp :?>W ExprOp :hal$ ; -: _/, _prep /, ; : _%, _prep %, ; -: _<<, _prep <<, ; : _>>, _prep >>, ; +: _/, _prep /mod, ; : _%, _prep /mod, A) &) @, ; +: _<<, _prep <<, ; : _>>, _prep >>, ; : _ptr-, ( left right -- eop ) _prep -, CELLSZ over ExprOp :/n dup ExprOp :toint ; @@ -82,8 +82,8 @@ UOPSCNT wordtbl uoptbl ( eop -- eop ) : _prep ( left right -- eop halop ) ExprOp :?freeCurrentW ExprOp :?>W$ dup ExprOp :hal# <>) ; : _=, _prep @, ; : _-=, _prep -, ; -: _*=, _prep *, ; : _/=, _prep /, ; : _%=, _prep %, ; -: _&=, _prep &, ; : _^=, _prep ^, ; : _|=, _prep |, ; +: _*=, _prep *, ; : _/=, _prep /mod, ; : _%=, _prep /mod, A) &) @, ; +: _&=, _prep &, ; : _^=, _prep ^, ; : _|=, _prep |, ; : _<<=, _prep <<, ; : _>>=, _prep >>, ; : _+=, diff --git a/fs/comp/c/expr.fs b/fs/comp/c/expr.fs @@ -96,7 +96,7 @@ struct[ ExprOp : :*n ( n self -- ) over 1 = if 2drop exit then dup :isconst? if dup arg rot * swap to arg else :?>W i) *, then ; : :/n ( n self -- ) over 1 = if 2drop exit then - dup :isconst? if dup arg rot / swap to arg else :?>W i) /, then ; + dup :isconst? if dup arg rot / swap to arg else :?>W i) /mod, then ; \ For pointer arithmetics, we apply the "bottom level" logic one level higher. \ That is, when lvl=blvl our "arisz" is 1 (regular arithmetics), when \ lvl=blvl our arisz is "basesz" (we add and subtract by chunks of the diff --git a/fs/doc/hal.txt b/fs/doc/hal.txt @@ -234,8 +234,8 @@ Instructions: +, op -- Z Add source to dest -, op -- dest - operand *, op -- dest * operand -/, op -- dest / operand -%, op -- dest modulo operand +/mod, op -- divide dest by operand and put remainder in A register. + Can't be used with A>). <<, op -- dest lshift operand >>, op -- dest rshift operand &, op -- Z dest and operand diff --git a/fs/xcomp/arm/rpi/kernel.fs b/fs/xcomp/arm/rpi/kernel.fs @@ -954,6 +954,42 @@ xcode litn wcall, dup, mov) r0 rd) rTOP imm) ,) lbllitwr abs>rel b) ,) +pc ," divide by zero" alignhere +pc to L1 \ rTOP=dividend rA=divisor + ( pc ) r0 pc>reg, + mov) r1 rd) 14 imm) ,) + cmp) rA rn) 0 imm) ,) + lblerrmsg abs>rel b) z) ,) + \ rTOP is active remainder + mov) r1 rd) 0 imm) ,) \ r1=quotient + mov) r2 rd) rA rm) ,) \ r2=tmp + \ double tmp until 2 * tmp > dividend + cmp) r2 rn) rTOP rm) 1 lsr) ,) +pc + mov) ls) r2 rd) r2 rm) 1 lsl) ,) + cmp) r2 rn) rTOP rm) 1 lsr) ,) + ( pc ) abs>rel b) ls) ,) +pc + cmp) rTOP rn) r2 rm) ,) \ can we subtract temp from dividend? + sub) cs) rTOP rdn) r2 rm) ,) \ if yes, do it + adc) r1 rdn) r1 rm) ,) \ double and add carry + mov) r2 rd) r2 rm) 1 lsr) ,) + cmp) r2 rn) rA rm) ,) + ( pc ) abs>rel b) hs) ,) + mov) rA rd) rTOP rm) ,) \ set remainder + mov) rTOP rd) r1 rm) ,) \ set quotient + ret, + +pc L1 le, +xcode /mod, ( operand -- ) + wcall, A>) + wcall, @, + wcall, pushret, + xdup, + ( pc ) rTOP pc@>reg, + wcall, branchR, + wjmp, popret, + \ Arithmetics xcode << ( n -- n ) mov) rTOP rd) rTOP rm) 1 lsl) ,) @@ -973,37 +1009,6 @@ xcode rshift ( n u -- n ) mov) rTOP rd) r0 rm) rTOP rlsr) ,) ret, -xcode * ( a b -- n ) - r0 ppop, - mul) rTOP rd) rTOP rs) r0 rm) ,) - ret, - -pc ," divide by zero" alignhere -xcode /mod ( a b -- r q ) - ( pc ) r0 pc>reg, - mov) r1 rd) 14 imm) ,) - cmp) rTOP rn) 0 imm) ,) - lblerrmsg abs>rel b) z) ,) - ldr) r0 rd) rPSP rn) ,) \ r0=dividend/remainder rTOP=divisor - mov) r1 rd) 0 imm) ,) \ r1=quotient - mov) r2 rd) rTOP rm) ,) \ r2=tmp - \ double tmp until 2 * tmp > dividend - cmp) r2 rn) r0 rm) 1 lsr) ,) -pc - mov) ls) r2 rd) r2 rm) 1 lsl) ,) - cmp) r2 rn) r0 rm) 1 lsr) ,) - ( pc ) abs>rel b) ls) ,) -pc - cmp) r0 rn) r2 rm) ,) \ can we subtract temp from dividend? - sub) cs) r0 rdn) r2 rm) ,) \ if yes, do it - adc) r1 rdn) r1 rm) ,) \ double and add carry - mov) r2 rd) r2 rm) 1 lsr) ,) - cmp) r2 rn) rTOP rm) ,) - ( pc ) abs>rel b) hs) ,) - str) r0 rd) rPSP rn) ,) \ remainder - mov) rTOP rd) r1 rm) ,) \ quotient - ret, - \ Speed-critical words xcode move ( src dst u -- ) r2 ppop, r0 ppop, \ r0=src r2=dst diff --git a/fs/xcomp/bootlo.fs b/fs/xcomp/bootlo.fs @@ -105,6 +105,7 @@ Z) _ = NZ) _ <> >) _ < <) _ > >=) _ <= <=) _ >= : 0>= $80000000 < ; : 0< 0>= not ; code * PSP) *, nip, exit, +code /mod PSP) @!, PSP) /mod, PSP) A>) !, exit, : / /mod nip ; : mod /mod drop ; : ?swap ( n n -- l h ) 2dup > if swap then ; diff --git a/fs/xcomp/i386/kernel.fs b/fs/xcomp/i386/kernel.fs @@ -289,6 +289,12 @@ xcode +n, ( n operand -- ) \ operand n i) add, xcode *, ( operand -- ) \ TODO: support A>) and i) ax $f720 i) or, L1 absjmp, +xcode /mod, ( operand -- ) \ TODO: support i) + $d231 i) wwrite, \ dx dx xor, + ax $f730 i) or, L1 abscall, + $d389 i) wwrite, \ bx dx mov, + ret, + \ Write: di 32b) operand mov, operand 32b) 1/2/4 i) add, pc to L2 ( operand -- operand-with-di-src ) xdup, @@ -396,17 +402,6 @@ xcode branch! ( tgt a -- ) ret, \ Regular words -xcode * - si 0 d) mul, - xnip, ret, - -xcode /mod ( a b -- r q ) - di ax mov, ax si 0 d) mov, - dx dx xor, - di div, - si 0 d) dx mov, \ remainder - ret, - xcode << ( n -- n ) ax 1 i) shl, ret, diff --git a/posix/vm.c b/posix/vm.c @@ -128,7 +128,6 @@ 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 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; } static dword rpeek() { return gd(vm.RSP); } @@ -568,12 +567,13 @@ static void COMPBINOP() { 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(BADD, +) BINOP(BSUB, -) BINOP(BMUL, *) BINOP(BSHL, <<) BINOP(BSHR, >>) BINOP(BAND, &) BINOP(BOR, |) BINOP(BXOR, ^) +static dword BDIVMOD(dword dst, dword src) { vm.A = dst % src; return dst / src; } #define BINOPCNT 0x10 static BinOp binops[BINOPCNT] = { - BADD, BSUB, BMUL, BDIV, BMOD, BSHL, BSHR, NULL, + BADD, BSUB, BMUL, BDIVMOD, NULL, BSHL, BSHR, NULL, BAND, BOR, BXOR, NULL, NULL, NULL, NULL, NULL, }; static void _binop() { @@ -583,7 +583,6 @@ static void _binop() { 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 NEG() { vm.W = -vm.W; } static void BYE() { vm.PC = MEMSZ; } // 0x50 @@ -905,7 +904,7 @@ static void (*ops[OPCNT])() = { MAYBEWORD, WORD, PARSE, FIND, WNF, FINDMOD, NULL, NULL, STACKCHK, COMPWORD, RUNWORD, COMPILING, STARTCOMP, STOPCOMP, RSADDWR, COMPOP, NULL, ENTRY, CODE, CODE16, CODE8, COMPBINOP, NULL, NULL, - WBINOP, WBINOP16, WBINOP8, DIVMOD, NULL, NULL, NEG, NULL, + WBINOP, WBINOP16, WBINOP8, NULL, NULL, NULL, NEG, NULL, BYE, BYEFAIL, QUIT, ABORT_, DBG, USLEEP, MPROTECT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, STOREC, NULL, FCHILD, FOPEN, FREADBUF, FCLOSE, FINFO, FITER, NULL, FSEEK, @@ -948,7 +947,7 @@ static char *opnames[OPCNT-0x28] = { "maybeword", "word", "parse", "find", "(wnf)", "findmod", NULL, NULL, "stack?", "compword", "runword", "compiling", "]", NULL, "rs+,", NULL, NULL, "entry", "code", "code16b", "code8b", NULL, NULL, NULL, - NULL, NULL, NULL, "/mod", NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "bye", "byefail", "quit", "(abort)", "dbg", "_usleep", "mprotect", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "_fchild", "_fopen", "_freadbuf", "_fclose", "_finfo", "_fiter", NULL, "_fseek", @@ -998,8 +997,7 @@ static void buildsysdict() { entry("+,"); compbinopwr(0x00); retwr(); entry("-,"); compbinopwr(0x01); retwr(); entry("*,"); compbinopwr(0x02); retwr(); - entry("/,"); compbinopwr(0x03); retwr(); - entry("%,"); compbinopwr(0x04); retwr(); + entry("/mod,"); compbinopwr(0x03); retwr(); entry("<<,"); compbinopwr(0x05); retwr(); entry(">>,"); compbinopwr(0x06); retwr(); entry("&,"); compbinopwr(0x08); retwr();