mirror of
https://github.com/corda/corda.git
synced 2025-01-09 14:33:30 +00:00
fix endianness issues with 64-bit locals
This commit is contained in:
parent
412348d938
commit
696282631a
@ -263,6 +263,8 @@ class Assembler {
|
|||||||
|
|
||||||
virtual bool condensedAddressing() = 0;
|
virtual bool condensedAddressing() = 0;
|
||||||
|
|
||||||
|
virtual bool bigEndian() = 0;
|
||||||
|
|
||||||
virtual bool reserved(int register_) = 0;
|
virtual bool reserved(int register_) = 0;
|
||||||
|
|
||||||
virtual unsigned argumentFootprint(unsigned footprint) = 0;
|
virtual unsigned argumentFootprint(unsigned footprint) = 0;
|
||||||
|
150
src/compiler.cpp
150
src/compiler.cpp
@ -2980,28 +2980,10 @@ Value*
|
|||||||
maybeBuddy(Context* c, Value* v);
|
maybeBuddy(Context* c, Value* v);
|
||||||
|
|
||||||
Value*
|
Value*
|
||||||
push(Context* c, unsigned footprint, Value* v)
|
pushWord(Context* c, Value* v)
|
||||||
{
|
{
|
||||||
assert(c, footprint);
|
|
||||||
|
|
||||||
Value* high;
|
|
||||||
if (footprint > 1) {
|
|
||||||
assert(c, footprint == 2);
|
|
||||||
|
|
||||||
if (BytesPerWord == 4 and v->high == 0) {
|
|
||||||
split(c, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
high = push(c, 1, v->high);
|
|
||||||
} else if (v) {
|
|
||||||
high = v->high;
|
|
||||||
} else {
|
|
||||||
high = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v) {
|
if (v) {
|
||||||
v = maybeBuddy(c, v);
|
v = maybeBuddy(c, v);
|
||||||
v->high = high;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack* s = stack(c, v, c->stack);
|
Stack* s = stack(c, v, c->stack);
|
||||||
@ -3019,10 +3001,47 @@ push(Context* c, unsigned footprint, Value* v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Value*
|
Value*
|
||||||
pop(Context* c, unsigned footprint)
|
push(Context* c, unsigned footprint, Value* v)
|
||||||
{
|
{
|
||||||
assert(c, footprint);
|
assert(c, footprint);
|
||||||
|
|
||||||
|
bool bigEndian = c->arch->bigEndian();
|
||||||
|
|
||||||
|
Value* low = v;
|
||||||
|
|
||||||
|
if (bigEndian) {
|
||||||
|
v = pushWord(c, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
Value* high;
|
||||||
|
if (footprint > 1) {
|
||||||
|
assert(c, footprint == 2);
|
||||||
|
|
||||||
|
if (BytesPerWord == 4 and low->high == 0) {
|
||||||
|
split(c, low);
|
||||||
|
}
|
||||||
|
|
||||||
|
high = pushWord(c, low->high);
|
||||||
|
} else if (v) {
|
||||||
|
high = v->high;
|
||||||
|
} else {
|
||||||
|
high = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not bigEndian) {
|
||||||
|
v = pushWord(c, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v) {
|
||||||
|
v->high = high;
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
popWord(Context* c)
|
||||||
|
{
|
||||||
Stack* s = c->stack;
|
Stack* s = c->stack;
|
||||||
assert(c, s->value == 0 or s->value->home >= 0);
|
assert(c, s->value == 0 or s->value->home >= 0);
|
||||||
|
|
||||||
@ -3031,15 +3050,48 @@ pop(Context* c, unsigned footprint)
|
|||||||
}
|
}
|
||||||
|
|
||||||
c->stack = s->next;
|
c->stack = s->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value*
|
||||||
|
pop(Context* c, unsigned footprint)
|
||||||
|
{
|
||||||
|
assert(c, footprint);
|
||||||
|
|
||||||
|
Stack* s;
|
||||||
|
|
||||||
|
bool bigEndian = c->arch->bigEndian();
|
||||||
|
|
||||||
|
if (not bigEndian) {
|
||||||
|
s = c->stack;
|
||||||
|
}
|
||||||
|
|
||||||
if (footprint > 1) {
|
if (footprint > 1) {
|
||||||
assert(c, footprint == 2);
|
assert(c, footprint == 2);
|
||||||
assert(c, s->value->high == s->next->value
|
|
||||||
and ((BytesPerWord == 8) xor (s->value->high != 0)));
|
|
||||||
|
|
||||||
pop(c, 1);
|
#ifndef NDEBUG
|
||||||
|
Stack* low;
|
||||||
|
Stack* high;
|
||||||
|
if (bigEndian) {
|
||||||
|
high = c->stack;
|
||||||
|
low = high->next;
|
||||||
|
} else {
|
||||||
|
low = c->stack;
|
||||||
|
high = low->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(c, low->value->high == high->value
|
||||||
|
and ((BytesPerWord == 8) xor (low->value->high != 0)));
|
||||||
|
#endif // not NDEBUG
|
||||||
|
|
||||||
|
popWord(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bigEndian) {
|
||||||
|
s = c->stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
popWord(c);
|
||||||
|
|
||||||
return s->value;
|
return s->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3059,15 +3111,25 @@ storeLocal(Context* c, unsigned footprint, Value* v, unsigned index, bool copy)
|
|||||||
if (footprint > 1) {
|
if (footprint > 1) {
|
||||||
assert(c, footprint == 2);
|
assert(c, footprint == 2);
|
||||||
|
|
||||||
|
unsigned highIndex;
|
||||||
|
unsigned lowIndex;
|
||||||
|
if (c->arch->bigEndian()) {
|
||||||
|
highIndex = index + 1;
|
||||||
|
lowIndex = index;
|
||||||
|
} else {
|
||||||
|
lowIndex = index + 1;
|
||||||
|
highIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
if (BytesPerWord == 4) {
|
if (BytesPerWord == 4) {
|
||||||
assert(c, v->high);
|
assert(c, v->high);
|
||||||
|
|
||||||
high = storeLocal(c, 1, v->high, index, false);
|
high = storeLocal(c, 1, v->high, highIndex, false);
|
||||||
} else {
|
} else {
|
||||||
high = 0;
|
high = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
++ index;
|
index = lowIndex;
|
||||||
} else {
|
} else {
|
||||||
high = v->high;
|
high = v->high;
|
||||||
}
|
}
|
||||||
@ -3088,15 +3150,17 @@ storeLocal(Context* c, unsigned footprint, Value* v, unsigned index, bool copy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Value*
|
Value*
|
||||||
loadLocal(Context* c, unsigned footprint UNUSED, unsigned index)
|
loadLocal(Context* c, unsigned footprint, unsigned index)
|
||||||
{
|
{
|
||||||
assert(c, index + footprint <= c->localFootprint);
|
assert(c, index + footprint <= c->localFootprint);
|
||||||
|
|
||||||
if (footprint > 1) {
|
if (footprint > 1) {
|
||||||
assert(c, footprint == 2);
|
assert(c, footprint == 2);
|
||||||
|
|
||||||
|
if (not c->arch->bigEndian()) {
|
||||||
++ index;
|
++ index;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert(c, c->locals[index].value);
|
assert(c, c->locals[index].value);
|
||||||
assert(c, c->locals[index].value->home >= 0);
|
assert(c, c->locals[index].value->home >= 0);
|
||||||
@ -4786,6 +4850,8 @@ class MyCompiler: public Compiler {
|
|||||||
{
|
{
|
||||||
va_list a; va_start(a, argumentCount);
|
va_list a; va_start(a, argumentCount);
|
||||||
|
|
||||||
|
bool bigEndian = c.arch->bigEndian();
|
||||||
|
|
||||||
unsigned footprint = 0;
|
unsigned footprint = 0;
|
||||||
unsigned size = BytesPerWord;
|
unsigned size = BytesPerWord;
|
||||||
Value* arguments[argumentCount];
|
Value* arguments[argumentCount];
|
||||||
@ -4793,8 +4859,11 @@ class MyCompiler: public Compiler {
|
|||||||
for (unsigned i = 0; i < argumentCount; ++i) {
|
for (unsigned i = 0; i < argumentCount; ++i) {
|
||||||
Value* o = va_arg(a, Value*);
|
Value* o = va_arg(a, Value*);
|
||||||
if (o) {
|
if (o) {
|
||||||
|
if (bigEndian and size > BytesPerWord) {
|
||||||
|
arguments[index++] = o->high;
|
||||||
|
}
|
||||||
arguments[index] = o;
|
arguments[index] = o;
|
||||||
if (size > BytesPerWord) {
|
if ((not bigEndian) and size > BytesPerWord) {
|
||||||
arguments[++index] = o->high;
|
arguments[++index] = o->high;
|
||||||
}
|
}
|
||||||
size = BytesPerWord;
|
size = BytesPerWord;
|
||||||
@ -4849,12 +4918,22 @@ class MyCompiler: public Compiler {
|
|||||||
if (footprint > 1) {
|
if (footprint > 1) {
|
||||||
assert(&c, footprint == 2);
|
assert(&c, footprint == 2);
|
||||||
|
|
||||||
if (BytesPerWord == 4) {
|
unsigned highIndex;
|
||||||
initLocal(1, index);
|
unsigned lowIndex;
|
||||||
v->high = c.locals[index].value;
|
if (c.arch->bigEndian()) {
|
||||||
|
highIndex = index + 1;
|
||||||
|
lowIndex = index;
|
||||||
|
} else {
|
||||||
|
lowIndex = index + 1;
|
||||||
|
highIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
++ index;
|
if (BytesPerWord == 4) {
|
||||||
|
initLocal(1, highIndex);
|
||||||
|
v->high = c.locals[highIndex].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = lowIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DebugFrame) {
|
if (DebugFrame) {
|
||||||
@ -4883,8 +4962,13 @@ class MyCompiler: public Compiler {
|
|||||||
if (local->value) {
|
if (local->value) {
|
||||||
initLocal(1, i);
|
initLocal(1, i);
|
||||||
|
|
||||||
if (i > 0 and local->value->high == local[-1].value) {
|
unsigned highOffset = c.arch->bigEndian() ? 1 : -1;
|
||||||
c.locals[i].value->high = c.locals[i - 1].value;
|
|
||||||
|
if (i + highOffset > 0
|
||||||
|
and i + highOffset < c.localFootprint
|
||||||
|
and local->value->high == local[highOffset].value)
|
||||||
|
{
|
||||||
|
c.locals[i].value->high = c.locals[i + highOffset].value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1514,8 +1514,13 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool bigEndian() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool reserved(int register_) {
|
virtual bool reserved(int register_) {
|
||||||
switch (register_) {
|
switch (register_) {
|
||||||
|
case 0: // r0 has special meaning in addi and other instructions
|
||||||
case StackRegister:
|
case StackRegister:
|
||||||
case ThreadRegister:
|
case ThreadRegister:
|
||||||
return true;
|
return true;
|
||||||
|
@ -2001,6 +2001,10 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool bigEndian() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool reserved(int register_) {
|
virtual bool reserved(int register_) {
|
||||||
switch (register_) {
|
switch (register_) {
|
||||||
case rbp:
|
case rbp:
|
||||||
|
Loading…
Reference in New Issue
Block a user