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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [src/] [symbolic.c] - Blame information for rev 97

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 hellwig
#include <time.h>
2
#include <ctype.h>
3
#include "c.h"
4
 
5
#define I(f) s_##f
6
static char rcsid[] = "$Id: symbolic.c,v 1.1 2002/08/28 23:12:47 drh Exp $";
7
 
8
static Node *tail;
9
static int off, maxoff, uid = 0, verbose = 0, html = 0;
10
 
11
static const char *yyBEGIN(const char *tag) {
12
        if (html)
13
                print("<%s>", tag);
14
        return tag;
15
}
16
 
17
static void yyEND(const char *tag) {
18
        if (html)
19
                print("</%s>", tag);
20
        if (isupper(*tag))
21
                print("\n");
22
}
23
 
24
#define BEGIN(tag) do { const char *yytag=yyBEGIN(#tag)
25
#define END yyEND(yytag); } while (0)
26
#define ITEM BEGIN(li)
27
#define START BEGIN(LI)
28
#define ANCHOR(attr,code) do { const char *yytag="a"; if (html) { printf("<a " #attr "=\""); code; print("\">"); }
29
#define NEWLINE print(html ? "<br>\n" : "\n")
30
 
31
static void emitCoord(Coordinate src) {
32
        if (src.file && *src.file) {
33
                ANCHOR(href,print("%s", src.file)); print("%s", src.file); END;
34
                print(":");
35
        }
36
        print("%d.%d", src.y, src.x);
37
}
38
 
39
static void emitString(int len, const char *s) {
40
        for ( ; len-- > 0; s++)
41
                if (*s == '&' && html)
42
                        print("&amp;");
43
                else if (*s == '<' && html)
44
                        print("&lt;");
45
                else if (*s == '>' && html)
46
                        print("&lt;");
47
                else if (*s == '"' || *s == '\\')
48
                        print("\\%c", *s);
49
                else if (*s >= ' ' && *s < 0177)
50
                        print("%c", *s);
51
                else
52
                        print("\\%d%d%d", (*s>>6)&3, (*s>>3)&7, *s&7);
53
}
54
 
55
static void emitSymRef(Symbol p) {
56
        (*IR->defsymbol)(p);
57
        ANCHOR(href,print("#%s", p->x.name)); BEGIN(code); print("%s", p->name); END; END;
58
}
59
 
60
static void emitSymbol(Symbol p) {
61
        (*IR->defsymbol)(p);
62
        ANCHOR(name,print("%s", p->x.name)); BEGIN(code); print("%s", p->name); END; END;
63
        BEGIN(ul);
64
#define xx(field,code) ITEM; if (!html) print(" "); print(#field "="); code; END
65
        if (verbose && (src.y || src.x))
66
                xx(src,emitCoord(p->src));
67
        xx(type,print("%t", p->type));
68
        xx(sclass,print("%k", p->sclass));
69
        switch (p->scope) {
70
        case CONSTANTS: xx(scope,print("CONSTANTS")); break;
71
        case LABELS:    xx(scope,print("LABELS"));    break;
72
        case GLOBAL:    xx(scope,print("GLOBAL"));    break;
73
        case PARAM:     xx(scope,print("PARAM"));     break;
74
        case LOCAL:     xx(scope,print("LOCAL"));     break;
75
        default:
76
                if (p->scope > LOCAL)
77
                        xx(scope,print("LOCAL+%d", p->scope-LOCAL));
78
                else
79
                        xx(scope,print("%d", p->scope));
80
        }
81
        ITEM;
82
        int n = 0;
83
        if (!html)
84
                print(" ");
85
        print("flags=");
86
#define yy(f) if (p->f) { if (n++) print("|"); print(#f); }
87
        yy(structarg)
88
        yy(addressed)
89
        yy(computed)
90
        yy(temporary)
91
        yy(generated)
92
#undef yy
93
        if (n == 0)
94
                print("0");
95
        END;
96
        if (p->scope >= PARAM && p->sclass != STATIC)
97
                xx(offset,print("%d", p->x.offset));
98
        xx(ref,print("%f", p->ref));
99
        if (p->temporary && p->u.t.cse)
100
                xx(u.t.cse,print("%p", p->u.t.cse));
101
        END;
102
#undef xx
103
}
104
 
105
/* address - initialize q for addressing expression p+n */
106
static void I(address)(Symbol q, Symbol p, long n) {
107
        q->name = stringf("%s%s%D", p->name, n > 0 ? "+" : "", n);
108
        (*IR->defsymbol)(q);
109
        START; print("address "); emitSymbol(q); END;
110
}
111
 
112
/* blockbeg - start a block */
113
static void I(blockbeg)(Env *e) {
114
        e->offset = off;
115
        START; print("blockbeg off=%d", off); END;
116
}
117
 
118
/* blockend - start a block */
119
static void I(blockend)(Env *e) {
120
        if (off > maxoff)
121
                maxoff = off;
122
        START; print("blockend off=%d", off); END;
123
        off = e->offset;
124
}
125
 
126
/* defaddress - initialize an address */
127
static void I(defaddress)(Symbol p){
128
        START; print("defaddress "); emitSymRef(p); END;
129
}
130
 
131
/* defconst - define a constant */
132
static void I(defconst)(int suffix, int size, Value v) {
133
        START;
134
        print("defconst ");
135
        switch (suffix) {
136
        case I:
137
                print("int.%d ", size);
138
                BEGIN(code);
139
                if (size > sizeof (int))
140
                        print("%D", v.i);
141
                else
142
                        print("%d", (int)v.i);
143
                END;
144
                break;
145
        case U:
146
                print("unsigned.%d ", size);
147
                BEGIN(code);
148
                if (size > sizeof (unsigned))
149
                        print("%U", v.u);
150
                else
151
                        print("%u", (unsigned)v.u);
152
                END;
153
                break;
154
        case P: print("void*.%d ", size); BEGIN(code); print("%p", v.p); END; break;
155
        case F:
156
                print("float.%d ", size);
157
                BEGIN(code);
158
                        double d = v.d;
159
                        if (d == 0.0) {
160
                                static union { int x; char endian; } little = { 1 };
161
                                signed char *b = (signed char *)&d;
162
                                if (!little.endian && b[0] < 0
163
                                ||   little.endian && b[sizeof (d)-1] < 0)
164
                                        print("-0.0");
165
                                else
166
                                        print("0.0");
167
                        } else
168
                                print("%g", d);
169
                END;
170
                break;
171
        default: assert(0);
172
        }
173
        END;
174
}
175
 
176
/* defstring - emit a string constant */
177
static void I(defstring)(int len, char *s) {
178
        START; print("defstring ");
179
        BEGIN(code); print("\""); emitString(len, s); print("\""); END;
180
        END;
181
}
182
 
183
/* defsymbol - define a symbol: initialize p->x */
184
static void I(defsymbol)(Symbol p) {
185
        if (p->x.name == NULL)
186
                p->x.name = stringd(++uid);
187
}
188
 
189
/* emit - emit the dags on list p */
190
static void I(emit)(Node p){
191
        ITEM;
192
        if (!html)
193
                print(" ");
194
        for (; p; p = p->x.next) {
195
                if (p->op == LABEL+V) {
196
                        assert(p->syms[0]);
197
                        ANCHOR(name,print("%s", p->syms[0]->x.name));
198
                        BEGIN(code); print("%s", p->syms[0]->name); END;
199
                        END;
200
                        print(":");
201
                } else {
202
                        int i;
203
                        if (p->x.listed) {
204
                                BEGIN(strong); print("%d", p->x.inst); END; print("'");
205
                                print(" %s", opname(p->op));
206
                        } else
207
                                print("%d. %s", p->x.inst, opname(p->op));
208
                        if (p->count > 1)
209
                                print(" count=%d", p->count);
210
                        for (i = 0; i < NELEMS(p->kids) && p->kids[i]; i++)
211
                                print(" #%d", p->kids[i]->x.inst);
212
                        if (generic(p->op) == CALL && p->syms[0] && p->syms[0]->type)
213
                                print(" {%t}", p->syms[0]->type);
214
                        else
215
                                for (i = 0; i < NELEMS(p->syms) && p->syms[i]; i++) {
216
                                        print(" ");
217
                                        if (p->syms[i]->scope == CONSTANTS)
218
                                                print(p->syms[i]->name);
219
                                        else
220
                                                emitSymRef(p->syms[i]);
221
                                }
222
                }
223
                NEWLINE;
224
        }
225
        END;
226
}
227
 
228
/* export - announce p as exported */
229
static void I(export)(Symbol p) {
230
        START; print("export "); emitSymRef(p); END;
231
}
232
 
233
/* function - generate code for a function */
234
static void I(function)(Symbol f, Symbol caller[], Symbol callee[], int ncalls) {
235
        int i;
236
 
237
        (*IR->defsymbol)(f);
238
        off = 0;
239
        for (i = 0; caller[i] && callee[i]; i++) {
240
                off = roundup(off, caller[i]->type->align);
241
                caller[i]->x.offset = callee[i]->x.offset = off;
242
                off += caller[i]->type->size;
243
        }
244
        if (!html) {
245
                print("function ");
246
                emitSymbol(f);
247
                print(" ncalls=%d\n", ncalls);
248
                for (i = 0; caller[i]; i++)
249
                        START; print("caller "); emitSymbol(caller[i]); END;
250
                for (i = 0; callee[i]; i++)
251
                        START; print("callee "); emitSymbol(callee[i]); END;
252
        } else {
253
                START;
254
                print("function");
255
                BEGIN(UL);
256
#define xx(field,code) ITEM; print(#field "="); code; END
257
                xx(f,emitSymbol(f));
258
                xx(ncalls,print("%d", ncalls));
259
                if (caller[0]) {
260
                        ITEM; print("caller"); BEGIN(OL);
261
                        for (i = 0; caller[i]; i++)
262
                                ITEM; emitSymbol(caller[i]); END;
263
                        END; END;
264
                        ITEM; print("callee"); BEGIN(OL);
265
                        for (i = 0; callee[i]; i++)
266
                                ITEM; emitSymbol(callee[i]); END;
267
                        END; END;
268
                } else {
269
                        xx(caller,BEGIN(em); print("empty"); END);
270
                        xx(callee,BEGIN(em); print("empty"); END);
271
                }
272
                END;
273
                END;
274
        }
275
        maxoff = off = 0;
276
        gencode(caller, callee);
277
        if (html)
278
                START; print("emitcode"); BEGIN(ul); emitcode(); END; END;
279
        else
280
                emitcode();
281
        START; print("maxoff=%d", maxoff); END;
282
#undef xx
283
}
284
 
285
/* visit - generate code for *p */
286
static int visit(Node p, int n) {
287
        if (p && p->x.inst == 0) {
288
                p->x.inst = ++n;
289
                n = visit(p->kids[0], n);
290
                n = visit(p->kids[1], n);
291
                *tail = p;
292
                tail = &p->x.next;
293
        }
294
        return n;
295
}
296
 
297
/* gen0 - generate code for the dags on list p */
298
static Node I(gen)(Node p) {
299
        int n;
300
        Node nodelist;
301
 
302
        tail = &nodelist;
303
        for (n = 0; p; p = p->link) {
304
                switch (generic(p->op)) {       /* check for valid forest */
305
                case CALL:
306
                        assert(IR->wants_dag || p->count == 0);
307
                        break;
308
                case ARG:
309
                case ASGN: case JUMP: case LABEL: case RET:
310
                case EQ: case GE: case GT: case LE: case LT: case NE:
311
                        assert(p->count == 0);
312
                        break;
313
                case INDIR:
314
                        assert(IR->wants_dag && p->count > 0);
315
                        break;
316
                default:
317
                        assert(0);
318
                }
319
                check(p);
320
                p->x.listed = 1;
321
                n = visit(p, n);
322
        }
323
        *tail = 0;
324
        return nodelist;
325
}
326
 
327
/* global - announce a global */
328
static void I(global)(Symbol p) {
329
        START; print("global "); emitSymbol(p); END;
330
}
331
 
332
/* import - import a symbol */
333
static void I(import)(Symbol p) {
334
        START; print("import "); emitSymRef(p); END;
335
}
336
 
337
/* local - local variable */
338
static void I(local)(Symbol p) {
339
        if (p->temporary)
340
                p->name = stringf("t%s", p->name);
341
        (*IR->defsymbol)(p);
342
        off = roundup(off, p->type->align);
343
        p->x.offset = off;
344
        off += p->type->size;
345
        START; print(p->temporary ? "temporary " : "local "); emitSymbol(p); END;
346
}
347
 
348
/* progbeg - beginning of program */
349
static void I(progbeg)(int argc, char *argv[]) {
350
        int i;
351
 
352
        for (i = 1; i < argc; i++)
353
                if (strcmp(argv[i], "-v") == 0)
354
                        verbose++;
355
                else if (strcmp(argv[i], "-html") == 0)
356
                        html++;
357
        if (html) {
358
                print("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n");
359
                print("<html>");
360
                BEGIN(head);
361
                if (firstfile && *firstfile)
362
                        BEGIN(title); emitString(strlen(firstfile), firstfile); END;
363
                print("<link rev=made href=\"mailto:drh@microsoft.com\">\n");
364
                END;
365
                print("<body>\n");
366
                if (firstfile && *firstfile)
367
                        BEGIN(h1); emitString(strlen(firstfile), firstfile); END;
368
                BEGIN(P); BEGIN(em);
369
                print("Links lead from uses of identifiers and labels to their definitions.");
370
                END; END;
371
                print("<ul>\n");
372
                START;
373
                print("progbeg");
374
                BEGIN(ol);
375
                for (i = 1; i < argc; i++) {
376
                        ITEM;
377
                        BEGIN(code); print("\""); emitString(strlen(argv[i]), argv[i]); print("\""); END;
378
                        END;
379
                }
380
                END;
381
                END;
382
        }
383
}
384
 
385
/* progend - end of program */
386
static void I(progend)(void) {
387
        START; print("progend"); END;
388
        if (html) {
389
                time_t t;
390
                print("</ul>\n");
391
                time(&t);
392
                print("<hr><address>%s</address>\n", ctime(&t));
393
                print("</body></html>\n");
394
        }
395
}
396
 
397
/* segment - switch to segment s */
398
static void I(segment)(int s) {
399
        START; print("segment %s", &"text\0bss\0.data\0lit\0.sym\0."[5*s-5]); END;
400
}
401
 
402
/* space - initialize n bytes of space */
403
static void I(space)(int n) {
404
        START; print("space %d", n); END;
405
}
406
 
407
static void I(stabblock)(int brace, int lev, Symbol *p) {}
408
 
409
/* stabend - finalize stab output */
410
static void I(stabend)(Coordinate *cp, Symbol p, Coordinate **cpp, Symbol *sp, Symbol *stab) {
411
        int i;
412
 
413
        if (p)
414
                emitSymRef(p);
415
        print("\n");
416
        if (cpp && sp)
417
                for (i = 0; cpp[i] && sp[i]; i++) {
418
                        print("%w.%d: ", cpp[i], cpp[i]->x);
419
                        emitSymRef(sp[i]);
420
                        print("\n");
421
                }
422
}
423
 
424
static void I(stabfend)(Symbol p, int lineno) {}
425
static void I(stabinit)(char *file, int argc, char *argv[]) {}
426
 
427
/* stabline - emit line number information for source coordinate *cp */
428
static void I(stabline)(Coordinate *cp) {
429
        if (cp->file)
430
                print("%s:", cp->file);
431
        print("%d.%d:\n", cp->y, cp->x);
432
}
433
 
434
static void I(stabsym)(Symbol p) {}
435
static void I(stabtype)(Symbol p) {}
436
 
437
Interface symbolicIR = {
438
        1, 1, 0, /* char */
439
        2, 2, 0, /* short */
440
        4, 4, 0, /* int */
441
        4, 4, 0, /* long */
442
        4, 4, 0, /* long long */
443
        4, 4, 1,        /* float */
444
        8, 8, 1,        /* double */
445
        8, 8, 1,        /* long double */
446
        4, 4, 0, /* T* */
447
        0, 4, 0,  /* struct */
448
        0,               /* little_endian */
449
        0,               /* mulops_calls */
450
        0,               /* wants_callb */
451
        1,              /* wants_argb */
452
        1,              /* left_to_right */
453
        1,              /* wants_dag */
454
        0,               /* unsigned_char */
455
        I(address),
456
        I(blockbeg),
457
        I(blockend),
458
        I(defaddress),
459
        I(defconst),
460
        I(defstring),
461
        I(defsymbol),
462
        I(emit),
463
        I(export),
464
        I(function),
465
        I(gen),
466
        I(global),
467
        I(import),
468
        I(local),
469
        I(progbeg),
470
        I(progend),
471
        I(segment),
472
        I(space),
473
        I(stabblock),
474
        I(stabend),
475
        I(stabfend),
476
        I(stabinit),
477
        I(stabline),
478
        I(stabsym),
479
        I(stabtype)
480
};
481
 
482
Interface symbolic64IR = {
483
        1, 1, 0, /* char */
484
        2, 2, 0, /* short */
485
        4, 4, 0, /* int */
486
        8, 8, 0, /* long */
487
        8, 8, 0, /* long long */
488
        4, 4, 1,        /* float */
489
        8, 8, 1,        /* double */
490
        8, 8, 1,        /* long double */
491
        8, 8, 0, /* T* */
492
        0, 1, 0,  /* struct */
493
        1,              /* little_endian */
494
        0,               /* mulops_calls */
495
        0,               /* wants_callb */
496
        1,              /* wants_argb */
497
        1,              /* left_to_right */
498
        1,              /* wants_dag */
499
        0,               /* unsigned_char */
500
        I(address),
501
        I(blockbeg),
502
        I(blockend),
503
        I(defaddress),
504
        I(defconst),
505
        I(defstring),
506
        I(defsymbol),
507
        I(emit),
508
        I(export),
509
        I(function),
510
        I(gen),
511
        I(global),
512
        I(import),
513
        I(local),
514
        I(progbeg),
515
        I(progend),
516
        I(segment),
517
        I(space),
518
        I(stabblock),
519
        I(stabend),
520
        I(stabfend),
521
        I(stabinit),
522
        I(stabline),
523
        I(stabsym),
524
        I(stabtype)
525
};

powered by: WebSVN 2.1.0

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