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 | }>>>>> |