2.11BSD/src/lib/libc/pdp/gen/rollback.s
/*
* Copyright (c) 1987 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#if defined(LIBC_SCCS) && !defined(lint)
<@(#)rollback.s 1.4 (2.11BSD GTE) 1/1/94\0>
.even
#endif
/*
* rollback(fp::r0)
* caddr_t fp;
*
* Overlaid version of rollback.
*
* This routine is used in conjuction with the various versions of longjmp to
* roll back r5 to a saved stack frame and restore r2, r3, and r4 from the
* immediately nested stack frame.
*
* Note that the register restore can fail if the routine being jumped to calls
* an assembly routine that uses one or more of the registers without creating
* a stack frame to save the old values of the registers. E.g. the assembly
* routine simply "pushes" any registers it uses then "pops" them afterwards.
* This causes rollback to fail because there's no stack frame to pull the
* original values of the registers from.
*
* Caveat: Don't use register variables in routines using setjmp's!
*/
.globl _longjmperror / just in case we roll off the end ...
.globl rollback
rollback:
cmp r5,r0 / if (we're longjmp'ing to ourselves)
beq 3f / return;
1: / do {
cmp (r5),r0 / if (the next frame is The Frame)
beq 2f / goto 2f;
mov (r5),r5 / while ((r5 = r5->next_frame) != 0)
bne 1b
jsr pc,_longjmperror / call longjmperror
iot / and die if we return
2:
mov r5,r2 / r2 = immediately nested frame
tst -(r2) / skip past saved overlay number
mov -(r2),r4 / restore r4,
mov -(r2),r3 / r3, and
mov -(r2),r2 / r2
mov (r5),r5 / r5 = desired frame
3:
rts pc / and return