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