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
 |