printk.cc revision 4429
16019Shines@cs.fsu.edu/*
26019Shines@cs.fsu.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan
37100Sgblack@eecs.umich.edu * All rights reserved.
47100Sgblack@eecs.umich.edu *
57100Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
67100Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
77100Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
87100Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
97100Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
107100Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
117100Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
127100Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
137100Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
147100Sgblack@eecs.umich.edu * this software without specific prior written permission.
156019Shines@cs.fsu.edu *
166019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276019Shines@cs.fsu.edu *
286019Shines@cs.fsu.edu * Authors: Nathan Binkert
296019Shines@cs.fsu.edu *          Ali Saidi
306019Shines@cs.fsu.edu */
316019Shines@cs.fsu.edu
326019Shines@cs.fsu.edu#include <sys/types.h>
336019Shines@cs.fsu.edu#include <algorithm>
346019Shines@cs.fsu.edu
356019Shines@cs.fsu.edu#include "arch/arguments.hh"
366019Shines@cs.fsu.edu#include "base/trace.hh"
376019Shines@cs.fsu.edu#include "kern/linux/printk.hh"
386019Shines@cs.fsu.edu
396019Shines@cs.fsu.eduusing namespace std;
406019Shines@cs.fsu.edu
416019Shines@cs.fsu.edu
426757SAli.Saidi@ARM.comvoid
436019Shines@cs.fsu.eduPrintk(stringstream &out, TheISA::Arguments args)
446019Shines@cs.fsu.edu{
456019Shines@cs.fsu.edu    char *p = (char *)args++;
466019Shines@cs.fsu.edu
476019Shines@cs.fsu.edu    while (*p) {
486019Shines@cs.fsu.edu        switch (*p) {
496019Shines@cs.fsu.edu          case '%': {
506019Shines@cs.fsu.edu              bool more = true;
517170Sgblack@eecs.umich.edu              bool islong = false;
526253Sgblack@eecs.umich.edu              bool leftjustify = false;
537202Sgblack@eecs.umich.edu              bool format = false;
546253Sgblack@eecs.umich.edu              bool zero = false;
556253Sgblack@eecs.umich.edu              int width = 0;
567396Sgblack@eecs.umich.edu              while (more && *++p) {
577405SAli.Saidi@ARM.com                  switch (*p) {
587259Sgblack@eecs.umich.edu                    case 'l':
597423Sgblack@eecs.umich.edu                    case 'L':
606397Sgblack@eecs.umich.edu                      islong = true;
616019Shines@cs.fsu.edu                      break;
626019Shines@cs.fsu.edu                    case '-':
636757SAli.Saidi@ARM.com                      leftjustify = true;
646019Shines@cs.fsu.edu                      break;
656397Sgblack@eecs.umich.edu                    case '#':
666019Shines@cs.fsu.edu                      format = true;
676397Sgblack@eecs.umich.edu                      break;
686019Shines@cs.fsu.edu                    case '0':
697404SAli.Saidi@ARM.com                      if (width)
706735Sgblack@eecs.umich.edu                          width *= 10;
717100Sgblack@eecs.umich.edu                      else
726019Shines@cs.fsu.edu                          zero = true;
736757SAli.Saidi@ARM.com                      break;
746757SAli.Saidi@ARM.com                    default:
756757SAli.Saidi@ARM.com                      if (*p >= '1' && *p <= '9')
767585SAli.Saidi@arm.com                          width = 10 * width + *p - '0';
777404SAli.Saidi@ARM.com                      else
786757SAli.Saidi@ARM.com                          more = false;
796757SAli.Saidi@ARM.com                      break;
806757SAli.Saidi@ARM.com                  }
816019Shines@cs.fsu.edu              }
826019Shines@cs.fsu.edu
836019Shines@cs.fsu.edu              bool hexnum = false;
846019Shines@cs.fsu.edu              bool octal = false;
856019Shines@cs.fsu.edu              bool sign = false;
866019Shines@cs.fsu.edu              switch (*p) {
876019Shines@cs.fsu.edu                case 'X':
886019Shines@cs.fsu.edu                case 'x':
896019Shines@cs.fsu.edu                  hexnum = true;
906019Shines@cs.fsu.edu                  break;
916019Shines@cs.fsu.edu                case 'O':
926019Shines@cs.fsu.edu                case 'o':
93                  octal = true;
94                  break;
95                case 'D':
96                case 'd':
97                  sign = true;
98                  break;
99                case 'P':
100                  format = true;
101                case 'p':
102                  hexnum = true;
103                  break;
104              }
105
106              switch (*p) {
107                case 'D':
108                case 'd':
109                case 'U':
110                case 'u':
111                case 'X':
112                case 'x':
113                case 'O':
114                case 'o':
115                case 'P':
116                case 'p': {
117                  if (hexnum)
118                      out << hex;
119
120                  if (octal)
121                      out << oct;
122
123                  if (format) {
124                      if (!zero)
125                          out.setf(ios::showbase);
126                      else {
127                          if (hexnum) {
128                              out << "0x";
129                              width -= 2;
130                          } else if (octal) {
131                              out << "0";
132                              width -= 1;
133                          }
134                      }
135                  }
136
137                  if (zero)
138                      out.fill('0');
139
140                  if (width > 0)
141                      out.width(width);
142
143                  if (leftjustify && !zero)
144                      out.setf(ios::left);
145
146                  if (sign) {
147                      if (islong)
148                          out << (int64_t)args;
149                      else
150                          out << (int32_t)args;
151                  } else {
152                      if (islong)
153                          out << (uint64_t)args;
154                      else
155                          out << (uint32_t)args;
156                  }
157
158                  if (zero)
159                      out.fill(' ');
160
161                  if (width > 0)
162                      out.width(0);
163
164                  out << dec;
165
166                  ++args;
167                }
168                  break;
169
170                case 's': {
171                    char *s = (char *)args;
172                    if (!s)
173                        s = "<NULL>";
174
175                    if (width > 0)
176                        out.width(width);
177                    if (leftjustify)
178                        out.setf(ios::left);
179
180                    out << s;
181                    ++args;
182                }
183                  break;
184                case 'C':
185                case 'c': {
186                    uint64_t mask = (*p == 'C') ? 0xffL : 0x7fL;
187                    uint64_t num;
188                    int width;
189
190                    if (islong) {
191                        num = (uint64_t)args;
192                        width = sizeof(uint64_t);
193                    } else {
194                        num = (uint32_t)args;
195                        width = sizeof(uint32_t);
196                    }
197
198                    while (width-- > 0) {
199                        char c = (char)(num & mask);
200                        if (c)
201                            out << c;
202                        num >>= 8;
203                    }
204
205                    ++args;
206                }
207                  break;
208                case 'b': {
209                  uint64_t n = (uint64_t)args++;
210                  char *s = (char *)args++;
211                  out << s << ": " << n;
212                }
213                  break;
214                case 'n':
215                case 'N': {
216                    args += 2;
217#if 0
218                    uint64_t n = (uint64_t)args++;
219                    struct reg_values *rv = (struct reg_values *)args++;
220#endif
221                }
222                  break;
223                case 'r':
224                case 'R': {
225                    args += 2;
226#if 0
227                    uint64_t n = (uint64_t)args++;
228                    struct reg_desc *rd = (struct reg_desc *)args++;
229#endif
230                }
231                  break;
232                case '%':
233                  out << '%';
234                  break;
235              }
236              ++p;
237          }
238            break;
239          case '\n':
240            out << endl;
241            ++p;
242            break;
243          case '\r':
244            ++p;
245            if (*p != '\n')
246                out << endl;
247            break;
248
249          default: {
250              size_t len = strcspn(p, "%\n\r\0");
251              out.write(p, len);
252              p += len;
253          }
254        }
255    }
256
257}
258
259