RA Kernel

The RA (Register Allocator) Kernel contains an analytical compiler which keeps track of the top five stack elements and maps them to registers whenever possible.

It is Matthias latest Mecrisp-Stellaris development line and available for about 35 of the MCUs in the supported hardware list, but can be enabled at compile time for all MCUS when building the Core binary.

It features:

  • constant folding

  • inlining

  • tail-call optimisations

RA Register Map

r0: Free scratch register            ( Saved on interrupt entry by hardware )
r1: Free scratch register            ( Saved on interrupt entry by hardware )
r2: Free scratch register            ( Saved on interrupt entry by hardware )
r3: Free scratch register            ( Saved on interrupt entry by hardware )

r4: Inner loop count                 ( Needs Push and Pop when used otherwise )
r5: Inner loop limit                 ( Needs Push and Pop when used otherwise )

r6=TOS: Top-Of-Stack                 ( Stack design is interrupt safe )
r7=PSP: Parameter Stack Pointer      ( Stack design is interrupt safe )

r8:  Unused
r9:  Unused
r10: Unused
r11: Unused
r12: Unused                          ( Saved on interrupt entry by hardware )

r13=SP: Return Stack Pointer
r14=LR: Link Register
r15=PC: Program Counter, always odd

RA Bitexp Example

: bitexp ( u -- u )
 \ Returns an integer value equivalent to
 \ the exponential. For numbers > 16,
 \ bitexp(x) approx = 2^(x/8 + 1)
 \ B(E(x)) = x for 16 <= x <= 247.

 dup 247 u>  \ Overflow ?
 if drop $F0000000
 else
   dup 16 u<= if 1 rshift
              else
                dup ( u u )
                7 and 8 or ( u b )
                swap ( b u )
                3 rshift 2 - lshift
              then
 then
 1-foldable ;

See bitexp

Note that it compiles bitexp without any stack movements at all

00006BA2: 2EF7  cmp r6 #F7
00006BA4: B500  push { lr }
00006BA6: D902  bls 00006BAE
00006BA8: 26F0  movs r6 #F0
00006BAA: 0636  lsls r6 r6 #18
00006BAC: E00C  b 00006BC8
00006BAE: 2E10  cmp r6 #10
00006BB0: D801  bhi 00006BB6
00006BB2: 0876  lsrs r6 r6 #1
00006BB4: E008  b 00006BC8
00006BB6: 0033  lsls r3 r6 #0
00006BB8: 2007  movs r0 #7
00006BBA: 4003  ands r3 r0
00006BBC: 2008  movs r0 #8
00006BBE: 4303  orrs r3 r0
00006BC0: 08F6  lsrs r6 r6 #3
00006BC2: 3E02  subs r6 #2
00006BC4: 40B3  lsls r3 r6
00006BC6: 461E  mov r6 r3
00006BC8: BD00  pop { pc }

Convert your Classic Kernel to RA

Dive into the core assembly code.

Activate RA compiler optimisations by increasing the reserved core size to 0x5000 (up from the 0x4000 of the classic cores) and by adding an assembler switch:

.equ registerallocator, 1

Rebuild your Kernel.

Classic Mecrisp-Stellaris

  • Does not have the RA compiler or register mapping

  • lacks automatic inlining

  • Won’t run ( excepting mecrisp-stellaris-2.3.6-hook-find) Manfred Mahlow’s VOCS, a collection of source code modules to add wordlists, vocabularies, vocabulary prefixes and classes (for context switching objects) to Mecrisp-Stellaris Forth.

  • Lacks the roll and -roll Words

Mecrisp-Stellaris Deeper Configuration

There are a few deeper configuration values in mecrisp-stellaris-2.4.X/mecrisp-stellaris-source/common/forth-core.s. Have a look there !

You can increase the stack sizes in that file. For default, they are set to 64 elements each