00001 subttl em387.inc - Emulator Internal Format and Macros
00002 page
00003 ;***
00004 ;em387.inc - Emulator Internal Format and Macros
00005 ;
00006 ; Microsoft
Confidential
00007 ;
00008 ;
Copyright (c) Microsoft Corporation 1987, 1992
00009 ;
00010 ; All Rights Reserved
00011 ;
00012 ;Purpose:
00013 ; Emulator Internal Format and Macros
00014 ;
00015 ;Revision History: (also see emulator.hst)
00016 ;
00017 ; 8/23/91 TP New tag definitions
00018 ; 10/30/89 WAJ Added this header.
00019 ; 02/12/89 WAJ Added local stack frame definition.
00020 ;
00021 ;*******************************************************************************
00022
00023
00024 GetEmData macro dest,use
00025 ifdef _CRUISER
00026 mov dest,[edataSEG]
00027 elseifdef _DOS32EXT
00028 ifdifi <use>,<ax>
00029 push eax
00030 call _SelKrnGetEmulData
00031 mov dest,ax
00032 pop eax
00033 else
00034 call _SelKrnGetEmulData
00035 mov dest,ax
00036 endif
00037 endif
00038 endm
00039
00040
00041
00042 ;The SKIP macro optimizes very
short jumps by treating the code
00043 ;as data to a "cmp" instruction. This reduces jump time from
00044 ;8 clocks or more down to 2 clocks. It destroy the flags!
00045
00046 SKIP macro dist,target
00047 if dist eq 4
00048 db 3DH ;cmp eax,<immed>
00049 elseif dist eq 3
00050 db 3DH,0 ;cmp eax,<immed>
00051 elseif dist eq 2
00052 db 66H,3DH ;cmp ax,<immed>
00053 elseif dist eq 1
00054 db 3CH ;cmp al,<immed>
00055 else
00056 .err
00057 endif
00058
00059 ifnb <target>
00060 .erre $+dist eq target
00061 endif
00062
00063 endm
00064
00065 ;*******************************************************************************
00066 ;
00067 ; 80x87 environment structures.
00068 ;
00069 ;*******************************************************************************
00070
00071
00072 Env80x87_32 struc
00073 E32_ControlWord dw ?
00074 reserved1 dw ?
00075 E32_StatusWord dw ?
00076 reserved2 dw ?
00077 E32_TagWord dw ?
00078 reserved3 dw ?
00079 E32_CodeOff dd ?
00080 E32_CodeSeg dw ?
00081 reserved4 dw ?
00082 E32_DataOff dd ?
00083 E32_DataSeg dw ?
00084 reserved5 dw ?
00085 Env80x87_32 ends
00086
00087
00088 ;---------------------------------------------------------------------------
00089 ;
00090 ; Emulator Internal Format:
00091 ;
00092 ; +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11
00093 ; .___.___.___.___.___.___.___.___.___.___.___.___.
00094 ; ptr --> |___|___|___|___|___|___|___|___|___|___|___|___|
00095 ; lsb msb tag sgn exl exh
00096 ; |<--- mantissa --->| |exponent
00097 ;
00098 ; The mantissa contains the leading 1 before the decimal point in the hi
00099 ; bit of the msb. The exponent is not biased (
signed two's complement).
00100 ; The flag and tag bytes are as below.
00101 ;
00102 ; bit: 7 6 5 4 3 2 1 0
00103 ; .___.___.___.___.___.___.___.___.
00104 ; Sign: |___|_X_|_X_|_X_|_X_|_X_|_X_|_X_| X = unused
00105 ; ^
00106 ; SIGN
00107 ;
00108 ;
00109 ; bit: 7 6 5 4 3 2 1 0
00110 ; .___.___.___.___.___.___.___.___.
00111 ; Tag: |___|___|_X_|_X_|___|___|___|___| X = unused
00112 ; ^ ^ ^ ^ ^ ^
00113 ; | | | | | |
00114 ; 387 tag -+---+ | | | |
00115 ; | | | |
00116 ; Special enumeration -----+---+ | |
00117 ; | |
00118 ; Internal tag --------------------+---+
00119 ;
00120 ;There are four internal tags: Single, Double, Zero, Special. Within
00121 ;Special, there is NAN, Infinity, Denormal, and Empty.
00122 ;
00123 ;Representations for Single, Double, and Denormal are the same. Denormals
00124 ;are not actually kept denormalized, although they are rounded to the
00125 ;correct number of bits as if they were. The Single tag means the
00126 ;low 32 bits of the mantissa are zero. This allows optimizing multiply
00127 ;and divide.
00128 ;
00129 ;Tag Mantissa Exponent Sign
00130 ;---------------------------------------------------
00131 ;Zero 0 0 valid
00132 ;Empty ? ? ?
00133 ;NAN valid TexpMax valid
00134 ;Infinity 8000...000 TexpMax valid
00135 ;
00136 ;The mantissa for a NAN distinguishes between a quiet NAN (QNAN) or a
00137 ;signaling NAN (SNAN). If the bit below the MSB is 1, it is a QNAN,
00138 ;otherwise it is an SNAN.
00139 ;
00140
00141
00142 ;*******************************************************************************
00143 ;*
00144 ;* Stack entry defineds with a struct.
00145 ;*
00146 ;*******************************************************************************
00147
00148 EmStackEntry struc
00149 bMan0 db ?
00150 bMan1 db ?
00151 bMan2 db ?
00152 bMan3 db ?
00153 bMan4 db ?
00154 bMan5 db ?
00155 bMan6 db ?
00156 bMan7 db ?
00157 bTag db ?
00158 bSgn db ?
00159 bExpLo db ?
00160 bExpHi db ?
00161 EmStackEntry ends
00162
00163 wMantisa struc
00164 wMan0 dw ?
00165 wMan1 dw ?
00166 wMan2 dw ?
00167 wMan3 dw ?
00168 TagSgn dw ?
00169 wExp dw ?
00170 wMantisa ends
00171
00172
00173 lMantisa struc
00174 lManLo dd ?
00175 lManHi dd ?
00176 ExpSgn dd ?
00177 lMantisa ends
00178
00179 .erre size lMantisa eq size wMantisa
00180
00181 Reg87Len equ size lMantisa
00182
00183
00184 ;*******************************************************************************
00185 ;*
00186 ;* bFlags and bTag constants.
00187 ;*
00188 ;*******************************************************************************
00189
00190 ;The rules for internal number formats:
00191 ;
00192 ;1. Everything is either normalized or zero--unnormalized formats cannot
00193 ;get in. So if the high half mantissa is zero, the number must be all zero.
00194 ;
00195 ;2. Although the exponent bias is different, NANs and Infinities are in
00196 ;standard IEEE format - exponent is TexpMax, mantissa indicates NAN vs.
00197 ;infinity (mantissa for infinity is 800..000H).
00198 ;
00199 ;3. Denormals have an exponent less than TexpMin.
00200 ;
00201 ;4. If the low half of the mantissa is zero, it is tagged bTAG_SNGL
00202 ;
00203 ;5. Everything else is bTAG_VALID
00204
00205
00206 bSign equ 80h
00207
00208 ;These are the INTERNAL flags
00209 TAG_MASK equ 3
00210 TAG_SHIFT equ 2
00211 ;
00212 TAG_SNGL equ 0 ;SINGLE: low 32 bits are zero
00213 TAG_VALID equ 1
00214 TAG_ZERO equ 2
00215 TAG_SPCL equ 3 ;NAN, Infinity, Denormal, Empty
00216 ZEROorSPCL equ 2 ;Test for Zero or Special
00217 ;Enumeration of "special":
00218 TAG_SPCLBITS equ 0CH
00219 TAG_EMPTY equ TAG_SPCL+(0 shl TAG_SHIFT)
00220 TAG_INF equ TAG_SPCL+(1 shl TAG_SHIFT)
00221 TAG_NAN equ TAG_SPCL+(2 shl TAG_SHIFT)
00222 TAG_DEN equ TAG_SPCL+(3 shl TAG_SHIFT)
00223
00224 ;These are the tags used by the 387
00225 T87_VALID equ 0
00226 T87_ZERO equ 1
00227 T87_SPCL equ 2 ;NAN, Infinity, Denormal
00228 T87_EMPTY equ 3
00229
00230 ;The tag word for each stack entry combines these two tags.
00231 ;Internal tags are in the low bits, 387 tags are in the high two bits
00232 bTAG_VALID equ (T87_VALID shl 6) or TAG_VALID
00233 bTAG_SNGL equ (T87_VALID shl 6) or TAG_SNGL
00234 bTAG_ZERO equ (T87_ZERO shl 6) or TAG_ZERO
00235 bTAG_NAN equ (T87_SPCL shl 6) or TAG_NAN
00236 bTAG_INF equ (T87_SPCL shl 6) or TAG_INF
00237 bTAG_EMPTY equ (T87_EMPTY shl 6) or TAG_EMPTY
00238 bTAG_DEN equ (T87_SPCL shl 6) or TAG_DEN
00239 bTAG_NOPOP equ -1
00240
00241 bTAG_MASK equ 3
00242
00243
00244
00245 MantissaByteCnt equ 8
00246
00247 IexpBias equ 3FFFh ; 16,383
00248 IexpMax equ 7FFFh ; Biased Exponent for Infinity
00249 IexpMin equ 0 ; Biased Exponent for zero
00250
00251 DexpBias equ 3FFh ; 1023
00252 DexpMax equ 7FFh ; Biased Exponent for Infinity
00253 DexpMin equ 0 ; Biased Exponent for zero
00254
00255 SexpBias equ 07Fh ; 127
00256 SexpMax equ 0FFh ; Biased Exponent for Infinity
00257 SexpMin equ 0 ; Biased Exponent for zero
00258
00259 TexpBias equ 0 ; Bias for internal format of temp real
00260 UnderBias equ 24576 ; 3 * 2^13. Extra bias for unmasked underflow
00261 TexpMax equ IexpMax - IexpBias + TexpBias ;NAN/Infinity exponent
00262 TexpMin equ IexpMin-IexpBias+1 ;Smallest non-denormal exponent
00263
00264 ; Control Word Format CWcntl
00265
00266 RoundControl equ 0Ch
00267 RCchop equ 0Ch
00268 RCup equ 08h
00269 RCdown equ 04h
00270 RCnear equ 0
00271
00272 PrecisionControl equ 03h
00273 PC24 equ 0
00274 PC53 equ 02h
00275 PC64 equ 03h
00276
00277 ; Status Word Format SWcc
00278 C0 equ 01h
00279 C1 equ 02h
00280 C2 equ 04h
00281 C3 equ 40h
00282 ConditionCode equ C3 or C2 or C1 or C0
00283 CCgreater equ 0
00284 CCless EQU C0
00285 CCequal equ C3
00286 CCincomprable equ C3 or C2 or C0
00287
00288 RoundUp equ C1
00289 StackOverflow equ C1
00290
00291 ; Status Flags Format CURerr
00292
00293 Invalid equ 1h ; chip status flags
00294 Denormal equ 2h
00295 ZeroDivide equ 4h
00296 Overflow equ 8h
00297 Underflow equ 10h
00298 Precision equ 20h
00299 StackFlag equ 40h
00300 Summary equ 80h
00301
00302 SavedErrs equ Invalid or Denormal or ZeroDivide or Overflow or Underflow or Precision or StackFlag
00303 LongSavedFlags equ (CCincomprable SHL 16) OR (SavedErrs SHL 8) ; save C0, C2, C3 & errs
00304 ;*******************************************************************************
00305 ;*
00306 ;* Define emulator interrupt stack frame.
00307 ;*
00308 ;*******************************************************************************
00309
00310 StackFrame struc
00311 regEAX dd ?
00312 regECX dd ?
00313 regEDX dd ?
00314 regEBX dd ?
00315 regESP dd ?
00316 regEBP dd ?
00317 regESI dd ?
00318 regEDI dd ?
00319 OldCodeOff dd ?
00320 OldLongStatus dd ?
00321 regDS dd ?
00322 regEIP dd ?
00323 regCS dd ?
00324 regFlg dd ?
00325 StackFrame ends
00326
00327 regAX equ word ptr regEAX
00328
00329 ; .erre StatusWord eq LongStatusWord+1
00330 OldStatus equ word ptr OldLongStatus+1
00331
00332 ;*******************************************************************************
00333 ;*
00334 ;* Define emulator entry point macro.
00335 ;*
00336 ;*******************************************************************************
00337
00338 EM_ENTRY macro entryname
00339 ifdef NT386
00340 public ___&entryname
00341 ___&entryname:
00342 endif ; ifdef NT386
00343 endm
00344
00345 Em87Busy EQU 1
00346 Em87Idle EQU 0
00347
00348
00349
00350 ifdef NT386
00351 ;*********************************************************************;
00352 ; ;
00353 ; Emulator TEB Layout ;
00354 ; ;
00355 ;*********************************************************************;
00356
00357 .errnz (TbSystemReserved1 and 3) ; Make sure TB is dword aligned
00358
00359 Numlev equ 8 ; Number of stack registers
00360
00361 InitControlWord equ 37FH ; Default - Round near,
00362 ; 64 bits, all exceptions masked
00363
00364 DefaultControlWord equ 27FH ; Default - Round near,
00365 ; 53 bits, all exceptions masked
00366
00367 EmulatorTebData struc
00368 TbSystemResrvd db TbSystemReserved1 DUP (?) ; Skip to Emulator area
00369
00370 RoundMode dd ? ; Address of rounding routine
00371 SavedRoundMode dd ? ; For restoring RoundMode
00372 ZeroVector dd ? ; Address of sum-to-zero routine
00373 TransRound dd ? ; Round mode w/o precision
00374 Result dd ? ; Result pointer
00375 PrevCodeOff dd ?
00376 PrevDataOff dd ?
00377
00378 ;(See comment below on 'emulator stack area'
00379 CURstk dd ? ; init to start of stack
00380 BEGstk db (Numlev-1)*Reg87Len dup(?) ;Allocate register 1 - 7
00381 INITstk db Reg87Len dup(?)
00382
00383 FloatTemp db Reg87Len dup(?)
00384 ArgTemp db Reg87Len dup(?)
00385
00386 Einstall db 0 ; Emulator installed flag
00387 SWerr db ? ; Initially no exceptions (sticky flags)
00388 SWcc db ? ; Condition codes from various operations
00389 CURerr db ? ; initially 8087 exception flags clear
00390 ; this is the internal flag reset after
00391 ; each operation to detect per instruction
00392 ; errors
00393 CWmask db ? ; exception masks
00394 CWcntl db ? ; arithmetic control flags
00395 ErrMask db ?
00396 dummy db ?
00397 EmulatorTebData ends
00398
00399 ENDstk equ byte ptr INITstk + Reg87Len
00400 LongStatusWord equ dword ptr Einstall ;Combine Einstall, CURerr, StatusWord
00401 StatusWord equ word ptr SWerr ;Combine SWerr, SWcc
00402 CurErrCond equ word ptr SWcc ;Combine SWcc, CURErr
00403 LongControlWord equ dword ptr CWmask ;Combine CWMask, CWcntl, ErrMask, dummy
00404 ControlWord equ word ptr CWmask ;Combine CWMask, CWcntl
00405
00406 YFloatTemp equ FloatTemp
00407 YArgTemp equ ArgTemp
00408
00409 .errnz (SWerr - Einstall -1)
00410 .errnz (SWcc - Einstall -2)
00411 .errnz (CURerr - Einstall -3)
00412 .errnz (CWcntl - CWmask -1)
00413 .errnz (ErrMask - CWmask -2)
00414 .errnz (dummy - CWmask -3)
00415
00416
00417 ;*******************************************************************************
00418 ;
00419 ; Emulator stack area
00420 ;
00421 ;The top of stack pointer CURstk is initialized to the last register
00422 ;in the list; on a real 8087, this corresponds to hardware register 0.
00423 ;The stack grows toward lower addresses, so the first push (which is
00424 ;hardware register 7) is stored into the second-to-last slot. This gives
00425 ;the following relationship between hardware registers and memory
00426 ;locations:
00427 ;
00428 ; BEGstk --> | reg 1 | (lowest memory address)
00429 ; | reg 2 |
00430 ; | reg 3 |
00431 ; | reg 4 |
00432 ; | reg 5 |
00433 ; | reg 6 |
00434 ; | reg 7 |
00435 ; | reg 0 | <-- Initial top of stack (empty)
00436 ; ENDstk -->
00437 ;
00438 ;This means that the wrap-around case on decrementing CURstk will not
00439 ;occur until the last (8th) item is pushed.
00440 ;
00441 ;Note that the physical register numbers are only used in regard to
00442 ;the tag word. All other operations are relative the current top.
00443
00444
00445 endif