e86ldi8.inc

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

INC
92
字号
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
;<>
;<> __LDI8 - convert long double to 8-byte integer
;<>          it is assumed that the long double has already been rounded
;<>          to an integer by calling __frndint.
;<>     input:  AX - pointer to operand
;<>     output: CX:BX:DX:AX 8-byte integer
;<>
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>

        modstart e86ldi8

        xdefp   __LDI8

        defp    __LDI8
        mov     BX,AX           ; point to operand
        mov     AX,8[BX]        ; get exponent
        and     AX,7FFFh        ; isolate exponent
        cmp     AX,3FFEh        ; if number < .5
        _if     b               ; then
          sub   AX,AX           ; - result is 0
          cwd                   ; - ...
          mov   BX,AX           ; - ...
          mov   CX,AX           ; - ...
          ret                   ; - return
        _endif                  ; endif
        cmp     AX,403Eh        ; if number too large
        _if     ae              ; then
          mov   CX,8000h        ; - return largest number
          sub   AX,AX           ; - ...
          mov   BX,AX           ; - ...
          mov   DX,AX           ; - ...
          ret                   ; - return
        _endif                  ; endif
        push    SI              ; save SI
        sub     AX,403Eh        ; calculate # of bits to shift
        neg     AX              ; ...
        mov     SI,AX           ; get shift count
        push    8[BX]           ; save exponent and sign
        mov     CX,6[BX]        ; get fraction
        mov     DX,2[BX]        ; ...
        mov     AX,[BX]         ; ...
        mov     BX,4[BX]        ; ...
        _loop                   ; loop
          cmp   SI,16           ; - quit if < 16 bits to shift
          _quif l               ; - ...
          mov   AX,DX           ; - shift right 16
          mov   DX,BX           ; - ...
          mov   BX,CX           ; - ...
          sub   CX,CX           ; - zero high word
          sub   SI,16           ; - adjust shift count
        _endloop                ; endloop
        cmp     SI,8            ; if >= 8 bits to shift
        _if     ge              ; then
          mov   AL,AH           ; - shift right 8 bits
          mov   AH,DL           ; - ...
          mov   DL,DH           ; - ...
          mov   DH,BL           ; - ...
          mov   BL,BH           ; - ...
          mov   BH,CL           ; - ...
          mov   CL,CH           ; - ...
          mov   CH,0            ; - ...
          sub   SI,8            ; - adjust shift count
        _endif                  ; endif
        or      SI,SI           ; if some bits to shift
        _if     ne              ; then
          _loop                 ; - loop (bit shift)
            shr   CX,1          ; - - shift right 1 bit
            rcr   BX,1          ; - - ...
            rcr   DX,1          ; - - ...
            rcr   AX,1          ; - - ...
            dec   SI            ; - - decrement shift count
          _until  e             ; - until done
        _endif                  ; endif
;
        pop     SI              ; get sign of the value
        or      SI,SI           ; if negative
        _if     s               ; then
          not   CX              ; - negate the value
          not   BX              ; - ...
          not   DX              ; - ...
          neg   AX              ; - ...
          sbb   DX,-1           ; - ...
          sbb   BX,-1           ; - ...
          sbb   CX,-1           ; - ...
        _endif                  ; endif
        pop     SI              ; restore SI
        ret                     ; return to caller

        endproc __LDI8

⌨️ 快捷键说明

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