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