Merge ktlim@zizzer:/bk/newmem
[gem5.git] / src / kern / tru64 / printf.cc
1 /*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
29 */
30
31 #include <sys/types.h>
32 #include <algorithm>
33
34 #include "base/cprintf.hh"
35 #include "base/trace.hh"
36 #include "sim/host.hh"
37 #include "arch/arguments.hh"
38 #include "arch/vtophys.hh"
39
40 using namespace std;
41
42 namespace tru64 {
43
44 void
45 Printf(TheISA::Arguments args)
46 {
47 std::ostream &out = Trace::output();
48
49 char *p = (char *)args++;
50
51 ios::fmtflags saved_flags = out.flags();
52 char old_fill = out.fill();
53 int old_precision = out.precision();
54
55 while (*p) {
56 switch (*p) {
57 case '%': {
58 bool more = true;
59 bool islong = false;
60 bool leftjustify = false;
61 bool format = false;
62 bool zero = false;
63 int width = 0;
64 while (more && *++p) {
65 switch (*p) {
66 case 'l':
67 case 'L':
68 islong = true;
69 break;
70 case '-':
71 leftjustify = true;
72 break;
73 case '#':
74 format = true;
75 break;
76 case '0':
77 if (width)
78 width *= 10;
79 else
80 zero = true;
81 break;
82 default:
83 if (*p >= '1' && *p <= '9')
84 width = 10 * width + *p - '0';
85 else
86 more = false;
87 break;
88 }
89 }
90
91 bool hexnum = false;
92 bool octal = false;
93 bool sign = false;
94 switch (*p) {
95 case 'X':
96 case 'x':
97 hexnum = true;
98 break;
99 case 'O':
100 case 'o':
101 octal = true;
102 break;
103 case 'D':
104 case 'd':
105 sign = true;
106 break;
107 case 'P':
108 format = true;
109 case 'p':
110 hexnum = true;
111 break;
112 }
113
114 switch (*p) {
115 case 'D':
116 case 'd':
117 case 'U':
118 case 'u':
119 case 'X':
120 case 'x':
121 case 'O':
122 case 'o':
123 case 'P':
124 case 'p': {
125 if (hexnum)
126 out << hex;
127
128 if (octal)
129 out << oct;
130
131 if (format) {
132 if (!zero)
133 out.setf(ios::showbase);
134 else {
135 if (hexnum) {
136 out << "0x";
137 width -= 2;
138 } else if (octal) {
139 out << "0";
140 width -= 1;
141 }
142 }
143 }
144
145 if (zero)
146 out.fill('0');
147
148 if (width > 0)
149 out.width(width);
150
151 if (leftjustify && !zero)
152 out.setf(ios::left);
153
154 if (sign) {
155 if (islong)
156 out << (int64_t)args;
157 else
158 out << (int32_t)args;
159 } else {
160 if (islong)
161 out << (uint64_t)args;
162 else
163 out << (uint32_t)args;
164 }
165
166 if (zero)
167 out.fill(' ');
168
169 if (width > 0)
170 out.width(0);
171
172 out << dec;
173
174 ++args;
175 }
176 break;
177
178 case 's': {
179 char *s = (char *)args;
180 if (!s)
181 s = "<NULL>";
182
183 if (width > 0)
184 out.width(width);
185 if (leftjustify)
186 out.setf(ios::left);
187
188 out << s;
189 ++args;
190 }
191 break;
192 case 'C':
193 case 'c': {
194 uint64_t mask = (*p == 'C') ? 0xffL : 0x7fL;
195 uint64_t num;
196 int width;
197
198 if (islong) {
199 num = (uint64_t)args;
200 width = sizeof(uint64_t);
201 } else {
202 num = (uint32_t)args;
203 width = sizeof(uint32_t);
204 }
205
206 while (width-- > 0) {
207 char c = (char)(num & mask);
208 if (c)
209 out << c;
210 num >>= 8;
211 }
212
213 ++args;
214 }
215 break;
216 case 'b': {
217 uint64_t n = (uint64_t)args++;
218 char *s = (char *)args++;
219 out << s << ": " << n;
220 }
221 break;
222 case 'n':
223 case 'N': {
224 args += 2;
225 #if 0
226 uint64_t n = (uint64_t)args++;
227 struct reg_values *rv = (struct reg_values *)args++;
228 #endif
229 }
230 break;
231 case 'r':
232 case 'R': {
233 args += 2;
234 #if 0
235 uint64_t n = (uint64_t)args++;
236 struct reg_desc *rd = (struct reg_desc *)args++;
237 #endif
238 }
239 break;
240 case '%':
241 out << '%';
242 break;
243 }
244 ++p;
245 }
246 break;
247 case '\n':
248 out << endl;
249 ++p;
250 break;
251 case '\r':
252 ++p;
253 if (*p != '\n')
254 out << endl;
255 break;
256
257 default: {
258 size_t len = strcspn(p, "%\n\r\0");
259 out.write(p, len);
260 p += len;
261 }
262 }
263 }
264
265 out.flags(saved_flags);
266 out.fill(old_fill);
267 out.precision(old_precision);
268 }
269
270 } // namespace Tru64