1625 lines
50 KiB
NASM
1625 lines
50 KiB
NASM
;
|
|
; Copyright (c) Microsoft Corporation. All rights reserved.
|
|
;
|
|
|
|
.code
|
|
|
|
ifdef SINGULARITY
|
|
SINGLE_THREADED equ 0
|
|
else ;; SINGULARITY
|
|
EXCLUDED equ 0
|
|
SINGLE_THREADED equ 0
|
|
endif ;; SINGULARITY
|
|
|
|
include hal.inc
|
|
|
|
externdef __throwDispatcher:NEAR
|
|
externdef __throwDispatcherExplicitAddrAfter:NEAR
|
|
; was externdef ?ExceptionTableLookup@@YI_KPEAUClass_System_Exception@@I@Z:NEAR
|
|
; don't understand the I -> _K change yet
|
|
;;externdef ?ExceptionTableLookup@@YA?AUPtrPair@@PEAUClass_System_Exception@@_K@Z:NEAR
|
|
externdef ?ExceptionTableLookup@@YA?AUPtrPair@@PEAUClass_System_Exception@@_K@Z:NEAR
|
|
ifndef SINGULARITY
|
|
externdef ?ResetGuardPage@@YAXXZ:NEAR
|
|
endif ;; !SINGULARITY
|
|
|
|
ifdef SINGULARITY_KERNEL
|
|
externdef ?g_setStopContext@Class_System_Threading_Thread@@SAXPEAU1@PEAUClass_System_Exception@@@Z:NEAR
|
|
externdef __throwBeyondMarker:NEAR
|
|
endif ; SINGULARITY_KERNEL
|
|
|
|
externdef __throwDivideByZeroException:NEAR
|
|
externdef __throwNullPointerException:NEAR
|
|
externdef __throwOverflowException:NEAR
|
|
externdef __throwStackOverflowException:NEAR
|
|
|
|
ifndef SINGULARITY
|
|
externdef ?g_throwNewOverflowException@Class_System_VTable@@SAXXZ:NEAR
|
|
externdef ?c_CheckCount@Class_System_GCs_StackManager@@2HA:int32
|
|
externdef ?g_GetStackChunk@Class_System_GCs_StackManager@@SAPEAUuintPtr@@PEAU2@PEAUClass_System_Threading_Thread@@_N@Z:NEAR
|
|
externdef ?g_ReturnStackChunk@Class_System_GCs_StackManager@@SAXPEAUClass_System_Threading_Thread@@_N@Z:NEAR
|
|
;
|
|
; externals used to construct instances of machine-level exceptions
|
|
;
|
|
|
|
externdef ?g_AllocateObject@Class_System_GC@@SAPEAUClass_System_Object@@PEAUClass_System_VTable@@@Z:NEAR
|
|
externdef ?m__ctor@Class_System_ArithmeticException@@SAXPEAU1@@Z:NEAR
|
|
externdef ??_7System_ArithmeticException@@6B@:dword ; vtable
|
|
externdef ?m__ctor@Class_System_DivideByZeroException@@SAXPEAU1@@Z:NEAR
|
|
externdef ??_7System_DivideByZeroException@@6B@:dword ; vtable
|
|
externdef ?m__ctor@Class_System_NullReferenceException@@SAXPEAU1@@Z:NEAR
|
|
externdef ??_7System_NullReferenceException@@6B@:dword ; vtable
|
|
externdef ?m__ctor@Class_System_OverflowException@@SAXPEAU1@@Z:NEAR
|
|
externdef ??_7System_OverflowException@@6B@:dword ; vtable
|
|
externdef ?m__ctor@Class_System_StackOverflowException@@SAXPEAU1@@Z:NEAR
|
|
externdef ??_7System_StackOverflowException@@6B@:PTR_Class_System_VTable
|
|
|
|
externdef ?c_allocationInhibitGC@Class_System_GC@@2_NA:dword
|
|
|
|
externdef ?g_doubleToInt@Class_System_VTable@@SAHN@Z:NEAR
|
|
externdef ?g_doubleToLong@Class_System_VTable@@SA_JN@Z:NEAR
|
|
externdef ?g_floatToInt@Class_System_VTable@@SAHM@Z:NEAR
|
|
externdef ?g_floatToLong@Class_System_VTable@@SA_JM@Z:NEAR
|
|
externdef ?g_checkedDoubleToInt@Class_System_VTable@@SAHN@Z:NEAR
|
|
externdef ?g_checkedDoubleToLong@Class_System_VTable@@SA_JN@Z:NEAR
|
|
externdef ?g_checkedFloatToInt@Class_System_VTable@@SAHM@Z:NEAR
|
|
externdef ?g_checkedFloatToLong@Class_System_VTable@@SA_JM@Z:NEAR
|
|
|
|
externdef ?g_Abs@Class_System_Math@@SAMM@Z:NEAR
|
|
externdef ?g_Abs@Class_System_Math@@SANN@Z:NEAR
|
|
externdef ?g_Atan@Class_System_Math@@SANN@Z:NEAR
|
|
externdef ?g_Ceiling@Class_System_Math@@SANN@Z:NEAR
|
|
externdef ?g_Cos@Class_System_Math@@SANN@Z:NEAR
|
|
externdef ?g_Floor@Class_System_Math@@SANN@Z:NEAR
|
|
externdef ?g_Log@Class_System_Math@@SANN@Z:NEAR
|
|
externdef ?g_Round@Class_System_Math@@SANN@Z:NEAR
|
|
externdef ?g_Sin@Class_System_Math@@SANN@Z:NEAR
|
|
externdef ?g_Tan@Class_System_Math@@SANN@Z:NEAR
|
|
externdef ?g_atan2@Class_System_Math@@SANNN@Z:NEAR
|
|
externdef ?g_exp@Class_System_Math@@SANN@Z:NEAR
|
|
endif ;; !SINGULARITY
|
|
|
|
if EXCLUDED
|
|
externdef __checkFPStackDepth0:NEAR
|
|
externdef __checkFPStackDepth1:NEAR
|
|
externdef __checkFPStackDepth2:NEAR
|
|
externdef __checkFPStackDepth3:NEAR
|
|
externdef __checkFPStackDepth4:NEAR
|
|
externdef __checkFPStackDepth5:NEAR
|
|
externdef __checkFPStackDepth6:NEAR
|
|
externdef __checkFPStackDepth7:NEAR
|
|
endif ;; EXCLUDED
|
|
|
|
align 8
|
|
$DBLMAXINT DQ 041dfffffffc00000r ; 2.14747e+009
|
|
$DBLMININT DQ 0c1e0000000000000r ; -2.14748e+009
|
|
$MAXLONG DQ 07fffffffffffffffh
|
|
$MINLONG DQ 08000000000000000h
|
|
|
|
;
|
|
; __throwDispatcher(ecx=exception)
|
|
;
|
|
; Description: this function is called to explicitly throw an exception.
|
|
; It assumes that the return address points to the instruction immediately
|
|
; after the one where the exception was thrown
|
|
;
|
|
; Arguments:
|
|
; ecx = exception object
|
|
; [esp] = the return address
|
|
; Effects:
|
|
; 1. Create ebp chain entry
|
|
; 2. Get return address and uses it to calculate the address of the
|
|
; instruction that threw the exception.
|
|
; 3. Looks up the appropriate handler and jumps to code to process it.
|
|
|
|
align 16
|
|
|
|
__throwDispatcher proc frame
|
|
PrologPush rbp ; create ebp chain entry
|
|
SetFramePointer rbp ; set new ebp
|
|
.endprolog
|
|
mov rdx, [rbp+8] ; get return address
|
|
push rcx ; save exception
|
|
sub rdx, 1 ; adjust to point to throw location
|
|
;; set up parameter
|
|
mov r8, rdx
|
|
mov rdx, rcx
|
|
sub rsp, 16
|
|
mov rcx, rsp
|
|
;; set up the frame for parameter
|
|
sub rsp, 32
|
|
call ?ExceptionTableLookup@@YA?AUPtrPair@@PEAUClass_System_Exception@@_K@Z
|
|
add rsp, 32
|
|
pop rax
|
|
pop rdx
|
|
pop rcx ; restore exception
|
|
pop rbp ; remove ebp chain
|
|
add rsp, 8 ; remove eip from the stack
|
|
; mov rdx is already ok
|
|
jmp __throwDispatcherHandler
|
|
__throwDispatcher endp
|
|
|
|
;
|
|
; __throwDispatcherExplicitAddr (ecx=exception, edx=throwAddress)
|
|
;
|
|
; Description:
|
|
; This is to be used when the address where the exception occurred
|
|
; is passed in as an extra argument
|
|
;
|
|
; Arguments:
|
|
; ecx = exception object
|
|
; edx = address where the exception was thrown
|
|
;
|
|
|
|
|
|
align 16
|
|
__throwDispatcherExplicitAddr proc frame
|
|
PrologPush rcx ; save exception
|
|
;; set up paramter
|
|
mov r8, rdx
|
|
mov rdx, rcx
|
|
SubRsp 16
|
|
mov rcx, rsp
|
|
SubRsp 32
|
|
.endprolog
|
|
call ?ExceptionTableLookup@@YA?AUPtrPair@@PEAUClass_System_Exception@@_K@Z
|
|
add rsp, 32
|
|
pop rax
|
|
pop rdx
|
|
pop rcx ; restore exception
|
|
; mov rdx is already ok
|
|
jmp __throwDispatcherHandler
|
|
__throwDispatcherExplicitAddr endp
|
|
|
|
;
|
|
; __throwDispatcherExplictAddrAfter (ecx=exception, edx=throwAddress)
|
|
;
|
|
; Description:
|
|
; This is to be used when the address of the instruction immediately after
|
|
; the one that actually threw the exception is passed as an argument.
|
|
;
|
|
; Arguments:
|
|
; ecx = pointer to exception object being thrown
|
|
; edx = address of the instruction following the one where
|
|
; the exception was thrown
|
|
;
|
|
; This is used, for example, in stack unwinding, where edx is the
|
|
; return address on the stack for the current procedure.
|
|
;
|
|
; Stack unwinding occurs when the current procedure does not have a handler
|
|
; for the routine. The idea is to pop the stack frame and treat the call
|
|
; instruction in the caller as though it threw. We only have the return
|
|
; address, though, which points to the instruction *after* the call.
|
|
;
|
|
|
|
align 16
|
|
__throwDispatcherExplicitAddrAfter proc frame
|
|
ifdef SINGULARITY
|
|
push rcx
|
|
push rdx
|
|
mov rcx, rdx
|
|
call ?g_IsUnlinkStack@Class_System_Exception@@SA_NPEAUuintPtr@@@Z
|
|
pop rdx
|
|
pop rcx
|
|
test al, al
|
|
je normal
|
|
mov rax, rcx ; save exception type
|
|
mov rcx, rdx
|
|
mov rdx, [rbp+8] ; save the return addr in caller
|
|
push rax
|
|
mov rax, afterUnlinkStack
|
|
mov [rbp+8], rax ; override return addr to instr after
|
|
pop rax
|
|
jmp rcx ; unlink stack which saves eax, edx
|
|
afterUnlinkStack:
|
|
mov rcx, rax ; restore return addr in caller
|
|
normal:
|
|
endif
|
|
PrologPush rcx ; save exception
|
|
dec rdx
|
|
;; set up paramter
|
|
mov r8, rdx
|
|
mov rdx, rcx
|
|
SubRsp 16
|
|
mov rcx, rsp
|
|
SubRsp 32
|
|
.endprolog
|
|
call ?ExceptionTableLookup@@YA?AUPtrPair@@PEAUClass_System_Exception@@_K@Z
|
|
add rsp, 32
|
|
pop rax
|
|
pop rdx
|
|
pop rcx ; restore exception
|
|
; mov edx is already ok
|
|
jmp __throwDispatcherHandler
|
|
__throwDispatcherExplicitAddrAfter endp
|
|
|
|
ifdef SINGULARITY_KERNEL
|
|
; There are 3 control paths that merge here:
|
|
; (1) When Thread.cs stops a process mode thread, it sets eip to point here.
|
|
; (2) When Thread.cs stops a blocked kernel thread, it sets eip to point here.
|
|
; (3) The stack unwinder falls through to this case when a kernel exception
|
|
; reaches a process's frames.
|
|
; For control path (3), a finally block puts us in a gc safe state
|
|
; just before we reach here.
|
|
; We also expect to be in the gc safe state most of the
|
|
; time for control paths (1) and (2), but
|
|
; because pushStackMark and popStackMark are not atomic operations,
|
|
; we cannot be 100% sure that we're in the gc safe state.
|
|
; eax: kernel->process or kernel->kernel marker
|
|
; ecx: exception
|
|
__throwBeyondMarker LABEL NEAR
|
|
push rcx
|
|
push rax
|
|
; Leave the gc safe state (if we're actually in it)
|
|
call ?g_RestoreMutatorControlIfNeeded@Class_System_GCs_Transitions@@SAXXZ
|
|
pop rax
|
|
pop rcx
|
|
; eax: kernel->process or kernel->kernel marker
|
|
; ecx: exception
|
|
; Restore state from the marker, skipping over any intermediate frames.
|
|
; Keep the original exception in ecx.
|
|
; Get the return address for the frame beyond the marker into edx:
|
|
mov rdx, qword ptr [rax].Struct_System_GCs_CallStack_TransitionRecord._stackBottom
|
|
mov rdx, qword ptr [rdx - 8]
|
|
; Restore the kernel's ebx, edi, esi, ebp from the marker:
|
|
mov rbx, qword ptr [rax].Struct_System_GCs_CallStack_TransitionRecord._calleeSaveRegisters._EBX
|
|
mov rdi, qword ptr [rax].Struct_System_GCs_CallStack_TransitionRecord._calleeSaveRegisters._EDI
|
|
mov rsi, qword ptr [eax].Struct_System_GCs_CallStack_TransitionRecord._calleeSaveRegisters._ESI
|
|
mov rbp, qword ptr [rax].Struct_System_GCs_CallStack_TransitionRecord._calleeSaveRegisters._EBP
|
|
; Keep a copy of transition record (eax) and oldTransitionRecord
|
|
push rax
|
|
push qword ptr [rax].Struct_System_GCs_CallStack_TransitionRecord._oldTransitionRecord
|
|
; Read _stackBottom (the new esp) from the kernel->process marker:
|
|
mov rax, qword ptr [rax].Struct_System_GCs_CallStack_TransitionRecord._stackBottom
|
|
; Save ecx, edx to new stack -- this may overwrite the transition record,
|
|
; so don't read any more fields from the transition record after this point.
|
|
mov [rax - 8], ecx ; (exception)
|
|
mov [rax - 16], edx ; (return address)
|
|
; Set up the two arguments to DiscardStackSegments
|
|
pop rdx ; (oldTransitionRecord)
|
|
pop rcx ; (marker)
|
|
; Restore the kernel's esp from the kernel->process marker:
|
|
lea rsp, [rax - 16]
|
|
; Free any stack segments that we skipped over:
|
|
;; TODO: are we sure there's enough stack space to call this?
|
|
call ?g_DiscardSkippedStackSegments@Class_System_Threading_Thread@@SAXPEAUStruct_System_GCs_CallStack_TransitionRecord@@0@Z
|
|
pop rdx ; (return address)
|
|
pop rcx ; (exception)
|
|
endif ; SINGULARITY_KERNEL
|
|
|
|
|
|
; __throwDispatcherHandler (eax=frameSetupInfo or exceptionType,
|
|
; ecx=exception,
|
|
; edx=spillSize,frameSetupSize, or handlerAddress
|
|
;
|
|
; Description:
|
|
; After the exception table entry has been found, the values are passed here
|
|
; for processing. This method simply checks for the easy case of an explicit
|
|
; handler (known if the exceptionType is given <-- low bit is zero).
|
|
; In this case it simply jumps to the handler. Otherwise it passes the
|
|
; information along to __throwDispatcherUnwind.
|
|
;
|
|
; Arguments:
|
|
; If low bit of eax is set:
|
|
; eax = frame setup information
|
|
; ecx = exception object
|
|
; edx = spill size excluding callee-save register saves
|
|
; or offset from ebp to end of callee-save register saves
|
|
; Otherwise:
|
|
; eax = exception type (unused)
|
|
; ecx = exception object
|
|
; edx = handler address
|
|
|
|
align 16
|
|
__throwDispatcherHandler proc ;frame
|
|
;.endprolog
|
|
test rax, 1
|
|
jne __throwDispatcherUnwind
|
|
;; ecx=exception, edx=handler
|
|
jmp rdx
|
|
__throwDispatcherHandler endp
|
|
|
|
; __throwDispatcherUnwind (eax=frame setup info, ecx=exception, edx=spill size
|
|
;
|
|
; Description:
|
|
; This is the global unwind handler. It is used to unwind a single stack
|
|
; frame if there are no explicit handlers that catch an exception in a given
|
|
; function.
|
|
;
|
|
; Arguments:
|
|
; eax = frame setup information, must have low bit set
|
|
; ecx = exception object
|
|
; edx = spill size excluding callee-save register saves
|
|
; or offset from ebp to end of callee-save register saves
|
|
;
|
|
; See tables\ExceptionTable.cs for details on these values
|
|
|
|
align 16
|
|
__throwDispatcherUnwind proc ;frame
|
|
;.endprolog
|
|
;; eax=frame info
|
|
;; edx=spill size
|
|
|
|
;; obviously ebp isn't useful under frame pointer omission
|
|
;; but less obviously esp may be invalid if ebp is good
|
|
;; (e.g. under varargs we may not have known how many arguments to
|
|
;; pop; this is one reason why varargs turns off frame pointer omission)
|
|
test rax, 2h
|
|
jne esp_is_good
|
|
;; ebp_is_good
|
|
add rdx, rbp
|
|
mov rsp, rdx
|
|
jmp esp_is_setup
|
|
esp_is_good:
|
|
;; pop spill slots
|
|
add rsp, rdx
|
|
|
|
esp_is_setup:
|
|
|
|
;; restore callee-saves and pop values from stack
|
|
;; (excludes ebp if used as the frame pointer)
|
|
|
|
; restore float registers
|
|
test rax, 100000h
|
|
je skip_xmm15_restore
|
|
;; restore xmm15
|
|
movdqa xmm15, [rsp]
|
|
add rsp, 16
|
|
skip_xmm15_restore:
|
|
test rax, 80000h
|
|
je skip_xmm14_restore
|
|
;; restore xmm14
|
|
movdqa xmm14, [rsp]
|
|
add rsp, 16
|
|
skip_xmm14_restore:
|
|
test rax, 40000h
|
|
je skip_xmm13_restore
|
|
;; restore xmm13
|
|
movdqa xmm13, [rsp]
|
|
add rsp, 16
|
|
skip_xmm13_restore:
|
|
test rax, 20000h
|
|
je skip_xmm12_restore
|
|
;; restore xmm12
|
|
movdqa xmm12, [rsp]
|
|
add rsp, 16
|
|
skip_xmm12_restore:
|
|
test rax, 10000h
|
|
je skip_xmm11_restore
|
|
;; restore xmm11
|
|
movdqa xmm11, [rsp]
|
|
add rsp, 16
|
|
skip_xmm11_restore:
|
|
test rax, 8000h
|
|
je skip_xmm10_restore
|
|
;; restore xmm10
|
|
movdqa xmm10, [rsp]
|
|
add rsp, 16
|
|
skip_xmm10_restore:
|
|
test rax, 4000h
|
|
je skip_xmm9_restore
|
|
;; restore xmm9
|
|
movdqa xmm9, [rsp]
|
|
add rsp, 16
|
|
skip_xmm9_restore:
|
|
test rax, 2000h
|
|
je skip_xmm8_restore
|
|
;; restore xmm8
|
|
movdqa xmm8, [rsp]
|
|
add rsp, 16
|
|
skip_xmm8_restore:
|
|
test rax, 1000h
|
|
je skip_xmm7_restore
|
|
;; restore xmm7
|
|
movdqa xmm7, [rsp]
|
|
add rsp, 16
|
|
skip_xmm7_restore:
|
|
test rax, 800h
|
|
je skip_xmm6_restore
|
|
;; restore xmm6
|
|
movdqa xmm6, [rsp]
|
|
add rsp, 16
|
|
skip_xmm6_restore:
|
|
|
|
; account of alignment
|
|
test rax, 200000h
|
|
je skip_align_xmm
|
|
;; add 8 to rsp for alignment
|
|
add rsp, 8
|
|
skip_align_xmm:
|
|
|
|
; restore int registers
|
|
test rax, 400h
|
|
je skip_r15_restore
|
|
;; restore r15
|
|
pop r15
|
|
skip_r15_restore:
|
|
test rax, 200h
|
|
je skip_r14_restore
|
|
;; restore r14
|
|
pop r14
|
|
skip_r14_restore:
|
|
test rax, 100h
|
|
je skip_r13_restore
|
|
;; restore r13
|
|
pop r13
|
|
skip_r13_restore:
|
|
test rax, 80h
|
|
je skip_r12_restore
|
|
;; restore r12
|
|
pop r12
|
|
skip_r12_restore:
|
|
test rax, 4h
|
|
je skip_edi_restore
|
|
;; restore edi
|
|
pop rdi
|
|
skip_edi_restore:
|
|
test rax, 8h
|
|
je skip_esi_restore
|
|
;; restore esi
|
|
pop rsi
|
|
skip_esi_restore:
|
|
test rax, 10h
|
|
je skip_ebp_restore
|
|
;; restore ebp
|
|
pop rbp
|
|
skip_ebp_restore:
|
|
test rax, 20h
|
|
je skip_ebx_restore
|
|
;; restore ebx
|
|
pop rbx
|
|
skip_ebx_restore:
|
|
|
|
test rax, 40h
|
|
je skip_jump_transition_record
|
|
;; jump over transition record
|
|
add rsp, (SIZE Struct_System_GCs_CallStack_TransitionRecord)
|
|
skip_jump_transition_record:
|
|
|
|
;; restore ebp if it was used as the frame pointer
|
|
test rax, 2h
|
|
jne skip_frame_pointer_restore
|
|
;; restore frame pointer (esp == ebp already)
|
|
pop rbp
|
|
skip_frame_pointer_restore:
|
|
|
|
;; set edx=return address
|
|
pop rdx
|
|
|
|
;; no arguments to pop
|
|
|
|
;; At this point
|
|
;; ecx=exception, edx=return address
|
|
;; esi/edi/ebx/ebp/esp have been restored
|
|
;; eax is scratch
|
|
|
|
;; set up next handler search
|
|
jmp __throwDispatcherExplicitAddrAfter
|
|
__throwDispatcherUnwind endp
|
|
|
|
;
|
|
; __throwDivideByZeroException: instantiate an divide-by-zero exception
|
|
; and throw it.
|
|
;
|
|
; Assumes rdx points to the address after the one that threw.
|
|
;
|
|
|
|
align 16
|
|
__throwDivideByZeroException proc frame
|
|
PrologPush rbx
|
|
PrologPush rsi
|
|
.endprolog
|
|
mov rbx,rdx ; save address
|
|
if SINGLE_THREADED
|
|
inc ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
else ; SINGLE_THREADED
|
|
lock inc ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
endif ; SINGLE_THREADED
|
|
mov rcx,offset ??_7System_DivideByZeroException@@6B@
|
|
call ?g_AllocateObject@Class_System_GC@@SAPEAUClass_System_Object@@PEAUClass_System_VTable@@@Z
|
|
mov rsi,rax ; save pointer to instance of exception
|
|
mov rcx,rax ; initialize instance
|
|
call ?m__ctor@Class_System_DivideByZeroException@@SAXPEAU1@@Z
|
|
if SINGLE_THREADED
|
|
dec ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
else ; SINGLE_THREADED
|
|
lock dec ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
endif ; SINGLE_THREADED
|
|
mov rcx,rsi
|
|
mov rdx,rbx
|
|
pop rsi
|
|
pop rbx
|
|
jmp __throwDispatcherExplicitAddr
|
|
__throwDivideByZeroException endp
|
|
|
|
;
|
|
; __throwStackOverflowException: instantiate an StackOverflow exception
|
|
; and throw it.
|
|
;
|
|
; Assumes edx points to the address of the instruction that faulted
|
|
;
|
|
|
|
align 16
|
|
__throwStackOverflowException proc frame
|
|
PrologPush rbx
|
|
PrologPush rsi
|
|
.endprolog
|
|
mov rbx,rdx ; save address
|
|
if SINGLE_THREADED
|
|
inc ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
else ; SINGLE_THREADED
|
|
lock inc ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
endif ; MULTI_THREADED
|
|
mov rcx,offset ??_7System_StackOverflowException@@6B@
|
|
call ?g_AllocateObject@Class_System_GC@@SAPEAUClass_System_Object@@PEAUClass_System_VTable@@@Z
|
|
mov rsi,rax ; save pointer to instance of exception
|
|
mov rcx,rax ; initialize instance
|
|
call ?m__ctor@Class_System_StackOverflowException@@SAXPEAU1@@Z
|
|
if SINGLE_THREADED
|
|
dec ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
else ; SINGLE_THREADED
|
|
lock dec ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
endif ; MULTI_THREADED
|
|
;; set up paramter
|
|
mov rdx, rsi
|
|
mov r8, rbx
|
|
sub rsp, 16
|
|
mov rcx, rsp
|
|
sub rsp, 32
|
|
call ?ExceptionTableLookup@@YA?AUPtrPair@@PEAUClass_System_Exception@@_K@Z
|
|
add rsp, 32
|
|
pop rax
|
|
pop rdx
|
|
ifndef SINGULARITY
|
|
push rsi
|
|
push rdx
|
|
call ?ResetGuardPage@@YAXXZ
|
|
pop rdx
|
|
pop rax
|
|
endif
|
|
pop rsi
|
|
pop rbx
|
|
mov rcx,rax
|
|
; mov rdx is already ok
|
|
jmp rdx
|
|
__throwStackOverflowException endp
|
|
|
|
;
|
|
; __throwNullReferenceException: instantiate an NullReference exception
|
|
; and throw it.
|
|
;
|
|
; Assumes edx points to the address of the instruction that faulted
|
|
;
|
|
|
|
align 16
|
|
__throwNullReferenceException proc frame
|
|
PrologPush rbx
|
|
PrologPush rsi
|
|
.endprolog
|
|
mov rbx,rdx ; save address
|
|
if SINGLE_THREADED
|
|
inc ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
else ; SINGLE_THREADED
|
|
lock inc ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
endif ; SINGLE_THREADED
|
|
mov rcx,offset ??_7System_NullReferenceException@@6B@
|
|
call ?g_AllocateObject@Class_System_GC@@SAPEAUClass_System_Object@@PEAUClass_System_VTable@@@Z
|
|
mov rsi,rax ; save pointer to instance of exception
|
|
mov rcx,rax ; initialize instance
|
|
call ?m__ctor@Class_System_NullReferenceException@@SAXPEAU1@@Z
|
|
if SINGLE_THREADED
|
|
dec ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
else ; SINGLE_THREADED
|
|
lock dec ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
endif ; SINGLE_THREADED
|
|
mov rcx,rsi
|
|
mov rdx,rbx
|
|
pop rsi
|
|
pop rbx
|
|
jmp __throwDispatcherExplicitAddr
|
|
__throwNullReferenceException endp
|
|
|
|
;
|
|
; __throwDivideByZeroException: instantiate an divide-by-zero exception
|
|
; and throw it.
|
|
;
|
|
; Assumes rdx points to the address of the instruction that faulted
|
|
;
|
|
|
|
align 16
|
|
__throwOverflowException proc frame
|
|
PrologPush rbx
|
|
PrologPush rsi
|
|
.endprolog
|
|
mov rbx,rdx ; save address
|
|
if SINGLE_THREADED
|
|
inc ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
else ; SINGLE_THREADED
|
|
lock inc ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
endif ; SINGLE_THREADED
|
|
mov rcx,offset ??_7System_OverflowException@@6B@
|
|
call ?g_AllocateObject@Class_System_GC@@SAPEAUClass_System_Object@@PEAUClass_System_VTable@@@Z
|
|
mov rsi,rax ; save pointer to instance of exception
|
|
mov rcx,rax ; initialize instance
|
|
call ?m__ctor@Class_System_OverflowException@@SAXPEAU1@@Z
|
|
if SINGLE_THREADED
|
|
dec ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
else ; SINGLE_THREADED
|
|
lock dec ?c_allocationInhibitGC@Class_System_GC@@2_NA
|
|
endif ; SINGLE_THREADED
|
|
mov rcx,rsi
|
|
mov rdx,rbx
|
|
pop rsi
|
|
pop rbx
|
|
jmp __throwDispatcherExplicitAddr
|
|
__throwOverflowException endp
|
|
|
|
|
|
ifdef SINGULARITY_KERNEL
|
|
;
|
|
; void Thread.setStopContext(Thread t, Exception exn)
|
|
;
|
|
|
|
align 16
|
|
|
|
?g_setStopContext@Class_System_Threading_Thread@@SAXPEAU1@PEAUClass_System_Exception@@@Z proc frame
|
|
PrologPush rbp ; create ebp chain entry
|
|
SetFramePointer rbp ; set new ebp
|
|
.endprolog
|
|
; rcx = rcx.context
|
|
add rcx, Class_System_Threading_Thread._context
|
|
; context.eip = __throwBeyondMarker
|
|
; context.ecx = processStopException
|
|
; context.eax = context.stackMarkers
|
|
mov rax, __throwBeyondMarker
|
|
mov [rcx].Struct_Microsoft_Singularity_ThreadContext._threadRecord._spill._ip, rax
|
|
mov [rcx].Struct_Microsoft_Singularity_ThreadContext._threadRecord._spill._cx, rdx
|
|
mov rax, [rcx].Struct_Microsoft_Singularity_ThreadContext._stackMarkers
|
|
mov [rcx].Struct_Microsoft_Singularity_ThreadContext._threadRecord._spill._ax, rax
|
|
; Epilogue
|
|
mov esp, ebp
|
|
pop rbp;
|
|
ret
|
|
?g_setStopContext@Class_System_Threading_Thread@@SAXPEAU1@PEAUClass_System_Exception@@@Z endp
|
|
|
|
endif ; SINGULARITY_KERNEL
|
|
|
|
|
|
ifdef SINGULARITY
|
|
?g_ZeroPages@Class_System_Buffer@@SAXPEAEH@Z proc frame
|
|
;; ECX = dst
|
|
;; EDX = len (bytes)
|
|
PrologPush rbp
|
|
SetFramePointer rbp
|
|
.endprolog
|
|
pxor mm0, mm0
|
|
next:
|
|
movntq [rcx + 0], mm0
|
|
movntq [rcx + 8], mm0
|
|
movntq [rcx + 16], mm0
|
|
movntq [rcx + 24], mm0
|
|
movntq [rcx + 32], mm0
|
|
movntq [rcx + 40], mm0
|
|
movntq [rcx + 48], mm0
|
|
movntq [rcx + 56], mm0
|
|
add rcx, 64
|
|
sub rdx, 64
|
|
ja next
|
|
|
|
sfence
|
|
emms
|
|
pop rbp
|
|
ret
|
|
?g_ZeroPages@Class_System_Buffer@@SAXPEAEH@Z endp
|
|
|
|
?g_CopyPages@Class_System_Buffer@@SAXPEAE0H@Z proc frame
|
|
PrologPush rbp
|
|
SetFramePointer rbp
|
|
.endprolog
|
|
|
|
;; RCX = dst
|
|
;; RX = src
|
|
;; r8 = len (bytes)
|
|
|
|
mov rax, r8
|
|
|
|
cmp rcx, rdx
|
|
js down
|
|
|
|
;; destination is lower than source
|
|
add rcx, rax
|
|
add rdx, rax
|
|
sub rcx, 64
|
|
sub rdx, 64
|
|
|
|
up:
|
|
movq mm0, [rdx + 0]
|
|
movq mm1, [rdx + 8]
|
|
movq mm2, [rdx + 16]
|
|
movq mm3, [rdx + 24]
|
|
movq mm4, [rdx + 32]
|
|
movq mm5, [rdx + 40]
|
|
movq mm6, [rdx + 48]
|
|
movq mm7, [rdx + 56]
|
|
movntq [rcx + 0], mm0
|
|
movntq [rcx + 8], mm1
|
|
movntq [rcx + 16], mm2
|
|
movntq [rcx + 24], mm3
|
|
movntq [rcx + 32], mm4
|
|
movntq [rcx + 40], mm5
|
|
movntq [rcx + 48], mm6
|
|
movntq [rcx + 56], mm7
|
|
sub rcx, 64
|
|
sub rdx, 64
|
|
sub rax, 64
|
|
ja up
|
|
|
|
sfence
|
|
emms
|
|
pop rbp
|
|
ret
|
|
|
|
;; destination is higher than source
|
|
down:
|
|
movq mm0, [rdx + 0]
|
|
movq mm1, [rdx + 8]
|
|
movq mm2, [rdx + 16]
|
|
movq mm3, [rdx + 24]
|
|
movq mm4, [rdx + 32]
|
|
movq mm5, [rdx + 40]
|
|
movq mm6, [rdx + 48]
|
|
movq mm7, [rdx + 56]
|
|
movntq [rcx + 0], mm0
|
|
movntq [rcx + 8], mm1
|
|
movntq [rcx + 16], mm2
|
|
movntq [rcx + 24], mm3
|
|
movntq [rcx + 32], mm4
|
|
movntq [rcx + 40], mm5
|
|
movntq [rcx + 48], mm6
|
|
movntq [rcx + 56], mm7
|
|
add rcx, 64
|
|
add rdx, 64
|
|
sub rax, 64
|
|
ja down
|
|
|
|
sfence
|
|
emms
|
|
pop rbp
|
|
ret
|
|
?g_CopyPages@Class_System_Buffer@@SAXPEAE0H@Z endp
|
|
endif
|
|
|
|
;
|
|
; int System.VTable.doubleToInt(double)
|
|
;
|
|
|
|
align 16
|
|
?g_doubleToInt@Class_System_VTable@@SAHN@Z proc frame
|
|
PrologPush rbp
|
|
SetFramePointer rbp
|
|
SubRsp 8
|
|
.endprolog
|
|
movsd real8 ptr [rbp+16], xmm0
|
|
fld real8 ptr [rbp+16]
|
|
wait
|
|
fnstcw word ptr [rbp-2]
|
|
wait
|
|
mov ax,word ptr [rbp-2]
|
|
or eax,0C00h
|
|
mov word ptr [rbp-4],ax
|
|
fldcw word ptr [rbp-4]
|
|
fistp dword ptr [rbp-8]
|
|
fldcw word ptr [rbp-2]
|
|
mov eax,dword ptr [rbp-8]
|
|
|
|
cmp eax,080000000h
|
|
je possible_overflow
|
|
return:
|
|
mov rsp,rbp
|
|
pop rbp
|
|
ret
|
|
|
|
possible_overflow:
|
|
fld real8 ptr [rbp+16]
|
|
fcomp real8 ptr $DBLMAXINT
|
|
fnstsw ax
|
|
test ah,4
|
|
jne short return_zero
|
|
test ah,1
|
|
jne short return_MININT
|
|
|
|
return_MAXINT:
|
|
mov eax, 07fffffffh
|
|
jmp short return
|
|
|
|
return_zero:
|
|
xor eax, eax
|
|
jmp short return
|
|
|
|
return_MININT:
|
|
mov eax, 080000000h
|
|
jmp short return
|
|
|
|
?g_doubleToInt@Class_System_VTable@@SAHN@Z endp
|
|
|
|
;
|
|
; long System.VTable.doubleToLong(double)
|
|
;
|
|
|
|
align 16
|
|
?g_doubleToLong@Class_System_VTable@@SA_JN@Z proc frame
|
|
PrologPush rbp
|
|
SetFramePointer rbp
|
|
.endprolog
|
|
add rsp,-12
|
|
movsd real8 ptr [rbp+16], xmm0
|
|
fld real8 ptr [rbp+16]
|
|
wait
|
|
fnstcw word ptr [rbp-2]
|
|
wait
|
|
mov ax,word ptr [rbp-2]
|
|
or eax,0C00h
|
|
mov word ptr [rbp-4],ax
|
|
fldcw word ptr [rbp-4]
|
|
fistp qword ptr [rbp-12]
|
|
fldcw word ptr [rbp-2]
|
|
mov rax,qword ptr [rbp-12]
|
|
mov rdx,08000000000000000h
|
|
cmp rax,rdx
|
|
je possible_overflow
|
|
return:
|
|
mov rsp,rbp
|
|
pop rbp
|
|
ret
|
|
|
|
possible_overflow:
|
|
mov rdx,rax ; save lsw
|
|
fld real8 ptr [rbp+16]
|
|
fild qword ptr $MAXLONG
|
|
fcompp
|
|
fnstsw ax
|
|
test ah,4
|
|
jne short return_zero
|
|
test ah,65
|
|
je short check_MINLONG
|
|
|
|
return_MAXLONG:
|
|
mov rax, 07fffffffffffffffh
|
|
jmp short return
|
|
|
|
return_zero:
|
|
xor rax, rax
|
|
jmp short return
|
|
|
|
check_MINLONG:
|
|
fld real8 ptr [rbp+16]
|
|
fild qword ptr $MINLONG
|
|
fcompp
|
|
fnstsw ax
|
|
test ah,1
|
|
jne short return_original
|
|
|
|
return_MINLONG:
|
|
mov rax, 08000000000000000h
|
|
jmp short return
|
|
|
|
return_original:
|
|
mov rax, rdx ; restore lsw to eax
|
|
mov rdx, 08000000000000000h
|
|
and rax, rdx
|
|
jmp short return
|
|
|
|
?g_doubleToLong@Class_System_VTable@@SA_JN@Z endp
|
|
|
|
;
|
|
; int System.VTable.floatToInt(float)
|
|
;
|
|
|
|
align 16
|
|
?g_floatToInt@Class_System_VTable@@SAHM@Z proc frame
|
|
PrologPush rbp
|
|
SetFramePointer rbp
|
|
SubRsp 8
|
|
.endprolog
|
|
movss real4 ptr [rbp+16], xmm0
|
|
fld real4 ptr [rbp+16]
|
|
wait
|
|
fnstcw word ptr [rbp-2]
|
|
wait
|
|
xor eax,eax
|
|
mov ax,word ptr [rbp-2]
|
|
or eax,0C00h
|
|
mov word ptr [rbp-4],ax
|
|
fldcw word ptr [rbp-4]
|
|
fistp dword ptr [rbp-8]
|
|
fldcw word ptr [rbp-2]
|
|
mov eax,dword ptr [rbp-8]
|
|
|
|
cmp eax,080000000h
|
|
je possible_overflow
|
|
return:
|
|
mov rsp,rbp
|
|
pop rbp
|
|
ret
|
|
|
|
possible_overflow:
|
|
fld real4 ptr [rbp+16]
|
|
fcomp real8 ptr $DBLMAXINT
|
|
fnstsw ax
|
|
test ah,4
|
|
jne short return_zero
|
|
test ah,1
|
|
jne short return_MININT
|
|
mov eax, 07fffffffh
|
|
jmp short return
|
|
|
|
return_zero:
|
|
xor eax, eax
|
|
jmp short return
|
|
|
|
return_MININT:
|
|
mov eax, 080000000h
|
|
jmp short return
|
|
|
|
?g_floatToInt@Class_System_VTable@@SAHM@Z endp
|
|
|
|
;
|
|
; long System.VTable.floatToLong(float)
|
|
;
|
|
|
|
align 16
|
|
?g_floatToLong@Class_System_VTable@@SA_JM@Z proc frame
|
|
PrologPush rbp
|
|
SetFramePointer rbp
|
|
.endprolog
|
|
add rsp,-12
|
|
movss real4 ptr [rbp+16], xmm0
|
|
fld real4 ptr [rbp+16]
|
|
wait
|
|
fnstcw word ptr [rbp-2]
|
|
wait
|
|
mov ax,word ptr [rbp-2]
|
|
or eax,0C00h
|
|
mov word ptr [rbp-4],ax
|
|
fldcw word ptr [rbp-4]
|
|
fistp qword ptr [rbp-12]
|
|
fldcw word ptr [rbp-2]
|
|
mov rax,qword ptr [rbp-12]
|
|
mov rdx,08000000000000000h
|
|
cmp rax,rdx
|
|
je possible_overflow
|
|
return:
|
|
mov rsp,rbp
|
|
pop rbp
|
|
ret
|
|
|
|
possible_overflow:
|
|
mov rdx,rax ; save lsw
|
|
fld real4 ptr [rbp+16]
|
|
fild qword ptr $MAXLONG
|
|
fcompp
|
|
fnstsw ax
|
|
test ah,4
|
|
jne short return_zero
|
|
test ah,65
|
|
je short check_MINLONG
|
|
|
|
return_MAXLONG:
|
|
mov rax, 07fffffffffffffffh
|
|
jmp short return
|
|
|
|
return_zero:
|
|
xor rax, rax
|
|
jmp short return
|
|
|
|
check_MINLONG:
|
|
fld real4 ptr [rbp+16]
|
|
fild qword ptr $MINLONG
|
|
fcompp
|
|
fnstsw ax
|
|
test ah,1
|
|
jne short return_original
|
|
|
|
return_MINLONG:
|
|
mov rax, 08000000000000000h
|
|
jmp short return
|
|
|
|
return_original:
|
|
mov rax, rdx ; restore lsw to eax
|
|
mov rdx, 08000000000000000h
|
|
and rax, rdx
|
|
jmp short return
|
|
|
|
?g_floatToLong@Class_System_VTable@@SA_JM@Z endp
|
|
|
|
;
|
|
; int System.VTable.checkedDoubleToInt(double)
|
|
;
|
|
|
|
align 16
|
|
?g_checkedDoubleToInt@Class_System_VTable@@SAHN@Z proc frame
|
|
PrologPush rbp
|
|
SetFramePointer rbp
|
|
SubRsp 8
|
|
.endprolog
|
|
movsd real8 ptr [rbp+16], xmm0
|
|
fld real8 ptr [rbp+16]
|
|
wait
|
|
fnstcw word ptr [rbp-2]
|
|
wait
|
|
mov ax,word ptr [rbp-2]
|
|
or eax,0C00h
|
|
mov word ptr [rbp-4],ax
|
|
fldcw word ptr [rbp-4]
|
|
fistp dword ptr [rbp-8]
|
|
fldcw word ptr [rbp-2]
|
|
mov eax,dword ptr [rbp-8]
|
|
|
|
cmp eax,080000000h
|
|
je possible_overflow
|
|
return:
|
|
mov rsp,rbp
|
|
pop rbp
|
|
ret
|
|
|
|
possible_overflow:
|
|
fld real8 ptr [rbp+16]
|
|
fcomp real8 ptr $DBLMAXINT
|
|
fnstsw ax
|
|
test ah,4 ; test for unordered
|
|
jne short throw_exception
|
|
test ah,1 ; test for <$DBLMAXINT
|
|
jne short return_MININT
|
|
; src > $DBLMAXINT
|
|
; throw an overflow exception
|
|
jmp short throw_exception
|
|
|
|
return_MININT:
|
|
; check against $DBLMININT
|
|
fld real8 ptr [rbp+16]
|
|
fcomp real8 ptr $DBLMININT
|
|
fnstsw ax
|
|
test ah, 1 ; test for < $DBLMININT
|
|
jne short throw_exception ; throw exception if true
|
|
mov eax, 080000000h
|
|
jmp short return
|
|
|
|
throw_exception:
|
|
; throw an overflow exception
|
|
; set up stack frame so that it looks like a call to throwNewOverflowException
|
|
; from the caller of this function.
|
|
mov rsp,rbp
|
|
pop rbp
|
|
; pop rax ; grab return address
|
|
; add rsp, 8 ; move rsp pass the first parameter.
|
|
; mov [rsp],rax ; overwrite argument
|
|
jmp ?g_throwNewOverflowException@Class_System_VTable@@SAXXZ
|
|
|
|
?g_checkedDoubleToInt@Class_System_VTable@@SAHN@Z endp
|
|
|
|
;
|
|
; long System.VTable.checkedDoubleToLong(double)
|
|
;
|
|
|
|
align 16
|
|
?g_checkedDoubleToLong@Class_System_VTable@@SA_JN@Z proc frame
|
|
PrologPush rbp
|
|
SetFramePointer rbp
|
|
.endprolog
|
|
add rsp,-12
|
|
movsd real8 ptr [rbp+16], xmm0
|
|
fld real8 ptr [rbp+16]
|
|
wait
|
|
fnstcw word ptr [rbp-2]
|
|
wait
|
|
mov ax,word ptr [rbp-2]
|
|
or eax,0C00h
|
|
mov word ptr [rbp-4],ax
|
|
fldcw word ptr [rbp-4]
|
|
fistp qword ptr [rbp-12]
|
|
fldcw word ptr [rbp-2]
|
|
mov rax,qword ptr [rbp-12]
|
|
mov rdx,08000000000000000h
|
|
cmp rax, rdx
|
|
je possible_overflow
|
|
return:
|
|
mov rsp,rbp
|
|
pop rbp
|
|
ret
|
|
|
|
possible_overflow:
|
|
mov rdx,rax ; save lsw
|
|
fld real8 ptr [rbp+16]
|
|
fild qword ptr $MAXLONG
|
|
fcompp
|
|
fnstsw ax
|
|
test ah,4 ; test for unordered
|
|
jne short return_zero
|
|
test ah,65 ; test for <= $MAXLONG
|
|
je short check_MINLONG
|
|
|
|
return_MAXLONG:
|
|
; src > $MAXLONG
|
|
; throw an exception
|
|
jmp short throw_exception
|
|
|
|
return_zero:
|
|
jmp short throw_exception
|
|
|
|
check_MINLONG:
|
|
; src <= $MINLONG
|
|
fild qword ptr $MINLONG
|
|
fld real8 ptr [rbp+16]
|
|
fcompp ; real8 ptr [rbp+8] < $MINLONG
|
|
fnstsw ax
|
|
test ah,1
|
|
jne short throw_exception
|
|
|
|
return_MINLONG:
|
|
mov rax, rdx ; restore lsw to eax
|
|
mov rdx, 08000000000000000h
|
|
and rax, rdx
|
|
jmp short return
|
|
|
|
|
|
throw_exception:
|
|
; throw an overflow exception
|
|
; set up stack frame so that it looks like a call to throwNewOverflowException
|
|
; from the caller of this function.
|
|
mov rsp,rbp
|
|
pop rbp
|
|
;pop rax ; grab return address
|
|
;add rsp, 8 ; move rsp pass the first parameter.
|
|
;mov [rsp],eax ; overwrite argument
|
|
jmp ?g_throwNewOverflowException@Class_System_VTable@@SAXXZ
|
|
|
|
?g_checkedDoubleToLong@Class_System_VTable@@SA_JN@Z endp
|
|
|
|
;
|
|
; int System.VTable.checkedFloatToInt(float)
|
|
;
|
|
|
|
align 16
|
|
?g_checkedFloatToInt@Class_System_VTable@@SAHM@Z proc frame
|
|
PrologPush rbp
|
|
SetFramePointer rbp
|
|
SubRsp 8
|
|
.endprolog
|
|
movss real4 ptr [rbp+16], xmm0
|
|
fld real4 ptr [rbp+16]
|
|
wait
|
|
fnstcw word ptr [rbp-2]
|
|
wait
|
|
xor eax,eax
|
|
mov ax,word ptr [rbp-2]
|
|
or eax,0C00h
|
|
mov word ptr [rbp-4],ax
|
|
fldcw word ptr [rbp-4]
|
|
fistp dword ptr [rbp-8]
|
|
fldcw word ptr [rbp-2]
|
|
mov eax,dword ptr [rbp-8]
|
|
|
|
cmp eax,080000000h
|
|
je possible_overflow
|
|
|
|
return:
|
|
mov rsp,rbp
|
|
pop rbp
|
|
ret
|
|
|
|
possible_overflow:
|
|
fld real4 ptr [rbp+16]
|
|
fcomp real8 ptr $DBLMAXINT
|
|
fnstsw ax
|
|
test ah,4 ; test for unordered
|
|
jne short throw_exception
|
|
test ah,1 ; test for src < $DBLMAXINT
|
|
jne short return_MININT
|
|
; src > $DBLMAXINT
|
|
; throw an overflow exception
|
|
jmp short throw_exception
|
|
|
|
return_MININT:
|
|
; need to check against $DBLMININT, if it is less than,
|
|
; then throw an overflow exception
|
|
fld real4 ptr [rbp+16]
|
|
fcomp real8 ptr $DBLMININT
|
|
fnstsw ax
|
|
test ah,1 ; test for less than
|
|
jne short throw_exception
|
|
mov eax, 080000000h
|
|
jmp short return
|
|
|
|
throw_exception:
|
|
; throw an overflow exception
|
|
; set up stack frame so that it looks like a call to throwNewOverflowException
|
|
; from the caller of this function.
|
|
mov rsp,rbp
|
|
pop rbp
|
|
;pop rax ; grab return address
|
|
;mov [rsp],eax ; overwrite argument
|
|
jmp ?g_throwNewOverflowException@Class_System_VTable@@SAXXZ
|
|
|
|
?g_checkedFloatToInt@Class_System_VTable@@SAHM@Z endp
|
|
|
|
;
|
|
; long System.VTable.checkedFloatToLong(float)
|
|
;
|
|
|
|
align 16
|
|
?g_checkedFloatToLong@Class_System_VTable@@SA_JM@Z proc frame
|
|
PrologPush rbp
|
|
SetFramePointer rbp
|
|
.endprolog
|
|
add rsp,-12
|
|
movss real4 ptr [rbp+16], xmm0
|
|
fld real4 ptr [rbp+16]
|
|
wait
|
|
fnstcw word ptr [rbp-2]
|
|
wait
|
|
mov ax,word ptr [rbp-2]
|
|
or eax,0C00h
|
|
mov word ptr [rbp-4],ax
|
|
fldcw word ptr [rbp-4]
|
|
fistp qword ptr [rbp-12]
|
|
fldcw word ptr [rbp-2]
|
|
mov rax,qword ptr [rbp-12]
|
|
mov rdx,08000000000000000h
|
|
cmp rax,rdx
|
|
je possible_overflow
|
|
return:
|
|
mov rsp,rbp
|
|
pop rbp
|
|
ret
|
|
|
|
possible_overflow:
|
|
mov rdx,rax ; save lsw
|
|
fld real4 ptr [rbp+16]
|
|
fild qword ptr $MAXLONG
|
|
fcompp
|
|
fnstsw ax
|
|
test ah,4 ; test for unordered
|
|
jne short return_zero
|
|
test ah,65 ; test for <= $MAXLONG
|
|
je short check_MINLONG
|
|
|
|
return_MAXLONG:
|
|
; src > $MAXLONG
|
|
; throw an exception
|
|
jmp short throw_exception
|
|
|
|
return_zero:
|
|
; compare with $MAXLONG results in unordered
|
|
; throw an overflow exception
|
|
jmp short throw_exception
|
|
|
|
check_MINLONG:
|
|
; src <= $MINLONG
|
|
fild qword ptr $MINLONG
|
|
fld real4 ptr [rbp+16]
|
|
fcompp ; real8 ptr [rbp+8] < $MINLONG
|
|
fnstsw ax
|
|
test ah,1
|
|
jne short throw_exception ; throw an overflow exception when src < $MINLONG
|
|
return_MINLONG:
|
|
mov rax, rdx ; restore lsw
|
|
mov rdx, 08000000000000000h
|
|
and rax, rdx
|
|
jmp short return
|
|
|
|
throw_exception:
|
|
; throw an overflow exception
|
|
; set up stack frame so that it looks like a call to throwNewOverflowException
|
|
; from the caller of this function.
|
|
mov rsp,rbp
|
|
pop rbp
|
|
;pop rax ; grab return address
|
|
;mov [rsp],eax ; overwrite argument
|
|
jmp ?g_throwNewOverflowException@Class_System_VTable@@SAXXZ
|
|
|
|
?g_checkedFloatToLong@Class_System_VTable@@SA_JM@Z endp
|
|
|
|
;
|
|
; double System.Math.Sin(double)
|
|
;
|
|
|
|
align 16
|
|
?g_Sin@Class_System_Math@@SANN@Z proc ;frame
|
|
;.endprolog
|
|
add rsp, -8
|
|
movsd real8 ptr [rsp+16], xmm0
|
|
fld real8 ptr [rsp+16]
|
|
fsin
|
|
fstp real8 ptr [rsp]
|
|
movsd xmm0, real8 ptr [rsp]
|
|
add rsp, 8
|
|
ret
|
|
?g_Sin@Class_System_Math@@SANN@Z endp
|
|
|
|
;
|
|
; double System.Math.Cos(double)
|
|
;
|
|
|
|
align 16
|
|
?g_Cos@Class_System_Math@@SANN@Z proc ;frame
|
|
;.endprolog
|
|
add rsp, -8
|
|
movsd real8 ptr [rsp+16], xmm0
|
|
fld real8 ptr [rsp+16]
|
|
fcos
|
|
fstp real8 ptr [rsp]
|
|
movsd xmm0, real8 ptr [rsp]
|
|
add rsp, 8
|
|
ret
|
|
?g_Cos@Class_System_Math@@SANN@Z endp
|
|
|
|
;
|
|
; double System.Math.Tan(double)
|
|
;
|
|
|
|
align 16
|
|
?g_Tan@Class_System_Math@@SANN@Z proc ;frame
|
|
;.endprolog
|
|
add rsp, -8
|
|
movsd real8 ptr [rsp+16], xmm0
|
|
fld real8 ptr [rsp+16]
|
|
fptan
|
|
fstp real8 ptr [rsp]
|
|
movsd xmm0, real8 ptr [rsp]
|
|
add rsp, 8
|
|
ret
|
|
?g_Tan@Class_System_Math@@SANN@Z endp
|
|
|
|
;
|
|
;
|
|
; double System.Math.Atan(double)
|
|
;
|
|
|
|
align 16
|
|
?g_Atan@Class_System_Math@@SANN@Z proc ;frame
|
|
;.endprolog
|
|
add rsp, -8
|
|
movsd real8 ptr [rsp+16], xmm0
|
|
fld real8 ptr [rsp+16]
|
|
fld1
|
|
fpatan
|
|
fstp real8 ptr [rsp]
|
|
movsd xmm0, real8 ptr [rsp]
|
|
add rsp, 8
|
|
ret
|
|
?g_Atan@Class_System_Math@@SANN@Z endp
|
|
|
|
;
|
|
; double System.Math.atan2(double,double)
|
|
;
|
|
|
|
align 16
|
|
?g_atan2@Class_System_Math@@SANNN@Z proc ;frame
|
|
;.endprolog
|
|
add rsp, -8
|
|
movsd real8 ptr [rsp+16], xmm0
|
|
movsd real8 ptr [rsp+24], xmm1
|
|
fld real8 ptr [rsp+16]
|
|
fld real8 ptr [rsp+24]
|
|
fpatan
|
|
fstp real8 ptr [rsp]
|
|
movsd xmm0, real8 ptr [rsp]
|
|
add rsp, 8
|
|
ret
|
|
?g_atan2@Class_System_Math@@SANNN@Z endp
|
|
|
|
;
|
|
; double System.Math.exp(double)
|
|
;
|
|
|
|
align 16
|
|
?g_exp@Class_System_Math@@SANN@Z proc frame
|
|
PrologPush rbp
|
|
SetFramePointer rbp
|
|
SubRsp 8
|
|
.endprolog
|
|
|
|
fldl2e
|
|
movsd real8 ptr [rbp+16], xmm0
|
|
fmul real8 ptr [rbp+16]
|
|
fld st(0)
|
|
frndint
|
|
fxch st(1)
|
|
fsub st(0), st(1)
|
|
f2xm1
|
|
fld1
|
|
faddp st(1), st(0)
|
|
fscale
|
|
;isNaN??
|
|
fstp st(1)
|
|
|
|
fstp real8 ptr [rbp-8]
|
|
movsd xmm0, real8 ptr [rbp-8]
|
|
mov rsp,rbp
|
|
pop rbp
|
|
ret
|
|
?g_exp@Class_System_Math@@SANN@Z endp
|
|
|
|
;
|
|
; double System.Math.log(double)
|
|
;
|
|
|
|
align 16
|
|
?g_Log@Class_System_Math@@SANN@Z proc ;frame
|
|
;.endprolog
|
|
add rsp, -8
|
|
fldln2
|
|
movsd real8 ptr [rsp+16], xmm0
|
|
fld real8 ptr [rsp+16]
|
|
fyl2x
|
|
fstp real8 ptr [rsp]
|
|
movsd xmm0, real8 ptr [rsp]
|
|
add rsp, 8
|
|
ret
|
|
?g_Log@Class_System_Math@@SANN@Z endp
|
|
|
|
;
|
|
; double System.Math.Ceiling(double)
|
|
;
|
|
|
|
align 16
|
|
?g_Ceiling@Class_System_Math@@SANN@Z proc frame
|
|
PrologPush rbp
|
|
SetFramePointer rbp
|
|
SubRsp 8
|
|
.endprolog
|
|
|
|
movsd real8 ptr [rbp+16], xmm0
|
|
fld real8 ptr [rbp+16]
|
|
wait
|
|
fnstcw word ptr [rbp-2]
|
|
wait
|
|
mov ax,word ptr [rbp-2]
|
|
and ah,0F3h
|
|
or ah,008h
|
|
mov word ptr [rbp-4],ax
|
|
fldcw word ptr [rbp-4]
|
|
frndint
|
|
fldcw word ptr [rbp-2]
|
|
|
|
fstp real8 ptr [rbp-8]
|
|
movsd xmm0, real8 ptr [rbp-8]
|
|
mov rsp,rbp
|
|
pop rbp
|
|
ret
|
|
?g_Ceiling@Class_System_Math@@SANN@Z endp
|
|
|
|
;
|
|
; double System.Math.Floor(double)
|
|
;
|
|
|
|
align 16
|
|
?g_Floor@Class_System_Math@@SANN@Z proc frame
|
|
PrologPush rbp
|
|
SetFramePointer rbp
|
|
SubRsp 8
|
|
.endprolog
|
|
|
|
movsd real8 ptr [rsp+16], xmm0
|
|
fld real8 ptr [rbp+16]
|
|
wait
|
|
fnstcw word ptr [rbp-2]
|
|
wait
|
|
mov ax,word ptr [rbp-2]
|
|
and ah,0F3h
|
|
or ah,004h
|
|
mov word ptr [rbp-4],ax
|
|
fldcw word ptr [rbp-4]
|
|
frndint
|
|
fldcw word ptr [rbp-2]
|
|
|
|
fstp real8 ptr [rbp-8]
|
|
movsd xmm0, real8 ptr [rbp-8]
|
|
mov rsp,rbp
|
|
pop rbp
|
|
ret
|
|
?g_Floor@Class_System_Math@@SANN@Z endp
|
|
|
|
;
|
|
; double System.Math.Round(double)
|
|
;
|
|
|
|
align 16
|
|
?g_Round@Class_System_Math@@SANN@Z proc ;frame
|
|
;.endprolog
|
|
add rsp, -8
|
|
movsd real8 ptr [rsp+16], xmm0
|
|
fld real8 ptr [rsp+16]
|
|
frndint
|
|
fstp real8 ptr [rsp]
|
|
movsd xmm0, real8 ptr [rsp]
|
|
add rsp, 8
|
|
ret
|
|
?g_Round@Class_System_Math@@SANN@Z endp
|
|
|
|
;
|
|
; float System.Math.Abs(float)
|
|
;
|
|
|
|
align 16
|
|
?g_abs@Class_System_Math@@SAMM@Z proc ;frame
|
|
;.endprolog
|
|
add rsp, -8
|
|
movss real4 ptr [rsp+16], xmm0
|
|
fld real4 ptr [rsp+16]
|
|
fabs
|
|
fstp real4 ptr [rsp]
|
|
movss xmm0, real4 ptr [rsp]
|
|
add rsp, 8
|
|
ret
|
|
?g_abs@Class_System_Math@@SAMM@Z endp
|
|
|
|
;
|
|
; double System.Math.Abs(double)
|
|
;
|
|
|
|
align 16
|
|
?g_abs@Class_System_Math@@SANN@Z proc ;frame
|
|
;.endprolog
|
|
add rsp, -8
|
|
movsd real8 ptr [rsp+16], xmm0
|
|
fld real8 ptr [rsp+16]
|
|
fabs
|
|
fstp real8 ptr [rsp]
|
|
movsd xmm0, real8 ptr [rsp]
|
|
add rsp, 8
|
|
ret
|
|
?g_abs@Class_System_Math@@SANN@Z endp
|
|
|
|
align 16
|
|
?g_floatRem@Class_System_VTable@@SAMMM@Z proc ;frame
|
|
;.endprolog
|
|
add rsp, -8
|
|
movss real4 ptr [rsp+16], xmm0
|
|
movss real4 ptr [rsp+24], xmm1
|
|
fld real4 ptr [rsp+24]
|
|
fld real4 ptr [rsp+16]
|
|
fremloop:
|
|
fprem
|
|
fstsw ax
|
|
fwait
|
|
sahf
|
|
jp fremloop ; Continue while the FPU status bit C2 is set
|
|
ffree st(1)
|
|
fstp real4 ptr [rsp]
|
|
movss xmm0, real4 ptr [rsp]
|
|
add rsp, 8
|
|
ret
|
|
?g_floatRem@Class_System_VTable@@SAMMM@Z endp
|
|
|
|
align 16
|
|
?g_doubleRem@Class_System_VTable@@SANNN@Z proc ;frame
|
|
;.endprolog
|
|
add rsp, -8
|
|
movsd real8 ptr [rsp+16], xmm0
|
|
movsd real8 ptr [rsp+24], xmm1
|
|
fld real8 ptr [rsp+24]
|
|
fld real8 ptr [rsp+16]
|
|
fremloop:
|
|
fprem
|
|
fstsw ax
|
|
fwait
|
|
sahf
|
|
jp fremloop ; Continue while the FPU status bit C2 is set
|
|
ffree st(1)
|
|
fstp real8 ptr [rsp]
|
|
movsd xmm0, real8 ptr [rsp]
|
|
add rsp, 8
|
|
ret
|
|
?g_doubleRem@Class_System_VTable@@SANNN@Z endp
|
|
|
|
extern ?brtmain@@3P6AHPEAUClassVector_Class_System_String@@@ZEA:qword
|
|
|
|
align 16
|
|
?g_CallMain@Class_Microsoft_Singularity_AppRuntime@@SAHPEAUClassVector_Class_System_String@@@Z proc
|
|
jmp qword ptr [?brtmain@@3P6AHPEAUClassVector_Class_System_String@@@ZEA]
|
|
?g_CallMain@Class_Microsoft_Singularity_AppRuntime@@SAHPEAUClassVector_Class_System_String@@@Z endp
|
|
|
|
end
|
|
|