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