added floating point support, split plan method

This commit is contained in:
Josh warner 2009-08-06 10:14:31 -06:00
parent 7483fa154d
commit 53c0656ee7

View File

@ -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,20 +964,41 @@ 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) {
@ -2949,6 +3014,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
@ -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));
} }
@ -5215,6 +5306,10 @@ class MyCompiler: public Compiler {
virtual void jne(Operand* address) { virtual void jne(Operand* address) {
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;
} }