OpenCores
URL https://opencores.org/ocsvn/yifive/yifive/trunk

Subversion Repositories yifive

[/] [yifive/] [trunk/] [caravel_yifive/] [verilog/] [rtl/] [syntacore/] [scr1/] [sim/] [tests/] [common/] [sc_print.c] - Blame information for rev 22

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 22 dinesha
/// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details
2
/// @file       <sc_print.c>
3
///
4
 
5
#include <string.h>
6
#include <stdarg.h>
7
#include "sc_print.h"
8
 
9
#define SC_SIM_OUTPORT (0xf0000000)
10
#define CHAR_BIT (8)
11
 
12
static void
13
sc_puts(long str, long strlen) {
14
        volatile char *out_ptr = (volatile char*)SC_SIM_OUTPORT;
15
        const char *in_ptr = (const char*)str;
16
        for (long len = strlen; len > 0; --len)
17
          *out_ptr = *in_ptr++;
18
}
19
 
20
#undef putchar
21
int
22
putchar(int ch) {
23
        static __thread char buf[64] __attribute__((aligned(64)));
24
    static __thread int buflen = 0;
25
 
26
    buf[buflen++] = ch;
27
 
28
        if ( ch == '\n' || buflen == sizeof(buf) ) {
29
        sc_puts((long)buf, buflen);
30
        buflen = 0;
31
    }
32
 
33
    return 0;
34
}
35
 
36
static void
37
printf_putch(int ch, void** data)
38
{
39
    putchar(ch);
40
}
41
 
42
static void
43
print(const char *str)
44
{
45
  sc_puts((long)str, strlen(str));
46
}
47
 
48
 
49
static long long
50
getint(va_list *ap, int lflag)
51
{
52
    if ( lflag >= 2 )
53
        return va_arg(*ap, long long);
54
    else if ( lflag )
55
        return va_arg(*ap, long);
56
    else
57
        return va_arg(*ap, int);
58
}
59
 
60
 
61
static unsigned long long
62
getuint(va_list *ap, int lflag)
63
{
64
    if ( lflag >= 2 )
65
        return va_arg(*ap, unsigned long long);
66
    else if ( lflag )
67
        return va_arg(*ap, unsigned long);
68
    else
69
        return va_arg(*ap, unsigned int);
70
}
71
 
72
static inline void
73
printnum(void(*putch)(int, void**),
74
void **putdat,
75
unsigned long long num,
76
unsigned base,
77
int width,
78
int padc,
79
int hex_A)
80
{
81
    unsigned digs[sizeof(num) * CHAR_BIT];
82
    int pos = 0;
83
 
84
    for ( ;; ) {
85
        digs[pos++] = num % base;
86
        if ( num < base )
87
            break;
88
        num /= base;
89
    }
90
 
91
    while ( width-- > pos )
92
        putch(padc, putdat);
93
 
94
    while ( pos-- > 0 )
95
        putch(digs[pos] + (digs[pos] >= 10 ? hex_A - 10 : '0'), putdat);
96
}
97
 
98
static void
99
vprintfmt(void(*putch)(int, void**), void **putdat, const char *fmt, va_list ap)
100
{
101
    register const char* p;
102
    const char* last_fmt;
103
    register int ch;
104
    int err;
105
    unsigned long long num;
106
    int base;
107
    int lflag;
108
    int width;
109
    int precision;
110
    int altflag;
111
    char padc;
112
    int hex_A = 'a';
113
    for ( ;; ) {
114
        while ( (ch = *(unsigned char *)fmt) != '%' ) {
115
            if ( ch == '\0' )
116
                return;
117
            ++fmt;
118
            putch(ch, putdat);
119
        }
120
        ++fmt;
121
 
122
        // Process a %-escape sequence
123
        last_fmt = fmt;
124
        padc = ' ';
125
        width = -1;
126
        precision = -1;
127
        lflag = 0;
128
        altflag = 0;
129
 
130
reswitch:
131
        switch ( ch = *(unsigned char *)fmt++ ) {
132
            // flag to pad on the right
133
            case '-':
134
                padc = '-';
135
                goto reswitch;
136
 
137
                // flag to pad with 0's instead of spaces
138
            case '0':
139
                padc = '0';
140
                goto reswitch;
141
 
142
                // width field
143
            case '1':
144
            case '2':
145
            case '3':
146
            case '4':
147
            case '5':
148
            case '6':
149
            case '7':
150
            case '8':
151
            case '9':
152
                for ( precision = 0;; ++fmt ) {
153
                    precision = precision * 10 + ch - '0';
154
                    ch = *fmt;
155
                    if ( ch < '0' || ch > '9' )
156
                        break;
157
                }
158
                goto process_precision;
159
 
160
            case '*':
161
                precision = va_arg(ap, int);
162
                goto process_precision;
163
 
164
            case '.':
165
                if ( width < 0 )
166
                    width = 0;
167
                goto reswitch;
168
 
169
            case '#':
170
                altflag = 1;
171
                goto reswitch;
172
 
173
process_precision:
174
                if ( width < 0 ) {
175
                    width = precision;
176
                    precision = -1;
177
                }
178
                goto reswitch;
179
 
180
                // long flag (doubled for long long)
181
            case 'l':
182
                lflag++;
183
                goto reswitch;
184
 
185
                // character
186
            case 'c':
187
                putch(va_arg(ap, int), putdat);
188
                break;
189
 
190
                // string
191
            case 's':
192
                if ( (p = va_arg(ap, char *)) == NULL )
193
                    p = "(null)";
194
                if ( width > 0 && padc != '-' )
195
                    for ( width -= strnlen(p, precision); width > 0; width-- )
196
                        putch(padc, putdat);
197
                for ( ; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width-- ) {
198
                    putch(ch, putdat);
199
                    p++;
200
                }
201
                for ( ; width > 0; width-- )
202
                    putch(' ', putdat);
203
                break;
204
 
205
                // (signed) decimal
206
            case 'd':
207
                num = getint(&ap, lflag);
208
                if ( (long long)num < 0 ) {
209
                    putch('-', putdat);
210
                    num = -(long long)num;
211
                }
212
                base = 10;
213
                goto signed_number;
214
 
215
            case 'f':
216
                {
217
                    // #ifndef nopfloat
218
                    // double num = getdouble(&ap, lflag);
219
                    // printdoubleF(putch, putdat, num, width, precision, padc);
220
                    // #endif
221
                }
222
                break;
223
 
224
                // unsigned decimal
225
            case 'u':
226
                base = 10;
227
                goto unsigned_number;
228
 
229
                // (unsigned) octal
230
            case 'o':
231
                // should do something with padding so it's always 3 octits
232
                base = 8;
233
                goto unsigned_number;
234
 
235
                // pointer
236
            case 'p':
237
                // static_assert(sizeof(long) == sizeof(void*));
238
                lflag = 1;
239
                putch('0', putdat);
240
                putch('x', putdat);
241
                /* fall through to 'x' */
242
 
243
                // (unsigned) hexadecimal
244
            case 'x':
245
                hex_A = 'a';
246
                base = 16;
247
                goto unsigned_number;
248
 
249
            case 'X':
250
                hex_A = 'A';
251
                base = 16;
252
unsigned_number:
253
                num = getuint(&ap, lflag);
254
signed_number:
255
                printnum(putch, putdat, num, base, width, padc, hex_A);
256
                break;
257
 
258
                // escaped '%' character
259
            case '%':
260
                putch(ch, putdat);
261
                break;
262
 
263
                // unrecognized escape sequence - just print it literally
264
            default:
265
                putch('%', putdat);
266
                fmt = last_fmt;
267
                break;
268
        }
269
    }
270
}
271
 
272
int
273
sc_printf(const char* fmt, ...)
274
{
275
    va_list ap;
276
    va_start(ap, fmt);
277
 
278
    vprintfmt(printf_putch, NULL, fmt, ap);
279
 
280
    va_end(ap);
281
    return 0; // incorrect return value, but who cares, anyway?
282
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.