diff options
Diffstat (limited to 'private/crt32/misc/ppc/setjmp.s')
-rw-r--r-- | private/crt32/misc/ppc/setjmp.s | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/private/crt32/misc/ppc/setjmp.s b/private/crt32/misc/ppc/setjmp.s new file mode 100644 index 000000000..65b58adf5 --- /dev/null +++ b/private/crt32/misc/ppc/setjmp.s @@ -0,0 +1,138 @@ +//++ +// +// Copyright (c) 1993 IBM Corporation and Microsoft Corporation +// +// Module Name: +// +// setjmp.s +// +// Abstract: +// +// This module implements the MIPS specific routine to perform a setjmp. +// +// N.B. This module conditionally provides UNSAFE handling of setjmp and +// which is NOT integrated with structured exception handling. The +// determination is made based on whether an uninitialized variable +// has been set to a nonzero value. +// +// Author: +// +// Rick Simpson 13-Oct-1993 +// +// based on MIPS version by David N. Cutler (davec) 7-Apr-1993 +// +// Environment: +// +// Any mode. +// +// Revision History: +// +//-- + +//list(off) +#include "ksppc.h" +//list(on) + +// +// Define variable that will cause setjmp/longjmp to be safe or unsafe with +// respect to structured exception handling. +// + + .globl _setjmpexused + .comm _setjmpexused , 4 + +//++ +// +// int +// setjmp ( +// IN jmp_buf JumpBuffer +// ) +// +// Routine Description: +// +// This function saved the current nonvolatile register state in the +// specified jump buffer and returns a function vlaue of zero. +// +// Arguments: +// +// JumpBuffer (r.3) - Supplies the address of a jump buffer to store the +// jump information. +// +// Return Value: +// +// A value of zero is returned. +// +//-- + + LEAF_ENTRY (setjmp) + +// +// If _setjmpexused is non-NULL, it contains the entry point address +// of the safe version of setjmp, ..setjmpex. We branch thru the CTR +// using this variable rather than branching directly to the entry point +// to avoid assembling a hard reference to ..setjmpex into this code. +// CTR is used to avoid killing caller's LR. +// + + lwz r.4, [toc] _setjmpexused (r.toc) // get address of switch variable + lwz r.0, 0 (r.4) // get value of switch variable + cmpwi r.0, 0 // see if switch is NULL + mtctr r.0 // if switch is non-NULL, + bnectr // branch to safe setjmp() routine + +// +// Provide unsafe handling of setjmp. +// + + mflr r.0 // fetch incoming LR + mfcr r.4 // fetch incoming CR + + stfd f.14, JbFpr14 (r.3) // save n-v floating point regs + stfd f.15, JbFpr15 (r.3) + stfd f.16, JbFpr16 (r.3) + stfd f.17, JbFpr17 (r.3) + stfd f.18, JbFpr18 (r.3) + stfd f.19, JbFpr19 (r.3) + stfd f.20, JbFpr20 (r.3) + stfd f.21, JbFpr21 (r.3) + stfd f.22, JbFpr22 (r.3) + stfd f.23, JbFpr23 (r.3) + stfd f.24, JbFpr24 (r.3) + stfd f.25, JbFpr25 (r.3) + stfd f.26, JbFpr26 (r.3) + stfd f.27, JbFpr27 (r.3) + stfd f.28, JbFpr28 (r.3) + stfd f.29, JbFpr29 (r.3) + stfd f.30, JbFpr30 (r.3) + stfd f.31, JbFpr31 (r.3) + + stw r.13, JbGpr13 (r.3) // save n-v general regs + stw r.14, JbGpr14 (r.3) + stw r.15, JbGpr15 (r.3) + stw r.16, JbGpr16 (r.3) + stw r.17, JbGpr17 (r.3) + stw r.18, JbGpr18 (r.3) + stw r.19, JbGpr19 (r.3) + stw r.20, JbGpr20 (r.3) + stw r.21, JbGpr21 (r.3) + stw r.22, JbGpr22 (r.3) + stw r.23, JbGpr23 (r.3) + stw r.24, JbGpr24 (r.3) + stw r.25, JbGpr25 (r.3) + stw r.26, JbGpr26 (r.3) + stw r.27, JbGpr27 (r.3) + stw r.28, JbGpr28 (r.3) + stw r.29, JbGpr29 (r.3) + stw r.30, JbGpr30 (r.3) + stw r.31, JbGpr31 (r.3) + + stw r.0, JbIar (r.3) // setjmp return address + stw r.4, JbCr (r.3) // save CR (n-v part) + stw r.sp, JbGpr1 (r.3) // save stack pointer + stw r.toc, JbGpr2 (r.3) // save TOC pointer + li r.0, 0 + stw r.0, JbType (r.3) // clean safe setjmp flag + + li r.3, 0 // set return value + LEAF_EXIT (setjmp) // return + |