gint_strcat/src/setjmp.s

83 lines
2.0 KiB
ArmAsm

/*
This file implements long jumps. An example of their use is with crt0.c
and exit()-family functions that use them to restore the execution
state when leaving the program from an unknown location.
The register contents are saved in a buffer when setjmp() is called and
restored at any time when longjmp() performs the jump, through an
exit() or abort() call, for instance.
This is actually a question of playing with pr ; the user program is
resumed after the setjmp() call when longjmp() is invoked but setjmp()
has nothing to do with this operation. longjmp() restores the pr value
that was saved by setjmp() and performs an rts instruction.
setjmp() returns 0 when called to set up the jump point and a non-zero
value when invoked through a long jump. If 0 is given as return value
to longjmp(), then 1 is returned.
*/
.global _setjmp
.global _longjmp
_setjmp:
/* Getting some free space. */
add #64, r4
/* Saving general-purpose registers. */
mov.l r15, @-r4
mov.l r14, @-r4
mov.l r13, @-r4
mov.l r12, @-r4
mov.l r11, @-r4
mov.l r10, @-r4
mov.l r9, @-r4
mov.l r8, @-r4
/* Saving control and system registers. */
stc.l sr, @-r4
stc.l ssr, @-r4
stc.l spc, @-r4
stc.l gbr, @-r4
stc.l vbr, @-r4
sts.l mach, @-r4
sts.l macl, @-r4
sts.l pr, @-r4
/* This function always return 0. The cases where setjmp() seems to
return non-zero values, when a long jump has just been performed, is
actually handled by longjmp(). */
rts
mov #0, r0
_longjmp:
/* Restoring the system and control registers. Restoring pr is actually
what performs the jump -- and makes the user program thinks that
setjmp() has returned. */
lds.l @r4+, pr
lds.l @r4+, macl
lds.l @r4+, mach
ldc.l @r4+, vbr
ldc.l @r4+, gbr
ldc.l @r4+, spc
ldc.l @r4+, ssr
ldc.l @r4+, sr
/* Restoring the general-purpose registers. */
mov.l @r4+, r8
mov.l @r4+, r9
mov.l @r4+, r10
mov.l @r4+, r11
mov.l @r4+, r12
mov.l @r4+, r13
mov.l @r4+, r14
mov.l @r4+, r15
/* Preventing return value from being 0 (must be at least 1). */
tst r5, r5
movt r0
rts
add r5, r0