duskos

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

commit 5d96fd4248507486fa78b0eac5b9c6fd53d96648
parent a7589021be2e66e858d3fae49b0718b170802724
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Fri, 24 Mar 2023 10:24:57 -0400

halcc: globalshort()

Diffstat:
Mfs/comp/c/egen.fs | 7++++---
Mfs/comp/c/expr.fs | 93+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Mfs/tests/comp/c/cc.fs | 2+-
3 files changed, 58 insertions(+), 44 deletions(-)

diff --git a/fs/comp/c/egen.fs b/fs/comp/c/egen.fs @@ -52,8 +52,9 @@ UOPSCNT wordtbl uoptbl ( res -- res ) : _+, ( left right -- res ) over Result :*arisz over Result :*arisz <> if over Result :*arisz 1 = if swap then \ left has mutiplier - over Result :*arisz log2 over Result :<<n then - _prep +, ; + over Result :*arisz log2 over Result :<<n ( left right*arisz ) + over >r _prep +, r> over Result :copymeta + else _prep +, then ; \ ops that can't freely swap their operands : _prep ( left right -- left halop ) Result :?>A over Result :?>W ; @@ -62,7 +63,7 @@ UOPSCNT wordtbl uoptbl ( res -- res ) : _-, ( left right -- res ) over Result :*arisz over Result :*arisz over = _assert ( left right arisz ) - >r _prep -, r> log2 ?dup if over Result :>>n then ; + >r _prep -, r> log2 ?dup if over Result :>>n then dup Result :toint ; : assign doer ' , does> @ ( left right w ) >r over Result :hal# rot> r> execute ( lefthal res ) swap !, ; diff --git a/fs/comp/c/expr.fs b/fs/comp/c/expr.fs @@ -6,33 +6,19 @@ : _err ( -- ) tokdbg abort" expr error" ; : _assert ( f -- ) not if _err then ; -\ Apply indirection level to halop. If necessary, use the A register to get to -\ the right place. -: applylvl ( halop lvl -- halop ) case ( halop ) - 0 of = endof - -1 of = A>) lea, A*) endof - of 0>= r@ for A>) @, A) next drop A) endof - _err endcase ; - -\ Operation levels vs Arithmetic levels -\ We track two types of indirection levels here. First, there's the "operations" -\ level, that is, where to get the damn value at the end. This is independent of -\ indirection levels in the declarations. It is only affected by & and * -\ operators applied within expressions. Therefore, Results begin their lives -\ at "oplvl" 0. There's one exception: Arrays living in the stack frame start -\ at lvl -1 because the pointer is RSP+offset without indirection. -\ When comes the time to resolve the oplvl, we first check if it's -1, in which -\ case we resolve it with a "lea,". This only works on CDECL results. Less than -\ -1 is an error. For positive oplvl, we move to W and repeatedly call @,. For -\ more efficiency, we bundle oplvl in 2s and use [@], when possible. -\ Arithmetic levels serve a different purpose: to know when we need to apply -\ pointer arithmetics. For this, we take CDecl's base lvl (if it's an array, -\ this adds 1 to this level) subtract Result's lvl from it. -\ This is the "arilvl". If that level is 0, then its "pointer arithmetics -\ multiplier" is 1. If the level is 1, then the multiplier is the size of the -\ base type. Otherwise, the multiplier is 4 (size of a pointer). Negative is an -\ error. The arilvl has no effect on how the fetching of the actual value -\ occurs. +\ Indirection levels +\ We track two types of indirection levels here. First, there's the "regular" +\ level, that is, where the result presently points to, with all & and * +\ applied, relative to the current location of the result. For example, if the +\ Result presently points to RS+4 and has "**" applied to it (lvl=2), we know +\ that when push comes to shove, we'll have two "@," to apply before we can +\ consider that we holw the value we're looking for. +\ When the base type is 32-bit, then it's easy. All "@," ops can be made in +\ 32-bit mode. When the base type is 16-bit or 8-bit, however, it's trickier and +\ we need a second indirection information: whether the final value we're about +\ to get is a direct value or a pointer. For this reason, we have the "blvl" +\ (Bottom Level), that is, the indirection level at which the final value lies. +\ That value has a size "basesz". All other levels have a 4b size. struct[ Result 0 const NONE \ Nothing (probably a released W) 1 const CONST \ Is a constant (value in arg) @@ -40,17 +26,19 @@ struct[ Result 3 const CDECL \ CDecl pointer is in arg. 4 const PS \ Result pushed to PS, offset in arg 5 const ARRAY \ Result is a constant array in a Stack. arg is a pointer to it. + sfield type sfield arg + sfield basesz \ size, in bytes of the base type sfield lvl \ lvl changed applied within the expression - sfield arilvl \ offset to apply to lvl to get the arithmetic level + sfield blvl \ Bottom Level \ 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 :[ , , 0 , 0 , syspad :] ; + : :new ( arg type -- res ) SZ syspad :[ , , CELLSZ , 0 , 0 , syspad :] ; : :none ( -- res ) 0 NONE :new ; : :const ( n -- res ) CONST :new ; : :W ( -- res ) :Wfree# 0 W :new dup to currentW ; @@ -62,22 +50,40 @@ struct[ Result : :?freeCurrentW ( -- ) currentW ?dup if :>PS then ; : :iscdecl? ( self -- f ) type CDECL = ; : :isarray? ( self -- f ) type ARRAY = ; + create _ ," NIWCPA" + : :. ( self -- ) + dup type _ + c@ emit spc> + dup arg over :iscdecl? if CDecl :. else .x then spc> + dup basesz . spc> dup lvl . spc> blvl . spc> + ." W=" currentW bool . nl> ; : :W! ( self -- ) dup to currentW W swap to type ; : :& ( self -- ) -1 swap to+ lvl ; : :cdecl ( cdecl -- res ) dup CDECL :new ( cdecl res ) - over bi CDecl lvl | CDecl nbelem bool + over to arilvl ( cdecl res ) - swap CDecl nbelem if dup :& -1 over to+ arilvl then ; + over CDecl type typesize over to basesz + over bi CDecl lvl | CDecl nbelem bool + over to blvl ( cdecl res ) + swap CDecl nbelem if dup :& -1 over to+ blvl then ; : :cdecl# dup :iscdecl? _assert arg ; + : :opsz ( halop self -- halop ) dup :. + bi+ lvl | blvl = if 'B' emit + basesz case 1 of = 8b) endof 2 of = 16b) endof endcase + else drop then ; : :hal# ( self -- halop ) dup type case ( self ) CONST of = arg i) endof - CDECL of = bi arg CDecl :halop | lvl applylvl endof + CDECL of = 'C' emit + bi+ arg CDecl :halop | lvl case ( self halop ) + 0 of = endof + -1 of = A>) lea, A*) endof + of 0>= r@ for A>) @, A) next drop A) endof + _err endcase ( self halop ) + swap :opsz endof PS of = arg PSP+) endof abort" :hal# error" endcase ; : :>W ( self -- ) - dup :isW? if drop else + dup :isW? if drop else 'W' emit :Wfree# dup :hal# @, + 0 over to@! lvl neg over to+ blvl dup to currentW W swap to type then ; : :>W$ ( self -- ) dup :>W :release ; : :isconst? ( self -- f ) type CONST = ; @@ -89,22 +95,29 @@ struct[ Result \ Free up W by sending it to A if needed. : :?>A ( self -- halop ) dup :isW? if :release W>A, A*) else :hal# then ; - : :* ( self -- ) - dup :isW? if W) @, then 1 swap to+ lvl ; + : :* ( self -- ) '*' emit + 1 over to+ lvl dup :isW? if '!' emit W) swap :opsz @, else drop then 'X' emit ; : :<<n ( n self -- ) dup :isconst? if dup arg rot lshift swap to arg else :?>W i) <<, then ; : :>>n ( n self -- ) dup :isconst? if dup arg rot rshift swap to arg else :?>W i) >>, then ; - : :arilvl bi arilvl | lvl - ; + \ 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+1, our arisz is "basesz" (we add and subtract by chunks of the + \ base type), otherwise it's 4 (we deal with pointers). : :*arisz ( self -- n ) \ pointer arithmetics multiplier - dup :arilvl case + dup bi blvl | lvl - case 0 of = drop 1 endof - \ TODO: make cdecl typesize follow when a :& converts the result. - \ Hardcoding to 4 is bad... - 1 of = dup :iscdecl? if :cdecl# CDecl type typesize else drop 4 then endof + 1 of = basesz endof drop 4 endcase ; + \ Copy meta information (basesz, lvl, blvl) from "other" result + : :copymeta ( other self -- ) + over basesz over to basesz + over lvl over to lvl + swap blvl swap to blvl ; + : :toint ( self -- ) 4 over to basesz 0 over to lvl 0 swap to blvl ; ]struct BOPSCNT wordtbl _tbl ( a b -- n ) diff --git a/fs/tests/comp/c/cc.fs b/fs/tests/comp/c/cc.fs @@ -38,8 +38,8 @@ array 52 #eq global 1234 #eq globalinc 1236 #eq globalinc 1238 #eq -testend \s 1 globalshort 2 #eq +testend \s 42 142 funcsig 184 #eq capture helloworld S" Hello World!" #s= create expected ," Null terminated\0"