This commit is contained in:
Joel Dice 2008-08-28 16:43:35 -06:00
parent a062d8c975
commit 767c3ce2e4
3 changed files with 270 additions and 226 deletions

View File

@ -489,7 +489,7 @@ class Context {
abort(t); abort(t);
} }
virtual intptr_t getThunk(BinaryOperation op, unsigned size) { virtual intptr_t getThunk(TernaryOperation op, unsigned size) {
switch (op) { switch (op) {
case Divide: case Divide:
if (size == 8) { if (size == 8) {

View File

@ -93,11 +93,13 @@ class Site {
class Stack: public Compiler::StackElement { class Stack: public Compiler::StackElement {
public: public:
Stack(unsigned index, Value* value, Stack* next): Stack(unsigned index, unsigned size, Value* value, Stack* next):
index(index), value(value), next(next) index(index), size(size), padding(0), value(value), next(next)
{ } { }
unsigned index; unsigned index;
unsigned size;
unsigned padding;
Value* value; Value* value;
Stack* next; Stack* next;
}; };
@ -165,13 +167,9 @@ class Junction {
class Read { class Read {
public: public:
Read(): Read():
next(0), event(0), eventNext(0) next(0), value(0), event(0), eventNext(0)
{ } { }
Read* next;
Event* event;
Read* eventNext;
virtual Site* pickSite(Context* c, Value* v) = 0; virtual Site* pickSite(Context* c, Value* v) = 0;
virtual Site* allocateSite(Context* c) = 0; virtual Site* allocateSite(Context* c) = 0;
@ -180,8 +178,23 @@ class Read {
int* frameIndex) = 0; int* frameIndex) = 0;
virtual bool valid() = 0; virtual bool valid() = 0;
Read* next;
Value* value;
Event* event;
Read* eventNext;
}; };
int
intersectFrameIndexes(int a, int b)
{
if (a == NoFrameIndex or b == NoFrameIndex) return NoFrameIndex;
if (a == AnyFrameIndex) return b;
if (b == AnyFrameIndex) return a;
if (a == b) return a;
return NoFrameIndex;
}
class Value: public Compiler::Operand { class Value: public Compiler::Operand {
public: public:
Value(Site* site, Site* target): Value(Site* site, Site* target):
@ -724,22 +737,6 @@ freeRegisterSite(Context* c, uint64_t mask = ~static_cast<uint64_t>(0))
RegisterSite(mask); RegisterSite(mask);
} }
RegisterSite*
fixedRegisterSite(Context* c, int low, int high = NoRegister)
{
uint64_t mask;
if (high == NoRegister) {
mask = (~static_cast<uint64_t>(0) << 32)
| (static_cast<uint64_t>(1) << low);
} else {
mask = (static_cast<uint64_t>(1) << (high + 32))
| (static_cast<uint64_t>(1) << low);
}
return new (c->zone->allocate(sizeof(RegisterSite)))
RegisterSite(mask);
}
Register* Register*
increment(Context* c, int i) increment(Context* c, int i)
{ {
@ -912,6 +909,77 @@ allocateSite(Context* c, uint8_t typeMask, uint64_t registerMask,
} }
} }
class SingleRead: public Read {
public:
SingleRead(unsigned size, uint8_t typeMask, uint64_t registerMask,
int frameIndex):
size(size), typeMask(typeMask), registerMask(registerMask),
frameIndex(frameIndex)
{ }
virtual Site* pickSite(Context* c, Value* value) {
return ::pickSite(c, value, typeMask, registerMask, frameIndex);
}
virtual Site* allocateSite(Context* c) {
return ::allocateSite(c, typeMask, registerMask, frameIndex);
}
virtual void intersect(uint8_t* typeMask, uint64_t* registerMask,
int* frameIndex)
{
*typeMask &= this->typeMask;
*registerMask &= this->registerMask;
*frameIndex = intersectFrameIndexes(*frameIndex, this->frameIndex);
}
virtual bool valid() {
return true;
}
unsigned size;
uint8_t typeMask;
uint64_t registerMask;
int frameIndex;
};
Read*
read(Context* c, unsigned size, uint8_t typeMask, uint64_t registerMask,
int frameIndex)
{
return new (c->zone->allocate(sizeof(SingleRead)))
SingleRead(size, typeMask, registerMask, frameIndex);
}
Read*
anyRegisterRead(Context* c, unsigned size)
{
return read(c, size, 1 << RegisterOperand, ~static_cast<uint64_t>(0),
NoFrameIndex);
}
Read*
registerOrConstantRead(Context* c, unsigned size)
{
return read(c, size, (1 << RegisterOperand) | (1 << ConstantOperand),
~static_cast<uint64_t>(0), NoFrameIndex);
}
Read*
fixedRegisterRead(Context* c, unsigned size, int low, int high = NoRegister)
{
uint64_t mask;
if (high == NoRegister) {
mask = (~static_cast<uint64_t>(0) << 32)
| (static_cast<uint64_t>(1) << low);
} else {
mask = (static_cast<uint64_t>(1) << (high + 32))
| (static_cast<uint64_t>(1) << low);
}
return read(c, size, 1 << RegisterOperand, mask, NoFrameIndex);
}
class MultiRead: public Read { class MultiRead: public Read {
public: public:
MultiRead(): MultiRead():
@ -1025,7 +1093,7 @@ trySteal(Context* c, Register* r, Stack* stack, Value** locals)
if (frameIndex >= 0) { if (frameIndex >= 0) {
saveSite = frameSite(c, frameIndex); saveSite = frameSite(c, frameIndex);
} else { } else {
saveSite = stackSite(c, s); saveSite = frameSite(c, s->index + c->localFootprint);
} }
break; break;
} }
@ -1163,7 +1231,7 @@ acquire(Context* c, uint32_t mask, Stack* stack, Value** locals,
} }
if (r->refCount) { if (r->refCount) {
r = replace(c, stack, r); r = replace(c, stack, locals, r);
} else { } else {
Value* oldValue = r->value; Value* oldValue = r->value;
if (oldValue if (oldValue
@ -1171,7 +1239,7 @@ acquire(Context* c, uint32_t mask, Stack* stack, Value** locals,
and findSite(c, oldValue, r->site)) and findSite(c, oldValue, r->site))
{ {
if (not trySteal(c, r, stack, locals)) { if (not trySteal(c, r, stack, locals)) {
r = replace(c, stack, r); r = replace(c, stack, locals, r);
} }
} }
} }
@ -1275,8 +1343,10 @@ apply(Context* c, TernaryOperation op,
} }
void void
insertRead(Context* c, Event* event, int sequence, Value* v, Read* r) insertRead(Context*, Event* event, int sequence, Value* v, Read* r)
{ {
r->value = v;
r->event = event;
event->reads = r; event->reads = r;
++ event->readCount; ++ event->readCount;
@ -1326,8 +1396,8 @@ clean(Context* c, Value* v)
void void
clean(Context* c, Stack* stack, Value** locals, Read* reads) clean(Context* c, Stack* stack, Value** locals, Read* reads)
{ {
for (unsigned i = 0; i < c->localCount; ++i) { for (unsigned i = 0; i < c->localFootprint; ++i) {
clean(c, locals[i]); if (locals[i]) clean(c, locals[i]);
} }
for (Stack* s = stack; s; s = s->next) { for (Stack* s = stack; s; s = s->next) {
@ -1371,40 +1441,40 @@ class CallEvent: public Event {
unsigned frameIndex = alignedFrameSize(c) + c->parameterFootprint; unsigned frameIndex = alignedFrameSize(c) + c->parameterFootprint;
for (unsigned i = 0; i < argumentCount; ++i) { for (unsigned i = 0; i < argumentCount; ++i) {
Read* target; Read* target;
if (index < c->assembler->argumentRegisterCount()) { if (index < c->arch->argumentRegisterCount()) {
int r = c->assembler->argumentRegister(index); int r = c->arch->argumentRegister(index);
target = fixedRegisterRead(c, r); target = fixedRegisterRead(c, s->size * BytesPerWord, r);
mask &= ~(1 << r); mask &= ~(1 << r);
} else { } else {
frameIndex -= s->geometry->size; frameIndex -= s->size;
target = read(c, 1 << MemoryOperand, 0, frameIndex); target = read(c, s->size * BytesPerWord, 1 << MemoryOperand, 0,
s->pushEvent->active = true; frameIndex);
} }
addRead(c, s->value, s->geometry->size * BytesPerWord, target); addRead(c, s->value, target);
index += s->geometry->size; index += s->size;
s = s->next; s = s->next;
} }
addRead(c, address, BytesPerWord, read addRead(c, address, read
(c, ~0, (static_cast<uint64_t>(mask) << 32) | mask, (c, BytesPerWord, ~0, (static_cast<uint64_t>(mask) << 32) | mask,
AnyFrameIndex)); AnyFrameIndex));
int footprint = stackArgumentFootprint; int footprint = stackArgumentFootprint;
for (Stack* s = stack; s; s = s->next) { for (Stack* s = stack; s; s = s->next) {
if (footprint) { if (footprint) {
addRead(c, s->value, s->geometry->size * BytesPerWord, read addRead(c, s->value, read(c, s->size * BytesPerWord,
(c, 1 << MemoryOperand, 0, frameIndex)); 1 << MemoryOperand, 0, frameIndex));
} else { } else {
unsigned index = s->geometry->index + c->localFootprint; unsigned index = s->index + c->localFootprint;
if (footprint == 0) { if (footprint == 0) {
assert(c, index <= frameIndex); assert(c, index <= frameIndex);
s->geometry->padding = frameIndex - index; s->padding = frameIndex - index;
} }
addRead(c, s->value, s->geometry->size * BytesPerWord, read addRead(c, s->value, read(c, s->size * BytesPerWord,
(c, 1 << MemoryOperand, 0, index)); 1 << MemoryOperand, 0, index));
} }
frameIndex -= s->geometry->size; frameIndex -= s->size;
footprint -= s->geometry->size; footprint -= s->size;
} }
} }
@ -1424,9 +1494,9 @@ class CallEvent: public Event {
if (resultSize and live(result)) { if (resultSize and live(result)) {
addSite(c, 0, 0, resultSize, result, registerSite addSite(c, 0, 0, resultSize, result, registerSite
(c, c->assembler->returnLow(), (c, c->arch->returnLow(),
resultSize > BytesPerWord ? resultSize > BytesPerWord ?
c->assembler->returnHigh() : NoRegister)); c->arch->returnHigh() : NoRegister));
} }
} }
@ -1459,10 +1529,10 @@ class ReturnEvent: public Event {
Event(c), value(value) Event(c), value(value)
{ {
if (value) { if (value) {
addRead(c, value, size, fixedRegisterSite addRead(c, value, fixedRegisterRead
(c, c->assembler->returnLow(), (c, size, c->arch->returnLow(),
size > BytesPerWord ? size > BytesPerWord ?
c->assembler->returnHigh() : NoRegister)); c->arch->returnHigh() : NoRegister));
} }
} }
@ -1475,11 +1545,7 @@ class ReturnEvent: public Event {
nextRead(c, value); nextRead(c, value);
} }
Assembler::Register frame(c->assembler->frame()); c->assembler->popFrame();
Assembler::Memory oldFrame(c->assembler->frame(), 0);
c->assembler->apply(Move, BytesPerWord, MemoryOperand, &oldFrame,
BytesPerWord, RegisterOperand, &frame);
c->assembler->apply(Return); c->assembler->apply(Return);
} }
@ -1499,12 +1565,11 @@ appendReturn(Context* c, unsigned size, Value* value)
class MoveEvent: public Event { class MoveEvent: public Event {
public: public:
MoveEvent(Context* c, BinaryOperation type, unsigned srcSize, Value* src, MoveEvent(Context* c, BinaryOperation type, unsigned srcSize, Value* src,
unsigned dstSize, Value* dst, Site* srcTarget, unsigned dstSize, Value* dst, Read* srcRead, Read* dstRead):
VirtualSite* dstTarget):
Event(c), type(type), srcSize(srcSize), src(src), dstSize(dstSize), Event(c), type(type), srcSize(srcSize), src(src), dstSize(dstSize),
dst(dst), dstTarget(dstTarget) dst(dst), dstRead(dstRead)
{ {
addRead(c, src, size, srcTarget); addRead(c, src, srcRead);
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
@ -1532,12 +1597,17 @@ class MoveEvent: public Event {
} }
if (cost or type != Move) { if (cost or type != Move) {
if (match(c, target, dstTarget->typeMask, dstTarget->registerMask)) { uint8_t typeMask = ~static_cast<uint8_t>(0);
uint64_t registerMask = ~static_cast<uint64_t>(0);
int frameIndex = AnyFrameIndex;
dstRead->intersect(&typeMask, &registerMask, &frameIndex);
if (target->match(c, typeMask, registerMask, frameIndex)) {
apply(c, type, srcSize, src->source, dstSize, target); apply(c, type, srcSize, src->source, dstSize, target);
} else { } else {
assert(c, dstTarget->typeMask & (1 << RegisterOperand)); assert(c, typeMask & (1 << RegisterOperand));
Site* tmpTarget = freeRegisterSite(c, dstTarget->registerMask); Site* tmpTarget = freeRegisterSite(c, registerMask);
addSite(c, stack, locals, dstSize, dst, tmpTarget); addSite(c, stack, locals, dstSize, dst, tmpTarget);
@ -1565,30 +1635,33 @@ class MoveEvent: public Event {
Value* src; Value* src;
unsigned dstSize; unsigned dstSize;
Value* dst; Value* dst;
VirtualSite* dstTarget; Read* dstRead;
}; };
void void
appendMove(Context* c, BinaryOperation type, unsigned size, Value* src, appendMove(Context* c, BinaryOperation type, unsigned srcSize, Value* src,
Value* dst) unsigned dstSize, Value* dst)
{ {
if (DebugAppend) { if (DebugAppend) {
fprintf(stderr, "appendMove\n"); fprintf(stderr, "appendMove\n");
} }
VirtualSite* srcTarget = virtualSite(c, dst);
VirtualSite* dstTarget = virtualSite(c);
bool thunk; bool thunk;
uint8_t srcTypeMask;
uint64_t srcRegisterMask;
uint8_t dstTypeMask;
uint64_t dstRegisterMask;
c->assembler->plan(type, size, c->arch->plan(type, srcSize, &srcTypeMask, &srcRegisterMask,
&(srcTarget->typeMask), &(srcTarget->registerMask), dstSize, &dstTypeMask, &dstRegisterMask,
&(dstTarget->typeMask), &(dstTarget->registerMask),
&thunk); &thunk);
assert(c, not thunk); // todo assert(c, not thunk); // todo
new (c->zone->allocate(sizeof(MoveEvent))) new (c->zone->allocate(sizeof(MoveEvent)))
MoveEvent(c, type, size, src, dst, srcTarget, dstTarget); MoveEvent(c, type, srcSize, src, dstSize, dst,
read(c, srcSize, srcTypeMask, srcRegisterMask, AnyFrameIndex),
read(c, dstSize, dstTypeMask, dstRegisterMask, AnyFrameIndex));
} }
ConstantSite* ConstantSite*
@ -1605,11 +1678,11 @@ findConstantSite(Context* c, Value* v)
class CompareEvent: public Event { class CompareEvent: public Event {
public: public:
CompareEvent(Context* c, unsigned size, Value* first, Value* second, CompareEvent(Context* c, unsigned size, Value* first, Value* second,
Site* firstTarget, Site* secondTarget): Read* firstRead, Read* secondRead):
Event(c), size(size), first(first), second(second) Event(c), size(size), first(first), second(second)
{ {
addRead(c, first, size, firstTarget); addRead(c, first, firstRead);
addRead(c, second, size, secondTarget); addRead(c, second, secondRead);
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
@ -1649,13 +1722,14 @@ class CompareEvent: public Event {
void void
appendCompare(Context* c, unsigned size, Value* first, Value* second) appendCompare(Context* c, unsigned size, Value* first, Value* second)
{ {
VirtualSite* firstTarget = virtualSite(c);
VirtualSite* secondTarget = virtualSite(c);
bool thunk; bool thunk;
uint8_t firstTypeMask;
uint64_t firstRegisterMask;
uint8_t secondTypeMask;
uint64_t secondRegisterMask;
c->assembler->plan(Compare, size, c->arch->plan(Compare, size, &firstTypeMask, &firstRegisterMask,
&(firstTarget->typeMask), &(firstTarget->registerMask), size, &secondTypeMask, &secondRegisterMask,
&(secondTarget->typeMask), &(secondTarget->registerMask),
&thunk); &thunk);
assert(c, not thunk); // todo assert(c, not thunk); // todo
@ -1665,25 +1739,29 @@ appendCompare(Context* c, unsigned size, Value* first, Value* second)
} }
new (c->zone->allocate(sizeof(CompareEvent))) new (c->zone->allocate(sizeof(CompareEvent)))
CompareEvent(c, size, first, second, firstTarget, secondTarget); CompareEvent
(c, size, first, second,
read(c, size, firstTypeMask, firstRegisterMask, AnyFrameIndex),
read(c, size, secondTypeMask, secondRegisterMask, AnyFrameIndex));
} }
void void
preserve(Context* c, Stack* stack, unsigned size, Value* v, Site* s, preserve(Context* c, Stack* stack, Value** locals, unsigned size, Value* v,
Read* read) Site* s, Read* read)
{ {
assert(c, v->sites == s); assert(c, v->sites == s);
Site* r = targetOrNull(c, read); Site* r = targetOrNull(c, v, read);
if (r == 0 or r == s) r = freeRegisterSite(c); if (r == 0 or r == s) r = freeRegisterSite(c);
addSite(c, stack, locals, size, v, r); addSite(c, stack, locals, size, v, r);
apply(c, Move, size, s, size, r); apply(c, Move, size, s, size, r);
} }
void void
maybePreserve(Context* c, Stack* stack, unsigned size, Value* v, Site* s) maybePreserve(Context* c, Stack* stack, Value** locals, unsigned size,
Value* v, Site* s)
{ {
if (valid(v->reads->next) and v->sites->next == 0) { if (valid(v->reads->next) and v->sites->next == 0) {
preserve(c, stack, size, v, s, v->reads->next); preserve(c, stack, locals, size, v, s, v->reads->next);
} }
} }
@ -1693,13 +1771,13 @@ class CombineEvent: public Event {
unsigned firstSize, Value* first, unsigned firstSize, Value* first,
unsigned secondSize, Value* second, unsigned secondSize, Value* second,
unsigned resultSize, Value* result, unsigned resultSize, Value* result,
Site* firstTarget, Site* secondTarget): Read* firstRead, Read* secondRead):
Event(c), type(type), firstSize(firstSize), first(first), Event(c), type(type), firstSize(firstSize), first(first),
secondSize(secondSize), second(second), resultSize(resultSize), secondSize(secondSize), second(second), resultSize(resultSize),
result(result) result(result)
{ {
addRead(c, first, firstSize, firstTarget); addRead(c, first, firstRead);
addRead(c, second, secondSize, secondTarget); addRead(c, second, secondRead);
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
@ -1707,7 +1785,7 @@ class CombineEvent: public Event {
fprintf(stderr, "CombineEvent.compile\n"); fprintf(stderr, "CombineEvent.compile\n");
} }
maybePreserve(c, stack, secondSize, second, second->source); maybePreserve(c, stack, locals, secondSize, second, second->source);
Site* target = targetOrRegister(c, result); Site* target = targetOrRegister(c, result);
apply(c, type, firstSize, first->source, secondSize, second->source, apply(c, type, firstSize, first->source, secondSize, second->source,
@ -1716,12 +1794,12 @@ class CombineEvent: public Event {
nextRead(c, first); nextRead(c, first);
nextRead(c, second); nextRead(c, second);
if (live(target)) { if (live(result)) {
addSite(c, 0, 0, resultSize, result, target); addSite(c, 0, 0, resultSize, result, target);
} }
} }
BinaryOperation type; TernaryOperation type;
unsigned firstSize; unsigned firstSize;
Value* first; Value* first;
unsigned secondSize; unsigned secondSize;
@ -1739,53 +1817,94 @@ value(Context* c, Site* site = 0, Site* target = 0)
return new (c->zone->allocate(sizeof(Value))) Value(site, target); return new (c->zone->allocate(sizeof(Value))) Value(site, target);
} }
void Stack*
appendCombine(Context* c, BinaryOperation type, unsigned size, Value* first, stack(Context* c, Value* value, unsigned size, unsigned index, Stack* next)
Value* second, Value* result)
{ {
VirtualSite* firstTarget = virtualSite(c); return new (c->zone->allocate(sizeof(Stack)))
VirtualSite* secondTarget = virtualSite(c, result); Stack(index, size, value, next);
bool thunk; }
c->assembler->plan(type, size, Stack*
&(firstTarget->typeMask), &(firstTarget->registerMask), stack(Context* c, Value* value, unsigned size, Stack* next)
&(secondTarget->typeMask), &(secondTarget->registerMask), {
return stack
(c, value, size, (next ? next->index + next->size : 0), next);
}
void
push(Context* c, unsigned size, Value* v)
{
assert(c, ceiling(size, BytesPerWord));
c->state->stack = stack(c, v, ceiling(size, BytesPerWord), c->state->stack);
}
Value*
pop(Context* c, unsigned size UNUSED)
{
Stack* s = c->state->stack;
assert(c, ceiling(size, BytesPerWord) == s->size);
c->state->stack = s->next;
return s->value;
}
void
appendCombine(Context* c, TernaryOperation type,
unsigned firstSize, Value* first,
unsigned secondSize, Value* second,
unsigned resultSize, Value* result)
{
bool thunk;
uint8_t firstTypeMask;
uint64_t firstRegisterMask;
uint8_t secondTypeMask;
uint64_t secondRegisterMask;
uint8_t resultTypeMask;
uint64_t resultRegisterMask;
c->arch->plan(type, firstSize, &firstTypeMask, &firstRegisterMask,
secondSize, &secondTypeMask, &secondRegisterMask,
resultSize, &resultTypeMask, &resultRegisterMask,
&thunk); &thunk);
if (thunk) { if (thunk) {
secondTarget->value = 0;
Stack* oldStack = c->state->stack; Stack* oldStack = c->state->stack;
::push(c, size, second); ::push(c, secondSize, second);
::push(c, size, first); ::push(c, firstSize, first);
Stack* argumentStack = c->state->stack; Stack* argumentStack = c->state->stack;
c->state->stack = oldStack; c->state->stack = oldStack;
appendCall(c, value(c, constantSite(c, c->client->getThunk(type, size))), appendCall
0, 0, result, size, argumentStack, 2); (c, value(c, constantSite(c, c->client->getThunk(type, resultSize))),
0, 0, result, resultSize, argumentStack, 2, 0);
} else { } else {
if (DebugAppend) { if (DebugAppend) {
fprintf(stderr, "appendCombine\n"); fprintf(stderr, "appendCombine\n");
} }
firstTarget->typeMask &= ~(1 << MemoryOperand); // todo: respect resultTypeMask and resultRegisterMask
secondTarget->typeMask &= ~(1 << MemoryOperand);
new (c->zone->allocate(sizeof(CombineEvent))) new (c->zone->allocate(sizeof(CombineEvent)))
CombineEvent(c, type, size, first, second, result, firstTarget, CombineEvent
secondTarget); (c, type,
firstSize, first,
secondSize, second,
resultSize, result,
read(c, firstSize, firstTypeMask, firstRegisterMask, AnyFrameIndex),
read(c, secondSize, secondTypeMask, secondRegisterMask, AnyFrameIndex));
} }
} }
class TranslateEvent: public Event { class TranslateEvent: public Event {
public: public:
TranslateEvent(Context* c, UnaryOperation type, unsigned size, Value* value, TranslateEvent(Context* c, BinaryOperation type, unsigned size, Value* value,
Value* result, Site* target): Value* result, Read* read):
Event(c), type(type), size(size), value(value), result(result) Event(c), type(type), size(size), value(value), result(result)
{ {
addRead(c, value, size, target); addRead(c, value, read);
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
@ -1793,9 +1912,10 @@ class TranslateEvent: public Event {
fprintf(stderr, "TranslateEvent.compile\n"); fprintf(stderr, "TranslateEvent.compile\n");
} }
maybePreserve(c, stack, size, value, value->source); maybePreserve(c, stack, locals, size, value, value->source);
apply(c, type, size, value->source); Site* target = targetOrRegister(c, result);
apply(c, type, size, value->source, size, target);
nextRead(c, value); nextRead(c, value);
@ -1805,32 +1925,38 @@ class TranslateEvent: public Event {
} }
} }
UnaryOperation type; BinaryOperation type;
unsigned size; unsigned size;
Value* value; Value* value;
Value* result; Value* result;
}; };
void void
appendTranslate(Context* c, UnaryOperation type, unsigned size, Value* value, appendTranslate(Context* c, BinaryOperation type, unsigned size, Value* value,
Value* result) Value* result)
{ {
if (DebugAppend) { if (DebugAppend) {
fprintf(stderr, "appendTranslate\n"); fprintf(stderr, "appendTranslate\n");
} }
VirtualSite* target = virtualSite(c, result);
bool thunk; bool thunk;
uint8_t firstTypeMask;
uint64_t firstRegisterMask;
uint8_t resultTypeMask;
uint64_t resultRegisterMask;
c->assembler->plan c->arch->plan(type, size, &firstTypeMask, &firstRegisterMask,
(type, size, &(target->typeMask), &(target->registerMask), &thunk); size, &resultTypeMask, &resultRegisterMask,
&thunk);
assert(c, not thunk); // todo assert(c, not thunk); // todo
target->typeMask &= ~(1 << MemoryOperand); // todo: respect resultTypeMask and resultRegisterMask
new (c->zone->allocate(sizeof(TranslateEvent))) new (c->zone->allocate(sizeof(TranslateEvent)))
TranslateEvent(c, type, size, value, result, target); TranslateEvent
(c, type, size, value, result,
read(c, size, firstTypeMask, firstRegisterMask, AnyFrameIndex));
} }
class MemoryEvent: public Event { class MemoryEvent: public Event {
@ -1840,8 +1966,8 @@ class MemoryEvent: public Event {
Event(c), base(base), displacement(displacement), index(index), Event(c), base(base), displacement(displacement), index(index),
scale(scale), result(result) scale(scale), result(result)
{ {
addRead(c, base, BytesPerWord, anyRegisterSite(c)); addRead(c, base, anyRegisterRead(c, BytesPerWord));
if (index) addRead(c, index, BytesPerWord, registerOrConstantSite(c)); if (index) addRead(c, index, registerOrConstantRead(c, BytesPerWord));
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
@ -1873,7 +1999,7 @@ class MemoryEvent: public Event {
nextRead(c, base); nextRead(c, base);
if (index) { if (index) {
if (BytesPerWord == 8 and indexRegister != NoRegister) { if (BytesPerWord == 8 and indexRegister != NoRegister) {
apply(c, Move4To8, 8, index->source, index->source); apply(c, Move, 4, index->source, 8, index->source);
} }
nextRead(c, index); nextRead(c, index);
@ -1903,65 +2029,13 @@ appendMemory(Context* c, Value* base, int displacement, Value* index,
MemoryEvent(c, base, displacement, index, scale, result); MemoryEvent(c, base, displacement, index, scale, result);
} }
Stack*
stack(Context* c, Value* value, StackGeometry* geometry, Stack* next)
{
return new (c->zone->allocate(sizeof(Stack))) Stack(value, geometry, next);
}
Stack*
stack(Context* c, Value* value, unsigned size, unsigned index, Stack* next)
{
return stack(c, value, new (c->zone->allocate(sizeof(StackGeometry)))
StackGeometry(size, index), next);
}
class StackSyncEvent: public Event {
public:
StackSyncEvent(Context* c):
Event(c)
{
for (Stack* s = stack; s; s = s->next) {
if (s->pushEvent) s->pushEvent->active = true;
addRead(c, s->value, s->geometry->size * BytesPerWord, 0);
}
}
StackSyncEvent(Context* c, unsigned sequence, Stack* stack, Local* locals):
Event(c, sequence, stack, locals)
{
for (Stack* s = stack; s; s = s->next) {
if (s->pushEvent) s->pushEvent->active = true;
insertRead
(c, this, sequence, s->value, s->geometry->size * BytesPerWord, 0);
}
}
virtual void compile(Context* c) {
if (DebugCompile) {
fprintf(stderr, "StackSyncEvent.compile\n");
}
clean(c, stack, locals, reads);
}
};
void
appendStackSync(Context* c)
{
if (DebugAppend) {
fprintf(stderr, "appendStackSync\n");
}
new (c->zone->allocate(sizeof(StackSyncEvent))) StackSyncEvent(c);
}
class BranchEvent: public Event { class BranchEvent: public Event {
public: public:
BranchEvent(Context* c, UnaryOperation type, Value* address): BranchEvent(Context* c, UnaryOperation type, Value* address):
Event(c), type(type), address(address) Event(c), type(type), address(address)
{ {
addRead(c, address, BytesPerWord, 0); addRead(c, address, read(c, BytesPerWord, ~0, ~static_cast<uint64_t>(0),
AnyFrameIndex));
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
@ -2106,8 +2180,8 @@ class BoundsCheckEvent: public Event {
Event(c), object(object), lengthOffset(lengthOffset), index(index), Event(c), object(object), lengthOffset(lengthOffset), index(index),
handler(handler) handler(handler)
{ {
addRead(c, object, BytesPerWord, anyRegisterSite(c)); addRead(c, object, anyRegisterRead(c, BytesPerWord));
addRead(c, index, BytesPerWord, registerOrConstantSite(c)); addRead(c, index, registerOrConstantRead(c, BytesPerWord));
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
@ -2513,36 +2587,6 @@ popState(Context* c)
} }
} }
Stack*
stack(Context* c, Value* value, unsigned size, Stack* next)
{
return stack
(c, value, size, (next ? next->geometry->index + next->geometry->size : 0),
next);
}
void
push(Context* c, unsigned size, Value* v)
{
assert(c, ceiling(size, BytesPerWord));
c->state->stack = stack(c, v, ceiling(size, BytesPerWord), c->state->stack);
appendPush(c);
}
Value*
pop(Context* c, unsigned size UNUSED)
{
Stack* s = c->state->stack;
assert(c, ceiling(size, BytesPerWord) == s->size);
appendPop(c, s->geometry->size, false);
c->state->stack = s->next;
return s->value;
}
void void
updateJunctions(Context* c) updateJunctions(Context* c)
{ {
@ -2793,20 +2837,20 @@ class MyCompiler: public Compiler {
} }
virtual unsigned size(StackElement* e) { virtual unsigned size(StackElement* e) {
return static_cast<Stack*>(e)->geometry->size; return static_cast<Stack*>(e)->size;
} }
virtual unsigned padding(StackElement* e) { virtual unsigned padding(StackElement* e) {
return static_cast<Stack*>(e)->geometry->padding; return static_cast<Stack*>(e)->padding;
} }
virtual Operand* peek(unsigned size UNUSED, unsigned index) { virtual Operand* peek(unsigned size UNUSED, unsigned index) {
Stack* s = c.state->stack; Stack* s = c.state->stack;
for (unsigned i = index; i > 0;) { for (unsigned i = index; i > 0;) {
i -= s->geometry->size; i -= s->size;
s = s->next; s = s->next;
} }
assert(&c, s->geometry->size == ceiling(size, BytesPerWord)); assert(&c, s->size == ceiling(size, BytesPerWord));
return s->value; return s->value;
} }
@ -2859,10 +2903,10 @@ class MyCompiler: public Compiler {
c.state->stack = oldStack; c.state->stack = oldStack;
unsigned padding = c->assembler->stackPadding unsigned padding = c->assembler->stackPadding
(c.state->stack->geometry->index + c.state->stack->geometry->size); (c.state->stack->index + c.state->stack->size);
if (bottomArgument) { if (bottomArgument) {
bottomArgument->geometry->padding = padding; bottomArgument->padding = padding;
} }
Value* result = value(&c); Value* result = value(&c);

View File

@ -24,7 +24,7 @@ class Compiler {
virtual ~Client() { } virtual ~Client() { }
virtual intptr_t getThunk(UnaryOperation op, unsigned size) = 0; virtual intptr_t getThunk(UnaryOperation op, unsigned size) = 0;
virtual intptr_t getThunk(BinaryOperation op, unsigned size) = 0; virtual intptr_t getThunk(TernaryOperation op, unsigned size) = 0;
}; };
static const unsigned Aligned = 1 << 0; static const unsigned Aligned = 1 << 0;