Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ;*****************************************************************************
  2. ;*
  3. ;*                            Open Watcom Project
  4. ;*
  5. ;*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
  6. ;*
  7. ;*  ========================================================================
  8. ;*
  9. ;*    This file contains Original Code and/or Modifications of Original
  10. ;*    Code as defined in and that are subject to the Sybase Open Watcom
  11. ;*    Public License version 1.0 (the 'License'). You may not use this file
  12. ;*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
  13. ;*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
  14. ;*    provided with the Original Code and Modifications, and is also
  15. ;*    available at www.sybase.com/developer/opensource.
  16. ;*
  17. ;*    The Original Code and all software distributed under the License are
  18. ;*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  19. ;*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
  20. ;*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
  21. ;*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
  22. ;*    NON-INFRINGEMENT. Please see the License for the specific language
  23. ;*    governing rights and limitations under the License.
  24. ;*
  25. ;*  ========================================================================
  26. ;*
  27. ;* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
  28. ;*               DESCRIBE IT HERE!
  29. ;*
  30. ;*****************************************************************************
  31.  
  32.  
  33. ;
  34. include mdef.inc
  35. include struct.inc
  36.  
  37.         modstart        fdi4386
  38.  
  39.         xdefp   __FDI4
  40.         xdefp   __RDI4
  41.  
  42.         xdefp   __FDU4
  43.         xdefp   __RDU4
  44.  
  45. ;[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
  46. ;[]
  47. ;[] __FDU4      convert double float EDX:EAX into 32-bit integer EAX
  48. ;[]     Input:  EDX:EAX  - double precision floating point number
  49. ;[]     Output: EAX      - 32-bit integer
  50. ;[]
  51. ;[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
  52. ;       convert floating double to 4-byte integer with rounding
  53.  
  54.         defpe   __RDU4
  55.         mov     AL,80h+20h      ; indicate we are rounding
  56.         jmp     short DtoI      ; do it
  57.  
  58.         defpe   __RDI4
  59.         mov     AL,80h+1Fh      ; indicate we are rounding
  60.         jmp     short DtoI      ; do it
  61.  
  62.         defpe   __FDI4
  63.         mov     AL,1Fh          ; indicate we are truncating
  64.         jmp     short DtoI      ; do it
  65.  
  66. ;       convert floating double to 4-byte integer with truncation
  67.  
  68.         defpe   __FDU4
  69.         mov     AL,20h          ; indicate we are truncating
  70.  
  71. DtoI:   _shl    EDX,1           ; get sign
  72.         rcr     AH,1            ; AH <-- sign
  73.         shr     AH,1            ; shift sign bit over 1
  74.         or      AH,AL           ; get rounding bit
  75.         shr     EDX,1           ; restore exponent to its place
  76.  
  77. ;       high bit of AH is rounding bit
  78. ;       next bit is the sign bit
  79.  
  80. ;<~> Shift real right four places so that exponent occupies an entire
  81. ;<~> word and the mantissa occupies the remaining words. We do not need
  82. ;<~> AX because we only need 32 sig digits
  83.  
  84.         push    ECX             ; save ECX
  85.         mov     ECX,EDX         ; get high part
  86.         sar     ECX,20          ; get exponent to the bottom
  87.         and     CX,07FFh        ; isolate exponent
  88.         sub     CX,03FEh        ; remove bias from exponent
  89.         jl      short DIzero    ; if |real| < .5 goto DIzero
  90.         cmp     CX,20h          ; if exponent > 32
  91.         jg      short DIo_f     ; goto DIo_flow
  92.         and     AL,3Fh          ; isolate # of significant bits
  93.         cmp     CL,AL           ; quit if number too big
  94.         jg      short DIo_f     ; goto DIo_flow
  95.         mov     CH,AH           ; save rounding/truncation bit
  96.         and     EDX,000FFFFFh   ; isolate top 20 bits of fraction
  97.         and     EAX,0FFF00000h  ; isolate next 12 bits of fraction
  98.         or      EDX,EAX         ; glue them together
  99.         rol     EDX,12          ; and rotate into position
  100.  
  101.         stc                     ; set carry and
  102.         rcr     EDX,1           ; restore implied 1/2 bit
  103.  
  104.         rcr     CH,1            ; save rounding bit
  105.         cmp     CL,32           ; if want 32 bits
  106.         _if     e               ; then
  107.           mov   EAX,EDX         ; - get them
  108.           _shl  CH,1            ; - get rounding bit
  109.         _else                   ; else
  110.           sub   EAX,EAX         ; - zero result register
  111.           shld  EAX,EDX,CL      ; - shift answer into EAX
  112.           shl   EDX,CL          ; - shift rounding bit into position
  113.           _shl  CH,1            ; - get rid of rounding bit from CH
  114.           _shl  EDX,1           ; - get proper rounding bit
  115.         _endif                  ; endif
  116.         mov     CL,0FFh         ; get mask
  117.         rcr     CL,1            ; get rounding bit
  118.         and     CH,CL           ; mask it with rounding control bit
  119.         _shl    CH,1            ; get rounding bit
  120.         adc     EAX,0           ; add it to the integer to round it up
  121.         _shl    CH,1            ; get sign
  122.         _if     c               ; if negative
  123.           neg   EAX             ; - negate integer
  124.         _endif                  ; endif
  125.         pop     ECX             ; restore ECX
  126.         ret                     ; return
  127.  
  128. DIo_f:
  129.         mov     EAX,80000000h   ; set answer to largest negative number
  130.         pop     ECX             ; restore ECX
  131.         ret                     ; return
  132. ;       jmp     I4OverFlow      ; report overflow
  133.  
  134. DIzero: sub     EAX,EAX         ; set result to zero
  135.         pop     ECX             ; restore ECX
  136.         ret
  137.  
  138.         endproc __FDU4
  139.         endproc __FDI4
  140.         endproc __RDI4
  141.         endproc __RDU4
  142.  
  143.         endmod
  144.         end
  145.