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