--- newlib-1.15.0/newlib/libc/machine/powerpc/setjmp.S.orig 2002-04-19 14:16:17.000000000 -0500 +++ newlib-1.15.0/newlib/libc/machine/powerpc/setjmp.S 2007-08-27 11:26:21.000000000 -0500 @@ -5,13 +5,14 @@ #include "ppc-asm.h" FUNC_START(setjmp) -#ifdef __ALTIVEC__ - addi 3,3,15 # align Altivec to 16 byte boundary + mfmsr 4 + rlwinm. 4,4,0,6,6 # check MSR_VE + addi 3,3,7 + rlwinm 3,3,0,0,28 # align to 8 byte boundary + beq 1f + addi 3,3,15 # VE is enabled; align to 16 byte bdry rlwinm 3,3,0,0,27 -#else - addi 3,3,7 # align to 8 byte boundary - rlwinm 3,3,0,0,28 -#endif +1: stw 1,0(3) # offset 0 stwu 2,4(3) # offset 4 stwu 13,4(3) # offset 8 @@ -39,6 +40,12 @@ stwu 4,4(3) # offset 88 # one word pad to get floating point aligned on 8 byte boundary #ifndef _SOFT_FLOAT + mfmsr 4 + rlwinm. 4,4,0,18,18 + bne 1f # only save FPregs if FPU is enabled + addi 3,3,18*8 # skip FPregs + b 2f +1: stfdu 14,8(3) # offset 96 stfdu 15,8(3) # offset 104 stfdu 16,8(3) # offset 112 @@ -57,12 +64,21 @@ stfdu 29,8(3) # offset 216 stfdu 30,8(3) # offset 224 stfdu 31,8(3) # offset 232 +2: #endif /* This requires a total of 21 * 4 + 18 * 8 + 4 + 4 + 4 bytes == 60 * 4 bytes == 240 bytes. */ -#ifdef __ALTIVEC__ +#if defined(__ALTIVEC__) + /* could reuse r4 but I reload it just in case the code changes... */ + mfmsr 4 + rlwinm. 4,4,0,6,6 # check MSR_VE + bne 1f # only save vector regs if altivec is enabled + addi 3,3,(8 + 12*16) # skip vector regs + b 2f +1: +#endif /* save Altivec vrsave and vr20-vr31 registers */ mfspr 4,256 # vrsave register stwu 4,16(3) # offset 248 @@ -90,6 +106,7 @@ stvx 30,0,3 # offset 416 addi 3,3,16 stvx 31,0,3 # offset 432 +2: /* This requires a total of 240 + 8 + 8 + 12 * 16 == 448 bytes. */ #endif @@ -99,13 +116,14 @@ FUNC_START(longjmp) -#ifdef __ALTIVEC__ - addi 3,3,15 # align Altivec to 16 byte boundary + mfmsr 4 + rlwinm. 4,4,0,6,6 # check MSR_VE + addi 3,3,7 + rlwinm 3,3,0,0,28 # align to 8 byte boundary + beq 1f + addi 3,3,15 # VE is enabled; align to 16 byte bdry rlwinm 3,3,0,0,27 -#else - addi 3,3,7 # align to 8 byte boundary - rlwinm 3,3,0,0,28 -#endif +1: lwz 1,0(3) # offset 0 lwzu 2,4(3) # offset 4 lwzu 13,4(3) # offset 8 @@ -129,10 +147,17 @@ lwzu 31,4(3) # offset 80 lwzu 5,4(3) # offset 84 mtlr 5 +#if !defined(_SOFT_FLOAT) + mfmsr 5 + rlwinm. 5,5,0,18,18 # is MSR_FP set? +#endif lwzu 5,4(3) # offset 88 - mtcrf 255,5 # one word pad to get floating point aligned on 8 byte boundary #ifndef _SOFT_FLOAT + bne 1f + addi 3,3,18*8 # skip FPregs + b 2f +1: lfdu 14,8(3) # offset 96 lfdu 15,8(3) # offset 104 lfdu 16,8(3) # offset 112 @@ -151,9 +176,17 @@ lfdu 29,8(3) # offset 216 lfdu 30,8(3) # offset 224 lfdu 31,8(3) # offset 232 +2: #endif + mtcrf 255,5 -#ifdef __ALTIVEC__ +#if defined(__ALTIVEC__) + mfmsr 5 + rlwinm. 5,5,0,6,6 # is MSR_FP set? + bne 1f + addi 3,3,(8+12*16) # skip vector regs + b 2f +1: /* restore Altivec vrsave and v20-v31 registers */ lwzu 5,16(3) # offset 248 mtspr 256,5 # vrsave @@ -181,6 +214,7 @@ lvx 30,0,3 # offset 416 addi 3,3,16 lvx 31,0,3 # offset 432 +2: #endif mr. 3,4