windows-nt/Source/XPSP1/NT/base/crts/fpw32/tran/i386/87disp.asm

299 lines
7.4 KiB
NASM
Raw Normal View History

2020-09-26 03:20:57 -05:00
page ,132
title 87disp - common transcendental dispatch routine
;***
;87disp.asm - common transcendental dispatch routine (80x87/emulator version)
;
; Copyright (c) 1984-2001, Microsoft Corporation. All rights reserved.
;
;Purpose:
; Common transcendental dispatch routine (80x87/emulator version)
;
;Revision History:
; 07-07-84 GFW initial version
; 11-20-85 GFW mask overflow/underflow/precision exceptions;
; fixed affine/projective infinity confusion
; 09-12-86 BCM added _Flanguage to distinguish languages
; 10-21-86 BCM use _cpower rather than _Flanguage to
; distinguish C and FORTRAN exponentiation semantics
; 06-11-87 GFW faster dispatch code - all in-line
; 10-26-87 BCM minor changes for new cmacros.inc
; 04-25-88 WAJ _cpower is now on stack for MTHREAD
; 08-24-88 WAJ 386 version
; 02-01-92 GDP ported to NT
; 09-06-94 CFW Replace MTHREAD with _MT.
;
;*******************************************************************************
.xlist
include cruntime.inc
include mrt386.inc
include elem87.inc
.list
.data
globalT _indefinite, 0FFFFC000000000000000R
globalT _piby2, 03FFFC90FDAA22168C235R
staticQ One, 03FF0000000000000R
ifndef _MT ; by default assume C pow() semantics
globalB _cpower, 1 ; if zero, assume FORTRAN (or other) exponentiation
endif ;_MT ; semantics
labelB XAMtoTagTab
; C2 C1 C0 C3 Meaning Meaning Tag 0
db 2 * ISIZE ; 0 0 0 0 +Unnormal => NAN 10 0
db 1 * ISIZE ; 0 0 0 1 +Zero => Zero 01 0
db 2 * ISIZE ; 0 0 1 0 +NAN => NAN 10 0
db 2 * ISIZE ; 0 0 1 1 Empty => NAN 10 0
db 2 * ISIZE ; 0 1 0 0 -Unnormal => NAN 10 0
db 1 * ISIZE ; 0 1 0 1 -Zero => Zero 01 0
db 2 * ISIZE ; 0 1 1 0 -NAN => NAN 10 0
db 2 * ISIZE ; 0 1 1 1 Empty => NAN 10 0
db 0 * ISIZE ; 1 0 0 0 +Normal => Valid 00 0
db 1 * ISIZE ; 1 0 0 1 +Denormal => Zero 01 0
db 3 * ISIZE ; 1 0 1 0 +Infinity => Infinity 11 0
db 2 * ISIZE ; 1 0 1 1 Empty => NAN 10 0
db 0 * ISIZE ; 1 1 0 0 -Normal => Valid 00 0
db 1 * ISIZE ; 1 1 0 1 -Denormal => Zero 01 0
db 3 * ISIZE ; 1 1 1 0 -Infinity => Infinity 11 0
db 2 * ISIZE ; 1 1 1 1 Empty => NAN 10 0
CODESEG
xamTOS macro
cmp [rdx].fnumber, OP_SQRT ; check for sqrt
JSNE cwdefault
mov bx, word ptr (DSF.savCntrl)
or bh, 2 ; set precision control to 53 bits
and bh, 0feh
mov bl, 03fh ; mask exceptions
jmp setcw
lab cwdefault
mov bx, 133fh ; default cw
lab setcw
mov DSF.setCntrl, bx ; set new control word
fldcw DSF.setCntrl ; load new control word
mov rbx, dataoffset XAMtoTagTab ; Prepare for XLAT
fxam
mov DSF.Function, rdx ; save function jmp table address
fstsw DSF.StatusWord
mov DSF.ErrorType, 0 ; clear error code
endm
comdisp macro
CBI
and rcx, 0404h ; clear all but signs from CX
mov rbx, rdx
add rbx, rax
add rbx, size funtab ; skip over name, error vals, etc.
jmp [rbx] ; jmp to function
endm
; Will dispatch to the special case routines for the single argument
; transcendental functions. It assumes on entry that the 8087 stack
; has the argument on the top of its stack and that DX has been set
; to the address of the dispatch table (which should be in Tag order).
; This routine will FXAM the top of the 8087 stack, generate Tag info
; from the condition code, and jump to the corresponding dispatch table
; entry. In the process of creating the offset for the XLAT instruction
; bit 2 of CL will be loaded with the sign of the argument. DI may not
; be used in any computations.
_trandisp1 proc near
xamTOS ; setup control word and check TOS
fwait
mov cl, CondCode
shl cl, 1
sar cl, 1
rol cl, 1
mov al, cl
and al, 0fh
xlat
comdisp
_trandisp1 endp
; Will dispatch to the special case routines for the double argument
; transcendental functions. It assumes on entry that the 8087 has arg1
; next to the top and arg2 on top of the 8087 stack and that DX has
; been set to the address of the dispatch table (which should be in
; Tag-arg1,Tag-arg2 order). This routine will FXAM the top two
; registers of the 8087 stack,generate Tag info from the condition
; codes, and jump to the corresponding dispatch table entry. In the
; process of creating the offsets for the XLAT statements bit 2 of
; CH and bit 2 of CL will be loaded with the signs of the arguments
; next to the top and on top, respectively, of the 8087 stack. DI may
; not be used in any computations.
_trandisp2 proc near
xamTOS ; setup control word and check TOS
fxch
mov cl, CondCode
fxam
fstsw DSF.StatusWord
fxch
mov ch, CondCode
shl ch, 1
sar ch, 1
rol ch, 1
mov al, ch
and al, 0fh
xlat
mov ah, al
shl cl, 1
sar cl, 1
rol cl, 1
mov al, cl
and al, 0fh
xlat
shl ah, 1
shl ah, 1
or al, ah
comdisp
_trandisp2 endp
page
;----------------------------------------------------------
;
; SPECIAL CASE RETURN FUNCTIONS
;
;----------------------------------------------------------
;
; INPUTS - The signs of the last, second to last
; arguments are in CH, CL respectively.
;
; OUTPUT - The result is the stack top.
;
;----------------------------------------------------------
labelNP _rttospopde, PUBLIC
call setDOMAIN
labelNP _rttospop, PUBLIC
fxch ; remove ST(1)
labelNP _rtnospop, PUBLIC
fstp st(0) ; remove ST(0)
labelNP _rttosnpop, PUBLIC
ret ; return TOS
labelNP _rtnospopde, PUBLIC
call setDOMAIN
jmp _rtnospop
;----------------------------------------------------------
labelNP _rtzeropop, PUBLIC
fstp st(0) ; remove ST(0)
labelNP _rtzeronpop, PUBLIC
fstp st(0) ; remove ST(0)
fldz ; push 0.0 onto stack
ret
;----------------------------------------------------------
labelNP _rtonepop, PUBLIC
fstp st(0) ; remove ST(0)
labelNP _rtonenpop, PUBLIC
fstp st(0) ; remove ST(0)
fld1 ; push 1.0 onto stack
ret
;----------------------------------------------------------
isQNAN macro
fstp DSF.Fac ; use ten byte storage
fld DSF.Fac
test byte ptr [DSF.Fac+7], 40h ; Test for QNaN or SNaN
endm
labelNP _tosnan1, PUBLIC ; ST(0) is a NaN
isQNAN
JSZ _tossnan1
mov DSF.Errortype, DOMAIN_QNAN
ret
lab _tossnan1
mov DSF.Errortype, DOMAIN
fadd [One] ; Convert SNaN to QNaN
ret
labelNP _nosnan2, PUBLIC ; ST(1) is a NaN
fxch
labelNP _tosnan2, PUBLIC ; ST(0) is a NaN
isQNAN
JSZ _tossnan2
mov DSF.Errortype, DOMAIN_QNAN
jmp _tosnan2ret
lab _tossnan2
mov DSF.Errortype, DOMAIN
lab _tosnan2ret
fadd ; Propagate NaN and pop
ret
labelNP _nan2, PUBLIC
isQNAN
JSZ _snan2
fxch
isQNAN
JSZ _snan2
mov DSF.Errortype, DOMAIN_QNAN
jmp _nan2ret
lab _snan2
mov DSF.Errortype, DOMAIN
lab _nan2ret
fadd ; Propagate NaN and pop
ret
;----------------------------------------------------------
labelNP _rtindfpop, PUBLIC
fstp st(0) ; remove ST(0)
labelNP _rtindfnpop, PUBLIC
fstp st(0) ; remove ST(0)
fld [_indefinite] ; push real indefinite onto stack
cmp DSF.ErrorType, 0 ; if error set
JSG retj ; must be SING, don't set DOMAIN
labelNP _rttosnpopde, PUBLIC
lab setDOMAIN
mov DSF.ErrorType, DOMAIN
lab retj
or cl, cl ; test sign in cl
ret
;----------------------------------------------------------
labelNP _rtchsifneg, PUBLIC
or cl, cl ; if arg is negative
JSZ chsifnegret ; negate top of stack
fchs
lab chsifnegret
ret
end