more bugfixes for handling 64-bit floats on 32-bit systems

This commit is contained in:
Joel Dice 2009-11-30 22:08:59 +00:00
parent 851187f0ce
commit 7fa10909f4

View File

@ -1476,12 +1476,19 @@ pickTarget(Context* c, Read* read, bool intersectRead,
Value* value = read->value;
uint32_t registerMask = (value->type == ValueGeneral
? c->arch->generalRegisterMask() : ~0);
uint32_t registerMask
= (value->type == ValueFloat ? ~0 : c->arch->generalRegisterMask());
SiteMask mask(~0, registerMask, AnyFrameIndex);
read->intersect(&mask);
if (value->type == ValueFloat) {
uint32_t floatMask = mask.registerMask & c->arch->floatRegisterMask();
if (floatMask) {
mask.registerMask = floatMask;
}
}
Target best;
Value* successor = read->successor();
@ -1792,8 +1799,21 @@ class RegisterSite: public Site {
}
virtual bool matchNextWord(Context* c, Site* s, unsigned) {
return s->type(c) == RegisterOperand
and s->registerSize(c) == BytesPerWord;
assert(c, number != NoRegister);
if (s->type(c) != RegisterOperand) {
return false;
}
RegisterSite* rs = static_cast<RegisterSite*>(s);
unsigned size = rs->registerSize(c);
if (size > BytesPerWord) {
assert(c, number != NoRegister);
return number == rs->number;
} else {
uint32_t mask = c->arch->generalRegisterMask();
return ((1 << number) & mask) and ((1 << rs->number) & mask);
}
}
virtual void acquire(Context* c, Value* v) {
@ -1876,6 +1896,9 @@ class RegisterSite: public Site {
}
virtual Site* makeNextWord(Context* c, unsigned) {
assert(c, number != NoRegister);
assert(c, ((1 << number) & c->arch->generalRegisterMask()));
return freeRegisterSite(c, c->arch->generalRegisterMask());
}
@ -1883,8 +1906,16 @@ class RegisterSite: public Site {
return SiteMask(1 << RegisterOperand, mask_, NoFrameIndex);
}
virtual SiteMask nextWordMask(Context*, unsigned) {
return SiteMask(1 << RegisterOperand, ~0, NoFrameIndex);
virtual SiteMask nextWordMask(Context* c, unsigned) {
assert(c, number != NoRegister);
if (registerSize(c) > BytesPerWord) {
return SiteMask
(1 << RegisterOperand, number, NoFrameIndex);
} else {
return SiteMask
(1 << RegisterOperand, c->arch->generalRegisterMask(), NoFrameIndex);
}
}
virtual unsigned registerSize(Context* c) {
@ -1965,12 +1996,14 @@ class MemorySite: public Site {
assert(c, acquired);
if (mask.typeMask & (1 << MemoryOperand)) {
if (base == c->arch->stack()) {
assert(c, index == NoRegister);
return mask.frameIndex == AnyFrameIndex
or (mask.frameIndex != NoFrameIndex
and static_cast<int>(frameIndexToOffset(c, mask.frameIndex))
== offset);
if (mask.frameIndex >= 0) {
if (base == c->arch->stack()) {
assert(c, index == NoRegister);
return static_cast<int>(frameIndexToOffset(c, mask.frameIndex))
== offset;
} else {
return false;
}
} else {
return true;
}
@ -3533,22 +3566,51 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize,
}
}
void
pickSiteOrMove(Context* c, Value* src, Value* dst)
Site*
pickMatchOrMove(Context* c, Read* r, Site* nextWord, unsigned index,
bool intersectRead)
{
Site* s = pickSite(c, r->value, nextWord, index, true);
SiteMask mask;
if (intersectRead) {
r->intersect(&mask);
}
if (s and s->match(c, mask)) {
return s;
}
return pickSiteOrMove
(c, r->value, intersect(mask, nextWord->nextWordMask(c, index)),
true, true);
}
Site*
pickSiteOrMove(Context* c, Value* src, Value* dst, Site* nextWord,
unsigned index)
{
if (live(dst)) {
Read* read = live(src);
Site* s = pickSourceSite(c, read, 0, 0, ~0, false, true, true);
Site* s;
if (nextWord) {
s = pickMatchOrMove(c, read, nextWord, index, false);
} else {
s = pickSourceSite(c, read, 0, 0, ~0, false, true, true);
if (s == 0 or s->isVolatile(c)) {
maybeMove(c, read, false, true);
if (s == 0 or s->isVolatile(c)) {
s = maybeMove(c, read, false, true);
}
}
assert(c, s);
addBuddy(src, dst);
if (src->source->isVolatile(c)) {
removeSite(c, src, src->source);
}
return s;
} else {
return 0;
}
}
@ -3645,6 +3707,13 @@ class MoveEvent: public Event {
{
apply(c, Move, srcSelectSize, src->source, src->source,
dstSize, dst->target, dst->target);
if (live(dst) == 0) {
removeSite(c, dst, dst->target);
if (dstSize > BytesPerWord) {
removeSite(c, dst->nextWord, dst->nextWord->target);
}
}
} else {
maybeMove(c, Move, BytesPerWord, BytesPerWord, src,
BytesPerWord, dst, dstLowMask);
@ -3654,9 +3723,9 @@ class MoveEvent: public Event {
}
}
} else {
pickSiteOrMove(c, src, dst);
Site* low = pickSiteOrMove(c, src, dst, 0, 0);
if (dstSize > BytesPerWord) {
pickSiteOrMove(c, src->nextWord, dst->nextWord);
pickSiteOrMove(c, src->nextWord, dst->nextWord, low, 1);
}
}
} else if (srcSelectSize <= BytesPerWord and dstSize <= BytesPerWord) {
@ -3714,7 +3783,7 @@ class MoveEvent: public Event {
low->thaw(c, dst);
} else {
pickSiteOrMove(c, src, dst);
pickSiteOrMove(c, src, dst, 0, 0);
}
}
@ -5065,16 +5134,7 @@ readSource(Context* c, Read* r)
Value* high = r->high(c);
if (high) {
Site* s = pickSite(c, r->value, high->source, 0, true);
SiteMask mask;
r->intersect(&mask);
if (s and s->match(c, mask)) {
return s;
} else {
return pickSiteOrMove
(c, r->value, intersect(mask, high->source->nextWordMask(c, 0)),
true, true);
}
return pickMatchOrMove(c, r, high->source, 0, true);
} else {
return pickSiteOrMove(c, r, true, true);
}