Deleted Added
sdiff udiff text old ( 8026:680f5c014bed ) new ( 8029:442f90a944eb )
full compact
1/*
2 * Copyright (c) 2003, 2004
3 * The Regents of The University of Michigan
4 * All Rights Reserved
5 *
6 * This code is part of the M5 simulator.
7 *
8 * Permission is granted to use, copy, create derivative works and
9 * redistribute this software and such derivative works for any purpose,
10 * so long as the copyright notice above, this grant of permission, and
11 * the disclaimer below appear in all copies made; and so long as the
12 * name of The University of Michigan is not used in any advertising or
13 * publicity pertaining to the use or distribution of this software
14 * without specific, written prior authorization.
15 *
16 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE
17 * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT
18 * WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR
19 * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF
21 * THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES,
22 * INCLUDING DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
23 * DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION
24 * WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
26 */
27
28/*
29 * Copyright 1993 Hewlett-Packard Development Company, L.P.
30 *
31 * Permission is hereby granted, free of charge, to any person
32 * obtaining a copy of this software and associated documentation
33 * files (the "Software"), to deal in the Software without
34 * restriction, including without limitation the rights to use, copy,
35 * modify, merge, publish, distribute, sublicense, and/or sell copies
36 * of the Software, and to permit persons to whom the Software is
37 * furnished to do so, subject to the following conditions:
38 *
39 * The above copyright notice and this permission notice shall be
40 * included in all copies or substantial portions of the Software.
41 *
42 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
43 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
45 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
46 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
47 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
48 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
49 * SOFTWARE.
50 */
51
52#include <sys/types.h>
53#include <stdarg.h>
54#include <stdint.h>
55#include "m5op.h"
56
57/* The string s is terminated by a '\0' */
58void
59PutString(const char *s)
60{
61 while (*s)
62 PutChar(*s++);
63}
64
65/* print c count times */
66void
67PutRepChar(char c, int count)
68{
69 while (count--)
70 PutChar(c);
71}
72
73/* put string reverse */
74void
75PutStringReverse(const char *s, int index)
76{
77 while (index-- > 0)
78 PutChar(s[index]);
79}
80
81/*
82 * prints value in radix, in a field width width, with fill
83 * character fill
84 * if radix is negative, print as signed quantity
85 * if width is negative, left justify
86 * if width is 0, use whatever is needed
87 * if fill is 0, use ' '
88 */
89void
90PutNumber(long value, int radix, int width, char fill)
91{
92 char buffer[40];
93 uint bufferindex = 0;
94 ulong uvalue;
95 ushort digit;
96 ushort left = 0;
97 ushort negative = 0;
98
99 if (fill == 0)
100 fill = ' ';
101
102 if (width < 0) {
103 width = -width;
104 left = 1;
105 }
106
107 if (width < 0 || width > 80)
108 width = 0;
109
110 if (radix < 0) {
111 radix = -radix;
112 if (value < 0) {
113 negative = 1;
114 value = -value;
115 }
116 }
117
118 switch (radix) {
119 case 8:
120 case 10:
121 case 16:
122 break;
123
124 default:
125 PutString("****");
126 return;
127 }
128
129 uvalue = value;
130
131 do {
132 if (radix != 16) {
133 digit = (ushort)(uvalue % radix);
134 uvalue /= radix;
135 } else {
136 digit = (ushort)(uvalue & 0xf);
137 uvalue = uvalue >> 4;
138 }
139 buffer[bufferindex] = digit + ((digit <= 9) ? '0' : ('A' - 10));
140 bufferindex += 1;
141 } while (uvalue != 0);
142
143 /* fill # ' ' and negative cannot happen at once */
144 if (negative) {
145 buffer[bufferindex] = '-';
146 bufferindex += 1;
147 }
148
149 if ((uint)width <= bufferindex) {
150 PutStringReverse(buffer, bufferindex);
151 } else {
152 width -= bufferindex;
153 if (!left)
154 PutRepChar(fill, width);
155 PutStringReverse(buffer, bufferindex);
156 if (left)
157 PutRepChar(fill, width);
158 }
159}
160
161ulong
162power(long base, long n)
163{
164 ulong p;
165
166 for (p = 1; n > 0; --n)
167 p = p * base;
168 return p;
169}
170
171void
172putFloat(double a, int fieldwidth, char fill)
173{
174 int i;
175 ulong b;
176
177 /*
178 * Put out everything before the decimal place.
179 */
180 PutNumber(((ulong) a), 10, fieldwidth, fill);
181
182 /*
183 * Output the decimal place.
184 */
185 PutChar('.' & 0x7f);
186
187 /*
188 * Output the n digits after the decimal place.
189 */
190 for (i = 1; i < 6; i++) {
191 b = (ulong)(power(10, i) * (double)(a - (ulong) a));
192 PutChar((char)(b % 10) + '0');
193 }
194}
195
196const char *
197FormatItem(const char *f, va_list *ap)
198{
199 char c;
200 int fieldwidth = 0;
201 int leftjust = 0;
202 int radix = 0;
203 char fill = ' ';
204
205 if (*f == '0')
206 fill = '0';
207
208 while (c = *f++) {
209 if (c >= '0' && c <= '9') {
210 fieldwidth = (fieldwidth * 10) + (c - '0');
211 } else {
212 switch (c) {
213 case '\000':
214 return(--f);
215 case '%':
216 PutChar('%');
217 return(f);
218 case '-':
219 leftjust = 1;
220 break;
221 case 'c': {
222 char a = (char)va_arg(*ap, int);
223
224 if (leftjust)
225 PutChar(a & 0x7f);
226 if (fieldwidth > 0)
227 PutRepChar(fill, fieldwidth - 1);
228 if (!leftjust)
229 PutChar(a & 0x7f);
230 return(f);
231 }
232 case 's': {
233 const char *a = va_arg(*ap, const char *);
234
235 if (leftjust)
236 PutString((const char *) a);
237 if (fieldwidth > strlen((const char *) a))
238 PutRepChar(fill, fieldwidth - strlen((const char *)a));
239 if (!leftjust)
240 PutString((const char *) a);
241 return(f);
242 }
243 case 'd':
244 radix = -10;
245 break;
246 case 'u':
247 radix = 10;
248 break;
249 case 'x':
250 radix = 16;
251 break;
252 case 'X':
253 radix = 16;
254 break;
255 case 'o':
256 radix = 8;
257 break;
258 case 'f': {
259 double a = va_arg(*ap, double);
260
261 putFloat(a, fieldwidth, fill);
262 return(f);
263 }
264 default: /* unknown switch! */
265 radix = 3;
266 break;
267 }
268 }
269
270 if (radix)
271 break;
272 }
273
274 if (leftjust)
275 fieldwidth = -fieldwidth;
276
277 long a = va_arg(*ap, long);
278 PutNumber(a, radix, fieldwidth, fill);
279
280 return(f);
281}
282
283int
284printf(const char *f, ...)
285{
286 va_list ap;
287
288 va_start(ap, f);
289
290 while (*f) {
291 if (*f == '%')
292 f = FormatItem(f + 1, &ap);
293 else
294 PutChar(*f++);
295 }
296
297 if (*(f - 1) == '\n') {
298 /* add a line-feed (SimOS console output goes to shell */
299 PutChar('\r');
300 }
301
302 va_end(ap); /* clean up */
303 return 0;
304}
305
306void
307panic(const char *f, ...)
308{
309 va_list ap;
310
311 va_start(ap, f);
312
313 printf("CONSOLE PANIC (looping): ");
314 while (*f) {
315 if (*f == '%')
316 f = FormatItem(f + 1, &ap);
317 else
318 PutChar(*f++);
319 }
320
321 va_end(ap); /* clean up */
322 m5_panic();
323}