diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/setjmp/powerpc64/longjmp.s | 14 | ||||
| -rw-r--r-- | src/setjmp/powerpc64/setjmp.s | 21 | ||||
| -rw-r--r-- | src/signal/powerpc64/sigsetjmp.s | 21 | 
3 files changed, 39 insertions, 17 deletions
| diff --git a/src/setjmp/powerpc64/longjmp.s b/src/setjmp/powerpc64/longjmp.s index 7f241c2d..81d45ff6 100644 --- a/src/setjmp/powerpc64/longjmp.s +++ b/src/setjmp/powerpc64/longjmp.s @@ -10,10 +10,14 @@ longjmp:  	# 1) restore cr  	ld   0,  1*8(3)  	mtcr 0 -	# 2) restore r1-r2 (SP and TOC) +	# 2) restore SP  	ld   1,  2*8(3) +	# 3) restore TOC into both r2 and the caller's stack. +	#    Which location is required depends on whether setjmp was called +	#    locally or non-locally, but it's always safe to restore to both.  	ld   2,  3*8(3) -	# 3) restore r14-r31 +	std  2,   24(1) +	# 4) restore r14-r31  	ld  14,  4*8(3)  	ld  15,  5*8(3)  	ld  16,  6*8(3) @@ -32,7 +36,7 @@ longjmp:  	ld  29, 19*8(3)  	ld  30, 20*8(3)  	ld  31, 21*8(3) -	# 4) restore floating point registers f14-f31 +	# 5) restore floating point registers f14-f31  	lfd 14, 22*8(3)  	lfd 15, 23*8(3)  	lfd 16, 24*8(3) @@ -52,7 +56,7 @@ longjmp:  	lfd 30, 38*8(3)  	lfd 31, 39*8(3) -	# 5) restore vector registers v20-v31 +	# 6) restore vector registers v20-v31  	addi 3, 3, 40*8  	lvx 20, 0, 3 ; addi 3, 3, 16  	lvx 21, 0, 3 ; addi 3, 3, 16 @@ -67,7 +71,7 @@ longjmp:  	lvx 30, 0, 3 ; addi 3, 3, 16  	lvx 31, 0, 3 -	# 6) return r4 ? r4 : 1 +	# 7) return r4 ? r4 : 1  	mr    3,   4  	cmpwi cr7, 4, 0  	bne   cr7, 1f diff --git a/src/setjmp/powerpc64/setjmp.s b/src/setjmp/powerpc64/setjmp.s index d16d4bae..37683fda 100644 --- a/src/setjmp/powerpc64/setjmp.s +++ b/src/setjmp/powerpc64/setjmp.s @@ -1,24 +1,35 @@ -	.global ___setjmp -	.hidden ___setjmp  	.global __setjmp  	.global _setjmp  	.global setjmp  	.type   __setjmp,@function  	.type   _setjmp,@function  	.type   setjmp,@function -___setjmp:  __setjmp:  _setjmp:  setjmp: +	ld 5, 24(1)   # load from the TOC slot in the caller's stack frame +	b __setjmp_toc + +	.localentry __setjmp,.-__setjmp +	.localentry _setjmp,.-_setjmp +	.localentry setjmp,.-setjmp +	mr 5, 2 + +	.global __setjmp_toc +	.hidden __setjmp_toc +	# same as normal setjmp, except TOC pointer to save is provided in r5. +	# r4 would normally be the 2nd parameter, but we're using r5 to simplify calling from sigsetjmp. +	# solves the problem of knowing whether to save the TOC pointer from r2 or the caller's stack frame. +__setjmp_toc:  	# 0) store IP into 0, then into the jmpbuf pointed to by r3 (first arg)  	mflr  0  	std   0,  0*8(3)  	# 1) store cr  	mfcr  0  	std   0,  1*8(3) -	# 2) store r1-r2 (SP and TOC) +	# 2) store SP and TOC  	std   1,  2*8(3) -	std   2,  3*8(3) +	std   5,  3*8(3)  	# 3) store r14-31  	std  14,  4*8(3)  	std  15,  5*8(3) diff --git a/src/signal/powerpc64/sigsetjmp.s b/src/signal/powerpc64/sigsetjmp.s index 52ac1d03..410c2831 100644 --- a/src/signal/powerpc64/sigsetjmp.s +++ b/src/signal/powerpc64/sigsetjmp.s @@ -2,29 +2,36 @@  	.global __sigsetjmp  	.type sigsetjmp,%function  	.type __sigsetjmp,%function -	.hidden ___setjmp +	.hidden __setjmp_toc  sigsetjmp:  __sigsetjmp:  	addis 2, 12, .TOC.-__sigsetjmp@ha  	addi  2,  2, .TOC.-__sigsetjmp@l +	ld    5, 24(1)   # load from the TOC slot in the caller's stack frame +	b     1f +  	.localentry sigsetjmp,.-sigsetjmp  	.localentry __sigsetjmp,.-__sigsetjmp +	mr    5,  2 +1:  	cmpwi cr7, 4, 0 -	beq-  cr7, ___setjmp +	beq-  cr7, __setjmp_toc -	mflr  5 -	std   5, 512(3) -	std  16, 512+8+8(3) +	mflr  6 +	std   6, 512(3) +	std   2, 512+16(3) +	std  16, 512+24(3)  	mr   16, 3 -	bl ___setjmp +	bl __setjmp_toc  	mr   4,  3  	mr   3, 16  	ld   5, 512(3)  	mtlr 5 -	ld  16, 512+8+8(3) +	ld   2, 512+16(3) +	ld  16, 512+24(3)  .hidden __sigsetjmp_tail  	b __sigsetjmp_tail | 
