various register marshalling bugfixes

This commit is contained in:
Joel Dice 2008-05-15 14:00:57 -06:00
parent 2ed6247cec
commit bbd1ee5540
3 changed files with 99 additions and 17 deletions

View File

@ -54,6 +54,8 @@ class Site {
virtual void thaw(Context*) { } virtual void thaw(Context*) { }
virtual void validate(Context*, Stack*, unsigned, Value*) { }
virtual OperandType type(Context*) = 0; virtual OperandType type(Context*) = 0;
virtual Assembler::Operand* asAssemblerOperand(Context*) = 0; virtual Assembler::Operand* asAssemblerOperand(Context*) = 0;
@ -101,12 +103,13 @@ class LogicalInstruction {
class Register { class Register {
public: public:
Register(int number): Register(int number):
value(0), site(0), number(number), size(0), refCount(0), freezeCount(0), value(0), site(0), mask(0), number(number), size(0), refCount(0),
reserved(false), pushed(false) freezeCount(0), reserved(false), pushed(false)
{ } { }
Value* value; Value* value;
Site* site; Site* site;
uint32_t mask;
int number; int number;
unsigned size; unsigned size;
unsigned refCount; unsigned refCount;
@ -384,7 +387,7 @@ removeMemorySites(Context* c, Value* v)
{ {
for (Site** p = &(v->sites); *p;) { for (Site** p = &(v->sites); *p;) {
if ((*p)->type(c) == MemoryOperand) { if ((*p)->type(c) == MemoryOperand) {
// fprintf(stderr, "remove site %p (%d) from %p\n", s, s->type(c), v); // fprintf(stderr, "remove site %p (%d) from %p\n", *p, (*p)->type(c), v);
(*p)->release(c); (*p)->release(c);
*p = (*p)->next; *p = (*p)->next;
break; break;
@ -504,6 +507,10 @@ acquire(Context* c, uint32_t mask, Stack* stack, unsigned newSize,
void void
release(Context* c, Register* r); release(Context* c, Register* r);
Register*
validate(Context* c, uint32_t mask, Stack* stack, unsigned size,
Value* value, Site* site, Register* current);
class RegisterSite: public Site { class RegisterSite: public Site {
public: public:
RegisterSite(uint64_t mask, Register* low = 0, Register* high = 0): RegisterSite(uint64_t mask, Register* low = 0, Register* high = 0):
@ -578,6 +585,15 @@ class RegisterSite: public Site {
} }
} }
virtual void validate(Context* c, Stack* stack, unsigned size, Value* v) {
low = ::validate(c, mask, stack, size, v, this, low);
if (size > BytesPerWord) {
::freeze(low);
high = ::validate(c, mask >> 32, stack, size, v, this, high);
::thaw(low);
}
}
virtual OperandType type(Context*) { virtual OperandType type(Context*) {
return RegisterOperand; return RegisterOperand;
} }
@ -996,7 +1012,6 @@ pickRegister(Context* c, uint32_t mask)
if ((1 << i) & mask) { if ((1 << i) & mask) {
Register* r = c->registers[i]; Register* r = c->registers[i];
if ((static_cast<uint32_t>(1) << i) == mask) { if ((static_cast<uint32_t>(1) << i) == mask) {
assert(c, r->freezeCount == 0);
return r; return r;
} }
@ -1032,10 +1047,14 @@ swap(Context* c, Register* a, Register* b)
Register* Register*
replace(Context* c, Stack* stack, Register* r) replace(Context* c, Stack* stack, Register* r)
{ {
uint32_t mask = (r->freezeCount? r->mask : ~0);
freeze(r); freeze(r);
Register* s = acquire(c, ~0, stack, r->size, r->value, r->site); Register* s = acquire(c, mask, stack, r->size, r->value, r->site);
thaw(r); thaw(r);
swap(c, r, s); swap(c, r, s);
return s; return s;
} }
@ -1066,6 +1085,7 @@ acquire(Context* c, uint32_t mask, Stack* stack, unsigned newSize,
} }
} }
r->mask = mask;
r->size = newSize; r->size = newSize;
r->value = newValue; r->value = newValue;
r->site = newSite; r->site = newSite;
@ -1080,11 +1100,31 @@ release(Context*, Register* r)
fprintf(stderr, "release %d\n", r->number); fprintf(stderr, "release %d\n", r->number);
} }
r->mask = 0;
r->size = 0; r->size = 0;
r->value = 0; r->value = 0;
r->site = 0; r->site = 0;
} }
Register*
validate(Context* c, uint32_t mask, Stack* stack, unsigned size,
Value* value, Site* site, Register* current)
{
if ((mask & (1 << current->number)) == 0) {
Register* r = acquire(c, mask, stack, size, value, site);
release(c, current);
Assembler::Register rr(r->number);
Assembler::Register cr(current->number);
c->assembler->apply
(Move, BytesPerWord, RegisterOperand, &cr, RegisterOperand, &rr);
return r;
} else {
return current;
}
}
void void
apply(Context* c, UnaryOperation op, unsigned size, Site* a) apply(Context* c, UnaryOperation op, unsigned size, Site* a)
{ {
@ -1206,17 +1246,15 @@ class CallEvent: public Event {
resultSize(resultSize), resultSize(resultSize),
argumentFootprint(0) argumentFootprint(0)
{ {
for (Stack* s = stack; s; s = s->next) { uint32_t mask = ~0;
addRead(c, s->value, s->size * BytesPerWord, 0);
}
Stack* s = argumentStack; Stack* s = argumentStack;
unsigned index = 0; unsigned index = 0;
for (unsigned i = 0; i < argumentCount; ++i) { for (unsigned i = 0; i < argumentCount; ++i) {
Site* target; Site* target;
if (index < c->assembler->argumentRegisterCount()) { if (index < c->assembler->argumentRegisterCount()) {
target = registerSite int r = c->assembler->argumentRegister(index);
(c, c->assembler->argumentRegister(index)); target = registerSite(c, r);
mask &= ~(1 << r);
} else { } else {
target = 0; target = 0;
s->pushEvent->active = true; s->pushEvent->active = true;
@ -1227,9 +1265,20 @@ class CallEvent: public Event {
s = s->next; s = s->next;
} }
addRead(c, address, BytesPerWord, if (flags & Compiler::Indirect) {
((flags & Compiler::Indirect) ? int r = c->assembler->returnLow();
registerSite(c, c->assembler->returnLow()) : 0)); addRead(c, address, BytesPerWord, registerSite(c, r));
mask &= ~(1 << r);
} else {
addRead(c, address, BytesPerWord, virtualSite
(c, 0, ~0, (static_cast<uint64_t>(mask) << 32) | mask));
}
for (Stack* s = stack; s; s = s->next) {
s->pushEvent->active = true;
addRead(c, s->value, s->size * BytesPerWord, virtualSite
(c, 0, ~0, (static_cast<uint64_t>(mask) << 32) | mask));
}
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
@ -1462,7 +1511,7 @@ maybePreserve(Context* c, Stack* stack, unsigned size, Value* v, Site* s)
if (v->reads->next and v->sites->next == 0) { if (v->reads->next and v->sites->next == 0) {
assert(c, v->sites == s); assert(c, v->sites == s);
Site* r = targetOrNull(c, v->reads->next); Site* r = targetOrNull(c, v->reads->next);
if (r == 0) r = freeRegister(c); if (r == 0 or r == s) r = freeRegister(c);
addSite(c, stack, size, v, r); addSite(c, stack, size, v, r);
apply(c, Move, size, s, r); apply(c, Move, size, s, r);
} }
@ -1890,6 +1939,10 @@ appendPop(Context* c, unsigned count, bool ignore)
Site* Site*
readSource(Context* c, Stack* stack, Read* r) readSource(Context* c, Stack* stack, Read* r)
{ {
if (r->value->sites == 0) {
return 0;
}
Site* target = (r->target ? r->target->readTarget(c, r) : 0); Site* target = (r->target ? r->target->readTarget(c, r) : 0);
unsigned copyCost; unsigned copyCost;
@ -1900,6 +1953,7 @@ readSource(Context* c, Stack* stack, Read* r)
apply(c, Move, r->size, site, target); apply(c, Move, r->size, site, target);
return target; return target;
} else { } else {
site->validate(c, stack, r->size, r->value);
return site; return site;
} }
} }

View File

@ -1950,6 +1950,7 @@ class MyAssembler: public Assembler {
case ShiftLeft: case ShiftLeft:
case ShiftRight: case ShiftRight:
case UnsignedShiftRight: { case UnsignedShiftRight: {
*aTypeMask = (1 << RegisterOperand);
*aRegisterMask = static_cast<uint64_t>(1) << rcx; *aRegisterMask = static_cast<uint64_t>(1) << rcx;
const uint32_t mask = ~(1 << rcx); const uint32_t mask = ~(1 << rcx);
*bRegisterMask = (static_cast<uint64_t>(mask) << 32) | mask; *bRegisterMask = (static_cast<uint64_t>(mask) << 32) | mask;

View File

@ -75,6 +75,23 @@ public class Misc {
} }
public static void main(String[] args) { public static void main(String[] args) {
{ int get_buffer = 2144642881;
int bits_left = 30;
int l = 9;
int code = (((get_buffer >> (bits_left -= (l)))) & ((1<<(l))-1));
expect(code == 510);
}
{ int width = 8;
int height = 8;
int depth = 24;
int scanlinePad = 4;
int bytesPerLine = (((width * depth + 7) / 8) + (scanlinePad - 1))
/ scanlinePad * scanlinePad;
expect(bytesPerLine == 24);
}
{ int a = -5; { int a = -5;
int b = 2; int b = 2;
expect(a >> b == -5 >> 2); expect(a >> b == -5 >> 2);
@ -83,6 +100,11 @@ public class Misc {
expect(a * b == -5 * 2); expect(a * b == -5 * 2);
expect(a / b == -5 / 2); expect(a / b == -5 / 2);
expect(a % b == -5 % 2); expect(a % b == -5 % 2);
expect((a & b) == (-5 & 2));
expect((a | b) == (-5 | 2));
expect((a ^ b) == (-5 ^ 2));
expect(-a == 5);
expect(~a == ~-5);
a = 5; a = 5;
b = 2; b = 2;
@ -92,6 +114,11 @@ public class Misc {
expect(a * b == 5 * 2); expect(a * b == 5 * 2);
expect(a / b == 5 / 2); expect(a / b == 5 / 2);
expect(a % b == 5 % 2); expect(a % b == 5 % 2);
expect((a & b) == (5 & 2));
expect((a | b) == (5 | 2));
expect((a ^ b) == (5 ^ 2));
expect(-a == -5);
expect(~a == ~5);
} }
byte2 = 0; byte2 = 0;