;
; csetjmp.s
;
; Support for setjmp and longjmp
;
;  1995 Straylight
;

;----- Standard header ------------------------------------------------------

		GET	libs:header
		GET	libs:swis

		GET	libs:stream

;----- Main code ------------------------------------------------------------

		AREA	|Sapphire$$Code|,CODE,READONLY

; --- setjmp ---
;
; On entry:	R0 == pointer to setjmp block
;
; On exit:	R0 == 0
;
; Use:		Fills a jmp_buf with useful information

		EXPORT	setjmp
setjmp		ROUT

		SWI	XFPEmulator_Version	;Do we have FP available?
		MOVVS	R12,#0			;No -- remember this
		STRVS	R12,[R0,#84]		;Store the value away
		STFVCE	F4,[R0],#12		;Store FP registers
		STFVCE	F5,[R0],#12
		STFVCE	F6,[R0],#12
		STFVCE	F7,[R0],#12
		STMIA	R0,{R4-R11,R13,R14}	;Store lots of stuff
		MOV	R0,#0			;Return zero
		MOVS	PC,R14			;And return to caller

		LTORG

; --- longjmp ---
;
; On entry:	R0 == pointer to jmp_buf block
;		R1 == return value
;
; On exit:	R0 == R1 on entry, or 1 if R1 was 0
;
; Use:		Returns to a setjmp position.

		EXPORT	longjmp
longjmp		ROUT

		LDR	R14,[R0,#84]		;Load the final word out
		CMP	R14,#0			;Is it defined there?
		LDFNEE	F4,[R0],#12		;Load FP registers back
		LDFNEE	F5,[R0],#12
		LDFNEE	F6,[R0],#12
		LDFNEE	F7,[R0],#12
		LDMIA	R0,{R4-R14}		;Restore old registers
		MOVS	R0,R1			;Get the return value
		MOVEQ	R0,#1			;If it was zero, fiddle it
		MOVS	PC,R14			;And return to `caller'

		LTORG

;----- That's all, folks ----------------------------------------------------

		END
