Backend for a stack-oriented architecture

Jeff Law jeffreyalaw@gmail.com
Mon Feb 24 19:57:49 GMT 2025



On 2/24/25 4:32 AM, Florian Weimer wrote:
> As a hobby project, I'm working on a mostly memory-safe architecture
> that is targeted at direct software emulation.  The majority of its
> instructions have memory operands that are relative to the stack
> pointer.  Calls and returns adjust the stack pointer, so I suppose one
> could say that the architecture has register windows.  The reason for
> the stack-based approach is that an emulated register move would be a
> memory-to-memory move anyway.  I believe this approach is similar to
> the Lua VM and other VMs which hare generally considered
> register-based instead of stack-based.  Writing it by hand, it feels
> more register-based than stack-based, too, although the direct support
> for multiple return values makes it possible to use some Forth-like
> idioms.
> 
> Here's some example code (destination operand comes first):
> 
> .proc fib (_long) (_long)
> # Argument/result register: %3
> # return address register: %2
> # local register: %1
> # outgoing argument/return register: %0
>    .framesize 24 # in bytes, three registers excluding the incoming argument
>    ldic %1, 2
>    jlels %3, %1, :0    # If the argument is less than 2, just return it.
>    addlc %0, %3, -1    # Prepare argument for first recursive call.
>    callp fib
>    mv %1, %0           # Save result of first call.
>    addlc %0, %3, -2    # Prepare argument for second recursive call.
>    callp fib
>    addlso %3, %1, %0   # Sum of results, with an overflow check.
> :0
>    ret 24
> 
> The call instruction increments the stack pointer by 24 bytes to
> create the new frame.  This is how the argument becomes available as
> %3 in the callee.  (The real assembler has a minimal register
> allocator and computes the frame size automatically, so that the
> change of the argument registers is hidden from the programmer
> new local registers are introduced.)
> 
> I tried to create a GCC backend for this, by looking at the existing
> mmix backend (for the register windows) and the bpf backend (due to
> its verified nature) for inspiration.  I did not get very far because
> it's my first GCC backend.  I wonder if that's just my lack
> experience, or if the target just isn't a good fit for GCC.  I found
> Hans-Peter Nilsson old description of the CRIS backend, and it it
> mentions that GCC is not a good starting point for accumulator
> machines with just one register (and my target doesn't even have that,
> not really).
> 
> If advisable, I can redefine the target to make it more GCC-friendly,
> perhaps by introducing a register file separate from the stack.
> (Although this would make the emulator and verifier more complex.)
You might be able to pretend you have a flat register file up through 
allocation & reloading, then convert that to a stack.   The code in 
reg-stack.c might help since it does basically the same thing for the 
x86 FP unit.

But it's not a great fit for GCC in general.

Jeff



More information about the Gcc mailing list