mirror of
https://github.com/corda/corda.git
synced 2025-01-09 14:33:30 +00:00
added floating point support, split plan method
This commit is contained in:
parent
7483fa154d
commit
53c0656ee7
331
src/compiler.cpp
331
src/compiler.cpp
@ -286,11 +286,16 @@ intersect(const SiteMask& a, const SiteMask& b)
|
|||||||
intersectFrameIndexes(a.frameIndex, b.frameIndex));
|
intersectFrameIndexes(a.frameIndex, b.frameIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ValueType {
|
||||||
|
ValueGeneral,
|
||||||
|
ValueFloat
|
||||||
|
};
|
||||||
|
|
||||||
class Value: public Compiler::Operand {
|
class Value: public Compiler::Operand {
|
||||||
public:
|
public:
|
||||||
Value(Site* site, Site* target):
|
Value(Site* site, Site* target):
|
||||||
reads(0), lastRead(0), sites(site), source(0), target(target), buddy(this),
|
reads(0), lastRead(0), sites(site), source(0), target(target), buddy(this),
|
||||||
high(0), home(NoFrameIndex)
|
high(0), home(NoFrameIndex), type(ValueGeneral)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void addPredecessor(Context*, Event*) { }
|
virtual void addPredecessor(Context*, Event*) { }
|
||||||
@ -303,6 +308,7 @@ class Value: public Compiler::Operand {
|
|||||||
Value* buddy;
|
Value* buddy;
|
||||||
Value* high;
|
Value* high;
|
||||||
int8_t home;
|
int8_t home;
|
||||||
|
ValueType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
@ -338,12 +344,19 @@ class Context {
|
|||||||
machineCodeSize(0),
|
machineCodeSize(0),
|
||||||
alignedFrameSize(0),
|
alignedFrameSize(0),
|
||||||
availableRegisterCount(arch->registerCount()),
|
availableRegisterCount(arch->registerCount()),
|
||||||
|
floatRegisterCount(arch->floatRegisterCount()),
|
||||||
|
generalRegisterCount(arch->generalRegisterCount()),
|
||||||
constantCompare(CompareNone)
|
constantCompare(CompareNone)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < arch->registerCount(); ++i) {
|
for (unsigned i = 0; i < arch->registerCount(); ++i) {
|
||||||
new (registerResources + i) RegisterResource(arch->reserved(i));
|
new (registerResources + i) RegisterResource(arch->reserved(i));
|
||||||
if (registerResources[i].reserved) {
|
if (registerResources[i].reserved) {
|
||||||
-- availableRegisterCount;
|
-- availableRegisterCount;
|
||||||
|
if (arch->generalRegisters() & (1 << i)) {
|
||||||
|
-- generalRegisterCount;
|
||||||
|
} else if (arch->floatRegisters() & (1 << i)) {
|
||||||
|
-- floatRegisterCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -375,6 +388,8 @@ class Context {
|
|||||||
unsigned machineCodeSize;
|
unsigned machineCodeSize;
|
||||||
unsigned alignedFrameSize;
|
unsigned alignedFrameSize;
|
||||||
unsigned availableRegisterCount;
|
unsigned availableRegisterCount;
|
||||||
|
unsigned floatRegisterCount;
|
||||||
|
unsigned generalRegisterCount;
|
||||||
ConstantCompare constantCompare;
|
ConstantCompare constantCompare;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -949,21 +964,42 @@ buddies(Value* a, Value* b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decrementAvailableRegisterCount(Context* c)
|
decrementAvailableRegisterCount(Context* c, Value* v)
|
||||||
{
|
{
|
||||||
assert(c, c->availableRegisterCount);
|
assert(c, c->availableRegisterCount);
|
||||||
-- c->availableRegisterCount;
|
-- c->availableRegisterCount;
|
||||||
|
|
||||||
|
if (v) {
|
||||||
|
if (v->type == ValueGeneral) {
|
||||||
|
-- c->generalRegisterCount;
|
||||||
|
} else if (v->type == ValueFloat) {
|
||||||
|
-- c->floatRegisterCount;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
-- c->generalRegisterCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (DebugResources) {
|
if (DebugResources) {
|
||||||
fprintf(stderr, "%d registers available\n", c->availableRegisterCount);
|
fprintf(stderr, "%d registers available - %d float, %d general\n", c->availableRegisterCount, c->floatRegisterCount, c->generalRegisterCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
incrementAvailableRegisterCount(Context* c)
|
incrementAvailableRegisterCount(Context* c, Value* v)
|
||||||
{
|
{
|
||||||
++ c->availableRegisterCount;
|
++ c->availableRegisterCount;
|
||||||
|
|
||||||
|
if (v) {
|
||||||
|
if (v->type == ValueGeneral) {
|
||||||
|
++ c->generalRegisterCount;
|
||||||
|
} else if (v->type == ValueFloat) {
|
||||||
|
++ c->floatRegisterCount;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
++ c->generalRegisterCount;
|
||||||
|
}
|
||||||
|
|
||||||
if (DebugResources) {
|
if (DebugResources) {
|
||||||
fprintf(stderr, "%d registers available\n", c->availableRegisterCount);
|
fprintf(stderr, "%d registers available\n", c->availableRegisterCount);
|
||||||
}
|
}
|
||||||
@ -981,7 +1017,7 @@ increment(Context* c, RegisterResource* r)
|
|||||||
++ r->referenceCount;
|
++ r->referenceCount;
|
||||||
|
|
||||||
if (r->referenceCount == 1) {
|
if (r->referenceCount == 1) {
|
||||||
decrementAvailableRegisterCount(c);
|
decrementAvailableRegisterCount(c, r->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1000,7 +1036,7 @@ decrement(Context* c, Resource* r)
|
|||||||
-- r->referenceCount;
|
-- r->referenceCount;
|
||||||
|
|
||||||
if (r->referenceCount == 0) {
|
if (r->referenceCount == 0) {
|
||||||
incrementAvailableRegisterCount(c);
|
incrementAvailableRegisterCount(c, r->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1023,7 +1059,7 @@ RegisterResource::freeze(Context* c, Value* v)
|
|||||||
freezeResource(c, this, v);
|
freezeResource(c, this, v);
|
||||||
|
|
||||||
if (freezeCount == 1) {
|
if (freezeCount == 1) {
|
||||||
decrementAvailableRegisterCount(c);
|
decrementAvailableRegisterCount(c, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1056,7 +1092,7 @@ RegisterResource::thaw(Context* c, Value* v)
|
|||||||
thawResource(c, this, v);
|
thawResource(c, this, v);
|
||||||
|
|
||||||
if (freezeCount == 0) {
|
if (freezeCount == 0) {
|
||||||
incrementAvailableRegisterCount(c);
|
incrementAvailableRegisterCount(c, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1112,6 +1148,13 @@ pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost)
|
|||||||
{
|
{
|
||||||
int target = NoRegister;
|
int target = NoRegister;
|
||||||
unsigned bestCost = Target::Impossible;
|
unsigned bestCost = Target::Impossible;
|
||||||
|
if (v) {
|
||||||
|
if (v->type == ValueFloat) {
|
||||||
|
mask &= (c->arch->floatRegisters() | c->arch->generalRegisters());
|
||||||
|
} else if(v->type == ValueGeneral) {
|
||||||
|
mask &= c->arch->generalRegisters();
|
||||||
|
}
|
||||||
|
}
|
||||||
for (int i = c->arch->registerCount() - 1; i >= 0; --i) {
|
for (int i = c->arch->registerCount() - 1; i >= 0; --i) {
|
||||||
if ((1 << i) & mask) {
|
if ((1 << i) & mask) {
|
||||||
RegisterResource* r = c->registerResources + i;
|
RegisterResource* r = c->registerResources + i;
|
||||||
@ -1190,15 +1233,30 @@ pickTarget(Context* c, Read* read, bool intersectRead,
|
|||||||
SiteMask mask;
|
SiteMask mask;
|
||||||
read->intersect(&mask);
|
read->intersect(&mask);
|
||||||
|
|
||||||
unsigned registerPenalty = (c->availableRegisterCount > registerReserveCount
|
unsigned registerPenalty;
|
||||||
|
if(read->value) {
|
||||||
|
if(read->value->type == ValueGeneral) {
|
||||||
|
registerPenalty = (c->generalRegisterCount > registerReserveCount
|
||||||
? 0 : Target::Penalty);
|
? 0 : Target::Penalty);
|
||||||
|
} else if(read->value->type == ValueFloat) {
|
||||||
|
registerPenalty = (c->floatRegisterCount > registerReserveCount
|
||||||
|
? 0 : Target::Penalty);
|
||||||
|
} else {
|
||||||
|
registerPenalty = (c->availableRegisterCount > registerReserveCount
|
||||||
|
? 0 : Target::Penalty);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
registerPenalty = (c->availableRegisterCount > registerReserveCount
|
||||||
|
? 0 : Target::Penalty);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Target best;
|
Target best;
|
||||||
if ((mask.typeMask & (1 << RegisterOperand))) {
|
if ((mask.typeMask & (1 << RegisterOperand))) {
|
||||||
Target mine = pickRegisterTarget(c, read->value, mask.registerMask);
|
Target mine = pickRegisterTarget(c, read->value, mask.registerMask);
|
||||||
|
|
||||||
mine.cost += registerPenalty;
|
mine.cost += registerPenalty;
|
||||||
|
if(mine.cost == Target::Impossible) asm("int3");
|
||||||
if (mine.cost == 0) {
|
if (mine.cost == 0) {
|
||||||
return mine;
|
return mine;
|
||||||
} else if (mine.cost < best.cost) {
|
} else if (mine.cost < best.cost) {
|
||||||
@ -1916,17 +1974,17 @@ read(Context* c, const SiteMask& mask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Read*
|
Read*
|
||||||
anyRegisterRead(Context* c)
|
generalRegisterRead(Context* c)
|
||||||
{
|
{
|
||||||
return read(c, SiteMask(1 << RegisterOperand, ~0, NoFrameIndex));
|
return read(c, SiteMask(1 << RegisterOperand, c->arch->generalRegisters(), NoFrameIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
Read*
|
Read*
|
||||||
registerOrConstantRead(Context* c)
|
generalRegisterOrConstantRead(Context* c)
|
||||||
{
|
{
|
||||||
return read
|
return read
|
||||||
(c, SiteMask
|
(c, SiteMask
|
||||||
((1 << RegisterOperand) | (1 << ConstantOperand), ~0, NoFrameIndex));
|
((1 << RegisterOperand) | (1 << ConstantOperand), c->arch->generalRegisters(), NoFrameIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
Read*
|
Read*
|
||||||
@ -2524,12 +2582,9 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize,
|
|||||||
bool thunk;
|
bool thunk;
|
||||||
uint8_t srcTypeMask;
|
uint8_t srcTypeMask;
|
||||||
uint64_t srcRegisterMask;
|
uint64_t srcRegisterMask;
|
||||||
uint8_t dstTypeMask;
|
|
||||||
uint64_t dstRegisterMask;
|
|
||||||
|
|
||||||
c->arch->plan(type, dstSize, &srcTypeMask, &srcRegisterMask,
|
c->arch->planSource(type, dstSize, &srcTypeMask, &srcRegisterMask,
|
||||||
dstSize, &dstTypeMask, &dstRegisterMask,
|
dstSize, &thunk);
|
||||||
&thunk);
|
|
||||||
|
|
||||||
assert(c, dstMask.typeMask & srcTypeMask & (1 << RegisterOperand));
|
assert(c, dstMask.typeMask & srcTypeMask & (1 << RegisterOperand));
|
||||||
|
|
||||||
@ -2758,12 +2813,14 @@ appendMove(Context* c, BinaryOperation type, unsigned srcSize,
|
|||||||
uint8_t dstTypeMask;
|
uint8_t dstTypeMask;
|
||||||
uint64_t dstRegisterMask;
|
uint64_t dstRegisterMask;
|
||||||
|
|
||||||
c->arch->plan(type, srcSelectSize, &srcTypeMask, &srcRegisterMask,
|
c->arch->planSource(type, srcSelectSize, &srcTypeMask, &srcRegisterMask,
|
||||||
dstSize, &dstTypeMask, &dstRegisterMask,
|
dstSize, &thunk);
|
||||||
&thunk);
|
|
||||||
|
|
||||||
assert(c, not thunk);
|
assert(c, not thunk);
|
||||||
|
|
||||||
|
c->arch->planDestination(type, srcSelectSize, &srcTypeMask, &srcRegisterMask,
|
||||||
|
dstSize, &dstTypeMask, &dstRegisterMask);
|
||||||
|
|
||||||
append(c, new (c->zone->allocate(sizeof(MoveEvent)))
|
append(c, new (c->zone->allocate(sizeof(MoveEvent)))
|
||||||
MoveEvent
|
MoveEvent
|
||||||
(c, type, srcSize, srcSelectSize, src, dstSize, dst,
|
(c, type, srcSize, srcSelectSize, src, dstSize, dst,
|
||||||
@ -2787,10 +2844,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, BinaryOperation type, unsigned size, Value* first, Value* second,
|
||||||
const SiteMask& firstMask, const SiteMask& secondMask):
|
const SiteMask& firstMask, const SiteMask& secondMask):
|
||||||
Event(c), size(size), first(first), second(second)
|
Event(c), type(type), size(size), first(first), second(second)
|
||||||
{
|
{
|
||||||
|
assert(c, type != FloatCompare || (first->type == ValueFloat && first->type == ValueFloat));
|
||||||
addRead(c, this, first, read(c, firstMask));
|
addRead(c, this, first, read(c, firstMask));
|
||||||
addRead(c, this, second, read(c, secondMask));
|
addRead(c, this, second, read(c, secondMask));
|
||||||
}
|
}
|
||||||
@ -2817,20 +2875,21 @@ class CompareEvent: public Event {
|
|||||||
} else {
|
} else {
|
||||||
c->constantCompare = CompareNone;
|
c->constantCompare = CompareNone;
|
||||||
|
|
||||||
apply(c, Compare, size, first->source, 0, size, second->source, 0);
|
apply(c, type, size, first->source, 0, size, second->source, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
popRead(c, this, first);
|
popRead(c, this, first);
|
||||||
popRead(c, this, second);
|
popRead(c, this, second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BinaryOperation type;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
Value* first;
|
Value* first;
|
||||||
Value* second;
|
Value* second;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
appendCompare(Context* c, unsigned size, Value* first, Value* second)
|
appendCompare(Context* c, BinaryOperation op, unsigned size, Value* first, Value* second)
|
||||||
{
|
{
|
||||||
bool thunk;
|
bool thunk;
|
||||||
uint8_t firstTypeMask;
|
uint8_t firstTypeMask;
|
||||||
@ -2838,15 +2897,17 @@ appendCompare(Context* c, unsigned size, Value* first, Value* second)
|
|||||||
uint8_t secondTypeMask;
|
uint8_t secondTypeMask;
|
||||||
uint64_t secondRegisterMask;
|
uint64_t secondRegisterMask;
|
||||||
|
|
||||||
c->arch->plan(Compare, size, &firstTypeMask, &firstRegisterMask,
|
c->arch->planSource(op, size, &firstTypeMask, &firstRegisterMask,
|
||||||
size, &secondTypeMask, &secondRegisterMask,
|
size, &thunk);
|
||||||
&thunk);
|
|
||||||
|
|
||||||
assert(c, not thunk); // todo
|
assert(c, not thunk); // todo
|
||||||
|
|
||||||
|
c->arch->planDestination(op, size, &firstTypeMask, &firstRegisterMask,
|
||||||
|
size, &secondTypeMask, &secondRegisterMask);
|
||||||
|
|
||||||
append(c, new (c->zone->allocate(sizeof(CompareEvent)))
|
append(c, new (c->zone->allocate(sizeof(CompareEvent)))
|
||||||
CompareEvent
|
CompareEvent
|
||||||
(c, size, first, second,
|
(c, op, size, first, second,
|
||||||
SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex),
|
SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex),
|
||||||
SiteMask(secondTypeMask, secondRegisterMask, AnyFrameIndex)));
|
SiteMask(secondTypeMask, secondRegisterMask, AnyFrameIndex)));
|
||||||
}
|
}
|
||||||
@ -2867,7 +2928,7 @@ getTarget(Context* c, Value* value, Value* result, const SiteMask& resultMask)
|
|||||||
Site* s;
|
Site* s;
|
||||||
Value* v;
|
Value* v;
|
||||||
Read* r = liveNext(c, value);
|
Read* r = liveNext(c, value);
|
||||||
if (c->arch->condensedAddressing() or r == 0) {
|
if (r == 0 and value->source->match(c, static_cast<const SiteMask&>(resultMask))) {
|
||||||
s = value->source;
|
s = value->source;
|
||||||
v = value;
|
v = value;
|
||||||
if (r and not hasMoreThanOneSite(v)) {
|
if (r and not hasMoreThanOneSite(v)) {
|
||||||
@ -2911,6 +2972,13 @@ thawSource(Context* c, unsigned size, Value* v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
registerMask(Value* v) {
|
||||||
|
Site* s = source(v);
|
||||||
|
if(!s) return 0;
|
||||||
|
else return static_cast<uint64_t>(1) << ((RegisterSite*)s)->number;
|
||||||
|
}
|
||||||
|
|
||||||
class CombineEvent: public Event {
|
class CombineEvent: public Event {
|
||||||
public:
|
public:
|
||||||
CombineEvent(Context* c, TernaryOperation type,
|
CombineEvent(Context* c, TernaryOperation type,
|
||||||
@ -2920,13 +2988,10 @@ class CombineEvent: public Event {
|
|||||||
const SiteMask& firstLowMask,
|
const SiteMask& firstLowMask,
|
||||||
const SiteMask& firstHighMask,
|
const SiteMask& firstHighMask,
|
||||||
const SiteMask& secondLowMask,
|
const SiteMask& secondLowMask,
|
||||||
const SiteMask& secondHighMask,
|
const SiteMask& secondHighMask):
|
||||||
const SiteMask& resultLowMask,
|
|
||||||
const SiteMask& resultHighMask):
|
|
||||||
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), resultLowMask(resultLowMask),
|
result(result)
|
||||||
resultHighMask(resultHighMask)
|
|
||||||
{
|
{
|
||||||
addRead(c, this, first, read(c, firstLowMask));
|
addRead(c, this, first, read(c, firstLowMask));
|
||||||
if (firstSize > BytesPerWord) {
|
if (firstSize > BytesPerWord) {
|
||||||
@ -2950,6 +3015,17 @@ class CombineEvent: public Event {
|
|||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
freezeSource(c, firstSize, first);
|
freezeSource(c, firstSize, first);
|
||||||
|
|
||||||
|
uint8_t aTypeMask = first->source->type(c);
|
||||||
|
uint8_t bTypeMask = second->source->type(c);
|
||||||
|
uint8_t cTypeMask;
|
||||||
|
uint64_t aRegisterMask = (registerMask(first->high) << 32) | registerMask(first);
|
||||||
|
uint64_t bRegisterMask = (registerMask(second->high) << 32) | registerMask(second);
|
||||||
|
uint64_t cRegisterMask;
|
||||||
|
|
||||||
|
c->arch->planDestination(type, firstSize, &aTypeMask, &aRegisterMask, secondSize, &bTypeMask, &bRegisterMask, resultSize, &cTypeMask, &cRegisterMask);
|
||||||
|
SiteMask resultLowMask(cTypeMask, cRegisterMask, AnyFrameIndex);
|
||||||
|
SiteMask resultHighMask(cTypeMask, cRegisterMask >> 32, AnyFrameIndex);
|
||||||
|
|
||||||
Site* low = getTarget(c, second, result, resultLowMask);
|
Site* low = getTarget(c, second, result, resultLowMask);
|
||||||
Site* high
|
Site* high
|
||||||
= (resultSize > BytesPerWord
|
= (resultSize > BytesPerWord
|
||||||
@ -2987,8 +3063,6 @@ class CombineEvent: public Event {
|
|||||||
Value* second;
|
Value* second;
|
||||||
unsigned resultSize;
|
unsigned resultSize;
|
||||||
Value* result;
|
Value* result;
|
||||||
SiteMask resultLowMask;
|
|
||||||
SiteMask resultHighMask;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -3284,13 +3358,10 @@ appendCombine(Context* c, TernaryOperation type,
|
|||||||
uint64_t firstRegisterMask;
|
uint64_t firstRegisterMask;
|
||||||
uint8_t secondTypeMask;
|
uint8_t secondTypeMask;
|
||||||
uint64_t secondRegisterMask;
|
uint64_t secondRegisterMask;
|
||||||
uint8_t resultTypeMask;
|
|
||||||
uint64_t resultRegisterMask;
|
|
||||||
|
|
||||||
c->arch->plan(type, firstSize, &firstTypeMask, &firstRegisterMask,
|
c->arch->planSource(type, firstSize, &firstTypeMask, &firstRegisterMask,
|
||||||
secondSize, &secondTypeMask, &secondRegisterMask,
|
secondSize, &secondTypeMask, &secondRegisterMask,
|
||||||
resultSize, &resultTypeMask, &resultRegisterMask,
|
resultSize, &thunk);
|
||||||
&thunk);
|
|
||||||
|
|
||||||
if (thunk) {
|
if (thunk) {
|
||||||
Stack* oldStack = c->stack;
|
Stack* oldStack = c->stack;
|
||||||
@ -3302,7 +3373,7 @@ appendCombine(Context* c, TernaryOperation type,
|
|||||||
c->stack = oldStack;
|
c->stack = oldStack;
|
||||||
|
|
||||||
appendCall
|
appendCall
|
||||||
(c, value(c, constantSite(c, c->client->getThunk(type, resultSize))),
|
(c, value(c, constantSite(c, c->client->getThunk(type, firstSize, resultSize))),
|
||||||
0, 0, result, resultSize, argumentStack,
|
0, 0, result, resultSize, argumentStack,
|
||||||
ceiling(secondSize, BytesPerWord) + ceiling(firstSize, BytesPerWord),
|
ceiling(secondSize, BytesPerWord) + ceiling(firstSize, BytesPerWord),
|
||||||
0);
|
0);
|
||||||
@ -3317,22 +3388,17 @@ appendCombine(Context* c, TernaryOperation type,
|
|||||||
SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex),
|
SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex),
|
||||||
SiteMask(firstTypeMask, firstRegisterMask >> 32, AnyFrameIndex),
|
SiteMask(firstTypeMask, firstRegisterMask >> 32, AnyFrameIndex),
|
||||||
SiteMask(secondTypeMask, secondRegisterMask, AnyFrameIndex),
|
SiteMask(secondTypeMask, secondRegisterMask, AnyFrameIndex),
|
||||||
SiteMask(secondTypeMask, secondRegisterMask >> 32, AnyFrameIndex),
|
SiteMask(secondTypeMask, secondRegisterMask >> 32, AnyFrameIndex)));
|
||||||
SiteMask(resultTypeMask, resultRegisterMask, AnyFrameIndex),
|
|
||||||
SiteMask(resultTypeMask, resultRegisterMask >> 32, AnyFrameIndex)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TranslateEvent: public Event {
|
class TranslateEvent: public Event {
|
||||||
public:
|
public:
|
||||||
TranslateEvent(Context* c, BinaryOperation type, unsigned size, Value* value,
|
TranslateEvent(Context* c, BinaryOperation type, unsigned size, unsigned resSize, Value* value,
|
||||||
Value* result,
|
Value* result,
|
||||||
const SiteMask& valueLowMask,
|
const SiteMask& valueLowMask,
|
||||||
const SiteMask& valueHighMask,
|
const SiteMask& valueHighMask):
|
||||||
const SiteMask& resultLowMask,
|
Event(c), type(type), size(size), resSize(resSize), value(value), result(result)
|
||||||
const SiteMask& resultHighMask):
|
|
||||||
Event(c), type(type), size(size), value(value), result(result),
|
|
||||||
resultLowMask(resultLowMask), resultHighMask(resultHighMask)
|
|
||||||
{
|
{
|
||||||
addRead(c, this, value, read(c, valueLowMask));
|
addRead(c, this, value, read(c, valueLowMask));
|
||||||
if (size > BytesPerWord) {
|
if (size > BytesPerWord) {
|
||||||
@ -3346,6 +3412,15 @@ class TranslateEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
|
uint8_t aTypeMask = value->source->type(c);
|
||||||
|
uint8_t bTypeMask;
|
||||||
|
uint64_t aRegisterMask = (registerMask(value->high) << 32) | registerMask(value);
|
||||||
|
uint64_t bRegisterMask;
|
||||||
|
|
||||||
|
c->arch->planDestination(type, size, &aTypeMask, &aRegisterMask, resSize, &bTypeMask, &bRegisterMask);
|
||||||
|
SiteMask resultLowMask(bTypeMask, bRegisterMask, AnyFrameIndex);
|
||||||
|
SiteMask resultHighMask(bTypeMask, bRegisterMask >> 32, AnyFrameIndex);
|
||||||
|
|
||||||
Site* low = getTarget(c, value, result, resultLowMask);
|
Site* low = getTarget(c, value, result, resultLowMask);
|
||||||
Site* high
|
Site* high
|
||||||
= (size > BytesPerWord
|
= (size > BytesPerWord
|
||||||
@ -3375,6 +3450,7 @@ class TranslateEvent: public Event {
|
|||||||
|
|
||||||
BinaryOperation type;
|
BinaryOperation type;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
unsigned resSize;
|
||||||
Value* value;
|
Value* value;
|
||||||
Value* result;
|
Value* result;
|
||||||
Read* resultRead;
|
Read* resultRead;
|
||||||
@ -3383,28 +3459,35 @@ class TranslateEvent: public Event {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
appendTranslate(Context* c, BinaryOperation type, unsigned size, Value* value,
|
appendTranslate(Context* c, BinaryOperation type, unsigned firstSize, Value* first,
|
||||||
Value* result)
|
unsigned resultSize, Value* result)
|
||||||
{
|
{
|
||||||
bool thunk;
|
bool thunk;
|
||||||
uint8_t firstTypeMask;
|
uint8_t firstTypeMask;
|
||||||
uint64_t firstRegisterMask;
|
uint64_t firstRegisterMask;
|
||||||
uint8_t resultTypeMask;
|
|
||||||
uint64_t resultRegisterMask;
|
|
||||||
|
|
||||||
c->arch->plan(type, size, &firstTypeMask, &firstRegisterMask,
|
c->arch->planSource(type, firstSize, &firstTypeMask, &firstRegisterMask,
|
||||||
size, &resultTypeMask, &resultRegisterMask,
|
resultSize, &thunk);
|
||||||
&thunk);
|
|
||||||
|
|
||||||
assert(c, not thunk); // todo
|
if (thunk) {
|
||||||
|
Stack* oldStack = c->stack;
|
||||||
|
|
||||||
append(c, new (c->zone->allocate(sizeof(TranslateEvent)))
|
::push(c, ceiling(firstSize, BytesPerWord), first);
|
||||||
TranslateEvent
|
|
||||||
(c, type, size, value, result,
|
Stack* argumentStack = c->stack;
|
||||||
SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex),
|
c->stack = oldStack;
|
||||||
SiteMask(firstTypeMask, firstRegisterMask >> 32, AnyFrameIndex),
|
|
||||||
SiteMask(resultTypeMask, resultRegisterMask, AnyFrameIndex),
|
appendCall
|
||||||
SiteMask(resultTypeMask, resultRegisterMask >> 32, AnyFrameIndex)));
|
(c, value(c, constantSite(c, c->client->getThunk(type, firstSize, resultSize))),
|
||||||
|
0, 0, result, resultSize, argumentStack,
|
||||||
|
ceiling(firstSize, BytesPerWord), 0);
|
||||||
|
} else {
|
||||||
|
append(c, new (c->zone->allocate(sizeof(TranslateEvent)))
|
||||||
|
TranslateEvent
|
||||||
|
(c, type, firstSize, resultSize, first, result,
|
||||||
|
SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex),
|
||||||
|
SiteMask(firstTypeMask, firstRegisterMask >> 32, AnyFrameIndex)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BarrierEvent: public Event {
|
class BarrierEvent: public Event {
|
||||||
@ -3437,9 +3520,9 @@ 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, this, base, anyRegisterRead(c));
|
addRead(c, this, base, generalRegisterRead(c));
|
||||||
if (index) {
|
if (index) {
|
||||||
addRead(c, this, index, registerOrConstantRead(c));
|
addRead(c, this, index, generalRegisterOrConstantRead(c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3617,8 +3700,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, this, object, anyRegisterRead(c));
|
addRead(c, this, object, generalRegisterRead(c));
|
||||||
addRead(c, this, index, registerOrConstantRead(c));
|
addRead(c, this, index, generalRegisterOrConstantRead(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* name() {
|
virtual const char* name() {
|
||||||
@ -4322,10 +4405,8 @@ populateSources(Context* c, Event* e)
|
|||||||
{
|
{
|
||||||
SiteRecord frozenRecords[e->readCount];
|
SiteRecord frozenRecords[e->readCount];
|
||||||
SiteRecordList frozen(frozenRecords, e->readCount);
|
SiteRecordList frozen(frozenRecords, e->readCount);
|
||||||
|
|
||||||
for (Read* r = e->reads; r; r = r->eventNext) {
|
for (Read* r = e->reads; r; r = r->eventNext) {
|
||||||
r->value->source = readSource(c, r);
|
r->value->source = readSource(c, r);
|
||||||
|
|
||||||
if (r->value->source) {
|
if (r->value->source) {
|
||||||
if (DebugReads) {
|
if (DebugReads) {
|
||||||
char buffer[256]; r->value->source->toString(c, buffer, 256);
|
char buffer[256]; r->value->source->toString(c, buffer, 256);
|
||||||
@ -5188,10 +5269,20 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void cmp(unsigned size, Operand* a, Operand* b) {
|
virtual void cmp(unsigned size, Operand* a, Operand* b) {
|
||||||
appendCompare(&c, size, static_cast<Value*>(a),
|
appendCompare(&c, Compare, size, static_cast<Value*>(a),
|
||||||
static_cast<Value*>(b));
|
static_cast<Value*>(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void fcmp(unsigned size, Operand* a, Operand* b) {
|
||||||
|
static_cast<Value*>(a)->type = ValueFloat;
|
||||||
|
static_cast<Value*>(b)->type = ValueFloat;
|
||||||
|
appendCompare(&c, FloatCompare, size, static_cast<Value*>(a),
|
||||||
|
static_cast<Value*>(b));
|
||||||
|
//static_cast<Value*>(a)->type = ValueGeneral;
|
||||||
|
//static_cast<Value*>(b)->type = ValueGeneral;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void jl(Operand* address) {
|
virtual void jl(Operand* address) {
|
||||||
appendBranch(&c, JumpIfLess, static_cast<Value*>(address));
|
appendBranch(&c, JumpIfLess, static_cast<Value*>(address));
|
||||||
}
|
}
|
||||||
@ -5216,6 +5307,10 @@ class MyCompiler: public Compiler {
|
|||||||
appendBranch(&c, JumpIfNotEqual, static_cast<Value*>(address));
|
appendBranch(&c, JumpIfNotEqual, static_cast<Value*>(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void juo(Operand* address) {
|
||||||
|
appendBranch(&c, JumpIfUnordered, static_cast<Value*>(address));
|
||||||
|
}
|
||||||
|
|
||||||
virtual void jmp(Operand* address) {
|
virtual void jmp(Operand* address) {
|
||||||
appendBranch(&c, Jump, static_cast<Value*>(address));
|
appendBranch(&c, Jump, static_cast<Value*>(address));
|
||||||
}
|
}
|
||||||
@ -5255,6 +5350,46 @@ class MyCompiler: public Compiler {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual Operand* fadd(unsigned size, Operand* a, Operand* b) {
|
||||||
|
Value* result = value(&c);
|
||||||
|
static_cast<Value*>(a)->type = static_cast<Value*>(b)->type = ValueFloat;
|
||||||
|
appendCombine(&c, FloatAdd, size, static_cast<Value*>(a),
|
||||||
|
size, static_cast<Value*>(b), size, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Operand* fsub(unsigned size, Operand* a, Operand* b) {
|
||||||
|
Value* result = value(&c);
|
||||||
|
static_cast<Value*>(a)->type = static_cast<Value*>(b)->type = ValueFloat;
|
||||||
|
appendCombine(&c, FloatSubtract, size, static_cast<Value*>(a),
|
||||||
|
size, static_cast<Value*>(b), size, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Operand* fmul(unsigned size, Operand* a, Operand* b) {
|
||||||
|
Value* result = value(&c);
|
||||||
|
static_cast<Value*>(a)->type = static_cast<Value*>(b)->type = ValueFloat;
|
||||||
|
appendCombine(&c, FloatMultiply, size, static_cast<Value*>(a),
|
||||||
|
size, static_cast<Value*>(b), size, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Operand* fdiv(unsigned size, Operand* a, Operand* b) {
|
||||||
|
Value* result = value(&c);
|
||||||
|
static_cast<Value*>(a)->type = static_cast<Value*>(b)->type = ValueFloat;
|
||||||
|
appendCombine(&c, FloatDivide, size, static_cast<Value*>(a),
|
||||||
|
size, static_cast<Value*>(b), size, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Operand* frem(unsigned size, Operand* a, Operand* b) {
|
||||||
|
Value* result = value(&c);
|
||||||
|
static_cast<Value*>(a)->type = static_cast<Value*>(b)->type = ValueFloat;
|
||||||
|
appendCombine(&c, FloatRemainder, size, static_cast<Value*>(a),
|
||||||
|
size, static_cast<Value*>(b), size, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
virtual Operand* shl(unsigned size, Operand* a, Operand* b) {
|
virtual Operand* shl(unsigned size, Operand* a, Operand* b) {
|
||||||
Value* result = value(&c);
|
Value* result = value(&c);
|
||||||
appendCombine(&c, ShiftLeft, BytesPerWord, static_cast<Value*>(a),
|
appendCombine(&c, ShiftLeft, BytesPerWord, static_cast<Value*>(a),
|
||||||
@ -5299,7 +5434,51 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
virtual Operand* neg(unsigned size, Operand* a) {
|
virtual Operand* neg(unsigned size, Operand* a) {
|
||||||
Value* result = value(&c);
|
Value* result = value(&c);
|
||||||
appendTranslate(&c, Negate, size, static_cast<Value*>(a), result);
|
appendTranslate(&c, Negate, size, static_cast<Value*>(a), size, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Operand* fneg(unsigned size, Operand* a) {
|
||||||
|
Value* result = value(&c);
|
||||||
|
static_cast<Value*>(a)->type = ValueFloat;
|
||||||
|
appendTranslate(&c, FloatNegate, size, static_cast<Value*>(a), size, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Operand* operation(BinaryOperation op, unsigned aSize, unsigned resSize, Operand* a) {
|
||||||
|
Value* result = value(&c);
|
||||||
|
static_cast<Value*>(a)->type = ValueFloat;
|
||||||
|
appendTranslate(&c, op, aSize, static_cast<Value*>(a), resSize, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Operand* operation(TernaryOperation op, unsigned aSize, unsigned bSize, unsigned resSize, Operand* a, Operand* b) {
|
||||||
|
Value* result = value(&c);
|
||||||
|
static_cast<Value*>(a)->type = static_cast<Value*>(b)->type = ValueFloat;
|
||||||
|
appendCombine(&c, op, aSize, static_cast<Value*>(a),
|
||||||
|
bSize, static_cast<Value*>(b), resSize, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Operand* f2f(unsigned aSize, unsigned resSize, Operand* a) {
|
||||||
|
Value* result = value(&c);
|
||||||
|
static_cast<Value*>(a)->type = ValueFloat;
|
||||||
|
appendTranslate(&c, Float2Float, aSize, static_cast<Value*>(a), resSize, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Operand* f2i(unsigned aSize, unsigned resSize, Operand* a) {
|
||||||
|
Value* result = value(&c);
|
||||||
|
static_cast<Value*>(a)->type = ValueFloat;
|
||||||
|
appendTranslate(&c, Float2Int, aSize, static_cast<Value*>(a), resSize, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Operand* i2f(unsigned aSize, unsigned resSize, Operand* a) {
|
||||||
|
Value* result = value(&c);
|
||||||
|
//result->type = ValueFloat;
|
||||||
|
appendTranslate(&c, Int2Float, aSize, static_cast<Value*>(a), resSize, result);
|
||||||
|
//result->type = ValueGeneral;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user