Some words and code routines are marked in the documentation as INTERNAL. These are factors used by other words and do not have dictionary entries in the standalone Forth. They are only accessible to users of the VFX Forth ARM Cross Compiler. This also applies to definitions of the form:
n EQU <name>
PROC <name>
L: <name>
On the ARM the following register usage is the default:
|
The VFX optimiser reserves R0 and R1 for internal operations. CODE definitions must use R10 as TOS with NOS pointed to by R12 as a full descending stack in ARM terminology. R0..R8 are free for use by CODE definitions and need not be preserved or restored. You should assume that any register can be affected by other words.
These equates are set false (zero) if they have not already been defined.
false equ HIGH-LEVEL-ROLL \ -- flag
Set this equate true to compile a high level version of
ROLL.
false equ CLZ? \ -- flag
Set this non-zero to compile CLZ.
false equ DSQRT? \ -- flag
Set this non-zero to compile DSQRT.
false equ FastCmove? \ -- flag
Set this flag true to use a fast but vast (~1kb) version of
CMOVE. If your application uses either CMOVE or
MOVE in time-critical code, the fast version offers
an overall speed up of about four times. The code for the
fast but vast version was written by Rowley Associates,
whose permission to adapt and publish the code with the
MPE cross compiler is much appreciated.
CODE AND \ x1 x2 -- x3
Perform a logical AND between the top two stack items and retain
the result in top of stack.
CODE OR \ x1 x2 -- x3
Perform a logical OR between the top two stack items and retain
the result in top of stack.
CODE XOR \ x1 x2 -- x3
Perform a logical XOR between the top two stack items and retain
the result in top of stack.
CODE NOT \ x -- x'
Perform a bitwise NOT on the top stack item and retain result.
CODE INVERT \ x -- x'
Perform a bitwise NOT on the top stack item and retain result.
CODE 0= \ x -- flag
Compare the top stack item with 0 and return TRUE if equals.
CODE 0<> \ x -- flag
Compare the top stack item with 0 and return TRUE if not-equal.
CODE 0< \ x -- flag
Return TRUE if the top of stack is less-than-zero.
CODE 0> \ x -- flag
Return TRUE if the top of stack is greater-than-zero.
CODE = \ x1 x2 -- flag
Return TRUE if the two topmost stack items are equal.
CODE <> \ x1 x2 -- flag
Return TRUE if the two topmost stack items are different.
CODE < \ n1 n2 -- flag
Return TRUE if n1 is less than n2.
CODE > \ n1 n2 -- flag
Return TRUE if n1 is greater than n2.
CODE <= \ n1 n2 -- flag
Return TRUE if n1 is less than or equal to n2.
CODE >= \ x1 x2 -- flag
Return TRUE if n1 is greater than or equal to n2.
CODE U> \ u2 u2 -- flag
An UNSIGNED version of >.
CODE U< \ u1 u2 -- flag
An UNSIGNED version of <.
CODE DU< \ ud1 ud2 -- flag
Returns true if ud1 (unsigned double) is less than ud2.
CODE D0< \ d -- flag
Returns true if signed double d is less than zero.
CODE D0= \ xd -- flag
Returns true if xd is 0.
CODE D= \ xd1 xd2 -- flag
Return TRUE if the two double numbers are equal.
CODE D< \ d1 d2 -- flag
Return TRUE if the double number d1 is (signed) less than the
double number d2.
CODE DMAX \ d1 d2 -- d3 ; d3=max of d1/d2
Return the maximum double number from the two supplied.
CODE DMIN \ d1 d2 -- d3 ; d3=min of d1/d2
Return the minimum double number from the two supplied.
CODE MIN \ n1 n2 -- n1|n2
Given two data stack items preserve only the smaller.
CODE MAX \ n1 n2 -- n1|n2
Given two data stack items preserve only the larger.
CODE WITHIN? \ n1 n2 n3 -- flag
Return TRUE if N1 is within the range N2..N3.
This word uses signed arithmetic.
CODE WITHIN \ n1|u1 n2|u2 n3|u3 -- flag
The ANS version of WITHIN?.
This word uses unsigned arithmetic, so that signed compares are
treated as existing on a number circle.
CODE LSHIFT \ x1 u -- x2
Logically shift X1 by U bits left.
CODE RSHIFT \ x1 u -- x2
Logically shift X1 by U bits right.
CODE << \ x1 u -- x1<<u
Logically shift X1 by U bits left.
Obsolete - replaced by LSHIFT.
CODE >> \ x1 u -- x1<<u
Logically shift X1 by U bits right.
Obsolete - replaced by RSHIFT.
CODE EXECUTE \ xt --
Execute the code described by the XT. This is a Forth equivalent
to an assembler JSR/CALL instruction.
CODE BRANCH \ --
The run time action of unconditional branches compiled on the target.
INTERNAL.
CODE ?BRANCH \ n --
The run time action of conditional branches compiled on the target.
INTERNAL.
CODE (OF) \ n1 n2 -- n1|--
The run time action of OF compiled on the target.
INTERNAL.
CODE (LOOP) \ --
The run time action of LOOP compiled on the target.
INTERNAL.
CODE (+LOOP) \ n --
The run time action of +LOOP compiled on the target.
INTERNAL.
CODE (DO) \ limit index --
The run time action of DO compiled on the target.
INTERNAL.
CODE (?DO) \ limit index --
The run time action of ?DO compiled on the target.
INTERNAL.
CODE LEAVE \ --
Remove the current DO..LOOP parameters and jump to the
end of the DO..LOOP structure.
CODE ?LEAVE \ flag --
If flag is non-zero, remove the current DO..LOOP parameters
and jump to the end of the DO..LOOP structure.
CODE I \ -- n
Return the current index of the inner-most DO..LOOP.
CODE J \ -- n
Return the current index of the second DO..LOOP.
CODE UNLOOP \ -- ; R: loop-sys --
Remove the DO..LOOP control parameters from the return stack.
CODE S>D \ n -- d
Convert a single number to a double one.
CODE D>S \ d -- n
Convert a double number to a single.
CODE NOOP \ --
A NOOP, null instruction. )
CODE M+ \ d1|ud1 n -- d2|ud2
Add double d1 to sign extended single n to form double d2.
CODE 1+ \ n1|u1 -- n2|u2
Add one to top-of stack.
CODE 2+ \ n1|u1 -- n2|u2
Add two to top-of stack.
CODE 4+ \ n1|u1 -- n2|u2
Add four to top-of stack.
CODE 1- \ n1|u1 -- n2|u2
Subtract one from top-of stack.
CODE 2- \ n1|u1 -- n2|u2
Subtract two from top-of stack.
CODE 4- \ n1|u1 -- n2|u2
Subtract four from top-of stack.
CODE 2* \ x1 -- x2
Signed multiply top of stack by 2.
CODE 4* \ x1 -- x2
Signed multiply top of stack by 4.
CODE 2/ \ x1 -- x2
Signed divide top of stack by 2.
CODE U2/ \ x1 -- x2
Unsigned divide top of stack by 2.
CODE 4/ \ x1 -- x2
Signed divide top of stack by 4.
CODE U4/ \ x1 -- x2
Unsigned divide top of stack by 4.
CODE + \ n1|u1 n2|u2 -- n3|u3
Add two single precision integer numbers.
CODE - \ n1|u1 n2|u2 -- n3|u3
Subtract two single precision integer numbers. N3|u3=n1|u1-n2|u2.
CODE NEGATE \ n1 -- n2
Negate a single precision integer number.
CODE D+ \ d1 d2 -- d3
Add two double precision integers.
CODE D- \ d1 d2 -- d3
Subtract two double precision integers. D3=D1-D2.
CODE DNEGATE \ d1 -- -d1
Negate a double number.
CODE ?NEGATE \ n1 flag -- n1|n2
If flag is negative, then negate n1.
CODE ?DNEGATE \ d1 flag -- d1|d2
If flag is negative, then negate d1.
CODE ABS \ n -- u
If n is negative, return its positive equivalent (absolute value).
CODE DABS \ d -- ud
If d is negative, return its positive equivalent (absolute value).
CODE D2* \ xd1 -- xd2
Multiply the given double number by two.
CODE D2/ \ xd1 -- xd2
Divide the given double number by two.
CODE UM* \ u1 u2 -- ud
Perform unsigned-multiply between two numbers and return double
result.
CODE * \ n1 n2 -- n3
Standard signed multiply. N3 = n1 * n2.
CODE m* \ n1 n2 -- d
Signed multiply yielding double result.
Division on an ARM is really slow. Avoid it if you can where performance matters. Multiplication by the reciprocal and polynomial approximations are usually the recommended techniques. We have opted for performance over code size. The memory behaviour of many embedded ARM devices compunds the impact of the additional test and branch overheads. Consequently, the test and subtract loops are unrolled. Unlike most other processors, signed division is faster than unsigned!
For more details of implementing division on an ARM, and for many other numerical coding techniques, see the "ARM System Developer's Guide", ISBN 1-55860-874-5
macro: udiv64_step \ --
Cross compiler macro to perform one step of the unsigned
64 bit by 32 bit division
code um/mod \ ud1 u2 -- urem uquot
Slow and short - Full 64 by 32 unsigned division subroutine.
This routine uses a loop for code size. This version is
commented out by default.
code um/mod \ ud1 u2 -- urem uquot
Fast and big - Full 64 by 32 unsigned division subroutine.
Unrolled for speed. This routine uses 920 bytes of code space.
proc Udiv63/31 \ r0:r1/tos ; 64/32 unsigned divide -> tos=quot, r0=rem
Unsigned division primitive - unrolled for speed.
Note that this routine does not handle the top bit of the divisor
and dividend correctly. Udiv63/31 is used for signed divide
operations for which the top bits are always zero.
CODE FM/MOD \ d1 n2 -- rem quot ; floored division
Perform a signed division of double number D1 by single number N2
and return remainder and quotient using floored division. See the
ANS Forth specification for more details of floored division.
CODE SM/REM \ d1 n2 -- rem quot ; symmetric division
Perform a signed division of double number D1 by single number N2
and return remainder and quotient using symmetric (normal) division.
CODE /MOD \ n1 n2 -- rem quot
Signed division of N1 by N2 single-precision yielding remainder
and quotient.
CODE M/MOD \ d1 n2 -- rem quot
A synonym for FM/MOD for Forth-83 compatibility.
Obsolete - Use FM/MOD instead.
: / \ n1 n2 -- n3
Standard signed division operator. n3 = n1/n2.
: MOD \ n1 n2 -- n3
Return remainder of division of N1 by N2. n3 = n1 mod n2.
: M/ \ d n1 -- n2
Signed divide of a double by a single integer.
: MU/MOD \ d n -- rem d#quot
Perform an unsigned divide of a double by a single, returning
a single remainder and a double quotient.
These operations perform a multiply followed by a divide. The intermediate result is in an extended form. The point of this operation is to avoid loss of precision.
: */MOD \ n1 n2 n3 -- n4 n4
Multiply n1 by n2 to give a double precision result, and then
divide it by n3 returning the remainder and quotient.
: */ \ n1 n2 n3 -- n4
Multiply n1 by n2 to give a double precision result, and then
divide it by n3 returning the quotient.
: m*/ \ d1 n2 n3 -- dquot
The result dquot=(d1*n2)/n3. The intermediate value d1*n2
is triple-precision to avoid loss of precision. In an ANS
Forth standard program n3 can only be a positive signed
number and a negative value for n3 generates an ambiguous
condition, which may cause an error on some implementations,
but not in this one.
CODE NIP \ x1 x2 -- x2
Dispose of the second item on the data stack.
CODE TUCK \ x1 x2 -- x2 x1 x2
Insert a copy of the top data stack item underneath the current
second item.
CODE PICK \ xu .. x0 u -- xu .. x0 xu
Get a copy of the Nth data stack item and place on top of stack.
0 PICK is equivalent to DUP.
: ROLL \ xu xu-1 .. x0 u -- xu-1 .. x0 xu
Rotate the order of the top N stack items by one place such that
the current top of stack becomes the second item and the Nth item
becomes TOS. See also ROT.
CODE ROT \ x1 x2 x3 -- x2 x3 x1
ROTate the positions of the top three stack items such that the
current top of stack becomes the second item. See also ROLL.
CODE -ROT \ x1 x2 x3 -- x3 x1 x2
The inverse of ROT.
CODE >R \ x -- ; R: -- x
Push the current top item of the data stack onto the top of the
return stack.
CODE R> \ -- x ; R: x --
Pop the top item from the return stack to the data stack.
CODE R@ \ -- x ; R: x -- x
Copy the top item from the return stack to the data stack.
CODE 2>R \ x1 x2 -- ; R: -- x1 x2
Transfer the two top data stack items to the return stack.
CODE 2R> \ -- x1 x2 ; R: x1 x2 --
Transfer the top two return stack items to the data stack.
CODE 2R@ \ -- x1 x2 ; R: x1 x2 -- x1 x2
Copy the top two return stack items to the data stack.
CODE 2ROT \ x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2
Perform the ROT operation on three cell-pairs.
CODE SWAP \ x1 x2 -- x2 x1
Exchange the top two data stack items.
CODE DUP \ x -- x x
DUPlicate the top stack item.
CODE OVER \ x1 x2 -- x1 x2 x1
Copy NOS to a new top-of-stack item.
CODE DROP \ x --
Lose the top data stack item and promote NOS to TOS.
CODE 2DROP \ x1 x2 -- )
Discard the top two data stack items.
CODE 2SWAP \ x1 x2 x3 x4 -- x3 x4 x1 x2
Exchange the top two cell-pairs on the data stack.
CODE ?DUP \ x -- | x
DUPlicate the top stack item only if it non-zero.
CODE 2DUP \ x1 x2 -- x1 x2 x1 x2
DUPlicate the top cell-pair on the data stack.
CODE 2OVER \ x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2
As OVER but works with cell-pairs rather than single-cell items.
CODE SP@ \ -- x
Get the current address value of the data-stack pointer.
CODE SP! \ x --
Set the current address value of the data-stack pointer.
CODE RP@ \ -- x
Get the current address value of the return-stack pointer.
CODE RP! \ x --
Set the current address value of the return-stack pointer.
CODE COUNT \ c-addr1 -- c-addr2' u
Given the address of a counted string in memory this word will
return the address of the first character and the length in
characters of the string.
CODE /STRING \ c-addr1 u1 n -- c-addr2 u2
Modify a string address and length to remove the first N characters
from the string.
CODE SKIP \ c-addr1 u1 char -- c-addr2 u2
Modify the string description by skipping over leading occurrences of
'char'.
CODE SCAN \ c-addr1 u1 char -- c-addr2 u2
Look for first occurrence of char in the string and
return a new string. C-addr2/u2 describes the string
with char as the first character.
CODE S= \ c-addr1 c-addr2 u -- flag
Compare two same-length strings/memory blocks, returning TRUE if
they are identical.
: compare \ c-addr1 u1 c-addr2 u2 -- n 17.6.1.0935
Compare two strings. The return result is 0 for a match or can be
-ve/+ve indicating string differences.
If the two strings are identical, n is zero. If the two strings
are identical up to the length of the shorter string, n is
minus-one (-1) if u1 is less than u2 and one (1) otherwise.
If the two strings are not identical up to the length of the
shorter string, n is minus-one (-1) if the first non-matching
character in the string specified by c-addr1 u1 has a lesser
numeric value than the corresponding character in the string
specified by c-addr2 u2 and one (1) otherwise.
: SEARCH ( c-addr1 u1 c-addr2 u2 -- c-addr3 u3 flag )
Search the string c-addr1/u1 for the string c-addr2/u2. If a match
is found return c-addr3/u3, the address of the start of the match
and the number of characters remaining in c-addr1/u1, plus flag f
set to true. If no match was found return c-addr1/u1 and f=0.
code cmove \ asrc adest len --
Copy len bytes of memory forwards from asrc to adest.
If the performance of CMOVE is important in your
application, set the equate FastCmove? non-zero and
a much faster but much larger version will be compiled.
See Arm\fcmove.fth for the details.
CODE CMOVE> \ c-addr1 c-addr2 u --
As CMOVE but working in the opposite direction,
copying the last character in the string first.
CODE ON \ a-addr --
Given the address of a CELL this will set its contents to TRUE (-1).
CODE OFF \ a-addr --
Given the address of a CELL this will set its contents to FALSE (0).
CODE C+! \ b c-addr --
Add N to the character (byte) at memory address ADDR.
CODE 2@ \ a-addr -- x1 x2
Fetch and return the two CELLS from memory ADDR and ADDR+sizeof(CELL).
The cell at the lower address is on the top of the stack.
CODE 2! \ x1 x2 a-addr --
Store the two CELLS x1 and x2 at memory ADDR.
X2 is stored at ADDR and X1 is stored at ADDR+CELL.
CODE FILL \ c-addr u char --
Fill LEN bytes of memory starting at ADDR with the byte information
specified as CHAR.
CODE +! \ n|u a-addr --
Add N to the CELL at memory address ADDR.
CODE INCR \ a-addr --
Increment the data cell at a-addr by one.
CODE DECR \ a-addr --
Decrement the data cell at a-addr by one.
CODE @ \ a-addr -- x
Fetch and return the CELL at memory ADDR.
CODE W@ \ a-addr -- w
Fetch and 0 extend the word (16 bit) at memory ADDR.
CODE C@ \ c-addr -- char
Fetch and 0 extend the character at memory ADDR and return.
CODE ! \ x a-addr --
Store the CELL quantity X at memory A-ADDR.
CODE W! \ w a-addr --
Store the word (16 bit) quantity w at memory ADDR.
CODE C! \ char c-addr --
Store the character CHAR at memory C-ADDR.
CODE UPPER \ c-addr u --
Convert the ASCII string described to upper-case. This operation
happens in place.
CODE TEST-BIT \ mask c-addr -- flag
AND the mask with the contents of addr and return true if the
result is non-zero (-1) or false (0) if the result is zero.
Byte operation.
CODE SET-BIT \ mask c-addr --
Apply the mask ORred with the contents of c-addr.
Byte operation.
CODE RESET-BIT \ mask c-addr --
Apply the mask inverted and ANDed with the contents of c-addr.
Byte operation.
CODE TOGGLE-BIT \ u c-addr --
Invert the bits at c-addr specified by the mask. Byte operation.
CODE NAME> \ nfa -- cfa
Move a pointer from an NFA to the CFA or "XT" in ANS parlance.
CODE >NAME \ cfa -- nfa
Move a pointer from an XT back to the NFA or name-pointer.
If the original pointer was not an XT or if the definition in
question has no name header in the dictionary the returned pointer
will be useless. Care should be taken when manipulating or scanning
the Forth dictionary in this way.
: SEARCH-WORDLIST \ c-addr u wid -- 0|xt 1|xt -1
Search the given wordlist for a definition. If the definition is
not found then 0 is returned, otherwise the XT of the definition
is returned along with a non-zero code. A -ve code indicates a
"normal" definition and a +ve code indicates an IMMEDIATE word.
CODE DIGIT \ char n -- 0|n true
If the ASCII value CHAR can be treated as a digit for a number
within the radix N then return the digit and true, otherwise
return false.
Using these words will make code easier to port between 16, 32 and 64 bit targets.
CODE CELL+ \ a-addr1 -- a-addr2
Add the size of a CELL to the top-of stack.
CODE CELLS \ n1 -- n2
Return the size in address units of N1 cells in memory.
CODE CELL- \ a-addr1 -- a-addr2
Decrement an address by the size of a cell.
CODE CELL \ -- n
Return the size in address units of one CELL.
CODE CHAR+ \ c-addr1 -- c-addr2
Increment an address by the size of a character.
CODE CHARS \ n1 -- n2
Return size in address units of N1 characters.
CODE VAL! \ n -- ; store value address in-line
Store n at the inline address following this word.
INTERNAL.
CODE VAL@ \ -- n ; read value data address in-line
Read n from the inline address following this word.
INTERNAL.
L: DOCREATE \ -- addr
The run time action of CREATE.
INTERNAL.
CODE LIT \ -- x
Code which when CALLED at runtime will return an inline cell
value.
INTERNAL.
CODE (") \ -- a-addr ; return address of string, skip over it
Return the address of a counted string that is inline after the
CALLING word, and adjust the CALLING word's return address to
step over the inline string. See the definition of (.") for
an example.
INTERNAL.
: aligned \ addr -- addr'
Given an address pointer this word will return the next ALIGNED
address subject to system wide alignment restrictions.
: CONSTANT \ x "<spaces>name" -- ; Exec: -- x
Create a new CONSTANT called name which has the
value x. When NAME is executed the value is
returned.
: VARIABLE \ "<spaces>name" -- ; Exec: -- a-addr
Create a new variable called name. When name" is
executed the address of the data-cell is returned for use
with @ and ! operators.
: USER \ u "<spaces>name" -- ; Exec: -- addr ; SFP009
Create a new USER variable called name. The u
parameter specifies the index into the user-area table at which
to place the* data. USER variables are located in a
separate area of memory for each task or interrupt. Use in
the form:
$400 USER TaskData
: u# \ "<name>"-- u
An INTERPRETER word that returns the index of the
USER variable whose name follows, e.g.
u# S0
: DOCOLON, \ --
Compile the runtime entry code required by colon definitions.
INTERNAL.
: !call \ dest addr --
Install a BL DEST opcode at addr.
: scall, \ addr --
Compile a machine code BL to addr. No range checking is performed.
: compile, \ xt --
Compile the word specified by xt into the current definition.
: call, \ dest --
Compile a BL or long CALL into the current definition.
: >BODY \ xt -- a-addr
Move a pointer from a CFA or "XT" to the definition BODY. This
should only be used with children of CREATE. E.g. if
FOOBAR is defined by CREATE foobar, then the
phrase ' foobar >body would yield the same result as
executing foobar.
: : \ C: "<spaces>name" -- colon-sys ; Exec: i*x -- j*x ; R: -- nest-sys
Begin a new definition called name.
: :NONAME \ C: -- colon-sys ; Exec: i*x -- i*x ; R: -- nest-sys
Begin a new code definition which does not have a name. After the
definition is complete the semi-colon operator returns the XT of
newly compiled code on the stack.
: DOCREATE, \ --
Compile the run time action of CREATE.
INTERNAL.
: (;CODE) \ -- ; R: a-addr --
Performed at compile time by ;CODE and DOES>.
Patch the last word defined (by CREATE) to have the
run time actions that follow immediately after (;CODE).
INTERNAL.
: DOES> \ C: colon-sys1 -- colon-sys2 ; Run: -- ; R: nest-sys --
Begin definition of the runtime-action of a child of a defining word.
See the section about defining words in Programming Forth.
You should not use RECURSE after DOES>.
: CRASH \ -- ; used as action of DEFER
The default action of a DEFERed word. This will simply
THROW a code back to the system.
: DEFER \ Comp: "<spaces>name" -- ; Run: i*x -- j*x
Creates a new DEFERed word. A default action,
CRASH, is automatically assigned.
: 2CONSTANT \ Comp: x1 x2 "<spaces>name" -- ; Run: -- x1 x2
A two-cell equivalent to CONSTANT.
: 2VARIABLE \ Comp: "<spaces>name" -- ; Run: -- a-addr
A two-cell equivalent to VARIABLE.
: FIELD \ size n "<spaces>name" -- size+n ; Exec: addr -- addr+n
Create a new field within a structure definition of size n bytes.
These words define high level branches. They are used by the structure words such as IF and AGAIN.
: >mark \ -- addr
Mark the start of a forward branch. HIGH LEVEL CONSTRUCTS ONLY.
INTERNAL.
: >resolve \ addr --
Resolve absolute target of forward branch. HIGH LEVEL CONSTRUCTS ONLY.
INTERNAL.
: <mark \ -- addr
Mark the start (destination) of a backward branch.
HIGH LEVEL CONSTRUCTS ONLY.
INTERNAL.
: <resolve \ addr --
Resolve a backward branch to addr.
HIGH LEVEL CONSTRUCTS ONLY.
INTERNAL.
synonym >c_res_branch >resolve \ addr -- ; fix up forward referenced branch
See >RESOLVE.
INTERNAL.
synonym c_mrk_branch< <mark \ -- addr ; mark destination of backward branch
See <MARK
INTERNAL.
Used when compiling code on the target.
: c_branch< \ addr --
Lay the code for BRANCH.
INTERNAL.
: c_?branch< \ addr --
Lay the code for ?BRANCH.
: c_branch> \ -- addr
Lay the code for a forward referenced unconditional branch.
INTERNAL.
: c_?branch> \ -- addr
Lay the code for a forward referenced conditional branch.
INTERNAL.
: c_lit \ lit --
Compile the code for a LITERAL.
INTERNAL.
: c_drop \ --
Compile the code for DROP.
INTERNAL.
: c_exit \ --
Compile the code for EXIT.
INTERNAL.
: c_do \ C: -- do-sys ; Run: n1|u1 n2|u2 -- ; R: -- loop-sys
Compile the code for DO.
INTERNAL.
: c_?DO \ C: -- do-sys ; Run: n1|u1 n2|u2 -- ; R: -- | loop-sys
Compile the code for ?DO.
INTERNAL.
: c_LOOP \ C: do-sys -- ; Run: -- ; R: loop-sys1 -- | loop-sys2
Compile the code for LOOP.
INTERNAL.
: c_+LOOP \ C: do-sys -- ; Run: -- ; R: loop-sys1 -- | loop-sys2
Compile the code for +LOOP.
INTERNAL.
variable NextCaseTarg \ -- addr
Holds the entry point of the current CASE structure.
INTERNAL.
: c_case \ -- addr
Compile the code for CASE.
INTERNAL.
: c_OF \ C: -- of-sys ; Run: x1 x2 -- | x1
Compile the code for OF.
INTERNAL.
: c_ENDOF \ C: case-sys1 of-sys -- case-sys2 ; Run: --
Compile the code for ENDOF.
INTERNAL.
: FIX-EXITS \ n1..nn --
Compile the code to resolve the forward branches at the end
of a CASE structure.
INTERNAL.
: c_ENDCASE \ C: case-sys -- ; Run: x --
Compile the code for ENDCASE.
INTERNAL.
: c_END-CASE \ C: case-sys -- ; Run: x --
Compile the code for END-CASE.
INTERNAL. Only compiled if equate FullCase? is non-zero.
: c_NEXTCASE \ C: case-sys -- ; Run: x --
Compile the code for NEXTCASE.
INTERNAL. Only compiled if equate FullCase? is non-zero.
: c_?OF \ C: -- of-sys ; Run: flag --
Compile the code for ?OF.
INTERNAL. Only compiled if equate FullCase? is non-zero.
code clz \ x -- #lz
Count the number of leading zeros in x.
The equate CLZ? must be set true to compile this word.
32bit? [if] 32 [else] 16 [then] equ #bits \ -- u
Number of bits in a cell.
code dsqrt \ +d -- n
Single square root of a double number. 62 bits -> 31 bits.
The equate DSQRT? must be set true to compile this word.
: setMask \ value mask addr --
Clear the mask bits at addr and set (or) the
bits defined by value.