diff options
-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 |