2020-09-30 17:12:29 +02:00

265 lines
6.6 KiB
ArmAsm
Raw 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("Win32 Thunks")
//++
//
// Copyright (c) 1990 Microsoft Corporation
//
// Module Name:
//
// thunk.s
//
// Abstract:
//
// This module implements Win32 functions that must be written in assembler.
//
// Author:
//
// Mark Lucovsky (markl) 5-Oct-1990
//
// Revision History:
//
// Thomas Van Baak (tvb) 21-Jul-1992
//
// Adapted for Alpha AXP.
//
//--
#include "ksalpha.h"
//
// Division by 10000 is accomplished using reciprocal multiplication.
// Define the magic muliplier and right shift values for this.
//
#define MAGIC_10000_MULTIPLY 0xd1b71758e219652c
#define MAGIC_10000_SHIFT 13
SBTTL("Switch Stack Then Terminate")
//++
//
// VOID
// BaseSwitchStackThenTerminate (
// IN PVOID StackLimit,
// IN PVOID NewStack,
// IN DWORD ExitCode
// )
//
// Routine Description:
//
// This API is called during thread termination to delete a thread's
// stack, switch to a stack in the thread's TEB, and then terminate.
//
// Arguments:
//
// StackLimit (a0) - Supplies the address of the stack to be freed.
//
// NewStack (a1) - Supplies an address within the terminating thread's TE
// that is to be used as its temporary stack while exiting.
//
// ExitCode (a2) - Supplies the termination status that the thread
// is to exit with.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(BaseSwitchStackThenTerminate)
//
// Switch stacks and then jump to BaseFreeStackAndTerminate.
//
mov a1, sp // set new stack pointer
mov a2, a1 // set exit code argument
br zero, BaseFreeStackAndTerminate // jump
.end BaseSwitchStackThenTerminate
SBTTL("Base Attach Complete")
//++
//
// The following code is never executed. Its purpose is to support unwinding
// through the call to the exception dispatcher.
//
//--
NESTED_ENTRY(BaseAttachCompThunk, ContextFrameLength, zero);
.set noreorder
.set noat
lda sp, -ContextFrameLength(sp) // allocate stack frame
stq sp, CxIntSp(sp) // save stack pointer
stq ra, CxIntRa(sp) // save return address
stq ra, CxFir(sp) // mark continuation address location
stq fp, CxIntFp(sp) // save integer register fp/s6
stq gp, CxIntGp(sp) // save integer register gp
stq s0, CxIntS0(sp) // save integer registers s0 - s5
stq s1, CxIntS1(sp) //
stq s2, CxIntS2(sp) //
stq s3, CxIntS3(sp) //
stq s4, CxIntS4(sp) //
stq s5, CxIntS5(sp) //
stt f2, CxFltF2(sp) // store floating registers f2 - f9
stt f3, CxFltF3(sp) //
stt f4, CxFltF4(sp) //
stt f5, CxFltF5(sp) //
stt f6, CxFltF6(sp) //
stt f7, CxFltF7(sp) //
stt f8, CxFltF8(sp) //
stt f9, CxFltF9(sp) //
.set at
.set reorder
PROLOGUE_END
//++
//
// VOID
// BaseAttachCompleteThunk (
// VOID
// )
//
// Routine Description:
//
// This function is called after a successful debug attach. Its
// purpose is to call portable code that does a breakpoint, followed
// by an NtContinue.
//
// Arguments:
//
// None.
//
// Return Value:
//
// None.
//
//--
ALTERNATE_ENTRY(BaseAttachCompleteThunk)
mov s0, a0 // set context frame address argument
br zero, BaseAttachComplete // jump
.end BaseAttachCompThunk
//++
//
// VOID
// WINAPI
// SwitchToFiber (
// LPVOID lpFiber
// )
//
// Routine Description:
//
// This function saves the state of the current fiber and switches
// to the new fiber.
//
// Arguments:
//
// CurrentFiber - Supplies the address of the current fiber.
//
// NewFiber - Supplies the address of the new fiber.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(SwitchToFiber)
GET_THREAD_ENVIRONMENT_BLOCK // get TEB in v0
//
// Get current fiber
//
ldl a1, TeFiberData(v0)
//
// Set new deallocation stack and fiberdata in TEB
//
ldl t0, FbDeallocationStack(a0)
stl t0, TeDeallocationStack(v0)
stl a0, TeFiberData(v0)
//
// Save stack limit.
//
ldl t1, TeStackLimit(v0)
stl t1, FbStackLimit(a1) // save StackLimit
//
// Save nonvolatile integer state
//
stq s0, CxIntS0+FbFiberContext(a1)
stq s1, CxIntS1+FbFiberContext(a1)
stq s2, CxIntS2+FbFiberContext(a1)
stq s3, CxIntS3+FbFiberContext(a1)
stq s4, CxIntS4+FbFiberContext(a1)
stq s5, CxIntS5+FbFiberContext(a1)
stq fp, CxIntFp+FbFiberContext(a1)
//
// Save nonvolatile float state
//
stt f2, CxFltF2+FbFiberContext(a1)
stt f3, CxFltF3+FbFiberContext(a1)
stt f4, CxFltF4+FbFiberContext(a1)
stt f5, CxFltF5+FbFiberContext(a1)
stt f6, CxFltF6+FbFiberContext(a1)
stt f7, CxFltF7+FbFiberContext(a1)
stt f8, CxFltF8+FbFiberContext(a1)
stt f9, CxFltF9+FbFiberContext(a1)
//
// Save RA and SP
//
stq ra, CxFir+FbFiberContext(a1)
stq sp, CxIntSp+FbFiberContext(a1)
//
// Restore new fiber's stack base and stack limit
//
ldl t0, FbStackBase(a0) // restore StackBase
stl t0, TeStackBase(v0)
ldl t1, FbStackLimit(a0) // restore StackLimit
stl t1, TeStackLimit(v0)
//
// Restore nonvolatile integer state
//
ldq s0, CxIntS0+FbFiberContext(a0)
ldq s1, CxIntS1+FbFiberContext(a0)
ldq s2, CxIntS2+FbFiberContext(a0)
ldq s3, CxIntS3+FbFiberContext(a0)
ldq s4, CxIntS4+FbFiberContext(a0)
ldq s5, CxIntS5+FbFiberContext(a0)
ldq fp, CxIntFp+FbFiberContext(a0)
//
// Restore nonvolatile float state
//
ldt f2, CxFltF2+FbFiberContext(a0)
ldt f3, CxFltF3+FbFiberContext(a0)
ldt f4, CxFltF4+FbFiberContext(a0)
ldt f5, CxFltF5+FbFiberContext(a0)
ldt f6, CxFltF6+FbFiberContext(a0)
ldt f7, CxFltF7+FbFiberContext(a0)
ldt f8, CxFltF8+FbFiberContext(a0)
ldt f9, CxFltF9+FbFiberContext(a0)
//
// Restore RA and SP
//
ldq ra, CxFir+FbFiberContext(a0)
ldq sp, CxIntSp+FbFiberContext(a0)
ret zero, (ra)
.end BasepSwitchToFiber