ldfd086.asm

来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 205 行

ASM
205
字号
ifndef EMUL_VERSION
ifdef _BUILDING_MATHLIB
EMUL_VERSION equ 0
else
EMUL_VERSION equ 1
endif
endif

if EMUL_VERSION eq 0

include mdef.inc
include struct.inc
include xception.inc

        xref    F8OverFlow

        modstart    ldfd086, word


        xdefp   __iLDFD
else
        xdefp   __EmuLDFD
endif

;       convert long double to double
;if EMUL_VERSION eq 0
; input:
;       SS:AX - pointer to long double
;       SS:DX - pointer to double
;else
; input:
;       DS:BX - pointer to long double
; output:
;       AX:BX:CX:DX - double
;endif
;
if EMUL_VERSION eq 0
__iLDFD proc
        push    BX              ; save registers
        push    CX              ; ...
        push    DI              ; ...
        push    BP              ; ...
        push    DX              ; save return pointer
        mov     BP,AX
        mov     DI,8[BP]        ; get exponent and sign
        mov     AX,6[BP]        ; get fraction
        mov     CX,2[BP]        ; get fraction
        mov     DX, [BP]        ; get fraction
        mov     BX,4[BP]        ; get fraction
else
__EmuLDFD  proc    near
        push    DI              ; save di
        mov     DI,8[BX]        ; get exponent and sign
        mov     AX,6[BX]        ; get fraction
        mov     CX,2[BX]        ; get fraction
        mov     DX, [BX]        ; get fraction
        mov     BX,4[BX]        ; get fraction
endif
        test    DH,04h          ; if have to round
        _if     ne              ; - then
          add   DH,08h          ; - round up
          adc   CX,0            ; - ...
          adc   BX,0            ; - ...
          adc   AX,0            ; - ...
          _if   c               ; - if exponent needs adjusting
            mov   AH,80h        ; - - set fraction
            inc   DI            ; - - increment exponent
    ;  check for overflow
          _endif                ; - endif
          test  DX,03FFH        ; - if half way between
          _if   e               ; - then
            and   DH,0F0h       ; - - mask off bottom bit
          _endif                ; - endif
        _endif                  ; endif
        mov     DL,DH           ; shift fraction right by 8
        mov     DH,CL           ; ...
        mov     CL,CH           ; ...
        mov     CH,BL           ; ...
        mov     BL,BH           ; ...
        mov     BH,AL           ; ...
        mov     AL,AH           ; ...
        mov     AH,0            ; ...
        _shl    DI,1            ; get sign
        rcr     AX,1            ; shift number right one more is 9
        rcr     BX,1            ; ...
        rcr     CX,1            ; ...
        rcr     DX,1            ; ...
        shr     AL,1            ; and one more is 10
        rcr     BX,1            ; ...
        rcr     CX,1            ; ...
        rcr     DX,1            ; ...
        shr     AL,1            ; and one more is 11
        rcr     BX,1            ; ...
        rcr     CX,1            ; ...
        rcr     DX,1            ; ...
        add     DI,(03FFh-3FFFh) shl 1  ; change bias to double format
        cmp     DI,07FFh shl 1  ; if exponent is not too large or negative
        _if     b               ; then
          _shl  DI,1            ; - get exponent into position
          _shl  DI,1            ; - ...
          _shl  DI,1            ; - ...
          _if   e               ; - if denormal number          14-jul-90
            shr   AL,1          ; - - shift right one more time
            rcr   BX,1          ; - - ...
            rcr   CX,1          ; - - ...
            rcr   DX,1          ; - - ...
          _endif                ; - endif
          and   AL,0FH          ; - get rid of implied one bit
          or    AX,DI           ; - merge in exponent
if EMUL_VERSION eq 0
          jmp   _ret_ldfd       ; - return
else
          pop   DI              ; - restore di
          ret                   ; - return
endif
        _endif                  ; endif
        cmp     DI,8800h        ; if exponent >= 8800h (underflow)
        _if     ae              ; then
          sar   DI,1            ; - align exponent
          cmp   DI,-52          ; - if in the denormal range  02-jul-90
          _if   ge              ; - then
            dec   DI            ; - - adjust exponent for 1 more shift
            _loop               ; - - loop (denormalize number)
              cmp   DI,-8       ; - - - quit if less than 8
              _quif g           ; - - - ...
              mov   DL,DH       ; - - - shift fraction right by 8
              mov   DH,CL       ; - - - ...
              mov   CL,CH       ; - - - ...
              mov   CH,BL       ; - - - ...
              mov   BL,BH       ; - - - ...
              mov   BH,AL       ; - - - ...
              mov   AL,0        ; - - - ...
              add   DI,8        ; - - - adjust exponent
            _endloop            ; - - endloop
            _loop               ; - - loop (denormalize number)
              or    DI,DI       ; - - - quit when exponent is 0
              _quif e           ; - - - ...
              shr   AL,1        ; - - - shift fraction right 1 bit
              rcr   BX,1        ; - - - ...
              rcr   CX,1        ; - - - ...
              rcr   DX,1        ; - - - ...
              inc   DI          ; - - - increment exponent
            _endloop            ; - - endloop
if EMUL_VERSION eq 0
            jmp   _ret_ldfd     ; - - return
else
            pop   DI            ; - - restore di
            ret                 ; - - return
endif
          _endif                ; - endif
          sub   AX,AX           ; - set result to zero
          sub   BX,BX           ; - ...
          sub   CX,CX           ; - ...
          sub   DX,DX           ; - ...
if EMUL_VERSION eq 0
          jmp   _ret_ldfd       ; - return
else
          pop   DI              ; - restore di
          ret                   ; - return
endif
        _endif                  ; endif
        or      AX,7FF0h        ; set infinity (or NaN)
        cmp     DI,87FEh        ; if not infinity or NaN
        _if     ne              ; then (overflow)
          push  AX              ; - save it
          push  DX              ; - save it
          push  BX              ; - save it
          push  CX              ; - save it
          call  F8OverFlow      ; - set OVERFLOW exception
          pop   CX              ; - restore it
          pop   BX              ; - restore it
          pop   DX              ; - restore it
          pop   AX              ; - restore it
        _endif                  ; endif
if EMUL_VERSION eq 0
_ret_ldfd:                      ; function epilogue
        pop     BP              ; fetch return pointer
        mov     6[BP],AX        ; store return value
        mov     4[BP],BX        ; ...
        mov     2[BP],CX        ; ...
        mov     [BP],DX         ; ...
        pop     BP              ; restore registers
        pop     DI              ; ...
        pop     CX              ; ...
        pop     BX              ; ...
        ret                     ; return
__iLDFD endp
else
        pop     DI              ; restore di
        ret                     ; return
__EmuLDFD  endp
endif

if EMUL_VERSION eq 0

        endmod

        endf    equ end
else
        endf    equ <>

endif

endf

⌨️ 快捷键说明

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