duskos

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

commit 6a893ca80685ed2cba5cae763d15e6743410374b
parent 8b1d75c6eee6e6152e86192627b900842c67c602
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Sat, 25 Mar 2023 09:19:33 -0400

halcc: lts() ltu()

Diffstat:
Mfs/comp/c/egen.fs | 9++++++---
Mfs/comp/c/expr.fs | 4+++-
Mfs/tests/comp/c/cc.fs | 2+-
Mfs/tests/comp/c/test2.c | 6++++++
Mposix/vm.c | 13++++++++++++-
5 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/fs/comp/c/egen.fs b/fs/comp/c/egen.fs @@ -77,11 +77,14 @@ assign _<<=, _<<, assign _>>=, _>>, \ To avoid W juggling, we check if our right operand is W. If it is, no need \ for juggling, all we need is to invert the condition we use. -: cmpop doer swap , , does> ( left right 'conds ) +\ data: unsigned cond, unsigned swapped cond, signed cond, signed swapped cond +: cmpop doer 4 for ' execute , next does> ( left right 'conds ) + over Result unsigned? not if CELLSZ << + then over Result :isW? if CELLSZ + @ >r swap else @ >r then ( left right ) Result :hal# over Result :?>W cmp, r> C>W, ; -Z) Z) cmpop _==, NZ) NZ) cmpop _!=, -<) >=) cmpop _<, <=) >) cmpop _<=, >) <=) cmpop _>, >=) <) cmpop _>=, +cmpop _==, Z) Z) Z) Z) cmpop _!=, NZ) NZ) NZ) NZ) +cmpop _<, <) >=) s<) s>=) cmpop _<=, <=) >) s<=) s>) +cmpop _>, >) <=) s>) s<=) cmpop _>=, >=) <) s>=) s<) \ Our implementation of "x ? y : z" suffers a significant limitation because \ we're single pass: by the time _? is called, it's possible that code diff --git a/fs/comp/c/expr.fs b/fs/comp/c/expr.fs @@ -32,13 +32,14 @@ struct[ Result sfield basesz \ size, in bytes of the base type sfield lvl \ lvl changed applied within the expression sfield blvl \ Bottom Level + sfield unsigned? \ There can only be one result using W at once. Whenever a W result is \ created, it takes the lock. If it's already taken, there's an error. 0 value currentW \ link to Result : :Wfree# currentW if abort" W is already taken!" then ; - : :new ( arg type -- res ) SZ syspad :[ , , CELLSZ , 0 , 0 , syspad :] ; + : :new ( arg type -- res ) SZ syspad :[ , , CELLSZ , 0 , 0 , 0 , syspad :] ; : :none ( -- res ) 0 NONE :new ; : :const ( n -- res ) CONST :new ; : :W ( -- res ) :Wfree# 0 W :new dup to currentW ; @@ -61,6 +62,7 @@ struct[ Result : :cdecl ( cdecl -- res ) dup CDECL :new ( cdecl res ) over CDecl type typesize over to basesz + over typeunsigned? over to unsigned? over bi CDecl lvl | CDecl nbelem bool + over to blvl ( cdecl res ) swap CDecl nbelem if dup :& -1 over to+ blvl then ; diff --git a/fs/tests/comp/c/cc.fs b/fs/tests/comp/c/cc.fs @@ -53,9 +53,9 @@ nullstr expected 16 []= # forbreak 10 #eq forcontinue 9 #eq forempty \ no crash -testend \s -1 0 lts # -1 0 ltu not # +testend \s 0 boolnot 1 #eq 42 boolnot 0 #eq S" foobar" 2 get8b 'o' #eq diff --git a/fs/tests/comp/c/test2.c b/fs/tests/comp/c/test2.c @@ -215,3 +215,9 @@ int forcontinue() { void forempty() { for (;1;) return; } +int lts(int a, int b) { + return a < b; +} +int ltu(unsigned int a, unsigned int b) { + return a < b; +} diff --git a/posix/vm.c b/posix/vm.c @@ -69,6 +69,10 @@ no assembler to complete the HAL to "full" level later. It's all in there. #define CONDNC 0x81 #define CONDA 0x02 // above (unsigned gt) #define CONDNA 0x82 +#define CONDLT 0x03 // signed +#define CONDNLT 0x83 +#define CONDGT 0x04 // signed +#define CONDNGT 0x84 #define EMETA_8B 0x10 #define EMETA_16B 0x11 @@ -85,6 +89,7 @@ struct VM { dword *dst; byte Z; byte C; + byte SC; // signed C byte compiling; byte hbankidx; byte mem[MEMSZ]; @@ -235,6 +240,8 @@ static int checkcond(byte cond) { case CONDZ: r = vm.Z; break; case CONDC: r = vm.C; break; case CONDA: r = !vm.C && !vm.Z; break; + case CONDLT: r = vm.SC; break; + case CONDGT: r = !vm.SC && !vm.Z; break; } if (cond&0x80) r = !r; return r; @@ -274,7 +281,9 @@ 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; } static void WCMP() { - GETA; dword n = gdr(a); vm.Z = n == *vm.dst; vm.C = *vm.dst < n; } + 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 WADD() { GETA; *vm.dst += gdr(a); vm.Z = *vm.dst == 0; } @@ -933,6 +942,8 @@ static void buildsysdict() { sysconst("C)", CONDC); sysconst("NC)", CONDNC); sysconst("<)", CONDC); sysconst(">=)", CONDNC); sysconst(">)", CONDA); sysconst("<=)", CONDNA); + sysconst("s<)", CONDLT); sysconst("s>=)", CONDNLT); + sysconst("s>)", CONDGT); sysconst("s<=)", CONDNGT); for (int i=0; i<OPCNT-0x28; i++) { if (opnames[i]) wentry(opnames[i], i+0x28); }