diff --git a/tools/qfcc/include/dags.h b/tools/qfcc/include/dags.h index e9d58047d..db7dd3124 100644 --- a/tools/qfcc/include/dags.h +++ b/tools/qfcc/include/dags.h @@ -32,8 +32,10 @@ typedef struct daglabel_s { struct daglabel_s *next; + struct daglabel_s **prev; const char *opcode; ///< not if op struct operand_s *op; ///< not if opcode; + struct dagnode_s *dagnode; ///< node with which this label is associated } daglabel_t; typedef struct dagnode_s { @@ -57,5 +59,13 @@ typedef struct dagnode_s { const char *daglabel_string (daglabel_t *label); void print_dag (dagnode_t *node, const char *filename); +struct sblock_s; + +/** Make a dag for a single basic block. + + \param block The basic block for which the dag will be created. + \return The dag representing the basic block. +*/ +dagnode_t *make_dag (const struct sblock_s *block); #endif//dags_h diff --git a/tools/qfcc/include/symtab.h b/tools/qfcc/include/symtab.h index aead04d0c..083d34d7b 100644 --- a/tools/qfcc/include/symtab.h +++ b/tools/qfcc/include/symtab.h @@ -64,6 +64,7 @@ typedef struct symbol_s { sy_type_e sy_type; ///< symbol type (st_type) struct type_s *type; ///< type of object to which symbol refers struct param_s *params; ///< the parameters if a function + struct daglabel_s *daglabel;///< dag label for this symbol union { int offset; ///< st_var (in a struct/union) struct def_s *def; ///< st_var diff --git a/tools/qfcc/source/dags.c b/tools/qfcc/source/dags.c index 6cd8090d9..55934be49 100644 --- a/tools/qfcc/source/dags.c +++ b/tools/qfcc/source/dags.c @@ -40,9 +40,30 @@ #include #include "dags.h" +#include "diagnostic.h" +#include "qfcc.h" #include "statements.h" #include "symtab.h" +static daglabel_t *free_labels; +static dagnode_t *free_nodes; + +static daglabel_t * +new_label (void) +{ + daglabel_t *label; + ALLOC (256, daglabel_t, labels, label); + return label; +} + +static dagnode_t * +new_node (void) +{ + dagnode_t *node; + ALLOC (256, dagnode_t, nodes, node); + return node; +} + const char * daglabel_string (daglabel_t *label) { @@ -52,3 +73,71 @@ daglabel_string (daglabel_t *label) return label->opcode; return operand_string (label->op); } + +static const dagnode_t * +label_node (operand_t *op) +{ + operand_t *o = op; + dagnode_t *node; + daglabel_t *label; + symbol_t *sym = 0; + + while (o->op_type == op_alias) + o = o->o.alias; + if (o->op_type != op_symbol) { + if (o->op_type != op_value && o->op_type != op_pointer) + debug (0, "unexpected operand type"); + goto make_new_node; + } + sym = o->o.symbol; + if (sym->daglabel) + return sym->daglabel->dagnode; + +make_new_node: + label = new_label (); + label->op = op; + if (sym) + sym->daglabel = label; + node = new_node (); + node->label = label; + return node; +} + +dagnode_t * +make_dag (const sblock_t *block) +{ + statement_t *s; + dagnode_t *dag; + + for (s = block->statements; s; s = s->next) { + dagnode_t *x = 0, *y = 0, *z = 0; + // c = a * b + // c = ~a + // c = a / b + // c = a + b + // c = a - b + // c = a {==,!=,<=,>=,<,>} b + // c = a.b + // c = &a.b + // c = a (convert) + // b = a + // b .= a + // b.c = a + // c = !a + // cond a goto b + // callN a + // rcallN a, [b, [c]] + // state a, b + // state a, b, c + // goto a + // jump a + // jumpb a, b + // c = a &&/|| b + // c = a <> b + // c = a & b + // c = a | b + // c = a % b + // c = a ^ b + // c = a (move) b (count) + } +}