mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
3.9 KiB
139 lines
3.9 KiB
// TITLE("Long Jump")
|
|
//++
|
|
//
|
|
// Copyright (c) 1993 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// longjmp.s
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements the MIPS specific routine to perform a long
|
|
// jump operation.
|
|
//
|
|
// N.B. This routine conditionally provides UNSAFE handling of longjmp
|
|
// which is NOT integrated with structured exception handling. The
|
|
// determination is made based on whether an unitialized variable
|
|
// has been set to a nonzero value.
|
|
//
|
|
// Author:
|
|
//
|
|
// David N. Cutler (davec) 2-Apr-1993
|
|
//
|
|
// Environment:
|
|
//
|
|
// Any mode.
|
|
//
|
|
// Revision History:
|
|
//
|
|
// 04-15-95 TGL Added NLG support
|
|
//
|
|
//
|
|
//--
|
|
|
|
#include "ksmips.h"
|
|
|
|
SBTTL("Long Jump")
|
|
//++
|
|
//
|
|
// int
|
|
// longjmp (
|
|
// IN jmp_buf JumpBuffer,
|
|
// IN int ReturnValue
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function performs a long jump to the context specified by the
|
|
// jump buffer.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// JumpBuffer (a0) - Supplies the address of a jump buffer that contains
|
|
// jump information.
|
|
//
|
|
// ReturnValue (a1) - Supplies the value that is to be returned to the
|
|
// caller of set jump.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
|
|
//
|
|
// externs for Non Local Goto support
|
|
//
|
|
.extern _NLG_Notify
|
|
.extern __SetNLGCode
|
|
|
|
LEAF_ENTRY(longjmp)
|
|
|
|
bne zero,a1,10f // if ne, return value specified
|
|
li a1,1 // set return value to nonzero value
|
|
10: lw v0,JbType(a0) // get safe setjmp/longjmp flag
|
|
bne zero,v0,20f // if ne, provide safe longjmp
|
|
|
|
//
|
|
// Provide unsafe handling of longjmp.
|
|
//
|
|
//
|
|
// Do this NLG thing first, save/use/restore a0,ra
|
|
//
|
|
move t0,ra // save ra
|
|
move t1,a0 // save a0
|
|
move t2,a1 // save a1
|
|
lw a1,JbIntSp(t1) // pass target sp to _NLG_Notify
|
|
lw a0,JbFir(t1) // pass target address to _NLG_Notify
|
|
move a2, $0 // tell debugger NLG comes from longjump
|
|
jal _NLG_Notify // notify debugger, it doesn't modify any registers
|
|
move a1,t2 // restore a1
|
|
move a0,t1 // restore a0
|
|
move ra,t0 // restore ra
|
|
|
|
move v0,a1 // set return value
|
|
ldc1 f20,JbFltF20(a0) // restore floating registers f20 - f31
|
|
ldc1 f22,JbFltF22(a0) //
|
|
ldc1 f24,JbFltF24(a0) //
|
|
ldc1 f26,JbFltF26(a0) //
|
|
ldc1 f28,JbFltF28(a0) //
|
|
ldc1 f30,JbFltF30(a0) //
|
|
lw s0,JbIntS0(a0) // restore integer registers s0 - s8
|
|
lw s1,JbIntS1(a0) //
|
|
lw s2,JbIntS2(a0) //
|
|
lw s3,JbIntS3(a0) //
|
|
lw s4,JbIntS4(a0) //
|
|
lw s5,JbIntS5(a0) //
|
|
lw s6,JbIntS6(a0) //
|
|
lw s7,JbIntS7(a0) //
|
|
lw s8,JbIntS8(a0) //
|
|
lw a1,JbFir(a0) // get setjmp return address
|
|
lw sp,JbIntSp(a0) // restore stack pointer
|
|
j a1 // jump back to setjmp site
|
|
|
|
//
|
|
// Provide safe handling of longjmp.
|
|
//
|
|
//
|
|
// Do this NLG thing first, save/use/restore a0,ra
|
|
//
|
|
20:
|
|
move t0,ra // save ra
|
|
move t1,a0 // save a0
|
|
move t2,a1 // save a1
|
|
lw a1,0(t1) // pass target sp to _NLG_Notify
|
|
lw a0,4(t1) // pass target address to _NLG_Notify
|
|
li a2, 0x3 // Exception safe longjmp
|
|
jal _NLG_Notify // notify debugger, it doesn't modify any registers
|
|
move a1,t2 // restore a1
|
|
move a0,t1 // restore a0
|
|
move ra,t0 // restore ra
|
|
|
|
move a3,a1 // set return value
|
|
move a2,zero // set exception record addres
|
|
lw a1,4(a0) // set target instruction address
|
|
lw a0,0(a0) // set target frame value
|
|
j RtlUnwind // finish in common code
|
|
|
|
.end longjmp
|