Factor out the register handling code into a separate file, because everything
authorDavid Given <dg@cowlark.com>
Sat, 17 Dec 2016 18:33:56 +0000 (19:33 +0100)
committerDavid Given <dg@cowlark.com>
Sat, 17 Dec 2016 18:33:56 +0000 (19:33 +0100)
is getting to be a bit of a mess.

util/mcgg/build.lua
util/mcgg/gram.y
util/mcgg/iburg.c
util/mcgg/iburg.h
util/mcgg/mcgg.h
util/mcgg/registers.c [new file with mode: 0644]
util/mcgg/registers.h [new file with mode: 0644]

index f805505..9555369 100644 (file)
@@ -35,7 +35,7 @@ clibrary {
                matching(filenamesof("+ircodes"), "%.h$"),
                "./ircodes.h",
                "./mcgg.h"
-       }
+       },
 }
 
 cprogram {
@@ -51,7 +51,7 @@ cprogram {
                "+yacc",
                "modules/src/data+lib",
                "modules+headers",
-       }
+       },
 }
        
 definerule("mcgg",
index 891030a..2258a2d 100644 (file)
@@ -7,6 +7,7 @@
 #include <limits.h>
 #include "iburg.h"
 #include "astring.h"
+#include "registers.h"
 
 #define YYDEBUG 1
 
index 23705c7..75f6b26 100644 (file)
@@ -15,6 +15,7 @@
 #include "astring.h"
 #include "smap.h"
 #include "mcgg.h"
+#include "registers.h"
 
 static char rcsid[] = "$Id$";
 
@@ -33,13 +34,7 @@ static Nonterm nts;
 static Rule rules;
 static int nrules;
 
-static SMAPOF(struct reg) registers;
-static SMAPOF(struct regattr) registerattrs;
-
-static void print(const char* fmt, ...);
-static void printh(const char* fmt, ...);
 static void registerterminals(void);
-static struct regattr* makeregattr(const char* id);
 static void emitclosure(Nonterm nts);
 static void emitcost(Tree t, const char* v);
 static void emitcostcalc(Rule r);
@@ -53,8 +48,6 @@ static void emitleaf(Term p, int ntnumber);
 static void emitnts(Rule rules, int nrules);
 static void emitpredicatedefinitions(Rule rules);
 static void emitrecord(char* pre, Rule r, int cost);
-static void emitregisterattrs();
-static void emitregisters();
 static void emitrule(Nonterm nts);
 static void emitstate(Term terms, Nonterm start, int ntnumber);
 static void emitstring(Rule rules);
@@ -266,91 +259,6 @@ static void* install(const char* name)
        return &p->sym;
 }
 
-struct reg* makereg(const char* id)
-{
-       struct reg* p = smap_get(&registers, id);
-       static int number = 0;
-
-       if (p)
-               yyerror("redefinition of '%s'", id);
-       p = calloc(1, sizeof(*p));
-       p->name = id;
-       p->number = number++;
-       array_append(&p->aliases, p);
-       smap_put(&registers, id, p);
-
-       return p;
-}
-
-void setregnames(struct reg* reg, struct stringlist* names)
-{
-       if (reg->names)
-               yyerror("you can only set one set of register names");
-
-       reg->names = names;
-}
-
-struct regattr* makeregattr(const char* id)
-{
-       struct regattr* p = smap_get(&registerattrs, id);
-       static int number = 0;
-
-       if (p)
-               yyerror("redefinition of '%s'", id);
-       p = calloc(1, sizeof(*p));
-       p->name = id;
-       p->number = number++;
-       smap_put(&registerattrs, id, p);
-
-       return p;
-}
-
-void addregattr(struct reg* reg, const char* id)
-{
-       struct regattr* p = smap_get(&registerattrs, id);
-
-       if (!p)
-               p = makeregattr(id);
-
-       reg->attrs |= 1<<(p->number);
-}
-
-void addregalias(struct reg* r1, struct reg* r2)
-{
-       if (!array_appendu(&r1->aliases, r2))
-       {
-               int i;
-
-               for (i=0; i<r1->aliases.count; i++)
-                       addregalias(r1->aliases.item[i], r2);
-       }
-}
-
-void addregaliases(struct reg* reg, struct stringlist* aliases)
-{
-       struct stringfragment* f = aliases->first;
-
-       while (f)
-       {
-               struct reg* r = smap_get(&registers, f->data);
-               if (!r)
-                       yyerror("register '%s' is not defined here", f->data);
-
-               array_appendu(&reg->aliases, r);
-               array_appendu(&r->aliases, reg);
-
-               f = f->next;
-       }
-}
-
-struct regattr* getregattr(const char* id)
-{
-       struct regattr* p = smap_get(&registerattrs, id);
-       if (!p)
-               yyerror("'%s' is not the name of a register class", id);
-       return p;
-}
-
 /* nonterm - create a new terminal id, if necessary */
 Nonterm nonterm(const char* id, bool allocate)
 {
@@ -450,7 +358,7 @@ Tree tree(const struct terminfo* ti, Tree left, Tree right)
 
                if (ti->attr && ti->attr[0])
                {
-                       t->attr = smap_get(&registerattrs, ti->attr);
+                       t->attr = findregattr(ti->attr);
                        if (!t->attr)
                                yyerror("'%s' doesn't seem to be a known register attribute", ti->attr);
                }
@@ -508,7 +416,7 @@ Rule rule(const struct terminfo* ti, Tree pattern)
 
        if (ti->attr && ti->attr[0])
        {
-               r->attr = smap_get(&registerattrs, ti->attr);
+               r->attr = findregattr(ti->attr);
                if (!r->attr)
                        yyerror("'%s' doesn't seem to be a known register attribute", ti->attr);
        }
@@ -585,7 +493,7 @@ static void printto(FILE* fp, const char* fmt, va_list ap)
                        putc(*fmt, fp);
 }
 
-static void print(const char* fmt, ...)
+void print(const char* fmt, ...)
 {
        va_list ap;
        va_start(ap, fmt);
@@ -593,7 +501,7 @@ static void print(const char* fmt, ...)
        va_end(ap);
 }
 
-static void printh(const char* fmt, ...)
+void printh(const char* fmt, ...)
 {
        va_list ap;
        va_start(ap, fmt);
@@ -601,69 +509,6 @@ static void printh(const char* fmt, ...)
        va_end(ap);
 }
 
-static void emitregisterattrs(void)
-{
-       int i;
-
-       print("const char* %Pregister_class_names[] = {\n");
-       for (i=0; i<registerattrs.count; i++)
-       {
-               struct regattr* rc = registerattrs.item[i].right;
-               assert(rc->number == i);
-
-               print("%1\"%s\",\n", rc->name);
-               printh("#define %P%s_ATTR (1U<<%d)\n", rc->name, rc->number);
-       }
-       print("};\n\n");
-       printh("\n");
-}
-
-static void emitregisters(void)
-{
-       int i, j;
-
-       for (i=0; i<registers.count; i++)
-       {
-               struct reg* r = registers.item[i].right;
-
-               print("const struct %Pregister_data* %Pregister_aliases_%d_%s[] = {\n%1", i, r->name);
-               for (j=0; j<r->aliases.count; j++)
-                       print("&%Pregister_data[%d], ", r->aliases.item[j]->number);
-               print("NULL\n};\n");
-       }
-
-       for (i=0; i<registers.count; i++)
-       {
-               struct reg* r = registers.item[i].right;
-
-               print("const char* %Pregister_names_%d_%s[] = {\n%1", i, r->name);
-               if (r->names)
-               {
-                       struct stringfragment* f = r->names->first;
-                       while (f)
-                       {
-                               print("\"%s\", ", f->data);
-                               f = f->next;
-                       }
-               }
-               else
-                       print("\"%s\", ", r->name);
-               print("NULL\n};\n");
-       }
-
-       print("const struct %Pregister_data %Pregister_data[] = {\n");
-       for (i=0; i<registers.count; i++)
-       {
-               struct reg* r = registers.item[i].right;
-               assert(r->number == i);
-
-               print("%1{ \"%s\", 0x%x, %Pregister_names_%d_%s, %Pregister_aliases_%d_%s },\n",
-                       r->name, r->attrs, i, r->name, i, r->name);
-       }
-       print("%1{ NULL }\n");
-       print("};\n\n");
-}
-
 /* emitcase - emit one case in function state */
 static void emitcase(Term p, int ntnumber)
 {
@@ -1349,7 +1194,7 @@ static void emitinsndata(Rule rules)
 
                                if (c->type == CONSTRAINT_CORRUPTED_ATTR)
                                {
-                                       struct regattr* p = smap_get(&registerattrs, c->left);
+                                       struct regattr* p = findregattr(c->left);
                                        if (!p)
                                                yyerror("no such register attribute '%s'", c->left);
 
index 739641d..961beca 100644 (file)
@@ -57,27 +57,6 @@ struct terminfo
        const char* attr;
 };
 
-struct reg
-{
-       const char* name;          /* friendly register name */
-       int number;                /* identifying number */
-       uint32_t attrs;            /* bitfield of register attributes */
-       struct stringlist* names;  /* register names */
-       ARRAYOF(struct reg) aliases; /* registers that this one aliases */
-};
-
-struct regattr
-{
-       const char* name;      /* class name */
-       int number;            /* identifying number */
-};
-
-extern struct reg* makereg(const char* name);
-extern void setregnames(struct reg* reg, struct stringlist* names);
-extern void addregattr(struct reg* reg, const char* regattr);
-extern void addregaliases(struct reg* reg, struct stringlist* aliases);
-extern struct regattr* getregattr(const char* name);
-
 struct term
 { /* terminals: */
        char* name; /* terminal name */
@@ -153,6 +132,8 @@ extern FILE* hdrfp;
 extern FILE* yyin;
 extern int yylineno;
 
+extern void print(const char* fmt, ...);
+extern void printh(const char* fmt, ...);
 extern void printlineno(void);
 
 #include "mcgg.h"
index c0c930a..fdfc2c5 100644 (file)
@@ -36,6 +36,8 @@ extern const short *burm_nts[];
 extern NODEPTR_TYPE* burm_kids(NODEPTR_TYPE p, int eruleno, NODEPTR_TYPE kids[]);
 extern void burm_trace(NODEPTR_TYPE p, int ruleno, int cost, int bestcost);
 
+extern void yyerror(char *fmt, ...);
+
 struct burm_emitter_data
 {
     void (*emit_string)(const char* data);
diff --git a/util/mcgg/registers.c b/util/mcgg/registers.c
new file mode 100644 (file)
index 0000000..6a47514
--- /dev/null
@@ -0,0 +1,170 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <assert.h>
+#include "mcgg.h"
+#include "registers.h"
+#include "smap.h"
+#include "array.h"
+#include "stringlist.h"
+#include "iburg.h"
+#include "registers.h"
+
+static SMAPOF(struct reg) registers;
+static SMAPOF(struct regattr) registerattrs;
+
+struct reg* makereg(const char* id)
+{
+       struct reg* p = smap_get(&registers, id);
+       static int number = 0;
+
+       if (p)
+               yyerror("redefinition of '%s'", id);
+       p = calloc(1, sizeof(*p));
+       p->name = id;
+       p->number = number++;
+       array_append(&p->aliases, p);
+       smap_put(&registers, id, p);
+
+       return p;
+}
+
+void setregnames(struct reg* reg, struct stringlist* names)
+{
+       if (reg->names)
+               yyerror("you can only set one set of register names");
+
+       reg->names = names;
+}
+
+struct regattr* findregattr(const char* id)
+{
+       return smap_get(&registerattrs, id);
+}
+
+struct regattr* makeregattr(const char* id)
+{
+       struct regattr* p = smap_get(&registerattrs, id);
+       static int number = 0;
+
+       if (p)
+               yyerror("redefinition of '%s'", id);
+       p = calloc(1, sizeof(*p));
+       p->name = id;
+       p->number = number++;
+       smap_put(&registerattrs, id, p);
+
+       return p;
+}
+
+void addregattr(struct reg* reg, const char* id)
+{
+       struct regattr* p = smap_get(&registerattrs, id);
+
+       if (!p)
+               p = makeregattr(id);
+
+       reg->attrs |= 1<<(p->number);
+}
+
+void addregalias(struct reg* r1, struct reg* r2)
+{
+       if (!array_appendu(&r1->aliases, r2))
+       {
+               int i;
+
+               for (i=0; i<r1->aliases.count; i++)
+                       addregalias(r1->aliases.item[i], r2);
+       }
+}
+
+void addregaliases(struct reg* reg, struct stringlist* aliases)
+{
+       struct stringfragment* f = aliases->first;
+
+       while (f)
+       {
+               struct reg* r = smap_get(&registers, f->data);
+               if (!r)
+                       yyerror("register '%s' is not defined here", f->data);
+
+               array_appendu(&reg->aliases, r);
+               array_appendu(&r->aliases, reg);
+
+               f = f->next;
+       }
+}
+
+struct regattr* getregattr(const char* id)
+{
+       struct regattr* p = smap_get(&registerattrs, id);
+       if (!p)
+               yyerror("'%s' is not the name of a register class", id);
+       return p;
+}
+
+void emitregisterattrs(void)
+{
+       int i;
+
+       print("const char* %Pregister_class_names[] = {\n");
+       for (i=0; i<registerattrs.count; i++)
+       {
+               struct regattr* rc = registerattrs.item[i].right;
+               assert(rc->number == i);
+
+               print("%1\"%s\",\n", rc->name);
+               printh("#define %P%s_ATTR (1U<<%d)\n", rc->name, rc->number);
+       }
+       print("};\n\n");
+       printh("\n");
+}
+
+void emitregisters(void)
+{
+       int i, j;
+
+       for (i=0; i<registers.count; i++)
+       {
+               struct reg* r = registers.item[i].right;
+
+               print("const struct %Pregister_data* %Pregister_aliases_%d_%s[] = {\n%1", i, r->name);
+               for (j=0; j<r->aliases.count; j++)
+                       print("&%Pregister_data[%d], ", r->aliases.item[j]->number);
+               print("NULL\n};\n");
+       }
+
+       for (i=0; i<registers.count; i++)
+       {
+               struct reg* r = registers.item[i].right;
+
+               print("const char* %Pregister_names_%d_%s[] = {\n%1", i, r->name);
+               if (r->names)
+               {
+                       struct stringfragment* f = r->names->first;
+                       while (f)
+                       {
+                               print("\"%s\", ", f->data);
+                               f = f->next;
+                       }
+               }
+               else
+                       print("\"%s\", ", r->name);
+               print("NULL\n};\n");
+       }
+
+       print("const struct %Pregister_data %Pregister_data[] = {\n");
+       for (i=0; i<registers.count; i++)
+       {
+               struct reg* r = registers.item[i].right;
+               assert(r->number == i);
+
+               print("%1{ \"%s\", 0x%x, %Pregister_names_%d_%s, %Pregister_aliases_%d_%s },\n",
+                       r->name, r->attrs, i, r->name, i, r->name);
+       }
+       print("%1{ NULL }\n");
+       print("};\n\n");
+}
+
+
diff --git a/util/mcgg/registers.h b/util/mcgg/registers.h
new file mode 100644 (file)
index 0000000..51bcfc4
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef REGISTERS_H
+#define REGISTERS_H
+
+#include "array.h"
+
+struct reg
+{
+       const char* name;          /* friendly register name */
+       int number;                /* identifying number */
+       uint32_t attrs;            /* bitfield of register attributes */
+       struct stringlist* names;  /* register names */
+       ARRAYOF(struct reg) aliases; /* registers that this one aliases */
+};
+
+struct regattr
+{
+       const char* name;      /* class name */
+       int number;            /* identifying number */
+       unsigned int* bitmap;  /* hardware register bitmap */
+};
+
+extern struct reg* makereg(const char* name);
+extern void setregnames(struct reg* reg, struct stringlist* names);
+extern void addregattr(struct reg* reg, const char* regattr);
+extern void addregaliases(struct reg* reg, struct stringlist* aliases);
+extern struct regattr* getregattr(const char* name);
+
+extern void emitregisterattrs(void);
+extern void emitregisters(void);
+
+extern struct regattr* findregattr(const char* name);
+
+#endif
+