e86log.inc
来自「开放源码的编译器open watcom 1.6.0版的源代码」· INC 代码 · 共 270 行
INC
270 行
modstart e86log
xref __FLDA ; add
xref __FLDS ; subtract
xref __FLDD ; divide
xref __FLDM ; multiply
xref __FLDAC ; add
xref __FLDSC ; subtract
xref __FLDMC ; multiply
xref __I4LD ; convert long to long double
xref __EvalPoly ; evaluate polynomial
xref __Poly ; poly
xdefp __log ; calc log(fac1)
xdefp __fyl2x ; calc. log2([ax]) * [dx]
xdefp __fyl2xp1 ; calc. log2([ax]+1.0) * [dx]
one_over_loge2 dt 1.4426950408889634075
OneHalf dt 0.5
logconst1 dw 0,0,0,0b180h,3ffeh ; 355./512.
logconst2 dw 435ch,0865h,82e3h,0de80h,0bff2h
APoly dt -0.78956112887491257267
dt 0.16383943563021534222e+2
dt -0.64124943423745581147e+2
BPoly dt 1.0
dt -0.35667977739034646171e+2
dt 0.31203222091924532844e+3
dt -0.76949932108494879777e+3
defp __fyl2xp1
push DX ; save registers
push BX ; ...
push DI ; ...
mov DI,AX ; save pointer to operand
push word ptr 8[DI] ; duplicate argument on stack
push word ptr 6[DI] ; ...
push word ptr 4[DI] ; ...
push word ptr 2[DI] ; ...
push word ptr [DI] ; ...
mov DI,SP ; get pointer to argument
push AX ; push addr of old argument
push DS ; ...
push SS ; set DS=SS
pop DS ; ...
mov AX,DI ; point to pushed operand
mov DX,offset __One ; point to 1.0
mov BX,DI ; put answer back in operand
call __FLDAC ; add 1.0 to x
pop DS ; restore address of result
pop DI ; ...
pop word ptr [DI] ; copy value into result
pop word ptr 2[DI] ; ...
pop word ptr 4[DI] ; ...
pop word ptr 6[DI] ; ...
pop word ptr 8[DI] ; ...
mov AX,DI ; restore address of operand
pop DI ; restore DI
pop BX ; restore BX
pop DX ; restore DX
;
; fall into __fyl2x routine
;
__fyl2xp1 endp
defp __fyl2x
push DX ; save registers
push BX ; ...
push DI ; ...
mov DI,DX ; save pointer to operand
push word ptr 8[DI] ; duplicate argument on stack
push word ptr 6[DI] ; ...
push word ptr 4[DI] ; ...
push word ptr 2[DI] ; ...
push word ptr [DI] ; ...
mov DI,SP ; get pointer to argument
push DX ; push addr of old argument
push DS ; ...
mov DX,DI ; point to pushed operand
mov DI,AX ; save pointer to operand
push word ptr 8[DI] ; duplicate argument on stack
push word ptr 6[DI] ; ...
push word ptr 4[DI] ; ...
push word ptr 2[DI] ; ...
push word ptr [DI] ; ...
push SS ; set DS=SS
pop DS ; ...
mov AX,SP ; point to pushed operand
call __log ; calc. ln([ax])
mov AX,SP ; get address of ln([ax])
mov BX,DX ; point to place for result
push DX ; save address of result
call __FLDM ; multiply
pop AX ; restore address of result
mov DX,offset one_over_loge2 ; point to 1/loge(2)
mov BX,AX ; address for result
call __FLDMC ; do the multiply
add SP,10 ; remove temp from stack
pop DS ; restore address of result
pop DI ; ...
pop word ptr [DI] ; copy value into result
pop word ptr 2[DI] ; ...
pop word ptr 4[DI] ; ...
pop word ptr 6[DI] ; ...
pop word ptr 8[DI] ; ...
pop DI ; restore DI
pop BX ; restore BX
pop DX ; restore DX
ret ; return
__fyl2x endp
;;void __log( long double *x )
;;/**************************/
;;{
;; int exp;
;; double z;
;; if( x <= 0.0 ) {
;; x = _matherr( x == 0.0 ? SING : DOMAIN, "log", &x, &x, -HUGE_VAL );
;; } else {
defp __log
push BP ; save registers
push DI ; ...
push SI ; ...
push DX ; ...
push CX ; ...
push BX ; ...
mov DI,AX ; save address of argument
sub CX,CX ; zero ECX
mov CX,8[DI] ; get exponent
_guess ; guess: x > 0.0
or CX,CX ; - quit if negative
_quif s ; - ...
; check for 0
_admit ; admit: x <= 0.0
; ; - error
_endguess ; endguess
;; x = frexp( x, &exp );
mov DX,3FFEh ; set exponent
sub CX,3FFEh ; ...
push CX ; save exponent
mov 8[DI],DX ; set exponent in the fraction
sub SP,10*3 ; allocate temporaries
mov BP,SP ; get access to stack
add BP,10 ; point to z
;; z = x - .5;
mov AX,DI ; calc. z = x - .5
mov DX,offset OneHalf ; .5
mov BX,BP ; z
call __FLDSC ; ...
;; if( x > sqrt_of_half ) {
cmpconst DI,3FFEh,0B504h,0F333h,0F9DEh,06484h
_if a ; if x > sqrt(.5)
;; z -= .5;
;; } else {
;; x = z;
;; --exp;
;; }
mov AX,BP ; - calc. z = z - .5
mov DX,offset OneHalf ; - ...
mov BX,BP ; - ...
call __FLDSC ; - ...
mov AX,DI ; - point to x
_else ; else
mov AX,BP ; - point to z (set x = z)
dec word ptr 20[BP] ; - decrement exponent
_endif ; endif
;; z = z / (x * .5 + .5);
; calc. temp = x * .5
mov DX,offset OneHalf ; ...
mov BX,SP ; ...
call __FLDMC ; ...
mov AX,SP ; calc. temp = temp + .5
mov DX,offset OneHalf ; ...
mov BX,SP ; ...
call __FLDAC ; ...
mov AX,BP ; calc. z = z / temp
mov DX,SP ; ...
mov BX,BP ; ...
call __FLDD ; ...
;; x = z * z;
mov AX,BP ; calc. x = z * z
mov DX,BP ; ...
mov BX,DI ; ...
call __FLDM ; ...
;; x = z + z * x * _EvalPoly( x, APoly, 2 ) / _EvalPoly( x, BPoly, 3 );
mov AX,DI ; calc. _EvalPoly(x,BPoly,3)
mov DX,offset BPoly ; ...
mov BX,3 ;
mov CX,SP ; temp1
call __Poly ; evaluate polynomial
mov AX,DI ; calc. _EvalPoly(x,APoly,2)
mov DX,offset APoly ; ...
mov BX,2 ;
lea CX,10[BP] ; temp2
call __Poly ; evaluate polynomial
lea AX,10[BP] ; temp2
mov DX,SP ; temp1
mov BX,SP ; calc. temp1 = APoly / BPoly
call __FLDD ; ...
mov AX,DI ; calc. temp1 = x * APoly/BPoly
mov DX,SP ; ...
mov BX,SP ; ...
call __FLDM ; calc. x * Apoly / BPoly
mov AX,BP ; calc. temp1= z * x*APoly/BPoly
mov DX,SP ; ...
mov BX,SP ; ...
call __FLDM ; calc. z * x * Apoly / BPoly
mov AX,BP ; calc. x = z + z*x*APoly/BPoly
mov DX,SP ; ...
mov BX,DI ; ...
call __FLDA ; calc. x = z + z*x*Apoly/BPoly
;; if( exp != 0 ) {
;; z = exp;
;; x = (z * C2 + x) + z * C1;
;; }
mov AX,20[BP] ; get exponent
or AX,AX ; if not zero
_if ne ; then
cwd ; - convert to long
mov BX,BP ; - calc. z = exp
call __I4LD ; - ...
mov AX,BP ; - calc. temp = z * const2
mov DX,offset logconst2 ; - ...
mov BX,SP ; - ...
call __FLDMC ; - ...
mov AX,SP ; - calc. x = temp + x
mov DX,DI ; - ...
mov BX,DI ; - ...
call __FLDA ; - ...
mov AX,BP ; - calc. temp = z * const1
mov DX,offset logconst1 ; - ...
mov BX,SP ; - ...
call __FLDMC ; - ...
mov AX,SP ; - calc. x = temp + x
mov DX,DI ; - ...
mov BX,DI ; - ...
call __FLDA ; - ...
_endif ; endif
;; }
;; return( x );
;;}
add SP,(10*3)+2 ; remove temporaries
pop BX ; restore registers
pop CX ; ...
pop DX ; ...
pop SI ; ...
pop DI ; ...
pop BP ; ...
ret ; return
__log endp
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?