88 lines
2.3 KiB
ArmAsm
88 lines
2.3 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 the above copyright notice, this notice
|
|
and the following disclaimer are 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
|