mirror of
https://github.com/corda/corda.git
synced 2025-01-04 04:04:27 +00:00
fix int-to-long conversions from memory on x86_32
The instruction for 32-bit-to-64-bit sign extension on x86_32 requires that the input value be placed in EAX and the sign extension in EDX. However, the compiler can get confused if the input value is in memory addressed via one of those registers and doesn't know how to move it. This patch works around that limitation by doing the move explicitly in MemoryEvent::compile if necessary.
This commit is contained in:
parent
1a44ec9eef
commit
70a7a50a49
@ -2003,6 +2003,13 @@ class MemorySite: public Site {
|
||||
}
|
||||
}
|
||||
|
||||
bool conflicts(const SiteMask& mask) {
|
||||
return (mask.typeMask & (1 << RegisterOperand)) != 0
|
||||
and (((1 << base) & mask.registerMask) == 0
|
||||
or (index != NoRegister
|
||||
and ((1 << index) & mask.registerMask) == 0));
|
||||
}
|
||||
|
||||
virtual bool match(Context* c, const SiteMask& mask) {
|
||||
assert(c, acquired);
|
||||
|
||||
@ -4574,8 +4581,20 @@ class OperationEvent: public Event {
|
||||
void
|
||||
appendOperation(Context* c, Operation op)
|
||||
{
|
||||
append
|
||||
(c, new(c->zone) OperationEvent(c, op));
|
||||
append(c, new(c->zone) OperationEvent(c, op));
|
||||
}
|
||||
|
||||
void
|
||||
moveIfConflict(Context* c, Value* v, MemorySite* s)
|
||||
{
|
||||
if (v->reads) {
|
||||
SiteMask mask(1 << RegisterOperand, ~0, AnyFrameIndex);
|
||||
v->reads->intersect(&mask);
|
||||
if (s->conflicts(mask)) {
|
||||
maybeMove(c, v->reads, true, false);
|
||||
removeSite(c, v, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MemoryEvent: public Event {
|
||||
@ -4626,22 +4645,24 @@ class MemoryEvent: public Event {
|
||||
popRead(c, this, index);
|
||||
}
|
||||
|
||||
Site* site = memorySite
|
||||
MemorySite* site = memorySite
|
||||
(c, baseRegister, displacement, indexRegister, scale);
|
||||
|
||||
Site* low;
|
||||
MemorySite* low;
|
||||
if (result->nextWord != result) {
|
||||
Site* high = site->copyHigh(c);
|
||||
low = site->copyLow(c);
|
||||
MemorySite* high = static_cast<MemorySite*>(site->copyHigh(c));
|
||||
low = static_cast<MemorySite*>(site->copyLow(c));
|
||||
|
||||
result->nextWord->target = high;
|
||||
addSite(c, result->nextWord, high);
|
||||
moveIfConflict(c, result->nextWord, high);
|
||||
} else {
|
||||
low = site;
|
||||
}
|
||||
|
||||
result->target = low;
|
||||
addSite(c, result, low);
|
||||
moveIfConflict(c, result, low);
|
||||
}
|
||||
|
||||
Value* base;
|
||||
|
Loading…
Reference in New Issue
Block a user