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.
128 lines
4.0 KiB
128 lines
4.0 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:
|
|
//
|
|
//--
|
|
|
|
#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.
|
|
//
|
|
//--
|
|
|
|
.struct 0
|
|
.space 4 * 4 // argument save area
|
|
LjEr: .space ExceptionRecordLength // exception record
|
|
.space 4 * 3 // fill
|
|
LjRa: .space 4 // saved return address
|
|
LongjmpFrameLength:
|
|
|
|
NESTED_ENTRY(longjmp, LongjmpFrameLength, zero)
|
|
|
|
subu sp,sp,LongjmpFrameLength // allocate stack frame
|
|
sw ra,LjRa(sp) // save return address
|
|
|
|
PROLOGUE_END
|
|
|
|
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.
|
|
//
|
|
|
|
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.
|
|
//
|
|
// An exception record is constructed that contains a log jump status
|
|
// code and the first exception information parameter is a pointer to
|
|
// the jump buffer.
|
|
//
|
|
|
|
20: li v0,STATUS_LONGJUMP // get long jump status code
|
|
sw v0,LjEr + ErExceptionCode(sp) // set exception code
|
|
sw zero,LjEr + ErExceptionFlags(sp) // clear exception flags
|
|
sw zero,LjEr + ErExceptionRecord(sp) // clear associate record
|
|
sw zero,LjEr + ErExceptionAddress(sp) // clear exception address
|
|
li v0,1 // set number of parameters
|
|
sw v0,LjEr + ErNumberParameters(sp) //
|
|
sw a0,LjEr + ErExceptionInformation(sp) // set jump buffer address
|
|
move a3,a1 // set return value
|
|
addu a2,sp,LjEr // compute exception record address
|
|
lw a1,JbFir(a0) // set target instruction address
|
|
lw a0,JbType(a0) // set target virtual frame address
|
|
jal RtlUnwind // finish in common code
|
|
b 20b
|
|
|
|
.end longjmp
|