diff options
| author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-12-08 13:12:05 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:05:39 -0700 |
| commit | be25179dcf5bd9ac397e422089e9c4c5f883221f (patch) | |
| tree | 6c92bef1f749bd4cd05aa84270843e3b97d856b6 /example.c | |
| parent | a696ed3e5a8e21997d2e0e5a1bba86a4e606f842 (diff) | |
| download | sparse-dev-be25179dcf5bd9ac397e422089e9c4c5f883221f.tar.gz | |
Slowly, slowly, make the output of "example" slightly more readable.
I dunno if this will ever get anywhere.
Diffstat (limited to 'example.c')
| -rw-r--r-- | example.c | 93 |
1 files changed, 82 insertions, 11 deletions
@@ -8,41 +8,112 @@ #include "symbol.h" #include "expression.h" #include "linearize.h" +#include "flow.h" #include "storage.h" -static void output_bb(struct basic_block *bb) +struct hardreg { + const char *name; + pseudo_t contains; +}; + +static void output_bb(struct basic_block *bb, unsigned long generation); + +/* + * We only know about the caller-clobbered registers + * right now. + */ +static struct hardreg hardregs[] = { + { .name = "eax" }, + { .name = "edx" }, + { .name = "ecx" }, +}; +#define REGNO (sizeof(hardregs)/sizeof(struct hardreg)) + +static void generate_one_insn(struct instruction *insn, + struct storage_hash_list *inputs, + struct storage_hash_list *outputs) { + switch (insn->opcode) { + case OP_ENTRY: { + struct symbol *sym = insn->bb->ep->name; + const char *name = show_ident(sym->ident); + if (sym->ctype.modifiers & MOD_STATIC) + printf("\n\n%s:\n", name); + else + printf("\n\n.globl %s\n%s:\n", name, name); + break; + } + default: + show_instruction(insn); + break; + } +} + +static void generate(struct basic_block *bb, + struct storage_hash_list *inputs, + struct storage_hash_list *outputs) +{ + int i; struct storage_hash *entry; - struct storage_hash_list *inputs, *outputs; + struct instruction *insn; + struct basic_block *child; - inputs = gather_storage(bb, STOR_IN); - outputs = gather_storage(bb, STOR_OUT); + for (i = 0; i < REGNO; i++) + hardregs->contains = NULL; FOR_EACH_PTR(inputs, entry) { - printf("\t%s <- %s\n", show_pseudo(entry->pseudo), show_storage(entry->storage)); + struct storage *storage = entry->storage; + const char *name = show_storage(storage); + if (storage->type == REG_REG) { + int regno = storage->regno; + hardregs[regno].contains = entry->pseudo; + name = hardregs[regno].name; + } + printf("\t%s <- %s\n", show_pseudo(entry->pseudo), name); } END_FOR_EACH_PTR(entry); - show_bb(bb); + + FOR_EACH_PTR(bb->insns, insn) { + if (!insn->bb) + continue; + generate_one_insn(insn, inputs, outputs); + } END_FOR_EACH_PTR(insn); + FOR_EACH_PTR(outputs, entry) { printf("\t%s -> %s\n", show_pseudo(entry->pseudo), show_storage(entry->storage)); } END_FOR_EACH_PTR(entry); printf("\n"); + FOR_EACH_PTR(bb->children, child) { + if (child->generation == bb->generation) + continue; + printf(".L%p:\n", child); + output_bb(child, bb->generation); + } END_FOR_EACH_PTR(child); +} + +static void output_bb(struct basic_block *bb, unsigned long generation) +{ + struct storage_hash_list *inputs, *outputs; + + bb->generation = generation; + inputs = gather_storage(bb, STOR_IN); + outputs = gather_storage(bb, STOR_OUT); + + generate(bb, inputs, outputs); + free_ptr_list(&inputs); free_ptr_list(&outputs); } static void output(struct entrypoint *ep) { - struct basic_block *bb, *prev; + unsigned long generation = ++bb_generation; /* Set up initial inter-bb storage links */ set_up_storage(ep); /* Show the results ... */ - prev = NULL; - FOR_EACH_PTR(ep->bbs, bb) { - output_bb(bb); - } END_FOR_EACH_PTR(bb); + output_bb(ep->entry->bb, generation); /* Clear the storage hashes for the next function.. */ free_storage(); |
