summaryrefslogtreecommitdiffstats
path: root/private/ntos/inc/em387.inc
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/inc/em387.inc
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/inc/em387.inc')
-rw-r--r--private/ntos/inc/em387.inc445
1 files changed, 445 insertions, 0 deletions
diff --git a/private/ntos/inc/em387.inc b/private/ntos/inc/em387.inc
new file mode 100644
index 000000000..7c30099a8
--- /dev/null
+++ b/private/ntos/inc/em387.inc
@@ -0,0 +1,445 @@
+ subttl em387.inc - Emulator Internal Format and Macros
+ page
+;***
+;em387.inc - Emulator Internal Format and Macros
+;
+; Microsoft Confidential
+;
+; Copyright (c) Microsoft Corporation 1987, 1992
+;
+; All Rights Reserved
+;
+;Purpose:
+; Emulator Internal Format and Macros
+;
+;Revision History: (also see emulator.hst)
+;
+; 8/23/91 TP New tag definitions
+; 10/30/89 WAJ Added this header.
+; 02/12/89 WAJ Added local stack frame definition.
+;
+;*******************************************************************************
+
+
+GetEmData macro dest,use
+ifdef _CRUISER
+ mov dest,[edataSEG]
+elseifdef _DOS32EXT
+ifdifi <use>,<ax>
+ push eax
+ call _SelKrnGetEmulData
+ mov dest,ax
+ pop eax
+else
+ call _SelKrnGetEmulData
+ mov dest,ax
+endif
+endif
+ endm
+
+
+
+;The SKIP macro optimizes very short jumps by treating the code
+;as data to a "cmp" instruction. This reduces jump time from
+;8 clocks or more down to 2 clocks. It destroy the flags!
+
+SKIP macro dist,target
+if dist eq 4
+ db 3DH ;cmp eax,<immed>
+elseif dist eq 3
+ db 3DH,0 ;cmp eax,<immed>
+elseif dist eq 2
+ db 66H,3DH ;cmp ax,<immed>
+elseif dist eq 1
+ db 3CH ;cmp al,<immed>
+else
+ .err
+endif
+
+ ifnb <target>
+.erre $+dist eq target
+ endif
+
+ endm
+
+;*******************************************************************************
+;
+; 80x87 environment structures.
+;
+;*******************************************************************************
+
+
+Env80x87_32 struc
+ E32_ControlWord dw ?
+ reserved1 dw ?
+ E32_StatusWord dw ?
+ reserved2 dw ?
+ E32_TagWord dw ?
+ reserved3 dw ?
+ E32_CodeOff dd ?
+ E32_CodeSeg dw ?
+ reserved4 dw ?
+ E32_DataOff dd ?
+ E32_DataSeg dw ?
+ reserved5 dw ?
+Env80x87_32 ends
+
+
+;---------------------------------------------------------------------------
+;
+; Emulator Internal Format:
+;
+; +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11
+; .___.___.___.___.___.___.___.___.___.___.___.___.
+; ptr --> |___|___|___|___|___|___|___|___|___|___|___|___|
+; lsb msb tag sgn exl exh
+; |<--- mantissa --->| |exponent
+;
+; The mantissa contains the leading 1 before the decimal point in the hi
+; bit of the msb. The exponent is not biased (signed two's complement).
+; The flag and tag bytes are as below.
+;
+; bit: 7 6 5 4 3 2 1 0
+; .___.___.___.___.___.___.___.___.
+; Sign: |___|_X_|_X_|_X_|_X_|_X_|_X_|_X_| X = unused
+; ^
+; SIGN
+;
+;
+; bit: 7 6 5 4 3 2 1 0
+; .___.___.___.___.___.___.___.___.
+; Tag: |___|___|_X_|_X_|___|___|___|___| X = unused
+; ^ ^ ^ ^ ^ ^
+; | | | | | |
+; 387 tag -+---+ | | | |
+; | | | |
+; Special enumeration -----+---+ | |
+; | |
+; Internal tag --------------------+---+
+;
+;There are four internal tags: Single, Double, Zero, Special. Within
+;Special, there is NAN, Infinity, Denormal, and Empty.
+;
+;Representations for Single, Double, and Denormal are the same. Denormals
+;are not actually kept denormalized, although they are rounded to the
+;correct number of bits as if they were. The Single tag means the
+;low 32 bits of the mantissa are zero. This allows optimizing multiply
+;and divide.
+;
+;Tag Mantissa Exponent Sign
+;---------------------------------------------------
+;Zero 0 0 valid
+;Empty ? ? ?
+;NAN valid TexpMax valid
+;Infinity 8000...000 TexpMax valid
+;
+;The mantissa for a NAN distinguishes between a quiet NAN (QNAN) or a
+;signaling NAN (SNAN). If the bit below the MSB is 1, it is a QNAN,
+;otherwise it is an SNAN.
+;
+
+
+;*******************************************************************************
+;*
+;* Stack entry defineds with a struct.
+;*
+;*******************************************************************************
+
+EmStackEntry struc
+ bMan0 db ?
+ bMan1 db ?
+ bMan2 db ?
+ bMan3 db ?
+ bMan4 db ?
+ bMan5 db ?
+ bMan6 db ?
+ bMan7 db ?
+ bTag db ?
+ bSgn db ?
+ bExpLo db ?
+ bExpHi db ?
+EmStackEntry ends
+
+wMantisa struc
+ wMan0 dw ?
+ wMan1 dw ?
+ wMan2 dw ?
+ wMan3 dw ?
+ TagSgn dw ?
+ wExp dw ?
+wMantisa ends
+
+
+lMantisa struc
+ lManLo dd ?
+ lManHi dd ?
+ ExpSgn dd ?
+lMantisa ends
+
+.erre size lMantisa eq size wMantisa
+
+Reg87Len equ size lMantisa
+
+
+;*******************************************************************************
+;*
+;* bFlags and bTag constants.
+;*
+;*******************************************************************************
+
+;The rules for internal number formats:
+;
+;1. Everything is either normalized or zero--unnormalized formats cannot
+;get in. So if the high half mantissa is zero, the number must be all zero.
+;
+;2. Although the exponent bias is different, NANs and Infinities are in
+;standard IEEE format - exponent is TexpMax, mantissa indicates NAN vs.
+;infinity (mantissa for infinity is 800..000H).
+;
+;3. Denormals have an exponent less than TexpMin.
+;
+;4. If the low half of the mantissa is zero, it is tagged bTAG_SNGL
+;
+;5. Everything else is bTAG_VALID
+
+
+bSign equ 80h
+
+;These are the INTERNAL flags
+TAG_MASK equ 3
+TAG_SHIFT equ 2
+;
+TAG_SNGL equ 0 ;SINGLE: low 32 bits are zero
+TAG_VALID equ 1
+TAG_ZERO equ 2
+TAG_SPCL equ 3 ;NAN, Infinity, Denormal, Empty
+ZEROorSPCL equ 2 ;Test for Zero or Special
+;Enumeration of "special":
+TAG_SPCLBITS equ 0CH
+TAG_EMPTY equ TAG_SPCL+(0 shl TAG_SHIFT)
+TAG_INF equ TAG_SPCL+(1 shl TAG_SHIFT)
+TAG_NAN equ TAG_SPCL+(2 shl TAG_SHIFT)
+TAG_DEN equ TAG_SPCL+(3 shl TAG_SHIFT)
+
+;These are the tags used by the 387
+T87_VALID equ 0
+T87_ZERO equ 1
+T87_SPCL equ 2 ;NAN, Infinity, Denormal
+T87_EMPTY equ 3
+
+;The tag word for each stack entry combines these two tags.
+;Internal tags are in the low bits, 387 tags are in the high two bits
+bTAG_VALID equ (T87_VALID shl 6) or TAG_VALID
+bTAG_SNGL equ (T87_VALID shl 6) or TAG_SNGL
+bTAG_ZERO equ (T87_ZERO shl 6) or TAG_ZERO
+bTAG_NAN equ (T87_SPCL shl 6) or TAG_NAN
+bTAG_INF equ (T87_SPCL shl 6) or TAG_INF
+bTAG_EMPTY equ (T87_EMPTY shl 6) or TAG_EMPTY
+bTAG_DEN equ (T87_SPCL shl 6) or TAG_DEN
+bTAG_NOPOP equ -1
+
+bTAG_MASK equ 3
+
+
+
+MantissaByteCnt equ 8
+
+IexpBias equ 3FFFh ; 16,383
+IexpMax equ 7FFFh ; Biased Exponent for Infinity
+IexpMin equ 0 ; Biased Exponent for zero
+
+DexpBias equ 3FFh ; 1023
+DexpMax equ 7FFh ; Biased Exponent for Infinity
+DexpMin equ 0 ; Biased Exponent for zero
+
+SexpBias equ 07Fh ; 127
+SexpMax equ 0FFh ; Biased Exponent for Infinity
+SexpMin equ 0 ; Biased Exponent for zero
+
+TexpBias equ 0 ; Bias for internal format of temp real
+UnderBias equ 24576 ; 3 * 2^13. Extra bias for unmasked underflow
+TexpMax equ IexpMax - IexpBias + TexpBias ;NAN/Infinity exponent
+TexpMin equ IexpMin-IexpBias+1 ;Smallest non-denormal exponent
+
+; Control Word Format CWcntl
+
+RoundControl equ 0Ch
+ RCchop equ 0Ch
+ RCup equ 08h
+ RCdown equ 04h
+ RCnear equ 0
+
+PrecisionControl equ 03h
+ PC24 equ 0
+ PC53 equ 02h
+ PC64 equ 03h
+
+; Status Word Format SWcc
+ C0 equ 01h
+ C1 equ 02h
+ C2 equ 04h
+ C3 equ 40h
+ConditionCode equ C3 or C2 or C1 or C0
+ CCgreater equ 0
+ CCless EQU C0
+ CCequal equ C3
+ CCincomprable equ C3 or C2 or C0
+
+RoundUp equ C1
+StackOverflow equ C1
+
+; Status Flags Format CURerr
+
+Invalid equ 1h ; chip status flags
+Denormal equ 2h
+ZeroDivide equ 4h
+Overflow equ 8h
+Underflow equ 10h
+Precision equ 20h
+StackFlag equ 40h
+Summary equ 80h
+
+SavedErrs equ Invalid or Denormal or ZeroDivide or Overflow or Underflow or Precision or StackFlag
+LongSavedFlags equ (CCincomprable SHL 16) OR (SavedErrs SHL 8) ; save C0, C2, C3 & errs
+;*******************************************************************************
+;*
+;* Define emulator interrupt stack frame.
+;*
+;*******************************************************************************
+
+StackFrame struc
+ regEAX dd ?
+ regECX dd ?
+ regEDX dd ?
+ regEBX dd ?
+ regESP dd ?
+ regEBP dd ?
+ regESI dd ?
+ regEDI dd ?
+ OldCodeOff dd ?
+ OldLongStatus dd ?
+ regDS dd ?
+ regEIP dd ?
+ regCS dd ?
+ regFlg dd ?
+StackFrame ends
+
+regAX equ word ptr regEAX
+
+; .erre StatusWord eq LongStatusWord+1
+OldStatus equ word ptr OldLongStatus+1
+
+;*******************************************************************************
+;*
+;* Define emulator entry point macro.
+;*
+;*******************************************************************************
+
+EM_ENTRY macro entryname
+ifdef NT386
+public ___&entryname
+___&entryname:
+endif ; ifdef NT386
+ endm
+
+Em87Busy EQU 1
+Em87Idle EQU 0
+
+
+
+ifdef NT386
+;*********************************************************************;
+; ;
+; Emulator TEB Layout ;
+; ;
+;*********************************************************************;
+
+.errnz (TbSystemReserved1 and 3) ; Make sure TB is dword aligned
+
+Numlev equ 8 ; Number of stack registers
+
+InitControlWord equ 37FH ; Default - Round near,
+ ; 64 bits, all exceptions masked
+
+DefaultControlWord equ 27FH ; Default - Round near,
+ ; 53 bits, all exceptions masked
+
+EmulatorTebData struc
+ TbSystemResrvd db TbSystemReserved1 DUP (?) ; Skip to Emulator area
+
+ RoundMode dd ? ; Address of rounding routine
+ SavedRoundMode dd ? ; For restoring RoundMode
+ ZeroVector dd ? ; Address of sum-to-zero routine
+ TransRound dd ? ; Round mode w/o precision
+ Result dd ? ; Result pointer
+ PrevCodeOff dd ?
+ PrevDataOff dd ?
+
+ ;(See comment below on 'emulator stack area'
+ CURstk dd ? ; init to start of stack
+ BEGstk db (Numlev-1)*Reg87Len dup(?) ;Allocate register 1 - 7
+ INITstk db Reg87Len dup(?)
+
+ FloatTemp db Reg87Len dup(?)
+ ArgTemp db Reg87Len dup(?)
+
+ Einstall db 0 ; Emulator installed flag
+ SWerr db ? ; Initially no exceptions (sticky flags)
+ SWcc db ? ; Condition codes from various operations
+ CURerr db ? ; initially 8087 exception flags clear
+ ; this is the internal flag reset after
+ ; each operation to detect per instruction
+ ; errors
+ CWmask db ? ; exception masks
+ CWcntl db ? ; arithmetic control flags
+ ErrMask db ?
+ dummy db ?
+EmulatorTebData ends
+
+ENDstk equ byte ptr INITstk + Reg87Len
+LongStatusWord equ dword ptr Einstall ;Combine Einstall, CURerr, StatusWord
+StatusWord equ word ptr SWerr ;Combine SWerr, SWcc
+CurErrCond equ word ptr SWcc ;Combine SWcc, CURErr
+LongControlWord equ dword ptr CWmask ;Combine CWMask, CWcntl, ErrMask, dummy
+ControlWord equ word ptr CWmask ;Combine CWMask, CWcntl
+
+YFloatTemp equ FloatTemp
+YArgTemp equ ArgTemp
+
+.errnz (SWerr - Einstall -1)
+.errnz (SWcc - Einstall -2)
+.errnz (CURerr - Einstall -3)
+.errnz (CWcntl - CWmask -1)
+.errnz (ErrMask - CWmask -2)
+.errnz (dummy - CWmask -3)
+
+
+;*******************************************************************************
+;
+; Emulator stack area
+;
+;The top of stack pointer CURstk is initialized to the last register
+;in the list; on a real 8087, this corresponds to hardware register 0.
+;The stack grows toward lower addresses, so the first push (which is
+;hardware register 7) is stored into the second-to-last slot. This gives
+;the following relationship between hardware registers and memory
+;locations:
+;
+; BEGstk --> | reg 1 | (lowest memory address)
+; | reg 2 |
+; | reg 3 |
+; | reg 4 |
+; | reg 5 |
+; | reg 6 |
+; | reg 7 |
+; | reg 0 | <-- Initial top of stack (empty)
+; ENDstk -->
+;
+;This means that the wrap-around case on decrementing CURstk will not
+;occur until the last (8th) item is pushed.
+;
+;Note that the physical register numbers are only used in regard to
+;the tag word. All other operations are relative the current top.
+
+
+endif