8 static int off
, maxoff
, uid
= 0, verbose
= 0, html
= 0;
10 static const char *yyBEGIN(const char *tag
) {
16 static void yyEND(const char *tag
) {
23 #define BEGIN(tag) do { const char *yytag=yyBEGIN(#tag);
24 #define END yyEND(yytag); } while (0)
25 #define ITEM BEGIN(li)
26 #define START BEGIN(LI)
27 #define ANCHOR(attr,code) do { const char *yytag="a"; if (html) { printf("<a " #attr "=\""); code; print("\">"); }
28 #define NEWLINE print(html ? "<br>\n" : "\n")
30 static void emitCoord(Coordinate src
) {
31 if (src
.file
&& *src
.file
) {
32 ANCHOR(href
,print("%s", src
.file
)); print("%s", src
.file
); END
;
35 print("%d.%d", src
.y
, src
.x
);
38 static void emitString(int len
, const char *s
) {
39 for ( ; len
-- > 0; s
++)
40 if (*s
== '&' && html
)
42 else if (*s
== '<' && html
)
44 else if (*s
== '>' && html
)
46 else if (*s
== '"' || *s
== '\\')
48 else if (*s
>= ' ' && *s
< 0177)
51 print("\\%d%d%d", (*s
>>6)&3, (*s
>>3)&7, *s
&7);
54 static void emitSymRef(Symbol p
) {
56 ANCHOR(href
,print("#%s", p
->x
.name
)); BEGIN(code
); print("%s", p
->name
); END
; END
;
59 static void emitSymbol(Symbol p
) {
61 ANCHOR(name
,print("%s", p
->x
.name
)); BEGIN(code
); print("%s", p
->name
); END
; END
;
63 #define xx(field,code) ITEM; if (!html) print(" "); print(#field "="); code; END
64 if (verbose
&& (src
.y
|| src
.x
))
65 xx(src
,emitCoord(p
->src
));
66 xx(type
,print("%t", p
->type
));
67 xx(sclass
,print("%k", p
->sclass
));
69 case CONSTANTS
: xx(scope
,print("CONSTANTS")); break;
70 case LABELS
: xx(scope
,print("LABELS")); break;
71 case GLOBAL
: xx(scope
,print("GLOBAL")); break;
72 case PARAM
: xx(scope
,print("PARAM")); break;
73 case LOCAL
: xx(scope
,print("LOCAL")); break;
76 xx(scope
,print("LOCAL+%d", p
->scope
-LOCAL
));
78 xx(scope
,print("%d", p
->scope
));
80 if (p
->scope
>= PARAM
&& p
->sclass
!= STATIC
)
81 xx(offset
,print("%d", p
->x
.offset
));
82 xx(ref
,print("%f", p
->ref
));
83 if (p
->temporary
&& p
->u
.t
.cse
)
84 xx(u
.t
.cse
,print("%p", p
->u
.t
.cse
));
89 /* address - initialize q for addressing expression p+n */
90 static void I(address
)(Symbol q
, Symbol p
, long n
) {
91 q
->name
= stringf("%s%s%D", p
->name
, n
> 0 ? "+" : "", n
);
93 START
; print("address "); emitSymbol(q
); END
;
96 /* blockbeg - start a block */
97 static void I(blockbeg
)(Env
*e
) {
99 START
; print("blockbeg off=%d", off
); END
;
102 /* blockend - start a block */
103 static void I(blockend
)(Env
*e
) {
106 START
; print("blockend off=%d", off
); END
;
110 /* defaddress - initialize an address */
111 static void I(defaddress
)(Symbol p
){
112 START
; print("defaddress "); emitSymRef(p
); END
;
115 /* defconst - define a constant */
116 static void I(defconst
)(int suffix
, int size
, Value v
) {
121 print("int.%d ", size
);
123 if (size
> sizeof (int))
126 print("%d", (int)v
.i
);
130 print("unsigned.%d ", size
);
132 if (size
> sizeof (unsigned))
135 print("%u", (unsigned)v
.u
);
138 case P
: print("void*.%d ", size
); BEGIN(code
); print("%p", v
.p
); END
; break;
139 case F
: print("float.%d ", size
); BEGIN(code
); print("%g", (double)v
.d
); END
; break;
145 /* defstring - emit a string constant */
146 static void I(defstring
)(int len
, char *s
) {
147 START
; print("defstring ");
148 BEGIN(code
); print("\""); emitString(len
, s
); print("\""); END
;
152 /* defsymbol - define a symbol: initialize p->x */
153 static void I(defsymbol
)(Symbol p
) {
154 if (p
->x
.name
== NULL
)
155 p
->x
.name
= stringd(++uid
);
158 /* emit - emit the dags on list p */
159 static void I(emit
)(Node p
){
163 for (; p
; p
= p
->x
.next
) {
164 if (p
->op
== LABEL
+V
) {
166 ANCHOR(name
,print("%s", p
->syms
[0]->x
.name
));
167 BEGIN(code
); print("%s", p
->syms
[0]->name
); END
;
173 BEGIN(strong
); print("%d", p
->x
.inst
); END
; print("'");
174 print(" %s", opname(p
->op
));
176 print("%d. %s", p
->x
.inst
, opname(p
->op
));
178 print(" count=%d", p
->count
);
179 for (i
= 0; i
< NELEMS(p
->kids
) && p
->kids
[i
]; i
++)
180 print(" #%d", p
->kids
[i
]->x
.inst
);
181 if (generic(p
->op
) == CALL
&& p
->syms
[0] && p
->syms
[0]->type
)
182 print(" {%t}", p
->syms
[0]->type
);
184 for (i
= 0; i
< NELEMS(p
->syms
) && p
->syms
[i
]; i
++) {
186 if (p
->syms
[i
]->scope
== CONSTANTS
)
187 print(p
->syms
[i
]->name
);
189 emitSymRef(p
->syms
[i
]);
197 /* export - announce p as exported */
198 static void I(export
)(Symbol p
) {
199 START
; print("export "); emitSymRef(p
); END
;
202 /* function - generate code for a function */
203 static void I(function
)(Symbol f
, Symbol caller
[], Symbol callee
[], int ncalls
) {
208 for (i
= 0; caller
[i
] && callee
[i
]; i
++) {
209 off
= roundup(off
, caller
[i
]->type
->align
);
210 caller
[i
]->x
.offset
= callee
[i
]->x
.offset
= off
;
211 off
+= caller
[i
]->type
->size
;
216 print(" ncalls=%d\n", ncalls
);
217 for (i
= 0; caller
[i
]; i
++)
218 START
; print("caller "); emitSymbol(caller
[i
]); END
;
219 for (i
= 0; callee
[i
]; i
++)
220 START
; print("callee "); emitSymbol(callee
[i
]); END
;
225 #define xx(field,code) ITEM; print(#field "="); code; END
227 xx(ncalls
,print("%d", ncalls
));
229 ITEM
; print("caller"); BEGIN(OL
);
230 for (i
= 0; caller
[i
]; i
++)
231 ITEM
; emitSymbol(caller
[i
]); END
;
233 ITEM
; print("callee"); BEGIN(OL
);
234 for (i
= 0; callee
[i
]; i
++)
235 ITEM
; emitSymbol(callee
[i
]); END
;
238 xx(caller
,BEGIN(em
); print("empty"); END
);
239 xx(callee
,BEGIN(em
); print("empty"); END
);
245 gencode(caller
, callee
);
247 START
; print("emitcode"); BEGIN(ul
); emitcode(); END
; END
;
250 START
; print("maxoff=%d", maxoff
); END
;
254 /* visit - generate code for *p */
255 static int visit(Node p
, int n
) {
256 if (p
&& p
->x
.inst
== 0) {
258 n
= visit(p
->kids
[0], n
);
259 n
= visit(p
->kids
[1], n
);
266 /* gen0 - generate code for the dags on list p */
267 static Node
I(gen
)(Node p
) {
272 for (n
= 0; p
; p
= p
->link
) {
273 switch (generic(p
->op
)) { /* check for valid forest */
275 assert(IR
->wants_dag
|| p
->count
== 0);
278 case ASGN
: case JUMP
: case LABEL
: case RET
:
279 case EQ
: case GE
: case GT
: case LE
: case LT
: case NE
:
280 assert(p
->count
== 0);
283 assert(IR
->wants_dag
&& p
->count
> 0);
296 /* global - announce a global */
297 static void I(global
)(Symbol p
) {
298 START
; print("global "); emitSymbol(p
); END
;
301 /* import - import a symbol */
302 static void I(import
)(Symbol p
) {
303 START
; print("import "); emitSymRef(p
); END
;
306 /* local - local variable */
307 static void I(local
)(Symbol p
) {
309 p
->name
= stringf("t%s", p
->name
);
311 off
= roundup(off
, p
->type
->align
);
313 off
+= p
->type
->size
;
314 START
; print(p
->temporary
? "temporary " : "local "); emitSymbol(p
); END
;
317 /* progbeg - beginning of program */
318 static void I(progbeg
)(int argc
, char *argv
[]) {
321 for (i
= 1; i
< argc
; i
++)
322 if (strcmp(argv
[i
], "-v") == 0)
324 else if (strcmp(argv
[i
], "-html") == 0)
327 print("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n");
330 if (firstfile
&& *firstfile
)
331 BEGIN(title
); emitString(strlen(firstfile
), firstfile
); END
;
332 print("<link rev=made href=\"mailto:drh@microsoft.com\">\n");
335 if (firstfile
&& *firstfile
)
336 BEGIN(h1
); emitString(strlen(firstfile
), firstfile
); END
;
338 print("Links lead from uses of identifiers and labels to their definitions.");
344 for (i
= 1; i
< argc
; i
++) {
346 BEGIN(code
); print("\""); emitString(strlen(argv
[i
]), argv
[i
]); print("\""); END
;
354 /* progend - end of program */
355 static void I(progend
)(void) {
356 START
; print("progend"); END
;
361 print("<hr><address>%s</address>\n", ctime(&t
));
362 print("</body></html>\n");
366 /* segment - switch to segment s */
367 static void I(segment
)(int s
) {
368 START
; print("segment %s", &"text\0bss\0.data\0lit\0.sym\0."[5*s
-5]); END
;
371 /* space - initialize n bytes of space */
372 static void I(space
)(int n
) {
373 START
; print("space %d", n
); END
;
376 static void I(stabblock
)(int brace
, int lev
, Symbol
*p
) {}
378 /* stabend - finalize stab output */
379 static void I(stabend
)(Coordinate
*cp
, Symbol p
, Coordinate
**cpp
, Symbol
*sp
, Symbol
*stab
) {
386 for (i
= 0; cpp
[i
] && sp
[i
]; i
++) {
387 print("%w.%d: ", cpp
[i
], cpp
[i
]->x
);
393 static void I(stabfend
)(Symbol p
, int lineno
) {}
394 static void I(stabinit
)(char *file
, int argc
, char *argv
[]) {}
396 /* stabline - emit line number information for source coordinate *cp */
397 static void I(stabline
)(Coordinate
*cp
) {
399 print("%s:", cp
->file
);
400 print("%d.%d:\n", cp
->y
, cp
->x
);
403 static void I(stabsym
)(Symbol p
) {}
404 static void I(stabtype
)(Symbol p
) {}
406 Interface symbolicIR
= {
407 {1, 1, 0}, /* char */
408 {2, 2, 0}, /* short */
410 {4, 4, 0}, /* long */
411 {4, 4, 0}, /* long long */
412 {4, 4, 1}, /* float */
413 {8, 8, 1}, /* double */
414 {8, 8, 1}, /* long double */
416 {0, 4, 0}, /* struct */
417 0, /* little_endian */
418 0, /* mulops_calls */
421 1, /* left_to_right */
423 0, /* unsigned_char */
451 Interface symbolic64IR
= {
452 {1, 1, 0}, /* char */
453 {2, 2, 0}, /* short */
455 {8, 8, 0}, /* long */
456 {8, 8, 0}, /* long long */
457 {4, 4, 1}, /* float */
458 {8, 8, 1}, /* double */
459 {8, 8, 1}, /* long double */
461 {0, 1, 0}, /* struct */
462 1, /* little_endian */
463 0, /* mulops_calls */
466 1, /* left_to_right */
468 0, /* unsigned_char */