mirror of
https://github.com/corda/corda.git
synced 2025-02-02 09:18:13 +00:00
various register marshalling bugfixes
This commit is contained in:
parent
2ed6247cec
commit
bbd1ee5540
@ -54,6 +54,8 @@ class Site {
|
|||||||
|
|
||||||
virtual void thaw(Context*) { }
|
virtual void thaw(Context*) { }
|
||||||
|
|
||||||
|
virtual void validate(Context*, Stack*, unsigned, Value*) { }
|
||||||
|
|
||||||
virtual OperandType type(Context*) = 0;
|
virtual OperandType type(Context*) = 0;
|
||||||
|
|
||||||
virtual Assembler::Operand* asAssemblerOperand(Context*) = 0;
|
virtual Assembler::Operand* asAssemblerOperand(Context*) = 0;
|
||||||
@ -101,12 +103,13 @@ class LogicalInstruction {
|
|||||||
class Register {
|
class Register {
|
||||||
public:
|
public:
|
||||||
Register(int number):
|
Register(int number):
|
||||||
value(0), site(0), number(number), size(0), refCount(0), freezeCount(0),
|
value(0), site(0), mask(0), number(number), size(0), refCount(0),
|
||||||
reserved(false), pushed(false)
|
freezeCount(0), reserved(false), pushed(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Value* value;
|
Value* value;
|
||||||
Site* site;
|
Site* site;
|
||||||
|
uint32_t mask;
|
||||||
int number;
|
int number;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
unsigned refCount;
|
unsigned refCount;
|
||||||
@ -384,7 +387,7 @@ removeMemorySites(Context* c, Value* v)
|
|||||||
{
|
{
|
||||||
for (Site** p = &(v->sites); *p;) {
|
for (Site** p = &(v->sites); *p;) {
|
||||||
if ((*p)->type(c) == MemoryOperand) {
|
if ((*p)->type(c) == MemoryOperand) {
|
||||||
// fprintf(stderr, "remove site %p (%d) from %p\n", s, s->type(c), v);
|
// fprintf(stderr, "remove site %p (%d) from %p\n", *p, (*p)->type(c), v);
|
||||||
(*p)->release(c);
|
(*p)->release(c);
|
||||||
*p = (*p)->next;
|
*p = (*p)->next;
|
||||||
break;
|
break;
|
||||||
@ -504,6 +507,10 @@ acquire(Context* c, uint32_t mask, Stack* stack, unsigned newSize,
|
|||||||
void
|
void
|
||||||
release(Context* c, Register* r);
|
release(Context* c, Register* r);
|
||||||
|
|
||||||
|
Register*
|
||||||
|
validate(Context* c, uint32_t mask, Stack* stack, unsigned size,
|
||||||
|
Value* value, Site* site, Register* current);
|
||||||
|
|
||||||
class RegisterSite: public Site {
|
class RegisterSite: public Site {
|
||||||
public:
|
public:
|
||||||
RegisterSite(uint64_t mask, Register* low = 0, Register* high = 0):
|
RegisterSite(uint64_t mask, Register* low = 0, Register* high = 0):
|
||||||
@ -578,6 +585,15 @@ class RegisterSite: public Site {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void validate(Context* c, Stack* stack, unsigned size, Value* v) {
|
||||||
|
low = ::validate(c, mask, stack, size, v, this, low);
|
||||||
|
if (size > BytesPerWord) {
|
||||||
|
::freeze(low);
|
||||||
|
high = ::validate(c, mask >> 32, stack, size, v, this, high);
|
||||||
|
::thaw(low);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual OperandType type(Context*) {
|
virtual OperandType type(Context*) {
|
||||||
return RegisterOperand;
|
return RegisterOperand;
|
||||||
}
|
}
|
||||||
@ -996,7 +1012,6 @@ pickRegister(Context* c, uint32_t mask)
|
|||||||
if ((1 << i) & mask) {
|
if ((1 << i) & mask) {
|
||||||
Register* r = c->registers[i];
|
Register* r = c->registers[i];
|
||||||
if ((static_cast<uint32_t>(1) << i) == mask) {
|
if ((static_cast<uint32_t>(1) << i) == mask) {
|
||||||
assert(c, r->freezeCount == 0);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1032,10 +1047,14 @@ swap(Context* c, Register* a, Register* b)
|
|||||||
Register*
|
Register*
|
||||||
replace(Context* c, Stack* stack, Register* r)
|
replace(Context* c, Stack* stack, Register* r)
|
||||||
{
|
{
|
||||||
|
uint32_t mask = (r->freezeCount? r->mask : ~0);
|
||||||
|
|
||||||
freeze(r);
|
freeze(r);
|
||||||
Register* s = acquire(c, ~0, stack, r->size, r->value, r->site);
|
Register* s = acquire(c, mask, stack, r->size, r->value, r->site);
|
||||||
thaw(r);
|
thaw(r);
|
||||||
|
|
||||||
swap(c, r, s);
|
swap(c, r, s);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1066,6 +1085,7 @@ acquire(Context* c, uint32_t mask, Stack* stack, unsigned newSize,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r->mask = mask;
|
||||||
r->size = newSize;
|
r->size = newSize;
|
||||||
r->value = newValue;
|
r->value = newValue;
|
||||||
r->site = newSite;
|
r->site = newSite;
|
||||||
@ -1080,11 +1100,31 @@ release(Context*, Register* r)
|
|||||||
fprintf(stderr, "release %d\n", r->number);
|
fprintf(stderr, "release %d\n", r->number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r->mask = 0;
|
||||||
r->size = 0;
|
r->size = 0;
|
||||||
r->value = 0;
|
r->value = 0;
|
||||||
r->site = 0;
|
r->site = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Register*
|
||||||
|
validate(Context* c, uint32_t mask, Stack* stack, unsigned size,
|
||||||
|
Value* value, Site* site, Register* current)
|
||||||
|
{
|
||||||
|
if ((mask & (1 << current->number)) == 0) {
|
||||||
|
Register* r = acquire(c, mask, stack, size, value, site);
|
||||||
|
release(c, current);
|
||||||
|
|
||||||
|
Assembler::Register rr(r->number);
|
||||||
|
Assembler::Register cr(current->number);
|
||||||
|
c->assembler->apply
|
||||||
|
(Move, BytesPerWord, RegisterOperand, &cr, RegisterOperand, &rr);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
} else {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
apply(Context* c, UnaryOperation op, unsigned size, Site* a)
|
apply(Context* c, UnaryOperation op, unsigned size, Site* a)
|
||||||
{
|
{
|
||||||
@ -1206,17 +1246,15 @@ class CallEvent: public Event {
|
|||||||
resultSize(resultSize),
|
resultSize(resultSize),
|
||||||
argumentFootprint(0)
|
argumentFootprint(0)
|
||||||
{
|
{
|
||||||
for (Stack* s = stack; s; s = s->next) {
|
uint32_t mask = ~0;
|
||||||
addRead(c, s->value, s->size * BytesPerWord, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack* s = argumentStack;
|
Stack* s = argumentStack;
|
||||||
unsigned index = 0;
|
unsigned index = 0;
|
||||||
for (unsigned i = 0; i < argumentCount; ++i) {
|
for (unsigned i = 0; i < argumentCount; ++i) {
|
||||||
Site* target;
|
Site* target;
|
||||||
if (index < c->assembler->argumentRegisterCount()) {
|
if (index < c->assembler->argumentRegisterCount()) {
|
||||||
target = registerSite
|
int r = c->assembler->argumentRegister(index);
|
||||||
(c, c->assembler->argumentRegister(index));
|
target = registerSite(c, r);
|
||||||
|
mask &= ~(1 << r);
|
||||||
} else {
|
} else {
|
||||||
target = 0;
|
target = 0;
|
||||||
s->pushEvent->active = true;
|
s->pushEvent->active = true;
|
||||||
@ -1227,9 +1265,20 @@ class CallEvent: public Event {
|
|||||||
s = s->next;
|
s = s->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
addRead(c, address, BytesPerWord,
|
if (flags & Compiler::Indirect) {
|
||||||
((flags & Compiler::Indirect) ?
|
int r = c->assembler->returnLow();
|
||||||
registerSite(c, c->assembler->returnLow()) : 0));
|
addRead(c, address, BytesPerWord, registerSite(c, r));
|
||||||
|
mask &= ~(1 << r);
|
||||||
|
} else {
|
||||||
|
addRead(c, address, BytesPerWord, virtualSite
|
||||||
|
(c, 0, ~0, (static_cast<uint64_t>(mask) << 32) | mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
|
s->pushEvent->active = true;
|
||||||
|
addRead(c, s->value, s->size * BytesPerWord, virtualSite
|
||||||
|
(c, 0, ~0, (static_cast<uint64_t>(mask) << 32) | mask));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
@ -1462,7 +1511,7 @@ maybePreserve(Context* c, Stack* stack, unsigned size, Value* v, Site* s)
|
|||||||
if (v->reads->next and v->sites->next == 0) {
|
if (v->reads->next and v->sites->next == 0) {
|
||||||
assert(c, v->sites == s);
|
assert(c, v->sites == s);
|
||||||
Site* r = targetOrNull(c, v->reads->next);
|
Site* r = targetOrNull(c, v->reads->next);
|
||||||
if (r == 0) r = freeRegister(c);
|
if (r == 0 or r == s) r = freeRegister(c);
|
||||||
addSite(c, stack, size, v, r);
|
addSite(c, stack, size, v, r);
|
||||||
apply(c, Move, size, s, r);
|
apply(c, Move, size, s, r);
|
||||||
}
|
}
|
||||||
@ -1890,6 +1939,10 @@ appendPop(Context* c, unsigned count, bool ignore)
|
|||||||
Site*
|
Site*
|
||||||
readSource(Context* c, Stack* stack, Read* r)
|
readSource(Context* c, Stack* stack, Read* r)
|
||||||
{
|
{
|
||||||
|
if (r->value->sites == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Site* target = (r->target ? r->target->readTarget(c, r) : 0);
|
Site* target = (r->target ? r->target->readTarget(c, r) : 0);
|
||||||
|
|
||||||
unsigned copyCost;
|
unsigned copyCost;
|
||||||
@ -1900,6 +1953,7 @@ readSource(Context* c, Stack* stack, Read* r)
|
|||||||
apply(c, Move, r->size, site, target);
|
apply(c, Move, r->size, site, target);
|
||||||
return target;
|
return target;
|
||||||
} else {
|
} else {
|
||||||
|
site->validate(c, stack, r->size, r->value);
|
||||||
return site;
|
return site;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1950,6 +1950,7 @@ class MyAssembler: public Assembler {
|
|||||||
case ShiftLeft:
|
case ShiftLeft:
|
||||||
case ShiftRight:
|
case ShiftRight:
|
||||||
case UnsignedShiftRight: {
|
case UnsignedShiftRight: {
|
||||||
|
*aTypeMask = (1 << RegisterOperand);
|
||||||
*aRegisterMask = static_cast<uint64_t>(1) << rcx;
|
*aRegisterMask = static_cast<uint64_t>(1) << rcx;
|
||||||
const uint32_t mask = ~(1 << rcx);
|
const uint32_t mask = ~(1 << rcx);
|
||||||
*bRegisterMask = (static_cast<uint64_t>(mask) << 32) | mask;
|
*bRegisterMask = (static_cast<uint64_t>(mask) << 32) | mask;
|
||||||
|
@ -75,6 +75,23 @@ public class Misc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
{ int get_buffer = 2144642881;
|
||||||
|
int bits_left = 30;
|
||||||
|
int l = 9;
|
||||||
|
int code = (((get_buffer >> (bits_left -= (l)))) & ((1<<(l))-1));
|
||||||
|
expect(code == 510);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ int width = 8;
|
||||||
|
int height = 8;
|
||||||
|
int depth = 24;
|
||||||
|
int scanlinePad = 4;
|
||||||
|
|
||||||
|
int bytesPerLine = (((width * depth + 7) / 8) + (scanlinePad - 1))
|
||||||
|
/ scanlinePad * scanlinePad;
|
||||||
|
expect(bytesPerLine == 24);
|
||||||
|
}
|
||||||
|
|
||||||
{ int a = -5;
|
{ int a = -5;
|
||||||
int b = 2;
|
int b = 2;
|
||||||
expect(a >> b == -5 >> 2);
|
expect(a >> b == -5 >> 2);
|
||||||
@ -83,6 +100,11 @@ public class Misc {
|
|||||||
expect(a * b == -5 * 2);
|
expect(a * b == -5 * 2);
|
||||||
expect(a / b == -5 / 2);
|
expect(a / b == -5 / 2);
|
||||||
expect(a % b == -5 % 2);
|
expect(a % b == -5 % 2);
|
||||||
|
expect((a & b) == (-5 & 2));
|
||||||
|
expect((a | b) == (-5 | 2));
|
||||||
|
expect((a ^ b) == (-5 ^ 2));
|
||||||
|
expect(-a == 5);
|
||||||
|
expect(~a == ~-5);
|
||||||
|
|
||||||
a = 5;
|
a = 5;
|
||||||
b = 2;
|
b = 2;
|
||||||
@ -92,6 +114,11 @@ public class Misc {
|
|||||||
expect(a * b == 5 * 2);
|
expect(a * b == 5 * 2);
|
||||||
expect(a / b == 5 / 2);
|
expect(a / b == 5 / 2);
|
||||||
expect(a % b == 5 % 2);
|
expect(a % b == 5 % 2);
|
||||||
|
expect((a & b) == (5 & 2));
|
||||||
|
expect((a | b) == (5 | 2));
|
||||||
|
expect((a ^ b) == (5 ^ 2));
|
||||||
|
expect(-a == -5);
|
||||||
|
expect(~a == ~5);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte2 = 0;
|
byte2 = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user