1/*
2 * Copyright (c) 2004-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: Ali Saidi
29 */
30
31#include <sys/types.h>
32#include <algorithm>
33
34#include "base/trace.hh"
35#include "arch/arguments.hh"
36
37using namespace std;
38
39
40void
41Printk(AlphaISA::AlphaArguments args)
42{
43 char *p = (char *)args++;
44
45 ios::fmtflags saved_flags = DebugOut().flags();
46 char old_fill = DebugOut().fill();
47 int old_precision = DebugOut().precision();
48
49 while (*p) {
50 switch (*p) {
51 case '%': {
52 bool more = true;
53 bool islong = false;
54 bool leftjustify = false;
55 bool format = false;
56 bool zero = false;
57 int width = 0;
58 while (more && *++p) {
59 switch (*p) {
60 case 'l':
61 case 'L':
62 islong = true;
63 break;
64 case '-':
65 leftjustify = true;
66 break;
67 case '#':
68 format = true;
69 break;
70 case '0':
71 if (width)
72 width *= 10;
73 else
74 zero = true;
75 break;
76 default:
77 if (*p >= '1' && *p <= '9')
78 width = 10 * width + *p - '0';
79 else
80 more = false;
81 break;
82 }
83 }
84
85 bool hexnum = false;
86 bool octal = false;
87 bool sign = false;
88 switch (*p) {
89 case 'X':
90 case 'x':
91 hexnum = true;
92 break;
93 case 'O':
94 case 'o':
95 octal = true;
96 break;
97 case 'D':
98 case 'd':
99 sign = true;
100 break;
101 case 'P':
102 format = true;
103 case 'p':
104 hexnum = true;
105 break;
106 }
107
108 switch (*p) {
109 case 'D':
110 case 'd':
111 case 'U':
112 case 'u':
113 case 'X':
114 case 'x':
115 case 'O':
116 case 'o':
117 case 'P':
118 case 'p': {
119 if (hexnum)
120 DebugOut() << hex;
121
122 if (octal)
123 DebugOut() << oct;
124
125 if (format) {
126 if (!zero)
127 DebugOut().setf(ios::showbase);
128 else {
129 if (hexnum) {
130 DebugOut() << "0x";
131 width -= 2;
132 } else if (octal) {
133 DebugOut() << "0";
134 width -= 1;
135 }
136 }
137 }
138
139 if (zero)
140 DebugOut().fill('0');
141
142 if (width > 0)
143 DebugOut().width(width);
144
145 if (leftjustify && !zero)
146 DebugOut().setf(ios::left);
147
148 if (sign) {
149 if (islong)
150 DebugOut() << (int64_t)args;
151 else
152 DebugOut() << (int32_t)args;
153 } else {
154 if (islong)
155 DebugOut() << (uint64_t)args;
156 else
157 DebugOut() << (uint32_t)args;
158 }
159
160 if (zero)
161 DebugOut().fill(' ');
162
163 if (width > 0)
164 DebugOut().width(0);
165
166 DebugOut() << dec;
167
168 ++args;
169 }
170 break;
171
172 case 's': {
173 char *s = (char *)args;
174 if (!s)
175 s = "<NULL>";
176
177 if (width > 0)
178 DebugOut().width(width);
179 if (leftjustify)
180 DebugOut().setf(ios::left);
181
182 DebugOut() << s;
183 ++args;
184 }
185 break;
186 case 'C':
187 case 'c': {
188 uint64_t mask = (*p == 'C') ? 0xffL : 0x7fL;
189 uint64_t num;
190 int width;
191
192 if (islong) {
193 num = (uint64_t)args;
194 width = sizeof(uint64_t);
195 } else {
196 num = (uint32_t)args;
197 width = sizeof(uint32_t);
198 }
199
200 while (width-- > 0) {
201 char c = (char)(num & mask);
202 if (c)
203 DebugOut() << c;
204 num >>= 8;
205 }
206
207 ++args;
208 }
209 break;
210 case 'b': {
211 uint64_t n = (uint64_t)args++;
212 char *s = (char *)args++;
213 DebugOut() << s << ": " << n;
214 }
215 break;
216 case 'n':
217 case 'N': {
218 args += 2;
219#if 0
220 uint64_t n = (uint64_t)args++;
221 struct reg_values *rv = (struct reg_values *)args++;
222#endif
223 }
224 break;
225 case 'r':
226 case 'R': {
227 args += 2;
228#if 0
229 uint64_t n = (uint64_t)args++;
230 struct reg_desc *rd = (struct reg_desc *)args++;
231#endif
232 }
233 break;
234 case '%':
235 DebugOut() << '%';
236 break;
237 }
238 ++p;
239 }
240 break;
241 case '\n':
242 DebugOut() << endl;
243 ++p;
244 break;
245 case '\r':
246 ++p;
247 if (*p != '\n')
248 DebugOut() << endl;
249 break;
250
251 default: {
252 size_t len = strcspn(p, "%\n\r\0");
253 DebugOut().write(p, len);
254 p += len;
255 }
256 }
257 }
258
259 DebugOut().flags(saved_flags);
260 DebugOut().fill(old_fill);
261 DebugOut().precision(old_precision);
262}
263