Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
359 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
; This module converts a string to long_double
34
;       void __ZBuf2LD( char *buf, long_double *value );
35
;
36
include mdef.inc
37
include struct.inc
38
 
39
        modstart bufld386
40
 
41
        xdefp   __ZBuf2LD
42
 
43
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
44
;<>                                                                   <>
45
;<>   __ZBuf2LD - convert buffer of significant digits into floating  <>
46
;<>             void __ZBuf2LD( char *buf, long_double *value )       <>
47
;<>                                                                   <>
48
;<>   input:  EAX - address of buffer of significant digits           <>
49
;<>           EDX - place to store value                              <>
50
;<>   output: [EDX]        - floating-point number                    <>
51
;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
52
 
53
        defpe   __ZBuf2LD
54
        push    EBP             ; save EBP
55
        push    ESI             ; save ESI
56
        push    EDI             ; save EDI
57
        push    ECX             ; save ECX
58
        push    EBX             ; save EBX
59
        push    EDX             ; save pointer to result
60
        mov     ESI,EAX         ; get address of buffer
61
        sub     EDX,EDX         ; set 96-bit integer to 0
62
        sub     ECX,ECX         ; ...
63
        sub     EBP,EBP         ; ...
64
        sub     EAX,EAX         ; zero out EAX
65
        _loop                   ; loop (convert digits into 64-bit int)
66
          mov   AL,[ESI]        ; - get next digit
67
          cmp   AL,0            ; - quit if at end of buffer
68
          _quif e               ; - . . .
69
 
70
;[]  multiply current value in EDX:ECX:EBP by 10
71
 
72
          mov   EDI,EDX         ; - save current value
73
          mov   EBX,ECX         ; - ...
74
          mov   EAX,EBP         ; - ...
75
          _shl  EBP,1           ; - multiply number by 4
76
          _rcl  ECX,1           ; -   by shifting left 2 places
77
          _rcl  EDX,1           ; - ...
78
          _shl  EBP,1           ; - ...
79
          _rcl  ECX,1           ; - ...
80
          _rcl  EDX,1           ; - ...
81
          add   EBP,EAX         ; - add original value
82
          adc   ECX,EBX         ; -  (this will make it times 5)
83
          adc   EDX,EDI         ; - ...
84
          _shl  EBP,1           ; - shift left to make it times 10
85
          _rcl  ECX,1           ; - ...
86
          _rcl  EDX,1           ; - ...
87
          sub   EAX,EAX         ; - zero eax
88
          mov   AL,[ESI]        ; - get next digit
89
          and   AL,0Fh          ; - isolate binary digit
90
          add   EBP,EAX         ; - add in current digit
91
          adc   ECX,0           ; - ...
92
          adc   EDX,0           ; - ...
93
          inc   ESI             ; - point to next digit in buffer
94
        _endloop                ; endloop
95
        mov     EAX,ECX         ; get low order word into EAX
96
 
97
;[] Turn the integer in EDX:EAX:EBP into a real number
98
 
99
        mov     EDI,3FFFh+63+32 ; set exponent
100
        call    Norm            ; convert the 64 bit integer to a float
101
        pop     EBP             ; restore pointer to result
102
        mov     4[EBP],EDX      ; store result
103
        mov     0[EBP],EAX      ; ...
104
        mov     8[EBP],SI       ; ...
105
        pop     EBX             ; restore EBX
106
        pop     ECX             ; restore ECX
107
        pop     EDI             ; restore EDI
108
        pop     ESI             ; restore ESI
109
        pop     EBP             ; restore EBP
110
        ret                     ; return to caller
111
        endproc __ZBuf2LD
112
 
113
 
114
;[] Norm normalizes an unsigned real in EDX:EAX:EBP i.e grab top 64 bits
115
;[] expects the exponent to be in EDI.
116
;[]     SI contains the new exponent
117
 
118
Norm    proc    near            ; normalize floating point number
119
        sub     ESI,ESI         ; clear out SI
120
        or      ESI,EAX         ; see if the integer is zero
121
        or      ESI,EDX         ; ...
122
        or      ESI,EBP         ; ...
123
        _if     ne              ; if number is non-zero
124
          or    EDX,EDX         ; - see if high word is 0
125
          _if   e               ; - if high word is 0
126
            mov   EDX,EAX       ; - - shift by 32-bits
127
            mov   EAX,EBP       ; - - ...
128
            sub   EBP,EBP       ; - - ...
129
            sub   EDI,32        ; - - adjust exponent by 32
130
          _endif                ; - endif
131
          or    EDX,EDX         ; - see if high word is 0
132
          _if   e               ; - if high word is 0
133
            mov   EDX,EAX       ; - - shift by 32-bits
134
            mov   EAX,EBP       ; - - ...
135
            sub   EBP,EBP       ; - - ...
136
            sub   EDI,32        ; - - adjust exponent by 32
137
          _endif                ; - endif
138
          _loop                 ; - loop
139
            or    EDX,EDX       ; - - quit if high bit is on
140
            _quif s             ; - - ...
141
            dec   EDI           ; - - decrement exponent
142
            _shl  EBP,1         ; - - shift integer left by 1 bit
143
            _rcl  EAX,1         ; - - ...
144
            _rcl  EDX,1         ; - - ...
145
          _endloop              ; - endloop
146
          _shl  EBP,1           ; - get top bit of extra word
147
          adc   EAX,0           ; - round up
148
          adc   EDX,0           ; - ...
149
          _if   c               ; - if carry out the top
150
            rcr   EDX,1         ; - - shift fraction back 1
151
            inc   EDI           ; - - increment exponent
152
          _endif                ; - endif
153
          mov   ESI,EDI         ; - get exponent
154
        _endif                  ; endif
155
        ret                     ; return
156
        endproc Norm
157
 
158
        endmod
159
        end