Print this page
11972 resync smatch
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/show-parse.c
+++ new/usr/src/tools/smatch/src/show-parse.c
1 1 /*
2 2 * sparse/show-parse.c
3 3 *
4 4 * Copyright (C) 2003 Transmeta Corp.
5 5 * 2003-2004 Linus Torvalds
6 6 *
7 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 8 * of this software and associated documentation files (the "Software"), to deal
9 9 * in the Software without restriction, including without limitation the rights
10 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 11 * copies of the Software, and to permit persons to whom the Software is
12 12 * furnished to do so, subject to the following conditions:
13 13 *
14 14 * The above copyright notice and this permission notice shall be included in
15 15 * all copies or substantial portions of the Software.
16 16 *
17 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 23 * THE SOFTWARE.
24 24 *
25 25 * Print out results of parsing for debugging and testing.
26 26 */
27 27 #include <stdarg.h>
28 28 #include <stdlib.h>
29 29 #include <stdio.h>
30 30 #include <string.h>
31 31 #include <ctype.h>
32 32 #include <unistd.h>
33 33 #include <fcntl.h>
34 34
35 35 #include "lib.h"
36 36 #include "allocate.h"
37 37 #include "token.h"
38 38 #include "parse.h"
39 39 #include "symbol.h"
40 40 #include "scope.h"
41 41 #include "expression.h"
42 42 #include "target.h"
43 43
44 44 static int show_symbol_expr(struct symbol *sym);
45 45 static int show_string_expr(struct expression *expr);
46 46
47 47 static void do_debug_symbol(struct symbol *sym, int indent)
48 48 {
49 49 static const char indent_string[] = " ";
50 50 static const char *typestr[] = {
51 51 [SYM_UNINITIALIZED] = "none",
52 52 [SYM_PREPROCESSOR] = "cpp.",
53 53 [SYM_BASETYPE] = "base",
54 54 [SYM_NODE] = "node",
55 55 [SYM_PTR] = "ptr.",
56 56 [SYM_FN] = "fn..",
57 57 [SYM_ARRAY] = "arry",
58 58 [SYM_STRUCT] = "strt",
59 59 [SYM_UNION] = "unin",
60 60 [SYM_ENUM] = "enum",
61 61 [SYM_TYPEDEF] = "tdef",
62 62 [SYM_TYPEOF] = "tpof",
63 63 [SYM_MEMBER] = "memb",
64 64 [SYM_BITFIELD] = "bitf",
↓ open down ↓ |
64 lines elided |
↑ open up ↑ |
65 65 [SYM_LABEL] = "labl",
66 66 [SYM_RESTRICT] = "rstr",
67 67 [SYM_FOULED] = "foul",
68 68 [SYM_BAD] = "bad.",
69 69 };
70 70 struct context *context;
71 71 int i;
72 72
73 73 if (!sym)
74 74 return;
75 - fprintf(stderr, "%.*s%s%3d:%lu %s %s (as: %d) %p (%s:%d:%d) %s\n",
75 + fprintf(stderr, "%.*s%s%3d:%lu %s %s (as: %s) %p (%s:%d:%d) %s\n",
76 76 indent, indent_string, typestr[sym->type],
77 77 sym->bit_size, sym->ctype.alignment,
78 - modifier_string(sym->ctype.modifiers), show_ident(sym->ident), sym->ctype.as,
78 + modifier_string(sym->ctype.modifiers), show_ident(sym->ident),
79 + show_as(sym->ctype.as),
79 80 sym, stream_name(sym->pos.stream), sym->pos.line, sym->pos.pos,
80 81 builtin_typename(sym) ?: "");
81 82 i = 0;
82 83 FOR_EACH_PTR(sym->ctype.contexts, context) {
83 84 /* FIXME: should print context expression */
84 85 fprintf(stderr, "< context%d: in=%d, out=%d\n",
85 86 i, context->in, context->out);
86 87 fprintf(stderr, " end context%d >\n", i);
87 88 i++;
88 89 } END_FOR_EACH_PTR(context);
89 90 if (sym->type == SYM_FN) {
90 91 struct symbol *arg;
91 92 i = 0;
92 93 FOR_EACH_PTR(sym->arguments, arg) {
93 94 fprintf(stderr, "< arg%d:\n", i);
94 95 do_debug_symbol(arg, 0);
95 96 fprintf(stderr, " end arg%d >\n", i);
96 97 i++;
97 98 } END_FOR_EACH_PTR(arg);
98 99 }
99 100 do_debug_symbol(sym->ctype.base_type, indent+2);
100 101 }
101 102
102 103 void debug_symbol(struct symbol *sym)
103 104 {
104 105 do_debug_symbol(sym, 0);
105 106 }
106 107
107 108 /*
108 109 * Symbol type printout. The type system is by far the most
109 110 * complicated part of C - everything else is trivial.
110 111 */
111 112 const char *modifier_string(unsigned long mod)
112 113 {
113 114 static char buffer[100];
114 115 int len = 0;
115 116 int i;
116 117 struct mod_name {
117 118 unsigned long mod;
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
118 119 const char *name;
119 120 } *m;
120 121
121 122 static struct mod_name mod_names[] = {
122 123 {MOD_AUTO, "auto"},
123 124 {MOD_REGISTER, "register"},
124 125 {MOD_STATIC, "static"},
125 126 {MOD_EXTERN, "extern"},
126 127 {MOD_CONST, "const"},
127 128 {MOD_VOLATILE, "volatile"},
129 + {MOD_RESTRICT, "restrict"},
130 + {MOD_ATOMIC, "[atomic]"},
128 131 {MOD_SIGNED, "[signed]"},
129 132 {MOD_UNSIGNED, "[unsigned]"},
130 133 {MOD_CHAR, "[char]"},
131 134 {MOD_SHORT, "[short]"},
132 135 {MOD_LONG, "[long]"},
133 136 {MOD_LONGLONG, "[long long]"},
134 137 {MOD_LONGLONGLONG, "[long long long]"},
135 - {MOD_TYPEDEF, "[typedef]"},
136 138 {MOD_TLS, "[tls]"},
137 139 {MOD_INLINE, "inline"},
138 140 {MOD_ADDRESSABLE, "[addressable]"},
139 141 {MOD_NOCAST, "[nocast]"},
140 142 {MOD_NODEREF, "[noderef]"},
141 - {MOD_ACCESSED, "[accessed]"},
142 143 {MOD_TOPLEVEL, "[toplevel]"},
143 144 {MOD_ASSIGNED, "[assigned]"},
144 145 {MOD_TYPE, "[type]"},
145 146 {MOD_SAFE, "[safe]"},
146 147 {MOD_USERTYPE, "[usertype]"},
147 148 {MOD_NORETURN, "[noreturn]"},
148 149 {MOD_EXPLICITLY_SIGNED, "[explicitly-signed]"},
149 150 {MOD_BITWISE, "[bitwise]"},
150 151 {MOD_PURE, "[pure]"},
151 152 };
152 153
153 154 for (i = 0; i < ARRAY_SIZE(mod_names); i++) {
154 155 m = mod_names + i;
155 156 if (mod & m->mod) {
156 157 char c;
157 158 const char *name = m->name;
158 159 while ((c = *name++) != '\0' && len + 2 < sizeof buffer)
159 160 buffer[len++] = c;
160 161 buffer[len++] = ' ';
161 162 }
162 163 }
163 164 buffer[len] = 0;
164 165 return buffer;
165 166 }
166 167
167 168 static void show_struct_member(struct symbol *sym)
168 169 {
169 170 printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset);
170 171 printf("\n");
171 172 }
172 173
173 174 void show_symbol_list(struct symbol_list *list, const char *sep)
174 175 {
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
175 176 struct symbol *sym;
176 177 const char *prepend = "";
177 178
178 179 FOR_EACH_PTR(list, sym) {
179 180 puts(prepend);
180 181 prepend = ", ";
181 182 show_symbol(sym);
182 183 } END_FOR_EACH_PTR(sym);
183 184 }
184 185
186 +const char *show_as(struct ident *as)
187 +{
188 + if (!as)
189 + return "";
190 + return show_ident(as);
191 +}
192 +
185 193 struct type_name {
186 194 char *start;
187 195 char *end;
188 196 };
189 197
190 198 static void FORMAT_ATTR(2) prepend(struct type_name *name, const char *fmt, ...)
191 199 {
192 200 static char buffer[512];
193 201 int n;
194 202
195 203 va_list args;
196 204 va_start(args, fmt);
197 205 n = vsprintf(buffer, fmt, args);
198 206 va_end(args);
199 207
200 208 name->start -= n;
201 209 memcpy(name->start, buffer, n);
202 210 }
203 211
204 212 static void FORMAT_ATTR(2) append(struct type_name *name, const char *fmt, ...)
205 213 {
206 214 static char buffer[512];
207 215 int n;
208 216
209 217 va_list args;
210 218 va_start(args, fmt);
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
211 219 n = vsprintf(buffer, fmt, args);
212 220 va_end(args);
213 221
214 222 memcpy(name->end, buffer, n);
215 223 name->end += n;
216 224 }
217 225
218 226 static struct ctype_name {
219 227 struct symbol *sym;
220 228 const char *name;
229 + const char *suffix;
221 230 } typenames[] = {
222 - { & char_ctype, "char" },
223 - { &schar_ctype, "signed char" },
224 - { &uchar_ctype, "unsigned char" },
225 - { & short_ctype, "short" },
226 - { &sshort_ctype, "signed short" },
227 - { &ushort_ctype, "unsigned short" },
228 - { & int_ctype, "int" },
229 - { &sint_ctype, "signed int" },
230 - { &uint_ctype, "unsigned int" },
231 - { &slong_ctype, "signed long" },
232 - { & long_ctype, "long" },
233 - { &ulong_ctype, "unsigned long" },
234 - { & llong_ctype, "long long" },
235 - { &sllong_ctype, "signed long long" },
236 - { &ullong_ctype, "unsigned long long" },
237 - { & lllong_ctype, "long long long" },
238 - { &slllong_ctype, "signed long long long" },
239 - { &ulllong_ctype, "unsigned long long long" },
231 + { & char_ctype, "char", "" },
232 + { &schar_ctype, "signed char", "" },
233 + { &uchar_ctype, "unsigned char", "" },
234 + { & short_ctype, "short", "" },
235 + { &sshort_ctype, "signed short", "" },
236 + { &ushort_ctype, "unsigned short", "" },
237 + { & int_ctype, "int", "" },
238 + { &sint_ctype, "signed int", "" },
239 + { &uint_ctype, "unsigned int", "U" },
240 + { & long_ctype, "long", "L" },
241 + { &slong_ctype, "signed long", "L" },
242 + { &ulong_ctype, "unsigned long", "UL" },
243 + { & llong_ctype, "long long", "LL" },
244 + { &sllong_ctype, "signed long long", "LL" },
245 + { &ullong_ctype, "unsigned long long", "ULL" },
246 + { & lllong_ctype, "long long long", "LLL" },
247 + { &slllong_ctype, "signed long long long", "LLL" },
248 + { &ulllong_ctype, "unsigned long long long", "ULLL" },
240 249
241 - { &void_ctype, "void" },
242 - { &bool_ctype, "bool" },
243 - { &string_ctype, "string" },
250 + { &void_ctype, "void", "" },
251 + { &bool_ctype, "bool", "" },
244 252
245 - { &float_ctype, "float" },
246 - { &double_ctype, "double" },
247 - { &ldouble_ctype,"long double" },
248 - { &incomplete_ctype, "incomplete type" },
249 - { &int_type, "abstract int" },
250 - { &fp_type, "abstract fp" },
251 - { &label_ctype, "label type" },
252 - { &bad_ctype, "bad type" },
253 + { &float_ctype, "float", "F" },
254 + { &double_ctype, "double", "" },
255 + { &ldouble_ctype,"long double", "L" },
256 + { &incomplete_ctype, "incomplete type", "" },
257 + { &int_type, "abstract int", "" },
258 + { &fp_type, "abstract fp", "" },
259 + { &label_ctype, "label type", "" },
260 + { &bad_ctype, "bad type", "" },
253 261 };
254 262
255 263 const char *builtin_typename(struct symbol *sym)
256 264 {
257 265 int i;
258 266
259 267 for (i = 0; i < ARRAY_SIZE(typenames); i++)
260 268 if (typenames[i].sym == sym)
261 269 return typenames[i].name;
262 270 return NULL;
263 271 }
264 272
273 +const char *builtin_type_suffix(struct symbol *sym)
274 +{
275 + int i;
276 +
277 + for (i = 0; i < ARRAY_SIZE(typenames); i++)
278 + if (typenames[i].sym == sym)
279 + return typenames[i].suffix;
280 + return NULL;
281 +}
282 +
265 283 const char *builtin_ctypename(struct ctype *ctype)
266 284 {
267 285 int i;
268 286
269 287 for (i = 0; i < ARRAY_SIZE(typenames); i++)
270 288 if (&typenames[i].sym->ctype == ctype)
271 289 return typenames[i].name;
272 290 return NULL;
273 291 }
274 292
275 293 static void do_show_type(struct symbol *sym, struct type_name *name)
276 294 {
277 295 const char *typename;
278 296 unsigned long mod = 0;
279 - int as = 0;
297 + struct ident *as = NULL;
280 298 int was_ptr = 0;
281 299 int restr = 0;
282 300 int fouled = 0;
283 301
284 302 deeper:
285 303 if (!sym || (sym->type != SYM_NODE && sym->type != SYM_ARRAY &&
286 304 sym->type != SYM_BITFIELD)) {
287 305 const char *s;
288 306 size_t len;
289 307
290 308 if (as)
291 - prepend(name, "<asn:%d>", as);
309 + prepend(name, "%s ", show_as(as));
292 310
311 + if (sym->type == SYM_BASETYPE || sym->type == SYM_ENUM)
312 + mod &= ~MOD_SPECIFIER;
293 313 s = modifier_string(mod);
294 314 len = strlen(s);
295 315 name->start -= len;
296 316 memcpy(name->start, s, len);
297 317 mod = 0;
298 - as = 0;
318 + as = NULL;
299 319 }
300 320
301 321 if (!sym)
302 322 goto out;
303 323
304 324 if ((typename = builtin_typename(sym))) {
305 325 int len = strlen(typename);
306 326 if (name->start != name->end)
307 327 *--name->start = ' ';
308 328 name->start -= len;
309 329 memcpy(name->start, typename, len);
310 330 goto out;
311 331 }
312 332
313 333 /* Prepend */
314 334 switch (sym->type) {
315 335 case SYM_PTR:
316 336 prepend(name, "*");
317 337 mod = sym->ctype.modifiers;
318 338 as = sym->ctype.as;
319 339 was_ptr = 1;
320 340 break;
321 341
322 342 case SYM_FN:
323 343 if (was_ptr) {
324 344 prepend(name, "( ");
325 345 append(name, " )");
326 346 was_ptr = 0;
327 347 }
328 348 append(name, "( ... )");
329 349 break;
330 350
331 351 case SYM_STRUCT:
332 352 if (name->start != name->end)
333 353 *--name->start = ' ';
334 354 prepend(name, "struct %s", show_ident(sym->ident));
335 355 goto out;
336 356
337 357 case SYM_UNION:
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
338 358 if (name->start != name->end)
339 359 *--name->start = ' ';
340 360 prepend(name, "union %s", show_ident(sym->ident));
341 361 goto out;
342 362
343 363 case SYM_ENUM:
344 364 prepend(name, "enum %s ", show_ident(sym->ident));
345 365 break;
346 366
347 367 case SYM_NODE:
348 - append(name, "%s", show_ident(sym->ident));
368 + if (sym->ident)
369 + append(name, "%s", show_ident(sym->ident));
349 370 mod |= sym->ctype.modifiers;
350 - as |= sym->ctype.as;
371 + combine_address_space(sym->pos, &as, sym->ctype.as);
351 372 break;
352 373
353 374 case SYM_BITFIELD:
354 375 mod |= sym->ctype.modifiers;
355 - as |= sym->ctype.as;
376 + combine_address_space(sym->pos, &as, sym->ctype.as);
356 377 append(name, ":%d", sym->bit_size);
357 378 break;
358 379
359 380 case SYM_LABEL:
360 381 append(name, "label(%s:%p)", show_ident(sym->ident), sym);
361 382 return;
362 383
363 384 case SYM_ARRAY:
364 385 mod |= sym->ctype.modifiers;
365 - as |= sym->ctype.as;
386 + combine_address_space(sym->pos, &as, sym->ctype.as);
366 387 if (was_ptr) {
367 388 prepend(name, "( ");
368 389 append(name, " )");
369 390 was_ptr = 0;
370 391 }
371 392 append(name, "[%lld]", get_expression_value(sym->array_size));
372 393 break;
373 394
374 395 case SYM_RESTRICT:
375 396 if (!sym->ident) {
376 397 restr = 1;
377 398 break;
378 399 }
379 400 if (name->start != name->end)
380 401 *--name->start = ' ';
381 402 prepend(name, "restricted %s", show_ident(sym->ident));
382 403 goto out;
383 404
384 405 case SYM_FOULED:
385 406 fouled = 1;
386 407 break;
387 408
388 409 default:
389 410 if (name->start != name->end)
390 411 *--name->start = ' ';
391 412 prepend(name, "unknown type %d", sym->type);
392 413 goto out;
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
393 414 }
394 415
395 416 sym = sym->ctype.base_type;
396 417 goto deeper;
397 418
398 419 out:
399 420 if (restr)
400 421 prepend(name, "restricted ");
401 422 if (fouled)
402 423 prepend(name, "fouled ");
424 +
425 + // strip trailing space
426 + if (name->end > name->start && name->end[-1] == ' ')
427 + name->end--;
403 428 }
404 429
405 430 void show_type(struct symbol *sym)
406 431 {
407 432 char array[200];
408 433 struct type_name name;
409 434
410 435 name.start = name.end = array+100;
411 436 do_show_type(sym, &name);
412 437 *name.end = 0;
413 438 printf("%s", name.start);
414 439 }
415 440
416 441 const char *show_typename(struct symbol *sym)
417 442 {
418 443 static char array[200];
419 444 struct type_name name;
420 445
421 446 name.start = name.end = array+100;
422 447 do_show_type(sym, &name);
423 448 *name.end = 0;
424 449 return name.start;
425 450 }
426 451
427 452 void show_symbol(struct symbol *sym)
428 453 {
429 454 struct symbol *type;
430 455
431 456 if (!sym)
432 457 return;
433 458
434 459 if (sym->ctype.alignment)
435 460 printf(".align %ld\n", sym->ctype.alignment);
436 461
437 462 show_type(sym);
438 463 type = sym->ctype.base_type;
439 464 if (!type) {
440 465 printf("\n");
441 466 return;
442 467 }
443 468
444 469 /*
445 470 * Show actual implementation information
446 471 */
447 472 switch (type->type) {
448 473 struct symbol *member;
449 474
450 475 case SYM_STRUCT:
451 476 case SYM_UNION:
452 477 printf(" {\n");
453 478 FOR_EACH_PTR(type->symbol_list, member) {
454 479 show_struct_member(member);
455 480 } END_FOR_EACH_PTR(member);
456 481 printf("}\n");
457 482 break;
458 483
459 484 case SYM_FN: {
460 485 struct statement *stmt = type->stmt;
461 486 printf("\n");
462 487 if (stmt) {
463 488 int val;
464 489 val = show_statement(stmt);
465 490 if (val)
466 491 printf("\tmov.%d\t\tretval,%d\n", stmt->ret->bit_size, val);
467 492 printf("\tret\n");
468 493 }
469 494 break;
470 495 }
471 496
472 497 default:
473 498 printf("\n");
474 499 break;
475 500 }
476 501
477 502 if (sym->initializer) {
478 503 printf(" = \n");
479 504 show_expression(sym->initializer);
480 505 }
481 506 }
482 507
483 508 static int show_symbol_init(struct symbol *sym);
484 509
485 510 static int new_pseudo(void)
486 511 {
487 512 static int nr = 0;
488 513 return ++nr;
489 514 }
490 515
491 516 static int new_label(void)
492 517 {
493 518 static int label = 0;
494 519 return ++label;
495 520 }
496 521
497 522 static void show_switch_statement(struct statement *stmt)
498 523 {
499 524 int val = show_expression(stmt->switch_expression);
500 525 struct symbol *sym;
501 526 printf("\tswitch v%d\n", val);
502 527
503 528 /*
504 529 * Debugging only: Check that the case list is correct
505 530 * by printing it out.
506 531 *
507 532 * This is where a _real_ back-end would go through the
508 533 * cases to decide whether to use a lookup table or a
509 534 * series of comparisons etc
510 535 */
511 536 printf("# case table:\n");
512 537 FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
513 538 struct statement *case_stmt = sym->stmt;
514 539 struct expression *expr = case_stmt->case_expression;
515 540 struct expression *to = case_stmt->case_to;
516 541
517 542 if (!expr) {
518 543 printf(" default");
519 544 } else {
520 545 if (expr->type == EXPR_VALUE) {
521 546 printf(" case %lld", expr->value);
522 547 if (to) {
523 548 if (to->type == EXPR_VALUE) {
524 549 printf(" .. %lld", to->value);
525 550 } else {
526 551 printf(" .. what?");
527 552 }
528 553 }
529 554 } else
530 555 printf(" what?");
531 556 }
532 557 printf(": .L%p\n", sym);
533 558 } END_FOR_EACH_PTR(sym);
534 559 printf("# end case table\n");
535 560
536 561 show_statement(stmt->switch_statement);
537 562
538 563 if (stmt->switch_break->used)
539 564 printf(".L%p:\n", stmt->switch_break);
540 565 }
541 566
542 567 static void show_symbol_decl(struct symbol_list *syms)
543 568 {
544 569 struct symbol *sym;
545 570 FOR_EACH_PTR(syms, sym) {
546 571 show_symbol_init(sym);
547 572 } END_FOR_EACH_PTR(sym);
548 573 }
549 574
550 575 static int show_return_stmt(struct statement *stmt);
551 576
552 577 /*
553 578 * Print out a statement
554 579 */
555 580 int show_statement(struct statement *stmt)
556 581 {
557 582 if (!stmt)
558 583 return 0;
559 584 switch (stmt->type) {
560 585 case STMT_DECLARATION:
561 586 show_symbol_decl(stmt->declaration);
562 587 return 0;
563 588 case STMT_RETURN:
564 589 return show_return_stmt(stmt);
565 590 case STMT_COMPOUND: {
566 591 struct statement *s;
567 592 int last = 0;
568 593
569 594 if (stmt->inline_fn) {
570 595 show_statement(stmt->args);
571 596 printf("\tbegin_inline \t%s\n", show_ident(stmt->inline_fn->ident));
572 597 }
573 598 FOR_EACH_PTR(stmt->stmts, s) {
574 599 last = show_statement(s);
575 600 } END_FOR_EACH_PTR(s);
576 601 if (stmt->ret) {
577 602 int addr, bits;
578 603 printf(".L%p:\n", stmt->ret);
579 604 addr = show_symbol_expr(stmt->ret);
580 605 bits = stmt->ret->bit_size;
581 606 last = new_pseudo();
582 607 printf("\tld.%d\t\tv%d,[v%d]\n", bits, last, addr);
583 608 }
584 609 if (stmt->inline_fn)
585 610 printf("\tend_inlined\t%s\n", show_ident(stmt->inline_fn->ident));
586 611 return last;
587 612 }
588 613
589 614 case STMT_EXPRESSION:
590 615 return show_expression(stmt->expression);
591 616 case STMT_IF: {
592 617 int val, target;
593 618 struct expression *cond = stmt->if_conditional;
594 619
595 620 /* This is only valid if nobody can jump into the "dead" statement */
596 621 #if 0
597 622 if (cond->type == EXPR_VALUE) {
598 623 struct statement *s = stmt->if_true;
599 624 if (!cond->value)
600 625 s = stmt->if_false;
601 626 show_statement(s);
602 627 break;
603 628 }
604 629 #endif
605 630 val = show_expression(cond);
606 631 target = new_label();
607 632 printf("\tje\t\tv%d,.L%d\n", val, target);
608 633 show_statement(stmt->if_true);
609 634 if (stmt->if_false) {
610 635 int last = new_label();
611 636 printf("\tjmp\t\t.L%d\n", last);
612 637 printf(".L%d:\n", target);
613 638 target = last;
614 639 show_statement(stmt->if_false);
615 640 }
616 641 printf(".L%d:\n", target);
617 642 break;
618 643 }
619 644 case STMT_SWITCH:
620 645 show_switch_statement(stmt);
621 646 break;
622 647
623 648 case STMT_CASE:
624 649 printf(".L%p:\n", stmt->case_label);
625 650 show_statement(stmt->case_statement);
626 651 break;
627 652
628 653 case STMT_ITERATOR: {
629 654 struct statement *pre_statement = stmt->iterator_pre_statement;
630 655 struct expression *pre_condition = stmt->iterator_pre_condition;
631 656 struct statement *statement = stmt->iterator_statement;
632 657 struct statement *post_statement = stmt->iterator_post_statement;
633 658 struct expression *post_condition = stmt->iterator_post_condition;
634 659 int val, loop_top = 0, loop_bottom = 0;
635 660
636 661 show_symbol_decl(stmt->iterator_syms);
637 662 show_statement(pre_statement);
638 663 if (pre_condition) {
639 664 if (pre_condition->type == EXPR_VALUE) {
640 665 if (!pre_condition->value) {
641 666 loop_bottom = new_label();
642 667 printf("\tjmp\t\t.L%d\n", loop_bottom);
643 668 }
644 669 } else {
645 670 loop_bottom = new_label();
646 671 val = show_expression(pre_condition);
647 672 printf("\tje\t\tv%d, .L%d\n", val, loop_bottom);
648 673 }
649 674 }
650 675 if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
651 676 loop_top = new_label();
652 677 printf(".L%d:\n", loop_top);
653 678 }
654 679 show_statement(statement);
655 680 if (stmt->iterator_continue->used)
656 681 printf(".L%p:\n", stmt->iterator_continue);
657 682 show_statement(post_statement);
658 683 if (!post_condition) {
659 684 printf("\tjmp\t\t.L%d\n", loop_top);
660 685 } else if (post_condition->type == EXPR_VALUE) {
661 686 if (post_condition->value)
662 687 printf("\tjmp\t\t.L%d\n", loop_top);
663 688 } else {
664 689 val = show_expression(post_condition);
665 690 printf("\tjne\t\tv%d, .L%d\n", val, loop_top);
666 691 }
667 692 if (stmt->iterator_break->used)
668 693 printf(".L%p:\n", stmt->iterator_break);
669 694 if (loop_bottom)
670 695 printf(".L%d:\n", loop_bottom);
671 696 break;
672 697 }
673 698 case STMT_NONE:
674 699 break;
675 700
676 701 case STMT_LABEL:
677 702 printf(".L%p:\n", stmt->label_identifier);
678 703 show_statement(stmt->label_statement);
679 704 break;
680 705
681 706 case STMT_GOTO:
682 707 if (stmt->goto_expression) {
683 708 int val = show_expression(stmt->goto_expression);
684 709 printf("\tgoto\t\t*v%d\n", val);
685 710 } else {
686 711 printf("\tgoto\t\t.L%p\n", stmt->goto_label);
687 712 }
688 713 break;
689 714 case STMT_ASM:
690 715 printf("\tasm( .... )\n");
691 716 break;
692 717 case STMT_CONTEXT: {
693 718 int val = show_expression(stmt->expression);
694 719 printf("\tcontext( %d )\n", val);
695 720 break;
696 721 }
697 722 case STMT_RANGE: {
698 723 int val = show_expression(stmt->range_expression);
699 724 int low = show_expression(stmt->range_low);
700 725 int high = show_expression(stmt->range_high);
701 726 printf("\trange( %d %d-%d)\n", val, low, high);
702 727 break;
703 728 }
704 729 }
705 730 return 0;
706 731 }
707 732
708 733 static int show_call_expression(struct expression *expr)
709 734 {
710 735 struct symbol *direct;
711 736 struct expression *arg, *fn;
712 737 int fncall, retval;
713 738 int framesize;
714 739
715 740 if (!expr->ctype) {
716 741 warning(expr->pos, "\tcall with no type!");
717 742 return 0;
718 743 }
719 744
720 745 framesize = 0;
721 746 FOR_EACH_PTR_REVERSE(expr->args, arg) {
722 747 int new = show_expression(arg);
723 748 int size = arg->ctype->bit_size;
724 749 printf("\tpush.%d\t\tv%d\n", size, new);
725 750 framesize += bits_to_bytes(size);
726 751 } END_FOR_EACH_PTR_REVERSE(arg);
727 752
728 753 fn = expr->fn;
729 754
730 755 /* Remove dereference, if any */
731 756 direct = NULL;
732 757 if (fn->type == EXPR_PREOP) {
733 758 if (fn->unop->type == EXPR_SYMBOL) {
734 759 struct symbol *sym = fn->unop->symbol;
735 760 if (sym->ctype.base_type->type == SYM_FN)
736 761 direct = sym;
737 762 }
738 763 }
739 764 if (direct) {
740 765 printf("\tcall\t\t%s\n", show_ident(direct->ident));
741 766 } else {
742 767 fncall = show_expression(fn);
743 768 printf("\tcall\t\t*v%d\n", fncall);
744 769 }
745 770 if (framesize)
746 771 printf("\tadd.%d\t\tvSP,vSP,$%d\n", bits_in_pointer, framesize);
747 772
748 773 retval = new_pseudo();
749 774 printf("\tmov.%d\t\tv%d,retval\n", expr->ctype->bit_size, retval);
750 775 return retval;
751 776 }
752 777
753 778 static int show_comma(struct expression *expr)
754 779 {
755 780 show_expression(expr->left);
756 781 return show_expression(expr->right);
757 782 }
758 783
759 784 static int show_binop(struct expression *expr)
760 785 {
761 786 int left = show_expression(expr->left);
762 787 int right = show_expression(expr->right);
763 788 int new = new_pseudo();
764 789 const char *opname;
765 790 static const char *name[] = {
766 791 ['+'] = "add", ['-'] = "sub",
767 792 ['*'] = "mul", ['/'] = "div",
768 793 ['%'] = "mod", ['&'] = "and",
769 794 ['|'] = "lor", ['^'] = "xor"
770 795 };
771 796 unsigned int op = expr->op;
772 797
773 798 opname = show_special(op);
774 799 if (op < ARRAY_SIZE(name))
775 800 opname = name[op];
776 801 printf("\t%s.%d\t\tv%d,v%d,v%d\n", opname,
777 802 expr->ctype->bit_size,
778 803 new, left, right);
779 804 return new;
780 805 }
781 806
782 807 static int show_slice(struct expression *expr)
783 808 {
784 809 int target = show_expression(expr->base);
785 810 int new = new_pseudo();
786 811 printf("\tslice.%d\t\tv%d,v%d,%d\n", expr->r_nrbits, target, new, expr->r_bitpos);
787 812 return new;
788 813 }
789 814
790 815 static int show_regular_preop(struct expression *expr)
791 816 {
792 817 int target = show_expression(expr->unop);
793 818 int new = new_pseudo();
794 819 static const char *name[] = {
795 820 ['!'] = "nonzero", ['-'] = "neg",
796 821 ['~'] = "not",
797 822 };
798 823 unsigned int op = expr->op;
799 824 const char *opname;
800 825
801 826 opname = show_special(op);
802 827 if (op < ARRAY_SIZE(name))
803 828 opname = name[op];
804 829 printf("\t%s.%d\t\tv%d,v%d\n", opname, expr->ctype->bit_size, new, target);
805 830 return new;
806 831 }
807 832
808 833 /*
809 834 * FIXME! Not all accesses are memory loads. We should
810 835 * check what kind of symbol is behind the dereference.
811 836 */
812 837 static int show_address_gen(struct expression *expr)
813 838 {
814 839 return show_expression(expr->unop);
815 840 }
816 841
817 842 static int show_load_gen(int bits, struct expression *expr, int addr)
818 843 {
819 844 int new = new_pseudo();
820 845
821 846 printf("\tld.%d\t\tv%d,[v%d]\n", bits, new, addr);
822 847 return new;
823 848 }
824 849
825 850 static void show_store_gen(int bits, int value, struct expression *expr, int addr)
826 851 {
827 852 /* FIXME!!! Bitfield store! */
828 853 printf("\tst.%d\t\tv%d,[v%d]\n", bits, value, addr);
829 854 }
830 855
831 856 static int show_assignment(struct expression *expr)
832 857 {
833 858 struct expression *target = expr->left;
834 859 int val, addr, bits;
835 860
836 861 if (!expr->ctype)
837 862 return 0;
838 863
839 864 bits = expr->ctype->bit_size;
840 865 val = show_expression(expr->right);
841 866 addr = show_address_gen(target);
842 867 show_store_gen(bits, val, target, addr);
843 868 return val;
844 869 }
845 870
846 871 static int show_return_stmt(struct statement *stmt)
847 872 {
848 873 struct expression *expr = stmt->ret_value;
849 874 struct symbol *target = stmt->ret_target;
850 875
851 876 if (expr && expr->ctype) {
852 877 int val = show_expression(expr);
853 878 int bits = expr->ctype->bit_size;
854 879 int addr = show_symbol_expr(target);
855 880 show_store_gen(bits, val, NULL, addr);
856 881 }
857 882 printf("\tret\t\t(%p)\n", target);
858 883 return 0;
859 884 }
860 885
861 886 static int show_initialization(struct symbol *sym, struct expression *expr)
862 887 {
863 888 int val, addr, bits;
864 889
865 890 if (!expr->ctype)
866 891 return 0;
867 892
868 893 bits = expr->ctype->bit_size;
869 894 val = show_expression(expr);
870 895 addr = show_symbol_expr(sym);
871 896 // FIXME! The "target" expression is for bitfield store information.
872 897 // Leave it NULL, which works fine.
873 898 show_store_gen(bits, val, NULL, addr);
874 899 return 0;
875 900 }
876 901
877 902 static int show_access(struct expression *expr)
878 903 {
879 904 int addr = show_address_gen(expr);
880 905 return show_load_gen(expr->ctype->bit_size, expr, addr);
881 906 }
882 907
883 908 static int show_inc_dec(struct expression *expr, int postop)
884 909 {
885 910 int addr = show_address_gen(expr->unop);
886 911 int retval, new;
887 912 const char *opname = expr->op == SPECIAL_INCREMENT ? "add" : "sub";
888 913 int bits = expr->ctype->bit_size;
889 914
890 915 retval = show_load_gen(bits, expr->unop, addr);
891 916 new = retval;
892 917 if (postop)
893 918 new = new_pseudo();
894 919 printf("\t%s.%d\t\tv%d,v%d,$1\n", opname, bits, new, retval);
895 920 show_store_gen(bits, new, expr->unop, addr);
896 921 return retval;
897 922 }
898 923
899 924 static int show_preop(struct expression *expr)
900 925 {
901 926 /*
902 927 * '*' is an lvalue access, and is fundamentally different
903 928 * from an arithmetic operation. Maybe it should have an
904 929 * expression type of its own..
905 930 */
906 931 if (expr->op == '*')
907 932 return show_access(expr);
908 933 if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
909 934 return show_inc_dec(expr, 0);
910 935 return show_regular_preop(expr);
911 936 }
912 937
913 938 static int show_postop(struct expression *expr)
914 939 {
915 940 return show_inc_dec(expr, 1);
916 941 }
917 942
918 943 static int show_symbol_expr(struct symbol *sym)
919 944 {
↓ open down ↓ |
507 lines elided |
↑ open up ↑ |
920 945 int new = new_pseudo();
921 946
922 947 if (sym->initializer && sym->initializer->type == EXPR_STRING)
923 948 return show_string_expr(sym->initializer);
924 949
925 950 if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) {
926 951 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new, show_ident(sym->ident));
927 952 return new;
928 953 }
929 954 if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
930 - printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new, sym->value);
955 + printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new, 0LL);
931 956 return new;
932 957 }
933 958 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new, show_ident(sym->ident), sym);
934 959 return new;
935 960 }
936 961
937 962 static int show_symbol_init(struct symbol *sym)
938 963 {
939 964 struct expression *expr = sym->initializer;
940 965
941 966 if (expr) {
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
942 967 int val, addr, bits;
943 968
944 969 bits = expr->ctype->bit_size;
945 970 val = show_expression(expr);
946 971 addr = show_symbol_expr(sym);
947 972 show_store_gen(bits, val, NULL, addr);
948 973 }
949 974 return 0;
950 975 }
951 976
952 -static int type_is_signed(struct symbol *sym)
953 -{
954 - if (sym->type == SYM_NODE)
955 - sym = sym->ctype.base_type;
956 - if (sym->type == SYM_PTR)
957 - return 0;
958 - return !(sym->ctype.modifiers & MOD_UNSIGNED);
959 -}
960 -
961 977 static int show_cast_expr(struct expression *expr)
962 978 {
963 979 struct symbol *old_type, *new_type;
964 980 int op = show_expression(expr->cast_expression);
965 981 int oldbits, newbits;
966 982 int new, is_signed;
967 983
968 984 old_type = expr->cast_expression->ctype;
969 985 new_type = expr->cast_type;
970 986
971 987 oldbits = old_type->bit_size;
972 988 newbits = new_type->bit_size;
973 989 if (oldbits >= newbits)
974 990 return op;
975 991 new = new_pseudo();
976 - is_signed = type_is_signed(old_type);
992 + is_signed = is_signed_type(old_type);
977 993 if (is_signed) {
978 994 printf("\tsext%d.%d\tv%d,v%d\n", oldbits, newbits, new, op);
979 995 } else {
980 996 printf("\tandl.%d\t\tv%d,v%d,$%lu\n", newbits, new, op, (1UL << oldbits)-1);
981 997 }
982 998 return new;
983 999 }
984 1000
985 1001 static int show_value(struct expression *expr)
986 1002 {
987 1003 int new = new_pseudo();
988 1004 unsigned long long value = expr->value;
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
989 1005
990 1006 printf("\tmovi.%d\t\tv%d,$%llu\n", expr->ctype->bit_size, new, value);
991 1007 return new;
992 1008 }
993 1009
994 1010 static int show_fvalue(struct expression *expr)
995 1011 {
996 1012 int new = new_pseudo();
997 1013 long double value = expr->fvalue;
998 1014
999 - printf("\tmovf.%d\t\tv%d,$%Lf\n", expr->ctype->bit_size, new, value);
1015 + printf("\tmovf.%d\t\tv%d,$%Le\n", expr->ctype->bit_size, new, value);
1000 1016 return new;
1001 1017 }
1002 1018
1003 1019 static int show_string_expr(struct expression *expr)
1004 1020 {
1005 1021 int new = new_pseudo();
1006 1022
1007 1023 printf("\tmovi.%d\t\tv%d,&%s\n", bits_in_pointer, new, show_string(expr->string));
1008 1024 return new;
1009 1025 }
1010 1026
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
1011 1027 static int show_label_expr(struct expression *expr)
1012 1028 {
1013 1029 int new = new_pseudo();
1014 1030 printf("\tmovi.%d\t\tv%d,.L%p\n",bits_in_pointer, new, expr->label_symbol);
1015 1031 return new;
1016 1032 }
1017 1033
1018 1034 static int show_conditional_expr(struct expression *expr)
1019 1035 {
1020 1036 int cond = show_expression(expr->conditional);
1021 - int true = show_expression(expr->cond_true);
1022 - int false = show_expression(expr->cond_false);
1037 + int valt = show_expression(expr->cond_true);
1038 + int valf = show_expression(expr->cond_false);
1023 1039 int new = new_pseudo();
1024 1040
1025 - printf("[v%d]\tcmov.%d\t\tv%d,v%d,v%d\n", cond, expr->ctype->bit_size, new, true, false);
1041 + printf("[v%d]\tcmov.%d\t\tv%d,v%d,v%d\n", cond, expr->ctype->bit_size, new, valt, valf);
1026 1042 return new;
1027 1043 }
1028 1044
1029 1045 static int show_statement_expr(struct expression *expr)
1030 1046 {
1031 1047 return show_statement(expr->statement);
1032 1048 }
1033 1049
1034 1050 static int show_position_expr(struct expression *expr, struct symbol *base)
1035 1051 {
1036 1052 int new = show_expression(expr->init_expr);
1037 1053 struct symbol *ctype = expr->init_expr->ctype;
1038 1054 int bit_offset;
1039 1055
1040 1056 bit_offset = ctype ? ctype->bit_offset : -1;
1041 1057
1042 1058 printf("\tinsert v%d at [%d:%d] of %s\n", new,
1043 1059 expr->init_offset, bit_offset,
1044 1060 show_ident(base->ident));
1045 1061 return 0;
1046 1062 }
1047 1063
1048 1064 static int show_initializer_expr(struct expression *expr, struct symbol *ctype)
1049 1065 {
1050 1066 struct expression *entry;
1051 1067
1052 1068 FOR_EACH_PTR(expr->expr_list, entry) {
1053 1069
1054 1070 again:
1055 1071 // Nested initializers have their positions already
1056 1072 // recursively calculated - just output them too
1057 1073 if (entry->type == EXPR_INITIALIZER) {
1058 1074 show_initializer_expr(entry, ctype);
1059 1075 continue;
1060 1076 }
1061 1077
1062 1078 // Initializer indexes and identifiers should
1063 1079 // have been evaluated to EXPR_POS
1064 1080 if (entry->type == EXPR_IDENTIFIER) {
1065 1081 printf(" AT '%s':\n", show_ident(entry->expr_ident));
1066 1082 entry = entry->ident_expression;
1067 1083 goto again;
1068 1084 }
1069 1085
1070 1086 if (entry->type == EXPR_INDEX) {
1071 1087 printf(" AT '%d..%d:\n", entry->idx_from, entry->idx_to);
1072 1088 entry = entry->idx_expression;
1073 1089 goto again;
1074 1090 }
1075 1091 if (entry->type == EXPR_POS) {
1076 1092 show_position_expr(entry, ctype);
1077 1093 continue;
1078 1094 }
1079 1095 show_initialization(ctype, entry);
1080 1096 } END_FOR_EACH_PTR(entry);
1081 1097 return 0;
1082 1098 }
1083 1099
1084 1100 int show_symbol_expr_init(struct symbol *sym)
1085 1101 {
1086 1102 struct expression *expr = sym->initializer;
1087 1103
1088 1104 if (expr)
1089 1105 show_expression(expr);
1090 1106 return show_symbol_expr(sym);
1091 1107 }
1092 1108
1093 1109 /*
1094 1110 * Print out an expression. Return the pseudo that contains the
1095 1111 * variable.
1096 1112 */
1097 1113 int show_expression(struct expression *expr)
1098 1114 {
1099 1115 if (!expr)
1100 1116 return 0;
1101 1117
1102 1118 if (!expr->ctype) {
1103 1119 struct position *pos = &expr->pos;
1104 1120 printf("\tno type at %s:%d:%d\n",
1105 1121 stream_name(pos->stream),
1106 1122 pos->line, pos->pos);
1107 1123 return 0;
1108 1124 }
1109 1125
1110 1126 switch (expr->type) {
1111 1127 case EXPR_CALL:
1112 1128 return show_call_expression(expr);
1113 1129
1114 1130 case EXPR_ASSIGNMENT:
1115 1131 return show_assignment(expr);
1116 1132
1117 1133 case EXPR_COMMA:
1118 1134 return show_comma(expr);
1119 1135 case EXPR_BINOP:
1120 1136 case EXPR_COMPARE:
1121 1137 case EXPR_LOGICAL:
1122 1138 return show_binop(expr);
1123 1139 case EXPR_PREOP:
1124 1140 return show_preop(expr);
1125 1141 case EXPR_POSTOP:
1126 1142 return show_postop(expr);
1127 1143 case EXPR_SYMBOL:
1128 1144 return show_symbol_expr(expr->symbol);
1129 1145 case EXPR_DEREF:
1130 1146 case EXPR_SIZEOF:
1131 1147 case EXPR_PTRSIZEOF:
1132 1148 case EXPR_ALIGNOF:
1133 1149 case EXPR_OFFSETOF:
1134 1150 warning(expr->pos, "invalid expression after evaluation");
1135 1151 return 0;
1136 1152 case EXPR_CAST:
1137 1153 case EXPR_FORCE_CAST:
1138 1154 case EXPR_IMPLIED_CAST:
1139 1155 return show_cast_expr(expr);
1140 1156 case EXPR_VALUE:
1141 1157 return show_value(expr);
1142 1158 case EXPR_FVALUE:
1143 1159 return show_fvalue(expr);
1144 1160 case EXPR_STRING:
1145 1161 return show_string_expr(expr);
1146 1162 case EXPR_INITIALIZER:
1147 1163 return show_initializer_expr(expr, expr->ctype);
1148 1164 case EXPR_SELECT:
1149 1165 case EXPR_CONDITIONAL:
1150 1166 return show_conditional_expr(expr);
1151 1167 case EXPR_STATEMENT:
1152 1168 return show_statement_expr(expr);
1153 1169 case EXPR_LABEL:
1154 1170 return show_label_expr(expr);
1155 1171 case EXPR_SLICE:
1156 1172 return show_slice(expr);
1157 1173
1158 1174 // None of these should exist as direct expressions: they are only
1159 1175 // valid as sub-expressions of initializers.
1160 1176 case EXPR_POS:
1161 1177 warning(expr->pos, "unable to show plain initializer position expression");
↓ open down ↓ |
126 lines elided |
↑ open up ↑ |
1162 1178 return 0;
1163 1179 case EXPR_IDENTIFIER:
1164 1180 warning(expr->pos, "unable to show identifier expression");
1165 1181 return 0;
1166 1182 case EXPR_INDEX:
1167 1183 warning(expr->pos, "unable to show index expression");
1168 1184 return 0;
1169 1185 case EXPR_TYPE:
1170 1186 warning(expr->pos, "unable to show type expression");
1171 1187 return 0;
1188 + case EXPR_ASM_OPERAND:
1189 + warning(expr->pos, "unable to show asm operand expression");
1190 + return 0;
1172 1191 }
1173 1192 return 0;
1174 1193 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX