NT4/private/crt32/misc/mips/setjmpex.s
2020-09-30 17:12:29 +02:00

157 lines
5.4 KiB
ArmAsm
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// TITLE("Set Jump Extended")
//++
//
// Copyright (c) 1993 Microsoft Corporation
//
// Module Name:
//
// setjmpex.s
//
// Abstract:
//
// This module implements the MIPS specific routine to provide SAFE
// handling of setjmp/longjmp with respect to structured exception
// handling.
//
// Author:
//
// David N. Cutler (davec) 2-Apr-1993
//
// Environment:
//
// Any mode.
//
// Revision History:
//
//--
#include "ksmips.h"
//
// Define variable that will cause setjmp/longjmp to be safe with respect
// to structured exception handling.
//
.globl _setjmpexused
.data
_setjmpexused:
.word _setjmpex // set address of safe setjmp routine
SBTTL("Set Jump Extended")
//++
//
// int
// _setjmpex (
// IN jmp_buf JumpBuffer
// )
//
// Routine Description:
//
// This function transfers control to the actual setjmp routine.
//
// Arguments:
//
// JumpBuffer (a0) - Supplies the address of a jump buffer to store the
// jump information.
//
// Return Value:
//
// A value of zero is returned.
//
//--
.struct 0
.space 4 * 4 // argument save area
SjS0: .space 4 // saved integer register s0
SjFl: .space 4 // in function flag variable
.space 4 // fill
SjRa: .space 4 // saved return address
SetjmpFrameLength:
NESTED_ENTRY(_setjmpex, SetjmpFrameLength, zero)
subu sp,sp,SetjmpFrameLength // allocate stack frame
sw s0,SjS0(sp) // save integer register s0
sw ra,SjRa(sp) // save return address
move s0,sp // set frame pointer
PROLOGUE_END
subu sp,sp,ContextFrameLength + 16 // allocate a context frame
//
// Save the nonvolatile machine state in both the jump buffer and a context
// record that will be used to compute the virtual frame pointer.
//
sdc1 f20,JbFltF20(a0) // save floating registers f20 - f31
sdc1 f22,JbFltF22(a0) //
sdc1 f24,JbFltF24(a0) //
sdc1 f26,JbFltF26(a0) //
sdc1 f28,JbFltF28(a0) //
sdc1 f30,JbFltF30(a0) //
lw v0,SjS0(s0) // get saved integer register s0
sw v0,JbIntS0(a0) // save integer registers s0 - s8
sw s1,JbIntS1(a0) //
sw s2,JbIntS2(a0) //
sw s3,JbIntS3(a0) //
sw s4,JbIntS4(a0) //
sw s5,JbIntS5(a0) //
sw s6,JbIntS6(a0) //
sw s7,JbIntS7(a0) //
sw s8,JbIntS8(a0) //
sw ra,JbFir(a0) // get setjmp return address
addu v0,s0,SetjmpFrameLength // compute stack pointer address
sw v0,JbIntSp(a0) // save stack pointer
sdc1 f20,CxFltF20 + 16(sp) // save floating registers f20 - f31
sdc1 f22,CxFltF22 + 16(sp) //
sdc1 f24,CxFltF24 + 16(sp) //
sdc1 f26,CxFltF26 + 16(sp) //
sdc1 f28,CxFltF28 + 16(sp) //
sdc1 f30,CxFltF30 + 16(sp) //
lw v0,SjS0(s0) // get saved integer register s0
sw v0,CxIntS0 + 16(sp) // save integer registers s0 - s8
sw s1,CxIntS1 + 16(sp) //
sw s2,CxIntS2 + 16(sp) //
sw s3,CxIntS3 + 16(sp) //
sw s4,CxIntS4 + 16(sp) //
sw s5,CxIntS5 + 16(sp) //
sw s6,CxIntS6 + 16(sp) //
sw s7,CxIntS7 + 16(sp) //
sw s8,CxIntS8 + 16(sp) // save integer register s8
sw gp,CxIntGp + 16(sp) // save integer register gp
addu v0,s0,SetjmpFrameLength // compute stack pointer address
sw v0,CxIntSp + 16(sp) // save stack pointer
sw ra,CxIntRa + 16(sp) // save return address
sw ra,CxFir + 16(sp) // save return address
//
// Perform unwind to determine the virtual frame pointer of the caller.
//
addu a0,a0,JbType // set virtual frame address argument
sw a0,4 * 4(sp) //
subu a0,ra,4 // compute control PC address
jal RtlLookupFunctionEntry // lookup function table address
lw a0,SjRa(s0) // get return address
subu a0,a0,4 // compute control PC address
move a1,v0 // set address of function entry
addu a2,sp,16 // compute address of context record
addu a3,s0,SjFl // set address of in function variable
sw zero,4 * 5(sp) // set context pointer array address
jal RtlVirtualUnwind // compute virtual frame pointer value
//
// Set return value, restore registers, deallocate stack frame, and return.
//
move v0,zero // set return value
move sp,s0 // reset stack pointer
lw s0,SjS0(sp) // restore integer register s0
lw ra,SjRa(sp) // restore return address
addu sp,sp,SetjmpFrameLength // deallocate stack frame
j ra // return
.end _setjmpex