[patch] newlib: Tweak setjmp for E500
Jeff Johnston
jjohnstn@redhat.com
Wed Jan 17 15:19:00 GMT 2007
Ok. Patch checked in.
-- Jeff J.
Kazu Hirata wrote:
> Hi,
>
> Attached is a patch to tweak setjmp for E500.
>
> On E500V1 and E500V2, GPRs (general purpose registers) are 64-bit
> wide, so we need to modify setjmp and longjmp to save and restore
> 64-bit registers. I've put various comments in the code, so I hope
> the rest is fairly obvious.
>
> Tested by running setjmp and lonjmp on a simulator. OK to apply?
>
> Kazu Hirata
>
> 2007-01-12 Joseph Myers <joseph@codesourcery.com>
> Kazu Hirata <kazu@codesourcery.com>
>
> newlib/
> * libc/machine/powerpc/setjmp.S (setjmp, longjmp): Add support
> for E500V1 and E500V2.
>
> Index: newlib/libc/machine/powerpc/setjmp.S
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/machine/powerpc/setjmp.S,v
> retrieving revision 1.2
> diff -u -d -p -r1.2 setjmp.S
> --- newlib/libc/machine/powerpc/setjmp.S 19 Apr 2002 19:16:17 -0000 1.2
> +++ newlib/libc/machine/powerpc/setjmp.S 12 Jan 2007 23:24:19 -0000
> @@ -12,6 +12,35 @@ FUNC_START(setjmp)
> addi 3,3,7 # align to 8 byte boundary
> rlwinm 3,3,0,0,28
> #endif
> +#if __SPE__
> + /* If we are E500, then save 64-bit registers. */
> + evstdd 1,0(3) # offset 0
> + evstdd 2,8(3) # offset 8
> + evstdd 13,16(3) # offset 16
> + evstdd 14,24(3) # offset 24
> + evstdd 15,32(3) # offset 32
> + evstdd 16,40(3) # offset 40
> + evstdd 17,48(3) # offset 48
> + evstdd 18,56(3) # offset 56
> + evstdd 19,64(3) # offset 64
> + evstdd 20,72(3) # offset 72
> + evstdd 21,80(3) # offset 80
> + evstdd 22,88(3) # offset 88
> + evstdd 23,96(3) # offset 96
> + evstdd 24,104(3) # offset 104
> + evstdd 25,112(3) # offset 112
> + evstdd 26,120(3) # offset 120
> + evstdd 27,128(3) # offset 128
> + evstdd 28,136(3) # offset 136
> + evstdd 29,144(3) # offset 144
> + evstdd 30,152(3) # offset 152
> + evstdd 31,160(3) # offset 160
> +
> + /* Add 164 to r3 to account for the amount of data we just
> + stored. Note that we are not adding 168 because the next
> + store instruction uses an offset of 4. */
> + addi 3,3,164
> +#else
> stw 1,0(3) # offset 0
> stwu 2,4(3) # offset 4
> stwu 13,4(3) # offset 8
> @@ -33,12 +62,22 @@ FUNC_START(setjmp)
> stwu 29,4(3) # offset 72
> stwu 30,4(3) # offset 76
> stwu 31,4(3) # offset 80
> +#endif
> +
> + /* From this point on until the end of this function, add 84
> + to the offset shown if __SPE__. This difference comes from
> + the fact that we save 21 64-bit registers instead of 21
> + 32-bit registers above. */
> mflr 4
> stwu 4,4(3) # offset 84
> mfcr 4
> stwu 4,4(3) # offset 88
> # one word pad to get floating point aligned on 8 byte boundary
> -#ifndef _SOFT_FLOAT
> +
> + /* Check whether we need to save FPRs. Checking __NO_FPRS__
> + on its own would be enough for GCC 4.1 and above, but older
> + compilers only define _SOFT_FLOAT, so check both. */
> +#if !defined (__NO_FPRS__) && !defined (_SOFT_FLOAT)
> stfdu 14,8(3) # offset 96
> stfdu 15,8(3) # offset 104
> stfdu 16,8(3) # offset 112
> @@ -106,6 +145,35 @@ FUNC_START(longjmp)
> addi 3,3,7 # align to 8 byte boundary
> rlwinm 3,3,0,0,28
> #endif
> +#if __SPE__
> + /* If we are E500, then restore 64-bit registers. */
> + evldd 1,0(3) # offset 0
> + evldd 2,8(3) # offset 8
> + evldd 13,16(3) # offset 16
> + evldd 14,24(3) # offset 24
> + evldd 15,32(3) # offset 32
> + evldd 16,40(3) # offset 40
> + evldd 17,48(3) # offset 48
> + evldd 18,56(3) # offset 56
> + evldd 19,64(3) # offset 64
> + evldd 20,72(3) # offset 72
> + evldd 21,80(3) # offset 80
> + evldd 22,88(3) # offset 88
> + evldd 23,96(3) # offset 96
> + evldd 24,104(3) # offset 104
> + evldd 25,112(3) # offset 112
> + evldd 26,120(3) # offset 120
> + evldd 27,128(3) # offset 128
> + evldd 28,136(3) # offset 136
> + evldd 29,144(3) # offset 144
> + evldd 30,152(3) # offset 152
> + evldd 31,160(3) # offset 160
> +
> + /* Add 164 to r3 to account for the amount of data we just
> + loaded. Note that we are not adding 168 because the next
> + load instruction uses an offset of 4. */
> + addi 3,3,164
> +#else
> lwz 1,0(3) # offset 0
> lwzu 2,4(3) # offset 4
> lwzu 13,4(3) # offset 8
> @@ -127,12 +195,22 @@ FUNC_START(longjmp)
> lwzu 29,4(3) # offset 72
> lwzu 30,4(3) # offset 76
> lwzu 31,4(3) # offset 80
> +#endif
> + /* From this point on until the end of this function, add 84
> + to the offset shown if __SPE__. This difference comes from
> + the fact that we restore 21 64-bit registers instead of 21
> + 32-bit registers above. */
> lwzu 5,4(3) # offset 84
> mtlr 5
> lwzu 5,4(3) # offset 88
> mtcrf 255,5
> # one word pad to get floating point aligned on 8 byte boundary
> -#ifndef _SOFT_FLOAT
> +
> + /* Check whether we need to restore FPRs. Checking
> + __NO_FPRS__ on its own would be enough for GCC 4.1 and
> + above, but older compilers only define _SOFT_FLOAT, so
> + check both. */
> +#if !defined (__NO_FPRS__) && !defined (_SOFT_FLOAT)
> lfdu 14,8(3) # offset 96
> lfdu 15,8(3) # offset 104
> lfdu 16,8(3) # offset 112
More information about the Newlib
mailing list