Add (pretty crummy) support for register aliases and static pairs of registers.
authorDavid Given <dg@cowlark.com>
Fri, 21 Oct 2016 21:31:00 +0000 (23:31 +0200)
committerDavid Given <dg@cowlark.com>
Fri, 21 Oct 2016 21:31:00 +0000 (23:31 +0200)
We should have enough functionality now for rather buggy 8-bit ints and
doubles. Rework the table and the platform.c to match.

16 files changed:
mach/powerpc/mcg/platform.c
mach/powerpc/mcg/table
mach/proto/mcg/hop.c
mach/proto/mcg/hop.h
mach/proto/mcg/pass_instructionselection.c
mach/proto/mcg/pass_promotefloatops.c
mach/proto/mcg/pass_registerallocator.c
mach/proto/mcg/reg.c
mach/proto/mcg/reg.h
mach/proto/mcg/treebuilder.c
util/mcgg/gram.y
util/mcgg/iburg.c
util/mcgg/iburg.h
util/mcgg/ir.dat
util/mcgg/mcgg.h
util/mcgg/scan.l

index 0feaf0d..e3ab269 100644 (file)
@@ -98,51 +98,122 @@ struct hop* platform_epilogue(void)
 struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest)
 {
     struct hop* hop = new_hop(bb, NULL);
+    const uint32_t type_attrs =
+        burm_int_ATTR | burm_pair_ATTR | burm_float_ATTR | burm_double_ATTR;
 
-    if (!src->is_stacked && dest->is_stacked)
+    if ((src->type & type_attrs) != (dest->type & type_attrs))
     {
-        if (src->type & burm_int_ATTR)
-                       hop_add_insel(hop, "stw %H, %S(fp) ! %H", src, dest, dest);
-        else if (src->type & burm_float_ATTR)
-            hop_add_insel(hop, "stfs %H, %S(fp) ! %H", src, dest, dest);
-        else
-            assert(false);
-    }
-    else if (src->is_stacked && !dest->is_stacked)
-    {
-        if (src->type & burm_int_ATTR)
-                       hop_add_insel(hop, "lwz %H, %S(fp) ! %H", dest, src, src);
-        else if (src->type & burm_float_ATTR)
-            hop_add_insel(hop, "lfs %H, %S(fp) ! %H", dest, src, src);
-        else
-            assert(false);
-    }
-    else if (!src->is_stacked && !dest->is_stacked)
-    {
-        if ((src->type & burm_int_ATTR) && (dest->type & burm_int_ATTR))
-                       hop_add_insel(hop, "mr %H, %H", dest, src);
-        else if ((src->type & burm_float_ATTR) && (dest->type & burm_float_ATTR))
-            hop_add_insel(hop, "fmr %H, %H", dest, src);
-        else
+        assert(!src->is_stacked);
+        assert(!dest->is_stacked);
+
+        switch (src->type & type_attrs)
         {
-            if (src->type & burm_int_ATTR)
+            case burm_int_ATTR:
                 hop_add_insel(hop, "stwu %H, -4(sp)", src);
-            else if (src->type & burm_float_ATTR)
+                break;
+
+            case burm_float_ATTR:
                 hop_add_insel(hop, "stfsu %H, -4(sp)", src);
-            else
+                break;
+
+            case burm_double_ATTR:
+                hop_add_insel(hop, "stfdu %H, -8(sp)", src);
+                break;
+
+            default:
                 assert(false);
+        }
 
-            if (dest->type & burm_int_ATTR)
+        switch (dest->type & type_attrs)
+        {
+            case burm_int_ATTR:
                 hop_add_insel(hop, "lwz %H, 0(sp)", dest);
-            else if (dest->type & burm_float_ATTR)
+                break;
+
+            case burm_float_ATTR:
                 hop_add_insel(hop, "lfs %H, 0(sp)", dest);
-            else
+                break;
+
+            case burm_double_ATTR:
+                hop_add_insel(hop, "lfd %H, 0(sp)", dest);
+                break;
+
+            default:
                 assert(false);
-            hop_add_insel(hop, "addi sp, sp, 4");
         }
-       }
-       else
-               fatal("cannot generate move from %s to %s", src->name, dest->name);
+
+        switch (dest->type & type_attrs)
+        {
+            case burm_int_ATTR:
+            case burm_float_ATTR:
+                hop_add_insel(hop, "addi sp, sp, 4");
+                break;
+
+            case burm_double_ATTR:
+            case burm_pair_ATTR:
+                hop_add_insel(hop, "addi sp, sp, 8");
+                break;
+
+            default:
+                assert(false);
+        }
+    }
+    else
+    {
+        uint32_t type = src->type & type_attrs;
+
+        if (!src->is_stacked && dest->is_stacked)
+        {
+            switch (type)
+            {
+                case burm_int_ATTR:
+                    hop_add_insel(hop, "stw %H, %S(fp) ! %H", src, dest, dest);
+                    break;
+
+                case burm_float_ATTR:
+                    hop_add_insel(hop, "stfs %H, %S(fp) ! %H", src, dest, dest);
+                    break;
+
+                default:
+                    assert(false);
+            }
+        }
+        else if (src->is_stacked && !dest->is_stacked)
+        {
+            switch (type)
+            {
+                case burm_int_ATTR:
+                    hop_add_insel(hop, "lwz %H, %S(fp) ! %H", dest, src, src);
+                    break;
+
+                case burm_float_ATTR:
+                    hop_add_insel(hop, "lfs %H, %S(fp) ! %H", dest, src, src);
+                    break;
+
+                default:
+                    assert(false);
+            }
+        }
+        else if (!src->is_stacked && !dest->is_stacked)
+        {
+            switch (type)
+            {
+                case burm_int_ATTR:
+                    hop_add_insel(hop, "mr %H, %H", dest, src);
+                    break;
+
+                case burm_float_ATTR:
+                case burm_double_ATTR:
+                    hop_add_insel(hop, "fmr %H, %H", dest, src);
+                    break;
+
+                default:
+                    assert(false);
+            }
+        }
+        else
+            assert(false);
+    }
 
     return hop;
 }
index 3a1da6f..236f5c7 100644 (file)
@@ -7,71 +7,122 @@ REGISTERS
      * a register into another register (e.g. for eviction).
      */
 
-    r12 "r12" bytes4! int! volatile; 
-    r11 "r11" bytes4! int! volatile; 
-    r10 "r10" bytes4! int! volatile; 
-    r9  "r9"  bytes4! int! volatile;
-    r8  "r8"  bytes4! int! volatile;
-    r7  "r7"  bytes4! int! volatile;
-    r6  "r6"  bytes4! int! volatile;
-    r5  "r5"  bytes4! int! volatile;
-    r4  "r4"  bytes4! int! volatile;
-    r3  "r3"  bytes4! int! volatile ret;
-
-    r31 "r31" bytes4! int!; 
-    r30 "r30" bytes4! int!; 
-    r29 "r29" bytes4! int!; 
-    r28 "r28" bytes4! int!; 
-    r27 "r27" bytes4! int!; 
-    r26 "r26" bytes4! int!; 
-    r25 "r25" bytes4! int!; 
-    r24 "r24" bytes4! int!; 
-    r23 "r23" bytes4! int!; 
-    r22 "r22" bytes4! int!; 
-    r21 "r21" bytes4! int!; 
-    r20 "r20" bytes4! int!; 
-    r19 "r19" bytes4! int!; 
-    r18 "r18" bytes4! int!; 
-    r17 "r17" bytes4! int!; 
-    r16 "r16" bytes4! int!;
-    r15 "r15" bytes4! int!;
-    r14 "r14" bytes4! int!;
-
-    f14 "f14" bytes4! float! volatile;
-    f13 "f13" bytes4! float! volatile;
-    f12 "f12" bytes4! float! volatile;
-    f11 "f11" bytes4! float! volatile;
-    f10 "f10" bytes4! float! volatile;
-    f9  "f9"  bytes4! float! volatile;
-    f8  "f8"  bytes4! float! volatile;
-    f7  "f7"  bytes4! float! volatile;
-    f6  "f6"  bytes4! float! volatile;
-    f5  "f5"  bytes4! float! volatile;
-    f4  "f4"  bytes4! float! volatile;
-    f3  "f3"  bytes4! float! volatile fret;
-    f2  "f2"  bytes4! float! volatile;
-    f1  "f1"  bytes4! float! volatile;
-    f0  "f0"  bytes4! float! volatile;
-
-    f31 "f31" bytes4! float!;
-    f30 "f30" bytes4! float!;
-    f29 "f29" bytes4! float!;
-    f28 "f28" bytes4! float!;
-    f27 "f27" bytes4! float!;
-    f26 "f26" bytes4! float!;
-    f25 "f25" bytes4! float!;
-    f24 "f24" bytes4! float!;
-    f23 "f23" bytes4! float!;
-    f22 "f22" bytes4! float!;
-    f21 "f21" bytes4! float!;
-    f20 "f20" bytes4! float!;
-    f19 "f19" bytes4! float!;
-    f18 "f18" bytes4! float!;
-    f17 "f17" bytes4! float!;
-    f16 "f16" bytes4! float!;
-    f15 "f15" bytes4! float!;
-            
-       cr0 "cr0" cr!;
+    r12                                           bytes4! int! volatile; 
+    r11                                           bytes4! int! volatile; 
+    r10                                           bytes4! int! volatile; 
+    r9                                            bytes4! int! volatile;
+    r8                                            bytes4! int! volatile;
+    r7                                            bytes4! int! volatile;
+    r6                                            bytes4! int! volatile;
+    r5                                            bytes4! int! volatile;
+    r4                                            bytes4! int! volatile;
+    r3                                            bytes4! int! volatile ret;
+
+    r31                                           bytes4! int!; 
+    r30                                           bytes4! int!; 
+    r29                                           bytes4! int!; 
+    r28                                           bytes4! int!; 
+    r27                                           bytes4! int!; 
+    r26                                           bytes4! int!; 
+    r25                                           bytes4! int!; 
+    r24                                           bytes4! int!; 
+    r23                                           bytes4! int!; 
+    r22                                           bytes4! int!; 
+    r21                                           bytes4! int!; 
+    r20                                           bytes4! int!; 
+    r19                                           bytes4! int!; 
+    r18                                           bytes4! int!; 
+    r17                                           bytes4! int!; 
+    r16                                           bytes4! int!;
+    r15                                           bytes4! int!;
+    r14                                           bytes4! int!;
+    r13                                           bytes4! int!;
+
+    r11r12  named("r11", "r12") aliases(r11, r12) bytes8! pair! volatile;
+    r9r10   named("r9",  "r10") aliases(r9,  r10) bytes8! pair! volatile;
+    r7r8    named("r7",  "r8")  aliases(r7,  r8)  bytes8! pair! volatile;
+    r5r6    named("r5",  "r6")  aliases(r6,  r6)  bytes8! pair! volatile;
+    r3r4    named("r3",  "r4")  aliases(r3,  r4)  bytes8! pair! volatile pret;
+
+    r29r30  named("r29", "r30") aliases(r29, r30) bytes8! pair!;
+    r27r28  named("r27", "r28") aliases(r27, r28) bytes8! pair!;
+    r25r26  named("r25", "r26") aliases(r25, r26) bytes8! pair!;
+    r23r24  named("r23", "r24") aliases(r23, r24) bytes8! pair!;
+    r21r22  named("r21", "r22") aliases(r21, r22) bytes8! pair!;
+    r19r20  named("r19", "r20") aliases(r19, r20) bytes8! pair!;
+    r17r18  named("r17", "r18") aliases(r17, r18) bytes8! pair!;
+    r15r16  named("r15", "r16") aliases(r15, r16) bytes8! pair!;
+    r13r14  named("r13", "r14") aliases(r13, r14) bytes8! pair!;
+
+    f14                                           bytes4! float! volatile;
+    f13                                           bytes4! float! volatile;
+    f12                                           bytes4! float! volatile;
+    f11                                           bytes4! float! volatile;
+    f10                                           bytes4! float! volatile;
+    f9                                            bytes4! float! volatile;
+    f8                                            bytes4! float! volatile;
+    f7                                            bytes4! float! volatile;
+    f6                                            bytes4! float! volatile;
+    f5                                            bytes4! float! volatile;
+    f4                                            bytes4! float! volatile;
+    f3                                            bytes4! float! volatile fret;
+    f2                                            bytes4! float! volatile;
+    f1                                            bytes4! float! volatile;
+    f0                                            bytes4! float! volatile;
+
+    f31                                           bytes4! float!;
+    f30                                           bytes4! float!;
+    f29                                           bytes4! float!;
+    f28                                           bytes4! float!;
+    f27                                           bytes4! float!;
+    f26                                           bytes4! float!;
+    f25                                           bytes4! float!;
+    f24                                           bytes4! float!;
+    f23                                           bytes4! float!;
+    f22                                           bytes4! float!;
+    f21                                           bytes4! float!;
+    f20                                           bytes4! float!;
+    f19                                           bytes4! float!;
+    f18                                           bytes4! float!;
+    f17                                           bytes4! float!;
+    f16                                           bytes4! float!;
+    f15                                           bytes4! float!;
+
+    d14     named("f14")       aliases(f14)       bytes8! double! volatile;
+    d13     named("f13")       aliases(f13)       bytes8! double! volatile;
+    d12     named("f12")       aliases(f12)       bytes8! double! volatile;
+    d11     named("f11")       aliases(f11)       bytes8! double! volatile;
+    d10     named("f10")       aliases(f10)       bytes8! double! volatile;
+    d9      named("f9")        aliases(f9)        bytes8! double! volatile;
+    d8      named("f8")        aliases(f8)        bytes8! double! volatile;
+    d7      named("f7")        aliases(f7)        bytes8! double! volatile;
+    d6      named("f6")        aliases(f6)        bytes8! double! volatile;
+    d5      named("f5")        aliases(f5)        bytes8! double! volatile;
+    d4      named("f4")        aliases(f4)        bytes8! double! volatile;
+    d3      named("f3")        aliases(f3)        bytes8! double! volatile dret;
+    d2      named("f2")        aliases(f2)        bytes8! double! volatile;
+    d1      named("f1")        aliases(f1)        bytes8! double! volatile;
+    d0      named("f0")        aliases(f0)        bytes8! double! volatile;
+
+    d31     named("f31")       aliases(f31)       bytes8! double!;
+    d30     named("f30")       aliases(f30)       bytes8! double!;
+    d29     named("f29")       aliases(f29)       bytes8! double!;
+    d28     named("f28")       aliases(f28)       bytes8! double!;
+    d27     named("f27")       aliases(f27)       bytes8! double!;
+    d26     named("f26")       aliases(f26)       bytes8! double!;
+    d25     named("f25")       aliases(f25)       bytes8! double!;
+    d24     named("f24")       aliases(f24)       bytes8! double!;
+    d23     named("f23")       aliases(f23)       bytes8! double!;
+    d22     named("f22")       aliases(f22)       bytes8! double!;
+    d21     named("f21")       aliases(f21)       bytes8! double!;
+    d20     named("f20")       aliases(f20)       bytes8! double!;
+    d19     named("f19")       aliases(f19)       bytes8! double!;
+    d18     named("f18")       aliases(f18)       bytes8! double!;
+    d17     named("f17")       aliases(f17)       bytes8! double!;
+    d16     named("f16")       aliases(f16)       bytes8! double!;
+    d15     named("f15")       aliases(f15)       bytes8! double!;
+
+       cr0                                           cr!;
 
 
 
@@ -101,6 +152,11 @@ PATTERNS
                emit "stwu %in, -4(sp)"
                cost 4;
 
+    PUSH8(in:(pair)reg)
+        emit "stwu %in.0, -4(sp)"
+        emit "stwu %in.1, -4(sp)"
+        cost 8;
+
        out:(int)reg = POP4
                emit "lwz %out, 0(sp)"
         emit "addi sp, sp, 4"
@@ -113,12 +169,20 @@ PATTERNS
                
        SETRET4(in:(ret)reg)
                emit "! setret4"
-               cost 4;
+               cost 1;
+
+    SETRET8(in:(pret)reg)
+        emit "! setret8"
+        cost 1;
 
     (ret)reg = GETRET4
         emit "! getret4"
         cost 1;
 
+    (pret)reg = GETRET8
+        emit "! getret8"
+        cost 1;
+
        STACKADJUST4(delta:CONST4)
         when signed_constant(%delta, 16)
                emit "addi sp, sp, $delta"
@@ -142,6 +206,11 @@ PATTERNS
 
     /* Stores */
 
+       STORE8(addr:address, value:(pair)reg)
+               emit "stw %value.0, 4+%addr"
+               emit "stw %value.1, 0+%addr"
+               cost 4;
+
        STORE4(addr:address, value:(int)reg)
                emit "stw %value, %addr"
                cost 4;
@@ -168,6 +237,11 @@ PATTERNS
                emit "lwz %out, %addr"
                cost 4;
 
+    out:(pair)reg = LOAD8(addr:address)
+        emit "lwz %out.0, 4+%addr"
+        emit "lwz %out.1, 0+%addr"
+        cost 8;
+
        out:(int)ushort0 = LOAD2(addr:address)
                emit "lhz %out, %addr"
                cost 4;
@@ -480,6 +554,10 @@ PATTERNS
         emit "lfs %out, %addr"
         cost 4;
         
+    out:(double)reg = LOADF8(addr:address)
+        emit "lfd %out, %addr"
+        cost 4;
+        
        out:(float)reg = value:CONSTF4
                emit "lfs %out, address-containing-$value"
                cost 8;
@@ -488,6 +566,10 @@ PATTERNS
                emit "fadds %out, %left, %right"
                cost 4;
 
+       out:(double)reg = ADDF8(left:(double)reg, right:(double)reg)
+               emit "fadd %out, %left, %right"
+               cost 4;
+
        out:(float)reg = SUBF4(left:(float)reg, right:(float)reg)
                emit "fsubs %out, %left, %right"
                cost 4;
index 7bdb232..9dbb010 100644 (file)
@@ -31,17 +31,19 @@ void hop_add_string_insel(struct hop* hop, const char* string)
        array_append(&hop->insels, insel);
 }
 
-void hop_add_hreg_insel(struct hop* hop, struct hreg* hreg)
+void hop_add_hreg_insel(struct hop* hop, struct hreg* hreg, int index)
 {
        struct insel* insel = new_insel(INSEL_HREG);
        insel->u.hreg = hreg;
+    insel->index = index;
        array_append(&hop->insels, insel);
 }
 
-void hop_add_vreg_insel(struct hop* hop, struct vreg* vreg)
+void hop_add_vreg_insel(struct hop* hop, struct vreg* vreg, int index)
 {
        struct insel* insel = new_insel(INSEL_VREG);
        insel->u.vreg = vreg;
+    insel->index = index;
        array_append(&hop->insels, insel);
 }
 
@@ -108,11 +110,11 @@ void hop_add_insel(struct hop* hop, const char* fmt, ...)
                     break;
 
                 case 'H':
-                    hop_add_hreg_insel(hop, va_arg(ap, struct hreg*));
+                    hop_add_hreg_insel(hop, va_arg(ap, struct hreg*), 0);
                     break;
 
                 case 'V':
-                    hop_add_vreg_insel(hop, va_arg(ap, struct vreg*));
+                    hop_add_vreg_insel(hop, va_arg(ap, struct vreg*), 0);
                     break;
             }
         }
@@ -205,7 +207,7 @@ char* hop_render(struct hop* hop)
             case INSEL_HREG:
             {
                 struct hreg* hreg = insel->u.hreg;
-                appendf("%s", hreg->realname);
+                appendf("%s", hreg->brd->names[insel->index]);
                 break;
             }
 
@@ -216,7 +218,7 @@ char* hop_render(struct hop* hop)
                 if (!hreg)
                     hreg = pmap_findright(&hop->regsout, vreg);
                 if (hreg)
-                    appendf("%s", hreg->realname);
+                    appendf("%s", hreg->brd->names[insel->index]);
                 else
                     appendf("%%%d", vreg->id);
                                break;
index e1f2f6d..0cc5dc0 100644 (file)
@@ -16,6 +16,7 @@ enum insel_type
 struct insel
 {
        enum insel_type type;
+    int index;
        union
        {
                const char* string;
@@ -54,8 +55,8 @@ struct hop
 extern struct hop* new_hop(struct basicblock* bb, struct ir* ir);
 
 extern void hop_add_string_insel(struct hop* hop, const char* string);
-extern void hop_add_hreg_insel(struct hop* hop, struct hreg* hreg);
-extern void hop_add_vreg_insel(struct hop* hop, struct vreg* vreg);
+extern void hop_add_hreg_insel(struct hop* hop, struct hreg* hreg, int index);
+extern void hop_add_vreg_insel(struct hop* hop, struct vreg* vreg, int index);
 extern void hop_add_value_insel(struct hop* hop, struct ir* ir);
 extern void hop_add_st_offset_insel(struct hop* hop, struct hreg* hreg);
 extern void hop_add_ab_offset_insel(struct hop* hop, int offset);
index fcfb551..863ed56 100644 (file)
@@ -32,9 +32,9 @@ void burm_panic_cannot_match(struct burm_node* node)
        exit(1);
 }
 
-static void emit_return_reg(void)
+static void emit_return_reg(int index)
 {
-    hop_add_vreg_insel(current_hop, current_hop->output);
+    hop_add_vreg_insel(current_hop, current_hop->output, index);
 }
 
 static struct vreg* find_vreg_of_child(int child)
@@ -47,13 +47,13 @@ static struct vreg* find_vreg_of_child(int child)
         return insn->ir->result;
 }
 
-static void emit_reg(int child)
+static void emit_reg(int child, int index)
 {
     struct vreg* vreg = find_vreg_of_child(child);
 
     if (vreg)
     {
-        hop_add_vreg_insel(current_hop, vreg);
+        hop_add_vreg_insel(current_hop, vreg, index);
         array_appendu(&vreg->used, current_hop);
     }
 }
@@ -109,7 +109,7 @@ static uint32_t find_type_from_constraint(uint32_t attr)
      * this. */
 
     const struct burm_register_data* brd = burm_register_data;
-    while (brd->name)
+    while (brd->id)
     {
         if (brd->attrs & attr)
             return brd->type;
index 87db1e4..2708c7f 100644 (file)
@@ -48,7 +48,7 @@ static void promote(struct ir* ir)
         {
             int i;
             for (i=0; i<ir->u.phivalue.count; i++)
-                array_appendu(&promotable, ir->u.phivalue.item[i].right);
+                promote(ir->u.phivalue.item[i].right);
             break;
         }
     }
index 93a9b1d..5d9e702 100644 (file)
@@ -20,14 +20,30 @@ static bool type_match(struct hreg* hreg, struct vreg* vreg);
 
 static void populate_hregs(void)
 {
+    int i;
     const struct burm_register_data* brd = burm_register_data;
 
     hregs.count = 0;
-    while (brd->name)
+    while (brd->id)
     {
         array_append(&hregs, new_hreg(brd));
         brd++;
     }
+    
+    /* Wire up the register aliases. */
+
+    for (i=0; i<hregs.count; i++)
+    {
+        struct hreg* hreg = hregs.item[i];
+        const struct burm_register_data** alias = hreg->brd->aliases;
+
+        while (*alias)
+        {
+            int index = *alias - burm_register_data;
+            array_append(&hreg->aliases, hregs.item[index]);
+            alias++;
+        }
+    }
 }
 
 static void wire_up_blocks_ins_outs(void)
@@ -43,6 +59,20 @@ static void wire_up_blocks_ins_outs(void)
     }
 }
 
+static bool register_used(register_assignment_t* regs, struct hreg* hreg)
+{
+    int i;
+
+    for (i=0; i<hreg->aliases.count; i++)
+    {
+        struct hreg* alias = hreg->aliases.item[i];
+        if (pmap_findleft(regs, alias))
+            return true;
+    }
+
+    return false;
+}
+
 static struct hreg* allocate_phi_hreg(register_assignment_t* regs,
     struct vreg* vreg, uint32_t type)
 {
@@ -54,7 +84,7 @@ static struct hreg* allocate_phi_hreg(register_assignment_t* regs,
     for (i=0; i<hregs.count; i++)
     {
         struct hreg* hreg = hregs.item[i];
-        if (!pmap_findleft(regs, hreg) && (hreg->type == type))
+        if (!register_used(regs, hreg) && (hreg->type == type))
         {
             /* This one is unused. Use it. */
             return hreg;
@@ -86,7 +116,10 @@ static struct hreg* evict(struct vreg* vreg)
 
         if (evictable(hreg, vreg))
         {
-            if (!candidatein && !candidateout)
+            if (!candidatein &&
+                !candidateout &&
+                !register_used(current_ins, hreg) &&
+                !register_used(current_outs, hreg))
             {
                 /* This hreg is unused, so we don't need to evict anything.
                  * Shouldn't really happen in real life. */
@@ -95,7 +128,7 @@ static struct hreg* evict(struct vreg* vreg)
             if (candidatein == candidateout)
             {
                 /* This is a through register. */
-                tracef('R', "R: evicting %%%d from %s\n", candidatein->id, hreg->name);
+                tracef('R', "R: evicting %%%d from %s\n", candidatein->id, hreg->id);
                 pmap_put(&evicted, candidatein, hreg);
                 pmap_remove(current_ins, hreg, candidatein);
                 pmap_remove(current_outs, hreg, candidatein);
@@ -120,13 +153,13 @@ static bool type_match(struct hreg* hreg, struct vreg* vreg)
 
 static bool allocatable_stackable_input(struct hreg* hreg, struct vreg* vreg)
 {
-    return !pmap_findleft(current_ins, hreg) &&
+    return !register_used(current_ins, hreg) &&
         type_match(hreg, vreg);
 }
 
 static bool allocatable_stackable_output(struct hreg* hreg, struct vreg* vreg)
 {
-    return !pmap_findleft(current_outs, hreg) &&
+    return !register_used(current_outs, hreg) &&
         type_match(hreg, vreg) &&
         !(hreg->attrs & current_hop->insndata->corrupts);
 }
@@ -295,7 +328,7 @@ static void add_output_register(struct vreg* vreg)
 
         pmap_add(current_outs, hreg, vreg);
         tracef('R', "R: output equality constraint requires extra move of %%%d => %s\n",
-            c->equals_to->id, hreg->name);
+            c->equals_to->id, hreg->id);
         pmap_add(current_ins, hreg, c->equals_to);
     }
     else
@@ -332,7 +365,7 @@ static void add_through_register(struct vreg* vreg, struct hreg* hreg)
             /* Nope, can't honour the hint. Mark the register as evicted; we'll
              * put it in something later (probably a stack slot). */
 
-            tracef('R', "R: cannot place %%%d in %s, evicting\n", vreg->id, hreg->name);
+            tracef('R', "R: cannot place %%%d in %s, evicting\n", vreg->id, hreg->id);
             pmap_put(&evicted, vreg, hreg);
             pmap_remove(current_ins, hreg, vreg);
             pmap_remove(current_outs, hreg, vreg);
@@ -372,7 +405,7 @@ static void find_new_home_for_evicted_register(struct vreg* vreg, struct hreg* s
     array_append(&hregs, hreg);
 
 found:
-    tracef('R', "R: evicted %%%d moving to %s\n", vreg->id, hreg->name);
+    tracef('R', "R: evicted %%%d moving to %s\n", vreg->id, hreg->id);
     pmap_add(current_ins, hreg, vreg);
     pmap_add(current_outs, hreg, vreg);
 }
@@ -452,7 +485,7 @@ static void assign_hregs_to_vregs(void)
                 if (hreg)
                 {
                     tracef('R', "R: import hreg %s for input %%%d from %s\n",
-                        hreg->name, vreg->id, prevbb->name);
+                        hreg->id, vreg->id, prevbb->name);
                     assert(!pmap_findleft(old, hreg));
                     pmap_put(old, hreg, vreg);
                     goto nextvreg;
@@ -482,7 +515,7 @@ static void assign_hregs_to_vregs(void)
                 if (hreg && !pmap_findleft(old, hreg))
                 {
                     tracef('R', "R: import hreg %s for phi input %%%d from %s\n",
-                        hreg->name, vreg->id, phi->prev->name);
+                        hreg->id, vreg->id, phi->prev->name);
                     pmap_put(old, hreg, vreg);
                 }
             }
@@ -503,7 +536,7 @@ static void assign_hregs_to_vregs(void)
                 struct hreg* hreg = allocate_phi_hreg(old, vreg, c->type);
 
                 tracef('R', "R: import fallback hreg %s for phi input %%%d from %s\n",
-                    hreg->name, vreg->id, phi->prev->name);
+                    hreg->id, vreg->id, phi->prev->name);
                 pmap_add(old, hreg, vreg);
             }
         }
@@ -525,7 +558,7 @@ static void assign_hregs_to_vregs(void)
                 struct vreg* vreg = hop->regsin.item[k].right;
                 if (k != 0)
                     tracef('R', " ");
-                tracef('R', "%%%d=>%s", vreg->id, hreg->name);
+                tracef('R', "%%%d=>%s", vreg->id, hreg->id);
             }
             tracef('R', "] [");
             for (k=0; k<hop->regsout.count; k++)
@@ -534,7 +567,7 @@ static void assign_hregs_to_vregs(void)
                 struct vreg* vreg = hop->regsout.item[k].right;
                 if (k != 0)
                     tracef('R', " ");
-                tracef('R', "%%%d=>%s", vreg->id, hreg->name);
+                tracef('R', "%%%d=>%s", vreg->id, hreg->id);
             }
             tracef('R', "]\n");
 
@@ -551,9 +584,9 @@ static struct hop* create_swap(struct basicblock* bb, struct hreg* src, struct h
     struct hop* hop = new_hop(bb, NULL);
 
     hop_add_string_insel(hop, "! swap ");
-    hop_add_hreg_insel(hop, src);
+    hop_add_hreg_insel(hop, src, 0);
     hop_add_string_insel(hop, " <-> ");
-    hop_add_hreg_insel(hop, dest);
+    hop_add_hreg_insel(hop, dest, 0);
     hop_add_eoi_insel(hop);
 
     return hop;
@@ -661,7 +694,7 @@ static void insert_phi_copies(void)
 
                     tracef('R', "R: map %%%d -> %%%d (%s)\n",
                         phi->ir->result->id, 
-                        vreg->id, dest->name);
+                        vreg->id, dest->id);
 
                     pmap_put(&destregs, dest, phi->ir->result);
                 }
index 25ec0b6..8af8079 100644 (file)
@@ -12,11 +12,12 @@ struct vreg* new_vreg(void)
 struct hreg* new_hreg(const struct burm_register_data* brd)
 {
        struct hreg* hreg = calloc(1, sizeof *hreg);
-       hreg->name = brd->name;
-    hreg->realname = brd->realname;
+       hreg->id = brd->id;
+    hreg->brd = brd;
     hreg->type = brd->type;
        hreg->attrs = brd->attrs;
        hreg->is_stacked = false;
+    /* The aliases array needs to be initialised later. */
        return hreg;
 }
 
@@ -24,12 +25,12 @@ struct hreg* new_stacked_hreg(uint32_t type)
 {
     static int hreg_count = 1;
        struct hreg* hreg = calloc(1, sizeof *hreg);
-       hreg->name = aprintf("stacked_%d_id_%d", type, hreg_count++);
-    hreg->realname = hreg->name;
+       hreg->id = aprintf("stacked_%d_id_%d", type, hreg_count++);
     hreg->type = type;
        hreg->attrs = type;
        hreg->is_stacked = true;
        hreg->offset = -1;
+    array_append(&hreg->aliases, hreg);
        return hreg;
 }
 
index e71864f..f449b7e 100644 (file)
@@ -13,12 +13,13 @@ struct phicongruence
 
 struct hreg
 {
-       const char* name;
-    const char* realname;
+       const char* id;
+    const struct burm_register_data* brd;
     uint32_t type;
        uint32_t attrs;
        bool is_stacked;
        int offset;
+    ARRAYOF(struct hreg) aliases;
 };
 
 struct vreg
index 8684f1f..7b9ba84 100644 (file)
@@ -495,6 +495,16 @@ static void insn_ivalue(int opcode, arith value)
             );
             break;
 
+        case op_sdl:
+            appendir(
+                new_ir2(
+                    IR_STORE, EM_wordsize*2,
+                    new_localir(value),
+                    pop(EM_wordsize*2)
+                )
+            );
+            break;
+
         case op_lal:
             push(
                 new_localir(value)
@@ -972,6 +982,15 @@ static void insn_lvalue(int opcode, const char* label, arith offset)
             );
             break;
 
+        case op_lde:
+            push(
+                new_ir1(
+                    IR_LOAD, EM_wordsize*2,
+                    address_of_external(label, offset)
+                )
+            );
+            break;
+
         case op_ste:
             appendir(
                 new_ir2(
@@ -982,6 +1001,16 @@ static void insn_lvalue(int opcode, const char* label, arith offset)
             );
             break;
 
+        case op_sde:
+            appendir(
+                new_ir2(
+                    IR_STORE, EM_wordsize*2,
+                    address_of_external(label, offset),
+                    pop(EM_wordsize*2)
+                )
+            );
+            break;
+
         case op_zre:
             appendir(
                 new_ir2(
index e6b1c2f..4844da0 100644 (file)
@@ -33,6 +33,7 @@ extern int yylex(void);
 %term EMIT
 %term EQUALS
 %term FRAGMENT
+%term NAMED
 %term NOTEQUALS
 %term PATTERNS
 %term PREFERS
@@ -44,7 +45,6 @@ extern int yylex(void);
 %token <string>     ID
 %token <string>     QFRAGMENT
 
-%type  <stringlist> aliases;
 %type  <constraint> constraint
 %type  <constraint> constraints
 %type  <expr>       predicate
@@ -55,6 +55,8 @@ extern int yylex(void);
 %type  <rule>       pattern
 %type  <rule>       pattern_constraints
 %type  <rule>       pattern_emit
+%type  <stringlist> aliases;
+%type  <stringlist> names;
 %type  <stringlist> qfragments
 %type  <terminfo>   terminfo
 %type  <tree>       rhs
@@ -73,12 +75,18 @@ registers
     ;
 
 register
-    : ID QFRAGMENT                    { $$ = makereg($1, $2); }
+    : ID                              { $$ = makereg($1); }
+    | register NAMED '(' names ')'    { $$ = $1; setregnames($$, $4); }
     | register ALIASES '(' aliases ')' { $$ = $1; addregaliases($$, $4); }
     | register ID                     { $$ = $1; addregattr($1, $2, false); }
     | register ID '!'                 { $$ = $1; addregattr($1, $2, true); }
     ;
 
+names
+    : QFRAGMENT                       { $$ = calloc(1, sizeof(*$$)); stringlist_add($$, $1); }
+    | names ',' QFRAGMENT             { $$ = $1; stringlist_add($$, $3); }
+    ;
+
 aliases
     : ID                              { $$ = calloc(1, sizeof(*$$)); stringlist_add($$, $1); }
     | aliases ',' ID                  { $$ = $1; stringlist_add($$, $3); }
index cf7950b..146f920 100644 (file)
@@ -268,7 +268,7 @@ static void* install(const char* name)
        return &p->sym;
 }
 
-struct reg* makereg(const char* id, const char* realname)
+struct reg* makereg(const char* id)
 {
        struct reg* p = smap_get(&registers, id);
        static int number = 0;
@@ -277,7 +277,6 @@ struct reg* makereg(const char* id, const char* realname)
                yyerror("redefinition of '%s'", id);
        p = calloc(1, sizeof(*p));
        p->name = id;
-       p->realname = realname;
        p->number = number++;
        array_append(&p->aliases, p);
        smap_put(&registers, id, p);
@@ -285,6 +284,14 @@ struct reg* makereg(const char* id, const char* realname)
        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);
@@ -629,14 +636,33 @@ static void emitregisters(void)
                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\", \"%s\", 0x%x, 0x%x, %Pregister_aliases_%d_%s },\n",
-                       r->name, r->realname, r->type, r->attrs, i, r->name);
+               print("%1{ \"%s\", 0x%x, 0x%x, %Pregister_names_%d_%s, %Pregister_aliases_%d_%s },\n",
+                       r->name, r->type, r->attrs, i, r->name, i, r->name);
        }
        print("%1{ NULL }\n");
        print("};\n\n");
@@ -1215,14 +1241,18 @@ static void emitinsndata(Rule rules)
                
                while (f)
                {
-                       switch (f->data[0])
+                       char* data = strdup(f->data);
+                       int type = *data++;
+                       char* label = strtok(data, ".");
+                       char* nameindex_s = strtok(NULL, ".");
+                       int nameindex = nameindex_s ? atoi(nameindex_s) : 0;
+
+                       switch (type)
                        {
                                case '%':
                                {
-                                       const char* label = f->data + 1;
-
                                        if (r->label && (strcmp(label, r->label) == 0))
-                                               print("%1data->emit_return_reg();\n", label);
+                                               print("%1data->emit_return_reg(%d);\n", nameindex);
                                        else
                                        {
                                                Tree node;
@@ -1234,25 +1264,25 @@ static void emitinsndata(Rule rules)
                                                if (nt->kind == NONTERM)
                                                {
                                                        if (nt->is_fragment)
-                                                               print("%1data->emit_fragment(");
+                                                               print("%1data->emit_fragment(%d);\n", index);
                                                        else
-                                                               print("%1data->emit_reg(");
+                                                               print("%1data->emit_reg(%d, %d);\n", index, nameindex);
                                                }
                                                else
-                                                       print("%1data->emit_reg(");
-
-                                               print("%d);\n", index);
+                                                       print("%1data->emit_reg(%d, %d);\n", index, nameindex);
                                        }
                                        break;
                                }
 
                                case '$':
                                {
-                                       const char* label = f->data + 1;
                                        int index = 0;
                                        if (!find_child_index(r->pattern, label, &index, NULL))
                                                label_not_found(r, label);
 
+                                       if (nameindex != 0)
+                                               yyerror("indices other than 0 make no sense for $-values");
+
                                        print("%1data->emit_value(%d);\n", index);
                                        break;
                                }
index f50e4c9..e0bbeef 100644 (file)
@@ -59,10 +59,10 @@ struct terminfo
 struct reg
 {
        const char* name;          /* friendly register name */
-       const char* realname;      /* name used in assembly output */
        int number;                /* identifying number */
        uint32_t attrs;            /* bitfield of register attributes */
        uint32_t type;             /* register type */
+       struct stringlist* names;  /* register names */
        ARRAYOF(struct reg) aliases; /* registers that this one aliases */
 };
 
@@ -72,7 +72,8 @@ struct regattr
        int number;            /* identifying number */
 };
 
-extern struct reg* makereg(const char* name, const char* realname);
+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, bool exact);
 extern void addregaliases(struct reg* reg, struct stringlist* aliases);
 extern struct regattr* getregattr(const char* name);
index 6f40ae3..5765872 100644 (file)
@@ -23,6 +23,7 @@ S POPF
 S LOAD # must be followed by float form
 S LOADF
 S STORE
+S STOREF
 
 # Arithemetic operations
 S ADD
index 211aaf1..da0c8b1 100644 (file)
@@ -40,8 +40,8 @@ struct burm_emitter_data
 {
     void (*emit_string)(const char* data);
     void (*emit_fragment)(int child);
-    void (*emit_return_reg)(void);
-    void (*emit_reg)(int child);
+    void (*emit_return_reg)(int index);
+    void (*emit_reg)(int child, int index);
     void (*emit_value)(int child);
     void (*emit_eoi)(void);
     void (*constrain_input_reg)(int child, uint32_t attr);
@@ -63,10 +63,10 @@ extern const struct burm_instruction_data burm_instruction_data[];
 
 struct burm_register_data
 {
-    const char* name;
-    const char* realname;
+    const char* id;
     uint32_t type;
     uint32_t attrs;
+    const char** names;
     const struct burm_register_data** aliases;
 };
 
index 44a5824..272dd2b 100644 (file)
@@ -21,7 +21,7 @@ static int braces = 0;
 <INITIAL>"\""               BEGIN(QSTRING);
 <QSTRING>"\""               BEGIN(INITIAL);
 
-<QSTRING>[%$][a-zA-Z_][a-zA_Z_0-9]+ {
+<QSTRING>[%$][a-zA-Z_][a-zA_Z_0-9]+(\.[0-9]+)? {
                                 yylval.string = strdup(yytext);
                                 return QFRAGMENT;
                             }
@@ -44,6 +44,7 @@ static int braces = 0;
 "cost"                      return COST;
 "emit"                      return EMIT;
 "fragment"                  return FRAGMENT;
+"named"                     return NAMED;
 "prefers"                   return PREFERS;
 "when"                      return WHEN;
 "with"                      return WITH;