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