newlib-cygwin/newlib/libc/sys/mmixware/setjmp.S

86 lines
2.4 KiB
ArmAsm

/* Setjmp and longjmp for mmix.
Copyright (C) 2001 Hans-Peter Nilsson.
Permission to use, copy, modify, and distribute this software is freely
granted, provided that this notice is preserved with no changes.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.
jmp_buf[5]:
0: fp
1: rJ (return-address)
2: sp
3: rO *before* the setjmp call.
4: temporary storage. Reserved between setjmp and longjmp. */
#ifdef __MMIX_ABI_GNU__
#define arg1 $231
#define arg2 $232
#define outret $231
#define popval 0
#else
#define arg1 $0
#define arg2 $1
#define outret $0
#define popval 1
#endif
.section .text.setjmp,"ax",@progbits
.global setjmp
setjmp:
% Store fp, sp and return address. Recycle the static-chain and
% structure-return registers as temporary register, since we need to keep
% the jmp_buf (parameter 1) and the return address across a "POP".
SET $251,arg1
STOU $253,$251,0
GET $252,rJ
STOU $252,$251,8
STOU $254,$251,16
SETL outret,0
% Jump through hoops to get the value of rO *before* the setjmp call.
GETA $255,0f
PUT rJ,$255
POP popval,0
0:
GET $255,rO
STOU $255,$251,24
GO $255,$252,0
.size setjmp,.-setjmp
.section .text.longjmp,"ax",@progbits
.global longjmp
longjmp:
% Reset arg2 to 1 if it is 0 (see longjmp(2)) and store it in jmp_buf.
% Save arg1 in a global register, since it will be destroyed by the POPs
% (in the mmixware ABI).
CSZ arg2,arg2,1
STOU arg2,arg1,32
SET $251,arg1
% Loop and "POP 0,0" until rO is the expected value, like
% the expansion of nonlocal_goto_receiver, except that we put the return
% value in the right register and make sure that the POP causes it to
% enter the right return-value register as seen by the caller. For the
% GNU ABI, it is unnecessary to do this in the loop and perhaps the memory
% access can be hoisted outside the loop, but this is safe and simple and
% I see no need to optimize longjmps.
GETA $255,0f
PUT rJ,$255
LDOU $255,$251,24
0:
GET $252,rO
CMPU $252,$252,$255
BNP $252,1f
LDOU outret,$251,32
POP popval,0
1:
LDOU $253,$251,0
LDOU $255,$251,8
LDOU $254,$251,16
GO $255,$255,0
.size longjmp,.-longjmp