Better management of register data. Add struct hreg.
authorDavid Given <dg@cowlark.com>
Wed, 5 Oct 2016 19:00:28 +0000 (21:00 +0200)
committerDavid Given <dg@cowlark.com>
Wed, 5 Oct 2016 19:00:28 +0000 (21:00 +0200)
mach/proto/mcg/mcg.h
mach/proto/mcg/pass_splitcriticaledges.c
mach/proto/mcg/reg.c [new file with mode: 0644]
mach/proto/mcg/reg.h [new file with mode: 0644]
mach/proto/mcg/table
mach/proto/mcg/vreg.c [deleted file]
mach/proto/mcg/vreg.h [deleted file]
util/mcgg/gram.y
util/mcgg/iburg.c
util/mcgg/iburg.h
util/mcgg/mcgg.h

index dc70028..07da364 100644 (file)
@@ -24,7 +24,7 @@
 #include "ir.h"
 #include "mcgg.h"
 #include "hop.h"
-#include "vreg.h"
+#include "reg.h"
 #include "basicblock.h"
 #include "procedure.h"
 
index a7fa63e..9237be7 100644 (file)
@@ -88,4 +88,3 @@ void pass_split_critical_edges(struct procedure* proc)
 
 /* vim: set sw=4 ts=4 expandtab : */
 
-
diff --git a/mach/proto/mcg/reg.c b/mach/proto/mcg/reg.c
new file mode 100644 (file)
index 0000000..c4cf710
--- /dev/null
@@ -0,0 +1,32 @@
+#include "mcg.h"
+
+static int vreg_count = 1;
+
+struct vreg* new_vreg(void)
+{
+       struct vreg* vreg = calloc(1, sizeof *vreg);
+       vreg->id = vreg_count++;
+       return vreg;
+}
+
+struct hreg* new_hreg(struct burm_register_data* brd)
+{
+       struct hreg* hreg = calloc(1, sizeof *hreg);
+       hreg->name = brd->name;
+       hreg->attrs = brd->attrs;
+       hreg->is_stacked = false;
+       return hreg;
+}
+
+struct hreg* new_stacked_hreg(int offset, uint32_t attrs)
+{
+       struct hreg* hreg = calloc(1, sizeof *hreg);
+       hreg->name = aprintf("stacked_%d", offset);
+       hreg->attrs = attrs;
+       hreg->is_stacked = true;
+       hreg->offset = offset;
+       return hreg;
+}
+
+/* vim: set sw=4 ts=4 expandtab : */
+
diff --git a/mach/proto/mcg/reg.h b/mach/proto/mcg/reg.h
new file mode 100644 (file)
index 0000000..62bbb69
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef REG_H
+#define REG_H
+
+#define WITH_ATTR(a) (1<<(a))
+
+struct hreg
+{
+       const char* name;
+       uint32_t attrs;
+       bool is_stacked;
+       int offset;
+};
+
+struct vreg
+{
+       int id;
+};
+
+extern struct vreg* new_vreg(void);
+
+extern struct hreg* new_hreg(struct burm_register_data* brd);
+extern struct hreg* new_stacked_hreg(int offset, uint32_t attrs);
+
+#endif
+
+/* vim: set sw=4 ts=4 expandtab : */
index c333a63..8ff3b24 100644 (file)
@@ -1,28 +1,28 @@
 REGISTERS
 
-       r0  any int ret;
-       r1  any int;
-       r2  any int;
-       r3  any int;
-       r4  any int;
-       r5  any int;
-       r6  any int;
-       r7  any int;
-       r8  any int;
-       r9  any int;
-       r10 any int;
-       r11 any int;
-
-       s0  any float;
-       s1  any float;
-       s2  any float;
-       s3  any float;
-       s4  any float;
-       s5  any float;
-       s6  any float;
-       s7  any float;
-       s8  any float;
-       s9  any float;
+       r0  bytes4 int ret;
+       r1  bytes4 int;
+       r2  bytes4 int;
+       r3  bytes4 int;
+       r4  bytes4 int;
+       r5  bytes4 int;
+       r6  bytes4 int;
+       r7  bytes4 int;
+       r8  bytes4 int;
+       r9  bytes4 int;
+       r10 bytes4 int;
+       r11 bytes4 int;
+
+       s0  bytes4 float;
+       s1  bytes4 float;
+       s2  bytes4 float;
+       s3  bytes4 float;
+       s4  bytes4 float;
+       s5  bytes4 float;
+       s6  bytes4 float;
+       s7  bytes4 float;
+       s8  bytes4 float;
+       s9  bytes4 float;
 
        cc  cc;
 
diff --git a/mach/proto/mcg/vreg.c b/mach/proto/mcg/vreg.c
deleted file mode 100644 (file)
index 636475d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "mcg.h"
-
-static int vreg_count = 1;
-
-struct vreg* new_vreg(void)
-{
-       struct vreg* vreg = calloc(1, sizeof *vreg);
-       vreg->id = vreg_count++;
-       return vreg;
-}
diff --git a/mach/proto/mcg/vreg.h b/mach/proto/mcg/vreg.h
deleted file mode 100644 (file)
index ef92fd2..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef VREG_H
-#define VREG_H
-
-struct vreg
-{
-       int id;
-};
-
-extern struct vreg* new_vreg(void);
-
-#endif
-
index 5dc23a8..a7ba08d 100644 (file)
@@ -74,7 +74,7 @@ registers
 
 register
     : ID                              { $$ = makereg($1); }
-    | register ID                     { $$ = $1; addregclass($1, $2); }
+    | register ID                     { $$ = $1; addregattr($1, $2); }
     ;
 
 declarations
@@ -95,7 +95,7 @@ allocates
             $$ = $1;
             if ($$->allocate)
                 yyerror("pattern type is defined to already allocate a register");
-            $$->allocate = getregclass($4);
+            $$->allocate = getregattr($4);
         }
     ;
 
index 3eb703b..b9ecd2c 100644 (file)
@@ -29,11 +29,12 @@ static Rule rules;
 static int nrules;
 
 static SMAPOF(struct reg) registers;
-static SMAPOF(struct regclass) registerclasses;
+static SMAPOF(struct regattr) registerattrs;
 
 static void print(char* fmt, ...);
 static void ckreach(Nonterm p);
 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);
@@ -47,7 +48,7 @@ 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 emitregisterclasses();
+static void emitregisterattrs();
 static void emitregisters();
 static void emitrule(Nonterm nts);
 static void emitstate(Term terms, Nonterm start, int ntnumber);
@@ -125,6 +126,10 @@ int main(int argc, char* argv[])
        registerterminals();
 
        start = nonterm("stmt", true);
+       makeregattr("bytes1");
+       makeregattr("bytes2");
+       makeregattr("bytes4");
+       makeregattr("bytes8");
 
        yyin = infp;
        yyparse();
@@ -137,7 +142,7 @@ int main(int argc, char* argv[])
                        yyerror("can't reach non-terminal `%s'\n", p->name);
        #endif
 
-       emitregisterclasses();
+       emitregisterattrs();
        emitregisters();
        emitdefs(nts, ntnumber);
        emitstruct(nts, ntnumber);
@@ -194,7 +199,7 @@ struct entry
                struct term t;
                struct nonterm nt;
                struct reg r;
-               struct regclass rc;
+               struct regattr rc;
        } sym;
        struct entry* link;
 } * table[211];
@@ -236,7 +241,7 @@ static void* install(const char* name)
 struct reg* makereg(const char* id)
 {
        struct reg* p = smap_get(&registers, id);
-       static int number = 1;
+       static int number = 0;
 
        if (p)
                yyerror("redefinition of '%s'", id);
@@ -248,25 +253,34 @@ struct reg* makereg(const char* id)
        return p;
 }
 
-void addregclass(struct reg* reg, const char* id)
+struct regattr* makeregattr(const char* id)
 {
-       struct regclass* p = smap_get(&registerclasses, id);
-       static int number = 1;
+       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 = calloc(1, sizeof(*p));
-               p->name = id;
-               p->number = number++;
-               smap_put(&registerclasses, id, p);
-       }
+               p = makeregattr(id);
 
-       reg->classes |= 1<<(p->number);
+       reg->attrs |= 1<<(p->number);
 }
 
-struct regclass* getregclass(const char* id)
+struct regattr* getregattr(const char* id)
 {
-       struct regclass* p = smap_get(&registerclasses, id);
+       struct regattr* p = smap_get(&registerattrs, id);
        if (!p)
                yyerror("'%s' is not the name of a register class", id);
        return p;
@@ -318,9 +332,6 @@ Term term(const char* id, int esn)
                    p->name, p->esn);
        p->link = *q;
        *q = p;
-
-       if (esn != -1)
-               print("enum { %s = %d };\n", id, esn);
        return p;
 }
 
@@ -415,10 +426,6 @@ static void print(char* fmt, ...)
                                        fprintf(outfp, "%x", va_arg(ap, uint32_t));
                                        break;
 
-                               case 'X':
-                                       fprintf(outfp, "0x%" PRIx64 "ULL", va_arg(ap, uint64_t));
-                                       break;
-
                                case 's':
                                        fputs(va_arg(ap, char*), outfp);
                                        break;
@@ -499,16 +506,15 @@ static void ckreach(Nonterm p)
                reach(r->pattern);
 }
 
-static void emitregisterclasses(void)
+static void emitregisterattrs(void)
 {
        int i;
 
        print("const char* %Pregister_class_names[] = {\n");
-       print("%1NULL,\n"); /* register class id 0 is invalid */
-       for (i=0; i<registerclasses.count; i++)
+       for (i=0; i<registerattrs.count; i++)
        {
-               struct regclass* rc = registerclasses.item[i].right;
-               assert(rc->number == (i+1));
+               struct regattr* rc = registerattrs.item[i].right;
+               assert(rc->number == i);
 
                print("%1\"%s\",\n", rc->name);
        }
@@ -520,14 +526,14 @@ static void emitregisters(void)
        int i;
 
        print("const struct %Pregister_data %Pregister_data[] = {\n");
-       print("%1{ 0 },\n"); /* register id 0 is invalid */
        for (i=0; i<registers.count; i++)
        {
                struct reg* r = registers.item[i].right;
-               assert(r->number == (i+1));
+               assert(r->number == i);
 
-               print("%1{ \"%s\", %X },\n", r->name, r->classes);
+               print("%1{ \"%s\", 0x%x },\n", r->name, r->attrs);
        }
+       print("%1{ NULL }\n");
        print("};\n\n");
 }
 
@@ -1168,6 +1174,11 @@ static void emitterms(Term terms)
        Term p;
        int k;
 
+       print("enum {\n");
+       for (k = 0, p = terms; p; p = p->link)
+               print("%1%S = %d,\n", p, p->esn);
+       print("};\n\n");
+
        print("static const char %Parity[] = {\n");
        for (k = 0, p = terms; p; p = p->link)
        {
index 24700e5..60e51d7 100644 (file)
@@ -47,18 +47,18 @@ struct reg
 {
        const char* name;      /* register name */
        int number;            /* identifying number */
-       uint64_t classes;      // bitfield of classes */
+       uint32_t attrs;        /* bitfield of register attributes */
 };
 
-struct regclass
+struct regattr
 {
        const char* name;      /* class name */
        int number;            /* identifying number */
 };
 
 extern struct reg* makereg(const char* name);
-extern void addregclass(struct reg* reg, const char* regclass);
-extern struct regclass* getregclass(const char* name);
+extern void addregattr(struct reg* reg, const char* regattr);
+extern struct regattr* getregattr(const char* name);
 
 struct term
 { /* terminals: */
@@ -82,7 +82,7 @@ struct nonterm
        Rule chain;       /* chain rules w/non-terminal on rhs */
        Nonterm link;     /* next terminal in number order */
        bool is_fragment; /* these instructions are all fragments */
-       struct regclass* allocate; /* allocate this kind of register */
+       struct regattr* allocate; /* allocate this kind of register */
 };
 extern void* lookup(const char* name);
 extern Nonterm nonterm(const char* id, bool allocate);
index a3ff019..65dc26f 100644 (file)
@@ -61,12 +61,20 @@ extern const struct burm_instruction_data burm_instruction_data[];
 struct burm_register_data
 {
     const char* name;
-    uint32_t classes;
+    uint32_t attrs;
 };
 
 extern const struct burm_register_data burm_register_data[];
 extern const char* burm_register_class_names[];
 
+enum
+{
+    REGATTR_BYTES1 = 0,
+    REGATTR_BYTES2,
+    REGATTR_BYTES4,
+    REGATTR_BYTES8
+};
+
 #endif
 
 /* vim: set sw=4 ts=4 expandtab : */