aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/example.c
diff options
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-08 13:12:05 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:05:39 -0700
commitbe25179dcf5bd9ac397e422089e9c4c5f883221f (patch)
tree6c92bef1f749bd4cd05aa84270843e3b97d856b6 /example.c
parenta696ed3e5a8e21997d2e0e5a1bba86a4e606f842 (diff)
downloadsparse-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.c93
1 files changed, 82 insertions, 11 deletions
diff --git a/example.c b/example.c
index 284c9ffa..ff778ce5 100644
--- a/example.c
+++ b/example.c
@@ -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();