arch-arm,cpu: Introduce a getEMI virtual method on StaticInst.
[gem5.git] / src / base / cprintf_formats.hh
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
29 #ifndef __BASE_CPRINTF_FORMATS_HH__
30 #define __BASE_CPRINTF_FORMATS_HH__
31
32 #include <cstring>
33 #include <ostream>
34 #include <sstream>
35
36 namespace cp
37 {
38
39 struct Format
40 {
41 bool alternateForm;
42 bool flushLeft;
43 bool printSign;
44 bool blankSpace;
45 bool fillZero;
46 bool uppercase;
47 enum
48 {
49 Dec,
50 Hex,
51 Oct
52 } base;
53 enum
54 {
55 None,
56 String,
57 Integer,
58 Character,
59 Floating
60 } format;
61 enum
62 {
63 Best,
64 Fixed,
65 Scientific
66 } floatFormat;
67 int precision;
68 int width;
69 bool getPrecision;
70 bool getWidth;
71
72 Format() { clear(); }
73
74 void
75 clear()
76 {
77 alternateForm = false;
78 flushLeft = false;
79 printSign = false;
80 blankSpace = false;
81 fillZero = false;
82 uppercase = false;
83 base = Dec;
84 format = None;
85 floatFormat = Best;
86 precision = -1;
87 width = 0;
88 getPrecision = false;
89 getWidth = false;
90 }
91 };
92
93 template <typename T>
94 static inline void
95 _formatChar(std::ostream &out, const T &data, Format &fmt)
96 {
97 out << data;
98 }
99
100 template <typename T>
101 static inline void
102 _formatInteger(std::ostream &out, const T &data, Format &fmt)
103 {
104 std::ios::fmtflags flags(out.flags());
105
106 switch (fmt.base) {
107 case Format::Hex:
108 out.setf(std::ios::hex, std::ios::basefield);
109 break;
110
111 case Format::Oct:
112 out.setf(std::ios::oct, std::ios::basefield);
113 break;
114
115 case Format::Dec:
116 out.setf(std::ios::dec, std::ios::basefield);
117 break;
118 }
119
120 if (fmt.alternateForm) {
121 if (!fmt.fillZero) {
122 out.setf(std::ios::showbase);
123 } else {
124 switch (fmt.base) {
125 case Format::Hex:
126 out << "0x";
127 fmt.width -= 2;
128 break;
129 case Format::Oct:
130 out << "0";
131 fmt.width -= 1;
132 break;
133 case Format::Dec:
134 break;
135 }
136 }
137 }
138
139 if (fmt.fillZero)
140 out.fill('0');
141
142 if (fmt.width > 0)
143 out.width(fmt.width);
144
145 if (fmt.flushLeft && !fmt.fillZero)
146 out.setf(std::ios::left);
147
148 if (fmt.printSign)
149 out.setf(std::ios::showpos);
150
151 if (fmt.uppercase)
152 out.setf(std::ios::uppercase);
153
154 out << data;
155
156 out.flags(flags);
157 }
158
159 template <typename T>
160 static inline void
161 _formatFloat(std::ostream &out, const T &data, Format &fmt)
162 {
163 std::ios::fmtflags flags(out.flags());
164
165 if (fmt.fillZero)
166 out.fill('0');
167
168 switch (fmt.floatFormat) {
169 case Format::Scientific:
170 if (fmt.precision != -1) {
171 if (fmt.width > 0)
172 out.width(fmt.width);
173
174 if (fmt.precision == 0)
175 fmt.precision = 1;
176 else
177 out.setf(std::ios::scientific);
178
179 out.precision(fmt.precision);
180 } else if (fmt.width > 0) {
181 out.width(fmt.width);
182 }
183
184 if (fmt.uppercase)
185 out.setf(std::ios::uppercase);
186 break;
187
188 case Format::Fixed:
189 if (fmt.precision != -1) {
190 if (fmt.width > 0)
191 out.width(fmt.width);
192
193 out.setf(std::ios::fixed);
194 out.precision(fmt.precision);
195 } else if (fmt.width > 0) {
196 out.width(fmt.width);
197 }
198
199 break;
200
201 default:
202 if (fmt.precision != -1)
203 out.precision(fmt.precision);
204
205 if (fmt.width > 0)
206 out.width(fmt.width);
207
208 break;
209 }
210
211 out << data;
212
213 out.flags(flags);
214 }
215
216 template <typename T>
217 static inline void
218 _formatString(std::ostream &out, const T &data, Format &fmt)
219 {
220 if (fmt.width > 0) {
221 std::stringstream foo;
222 foo << data;
223 int flen = foo.str().size();
224
225 if (fmt.width > flen) {
226 char spaces[fmt.width - flen + 1];
227 std::memset(spaces, ' ', fmt.width - flen);
228 spaces[fmt.width - flen] = 0;
229
230 if (fmt.flushLeft)
231 out << foo.str() << spaces;
232 else
233 out << spaces << foo.str();
234 } else {
235 out << data;
236 }
237 } else {
238 out << data;
239 }
240 }
241
242 /////////////////////////////////////////////////////////////////////////////
243 //
244 // The code below controls the actual usage of formats for various types
245 //
246
247 //
248 // character formats
249 //
250 template <typename T>
251 static inline void
252 formatChar(std::ostream &out, const T &data, Format &fmt)
253 {
254 out << "<bad arg type for char format>";
255 }
256
257 static inline void
258 formatChar(std::ostream &out, char data, Format &fmt)
259 {
260 _formatChar(out, data, fmt);
261 }
262
263 static inline void
264 formatChar(std::ostream &out, unsigned char data, Format &fmt)
265 {
266 _formatChar(out, data, fmt);
267 }
268
269 static inline void
270 formatChar(std::ostream &out, signed char data, Format &fmt)
271 {
272 _formatChar(out, data, fmt);
273 }
274
275 static inline void
276 formatChar(std::ostream &out, short data, Format &fmt)
277 {
278 _formatChar(out, (char)data, fmt);
279 }
280
281 static inline void
282 formatChar(std::ostream &out, unsigned short data, Format &fmt)
283 {
284 _formatChar(out, (char)data, fmt);
285 }
286
287 static inline void
288 formatChar(std::ostream &out, int data, Format &fmt)
289 {
290 _formatChar(out, (char)data, fmt);
291 }
292
293 static inline void
294 formatChar(std::ostream &out, unsigned int data, Format &fmt)
295 {
296 _formatChar(out, (char)data, fmt);
297 }
298
299 static inline void
300 formatChar(std::ostream &out, long data, Format &fmt)
301 {
302 _formatChar(out, (char)data, fmt);
303 }
304
305 static inline void
306 formatChar(std::ostream &out, unsigned long data, Format &fmt)
307 {
308 _formatChar(out, (char)data, fmt);
309 }
310
311 static inline void
312 formatChar(std::ostream &out, long long data, Format &fmt)
313 {
314 _formatChar(out, (char)data, fmt);
315 }
316
317 static inline void
318 formatChar(std::ostream &out, unsigned long long data, Format &fmt)
319 {
320 _formatChar(out, (char)data, fmt);
321 }
322
323 //
324 // integer formats
325 //
326 template <typename T>
327 static inline void
328 formatInteger(std::ostream &out, const T &data, Format &fmt)
329 {
330 _formatInteger(out, data, fmt);
331 }
332 static inline void
333 formatInteger(std::ostream &out, char data, Format &fmt)
334 {
335 _formatInteger(out, (int)data, fmt);
336 }
337 static inline void
338 formatInteger(std::ostream &out, unsigned char data, Format &fmt)
339 {
340 _formatInteger(out, (int)data, fmt);
341 }
342 static inline void
343 formatInteger(std::ostream &out, signed char data, Format &fmt)
344 {
345 _formatInteger(out, (int)data, fmt);
346 }
347 static inline void
348 formatInteger(std::ostream &out, const unsigned char *data, Format &fmt)
349 {
350 _formatInteger(out, (uintptr_t)data, fmt);
351 }
352 static inline void
353 formatInteger(std::ostream &out, const signed char *data, Format &fmt)
354 {
355 _formatInteger(out, (uintptr_t)data, fmt);
356 }
357
358 //
359 // floating point formats
360 //
361 template <typename T>
362 static inline void
363 formatFloat(std::ostream &out, const T &data, Format &fmt)
364 {
365 out << "<bad arg type for float format>";
366 }
367
368 static inline void
369 formatFloat(std::ostream &out, float data, Format &fmt)
370 {
371 _formatFloat(out, data, fmt);
372 }
373
374 static inline void
375 formatFloat(std::ostream &out, double data, Format &fmt)
376 {
377 _formatFloat(out, data, fmt);
378 }
379
380 //
381 // string formats
382 //
383 template <typename T>
384 static inline void
385 formatString(std::ostream &out, const T &data, Format &fmt)
386 {
387 _formatString(out, data, fmt);
388 }
389
390 } // namespace cp
391
392 #endif // __CPRINTF_FORMATS_HH__