| Copyright (C) 1992, Digital Equipment Corporation | All rights reserved. | See the file COPYRIGHT for a full description. | ! crunt.s | Last modified on Sep 15 21:19:07 1992 by rustan | ! Rustan Leino ! 15 September 1992 ! This file and the associated C file provide the C run-time ! that is needed to compile Modula-3 programs for the Mosaic ! Descriptions of the words in a jmp_buf: ! Offset Contents ! 0 sp (aka r1), containing the address of the return value ! placed on the stack for the setjmp call ! 1 pc, containing the return address for the setjmp call ! 2 r2, containing the value at the time of the setjmp call ! 3 r3, containing the value at the time of the setjmp call ! 4 r4, containing the value at the time of the setjmp call ! 5 r5, containing the value at the time of the setjmp call ! 6 r6, containing the value at the time of the setjmp call ! 7 r7, containing the value at the time of the setjmp call ! Note, r0 is used to hold function return values. Thus, it does not ! need to be stored in the jmp_buf. ! The number of words in the jmp_buf structure is 8. ! ! The prototypes of these functions are found in M3Runtime.h (except | newjmpbuf) and RTRegisters.i3. ! Note that longjmp does not take the usual 'val' parameter. .text ! ! int newjmpbuf( jmp_buf * env, int stackHigh, int pc ); ! ! stackHigh is the lowest address above the thread's stack. This must ! agree with the RTStack and RTMemory modules. .globl _newjmpbuf _newjmpbuf: mov r3,@--sp ! save old r3 mov 2[sp],r3 ! r3 := ADR( env[0] ) mov 3[sp],r0 ! env[0] := stackHigh sub #2,r0 ! - 2*ADRSIZE( ADDRESS ) mov r0,@r3++ mov 4[sp],@r3++ ! env[1] := given pc mov #0,r0 ! r0 := 0 mov r0,@r3++ ! env[2] := 0 (bp) mov r0,@r3++ ! env[3] := 0 (r3) mov r0,@r3++ ! env[4] := 0 (r4) mov r0,@r3++ ! env[5] := 0 (r5) mov r0,@r3++ ! env[6] := 0 (r6) mov r0,@r3 ! env[7] := 0 (r7) mov @sp++,r3 ! restore r3 jmp @@sp++ ! ! int setjmp( jmp_buf * env ); ! .globl _setjmp _setjmp: mov 1[sp],r0 ! r0 := ADR( env[0] ) mov sp,@r0++ ! env[0] := sp mov @sp,@r0++ ! env[1] := return address mov bp,@r0++ ! env[2] := bp mov r3,@r0++ ! env[3] := r3 mov r4,@r0++ ! env[4] := r4 mov r5,@r0++ ! env[5] := r5 mov r6,@r0++ ! env[6] := r6 mov r7,@r0 ! env[7] := r7 mov #0,r0 ! return value := 0 jmp @@sp++ ! ! void longjmp( jmp_buf * env ); ! .globl _longjmp _longjmp: mov 1[sp],r0 ! r0 := ADR( env[0] ) mov @r0,sp ! sp := env[0] mov r0,1[sp] ! previous setjmp parameter := ADR( env[0] ) inc r0,r0 ! r0 := ADR( env[1] ) mov @r0++,@sp ! return address := env[1] mov @r0++,bp ! bp := env[2] mov @r0++,r3 ! r3 := env[3] mov @r0++,r4 ! r4 := env[4] mov @r0++,r5 ! r5 := env[5] mov @r0++,r6 ! r6 := env[6] mov @r0,r7 ! r7 := env[7] mov #1,r0 ! return value := 1 jmp @@sp++ ! ! Modula-3 declaration: ! <* EXTERNAL "RTRegisters__SaveOtherSequence" *> ! PROCEDURE SaveOtherSequence( VAR regs: T ); ! An equivalent C declaration would read: ! void RTRegisters__SaveOtherSequence( jmp_buf * env ) ! ! (* Note, the registers saved in this call have a different format from ! those saved in setjmp. The buffers returned from these two calls ! are NOT compatible! *) ! (* REQUIRES inSystemCritical *) ! .globl _RTRegisters__SaveOtherSequence _RTRegisters__SaveOtherSequence: mov apc,@--sp ! save apc mov r8,@--sp ! save r8 mov 3[sp],r8 ! r8 := ADR( env[0] ) mov #doTheSave,apc punt mov @sp++,r8 ! restore r8 mov @sp++,apc ! restore apc jmp @@sp++ doTheSave: mov sp,@r8++ ! env[0] := sp mov r0,@r8++ ! env[1] := r0 NOTE, this is different from setjmp! mov bp,@r8++ ! env[2] := bp mov r3,@r8++ ! env[3] := r3 mov r4,@r8++ ! env[4] := r4 mov r5,@r8++ ! env[5] := r5 mov r6,@r8++ ! env[6] := r6 mov r7,@r8 ! env[7] := r7 punt ! return to calling context ! end of crunt.s