Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
553 serge 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