157 lines
5.4 KiB
ArmAsm
157 lines
5.4 KiB
ArmAsm
|
// 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
|