setjmp and longjmp implementation in mmix

137 views Asked by At

I've written an implementation of setjmp and longjmp in MMIX (assuming no name mangling). I also hand-assembled it.
Are there any mistakes anyone can spot?

    // Memory stack pointer is stored in $254.
    // jmp_buf is rO, next address after setjmp call, memory stack pointer,
    // frame pointer, then possibly other data (for sigsetjmp/siglongjmp).
    // rG is preserved over a longjmp call
    // (not that it should change over one, anyway)
setjmp IS @
    GET    $1,rO            // FE01000A
    STOU   $1,$0,0          // AF010000
    GET    $1,rJ            // FE010004
    STOU   $1,$0,8          // AF010008
    STOU   $254,$0,16       // AFFE0010
    STOU   $253,$0,24       // AFFD0018
    SETL   $0,0             // E3000000
    POP    1,0              // F8010000
longjmp IS @
    LDOU   $254,$0,0        // 8FFE0000
    SAVE   $255,0           // FAFF0000
    GET    $1,rG            // FE000013
    // why 15? We save 13 special registers, two local registers,
    // and the number 2, as well as any global registers.
    // That's 256-rG + 16, and we add only 15 because $255 is the address
    // of the saved rGA.
    SETL   $0,271           // E300010F
    SUBU   $1,$1,$0         // 26010100
    SLU    $1,$1,3          // 39000003
    // now $255 is topmost saved register, $255+$1 is bottommost such,
    // $254 is rO after.
    SUBU   $0,$254,$1       // 2600FE01
    LDOU   $2,$255,$1       // 8E02FF01
    STOU   $2,$0,$1         // AE020001
    INCL   $1,8             // E7010008
    PBNZ   $1,@-12          // 5B01FFFD
    OR     $255,$0,0        // C1FF0000
    UNSAVE 0,$255           // FB0000FF
    // now we have restored rO, but not other stuff
    LDOU   $253,$0,24       // 8FFD0018
    LDOU   $254,$0,16       // 8FFE0010
    LDOU   $0,$0,8          // 8F000008
    PUT    rJ,$0            // F6040000
    OR     $0,$1,0          // C1000100
    POP    1,0              // F8010000

The register stack was the hard part here. Everything between the SAVE and the UNSAVE inclusive is essentially just “set rO properly”; after that it takes no time at all to fix up the other registers and return.

If you have any other questions, I'm happy to explain my reasons for each tetra of that code.

0

There are 0 answers