printf.c revision 8013
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> 577977Shsul@eecs.umich.edu 587977Shsul@eecs.umich.edu/* The string s is terminated by a '\0' */ 597978Sbinkertn@umich.eduvoid 607978Sbinkertn@umich.eduPutString(const char *s) 617977Shsul@eecs.umich.edu{ 628013Sbinkertn@umich.edu while (*s) 638013Sbinkertn@umich.edu PutChar(*s++); 647977Shsul@eecs.umich.edu} 657977Shsul@eecs.umich.edu 667977Shsul@eecs.umich.edu/* print c count times */ 677978Sbinkertn@umich.eduvoid 687978Sbinkertn@umich.eduPutRepChar(char c, int count) 697977Shsul@eecs.umich.edu{ 708013Sbinkertn@umich.edu while (count--) 718013Sbinkertn@umich.edu PutChar(c); 727977Shsul@eecs.umich.edu} 737977Shsul@eecs.umich.edu 747977Shsul@eecs.umich.edu/* put string reverse */ 757978Sbinkertn@umich.eduvoid 767978Sbinkertn@umich.eduPutStringReverse(const char *s, int index) 777977Shsul@eecs.umich.edu{ 788013Sbinkertn@umich.edu while (index-- > 0) 798013Sbinkertn@umich.edu PutChar(s[index]); 807977Shsul@eecs.umich.edu} 817977Shsul@eecs.umich.edu 828013Sbinkertn@umich.edu/* 838013Sbinkertn@umich.edu * prints value in radix, in a field width width, with fill 848013Sbinkertn@umich.edu * character fill 858013Sbinkertn@umich.edu * if radix is negative, print as signed quantity 868013Sbinkertn@umich.edu * if width is negative, left justify 878013Sbinkertn@umich.edu * if width is 0, use whatever is needed 888013Sbinkertn@umich.edu * if fill is 0, use ' ' 897977Shsul@eecs.umich.edu */ 907978Sbinkertn@umich.eduvoid 918013Sbinkertn@umich.eduPutNumber(long value, int radix, int width, char fill) 927977Shsul@eecs.umich.edu{ 938013Sbinkertn@umich.edu char buffer[40]; 948013Sbinkertn@umich.edu uint bufferindex = 0; 958013Sbinkertn@umich.edu ulong uvalue; 968013Sbinkertn@umich.edu ushort digit; 978013Sbinkertn@umich.edu ushort left = 0; 988013Sbinkertn@umich.edu ushort negative = 0; 997977Shsul@eecs.umich.edu 1008013Sbinkertn@umich.edu if (fill == 0) 1018013Sbinkertn@umich.edu fill = ' '; 1027977Shsul@eecs.umich.edu 1038013Sbinkertn@umich.edu if (width < 0) { 1048013Sbinkertn@umich.edu width = -width; 1058013Sbinkertn@umich.edu left = 1; 1067977Shsul@eecs.umich.edu } 1077977Shsul@eecs.umich.edu 1088013Sbinkertn@umich.edu if (width < 0 || width > 80) 1098013Sbinkertn@umich.edu width = 0; 1108013Sbinkertn@umich.edu 1118013Sbinkertn@umich.edu if (radix < 0) { 1128013Sbinkertn@umich.edu radix = -radix; 1138013Sbinkertn@umich.edu if (value < 0) { 1148013Sbinkertn@umich.edu negative = 1; 1158013Sbinkertn@umich.edu value = -value; 1168013Sbinkertn@umich.edu } 1177977Shsul@eecs.umich.edu } 1188013Sbinkertn@umich.edu 1198013Sbinkertn@umich.edu switch (radix) { 1208013Sbinkertn@umich.edu case 8: 1218013Sbinkertn@umich.edu case 10: 1228013Sbinkertn@umich.edu case 16: 1238013Sbinkertn@umich.edu break; 1248013Sbinkertn@umich.edu 1258013Sbinkertn@umich.edu default: 1268013Sbinkertn@umich.edu PutString("****"); 1278013Sbinkertn@umich.edu return; 1287977Shsul@eecs.umich.edu } 1298013Sbinkertn@umich.edu 1308013Sbinkertn@umich.edu uvalue = value; 1318013Sbinkertn@umich.edu 1328013Sbinkertn@umich.edu do { 1338013Sbinkertn@umich.edu if (radix != 16) { 1348013Sbinkertn@umich.edu digit = (ushort)(uvalue % radix); 1358013Sbinkertn@umich.edu uvalue /= radix; 1368013Sbinkertn@umich.edu } else { 1378013Sbinkertn@umich.edu digit = (ushort)(uvalue & 0xf); 1388013Sbinkertn@umich.edu uvalue = uvalue >> 4; 1398013Sbinkertn@umich.edu } 1408013Sbinkertn@umich.edu buffer[bufferindex] = digit + ((digit <= 9) ? '0' : ('A' - 10)); 1418013Sbinkertn@umich.edu bufferindex += 1; 1428013Sbinkertn@umich.edu } while (uvalue != 0); 1438013Sbinkertn@umich.edu 1448013Sbinkertn@umich.edu /* fill # ' ' and negative cannot happen at once */ 1458013Sbinkertn@umich.edu if (negative) { 1468013Sbinkertn@umich.edu buffer[bufferindex] = '-'; 1478013Sbinkertn@umich.edu bufferindex += 1; 1487977Shsul@eecs.umich.edu } 1498013Sbinkertn@umich.edu 1508013Sbinkertn@umich.edu if ((uint)width <= bufferindex) { 1518013Sbinkertn@umich.edu PutStringReverse(buffer, bufferindex); 1528013Sbinkertn@umich.edu } else { 1538013Sbinkertn@umich.edu width -= bufferindex; 1548013Sbinkertn@umich.edu if (!left) 1558013Sbinkertn@umich.edu PutRepChar(fill, width); 1568013Sbinkertn@umich.edu PutStringReverse(buffer, bufferindex); 1578013Sbinkertn@umich.edu if (left) 1588013Sbinkertn@umich.edu PutRepChar(fill, width); 1597977Shsul@eecs.umich.edu } 1607977Shsul@eecs.umich.edu} 1617977Shsul@eecs.umich.edu 1628013Sbinkertn@umich.eduulong 1638013Sbinkertn@umich.edupower(long base, long n) 1647977Shsul@eecs.umich.edu{ 1658013Sbinkertn@umich.edu ulong p; 1667977Shsul@eecs.umich.edu 1678013Sbinkertn@umich.edu for (p = 1; n > 0; --n) 1688013Sbinkertn@umich.edu p = p * base; 1698013Sbinkertn@umich.edu return p; 1707977Shsul@eecs.umich.edu} 1717977Shsul@eecs.umich.edu 1728013Sbinkertn@umich.eduvoid 1738013Sbinkertn@umich.eduputFloat(double a, int fieldwidth, char fill) 1747977Shsul@eecs.umich.edu{ 1758013Sbinkertn@umich.edu int i; 1768013Sbinkertn@umich.edu ulong b; 1777977Shsul@eecs.umich.edu 1788013Sbinkertn@umich.edu /* 1798013Sbinkertn@umich.edu * Put out everything before the decimal place. 1808013Sbinkertn@umich.edu */ 1818013Sbinkertn@umich.edu PutNumber(((ulong) a), 10, fieldwidth, fill); 1828013Sbinkertn@umich.edu 1838013Sbinkertn@umich.edu /* 1848013Sbinkertn@umich.edu * Output the decimal place. 1858013Sbinkertn@umich.edu */ 1868013Sbinkertn@umich.edu PutChar('.' & 0x7f); 1878013Sbinkertn@umich.edu 1888013Sbinkertn@umich.edu /* 1898013Sbinkertn@umich.edu * Output the n digits after the decimal place. 1908013Sbinkertn@umich.edu */ 1918013Sbinkertn@umich.edu for (i = 1; i < 6; i++) { 1928013Sbinkertn@umich.edu b = (ulong)(power(10, i) * (double)(a - (ulong) a)); 1938013Sbinkertn@umich.edu PutChar((char)(b % 10) + '0'); 1948013Sbinkertn@umich.edu } 1957977Shsul@eecs.umich.edu} 1968013Sbinkertn@umich.edu 1977978Sbinkertn@umich.educonst char * 1987978Sbinkertn@umich.eduFormatItem(const char *f, va_list *ap) 1997977Shsul@eecs.umich.edu{ 2008013Sbinkertn@umich.edu char c; 2018013Sbinkertn@umich.edu int fieldwidth = 0; 2028013Sbinkertn@umich.edu int leftjust = 0; 2038013Sbinkertn@umich.edu int radix = 0; 2048013Sbinkertn@umich.edu char fill = ' '; 2057977Shsul@eecs.umich.edu 2068013Sbinkertn@umich.edu if (*f == '0') 2078013Sbinkertn@umich.edu fill = '0'; 2088013Sbinkertn@umich.edu 2098013Sbinkertn@umich.edu while (c = *f++) { 2108013Sbinkertn@umich.edu if (c >= '0' && c <= '9') { 2118013Sbinkertn@umich.edu fieldwidth = (fieldwidth * 10) + (c - '0'); 2128013Sbinkertn@umich.edu } else { 2138013Sbinkertn@umich.edu switch (c) { 2148013Sbinkertn@umich.edu case '\000': 2158013Sbinkertn@umich.edu return(--f); 2168013Sbinkertn@umich.edu case '%': 2178013Sbinkertn@umich.edu PutChar('%'); 2188013Sbinkertn@umich.edu return(f); 2198013Sbinkertn@umich.edu case '-': 2208013Sbinkertn@umich.edu leftjust = 1; 2218013Sbinkertn@umich.edu break; 2228013Sbinkertn@umich.edu case 'c': { 2238013Sbinkertn@umich.edu char a = (char)va_arg(*ap, int); 2248013Sbinkertn@umich.edu 2258013Sbinkertn@umich.edu if (leftjust) 2268013Sbinkertn@umich.edu PutChar(a & 0x7f); 2278013Sbinkertn@umich.edu if (fieldwidth > 0) 2288013Sbinkertn@umich.edu PutRepChar(fill, fieldwidth - 1); 2298013Sbinkertn@umich.edu if (!leftjust) 2308013Sbinkertn@umich.edu PutChar(a & 0x7f); 2318013Sbinkertn@umich.edu return(f); 2328013Sbinkertn@umich.edu } 2338013Sbinkertn@umich.edu case 's': { 2348013Sbinkertn@umich.edu const char *a = va_arg(*ap, const char *); 2358013Sbinkertn@umich.edu 2368013Sbinkertn@umich.edu if (leftjust) 2378013Sbinkertn@umich.edu PutString((const char *) a); 2388013Sbinkertn@umich.edu if (fieldwidth > strlen((const char *) a)) 2398013Sbinkertn@umich.edu PutRepChar(fill, fieldwidth - strlen((const char *)a)); 2408013Sbinkertn@umich.edu if (!leftjust) 2418013Sbinkertn@umich.edu PutString((const char *) a); 2428013Sbinkertn@umich.edu return(f); 2438013Sbinkertn@umich.edu } 2448013Sbinkertn@umich.edu case 'd': 2458013Sbinkertn@umich.edu radix = -10; 2468013Sbinkertn@umich.edu break; 2478013Sbinkertn@umich.edu case 'u': 2488013Sbinkertn@umich.edu radix = 10; 2498013Sbinkertn@umich.edu break; 2508013Sbinkertn@umich.edu case 'x': 2518013Sbinkertn@umich.edu radix = 16; 2528013Sbinkertn@umich.edu break; 2538013Sbinkertn@umich.edu case 'X': 2548013Sbinkertn@umich.edu radix = 16; 2558013Sbinkertn@umich.edu break; 2568013Sbinkertn@umich.edu case 'o': 2578013Sbinkertn@umich.edu radix = 8; 2588013Sbinkertn@umich.edu break; 2598013Sbinkertn@umich.edu case 'f': { 2608013Sbinkertn@umich.edu double a = va_arg(*ap, double); 2618013Sbinkertn@umich.edu 2628013Sbinkertn@umich.edu putFloat(a, fieldwidth, fill); 2638013Sbinkertn@umich.edu return(f); 2648013Sbinkertn@umich.edu } 2658013Sbinkertn@umich.edu default: /* unknown switch! */ 2668013Sbinkertn@umich.edu radix = 3; 2678013Sbinkertn@umich.edu break; 2688013Sbinkertn@umich.edu } 2697977Shsul@eecs.umich.edu } 2707977Shsul@eecs.umich.edu 2718013Sbinkertn@umich.edu if (radix) 2728013Sbinkertn@umich.edu break; 2738013Sbinkertn@umich.edu } 2747977Shsul@eecs.umich.edu 2758013Sbinkertn@umich.edu if (leftjust) 2768013Sbinkertn@umich.edu fieldwidth = -fieldwidth; 2778013Sbinkertn@umich.edu 2788013Sbinkertn@umich.edu long a = va_arg(*ap, long); 2798013Sbinkertn@umich.edu PutNumber(a, radix, fieldwidth, fill); 2808013Sbinkertn@umich.edu 2818013Sbinkertn@umich.edu return(f); 2827977Shsul@eecs.umich.edu} 2837977Shsul@eecs.umich.edu 2847978Sbinkertn@umich.eduint 2857978Sbinkertn@umich.eduprintf(const char *f, ...) 2867977Shsul@eecs.umich.edu{ 2878013Sbinkertn@umich.edu va_list ap; 2887977Shsul@eecs.umich.edu 2898013Sbinkertn@umich.edu va_start(ap, f); 2907977Shsul@eecs.umich.edu 2918013Sbinkertn@umich.edu while (*f) { 2928013Sbinkertn@umich.edu if (*f == '%') 2938013Sbinkertn@umich.edu f = FormatItem(f + 1, &ap); 2948013Sbinkertn@umich.edu else 2958013Sbinkertn@umich.edu PutChar(*f++); 2968013Sbinkertn@umich.edu } 2977977Shsul@eecs.umich.edu 2988013Sbinkertn@umich.edu if (*(f - 1) == '\n') { 2998013Sbinkertn@umich.edu /* add a line-feed (SimOS console output goes to shell */ 3008013Sbinkertn@umich.edu PutChar('\r'); 3018013Sbinkertn@umich.edu } 3027977Shsul@eecs.umich.edu 3038013Sbinkertn@umich.edu va_end(ap); /* clean up */ 3048013Sbinkertn@umich.edu return 0; 3057977Shsul@eecs.umich.edu} 3067977Shsul@eecs.umich.edu 3077978Sbinkertn@umich.eduvoid 3087978Sbinkertn@umich.edupanic(const char *f, ...) 3097977Shsul@eecs.umich.edu{ 3108013Sbinkertn@umich.edu va_list ap; 3117977Shsul@eecs.umich.edu 3128013Sbinkertn@umich.edu va_start(ap, f); 3137977Shsul@eecs.umich.edu 3148013Sbinkertn@umich.edu printf("CONSOLE PANIC (looping): "); 3158013Sbinkertn@umich.edu while (*f) { 3168013Sbinkertn@umich.edu if (*f == '%') 3178013Sbinkertn@umich.edu f = FormatItem(f + 1, &ap); 3188013Sbinkertn@umich.edu else 3198013Sbinkertn@umich.edu PutChar(*f++); 3207977Shsul@eecs.umich.edu } 3217977Shsul@eecs.umich.edu 3228013Sbinkertn@umich.edu va_end(ap); /* clean up */ 3238013Sbinkertn@umich.edu while(1); 3247977Shsul@eecs.umich.edu} 325