source: mainline/src/debug/print.c@ 18e0a6c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 18e0a6c was 18e0a6c, checked in by Jakub Jermar <jakub@…>, 20 years ago

Implement several assembler functions in gcc's asm notation instead of in .s or .S file.
Gain both better speed and size.

  • Property mode set to 100644
File size: 6.3 KB
RevLine 
[f761f1eb]1/*
2 * Copyright (C) 2001-2004 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <putchar.h>
30#include <print.h>
31#include <synch/spinlock.h>
[0d2f805]32#include <arch/arg.h>
[18e0a6c]33#include <arch/asm.h>
[0d2f805]34
[f761f1eb]35
[724b58a]36static char digits[] = "0123456789abcdef"; /**< Hexadecimal characters */
37static spinlock_t printflock; /**< printf spinlock */
[f761f1eb]38
[724b58a]39
40/** Print NULL terminated string
41 *
42 * Print characters from str using putchar() until
43 * \x00 character is reached.
44 *
45 * @param str Characters to print.
46 *
47 */
[27dc170]48void print_str(const char *str)
[f761f1eb]49{
[02a99d2]50 int i = 0;
[f761f1eb]51 char c;
[02a99d2]52
[f761f1eb]53 while (c = str[i++])
[02a99d2]54 putchar(c);
[f761f1eb]55}
56
57
[724b58a]58/** Print hexadecimal digits
59 *
60 * Print fixed count of hexadecimal digits from
61 * the number num. The digits are printed in
62 * natural left-to-right order starting with
63 * the width-th digit.
64 *
65 * @param num Number containing digits.
66 * @param width Count of digits to print.
67 *
[f761f1eb]68 */
[27dc170]69void print_fixed_hex(const __native num, const int width)
[f761f1eb]70{
71 int i;
72
73 for (i = width*8 - 4; i >= 0; i -= 4)
74 putchar(digits[(num>>i) & 0xf]);
75}
76
[724b58a]77
78/** Print number in given base
79 *
80 * Print significant digits of a number in given
81 * base.
82 *
83 * @param num Number to print.
84 * @param base Base to print the number in (should
85 * be in range 2 .. 16).
86 *
[f761f1eb]87 */
[02a99d2]88void print_number(const __native num, const unsigned int base)
[27dc170]89{
90 int val = num;
[199145a1]91 char d[sizeof(__native)*8+1]; /* this is good enough even for base == 2 */
[02a99d2]92 int i = sizeof(__native)*8-1;
93
[f761f1eb]94 do {
[27dc170]95 d[i--] = digits[val % base];
96 } while (val /= base);
[f761f1eb]97
[199145a1]98 d[sizeof(__native)*8] = 0;
[f761f1eb]99 print_str(&d[i + 1]);
100}
101
[724b58a]102
103/** General formatted text print
104 *
105 * Print text formatted according the fmt parameter
106 * and variant arguments. Each formatting directive
107 * begins with % (percentage) character and one of the
108 * following character:
109 *
110 * % Prints the percentage character.
[d7568a9f]111 * s The next variant argument is treated as char*
[724b58a]112 * and printed as a NULL terminated string.
[d7568a9f]113 * c The next variant argument is treated as a single char.
[da79d0fd]114 * p The next variant argument is treated as a maximum
115 * bit-width integer with respect to architecture
116 * and printed in full hexadecimal width.
117 * P As with 'p', but '0x' is prefixed.
118 * q The next variant argument is treated as a 64b integer
119 * and printed in full hexadecimal width.
120 * Q As with 'q', but '0x' is prefixed.
[d7568a9f]121 * l The next variant argument is treated as a 32b integer
[724b58a]122 * and printed in full hexadecimal width.
123 * L As with 'l', but '0x' is prefixed.
[d7568a9f]124 * w The next variant argument is treated as a 16b integer
[724b58a]125 * and printed in full hexadecimal width.
126 * W As with 'w', but '0x' is prefixed.
[d7568a9f]127 * b The next variant argument is treated as a 8b integer
[724b58a]128 * and printed in full hexadecimal width.
129 * N As with 'b', but '0x' is prefixed.
[d7568a9f]130 * d The next variant argument is treated as integer
[724b58a]131 * and printed in standard decimal format (only significant
132 * digits).
[d7568a9f]133 * x The next variant argument is treated as integer
[724b58a]134 * and printed in standard hexadecimal format (only significant
135 * digits).
136 * X As with 'x', but '0x' is prefixed.
137 *
138 * All other characters from fmt except the formatting directives
139 * are printed in verbatim.
140 *
141 * @param fmt Formatting NULL terminated string.
142 *
[f761f1eb]143 */
[27dc170]144void printf(const char *fmt, ...)
[f761f1eb]145{
[0d2f805]146 int irqpri, i = 0;
147 va_list ap;
148 char c;
149
150 va_start(ap, fmt);
[f761f1eb]151
152 irqpri = cpu_priority_high();
153 spinlock_lock(&printflock);
[0d2f805]154
[f761f1eb]155 while (c = fmt[i++]) {
156 switch (c) {
157
158 /* control character */
159 case '%':
160 switch (c = fmt[i++]) {
161
162 /* percentile itself */
163 case '%':
164 break;
165
166 /*
167 * String and character conversions.
168 */
169 case 's':
[0d2f805]170 print_str(va_arg(ap, char_ptr));
[f761f1eb]171 goto loop;
172
173 case 'c':
[199145a1]174 c = (char) va_arg(ap, int);
[f761f1eb]175 break;
176
177 /*
178 * Hexadecimal conversions with fixed width.
179 */
[da79d0fd]180 case 'P':
181 print_str("0x");
182 case 'p':
183 print_fixed_hex(va_arg(ap, __native), sizeof(__native));
184 goto loop;
185
186 case 'Q':
187 print_str("0x");
188 case 'q':
189 print_fixed_hex(va_arg(ap, __native), INT64);
190 goto loop;
191
[f761f1eb]192 case 'L':
193 print_str("0x");
194 case 'l':
[0d2f805]195 print_fixed_hex(va_arg(ap, __native), INT32);
[f761f1eb]196 goto loop;
197
198 case 'W':
199 print_str("0x");
200 case 'w':
[0d2f805]201 print_fixed_hex(va_arg(ap, __native), INT16);
[f761f1eb]202 goto loop;
203
204 case 'B':
205 print_str("0x");
206 case 'b':
[0d2f805]207 print_fixed_hex(va_arg(ap, __native), INT8);
[f761f1eb]208 goto loop;
209
210 /*
211 * Decimal and hexadecimal conversions.
212 */
213 case 'd':
[0d2f805]214 print_number(va_arg(ap, __native), 10);
[f761f1eb]215 goto loop;
216
217 case 'X':
218 print_str("0x");
219 case 'x':
[0d2f805]220 print_number(va_arg(ap, __native), 16);
[f761f1eb]221 goto loop;
222
223 /*
224 * Bad formatting.
225 */
226 default:
227 goto out;
228 }
229
230 default: putchar(c);
231 }
232
233loop:
234 ;
235 }
236
237out:
238 spinlock_unlock(&printflock);
239 cpu_priority_restore(irqpri);
[0d2f805]240
241 va_end(ap);
[f761f1eb]242}
Note: See TracBrowser for help on using the repository browser.