Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
554 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:  Long long integer to ASCII conversion routines.
28
*
29
****************************************************************************/
30
 
31
 
32
#include "variety.h"
33
#include "widechar.h"
34
#include "watcom.h"
35
#include "clibi64.h"
36
#include 
37
 
38
extern const char __based(__segname("_CONST")) __Alphabet[];
39
 
40
#if defined(__386__) || defined(M_I86)
41
unsigned long long __ulldiv( unsigned long long, unsigned _WCNEAR *);
42
#if defined(__386__)
43
    #pragma aux __ulldiv = \
44
        "xor ecx,ecx"     /* set high word of quotient to 0 */ \
45
        "cmp edx,dword ptr[ebx]" /* if quotient will be >= 4G */ \
46
        "jb less4g"       /* then */ \
47
        "mov ecx,eax"     /* - save low word of dividend */ \
48
        "mov eax,edx"     /* - get high word of dividend */ \
49
        "xor edx,edx"     /* - zero high part */ \
50
        "div dword ptr[ebx]"  /* - divide into high part of dividend */ \
51
        "xchg eax,ecx"    /* - swap high part of quot,low word of dvdnd */ \
52
      "less4g:"           \
53
        "div dword ptr[ebx]" /* calculate low part */ \
54
        "mov [ebx],edx"   /* store remainder */ \
55
        parm [eax edx] [ebx] value [eax ecx];
56
#elif defined(M_I86)  && defined(__BIG_DATA__)
57
    #pragma aux __ulldiv = \
58
        "mov di,dx"        /* initial dividend = ax:bx:cx:dx(di); save dx */ \
59
        "test ax,ax"       /* less work to do if ax == 0 */ \
60
        "jz skip1"  \
61
        "mov dx,ax"        /* dx:ax = ax:bx */ \
62
        "mov ax,bx" \
63
        "xor bx,bx"           /* set word 3 of quotient to 0 */ \
64
        "cmp dx,word ptr ss:[si]" /* if quotient will be >= 64K */ \
65
        "jb div2"             /* then */ \
66
        "mov bx,ax"       /* restore word 2 of dividend */ \
67
        "mov ax,dx"       /* restore word 3 of dividend */ \
68
        "xor dx,dx"       /* - zero high part */ \
69
        "div word ptr ss:[si]"  /* - divide into word 3 of dividend */ \
70
        "xchg ax,bx"      /* - swap word 3,word 2 of dvdnd */ \
71
      "div2:"           \
72
        "div word ptr ss:[si]"  /* - divide into word 2 of dividend */ \
73
        "xchg ax,cx"      /* - swap word 2,word 1 of dvdnd */ \
74
      "div3:"           \
75
        "div word ptr ss:[si]"  /* - divide into word 1 of dividend */ \
76
        "xchg ax,di"      /* - swap word 1,word 0 of dvdnd */ \
77
      "div4:"           \
78
        "div word ptr ss:[si]" /* calculate low part */ \
79
        "mov  ss:[si],dx"      /* store remainder */ \
80
        "mov dx,ax"        /* dx is word 0 */ \
81
        "mov ax,bx"        /* ax:bx:cx:dx = bx:cx:di:ax */ \
82
        "mov bx,cx" \
83
        "mov cx,di" \
84
        "jmp end_div" \
85
      "skip1:"      /* ax==0 */  \
86
        "test bx,bx"       /* even less work to do if bx == 0 too */ \
87
        "jz skip2" \
88
        "mov dx,bx"        /* dx:ax = bx:cx */ \
89
        "mov ax,cx" \
90
        "xor bx,bx"        /* set word 3 of quotient to 0 */ \
91
        "xor cx,cx"        /* set word 2 of quotient to 0 */ \
92
        "cmp dx,word ptr ss:[si]" /* if quotient will be < 64K */ \
93
        "jb div3"             /* then need to do two divisions */ \
94
        "mov cx,ax"        /* restore word 1 of dividend */ \
95
        "mov ax,dx"        /* restore word 2 of dividend */ \
96
        "xor dx,dx"        /* zero high part */ \
97
        "jmp div2"         /* do three divisions*/ \
98
      "skip2:"      /* ax==bx==0 */ \
99
        "mov dx,cx"        /* dx:ax = cx:di */ \
100
        "mov ax,di" \
101
        "xor cx,cx"        /* set word 2 of quotient to 0 */ \
102
        "xor di,di"        /* set word 1 of quotient to 0 */ \
103
        "cmp dx,word ptr ss:[si]" /* if quotient will be < 64K */ \
104
        "jb div4"             /* then only one division to do */ \
105
        "mov di,ax"        /* restore word 0 of dividend */ \
106
        "mov ax,dx"        /* restore word 1 of dividend */ \
107
        "xor dx,dx"        /* zero high part */ \
108
        "jmp div3"         /* do two divisions */ \
109
      "end_div:" \
110
        parm [ax bx cx dx] [si] modify [di] value [ax bx cx dx];
111
#elif defined(M_I86) && defined(__SMALL_DATA__)
112
    #pragma aux __ulldiv = \
113
        "mov di,dx"        /* initial dividend = ax:bx:cx:dx(di); save dx */ \
114
        "test ax,ax"       /* less work to do if ax == 0 */ \
115
        "jz skip1"  \
116
        "mov dx,ax"        /* dx:ax = ax:bx */ \
117
        "mov ax,bx" \
118
        "xor bx,bx"           /* set word 3 of quotient to 0 */ \
119
        "cmp dx,word ptr[si]" /* if quotient will be >= 64K */ \
120
        "jb div2"             /* then */ \
121
        "mov bx,ax"       /* restore word 2 of dividend */ \
122
        "mov ax,dx"       /* restore word 3 of dividend */ \
123
        "xor dx,dx"       /* - zero high part */ \
124
        "div word ptr[si]"  /* - divide into word 3 of dividend */ \
125
        "xchg ax,bx"      /* - swap word 3,word 2 of dvdnd */ \
126
      "div2:"           \
127
        "div word ptr[si]"  /* - divide into word 2 of dividend */ \
128
        "xchg ax,cx"      /* - swap word 2,word 1 of dvdnd */ \
129
      "div3:"           \
130
        "div word ptr[si]"  /* - divide into word 1 of dividend */ \
131
        "xchg ax,di"      /* - swap word 1,word 0 of dvdnd */ \
132
      "div4:"           \
133
        "div word ptr[si]" /* calculate low part */ \
134
        "mov [si],dx"      /* store remainder */ \
135
        "mov dx,ax"        /* dx is word 0 */ \
136
        "mov ax,bx"        /* ax:bx:cx:dx = bx:cx:di:ax */ \
137
        "mov bx,cx" \
138
        "mov cx,di" \
139
        "jmp end_div" \
140
      "skip1:"      /* dx==0 */  \
141
        "test bx,bx"       /* even less work to do if bx == 0 too */ \
142
        "jz skip2" \
143
        "mov dx,bx"        /* dx:ax = bx:cx */ \
144
        "mov ax,cx" \
145
        "xor bx,bx"        /* set word 3 of quotient to 0 */ \
146
        "xor cx,cx"        /* set word 2 of quotient to 0 */ \
147
        "cmp dx,word ptr[si]" /* if quotient will be < 64K */ \
148
        "jb div3"             /* then need to do two divisions */ \
149
        "mov cx,ax"        /* restore word 1 of dividend */ \
150
        "mov ax,dx"        /* restore word 2 of dividend */ \
151
        "xor dx,dx"        /* zero high part */ \
152
        "jmp div2"         /* do three divisions*/ \
153
      "skip2:"      /* ax==bx==0 */ \
154
        "mov dx,cx"        /* dx:ax = cx:di */ \
155
        "mov ax,di" \
156
        "xor cx,cx"        /* set word 2 of quotient to 0 */ \
157
        "xor di,di"        /* set word 1 of quotient to 0 */ \
158
        "cmp dx,word ptr[si]" /* if quotient will be < 64K */ \
159
        "jb div4"             /* then only one division to do */ \
160
        "mov di,ax"        /* restore word 0 of dividend */ \
161
        "mov ax,dx"        /* restore word 1 of dividend */ \
162
        "xor dx,dx"        /* zero high part */ \
163
        "jmp div3"         /* do two divisions */ \
164
      "end_div:" \
165
        parm [ax bx cx dx] [si] modify [di] value [ax bx cx dx];
166
#endif
167
#endif
168
 
169
_WCRTLINK CHAR_TYPE *__F_NAME(ulltoa,_ulltow)(
170
        unsigned long long int value,
171
        CHAR_TYPE *buffer,
172
        int radix )
173
    {
174
        CHAR_TYPE *p = buffer;
175
        char *q;
176
        unsigned rem;
177
        auto char buf[66];      // only holds ASCII so 'char' is OK
178
 
179
        buf[0] = '\0';
180
        q = &buf[1];
181
        do {
182
#if defined(__386__) || defined(M_I86)
183
            rem = radix;
184
            value = __ulldiv( value, (unsigned _WCNEAR *) &rem );
185
#else
186
            rem = value % radix;
187
            value = value / radix;
188
#endif
189
            *q = __Alphabet[ rem ];
190
            ++q;
191
        } while( value );
192
        while( *p++ = (CHAR_TYPE)*--q );
193
        return( buffer );
194
    }
195
 
196
 
197
_WCRTLINK CHAR_TYPE *__F_NAME(lltoa,_lltow)(
198
        long long int value,
199
        CHAR_TYPE *buffer,
200
        int radix )
201
    {
202
        register CHAR_TYPE *p = buffer;
203
 
204
        if( radix == 10 ) {
205
            if( value < 0 ) {
206
                *p++ = '-';
207
                value = -value;
208
            }
209
        }
210
        __F_NAME(ulltoa,_ulltow)( value, p, radix );
211
        return( buffer );
212
    }