duskos

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

commit dceccf2ca00c8133c7c60e3cd508bd203dc100ed
parent 4c1b658bc2ea51c4525a1cb58cc9a46a027e5e8c
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Wed, 14 Sep 2022 10:39:24 -0400

cc: add signed comparisons

Diffstat:
Mfs/app/cos/tools/blkpack.c | 1-
Mfs/asm/i386.fs | 4++--
Mfs/cc/gen.fs | 4+++-
Mfs/cc/type.fs | 6+++---
Mfs/cc/vm/common.fs | 3+++
Mfs/cc/vm/forth.fs | 32++++++++++++++++----------------
Mfs/cc/vm/i386.fs | 4++--
Mfs/tests/cc/cc.fs | 2++
Mfs/tests/cc/test.c | 6++++++
9 files changed, 37 insertions(+), 25 deletions(-)

diff --git a/fs/app/cos/tools/blkpack.c b/fs/app/cos/tools/blkpack.c @@ -1,6 +1,5 @@ // This doesn't actually work, I'm just drafting how it would look. // TODO: string scanning -// TODO: signed arithmetics #[ 10 const BUMP_GRANULARITY ]# diff --git a/fs/asm/i386.fs b/fs/asm/i386.fs @@ -211,8 +211,8 @@ $04e9 op jmp, $02e8 op call, dup 16 rshift opreg! $ffff and opmodrm, ; $0400f7 op mul, $0600f7 op div, $0300f7 op neg, $0200f7 op not, $0100ff op dec, $0000ff op inc, -$000f9f op setg, $000f9c op setl, $000f94 op setz, $000f95 op setnz, -$000f92 op setc, $000f93 op setnc, +$000f9f op setg, $000f9c op setl, $000f97 op seta, $000f92 op setb, +$000f94 op setz, $000f95 op setnz, $000f92 op setc, $000f93 op setnc, $020f01 op lgdt, $030f01 op lidt, \ Two operands diff --git a/fs/cc/gen.fs b/fs/cc/gen.fs @@ -170,7 +170,9 @@ BOPSCNT wordtbl bopgentblpost ( -- ) 'w vm<<=, 'w vm>>=, -: decl>op ( dnode -- ) case +: decl>op ( dnode -- ) + dup Declare type typeunsigned? if opsunsigned! then ( dnode ) + case of Declare :isglobal? r@ Declare address mem>op endof of Declare :isarg? r@ Declare address ps+>op endof r@ Declare address sf+>op diff --git a/fs/cc/type.fs b/fs/cc/type.fs @@ -5,14 +5,14 @@ \ All information related to a basic type fits in a 32b integer, so that's \ how "type" is passed around. Structure: \ b2:0 = size. 0=0 1=8 2=16 3=32 4+=reserved for future use -\ b3 = sign. 0=unsigned 1=signed +\ b3 = sign. 0=signed 1=unsigned \ b6:4 = *lvl. Indirection levels, from 0 to 7. 0 const TYPE_VOID 4 const TYPE_UINT 4 stringlist typenames "void" "char" "short" "int" -: typesigned? ( type -- flags ) 2 rshift 1 and ; +: typeunsigned? ( type -- flags ) 2 rshift 1 and ; : type*lvl ( type -- lvl ) 3 rshift 3 and ; : type*lvl! ( lvl type -- type ) $f and swap 3 lshift or ; : type*lvl+ ( type -- type ) dup type*lvl 1+ swap type*lvl! ; @@ -39,6 +39,6 @@ create _ 0 c, 1 c, 2 c, 4 c, typenames sfind dup 0>= if ( type idx ) or 1 else 2drop 0 then ( type ) ; : printtype ( type -- ) - dup typesigned? if ." unsigned " then + dup typeunsigned? if ." unsigned " then dup 3 and typenames slistiter stype type*lvl ?dup if >r begin '*' emit next then ; diff --git a/fs/cc/vm/common.fs b/fs/cc/vm/common.fs @@ -22,6 +22,7 @@ $14 const VM_*REGISTER \ [eax] \ 2 operands, 2 fields each (type, arg), 4b per field create operands 16 allot0 +0 value opsunsigned \ when 1, ops are considered unsigned operands value 'curop : selop1 ( -- ) operands to 'curop ; @@ -36,8 +37,10 @@ operands value 'curop : 'oparg 'curop 4 + ; : oparg ( -- arg ) 'oparg @ ; : oparg! ( arg -- ) 'oparg ! ; +: opsunsigned! 1 to opsunsigned ; : .ops selectedop .x1 spc> 4 >r operands begin @+ .x spc> next drop nl> ; +: _ops$ operands 16 0 fill 0 to opsunsigned ; \ Managing operands diff --git a/fs/cc/vm/forth.fs b/fs/cc/vm/forth.fs @@ -29,9 +29,7 @@ create argsframe MAXARGSZ allot : opdeinit VM_NONE optype! ; : opfree optypelo VM_TOS = if compile drop then opdeinit ; -: ops$ - selop2 opfree selop1 opfree - operands 16 0 fill ; +: ops$ selop2 opfree selop1 opfree _ops$ ; : TOS# selop^ optypelo VM_TOS <> _assert selop^ ; : op>TOS VM_TOS optype! ; @@ -143,7 +141,8 @@ unop vm--op, 1- postop vmop++, 1+ postop vmop--, 1- -: binop doer ' , does> @ ( w ) +\ 2 fields: signed op, unsigned op +: binop doer ' , ' , does> opsunsigned if CELLSZ + then @ ( w ) selop1 opCompile* opdeinit \ op1 is "lost" on PS selop2 hasop# optypelo VM_TOS = if \ if op2=TOS, we need to swap because our previous opCompile* buried it. @@ -152,18 +151,19 @@ postop vmop--, 1- ( w ) execute, selop1 op>TOS ; \ result in op1 as VM_TOS -binop vmadd, + -binop vmsub, - -binop vmmul, * -binop vm&, and -binop vm|, or -binop vm^, xor -binop vm<<, lshift -binop vm>>, rshift -binop vm<, < -binop vm==, = -binop vm&&, and -binop vm||, or +binop vmadd, + + +binop vmsub, - - +binop vmmul, * * +binop vm&, and and +binop vm|, or or +binop vm^, xor xor +binop vm<<, lshift lshift +binop vm>>, rshift rshift +: s< $80000000 + swap $80000000 + swap < ; +binop vm<, s< < +binop vm==, = = +binop vm&&, and and +binop vm||, or and \ a binop= is like a unop in the sense that it operates directly on op1, but \ with the participation of op2. diff --git a/fs/cc/vm/i386.fs b/fs/cc/vm/i386.fs @@ -72,7 +72,7 @@ create registers AX c, BX c, CX c, DX c, SI c, DI c, : ops$ selop2 opdeinit selop1 opdeinit reglvl if abort" unbalanced reg allot/free" then - operands 16 0 fill ; + _ops$ ; \ Resolve current operand as an assembler "src" argument. : opAsm ( -- ) @@ -258,7 +258,7 @@ create registers AX c, BX c, CX c, DX c, SI c, DI c, : _ selop1 op>reg opAsm selop2 opAsm cmp, opdeinit selop1 opAsm 0 i) mov, ; -: vm<, _ opAsm setl, ; +: vm<, _ opAsm opsunsigned if setb, else setl, then ; : vm==, _ opAsm setz, ; : _ ( 'w -- ) selop1 opAsm selop2 opAsm execute opdeinit selop1 vmboolify, ; : vm&&, ['] and, _ ; diff --git a/fs/tests/cc/cc.fs b/fs/tests/cc/cc.fs @@ -39,6 +39,8 @@ capture helloworld S" Hello World!" #s= 42 multret 32 #eq 55 capture multretvoid S" Nope" #s= 42 capture multretvoid S" Answer to the universe" #s= +-1 0 lts # +-1 0 ltu not # \ and what about inline functions? :cfunc int myinline() { return 42; } diff --git a/fs/tests/cc/test.c b/fs/tests/cc/test.c @@ -159,3 +159,9 @@ extern int forbreak() { } return i; } +extern int lts(int a, int b) { + return a < b; +} +extern int ltu(unsigned int a, unsigned int b) { + return a < b; +}