Remove the bytes1, bytes2, bytes4, bytes8 attributes; remove the concept of a

register 'type'; now use int/float/long/double throughout to identify
registers. Lots of register allocator tweaks and table bugfixes --- we now get
through the dreading Mathlib.mod!
This commit is contained in:
David Given 2016-10-25 23:04:20 +02:00
parent 45a7f2e993
commit 9977ce841a
12 changed files with 207 additions and 200 deletions

View file

@ -59,9 +59,9 @@ struct hop* platform_prologue(void)
for (i=0; i<saved_regs.count; i++) for (i=0; i<saved_regs.count; i++)
{ {
struct hreg* hreg = saved_regs.item[i]; struct hreg* hreg = saved_regs.item[i];
if (hreg->type & burm_int_ATTR) if (hreg->attrs & burm_int_ATTR)
hop_add_insel(hop, "stw %H, %d(fp)", hreg, saved_offset); hop_add_insel(hop, "stw %H, %d(fp)", hreg, saved_offset);
else if (hreg->type & burm_float_ATTR) else if (hreg->attrs & burm_float_ATTR)
hop_add_insel(hop, "stfs %H, %d(fp)", hreg, saved_offset); hop_add_insel(hop, "stfs %H, %d(fp)", hreg, saved_offset);
saved_offset += 4; saved_offset += 4;
} }
@ -78,9 +78,9 @@ struct hop* platform_epilogue(void)
for (i=0; i<saved_regs.count; i++) for (i=0; i<saved_regs.count; i++)
{ {
struct hreg* hreg = saved_regs.item[i]; struct hreg* hreg = saved_regs.item[i];
if (hreg->type & burm_int_ATTR) if (hreg->attrs & burm_int_ATTR)
hop_add_insel(hop, "lwz %H, %d(fp)", hreg, saved_offset); hop_add_insel(hop, "lwz %H, %d(fp)", hreg, saved_offset);
else if (hreg->type & burm_float_ATTR) else if (hreg->attrs & burm_float_ATTR)
hop_add_insel(hop, "lfs %H, %d(fp)", hreg, saved_offset); hop_add_insel(hop, "lfs %H, %d(fp)", hreg, saved_offset);
saved_offset += 4; saved_offset += 4;
} }
@ -98,15 +98,13 @@ struct hop* platform_epilogue(void)
struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest) struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest)
{ {
struct hop* hop = new_hop(bb, NULL); struct hop* hop = new_hop(bb, NULL);
const uint32_t type_attrs =
burm_int_ATTR | burm_long_ATTR | burm_float_ATTR | burm_double_ATTR;
if ((src->type & type_attrs) != (dest->type & type_attrs)) if ((src->attrs & TYPE_ATTRS) != (dest->attrs & TYPE_ATTRS))
{ {
assert(!src->is_stacked); assert(!src->is_stacked);
assert(!dest->is_stacked); assert(!dest->is_stacked);
switch (src->type & type_attrs) switch (src->attrs & TYPE_ATTRS)
{ {
case burm_int_ATTR: case burm_int_ATTR:
hop_add_insel(hop, "stwu %H, -4(sp)", src); hop_add_insel(hop, "stwu %H, -4(sp)", src);
@ -126,10 +124,10 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
break; break;
default: default:
assert(false); goto nomove;
} }
switch (dest->type & type_attrs) switch (dest->attrs & TYPE_ATTRS)
{ {
case burm_int_ATTR: case burm_int_ATTR:
hop_add_insel(hop, "lwz %H, 0(sp)", dest); hop_add_insel(hop, "lwz %H, 0(sp)", dest);
@ -149,10 +147,10 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
break; break;
default: default:
assert(false); goto nomove;
} }
switch (dest->type & type_attrs) switch (dest->attrs & TYPE_ATTRS)
{ {
case burm_int_ATTR: case burm_int_ATTR:
case burm_float_ATTR: case burm_float_ATTR:
@ -165,12 +163,12 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
break; break;
default: default:
assert(false); goto nomove;
} }
} }
else else
{ {
uint32_t type = src->type & type_attrs; uint32_t type = src->attrs & TYPE_ATTRS;
if (!src->is_stacked && dest->is_stacked) if (!src->is_stacked && dest->is_stacked)
{ {
@ -194,7 +192,7 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
break; break;
default: default:
assert(false); goto nomove;
} }
} }
else if (src->is_stacked && !dest->is_stacked) else if (src->is_stacked && !dest->is_stacked)
@ -214,7 +212,7 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
break; break;
default: default:
assert(false); goto nomove;
} }
} }
else if (!src->is_stacked && !dest->is_stacked) else if (!src->is_stacked && !dest->is_stacked)
@ -236,14 +234,17 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
break; break;
default: default:
assert(false); goto nomove;
} }
} }
else else
assert(false); goto nomove;
} }
return hop; return hop;
nomove:
fatal("cannot move %s to %s", src->id, dest->id);
} }
/* vim: set sw=4 ts=4 expandtab : */ /* vim: set sw=4 ts=4 expandtab : */

View file

@ -3,126 +3,129 @@ REGISTERS
/* Registers are allocated top down; the order here is odd in order to make /* Registers are allocated top down; the order here is odd in order to make
* sure that non-volatile registers get allocated from r31 (or f31) down. * sure that non-volatile registers get allocated from r31 (or f31) down.
* *
* Attributes ending in an exclamation mark must match exactly when copying * Attributes may have at most one of: int, float, long, double. These
* a register into another register (e.g. for eviction). * indicate that the register is used to store a value of that type. If
* your register can store more than one type, create an alias. Registers
* with none of these cannot be copied by the code generator (and so cannot
* be moved from register to register or spilt).
*/ */
r12 bytes4! int! volatile; r12 int volatile;
r11 bytes4! int! volatile; r11 int volatile;
r10 bytes4! int! volatile; r10 int volatile;
r9 bytes4! int! volatile; r9 int volatile;
r8 bytes4! int! volatile; r8 int volatile;
r7 bytes4! int! volatile; r7 int volatile;
r6 bytes4! int! volatile; r6 int volatile;
r5 bytes4! int! volatile; r5 int volatile;
r4 bytes4! int! volatile; r4 int volatile;
r3 bytes4! int! volatile ret; r3 int volatile ret;
r31 bytes4! int!; r31 int;
r30 bytes4! int!; r30 int;
r29 bytes4! int!; r29 int;
r28 bytes4! int!; r28 int;
r27 bytes4! int!; r27 int;
r26 bytes4! int!; r26 int;
r25 bytes4! int!; r25 int;
r24 bytes4! int!; r24 int;
r23 bytes4! int!; r23 int;
r22 bytes4! int!; r22 int;
r21 bytes4! int!; r21 int;
r20 bytes4! int!; r20 int;
r19 bytes4! int!; r19 int;
r18 bytes4! int!; r18 int;
r17 bytes4! int!; r17 int;
r16 bytes4! int!; r16 int;
r15 bytes4! int!; r15 int;
r14 bytes4! int!; r14 int;
r13 bytes4! int!; r13 int;
r11r12 named("r11", "r12") aliases(r11, r12) bytes8! long! volatile; r11r12 named("r11", "r12") aliases(r11, r12) long volatile;
r9r10 named("r9", "r10") aliases(r9, r10) bytes8! long! volatile; r9r10 named("r9", "r10") aliases(r9, r10) long volatile;
r7r8 named("r7", "r8") aliases(r7, r8) bytes8! long! volatile; r7r8 named("r7", "r8") aliases(r7, r8) long volatile;
r5r6 named("r5", "r6") aliases(r6, r6) bytes8! long! volatile; r5r6 named("r5", "r6") aliases(r6, r6) long volatile;
r3r4 named("r3", "r4") aliases(r3, r4) bytes8! long! volatile pret; r3r4 named("r3", "r4") aliases(r3, r4) long volatile lret;
r29r30 named("r29", "r30") aliases(r29, r30) bytes8! long!; r29r30 named("r29", "r30") aliases(r29, r30) long;
r27r28 named("r27", "r28") aliases(r27, r28) bytes8! long!; r27r28 named("r27", "r28") aliases(r27, r28) long;
r25r26 named("r25", "r26") aliases(r25, r26) bytes8! long!; r25r26 named("r25", "r26") aliases(r25, r26) long;
r23r24 named("r23", "r24") aliases(r23, r24) bytes8! long!; r23r24 named("r23", "r24") aliases(r23, r24) long;
r21r22 named("r21", "r22") aliases(r21, r22) bytes8! long!; r21r22 named("r21", "r22") aliases(r21, r22) long;
r19r20 named("r19", "r20") aliases(r19, r20) bytes8! long!; r19r20 named("r19", "r20") aliases(r19, r20) long;
r17r18 named("r17", "r18") aliases(r17, r18) bytes8! long!; r17r18 named("r17", "r18") aliases(r17, r18) long;
r15r16 named("r15", "r16") aliases(r15, r16) bytes8! long!; r15r16 named("r15", "r16") aliases(r15, r16) long;
r13r14 named("r13", "r14") aliases(r13, r14) bytes8! long!; r13r14 named("r13", "r14") aliases(r13, r14) long;
f14 bytes4! float! volatile; f14 float volatile;
f13 bytes4! float! volatile; f13 float volatile;
f12 bytes4! float! volatile; f12 float volatile;
f11 bytes4! float! volatile; f11 float volatile;
f10 bytes4! float! volatile; f10 float volatile;
f9 bytes4! float! volatile; f9 float volatile;
f8 bytes4! float! volatile; f8 float volatile;
f7 bytes4! float! volatile; f7 float volatile;
f6 bytes4! float! volatile; f6 float volatile;
f5 bytes4! float! volatile; f5 float volatile;
f4 bytes4! float! volatile; f4 float volatile;
f3 bytes4! float! volatile fret; f3 float volatile fret;
f2 bytes4! float! volatile; f2 float volatile;
f1 bytes4! float! volatile; f1 float volatile;
f0 bytes4! float! volatile; f0 float volatile;
f31 bytes4! float!; f31 float;
f30 bytes4! float!; f30 float;
f29 bytes4! float!; f29 float;
f28 bytes4! float!; f28 float;
f27 bytes4! float!; f27 float;
f26 bytes4! float!; f26 float;
f25 bytes4! float!; f25 float;
f24 bytes4! float!; f24 float;
f23 bytes4! float!; f23 float;
f22 bytes4! float!; f22 float;
f21 bytes4! float!; f21 float;
f20 bytes4! float!; f20 float;
f19 bytes4! float!; f19 float;
f18 bytes4! float!; f18 float;
f17 bytes4! float!; f17 float;
f16 bytes4! float!; f16 float;
f15 bytes4! float!; f15 float;
d14 named("f14") aliases(f14) bytes8! double! volatile; d14 named("f14") aliases(f14) double volatile;
d13 named("f13") aliases(f13) bytes8! double! volatile; d13 named("f13") aliases(f13) double volatile;
d12 named("f12") aliases(f12) bytes8! double! volatile; d12 named("f12") aliases(f12) double volatile;
d11 named("f11") aliases(f11) bytes8! double! volatile; d11 named("f11") aliases(f11) double volatile;
d10 named("f10") aliases(f10) bytes8! double! volatile; d10 named("f10") aliases(f10) double volatile;
d9 named("f9") aliases(f9) bytes8! double! volatile; d9 named("f9") aliases(f9) double volatile;
d8 named("f8") aliases(f8) bytes8! double! volatile; d8 named("f8") aliases(f8) double volatile;
d7 named("f7") aliases(f7) bytes8! double! volatile; d7 named("f7") aliases(f7) double volatile;
d6 named("f6") aliases(f6) bytes8! double! volatile; d6 named("f6") aliases(f6) double volatile;
d5 named("f5") aliases(f5) bytes8! double! volatile; d5 named("f5") aliases(f5) double volatile;
d4 named("f4") aliases(f4) bytes8! double! volatile; d4 named("f4") aliases(f4) double volatile;
d3 named("f3") aliases(f3) bytes8! double! volatile dret; d3 named("f3") aliases(f3) double volatile dret;
d2 named("f2") aliases(f2) bytes8! double! volatile; d2 named("f2") aliases(f2) double volatile;
d1 named("f1") aliases(f1) bytes8! double! volatile; d1 named("f1") aliases(f1) double volatile;
d0 named("f0") aliases(f0) bytes8! double! volatile; d0 named("f0") aliases(f0) double volatile;
d31 named("f31") aliases(f31) bytes8! double!; d31 named("f31") aliases(f31) double;
d30 named("f30") aliases(f30) bytes8! double!; d30 named("f30") aliases(f30) double;
d29 named("f29") aliases(f29) bytes8! double!; d29 named("f29") aliases(f29) double;
d28 named("f28") aliases(f28) bytes8! double!; d28 named("f28") aliases(f28) double;
d27 named("f27") aliases(f27) bytes8! double!; d27 named("f27") aliases(f27) double;
d26 named("f26") aliases(f26) bytes8! double!; d26 named("f26") aliases(f26) double;
d25 named("f25") aliases(f25) bytes8! double!; d25 named("f25") aliases(f25) double;
d24 named("f24") aliases(f24) bytes8! double!; d24 named("f24") aliases(f24) double;
d23 named("f23") aliases(f23) bytes8! double!; d23 named("f23") aliases(f23) double;
d22 named("f22") aliases(f22) bytes8! double!; d22 named("f22") aliases(f22) double;
d21 named("f21") aliases(f21) bytes8! double!; d21 named("f21") aliases(f21) double;
d20 named("f20") aliases(f20) bytes8! double!; d20 named("f20") aliases(f20) double;
d19 named("f19") aliases(f19) bytes8! double!; d19 named("f19") aliases(f19) double;
d18 named("f18") aliases(f18) bytes8! double!; d18 named("f18") aliases(f18) double;
d17 named("f17") aliases(f17) bytes8! double!; d17 named("f17") aliases(f17) double;
d16 named("f16") aliases(f16) bytes8! double!; d16 named("f16") aliases(f16) double;
d15 named("f15") aliases(f15) bytes8! double!; d15 named("f15") aliases(f15) double;
cr0 cr!; cr0 cr;
@ -177,7 +180,7 @@ PATTERNS
emit "addi sp, sp, 4" emit "addi sp, sp, 4"
cost 8; cost 8;
out:(long)reg = POP.D out:(double)reg = POP.D
emit "lfd %out, 0(sp)" emit "lfd %out, 0(sp)"
emit "addi sp, sp, 8" emit "addi sp, sp, 8"
cost 8; cost 8;
@ -186,7 +189,7 @@ PATTERNS
emit "! setret4" emit "! setret4"
cost 1; cost 1;
SETRET.L(in:(pret)reg) SETRET.L(in:(lret)reg)
emit "! setret8" emit "! setret8"
cost 1; cost 1;
@ -250,7 +253,7 @@ PATTERNS
/* Stores */ /* Stores */
STORE.D(addr:address, value:(double)reg) STORE.D(addr:address, value:(double)reg)
emit "sfd %value, %addr" emit "stfd %value, %addr"
cost 4; cost 4;
STORE.L(addr:address, value:(long)reg) STORE.L(addr:address, value:(long)reg)
@ -293,10 +296,6 @@ PATTERNS
emit "lwz %out.1, 0+%addr" emit "lwz %out.1, 0+%addr"
cost 8; cost 8;
out:(double)reg = LOAD.D(addr:address)
emit "lfsd %out, %addr"
cost 4;
out:(int)ushort0 = LOADH.I(addr:address) out:(int)ushort0 = LOADH.I(addr:address)
emit "lhz %out, %addr" emit "lhz %out, %addr"
cost 4; cost 4;
@ -373,17 +372,17 @@ PATTERNS
emit "srawi %out.1, %out.0, 31" emit "srawi %out.1, %out.0, 31"
cost 8; cost 8;
out:(int)reg = FROMD.I(in:(double)reg) out:(ret)reg = FROMD.I(in:(dret)reg)
with corrupted(volatile) with corrupted(volatile)
emit "bl .fromd2i" emit "bl .fromd2i"
cost 4; cost 4;
out:(long)reg = FROMF.L(in:(double)reg) out:(lret)reg = FROMF.L(in:(fret)reg)
with corrupted(volatile) with corrupted(volatile)
emit "bl .fromf2l" emit "bl .fromf2l"
cost 4; cost 4;
out:(long)reg = FROMSI.D(in:(double)reg) out:(dret)reg = FROMSI.D(in:(ret)reg)
with corrupted(volatile) with corrupted(volatile)
emit "bl .fromsi2d" emit "bl .fromsi2d"
cost 4; cost 4;
@ -491,7 +490,7 @@ PATTERNS
emit "bl $dest" emit "bl $dest"
cost 4; cost 4;
out:(pret)reg = CALL.L(dest:LABEL.I) out:(lret)reg = CALL.L(dest:LABEL.I)
with corrupted(volatile) with corrupted(volatile)
emit "bl $dest" emit "bl $dest"
cost 4; cost 4;
@ -508,7 +507,7 @@ PATTERNS
emit "bcctrl 20, 0, 0" emit "bcctrl 20, 0, 0"
cost 8; cost 8;
out:(pret)reg = CALL.L(dest:(int)reg) out:(lret)reg = CALL.L(dest:(int)reg)
with corrupted(volatile) with corrupted(volatile)
emit "mtspr ctr, %dest" emit "mtspr ctr, %dest"
emit "bcctrl 20, 0, 0" emit "bcctrl 20, 0, 0"

View file

@ -94,9 +94,9 @@ static void constrain_input_reg(int child, uint32_t attr)
struct vreg* vreg = find_vreg_of_child(child); struct vreg* vreg = find_vreg_of_child(child);
struct constraint* c; struct constraint* c;
if (vreg) assert(vreg);
array_appendu(&current_hop->ins, vreg);
array_appendu(&current_hop->ins, vreg);
get_constraint(vreg)->attrs = attr; get_constraint(vreg)->attrs = attr;
} }
@ -112,7 +112,15 @@ static uint32_t find_type_from_constraint(uint32_t attr)
while (brd->id) while (brd->id)
{ {
if (brd->attrs & attr) if (brd->attrs & attr)
return brd->type; {
const uint32_t type_attrs =
(burm_int_ATTR | burm_float_ATTR |
burm_long_ATTR | burm_double_ATTR);
if (brd->attrs & type_attrs)
return brd->attrs & type_attrs;
return attr;
}
brd++; brd++;
} }

View file

@ -36,6 +36,7 @@ static void recursively_associate_group(struct phicongruence* c, struct vreg* vr
struct constraint* constraint = pmap_findleft(&vreg->defined->constraints, vreg); struct constraint* constraint = pmap_findleft(&vreg->defined->constraints, vreg);
if (c->type == 0) if (c->type == 0)
c->type = vreg->type; c->type = vreg->type;
assert(c->type == vreg->type); assert(c->type == vreg->type);
array_appendu(&c->definitions, vreg->defined); array_appendu(&c->definitions, vreg->defined);
@ -62,6 +63,21 @@ static void recursively_associate_group(struct phicongruence* c, struct vreg* vr
} }
} }
static void update_vreg_types(struct phicongruence* c)
{
int i;
for (i=0; i<c->vregs.count; i++)
{
struct vreg* vreg = c->vregs.item[i];
if (vreg->type == 0)
vreg->type = c->type;
assert(vreg->type == c->type);
assert(vreg->type != 0);
}
}
static void associate_groups(void) static void associate_groups(void)
{ {
static int number = 0; static int number = 0;
@ -71,6 +87,7 @@ static void associate_groups(void)
struct phicongruence* c = calloc(1, sizeof(*c)); struct phicongruence* c = calloc(1, sizeof(*c));
c->id = number++; c->id = number++;
recursively_associate_group(c, phimap.item[0].left); recursively_associate_group(c, phimap.item[0].left);
update_vreg_types(c);
} }
} }

View file

@ -84,7 +84,7 @@ static struct hreg* allocate_phi_hreg(register_assignment_t* regs,
for (i=0; i<hregs.count; i++) for (i=0; i<hregs.count; i++)
{ {
struct hreg* hreg = hregs.item[i]; struct hreg* hreg = hregs.item[i];
if (!register_used(regs, hreg) && (hreg->type == type)) if (!register_used(regs, hreg) && (hreg->attrs & type))
{ {
/* This one is unused. Use it. */ /* This one is unused. Use it. */
return hreg; return hreg;
@ -95,11 +95,6 @@ static struct hreg* allocate_phi_hreg(register_assignment_t* regs,
assert(false); assert(false);
} }
static bool evictable(struct hreg* hreg, struct vreg* vreg)
{
return type_match(hreg, vreg) && !array_contains(&current_hop->ins, vreg);
}
static struct hreg* evict(struct vreg* vreg) static struct hreg* evict(struct vreg* vreg)
{ {
int i; int i;
@ -114,7 +109,7 @@ static struct hreg* evict(struct vreg* vreg)
struct vreg* candidatein = pmap_findleft(current_ins, hreg); struct vreg* candidatein = pmap_findleft(current_ins, hreg);
struct vreg* candidateout = pmap_findleft(current_outs, hreg); struct vreg* candidateout = pmap_findleft(current_outs, hreg);
if (evictable(hreg, vreg)) if (hreg->attrs & vreg->type)
{ {
if (!candidatein && if (!candidatein &&
!candidateout && !candidateout &&
@ -141,41 +136,47 @@ static struct hreg* evict(struct vreg* vreg)
assert(false); assert(false);
} }
static bool type_match(struct hreg* hreg, struct vreg* vreg) static bool constraints_match(struct hreg* hreg, struct vreg* vreg)
{ {
struct constraint* c = pmap_findleft(&current_hop->constraints, vreg); struct constraint* c = pmap_findleft(&current_hop->constraints, vreg);
if (c) if (c)
return (hreg->attrs & c->attrs); return (hreg->attrs & c->attrs);
if (vreg->congruence) return true;
return (hreg->type == vreg->congruence->type);
return (hreg->type == vreg->type);
} }
static bool allocatable_stackable_input(struct hreg* hreg, struct vreg* vreg) static bool allocatable_stackable_input(struct hreg* hreg, struct vreg* vreg)
{ {
return !register_used(current_ins, hreg) && return !register_used(current_ins, hreg) &&
type_match(hreg, vreg); (hreg->attrs & vreg->type);
} }
static bool allocatable_stackable_output(struct hreg* hreg, struct vreg* vreg) static bool allocatable_stackable_output(struct hreg* hreg, struct vreg* vreg)
{ {
return !register_used(current_outs, hreg) && return !register_used(current_outs, hreg) &&
type_match(hreg, vreg) && (hreg->attrs & vreg->type) &&
!(hreg->attrs & current_hop->insndata->corrupts); !(hreg->attrs & current_hop->insndata->corrupts);
} }
static bool allocatable_input(struct hreg* hreg, struct vreg* vreg) static bool allocatable_input(struct hreg* hreg, struct vreg* vreg)
{ {
return allocatable_stackable_input(hreg, vreg) && return allocatable_stackable_input(hreg, vreg) &&
constraints_match(hreg, vreg) &&
!hreg->is_stacked; !hreg->is_stacked;
} }
static bool allocatable_output(struct hreg* hreg, struct vreg* vreg) static bool allocatable_output(struct hreg* hreg, struct vreg* vreg)
{ {
return allocatable_stackable_output(hreg, vreg) && return allocatable_stackable_output(hreg, vreg) &&
constraints_match(hreg, vreg) &&
!hreg->is_stacked; !hreg->is_stacked;
} }
static bool allocatable_through(struct hreg* hreg, struct vreg* vreg)
{
return allocatable_stackable_input(hreg, vreg) &&
allocatable_stackable_output(hreg, vreg);
}
static struct hreg* find_input_reg(struct vreg* vreg) static struct hreg* find_input_reg(struct vreg* vreg)
{ {
int i; int i;
@ -218,8 +219,7 @@ static struct hreg* find_through_reg(struct vreg* vreg)
for (i=0; i<hregs.count; i++) for (i=0; i<hregs.count; i++)
{ {
hreg = hregs.item[i]; hreg = hregs.item[i];
if (allocatable_input(hreg, vreg) && if (allocatable_through(hreg, vreg))
allocatable_output(hreg, vreg))
{ {
return hreg; return hreg;
} }
@ -349,13 +349,13 @@ static void add_through_register(struct vreg* vreg, struct hreg* hreg)
if (hreg) if (hreg)
{ {
bool infree = allocatable_stackable_input(hreg, vreg); bool unusedin = allocatable_stackable_input(hreg, vreg);
bool outfree = allocatable_stackable_output(hreg, vreg); bool unusedout = allocatable_stackable_output(hreg, vreg);
struct vreg* inuse = pmap_findleft(current_ins, hreg); struct vreg* inuse = pmap_findleft(current_ins, hreg);
struct vreg* outuse = pmap_findleft(current_outs, hreg); struct vreg* outuse = pmap_findleft(current_outs, hreg);
if ((infree || (inuse == vreg)) && if ((unusedin || (inuse == vreg)) &&
(outfree || (outuse == vreg))) (unusedout || (outuse == vreg)))
{ {
/* Input and output are either free or already assigned to this /* Input and output are either free or already assigned to this
* vreg. */ * vreg. */
@ -380,7 +380,7 @@ static void add_through_register(struct vreg* vreg, struct hreg* hreg)
static void find_new_home_for_evicted_register(struct vreg* vreg, struct hreg* src) static void find_new_home_for_evicted_register(struct vreg* vreg, struct hreg* src)
{ {
uint32_t srctype = src->type; uint32_t srctype = vreg->type;
struct hreg* hreg; struct hreg* hreg;
int i; int i;
@ -391,9 +391,8 @@ static void find_new_home_for_evicted_register(struct vreg* vreg, struct hreg* s
for (i=0; i<hregs.count; i++) for (i=0; i<hregs.count; i++)
{ {
hreg = hregs.item[i]; hreg = hregs.item[i];
if ((hreg->type == src->type) && if ((hreg->attrs & srctype) &&
allocatable_stackable_input(hreg, vreg) && allocatable_through(hreg, vreg))
allocatable_stackable_output(hreg, vreg))
{ {
goto found; goto found;
} }
@ -401,7 +400,7 @@ static void find_new_home_for_evicted_register(struct vreg* vreg, struct hreg* s
/* No more registers --- allocate a stack slot. */ /* No more registers --- allocate a stack slot. */
hreg = new_stacked_hreg(src->type); hreg = new_stacked_hreg(srctype);
array_append(&hregs, hreg); array_append(&hregs, hreg);
found: found:
@ -725,7 +724,7 @@ static int pack_stackframe(int stacksize, int size, uint32_t attr)
for (i=0; i<hregs.count; i++) for (i=0; i<hregs.count; i++)
{ {
struct hreg* hreg = hregs.item[i]; struct hreg* hreg = hregs.item[i];
if (hreg->is_stacked && (hreg->type & attr)) if (hreg->is_stacked && (hreg->attrs & attr))
{ {
hreg->offset = stacksize; hreg->offset = stacksize;
stacksize += size; stacksize += size;
@ -738,10 +737,10 @@ static int pack_stackframe(int stacksize, int size, uint32_t attr)
static void layout_stack_frame(void) static void layout_stack_frame(void)
{ {
int stacksize = 0; int stacksize = 0;
stacksize = pack_stackframe(stacksize, 8, burm_bytes8_ATTR); stacksize = pack_stackframe(stacksize, EM_wordsize*2, burm_double_ATTR);
stacksize = pack_stackframe(stacksize, 4, burm_bytes4_ATTR); stacksize = pack_stackframe(stacksize, EM_wordsize*2, burm_long_ATTR);
stacksize = pack_stackframe(stacksize, 2, burm_bytes2_ATTR); stacksize = pack_stackframe(stacksize, EM_wordsize*1, burm_float_ATTR);
stacksize = pack_stackframe(stacksize, 1, burm_bytes1_ATTR); stacksize = pack_stackframe(stacksize, EM_wordsize*1, burm_int_ATTR);
current_proc->spills_size = stacksize; current_proc->spills_size = stacksize;
} }

View file

@ -14,20 +14,18 @@ struct hreg* new_hreg(const struct burm_register_data* brd)
struct hreg* hreg = calloc(1, sizeof *hreg); struct hreg* hreg = calloc(1, sizeof *hreg);
hreg->id = brd->id; hreg->id = brd->id;
hreg->brd = brd; hreg->brd = brd;
hreg->type = brd->type;
hreg->attrs = brd->attrs; hreg->attrs = brd->attrs;
hreg->is_stacked = false; hreg->is_stacked = false;
/* The aliases array needs to be initialised later. */ /* The aliases array needs to be initialised later. */
return hreg; return hreg;
} }
struct hreg* new_stacked_hreg(uint32_t type) struct hreg* new_stacked_hreg(uint32_t attrs)
{ {
static int hreg_count = 1; static int hreg_count = 1;
struct hreg* hreg = calloc(1, sizeof *hreg); struct hreg* hreg = calloc(1, sizeof *hreg);
hreg->id = aprintf("stacked_%d_id_%d", type, hreg_count++); hreg->id = aprintf("stacked_%d_id_%d", attrs, hreg_count++);
hreg->type = type; hreg->attrs = attrs;
hreg->attrs = type;
hreg->is_stacked = true; hreg->is_stacked = true;
hreg->offset = -1; hreg->offset = -1;
array_append(&hreg->aliases, hreg); array_append(&hreg->aliases, hreg);

View file

@ -15,7 +15,6 @@ struct hreg
{ {
const char* id; const char* id;
const struct burm_register_data* brd; const struct burm_register_data* brd;
uint32_t type;
uint32_t attrs; uint32_t attrs;
bool is_stacked; bool is_stacked;
int offset; int offset;

View file

@ -80,8 +80,7 @@ register
: ID { $$ = makereg($1); } : ID { $$ = makereg($1); }
| register NAMED '(' names ')' { $$ = $1; setregnames($$, $4); } | register NAMED '(' names ')' { $$ = $1; setregnames($$, $4); }
| register ALIASES '(' aliases ')' { $$ = $1; addregaliases($$, $4); } | register ALIASES '(' aliases ')' { $$ = $1; addregaliases($$, $4); }
| register ID { $$ = $1; addregattr($1, $2, false); } | register ID { $$ = $1; addregattr($1, $2); }
| register ID '!' { $$ = $1; addregattr($1, $2, true); }
; ;
names names

View file

@ -141,10 +141,6 @@ int main(int argc, char* argv[])
registerterminals(); registerterminals();
start = nonterm("stmt", true); start = nonterm("stmt", true);
makeregattr("bytes1");
makeregattr("bytes2");
makeregattr("bytes4");
makeregattr("bytes8");
/* Define some standard terms. */ /* Define some standard terms. */
@ -309,7 +305,7 @@ struct regattr* makeregattr(const char* id)
return p; return p;
} }
void addregattr(struct reg* reg, const char* id, bool exact) void addregattr(struct reg* reg, const char* id)
{ {
struct regattr* p = smap_get(&registerattrs, id); struct regattr* p = smap_get(&registerattrs, id);
@ -317,8 +313,6 @@ void addregattr(struct reg* reg, const char* id, bool exact)
p = makeregattr(id); p = makeregattr(id);
reg->attrs |= 1<<(p->number); reg->attrs |= 1<<(p->number);
if (exact)
reg->type |= 1<<(p->number);
} }
void addregalias(struct reg* r1, struct reg* r2) void addregalias(struct reg* r1, struct reg* r2)
@ -663,8 +657,8 @@ static void emitregisters(void)
struct reg* r = registers.item[i].right; struct reg* r = registers.item[i].right;
assert(r->number == i); assert(r->number == i);
print("%1{ \"%s\", 0x%x, 0x%x, %Pregister_names_%d_%s, %Pregister_aliases_%d_%s },\n", print("%1{ \"%s\", 0x%x, %Pregister_names_%d_%s, %Pregister_aliases_%d_%s },\n",
r->name, r->type, r->attrs, i, r->name, i, r->name); r->name, r->attrs, i, r->name, i, r->name);
} }
print("%1{ NULL }\n"); print("%1{ NULL }\n");
print("};\n\n"); print("};\n\n");

View file

@ -61,7 +61,6 @@ struct reg
const char* name; /* friendly register name */ const char* name; /* friendly register name */
int number; /* identifying number */ int number; /* identifying number */
uint32_t attrs; /* bitfield of register attributes */ uint32_t attrs; /* bitfield of register attributes */
uint32_t type; /* register type */
struct stringlist* names; /* register names */ struct stringlist* names; /* register names */
ARRAYOF(struct reg) aliases; /* registers that this one aliases */ ARRAYOF(struct reg) aliases; /* registers that this one aliases */
}; };
@ -74,7 +73,7 @@ struct regattr
extern struct reg* makereg(const char* name); extern struct reg* makereg(const char* name);
extern void setregnames(struct reg* reg, struct stringlist* names); extern void setregnames(struct reg* reg, struct stringlist* names);
extern void addregattr(struct reg* reg, const char* regattr, bool exact); extern void addregattr(struct reg* reg, const char* regattr);
extern void addregaliases(struct reg* reg, struct stringlist* aliases); extern void addregaliases(struct reg* reg, struct stringlist* aliases);
extern struct regattr* getregattr(const char* name); extern struct regattr* getregattr(const char* name);

View file

@ -17,6 +17,9 @@ struct ir_data
extern const struct ir_data ir_data[]; extern const struct ir_data ir_data[];
#define TYPE_ATTRS \
(burm_int_ATTR | burm_long_ATTR | burm_float_ATTR | burm_double_ATTR)
#include "ircodes-dyn.h" #include "ircodes-dyn.h"
#endif #endif

View file

@ -64,7 +64,6 @@ extern const struct burm_instruction_data burm_instruction_data[];
struct burm_register_data struct burm_register_data
{ {
const char* id; const char* id;
uint32_t type;
uint32_t attrs; uint32_t attrs;
const char** names; const char** names;
const struct burm_register_data** aliases; const struct burm_register_data** aliases;
@ -73,14 +72,6 @@ struct burm_register_data
extern const struct burm_register_data burm_register_data[]; extern const struct burm_register_data burm_register_data[];
extern const char* burm_register_class_names[]; extern const char* burm_register_class_names[];
enum
{
REGATTR_BYTES1 = 0,
REGATTR_BYTES2,
REGATTR_BYTES4,
REGATTR_BYTES8
};
enum enum
{ {
NONTERM_STMT = 1 NONTERM_STMT = 1