refactor code responsible for moving data in the compiler

This is partially to address incorrect code generation for 64-bit
floating-point values on x86_32 and partially to reduce unnecessary
moves.
This commit is contained in:
Joel Dice 2009-11-27 21:15:12 -07:00
parent bd72745ff9
commit 5ead8fab17
7 changed files with 414 additions and 337 deletions

View File

@ -361,10 +361,9 @@ class Assembler {
unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask) = 0;
virtual void planMove
(unsigned size,
uint8_t srcTypeMask, uint64_t srcRegisterMask,
uint8_t dstTypeMask, uint64_t dstRegisterMask,
uint8_t* tmpTypeMask, uint64_t* tmpRegisterMask) = 0;
(unsigned size, uint8_t* srcTypeMask, uint64_t* srcRegisterMask,
uint8_t* tmpTypeMask, uint64_t* tmpRegisterMask,
uint8_t dstTypeMask, uint64_t dstRegisterMask) = 0;
virtual void planSource
(TernaryOperation op,

View File

@ -133,12 +133,16 @@ class Site {
virtual Site* makeNextWord(Context*, unsigned) = 0;
virtual SiteMask mask(Context*) = 0;
virtual SiteMask nextWordMask(Context*, unsigned) = 0;
virtual unsigned registerSize(Context*) { return BytesPerWord; }
virtual unsigned registerMask(Context*) { return 0; }
virtual bool isVolatile(Context*) { return false; }
Site* next;
};
@ -1091,6 +1095,23 @@ buddies(Value* a, Value* b)
return false;
}
void
addBuddy(Value* original, Value* buddy)
{
buddy->buddy = original;
Value* p = original;
while (p->buddy != original) p = p->buddy;
p->buddy = buddy;
if (DebugBuddies) {
fprintf(stderr, "add buddy %p to", buddy);
for (Value* p = buddy->buddy; p != buddy; p = p->buddy) {
fprintf(stderr, " %p", p);
}
fprintf(stderr, "\n");
}
}
void
decrementAvailableGeneralRegisterCount(Context* c)
{
@ -1582,6 +1603,10 @@ class ConstantSite: public Site {
abort(c);
}
virtual SiteMask mask(Context*) {
return SiteMask(1 << ConstantOperand, 0, NoFrameIndex);
}
virtual SiteMask nextWordMask(Context*, unsigned) {
return SiteMask(1 << ConstantOperand, 0, NoFrameIndex);
}
@ -1668,6 +1693,10 @@ class AddressSite: public Site {
abort(c);
}
virtual SiteMask mask(Context*) {
return SiteMask(1 << AddressOperand, 0, NoFrameIndex);
}
virtual SiteMask nextWordMask(Context* c, unsigned) {
abort(c);
}
@ -1687,7 +1716,7 @@ freeRegisterSite(Context* c, uint32_t mask);
class RegisterSite: public Site {
public:
RegisterSite(uint32_t mask, int number):
mask(mask), number(number)
mask_(mask), number(number)
{ }
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) {
@ -1695,7 +1724,7 @@ class RegisterSite: public Site {
return vm::snprintf(buffer, bufferSize, "%p register %d", this, number);
} else {
return vm::snprintf(buffer, bufferSize,
"%p register unacquired (mask %d)", this, mask);
"%p register unacquired (mask %d)", this, mask_);
}
}
@ -1705,7 +1734,7 @@ class RegisterSite: public Site {
if (s and
(this == s or
(s->type(c) == RegisterOperand
and (static_cast<RegisterSite*>(s)->mask & (1 << number)))))
and (static_cast<RegisterSite*>(s)->mask_ & (1 << number)))))
{
return 0;
} else {
@ -1743,7 +1772,7 @@ class RegisterSite: public Site {
if (number != NoRegister) {
target = Target(number, RegisterOperand, 0);
} else {
target = pickRegisterTarget(c, v, mask);
target = pickRegisterTarget(c, v, mask_);
expect(c, target.cost < Target::Impossible);
}
@ -1803,7 +1832,7 @@ class RegisterSite: public Site {
if (number != NoRegister) {
mask = 1 << number;
} else {
mask = this->mask;
mask = mask_;
}
return freeRegisterSite(c, mask);
@ -1821,6 +1850,10 @@ class RegisterSite: public Site {
return freeRegisterSite(c, c->arch->generalRegisterMask());
}
virtual SiteMask mask(Context* c UNUSED) {
return SiteMask(1 << RegisterOperand, mask_, NoFrameIndex);
}
virtual SiteMask nextWordMask(Context*, unsigned) {
return SiteMask(1 << RegisterOperand, ~0, NoFrameIndex);
}
@ -1841,7 +1874,7 @@ class RegisterSite: public Site {
return 1 << number;
}
uint32_t mask;
uint32_t mask_;
int number;
};
@ -2059,6 +2092,11 @@ class MemorySite: public Site {
this->index, scale);
}
virtual SiteMask mask(Context* c) {
return SiteMask(1 << MemoryOperand, 0, (base == c->arch->stack())
? offsetToFrameIndex(c, offset) : NoFrameIndex);
}
virtual SiteMask nextWordMask(Context* c, unsigned index) {
// todo: endianness?
int frameIndex;
@ -2072,6 +2110,10 @@ class MemorySite: public Site {
return SiteMask(1 << MemoryOperand, 0, frameIndex);
}
virtual bool isVolatile(Context* c) {
return base != c->arch->stack();
}
bool acquired;
int base;
int offset;
@ -2155,74 +2197,6 @@ pickTargetSite(Context* c, Read* read, bool intersectRead = false,
}
}
void
steal(Context* c, Resource* r, Value* thief)
{
if (DebugResources) {
char resourceBuffer[256]; r->toString(c, resourceBuffer, 256);
char siteBuffer[1024]; sitesToString(c, r->value, siteBuffer, 1024);
fprintf(stderr, "%p steal %s from %p (%s)\n",
thief, resourceBuffer, r->value, siteBuffer);
}
if ((not (thief and buddies(thief, r->value))
and uniqueSite(c, r->value, r->site)))
{
r->site->freeze(c, r->value);
move(c, r->value, r->site, pickTargetSite
(c, live(r->value), false, StealRegisterReserveCount));
r->site->thaw(c, r->value);
}
removeSite(c, r->value, r->site);
}
void
acquire(Context* c, Resource* resource, Value* value, Site* site)
{
assert(c, value);
assert(c, site);
if (not resource->reserved) {
if (DebugResources) {
char buffer[256]; resource->toString(c, buffer, 256);
fprintf(stderr, "%p acquire %s\n", value, buffer);
}
if (resource->value) {
assert(c, findSite(c, resource->value, resource->site));
assert(c, not findSite(c, value, resource->site));
steal(c, resource, value);
}
resource->value = value;
resource->site = site;
}
}
void
release(Context* c, Resource* resource, Value* value UNUSED, Site* site UNUSED)
{
if (not resource->reserved) {
if (DebugResources) {
char buffer[256]; resource->toString(c, buffer, 256);
fprintf(stderr, "%p release %s\n", resource->value, buffer);
}
assert(c, resource->value);
assert(c, resource->site);
assert(c, buddies(resource->value, value));
assert(c, site == resource->site);
resource->value = 0;
resource->site = 0;
}
}
class SingleRead: public Read {
public:
SingleRead(const SiteMask& mask, Value* successor):
@ -2274,6 +2248,212 @@ read(Context* c, const SiteMask& mask, Value* successor = 0)
SingleRead(mask, successor);
}
bool
acceptMatch(Context* c, Site* s, Read*, const SiteMask& mask)
{
return s->match(c, mask);
}
Site*
pickSourceSite(Context* c, Read* read, Site* target = 0,
unsigned* cost = 0, uint8_t typeMask = ~0,
bool intersectRead = true, bool includeBuddies = true,
bool includeNextWord = true,
bool (*accept)(Context*, Site*, Read*, const SiteMask&)
= acceptMatch)
{
SiteMask mask(typeMask, ~0, AnyFrameIndex);
if (intersectRead) {
read->intersect(&mask);
}
Site* site = 0;
unsigned copyCost = 0xFFFFFFFF;
for (SiteIterator it(c, read->value, includeBuddies, includeNextWord);
it.hasMore();)
{
Site* s = it.next();
if (accept(c, s, read, mask)) {
unsigned v = s->copyCost(c, target);
if (v < copyCost) {
site = s;
copyCost = v;
}
}
}
if (DebugMoves and site and target) {
char srcb[256]; site->toString(c, srcb, 256);
char dstb[256]; target->toString(c, dstb, 256);
fprintf(stderr, "pick source %s to %s for %p cost %d\n",
srcb, dstb, read->value, copyCost);
}
if (cost) *cost = copyCost;
return site;
}
Site*
maybeMove(Context* c, Read* read, bool intersectRead, bool includeNextWord,
unsigned registerReserveCount = 0)
{
Site* dst = pickTargetSite(c, read, intersectRead, registerReserveCount);
Value* value = read->value;
unsigned size = value == value->nextWord ? BytesPerWord : 8;
uint8_t srcTypeMask;
uint64_t srcRegisterMask;
uint8_t tmpTypeMask;
uint64_t tmpRegisterMask;
c->arch->planMove
(size, &srcTypeMask, &srcRegisterMask,
&tmpTypeMask, &tmpRegisterMask,
1 << dst->type(c), dst->registerMask(c));
SiteMask srcMask(srcTypeMask, srcRegisterMask, AnyFrameIndex);
SingleRead srcRead(srcMask, 0);
srcRead.value = value;
unsigned cost;
Site* src = pickSourceSite
(c, &srcRead, dst, &cost, ~0, true, true, includeNextWord);
if (src == 0 or cost) {
unsigned cost2;
Site* src2 = pickSourceSite
(c, &srcRead, dst, &cost2, ~0, false, true, includeNextWord);
if (src == 0 or cost2 == 0) {
src = src2;
cost = cost2;
}
}
if (cost) {
if (not src->match(c, srcMask)) {
src->freeze(c, value);
dst->freeze(c, value);
SiteMask tmpMask(tmpTypeMask, tmpRegisterMask, AnyFrameIndex);
SingleRead tmpRead(tmpMask, 0);
tmpRead.value = value;
Site* tmp = pickTargetSite(c, &tmpRead, true);
move(c, value, src, tmp);
dst->thaw(c, value);
src->thaw(c, value);
src = tmp;
}
move(c, value, src, dst);
}
return dst;
}
Site*
pickSiteOrMove(Context* c, Read* read, bool intersectRead,
bool includeNextWord, unsigned registerReserveCount = 0)
{
Site* s = pickSourceSite
(c, read, 0, 0, ~0, intersectRead, true, includeNextWord);
if (s) {
return s;
} else {
return maybeMove
(c, read, intersectRead, includeNextWord, registerReserveCount);
}
}
Site*
pickSiteOrMove(Context* c, Value* v, const SiteMask& mask, bool intersectMask,
bool includeNextWord, unsigned registerReserveCount = 0)
{
SingleRead read(mask, 0);
read.value = v;
return pickSiteOrMove
(c, &read, intersectMask, includeNextWord, registerReserveCount);
}
Site*
pickSiteOrMove(Context* c, Value* v, Site* s, unsigned index)
{
return pickSiteOrMove(c, v, s->nextWordMask(c, index), true, false);
}
void
steal(Context* c, Resource* r, Value* thief)
{
if (DebugResources) {
char resourceBuffer[256]; r->toString(c, resourceBuffer, 256);
char siteBuffer[1024]; sitesToString(c, r->value, siteBuffer, 1024);
fprintf(stderr, "%p steal %s from %p (%s)\n",
thief, resourceBuffer, r->value, siteBuffer);
}
if ((not (thief and buddies(thief, r->value))
and uniqueSite(c, r->value, r->site)))
{
r->site->freeze(c, r->value);
maybeMove(c, live(r->value), false, true, StealRegisterReserveCount);
r->site->thaw(c, r->value);
}
removeSite(c, r->value, r->site);
}
void
acquire(Context* c, Resource* resource, Value* value, Site* site)
{
assert(c, value);
assert(c, site);
if (not resource->reserved) {
if (DebugResources) {
char buffer[256]; resource->toString(c, buffer, 256);
fprintf(stderr, "%p acquire %s\n", value, buffer);
}
if (resource->value) {
assert(c, findSite(c, resource->value, resource->site));
assert(c, not findSite(c, value, resource->site));
steal(c, resource, value);
}
resource->value = value;
resource->site = site;
}
}
void
release(Context* c, Resource* resource, Value* value UNUSED, Site* site UNUSED)
{
if (not resource->reserved) {
if (DebugResources) {
char buffer[256]; resource->toString(c, buffer, 256);
fprintf(stderr, "%p release %s\n", resource->value, buffer);
}
assert(c, resource->value);
assert(c, resource->site);
assert(c, buddies(resource->value, value));
assert(c, site == resource->site);
resource->value = 0;
resource->site = 0;
}
}
SiteMask
generalRegisterMask(Context* c)
{
@ -2463,47 +2643,21 @@ pickSite(Context* c, Value* v, Site* s, unsigned index)
}
Site*
pickOrMoveSite(Context* c, Value* v, Site* s, unsigned index)
{
Site* n = pickSite(c, v, s, index);
if (n) {
return n;
}
n = s->makeNextWord(c, index);
Site* src = 0;
unsigned copyCost = 0xFFFFFFFF;
for (SiteIterator it(c, v, true, false); it.hasMore();) {
Site* candidate = it.next();
unsigned cost = candidate->copyCost(c, n);
if (cost < copyCost) {
src = candidate;
copyCost = cost;
}
}
move(c, v, src, n);
return n;
}
Site*
pickOrMoveSite(Context* c, Value* v, Site* s, Site** low, Site** high)
pickSiteOrMove(Context* c, Value* v, Site* s, Site** low, Site** high)
{
if (v->wordIndex == 0) {
*low = s;
*high = pickOrMoveSite(c, v->nextWord, s, 1);
*high = pickSiteOrMove(c, v->nextWord, s, 1);
return *high;
} else {
*low = pickOrMoveSite(c, v->nextWord, s, 0);
*low = pickSiteOrMove(c, v->nextWord, s, 0);
*high = s;
return *low;
}
}
Site*
pickOrGrowSite(Context* c, Value* v, Site* s, unsigned index)
pickSiteOrGrow(Context* c, Value* v, Site* s, unsigned index)
{
Site* n = pickSite(c, v, s, index);
if (n) {
@ -2516,25 +2670,19 @@ pickOrGrowSite(Context* c, Value* v, Site* s, unsigned index)
}
Site*
pickOrGrowSite(Context* c, Value* v, Site* s, Site** low, Site** high)
pickSiteOrGrow(Context* c, Value* v, Site* s, Site** low, Site** high)
{
if (v->wordIndex == 0) {
*low = s;
*high = pickOrGrowSite(c, v->nextWord, s, 1);
*high = pickSiteOrGrow(c, v->nextWord, s, 1);
return *high;
} else {
*low = pickOrGrowSite(c, v->nextWord, s, 0);
*low = pickSiteOrGrow(c, v->nextWord, s, 0);
*high = s;
return *low;
}
}
bool
acceptMatch(Context* c, Site* s, Read*, const SiteMask& mask)
{
return s->match(c, mask);
}
bool
isHome(Value* v, int frameIndex)
{
@ -2566,97 +2714,20 @@ acceptForResolve(Context* c, Site* s, Read* read, const SiteMask& mask)
}
}
Site*
pickSourceSite(Context* c, Read* read, Site* target = 0,
unsigned* cost = 0, uint8_t typeMask = ~0,
bool intersectRead = true, bool includeBuddies = true,
bool (*accept)(Context*, Site*, Read*, const SiteMask&)
= acceptMatch)
{
SiteMask mask(typeMask, ~0, AnyFrameIndex);
if (intersectRead) {
read->intersect(&mask);
}
Site* site = 0;
unsigned copyCost = 0xFFFFFFFF;
for (SiteIterator it(c, read->value, includeBuddies); it.hasMore();) {
Site* s = it.next();
if (accept(c, s, read, mask)) {
unsigned v = s->copyCost(c, target);
if (v < copyCost) {
site = s;
copyCost = v;
}
}
}
if (DebugMoves and site and target) {
char srcb[256]; site->toString(c, srcb, 256);
char dstb[256]; target->toString(c, dstb, 256);
fprintf(stderr, "pick source %s to %s for %p cost %d\n",
srcb, dstb, read->value, copyCost);
}
if (cost) *cost = copyCost;
return site;
}
void
move(Context* c, Value* value, Site* src, Site* dst)
{
if (DebugMoves) {
char srcb[256]; src->toString(c, srcb, 256);
char dstb[256]; dst->toString(c, dstb, 256);
fprintf(stderr, "move %s to %s for %p to %p\n",
srcb, dstb, value, value);
}
src->freeze(c, value);
addSite(c, value, dst);
src->thaw(c, value);
uint8_t tmpTypeMask;
uint64_t tmpRegisterMask;
c->arch->planMove
(value->nextWord == value ? BytesPerWord : 8,
1 << src->type(c), src->registerMask(c),
1 << dst->type(c), dst->registerMask(c),
&tmpTypeMask, &tmpRegisterMask);
SiteMask mask(tmpTypeMask, tmpRegisterMask, AnyFrameIndex);
if (not src->match(c, mask)) {
// we can't move directly from src to dst on this architecture, so
// we need to either pick a difference source or use a temporary
removeSite(c, value, dst);
SingleRead read(mask, 0);
read.value = value;
Site* newSrc = pickSourceSite(c, &read);
if (newSrc) {
src = newSrc;
} else {
src->freeze(c, value);
dst->freeze(c, value);
Site* tmp = pickTargetSite(c, &read, true);
move(c, value, src, tmp);
dst->thaw(c, value);
src->thaw(c, value);
src = tmp;
}
addSite(c, value, dst);
}
if (DebugMoves) {
char srcb[256]; src->toString(c, srcb, 256);
char dstb[256]; dst->toString(c, dstb, 256);
fprintf(stderr, "move %s to %s for %p\n", srcb, dstb, value);
}
src->freeze(c, value);
dst->freeze(c, value);
unsigned srcSize;
@ -2672,14 +2743,14 @@ move(Context* c, Value* value, Site* src, Site* dst)
if (srcSize == dstSize) {
apply(c, Move, srcSize, src, src, dstSize, dst, dst);
} else if (srcSize > BytesPerWord) {
Site* low, *high, *other = pickOrGrowSite(c, value, dst, &low, &high);
Site* low, *high, *other = pickSiteOrGrow(c, value, dst, &low, &high);
other->freeze(c, value->nextWord);
apply(c, Move, srcSize, src, src, srcSize, low, high);
other->thaw(c, value->nextWord);
} else {
Site* low, *high, *other = pickOrMoveSite(c, value, src, &low, &high);
Site* low, *high, *other = pickSiteOrMove(c, value, src, &low, &high);
other->freeze(c, value->nextWord);
apply(c, Move, dstSize, low, high, dstSize, dst, dst);
@ -3228,24 +3299,6 @@ appendReturn(Context* c, unsigned size, Value* value)
ReturnEvent(c, size, value));
}
void
addBuddy(Value* original, Value* buddy)
{
buddy->buddy = original;
Value* p = original;
while (p->buddy != original) p = p->buddy;
p->buddy = buddy;
//buddy->type = original->type;
if (DebugBuddies) {
fprintf(stderr, "add buddy %p to", buddy);
for (Value* p = buddy->buddy; p != buddy; p = p->buddy) {
fprintf(stderr, " %p", p);
}
fprintf(stderr, "\n");
}
}
void
maybeMove(Context* c, BinaryOperation type, unsigned srcSize,
unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst,
@ -3375,11 +3428,6 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize,
} else {
target = src->source;
assert(c, src);
assert(c, dst);
addBuddy(src, dst);
if (DebugMoves) {
char dstb[256]; target->toString(c, dstb, 256);
fprintf(stderr, "null move in %s for %p to %p\n", dstb, src, dst);
@ -3391,6 +3439,19 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize,
}
}
void
maybeMove(Context* c, Value* src, Value* dst)
{
if (live(dst)) {
maybeMove(c, live(src), false, true);
addBuddy(src, dst);
if (src->source->isVolatile(c)) {
removeSite(c, src, src->source);
}
}
}
Value*
value(Context* c, ValueType type, Site* site = 0, Site* target = 0)
{
@ -3474,19 +3535,26 @@ class MoveEvent: public Event {
SiteMask dstLowMask(dstTypeMask, dstRegisterMask, AnyFrameIndex);
SiteMask dstHighMask(dstTypeMask, dstRegisterMask >> 32, AnyFrameIndex);
if (srcSelectSize <= BytesPerWord and dstSize <= BytesPerWord) {
if (srcSelectSize >= BytesPerWord
and dstSize >= BytesPerWord
and srcSelectSize >= dstSize)
{
if (dst->target) {
maybeMove(c, Move, BytesPerWord, BytesPerWord, src, BytesPerWord, dst,
dstLowMask);
if (dstSize > BytesPerWord) {
maybeMove(c, Move, BytesPerWord, BytesPerWord, src->nextWord,
BytesPerWord, dst->nextWord, dstHighMask);
}
} else {
maybeMove(c, src, dst);
if (dstSize > BytesPerWord) {
maybeMove(c, src->nextWord, dst->nextWord);
}
}
} else if (srcSelectSize <= BytesPerWord and dstSize <= BytesPerWord) {
maybeMove(c, type, srcSize, srcSelectSize, src, dstSize, dst,
dstLowMask);
} else if (srcSelectSize == dstSize) {
maybeMove(c, Move, BytesPerWord, BytesPerWord, src, BytesPerWord, dst,
dstLowMask);
maybeMove(c, Move, BytesPerWord, BytesPerWord, src->nextWord,
BytesPerWord, dst->nextWord, dstHighMask);
} else if (srcSize > BytesPerWord) {
assert(c, dstSize == BytesPerWord);
maybeMove(c, Move, BytesPerWord, BytesPerWord, src, BytesPerWord, dst,
dstLowMask);
} else {
assert(c, srcSize == BytesPerWord);
assert(c, srcSelectSize == BytesPerWord);
@ -3539,8 +3607,7 @@ class MoveEvent: public Event {
low->thaw(c, dst);
} else {
maybeMove(c, Move, BytesPerWord, BytesPerWord, src, BytesPerWord, dst,
dstLowMask);
maybeMove(c, src, dst);
}
}
@ -3590,11 +3657,11 @@ findConstantSite(Context* c, Value* v)
}
void
preserve(Context* c, Value* v, Site* s, Read* r)
preserve(Context* c, Value* v, Read* r, Site* s)
{
s->freeze(c, v);
move(c, v, s, pickTargetSite(c, r));
maybeMove(c, r, false, true, 0);
s->thaw(c, v);
}
@ -3613,7 +3680,7 @@ getTarget(Context* c, Value* value, Value* result, const SiteMask& resultMask)
s = value->source;
v = value;
if (r and uniqueSite(c, v, s)) {
preserve(c, v, s, r);
preserve(c, v, r, s);
}
} else {
SingleRead r(resultMask, 0);
@ -4723,7 +4790,10 @@ class BuddyEvent: public Event {
}
virtual void compile(Context* c) {
// fprintf(stderr, "original %p buddy %p\n", original, buddy);
if (DebugBuddies) {
fprintf(stderr, "original %p buddy %p\n", original, buddy);
}
assert(c, hasSite(c, original));
assert(c, original);
@ -4887,18 +4957,7 @@ readSource(Context* c, Read* r)
r->maybeIntersectWithHighSource(c);
Site* site = pickSourceSite(c, r);
if (site) {
return site;
} else {
Site* target = pickTargetSite(c, r, true);
unsigned copyCost;
site = pickSourceSite(c, r, target, &copyCost, ~0, false);
assert(c, copyCost);
move(c, v, site, target);
return target;
}
return pickSiteOrMove(c, r, true, true);
}
void
@ -4974,33 +5033,6 @@ thaw(Context* c, SiteRecordList* frozen)
}
}
Site*
acquireSite(Context* c, SiteRecordList* frozen, Site* target, Value* v,
Read* r, bool pickSource)
{
assert(c, hasSite(c, v));
unsigned copyCost;
Site* source;
if (pickSource) {
source = pickSourceSite(c, r, target, &copyCost, ~0, false);
} else {
copyCost = 0;
source = target;
}
if (copyCost) {
target = target->copy(c);
move(c, v, source, target);
} else {
target = source;
}
freeze(c, frozen, target, v);
return target;
}
bool
resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen,
Site** sites)
@ -5023,7 +5055,10 @@ resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen,
buffer, v, el.localIndex, frameIndex(c, &el));
}
acquireSite(c, frozen, s, v, r, true);
Site* target = pickSiteOrMove
(c, v, s->mask(c), true, true, ResolveRegisterReserveCount);
freeze(c, frozen, target, v);
} else {
complete = false;
}
@ -5058,9 +5093,10 @@ resolveSourceSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites)
const uint32_t mask = (1 << RegisterOperand) | (1 << MemoryOperand);
Site* s = pickSourceSite
(c, r, 0, 0, mask, true, false, acceptForResolve);
(c, r, 0, 0, mask, true, false, true, acceptForResolve);
if (s == 0) {
s = pickSourceSite(c, r, 0, 0, mask, false, false, acceptForResolve);
s = pickSourceSite
(c, r, 0, 0, mask, false, false, true, acceptForResolve);
}
if (s) {
@ -5070,7 +5106,9 @@ resolveSourceSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites)
buffer, v, el.localIndex, frameIndex(c, &el));
}
sites[el.localIndex] = acquireSite(c, frozen, s, v, r, false)->copy(c);
freeze(c, frozen, s, v);
sites[el.localIndex] = s->copy(c);
} else {
complete = false;
}
@ -5091,25 +5129,25 @@ resolveTargetSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites)
if (r and sites[el.localIndex] == 0) {
const uint32_t mask = (1 << RegisterOperand) | (1 << MemoryOperand);
bool useTarget = false;
Site* s = pickSourceSite(c, r, 0, 0, mask, true, true, acceptForResolve);
Site* s = pickSourceSite
(c, r, 0, 0, mask, true, true, true, acceptForResolve);
if (s == 0) {
s = pickSourceSite(c, r, 0, 0, mask, false, true, acceptForResolve);
s = pickSourceSite
(c, r, 0, 0, mask, false, true, true, acceptForResolve);
if (s == 0) {
s = pickTargetSite(c, r, false, ResolveRegisterReserveCount);
useTarget = true;
s = maybeMove(c, r, false, true, ResolveRegisterReserveCount);
}
}
freeze(c, frozen, s, v);
sites[el.localIndex] = s->copy(c);
if (DebugControl) {
char buffer[256]; s->toString(c, buffer, 256);
char buffer[256]; sites[el.localIndex]->toString(c, buffer, 256);
fprintf(stderr, "resolve target %s for %p local %d frame %d\n",
buffer, el.value, el.localIndex, frameIndex(c, &el));
}
Site* acquired = acquireSite(c, frozen, s, v, r, useTarget)->copy(c);
sites[el.localIndex] = (useTarget ? s : acquired->copy(c));
}
}
}

View File

@ -2169,10 +2169,7 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
System* s = makeSystem(crashDumpDirectory);
Heap* h = makeHeap(s, heapLimit);
Finder* f = makeFinder(s, RUNTIME_ARRAY_BODY(classpathBuffer), bootLibrary);
Processor* p = makeProcessor(s, h, false); // change back to true
// once use of SSE is
// fixed on 32-bit
// systems
Processor* p = makeProcessor(s, h, true);
const char** properties = static_cast<const char**>
(h->allocate(sizeof(const char*) * propertyCount));

View File

@ -2096,19 +2096,20 @@ class MyArchitecture: public Assembler::Architecture {
}
virtual void planMove
(unsigned,
uint8_t srcTypeMask, uint64_t srcRegisterMask,
uint8_t dstTypeMask, uint64_t,
uint8_t* tmpTypeMask, uint64_t* tmpRegisterMask)
(unsigned size, uint8_t* srcTypeMask, uint64_t* srcRegisterMask,
uint8_t* tmpTypeMask, uint64_t* tmpRegisterMask,
uint8_t dstTypeMask, uint64_t dstRegisterMask)
{
*tmpTypeMask = srcTypeMask;
*tmpRegisterMask = srcRegisterMask;
*srcTypeMask = ~0;
*srcRegisterMask = ~static_cast<uint64_t>(0);
if ((dstTypeMask & (1 << MemoryOperand))
and (srcTypeMask & ((1 << MemoryOperand) | 1 << AddressOperand)))
{
// can't move directly from memory to memory
*tmpTypeMask = (1 << RegisterOperand);
*tmpTypeMask = 0;
*tmpRegisterMask = 0;
if (dstTypeMask & (1 << MemoryOperand)) {
// can't move directly from memory or constant to memory
*srcTypeMask = 1 << RegisterOperand;
*tmpTypeMask = 1 << RegisterOperand;
*tmpRegisterMask = ~static_cast<uint64_t>(0);
}
}

View File

@ -2921,7 +2921,7 @@ class MyArchitecture: public Assembler::Architecture {
break;
case Float2Int:
if (useSSE(&c) and (bSize <= BytesPerWord)) {
if (useSSE(&c) and bSize <= BytesPerWord) {
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
*aRegisterMask = (static_cast<uint64_t>(FloatRegisterMask) << 32)
| FloatRegisterMask;
@ -2931,7 +2931,7 @@ class MyArchitecture: public Assembler::Architecture {
break;
case Int2Float:
if (useSSE(&c) and (aSize <= BytesPerWord)) {
if (useSSE(&c) and aSize <= BytesPerWord) {
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
*aRegisterMask = GeneralRegisterMask
| (static_cast<uint64_t>(GeneralRegisterMask) << 32);
@ -3039,38 +3039,46 @@ class MyArchitecture: public Assembler::Architecture {
}
virtual void planMove
(unsigned size,
uint8_t srcTypeMask, uint64_t srcRegisterMask,
uint8_t dstTypeMask, uint64_t dstRegisterMask,
uint8_t* tmpTypeMask, uint64_t* tmpRegisterMask)
(unsigned size, uint8_t* srcTypeMask, uint64_t* srcRegisterMask,
uint8_t* tmpTypeMask, uint64_t* tmpRegisterMask,
uint8_t dstTypeMask, uint64_t dstRegisterMask)
{
*tmpTypeMask = srcTypeMask;
*tmpRegisterMask = srcRegisterMask;
*srcTypeMask = ~0;
*srcRegisterMask = ~static_cast<uint64_t>(0);
if ((dstTypeMask & (1 << MemoryOperand))
and (srcTypeMask & ((1 << MemoryOperand) | 1 << AddressOperand)))
{
*tmpTypeMask = 0;
*tmpRegisterMask = 0;
if (dstTypeMask & (1 << MemoryOperand)) {
// can't move directly from memory to memory
*tmpTypeMask = (1 << RegisterOperand);
*srcTypeMask = (1 << RegisterOperand) | (1 << ConstantOperand);
*tmpTypeMask = 1 << RegisterOperand;
*tmpRegisterMask = GeneralRegisterMask
| (static_cast<uint64_t>(GeneralRegisterMask) << 32);
} else if (dstTypeMask & (1 << RegisterOperand)) {
if (srcTypeMask & (1 << RegisterOperand)) {
if (size != BytesPerWord
and (((dstRegisterMask & FloatRegisterMask) == 0)
xor ((srcRegisterMask & FloatRegisterMask) == 0)))
{
// can't move directly from FPR to GPR or vice-versa for
// values larger than the GPR size
*tmpTypeMask = (1 << MemoryOperand);
*tmpRegisterMask = 0;
if (size > BytesPerWord) {
// can't move directly from FPR to GPR or vice-versa for
// values larger than the GPR size
if (dstRegisterMask & FloatRegisterMask) {
*srcRegisterMask = FloatRegisterMask
| (static_cast<uint64_t>(FloatRegisterMask) << 32);
*tmpTypeMask = 1 << MemoryOperand;
} else if (dstRegisterMask & GeneralRegisterMask) {
*srcRegisterMask = GeneralRegisterMask
| (static_cast<uint64_t>(GeneralRegisterMask) << 32);
*tmpTypeMask = 1 << MemoryOperand;
}
} else if ((dstRegisterMask & FloatRegisterMask)
and (srcTypeMask & (1 << ConstantOperand)))
{
}
if (dstRegisterMask & FloatRegisterMask) {
// can't move directly from constant to FPR
*tmpTypeMask = (1 << MemoryOperand);
*tmpRegisterMask = 0;
*srcTypeMask &= ~(1 << ConstantOperand);
if (size > BytesPerWord) {
*tmpTypeMask = 1 << MemoryOperand;
} else {
*tmpTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
*tmpRegisterMask = GeneralRegisterMask
| (static_cast<uint64_t>(GeneralRegisterMask) << 32);
}
}
}
}

View File

@ -19,6 +19,8 @@ public class AllFloats {
private static float complex(float a, float b) {return (a - b) / (a * b) + (float)Math.sqrt(a);}
private static double complex(double a, double b) {return (a - b) / (a * b) + Math.sqrt(a);}
private static double complex(float a, double b) {return (a - b) / (a * b) + Math.sqrt(a);}
private static double sqrt(double a) {return Math.sqrt(a);}
private static float complexNoIntrinsic(float a, float b) {return (a - b) / (a * b) + (float)sqrt(a);}
private static int f2i(float a) {return (int)a;}
private static long f2l(float a) {return (long)a;}
private static float i2f(int a) {return (float)a;}
@ -59,6 +61,7 @@ public class AllFloats {
expect(complex(4f, 3f) == (4f-3f)/(4f*3f) + 2f);
expect(complex(4d, 3d) == (4d-3d)/(4d*3d) + 2d);
expect(complex(4f, 3d) == (4f-3d)/(4f*3d) + 2f);
expect(complexNoIntrinsic(4f, 3f) == (4f-3f)/(4f*3f) + 2f);
expect(f2i(4f) == 4);
expect(f2l(4f) == 4);

View File

@ -19,6 +19,12 @@ public class Floats {
return a - b;
}
private double field = 100d;
private static int doubleToInt(Floats f) {
return (int) f.field;
}
public static void main(String[] args) {
expect(multiply(0.5d, 0.5d) == 0.25d);
expect(multiply(0.5f, 0.5f) == 0.25f);
@ -50,10 +56,20 @@ public class Floats {
expect(((int) d) == 1);
}
{ double d = 12345d;
expect(((int) d) == 12345);
}
expect(doubleToInt(new Floats()) == 100);
{ float f = 1f;
expect(((int) f) == 1);
}
{ float f = 1f;
expect(((long) f) == 1);
}
expect(Math.round(0.4f) == 0);
expect(Math.round(0.5f) == 1);
expect(Math.round(1.0f) == 1);
@ -73,5 +89,20 @@ public class Floats {
double d = (double) z;
expect(d == 6553311036568663.0);
}
{ long z = 12345L;
float f = (float) z;
expect(f == 12345.0);
}
{ int z = 12345;
float f = (float) z;
expect(f == 12345.0);
}
{ int z = 12345;
double d = (double) z;
expect(d == 12345.0);
}
}
}