printf.c revision 8024
18012Ssaidi@eecs.umich.edu/* 28013Sbinkertn@umich.edu * Copyright (c) 2003, 2004 38013Sbinkertn@umich.edu * The Regents of The University of Michigan 48013Sbinkertn@umich.edu * All Rights Reserved 58013Sbinkertn@umich.edu * 68013Sbinkertn@umich.edu * This code is part of the M5 simulator, developed by Nathan Binkert, 78013Sbinkertn@umich.edu * Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions 88013Sbinkertn@umich.edu * from Ron Dreslinski, Dave Greene, Lisa Hsu, Ali Saidi, and Andrew 98013Sbinkertn@umich.edu * Schultz. 108013Sbinkertn@umich.edu * 118013Sbinkertn@umich.edu * Permission is granted to use, copy, create derivative works and 128013Sbinkertn@umich.edu * redistribute this software and such derivative works for any purpose, 138013Sbinkertn@umich.edu * so long as the copyright notice above, this grant of permission, and 148013Sbinkertn@umich.edu * the disclaimer below appear in all copies made; and so long as the 158013Sbinkertn@umich.edu * name of The University of Michigan is not used in any advertising or 168013Sbinkertn@umich.edu * publicity pertaining to the use or distribution of this software 178013Sbinkertn@umich.edu * without specific, written prior authorization. 188013Sbinkertn@umich.edu * 198013Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE 208013Sbinkertn@umich.edu * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT 218013Sbinkertn@umich.edu * WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR 228013Sbinkertn@umich.edu * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF 238013Sbinkertn@umich.edu * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF 248013Sbinkertn@umich.edu * THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES, 258013Sbinkertn@umich.edu * INCLUDING DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 268013Sbinkertn@umich.edu * DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION 278013Sbinkertn@umich.edu * WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER 288013Sbinkertn@umich.edu * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 298013Sbinkertn@umich.edu */ 307977Shsul@eecs.umich.edu 317977Shsul@eecs.umich.edu/* 328013Sbinkertn@umich.edu * Copyright 1993 Hewlett-Packard Development Company, L.P. 337977Shsul@eecs.umich.edu * 348013Sbinkertn@umich.edu * Permission is hereby granted, free of charge, to any person 358013Sbinkertn@umich.edu * obtaining a copy of this software and associated documentation 368013Sbinkertn@umich.edu * files (the "Software"), to deal in the Software without 378013Sbinkertn@umich.edu * restriction, including without limitation the rights to use, copy, 388013Sbinkertn@umich.edu * modify, merge, publish, distribute, sublicense, and/or sell copies 398013Sbinkertn@umich.edu * of the Software, and to permit persons to whom the Software is 408013Sbinkertn@umich.edu * furnished to do so, subject to the following conditions: 417977Shsul@eecs.umich.edu * 428013Sbinkertn@umich.edu * The above copyright notice and this permission notice shall be 438013Sbinkertn@umich.edu * included in all copies or substantial portions of the Software. 447977Shsul@eecs.umich.edu * 458013Sbinkertn@umich.edu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 468013Sbinkertn@umich.edu * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 478013Sbinkertn@umich.edu * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 488013Sbinkertn@umich.edu * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 498013Sbinkertn@umich.edu * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 508013Sbinkertn@umich.edu * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 518013Sbinkertn@umich.edu * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 528013Sbinkertn@umich.edu * SOFTWARE. 537977Shsul@eecs.umich.edu */ 547977Shsul@eecs.umich.edu 558013Sbinkertn@umich.edu#include <sys/types.h> 567977Shsul@eecs.umich.edu#include <stdarg.h> 578024Ssaidi@eecs.umich.edu#include <stdint.h> 588024Ssaidi@eecs.umich.edu#include "m5op.h" 597977Shsul@eecs.umich.edu 607977Shsul@eecs.umich.edu/* The string s is terminated by a '\0' */ 617978Sbinkertn@umich.eduvoid 627978Sbinkertn@umich.eduPutString(const char *s) 637977Shsul@eecs.umich.edu{ 648013Sbinkertn@umich.edu while (*s) 658013Sbinkertn@umich.edu PutChar(*s++); 667977Shsul@eecs.umich.edu} 677977Shsul@eecs.umich.edu 687977Shsul@eecs.umich.edu/* print c count times */ 697978Sbinkertn@umich.eduvoid 707978Sbinkertn@umich.eduPutRepChar(char c, int count) 717977Shsul@eecs.umich.edu{ 728013Sbinkertn@umich.edu while (count--) 738013Sbinkertn@umich.edu PutChar(c); 747977Shsul@eecs.umich.edu} 757977Shsul@eecs.umich.edu 767977Shsul@eecs.umich.edu/* put string reverse */ 777978Sbinkertn@umich.eduvoid 787978Sbinkertn@umich.eduPutStringReverse(const char *s, int index) 797977Shsul@eecs.umich.edu{ 808013Sbinkertn@umich.edu while (index-- > 0) 818013Sbinkertn@umich.edu PutChar(s[index]); 827977Shsul@eecs.umich.edu} 837977Shsul@eecs.umich.edu 848013Sbinkertn@umich.edu/* 858013Sbinkertn@umich.edu * prints value in radix, in a field width width, with fill 868013Sbinkertn@umich.edu * character fill 878013Sbinkertn@umich.edu * if radix is negative, print as signed quantity 888013Sbinkertn@umich.edu * if width is negative, left justify 898013Sbinkertn@umich.edu * if width is 0, use whatever is needed 908013Sbinkertn@umich.edu * if fill is 0, use ' ' 917977Shsul@eecs.umich.edu */ 927978Sbinkertn@umich.eduvoid 938013Sbinkertn@umich.eduPutNumber(long value, int radix, int width, char fill) 947977Shsul@eecs.umich.edu{ 958013Sbinkertn@umich.edu char buffer[40]; 968013Sbinkertn@umich.edu uint bufferindex = 0; 978013Sbinkertn@umich.edu ulong uvalue; 988013Sbinkertn@umich.edu ushort digit; 998013Sbinkertn@umich.edu ushort left = 0; 1008013Sbinkertn@umich.edu ushort negative = 0; 1017977Shsul@eecs.umich.edu 1028013Sbinkertn@umich.edu if (fill == 0) 1038013Sbinkertn@umich.edu fill = ' '; 1047977Shsul@eecs.umich.edu 1058013Sbinkertn@umich.edu if (width < 0) { 1068013Sbinkertn@umich.edu width = -width; 1078013Sbinkertn@umich.edu left = 1; 1087977Shsul@eecs.umich.edu } 1097977Shsul@eecs.umich.edu 1108013Sbinkertn@umich.edu if (width < 0 || width > 80) 1118013Sbinkertn@umich.edu width = 0; 1128013Sbinkertn@umich.edu 1138013Sbinkertn@umich.edu if (radix < 0) { 1148013Sbinkertn@umich.edu radix = -radix; 1158013Sbinkertn@umich.edu if (value < 0) { 1168013Sbinkertn@umich.edu negative = 1; 1178013Sbinkertn@umich.edu value = -value; 1188013Sbinkertn@umich.edu } 1197977Shsul@eecs.umich.edu } 1208013Sbinkertn@umich.edu 1218013Sbinkertn@umich.edu switch (radix) { 1228013Sbinkertn@umich.edu case 8: 1238013Sbinkertn@umich.edu case 10: 1248013Sbinkertn@umich.edu case 16: 1258013Sbinkertn@umich.edu break; 1268013Sbinkertn@umich.edu 1278013Sbinkertn@umich.edu default: 1288013Sbinkertn@umich.edu PutString("****"); 1298013Sbinkertn@umich.edu return; 1307977Shsul@eecs.umich.edu } 1318013Sbinkertn@umich.edu 1328013Sbinkertn@umich.edu uvalue = value; 1338013Sbinkertn@umich.edu 1348013Sbinkertn@umich.edu do { 1358013Sbinkertn@umich.edu if (radix != 16) { 1368013Sbinkertn@umich.edu digit = (ushort)(uvalue % radix); 1378013Sbinkertn@umich.edu uvalue /= radix; 1388013Sbinkertn@umich.edu } else { 1398013Sbinkertn@umich.edu digit = (ushort)(uvalue & 0xf); 1408013Sbinkertn@umich.edu uvalue = uvalue >> 4; 1418013Sbinkertn@umich.edu } 1428013Sbinkertn@umich.edu buffer[bufferindex] = digit + ((digit <= 9) ? '0' : ('A' - 10)); 1438013Sbinkertn@umich.edu bufferindex += 1; 1448013Sbinkertn@umich.edu } while (uvalue != 0); 1458013Sbinkertn@umich.edu 1468013Sbinkertn@umich.edu /* fill # ' ' and negative cannot happen at once */ 1478013Sbinkertn@umich.edu if (negative) { 1488013Sbinkertn@umich.edu buffer[bufferindex] = '-'; 1498013Sbinkertn@umich.edu bufferindex += 1; 1507977Shsul@eecs.umich.edu } 1518013Sbinkertn@umich.edu 1528013Sbinkertn@umich.edu if ((uint)width <= bufferindex) { 1538013Sbinkertn@umich.edu PutStringReverse(buffer, bufferindex); 1548013Sbinkertn@umich.edu } else { 1558013Sbinkertn@umich.edu width -= bufferindex; 1568013Sbinkertn@umich.edu if (!left) 1578013Sbinkertn@umich.edu PutRepChar(fill, width); 1588013Sbinkertn@umich.edu PutStringReverse(buffer, bufferindex); 1598013Sbinkertn@umich.edu if (left) 1608013Sbinkertn@umich.edu PutRepChar(fill, width); 1617977Shsul@eecs.umich.edu } 1627977Shsul@eecs.umich.edu} 1637977Shsul@eecs.umich.edu 1648013Sbinkertn@umich.eduulong 1658013Sbinkertn@umich.edupower(long base, long n) 1667977Shsul@eecs.umich.edu{ 1678013Sbinkertn@umich.edu ulong p; 1687977Shsul@eecs.umich.edu 1698013Sbinkertn@umich.edu for (p = 1; n > 0; --n) 1708013Sbinkertn@umich.edu p = p * base; 1718013Sbinkertn@umich.edu return p; 1727977Shsul@eecs.umich.edu} 1737977Shsul@eecs.umich.edu 1748013Sbinkertn@umich.eduvoid 1758013Sbinkertn@umich.eduputFloat(double a, int fieldwidth, char fill) 1767977Shsul@eecs.umich.edu{ 1778013Sbinkertn@umich.edu int i; 1788013Sbinkertn@umich.edu ulong b; 1797977Shsul@eecs.umich.edu 1808013Sbinkertn@umich.edu /* 1818013Sbinkertn@umich.edu * Put out everything before the decimal place. 1828013Sbinkertn@umich.edu */ 1838013Sbinkertn@umich.edu PutNumber(((ulong) a), 10, fieldwidth, fill); 1848013Sbinkertn@umich.edu 1858013Sbinkertn@umich.edu /* 1868013Sbinkertn@umich.edu * Output the decimal place. 1878013Sbinkertn@umich.edu */ 1888013Sbinkertn@umich.edu PutChar('.' & 0x7f); 1898013Sbinkertn@umich.edu 1908013Sbinkertn@umich.edu /* 1918013Sbinkertn@umich.edu * Output the n digits after the decimal place. 1928013Sbinkertn@umich.edu */ 1938013Sbinkertn@umich.edu for (i = 1; i < 6; i++) { 1948013Sbinkertn@umich.edu b = (ulong)(power(10, i) * (double)(a - (ulong) a)); 1958013Sbinkertn@umich.edu PutChar((char)(b % 10) + '0'); 1968013Sbinkertn@umich.edu } 1977977Shsul@eecs.umich.edu} 1988013Sbinkertn@umich.edu 1997978Sbinkertn@umich.educonst char * 2007978Sbinkertn@umich.eduFormatItem(const char *f, va_list *ap) 2017977Shsul@eecs.umich.edu{ 2028013Sbinkertn@umich.edu char c; 2038013Sbinkertn@umich.edu int fieldwidth = 0; 2048013Sbinkertn@umich.edu int leftjust = 0; 2058013Sbinkertn@umich.edu int radix = 0; 2068013Sbinkertn@umich.edu char fill = ' '; 2077977Shsul@eecs.umich.edu 2088013Sbinkertn@umich.edu if (*f == '0') 2098013Sbinkertn@umich.edu fill = '0'; 2108013Sbinkertn@umich.edu 2118013Sbinkertn@umich.edu while (c = *f++) { 2128013Sbinkertn@umich.edu if (c >= '0' && c <= '9') { 2138013Sbinkertn@umich.edu fieldwidth = (fieldwidth * 10) + (c - '0'); 2148013Sbinkertn@umich.edu } else { 2158013Sbinkertn@umich.edu switch (c) { 2168013Sbinkertn@umich.edu case '\000': 2178013Sbinkertn@umich.edu return(--f); 2188013Sbinkertn@umich.edu case '%': 2198013Sbinkertn@umich.edu PutChar('%'); 2208013Sbinkertn@umich.edu return(f); 2218013Sbinkertn@umich.edu case '-': 2228013Sbinkertn@umich.edu leftjust = 1; 2238013Sbinkertn@umich.edu break; 2248013Sbinkertn@umich.edu case 'c': { 2258013Sbinkertn@umich.edu char a = (char)va_arg(*ap, int); 2268013Sbinkertn@umich.edu 2278013Sbinkertn@umich.edu if (leftjust) 2288013Sbinkertn@umich.edu PutChar(a & 0x7f); 2298013Sbinkertn@umich.edu if (fieldwidth > 0) 2308013Sbinkertn@umich.edu PutRepChar(fill, fieldwidth - 1); 2318013Sbinkertn@umich.edu if (!leftjust) 2328013Sbinkertn@umich.edu PutChar(a & 0x7f); 2338013Sbinkertn@umich.edu return(f); 2348013Sbinkertn@umich.edu } 2358013Sbinkertn@umich.edu case 's': { 2368013Sbinkertn@umich.edu const char *a = va_arg(*ap, const char *); 2378013Sbinkertn@umich.edu 2388013Sbinkertn@umich.edu if (leftjust) 2398013Sbinkertn@umich.edu PutString((const char *) a); 2408013Sbinkertn@umich.edu if (fieldwidth > strlen((const char *) a)) 2418013Sbinkertn@umich.edu PutRepChar(fill, fieldwidth - strlen((const char *)a)); 2428013Sbinkertn@umich.edu if (!leftjust) 2438013Sbinkertn@umich.edu PutString((const char *) a); 2448013Sbinkertn@umich.edu return(f); 2458013Sbinkertn@umich.edu } 2468013Sbinkertn@umich.edu case 'd': 2478013Sbinkertn@umich.edu radix = -10; 2488013Sbinkertn@umich.edu break; 2498013Sbinkertn@umich.edu case 'u': 2508013Sbinkertn@umich.edu radix = 10; 2518013Sbinkertn@umich.edu break; 2528013Sbinkertn@umich.edu case 'x': 2538013Sbinkertn@umich.edu radix = 16; 2548013Sbinkertn@umich.edu break; 2558013Sbinkertn@umich.edu case 'X': 2568013Sbinkertn@umich.edu radix = 16; 2578013Sbinkertn@umich.edu break; 2588013Sbinkertn@umich.edu case 'o': 2598013Sbinkertn@umich.edu radix = 8; 2608013Sbinkertn@umich.edu break; 2618013Sbinkertn@umich.edu case 'f': { 2628013Sbinkertn@umich.edu double a = va_arg(*ap, double); 2638013Sbinkertn@umich.edu 2648013Sbinkertn@umich.edu putFloat(a, fieldwidth, fill); 2658013Sbinkertn@umich.edu return(f); 2668013Sbinkertn@umich.edu } 2678013Sbinkertn@umich.edu default: /* unknown switch! */ 2688013Sbinkertn@umich.edu radix = 3; 2698013Sbinkertn@umich.edu break; 2708013Sbinkertn@umich.edu } 2717977Shsul@eecs.umich.edu } 2727977Shsul@eecs.umich.edu 2738013Sbinkertn@umich.edu if (radix) 2748013Sbinkertn@umich.edu break; 2758013Sbinkertn@umich.edu } 2767977Shsul@eecs.umich.edu 2778013Sbinkertn@umich.edu if (leftjust) 2788013Sbinkertn@umich.edu fieldwidth = -fieldwidth; 2798013Sbinkertn@umich.edu 2808013Sbinkertn@umich.edu long a = va_arg(*ap, long); 2818013Sbinkertn@umich.edu PutNumber(a, radix, fieldwidth, fill); 2828013Sbinkertn@umich.edu 2838013Sbinkertn@umich.edu return(f); 2847977Shsul@eecs.umich.edu} 2857977Shsul@eecs.umich.edu 2867978Sbinkertn@umich.eduint 2877978Sbinkertn@umich.eduprintf(const char *f, ...) 2887977Shsul@eecs.umich.edu{ 2898013Sbinkertn@umich.edu va_list ap; 2907977Shsul@eecs.umich.edu 2918013Sbinkertn@umich.edu va_start(ap, f); 2927977Shsul@eecs.umich.edu 2938013Sbinkertn@umich.edu while (*f) { 2948013Sbinkertn@umich.edu if (*f == '%') 2958013Sbinkertn@umich.edu f = FormatItem(f + 1, &ap); 2968013Sbinkertn@umich.edu else 2978013Sbinkertn@umich.edu PutChar(*f++); 2988013Sbinkertn@umich.edu } 2997977Shsul@eecs.umich.edu 3008013Sbinkertn@umich.edu if (*(f - 1) == '\n') { 3018013Sbinkertn@umich.edu /* add a line-feed (SimOS console output goes to shell */ 3028013Sbinkertn@umich.edu PutChar('\r'); 3038013Sbinkertn@umich.edu } 3047977Shsul@eecs.umich.edu 3058013Sbinkertn@umich.edu va_end(ap); /* clean up */ 3068013Sbinkertn@umich.edu return 0; 3077977Shsul@eecs.umich.edu} 3087977Shsul@eecs.umich.edu 3097978Sbinkertn@umich.eduvoid 3107978Sbinkertn@umich.edupanic(const char *f, ...) 3117977Shsul@eecs.umich.edu{ 3128013Sbinkertn@umich.edu va_list ap; 3137977Shsul@eecs.umich.edu 3148013Sbinkertn@umich.edu va_start(ap, f); 3157977Shsul@eecs.umich.edu 3168013Sbinkertn@umich.edu printf("CONSOLE PANIC (looping): "); 3178013Sbinkertn@umich.edu while (*f) { 3188013Sbinkertn@umich.edu if (*f == '%') 3198013Sbinkertn@umich.edu f = FormatItem(f + 1, &ap); 3208013Sbinkertn@umich.edu else 3218013Sbinkertn@umich.edu PutChar(*f++); 3227977Shsul@eecs.umich.edu } 3237977Shsul@eecs.umich.edu 3248013Sbinkertn@umich.edu va_end(ap); /* clean up */ 3258024Ssaidi@eecs.umich.edu m5_panic(); 3267977Shsul@eecs.umich.edu} 327