18012Ssaidi@eecs.umich.edu/*
28029Snate@binkert.org * Copyright (c) 2003-2004 The Regents of The University of Michigan
38029Snate@binkert.org * Copyright (c) 1993 The Hewlett-Packard Development Company
48029Snate@binkert.org * All rights reserved.
58013Sbinkertn@umich.edu *
68029Snate@binkert.org * Redistribution and use in source and binary forms, with or without
78029Snate@binkert.org * modification, are permitted provided that the following conditions are
88029Snate@binkert.org * met: redistributions of source code must retain the above copyright
98029Snate@binkert.org * notice, this list of conditions and the following disclaimer;
108029Snate@binkert.org * redistributions in binary form must reproduce the above copyright
118029Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
128029Snate@binkert.org * documentation and/or other materials provided with the distribution;
138029Snate@binkert.org * neither the name of the copyright holders nor the names of its
148029Snate@binkert.org * contributors may be used to endorse or promote products derived from
158029Snate@binkert.org * this software without specific prior written permission.
168013Sbinkertn@umich.edu *
178029Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
188029Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
198029Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
208029Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
218029Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
228029Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
238029Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
248029Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
258029Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268029Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
278029Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
287977Shsul@eecs.umich.edu */
297977Shsul@eecs.umich.edu
308013Sbinkertn@umich.edu#include <sys/types.h>
317977Shsul@eecs.umich.edu#include <stdarg.h>
328024Ssaidi@eecs.umich.edu#include <stdint.h>
338024Ssaidi@eecs.umich.edu#include "m5op.h"
347977Shsul@eecs.umich.edu
357977Shsul@eecs.umich.edu/* The string s is terminated by a '\0' */
367978Sbinkertn@umich.eduvoid
377978Sbinkertn@umich.eduPutString(const char *s)
387977Shsul@eecs.umich.edu{
398013Sbinkertn@umich.edu    while (*s)
408013Sbinkertn@umich.edu        PutChar(*s++);
417977Shsul@eecs.umich.edu}
427977Shsul@eecs.umich.edu
437977Shsul@eecs.umich.edu/* print c count times */
447978Sbinkertn@umich.eduvoid
457978Sbinkertn@umich.eduPutRepChar(char c, int count)
467977Shsul@eecs.umich.edu{
478013Sbinkertn@umich.edu    while (count--)
488013Sbinkertn@umich.edu        PutChar(c);
497977Shsul@eecs.umich.edu}
507977Shsul@eecs.umich.edu
517977Shsul@eecs.umich.edu/* put string reverse */
527978Sbinkertn@umich.eduvoid
537978Sbinkertn@umich.eduPutStringReverse(const char *s, int index)
547977Shsul@eecs.umich.edu{
558013Sbinkertn@umich.edu    while (index-- > 0)
568013Sbinkertn@umich.edu        PutChar(s[index]);
577977Shsul@eecs.umich.edu}
587977Shsul@eecs.umich.edu
598013Sbinkertn@umich.edu/*
608013Sbinkertn@umich.edu * prints value in radix, in a field width width, with fill
618013Sbinkertn@umich.edu * character fill
628013Sbinkertn@umich.edu * if radix is negative, print as signed quantity
638013Sbinkertn@umich.edu * if width is negative, left justify
648013Sbinkertn@umich.edu * if width is 0, use whatever is needed
658013Sbinkertn@umich.edu * if fill is 0, use ' '
667977Shsul@eecs.umich.edu */
677978Sbinkertn@umich.eduvoid
688013Sbinkertn@umich.eduPutNumber(long value, int radix, int width, char fill)
697977Shsul@eecs.umich.edu{
708013Sbinkertn@umich.edu    char buffer[40];
718013Sbinkertn@umich.edu    uint bufferindex = 0;
728013Sbinkertn@umich.edu    ulong uvalue;
738013Sbinkertn@umich.edu    ushort digit;
748013Sbinkertn@umich.edu    ushort left = 0;
758013Sbinkertn@umich.edu    ushort negative = 0;
767977Shsul@eecs.umich.edu
778013Sbinkertn@umich.edu    if (fill == 0)
788013Sbinkertn@umich.edu        fill = ' ';
797977Shsul@eecs.umich.edu
808013Sbinkertn@umich.edu    if (width < 0) {
818013Sbinkertn@umich.edu        width = -width;
828013Sbinkertn@umich.edu        left = 1;
837977Shsul@eecs.umich.edu    }
847977Shsul@eecs.umich.edu
858013Sbinkertn@umich.edu    if (width < 0 || width > 80)
868013Sbinkertn@umich.edu        width = 0;
878013Sbinkertn@umich.edu
888013Sbinkertn@umich.edu    if (radix < 0) {
898013Sbinkertn@umich.edu        radix = -radix;
908013Sbinkertn@umich.edu        if (value < 0) {
918013Sbinkertn@umich.edu            negative = 1;
928013Sbinkertn@umich.edu            value = -value;
938013Sbinkertn@umich.edu        }
947977Shsul@eecs.umich.edu    }
958013Sbinkertn@umich.edu
968013Sbinkertn@umich.edu    switch (radix) {
978013Sbinkertn@umich.edu      case 8:
988013Sbinkertn@umich.edu      case 10:
998013Sbinkertn@umich.edu      case 16:
1008013Sbinkertn@umich.edu        break;
1018013Sbinkertn@umich.edu
1028013Sbinkertn@umich.edu      default:
1038013Sbinkertn@umich.edu        PutString("****");
1048013Sbinkertn@umich.edu        return;
1057977Shsul@eecs.umich.edu    }
1068013Sbinkertn@umich.edu
1078013Sbinkertn@umich.edu    uvalue = value;
1088013Sbinkertn@umich.edu
1098013Sbinkertn@umich.edu    do {
1108013Sbinkertn@umich.edu        if (radix != 16) {
1118013Sbinkertn@umich.edu            digit = (ushort)(uvalue % radix);
1128013Sbinkertn@umich.edu            uvalue /= radix;
1138013Sbinkertn@umich.edu        } else {
1148013Sbinkertn@umich.edu            digit = (ushort)(uvalue & 0xf);
1158013Sbinkertn@umich.edu            uvalue = uvalue >> 4;
1168013Sbinkertn@umich.edu        }
1178013Sbinkertn@umich.edu        buffer[bufferindex] = digit + ((digit <= 9) ? '0' : ('A' - 10));
1188013Sbinkertn@umich.edu        bufferindex += 1;
1198013Sbinkertn@umich.edu    } while (uvalue != 0);
1208013Sbinkertn@umich.edu
1218013Sbinkertn@umich.edu  /* fill # ' ' and negative cannot happen at once */
1228013Sbinkertn@umich.edu    if (negative) {
1238013Sbinkertn@umich.edu        buffer[bufferindex] = '-';
1248013Sbinkertn@umich.edu        bufferindex += 1;
1257977Shsul@eecs.umich.edu    }
1268013Sbinkertn@umich.edu
1278013Sbinkertn@umich.edu    if ((uint)width <= bufferindex) {
1288013Sbinkertn@umich.edu        PutStringReverse(buffer, bufferindex);
1298013Sbinkertn@umich.edu    } else {
1308013Sbinkertn@umich.edu        width -= bufferindex;
1318013Sbinkertn@umich.edu        if (!left)
1328013Sbinkertn@umich.edu            PutRepChar(fill, width);
1338013Sbinkertn@umich.edu        PutStringReverse(buffer, bufferindex);
1348013Sbinkertn@umich.edu        if (left)
1358013Sbinkertn@umich.edu            PutRepChar(fill, width);
1367977Shsul@eecs.umich.edu    }
1377977Shsul@eecs.umich.edu}
1387977Shsul@eecs.umich.edu
1398013Sbinkertn@umich.eduulong
1408013Sbinkertn@umich.edupower(long base, long n)
1417977Shsul@eecs.umich.edu{
1428013Sbinkertn@umich.edu    ulong p;
1437977Shsul@eecs.umich.edu
1448013Sbinkertn@umich.edu    for (p = 1; n > 0; --n)
1458013Sbinkertn@umich.edu        p = p * base;
1468013Sbinkertn@umich.edu    return p;
1477977Shsul@eecs.umich.edu}
1487977Shsul@eecs.umich.edu
1498013Sbinkertn@umich.eduvoid
1508013Sbinkertn@umich.eduputFloat(double a, int fieldwidth, char fill)
1517977Shsul@eecs.umich.edu{
1528013Sbinkertn@umich.edu    int i;
1538013Sbinkertn@umich.edu    ulong b;
1547977Shsul@eecs.umich.edu
1558013Sbinkertn@umich.edu    /*
1568013Sbinkertn@umich.edu     *  Put out everything before the decimal place.
1578013Sbinkertn@umich.edu     */
1588013Sbinkertn@umich.edu    PutNumber(((ulong) a), 10, fieldwidth, fill);
1598013Sbinkertn@umich.edu
1608013Sbinkertn@umich.edu    /*
1618013Sbinkertn@umich.edu     *  Output the decimal place.
1628013Sbinkertn@umich.edu     */
1638013Sbinkertn@umich.edu    PutChar('.' & 0x7f);
1648013Sbinkertn@umich.edu
1658013Sbinkertn@umich.edu    /*
1668013Sbinkertn@umich.edu     *  Output the n digits after the decimal place.
1678013Sbinkertn@umich.edu     */
1688013Sbinkertn@umich.edu    for (i = 1; i < 6; i++) {
1698013Sbinkertn@umich.edu        b = (ulong)(power(10, i) * (double)(a - (ulong) a));
1708013Sbinkertn@umich.edu        PutChar((char)(b % 10) + '0');
1718013Sbinkertn@umich.edu    }
1727977Shsul@eecs.umich.edu}
1738013Sbinkertn@umich.edu
1747978Sbinkertn@umich.educonst char *
1757978Sbinkertn@umich.eduFormatItem(const char *f, va_list *ap)
1767977Shsul@eecs.umich.edu{
1778013Sbinkertn@umich.edu    char c;
1788013Sbinkertn@umich.edu    int fieldwidth = 0;
1798013Sbinkertn@umich.edu    int leftjust = 0;
1808013Sbinkertn@umich.edu    int radix = 0;
1818013Sbinkertn@umich.edu    char fill = ' ';
1827977Shsul@eecs.umich.edu
1838013Sbinkertn@umich.edu    if (*f == '0')
1848013Sbinkertn@umich.edu        fill = '0';
1858013Sbinkertn@umich.edu
1868013Sbinkertn@umich.edu    while (c = *f++) {
1878013Sbinkertn@umich.edu        if (c >= '0' && c <= '9') {
1888013Sbinkertn@umich.edu            fieldwidth = (fieldwidth * 10) + (c - '0');
1898013Sbinkertn@umich.edu        } else {
1908013Sbinkertn@umich.edu            switch (c) {
1918013Sbinkertn@umich.edu              case '\000':
1928013Sbinkertn@umich.edu                return(--f);
1938013Sbinkertn@umich.edu              case '%':
1948013Sbinkertn@umich.edu                PutChar('%');
1958013Sbinkertn@umich.edu                return(f);
1968013Sbinkertn@umich.edu              case '-':
1978013Sbinkertn@umich.edu                leftjust = 1;
1988013Sbinkertn@umich.edu                break;
1998013Sbinkertn@umich.edu              case 'c': {
2008013Sbinkertn@umich.edu                  char a = (char)va_arg(*ap, int);
2018013Sbinkertn@umich.edu
2028013Sbinkertn@umich.edu                  if (leftjust)
2038013Sbinkertn@umich.edu                      PutChar(a & 0x7f);
2048013Sbinkertn@umich.edu                  if (fieldwidth > 0)
2058013Sbinkertn@umich.edu                      PutRepChar(fill, fieldwidth - 1);
2068013Sbinkertn@umich.edu                  if (!leftjust)
2078013Sbinkertn@umich.edu                      PutChar(a & 0x7f);
2088013Sbinkertn@umich.edu                  return(f);
2098013Sbinkertn@umich.edu              }
2108013Sbinkertn@umich.edu              case 's': {
2118013Sbinkertn@umich.edu                  const char *a = va_arg(*ap, const char *);
2128013Sbinkertn@umich.edu
2138013Sbinkertn@umich.edu                  if (leftjust)
2148013Sbinkertn@umich.edu                      PutString((const char *) a);
2158013Sbinkertn@umich.edu                  if (fieldwidth > strlen((const char *) a))
2168013Sbinkertn@umich.edu                      PutRepChar(fill, fieldwidth - strlen((const char *)a));
2178013Sbinkertn@umich.edu                  if (!leftjust)
2188013Sbinkertn@umich.edu                      PutString((const char *) a);
2198013Sbinkertn@umich.edu                  return(f);
2208013Sbinkertn@umich.edu              }
2218013Sbinkertn@umich.edu              case 'd':
2228013Sbinkertn@umich.edu                radix = -10;
2238013Sbinkertn@umich.edu                break;
2248013Sbinkertn@umich.edu              case 'u':
2258013Sbinkertn@umich.edu                radix = 10;
2268013Sbinkertn@umich.edu                break;
2278013Sbinkertn@umich.edu              case 'x':
2288013Sbinkertn@umich.edu                radix = 16;
2298013Sbinkertn@umich.edu                break;
2308013Sbinkertn@umich.edu              case 'X':
2318013Sbinkertn@umich.edu                radix = 16;
2328013Sbinkertn@umich.edu                break;
2338013Sbinkertn@umich.edu              case 'o':
2348013Sbinkertn@umich.edu                radix = 8;
2358013Sbinkertn@umich.edu                break;
2368013Sbinkertn@umich.edu              case 'f': {
2378013Sbinkertn@umich.edu                  double a = va_arg(*ap, double);
2388013Sbinkertn@umich.edu
2398013Sbinkertn@umich.edu                  putFloat(a, fieldwidth, fill);
2408013Sbinkertn@umich.edu                  return(f);
2418013Sbinkertn@umich.edu              }
2428013Sbinkertn@umich.edu              default:   /* unknown switch! */
2438013Sbinkertn@umich.edu                radix = 3;
2448013Sbinkertn@umich.edu                break;
2458013Sbinkertn@umich.edu            }
2467977Shsul@eecs.umich.edu        }
2477977Shsul@eecs.umich.edu
2488013Sbinkertn@umich.edu        if (radix)
2498013Sbinkertn@umich.edu            break;
2508013Sbinkertn@umich.edu    }
2517977Shsul@eecs.umich.edu
2528013Sbinkertn@umich.edu    if (leftjust)
2538013Sbinkertn@umich.edu        fieldwidth = -fieldwidth;
2548013Sbinkertn@umich.edu
2558013Sbinkertn@umich.edu    long a = va_arg(*ap, long);
2568013Sbinkertn@umich.edu    PutNumber(a, radix, fieldwidth, fill);
2578013Sbinkertn@umich.edu
2588013Sbinkertn@umich.edu    return(f);
2597977Shsul@eecs.umich.edu}
2607977Shsul@eecs.umich.edu
2617978Sbinkertn@umich.eduint
2627978Sbinkertn@umich.eduprintf(const char *f, ...)
2637977Shsul@eecs.umich.edu{
2648013Sbinkertn@umich.edu    va_list ap;
2657977Shsul@eecs.umich.edu
2668013Sbinkertn@umich.edu    va_start(ap, f);
2677977Shsul@eecs.umich.edu
2688013Sbinkertn@umich.edu    while (*f) {
2698013Sbinkertn@umich.edu        if (*f == '%')
2708013Sbinkertn@umich.edu            f = FormatItem(f + 1, &ap);
2718013Sbinkertn@umich.edu        else
2728013Sbinkertn@umich.edu            PutChar(*f++);
2738013Sbinkertn@umich.edu    }
2747977Shsul@eecs.umich.edu
2758013Sbinkertn@umich.edu    if (*(f - 1) == '\n') {
2768013Sbinkertn@umich.edu        /* add a line-feed (SimOS console output goes to shell */
2778013Sbinkertn@umich.edu        PutChar('\r');
2788013Sbinkertn@umich.edu    }
2797977Shsul@eecs.umich.edu
2808013Sbinkertn@umich.edu    va_end(ap);         /* clean up */
2818013Sbinkertn@umich.edu    return 0;
2827977Shsul@eecs.umich.edu}
2837977Shsul@eecs.umich.edu
2847978Sbinkertn@umich.eduvoid
2857978Sbinkertn@umich.edupanic(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    printf("CONSOLE PANIC (looping): ");
2928013Sbinkertn@umich.edu    while (*f) {
2938013Sbinkertn@umich.edu        if (*f == '%')
2948013Sbinkertn@umich.edu            f = FormatItem(f + 1, &ap);
2958013Sbinkertn@umich.edu        else
2968013Sbinkertn@umich.edu            PutChar(*f++);
2977977Shsul@eecs.umich.edu    }
2987977Shsul@eecs.umich.edu
2998013Sbinkertn@umich.edu    va_end(ap);         /* clean up */
3008024Ssaidi@eecs.umich.edu    m5_panic();
3017977Shsul@eecs.umich.edu}
302