From bbd1ee5540863392fab30f8a4cea9e95ce55f921 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 15 May 2008 14:00:57 -0600 Subject: [PATCH] various register marshalling bugfixes --- src/compiler.cpp | 88 ++++++++++++++++++++++++++++++++++++++---------- src/x86.cpp | 1 + test/Misc.java | 27 +++++++++++++++ 3 files changed, 99 insertions(+), 17 deletions(-) diff --git a/src/compiler.cpp b/src/compiler.cpp index dc0043327f..8c0fcbb6f5 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -54,6 +54,8 @@ class Site { virtual void thaw(Context*) { } + virtual void validate(Context*, Stack*, unsigned, Value*) { } + virtual OperandType type(Context*) = 0; virtual Assembler::Operand* asAssemblerOperand(Context*) = 0; @@ -101,12 +103,13 @@ class LogicalInstruction { class Register { public: Register(int number): - value(0), site(0), number(number), size(0), refCount(0), freezeCount(0), - reserved(false), pushed(false) + value(0), site(0), mask(0), number(number), size(0), refCount(0), + freezeCount(0), reserved(false), pushed(false) { } Value* value; Site* site; + uint32_t mask; int number; unsigned size; unsigned refCount; @@ -384,7 +387,7 @@ removeMemorySites(Context* c, Value* v) { for (Site** p = &(v->sites); *p;) { 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 = (*p)->next; break; @@ -504,6 +507,10 @@ acquire(Context* c, uint32_t mask, Stack* stack, unsigned newSize, void 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 { public: 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*) { return RegisterOperand; } @@ -816,8 +832,8 @@ class VirtualSite: public AbstractSite { VirtualSite* virtualSite(Context* c, Value* v = 0, - uint8_t typeMask = ~static_cast(0), - uint64_t registerMask = ~static_cast(0)) + uint8_t typeMask = ~static_cast(0), + uint64_t registerMask = ~static_cast(0)) { return new (c->zone->allocate(sizeof(VirtualSite))) VirtualSite(v, typeMask, registerMask); @@ -996,7 +1012,6 @@ pickRegister(Context* c, uint32_t mask) if ((1 << i) & mask) { Register* r = c->registers[i]; if ((static_cast(1) << i) == mask) { - assert(c, r->freezeCount == 0); return r; } @@ -1032,10 +1047,14 @@ swap(Context* c, Register* a, Register* b) Register* replace(Context* c, Stack* stack, Register* r) { + uint32_t mask = (r->freezeCount? r->mask : ~0); + 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); + swap(c, r, s); + return s; } @@ -1066,6 +1085,7 @@ acquire(Context* c, uint32_t mask, Stack* stack, unsigned newSize, } } + r->mask = mask; r->size = newSize; r->value = newValue; r->site = newSite; @@ -1080,11 +1100,31 @@ release(Context*, Register* r) fprintf(stderr, "release %d\n", r->number); } + r->mask = 0; r->size = 0; r->value = 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 apply(Context* c, UnaryOperation op, unsigned size, Site* a) { @@ -1206,17 +1246,15 @@ class CallEvent: public Event { resultSize(resultSize), argumentFootprint(0) { - for (Stack* s = stack; s; s = s->next) { - addRead(c, s->value, s->size * BytesPerWord, 0); - } - + uint32_t mask = ~0; Stack* s = argumentStack; unsigned index = 0; for (unsigned i = 0; i < argumentCount; ++i) { Site* target; if (index < c->assembler->argumentRegisterCount()) { - target = registerSite - (c, c->assembler->argumentRegister(index)); + int r = c->assembler->argumentRegister(index); + target = registerSite(c, r); + mask &= ~(1 << r); } else { target = 0; s->pushEvent->active = true; @@ -1227,9 +1265,20 @@ class CallEvent: public Event { s = s->next; } - addRead(c, address, BytesPerWord, - ((flags & Compiler::Indirect) ? - registerSite(c, c->assembler->returnLow()) : 0)); + if (flags & Compiler::Indirect) { + int r = c->assembler->returnLow(); + addRead(c, address, BytesPerWord, registerSite(c, r)); + mask &= ~(1 << r); + } else { + addRead(c, address, BytesPerWord, virtualSite + (c, 0, ~0, (static_cast(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(mask) << 32) | mask)); + } } 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) { assert(c, v->sites == s); 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); apply(c, Move, size, s, r); } @@ -1890,6 +1939,10 @@ appendPop(Context* c, unsigned count, bool ignore) Site* readSource(Context* c, Stack* stack, Read* r) { + if (r->value->sites == 0) { + return 0; + } + Site* target = (r->target ? r->target->readTarget(c, r) : 0); unsigned copyCost; @@ -1900,6 +1953,7 @@ readSource(Context* c, Stack* stack, Read* r) apply(c, Move, r->size, site, target); return target; } else { + site->validate(c, stack, r->size, r->value); return site; } } diff --git a/src/x86.cpp b/src/x86.cpp index 6ecd286005..882fcdd864 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -1950,6 +1950,7 @@ class MyAssembler: public Assembler { case ShiftLeft: case ShiftRight: case UnsignedShiftRight: { + *aTypeMask = (1 << RegisterOperand); *aRegisterMask = static_cast(1) << rcx; const uint32_t mask = ~(1 << rcx); *bRegisterMask = (static_cast(mask) << 32) | mask; diff --git a/test/Misc.java b/test/Misc.java index 259a87b5b4..89605d4400 100644 --- a/test/Misc.java +++ b/test/Misc.java @@ -75,6 +75,23 @@ public class Misc { } 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 b = 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 == 5); + expect(~a == ~-5); a = 5; 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 == -5); + expect(~a == ~5); } byte2 = 0;