386log.inc

来自「开放源码的编译器open watcom 1.6.0版的源代码」· INC 代码 · 共 322 行 · 第 1/2 页

INC
322
字号
;*****************************************************************************
;*
;*                            Open Watcom Project
;*
;*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;*  ========================================================================
;*
;*    This file contains Original Code and/or Modifications of Original
;*    Code as defined in and that are subject to the Sybase Open Watcom
;*    Public License version 1.0 (the 'License'). You may not use this file
;*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;*    provided with the Original Code and Modifications, and is also
;*    available at www.sybase.com/developer/opensource.
;*
;*    The Original Code and all software distributed under the License are
;*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;*    NON-INFRINGEMENT. Please see the License for the specific language
;*    governing rights and limitations under the License.
;*
;*  ========================================================================
;*
;* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
;*               DESCRIBE IT HERE!
;*
;*****************************************************************************


        modstart  386log

        xref    __FLDAC         ; add constant from stack
        xref    ___LDA          ; add
        xref    __FLDS          ; subtract
        xref    __FLDD          ; divide
        xref    ___LDD          ; divide
        xref    __FLDM          ; multiply
        xref    ___LDM          ; multiply
        xref    __I4LD          ; convert long to long double
        xref    __EvalPoly      ; evaluate polynomial
        xref    __poly          ; evaluate polynomial
        xref    __OddPoly       ; oddpoly

        xdefp   __log           ; calc log(fac1)
        xdefp   __fyl2x         ; calc. log2([eax]) * [edx]
        xdefp   __fyl2xp1       ; calc. log2([ax]+1.0) * [dx]

;;one_over_loge2 dt      1.4426950408889634075

        align   2
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    EBX             ; save EBX
        push    EDX             ; save address for result
        push    EAX             ; save address of operand
        push    ONE_EXP         ; point to 1.0
        push    ONE_HW          ; ...
        push    ONE_LW          ; ...
        mov     EBX,EAX         ; place for result
        call    __FLDAC         ; calc. x = x + 1.0
        pop     EAX             ; restore address of operand
        pop     EDX             ; restore address for result
        pop     EBX             ; restore EBX
;
;       fall into __fyl2x routine
;
__fyl2xp1 endp


        defp    __fyl2x
        push    EDI                     ; save registers
        push    ESI                     ; ...
        push    EDX                     ; ...
        push    ECX                     ; ...
        push    EBX                     ; ...
        push    EAX                     ; save address of operand
        call    __log                   ; calc. ln([eax])
        pop     EAX                     ; restore address of ln([eax])
        mov     EBX,EDX                 ; point to place for result
        push    EDX                     ; save address of result
        call    __FLDM                  ; multiply
        pop     EDI                     ; restore address of result
        mov     SI,8[EDI]               ; load x
        mov     ECX,4[EDI]              ; ...
        mov     EBX,[EDI]               ; ...
        shl     ESI,16                  ; shift exponent to top
        mov     SI,LN2R_EXP             ; load 1/loge(2)
        mov     EDX,LN2R_HW             ; ...
        mov     EAX,LN2R_LW             ; ...
        call    ___LDM                  ; calc x * 1/loge(2)
        mov     [EDI],EAX               ; store result
        mov     4[EDI],EDX              ; ...
        mov     8[EDI],SI               ; ...
        pop     EBX                     ; restore EBX
        pop     ECX                     ; restore ECX
        pop     EDX                     ; restore EDX
        pop     ESI                     ; restore ESI
        pop     EDI                     ; restore EDI
        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    EDI                     ; save registers
        push    ESI                     ; ...
        push    EDX                     ; ...
        push    ECX                     ; ...
        push    EBX                     ; ...
        sub     ECX,ECX                 ; zero ECX
        mov     CX,8[EAX]               ; 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     EDI,EAX                 ; save address of argument
        mov     EDX,00003FFEh           ; set exponent
        sub     ECX,00003FFEh           ; ...
        push    ECX                     ; save exponent
        mov     8[EDI],DX               ; set exponent in the fraction

;;        z = x - .5;
        mov     EAX,[EDI]               ; load x
        mov     EDX,4[EDI]              ; ...
        mov     ESI,0BFFE3FFEh          ; and -.5
        mov     ECX,080000000h          ; ...
        sub     EBX,EBX                 ; ...
        call    ___LDA                  ; calc. z = x - .5

;;        if( x > sqrt_of_half ) {
        cmp     word ptr 8[EDI],3FFEh           ; if x > sqrt(.5)
        _if     e                               ; ...
          cmp   dword ptr 4[EDI],0B504F333h     ; ...

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?