mirror of
https://github.com/corda/corda.git
synced 2025-01-21 03:55:00 +00:00
fix endianness issues when loading values smaller than BytesPerWord from the stack
This commit is contained in:
parent
ca0d4b44c1
commit
7388da6282
@ -2137,35 +2137,36 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
case aaload:
|
case aaload:
|
||||||
frame->pushObject
|
frame->pushObject
|
||||||
(c->load
|
(c->load
|
||||||
(BytesPerWord, c->memory(array, ArrayBody, index, BytesPerWord),
|
(BytesPerWord, BytesPerWord,
|
||||||
BytesPerWord));
|
c->memory(array, ArrayBody, index, BytesPerWord), BytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case faload:
|
case faload:
|
||||||
case iaload:
|
case iaload:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load(4, c->memory(array, ArrayBody, index, 4), BytesPerWord));
|
(c->load(4, 4, c->memory(array, ArrayBody, index, 4), BytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case baload:
|
case baload:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load(1, c->memory(array, ArrayBody, index, 1), BytesPerWord));
|
(c->load(1, 1, c->memory(array, ArrayBody, index, 1), BytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case caload:
|
case caload:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->loadz(2, c->memory(array, ArrayBody, index, 2), BytesPerWord));
|
(c->loadz(2, 2, c->memory(array, ArrayBody, index, 2),
|
||||||
|
BytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case daload:
|
case daload:
|
||||||
case laload:
|
case laload:
|
||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->load(8, c->memory(array, ArrayBody, index, 8), 8));
|
(c->load(8, 8, c->memory(array, ArrayBody, index, 8), 8));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case saload:
|
case saload:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load(2, c->memory(array, ArrayBody, index, 2), BytesPerWord));
|
(c->load(2, 2, c->memory(array, ArrayBody, index, 2), BytesPerWord));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -2284,8 +2285,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
case arraylength: {
|
case arraylength: {
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load
|
||||||
(BytesPerWord, c->memory(frame->popObject(), ArrayLength, 0, 1),
|
(BytesPerWord, BytesPerWord,
|
||||||
BytesPerWord));
|
c->memory(frame->popObject(), ArrayLength, 0, 1), BytesPerWord));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case astore:
|
case astore:
|
||||||
@ -2648,40 +2649,40 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
case ByteField:
|
case ByteField:
|
||||||
case BooleanField:
|
case BooleanField:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load(1, 1, c->memory(table, fieldOffset(t, field), 0, 1),
|
||||||
(1, c->memory(table, fieldOffset(t, field), 0, 1), BytesPerWord));
|
BytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CharField:
|
case CharField:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->loadz
|
(c->loadz(2, 2, c->memory(table, fieldOffset(t, field), 0, 1),
|
||||||
(2, c->memory(table, fieldOffset(t, field), 0, 1), BytesPerWord));
|
BytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ShortField:
|
case ShortField:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load(2, 2, c->memory(table, fieldOffset(t, field), 0, 1),
|
||||||
(2, c->memory(table, fieldOffset(t, field), 0, 1), BytesPerWord));
|
BytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FloatField:
|
case FloatField:
|
||||||
case IntField:
|
case IntField:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load(4, 4, c->memory(table, fieldOffset(t, field), 0, 1),
|
||||||
(4, c->memory(table, fieldOffset(t, field), 0, 1), BytesPerWord));
|
BytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DoubleField:
|
case DoubleField:
|
||||||
case LongField:
|
case LongField:
|
||||||
frame->pushLong
|
frame->pushLong
|
||||||
(c->load(8, c->memory(table, fieldOffset(t, field), 0, 1), 8));
|
(c->load(8, 8, c->memory(table, fieldOffset(t, field), 0, 1), 8));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ObjectField:
|
case ObjectField:
|
||||||
frame->pushObject
|
frame->pushObject
|
||||||
(c->load
|
(c->load
|
||||||
(BytesPerWord, c->memory(table, fieldOffset(t, field), 0, 1),
|
(BytesPerWord, BytesPerWord,
|
||||||
BytesPerWord));
|
c->memory(table, fieldOffset(t, field), 0, 1), BytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2721,11 +2722,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2b: {
|
case i2b: {
|
||||||
frame->pushInt(c->load(1, frame->popInt(), BytesPerWord));
|
frame->pushInt(c->load(BytesPerWord, 1, frame->popInt(), BytesPerWord));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2c: {
|
case i2c: {
|
||||||
frame->pushInt(c->loadz(2, frame->popInt(), BytesPerWord));
|
frame->pushInt(c->loadz(BytesPerWord, 2, frame->popInt(), BytesPerWord));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2d: {
|
case i2d: {
|
||||||
@ -2743,11 +2744,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2l:
|
case i2l:
|
||||||
frame->pushLong(c->load(4, frame->popInt(), 8));
|
frame->pushLong(c->load(BytesPerWord, 4, frame->popInt(), 8));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case i2s: {
|
case i2s: {
|
||||||
frame->pushInt(c->load(2, frame->popInt(), BytesPerWord));
|
frame->pushInt(c->load(BytesPerWord, 2, frame->popInt(), BytesPerWord));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case iadd: {
|
case iadd: {
|
||||||
@ -3201,7 +3202,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case l2i:
|
case l2i:
|
||||||
frame->pushInt(c->load(8, frame->popLong(), BytesPerWord));
|
frame->pushInt(c->load(8, 8, frame->popLong(), BytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ladd: {
|
case ladd: {
|
||||||
@ -3729,7 +3730,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
|
|
||||||
saveStateAndCompile(t, frame, defaultIp);
|
saveStateAndCompile(t, frame, defaultIp);
|
||||||
|
|
||||||
c->jmp(c->load(BytesPerWord,
|
c->jmp(c->load(BytesPerWord, BytesPerWord,
|
||||||
c->memory(start, 0, c->sub(4, c->constant(bottom), key),
|
c->memory(start, 0, c->sub(4, c->constant(bottom), key),
|
||||||
BytesPerWord), BytesPerWord));
|
BytesPerWord), BytesPerWord));
|
||||||
|
|
||||||
|
@ -2420,8 +2420,9 @@ addBuddy(Value* original, Value* buddy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
maybeMove(Context* c, BinaryOperation type, unsigned srcSize, Value* src,
|
maybeMove(Context* c, BinaryOperation type, unsigned srcSize,
|
||||||
unsigned dstSize, Value* dst, const SiteMask& dstMask)
|
unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst,
|
||||||
|
const SiteMask& dstMask)
|
||||||
{
|
{
|
||||||
Read* read = live(dst);
|
Read* read = live(dst);
|
||||||
bool isStore = read == 0;
|
bool isStore = read == 0;
|
||||||
@ -2437,16 +2438,24 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize, Value* src,
|
|||||||
|
|
||||||
unsigned cost = src->source->copyCost(c, target);
|
unsigned cost = src->source->copyCost(c, target);
|
||||||
|
|
||||||
if (srcSize != dstSize) cost = 1;
|
if (srcSelectSize != dstSize) cost = 1;
|
||||||
|
|
||||||
if (cost) {
|
if (cost) {
|
||||||
bool useTemporary = ((target->type(c) == MemoryOperand
|
bool useTemporary = ((target->type(c) == MemoryOperand
|
||||||
and src->source->type(c) == MemoryOperand)
|
and src->source->type(c) == MemoryOperand)
|
||||||
or (srcSize != dstSize
|
or (srcSelectSize != dstSize
|
||||||
and target->type(c) != RegisterOperand));
|
and target->type(c) != RegisterOperand));
|
||||||
|
|
||||||
addSite(c, dst, target);
|
addSite(c, dst, target);
|
||||||
|
|
||||||
|
if (srcSize != srcSelectSize
|
||||||
|
and c->arch->bigEndian()
|
||||||
|
and src->source->type(c) == MemoryOperand)
|
||||||
|
{
|
||||||
|
static_cast<MemorySite*>(src->source)->offset
|
||||||
|
+= (srcSize - srcSelectSize);
|
||||||
|
}
|
||||||
|
|
||||||
if (target->match(c, dstMask) and not useTemporary) {
|
if (target->match(c, dstMask) and not useTemporary) {
|
||||||
if (DebugMoves) {
|
if (DebugMoves) {
|
||||||
char srcb[256]; src->source->toString(c, srcb, 256);
|
char srcb[256]; src->source->toString(c, srcb, 256);
|
||||||
@ -2455,7 +2464,7 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize, Value* src,
|
|||||||
srcb, dstb, src, dst);
|
srcb, dstb, src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(c, type, srcSize, src->source, 0, dstSize, target, 0);
|
apply(c, type, srcSelectSize, src->source, 0, dstSize, target, 0);
|
||||||
} else {
|
} else {
|
||||||
target->freeze(c, dst);
|
target->freeze(c, dst);
|
||||||
|
|
||||||
@ -2486,7 +2495,7 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize, Value* src,
|
|||||||
srcb, dstb, src, dst);
|
srcb, dstb, src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(c, type, srcSize, src->source, 0, dstSize, tmpTarget, 0);
|
apply(c, type, srcSelectSize, src->source, 0, dstSize, tmpTarget, 0);
|
||||||
|
|
||||||
if (useTemporary or isStore) {
|
if (useTemporary or isStore) {
|
||||||
if (DebugMoves) {
|
if (DebugMoves) {
|
||||||
@ -2562,15 +2571,18 @@ grow(Context* c, Value* v)
|
|||||||
|
|
||||||
class MoveEvent: public Event {
|
class MoveEvent: public Event {
|
||||||
public:
|
public:
|
||||||
MoveEvent(Context* c, BinaryOperation type, unsigned srcSize, Value* src,
|
MoveEvent(Context* c, BinaryOperation type, unsigned srcSize,
|
||||||
unsigned dstSize, Value* dst,
|
unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst,
|
||||||
const SiteMask& srcLowMask, const SiteMask& srcHighMask,
|
const SiteMask& srcLowMask, const SiteMask& srcHighMask,
|
||||||
const SiteMask& dstLowMask, const SiteMask& dstHighMask):
|
const SiteMask& dstLowMask, const SiteMask& dstHighMask):
|
||||||
Event(c), type(type), srcSize(srcSize), src(src), dstSize(dstSize),
|
Event(c), type(type), srcSize(srcSize), srcSelectSize(srcSelectSize),
|
||||||
dst(dst), dstLowMask(dstLowMask), dstHighMask(dstHighMask)
|
src(src), dstSize(dstSize), dst(dst), dstLowMask(dstLowMask),
|
||||||
|
dstHighMask(dstHighMask)
|
||||||
{
|
{
|
||||||
|
assert(c, srcSelectSize <= srcSize);
|
||||||
|
|
||||||
addRead(c, this, src, read(c, srcLowMask));
|
addRead(c, this, src, read(c, srcLowMask));
|
||||||
if (srcSize > BytesPerWord) {
|
if (srcSelectSize > BytesPerWord) {
|
||||||
maybeSplit(c, src);
|
maybeSplit(c, src);
|
||||||
addRead(c, this, src->high, read(c, srcHighMask));
|
addRead(c, this, src->high, read(c, srcHighMask));
|
||||||
}
|
}
|
||||||
@ -2585,18 +2597,22 @@ class MoveEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
if (srcSize <= BytesPerWord and dstSize <= BytesPerWord) {
|
if (srcSelectSize <= BytesPerWord and dstSize <= BytesPerWord) {
|
||||||
maybeMove(c, type, srcSize, src, dstSize, dst, dstLowMask);
|
maybeMove(c, type, srcSize, srcSelectSize, src, dstSize, dst,
|
||||||
} else if (srcSize == dstSize) {
|
dstLowMask);
|
||||||
maybeMove(c, Move, BytesPerWord, src, BytesPerWord, dst, dstLowMask);
|
} else if (srcSelectSize == dstSize) {
|
||||||
maybeMove(c, Move, BytesPerWord, src->high,
|
maybeMove(c, Move, BytesPerWord, BytesPerWord, src, BytesPerWord, dst,
|
||||||
BytesPerWord, dst->high, dstHighMask);
|
dstLowMask);
|
||||||
|
maybeMove(c, Move, BytesPerWord, BytesPerWord, src->high, BytesPerWord,
|
||||||
|
dst->high, dstHighMask);
|
||||||
} else if (srcSize > BytesPerWord) {
|
} else if (srcSize > BytesPerWord) {
|
||||||
assert(c, dstSize == BytesPerWord);
|
assert(c, dstSize == BytesPerWord);
|
||||||
|
|
||||||
maybeMove(c, Move, BytesPerWord, src, BytesPerWord, dst, dstLowMask);
|
maybeMove(c, Move, BytesPerWord, BytesPerWord, src, BytesPerWord, dst,
|
||||||
|
dstLowMask);
|
||||||
} else {
|
} else {
|
||||||
assert(c, srcSize == BytesPerWord);
|
assert(c, srcSize == BytesPerWord);
|
||||||
|
assert(c, srcSelectSize == BytesPerWord);
|
||||||
|
|
||||||
if (dst->high->target or live(dst->high)) {
|
if (dst->high->target or live(dst->high)) {
|
||||||
assert(c, dstLowMask.typeMask & (1 << RegisterOperand));
|
assert(c, dstLowMask.typeMask & (1 << RegisterOperand));
|
||||||
@ -2637,7 +2653,8 @@ class MoveEvent: public Event {
|
|||||||
|
|
||||||
apply(c, Move, BytesPerWord, low, 0, dstSize, low, high);
|
apply(c, Move, BytesPerWord, low, 0, dstSize, low, high);
|
||||||
} else {
|
} else {
|
||||||
maybeMove(c, Move, BytesPerWord, src, BytesPerWord, dst, dstLowMask);
|
maybeMove(c, Move, BytesPerWord, BytesPerWord, src, BytesPerWord, dst,
|
||||||
|
dstLowMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2648,6 +2665,7 @@ class MoveEvent: public Event {
|
|||||||
|
|
||||||
BinaryOperation type;
|
BinaryOperation type;
|
||||||
unsigned srcSize;
|
unsigned srcSize;
|
||||||
|
unsigned srcSelectSize;
|
||||||
Value* src;
|
Value* src;
|
||||||
unsigned dstSize;
|
unsigned dstSize;
|
||||||
Value* dst;
|
Value* dst;
|
||||||
@ -2656,8 +2674,8 @@ class MoveEvent: public Event {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
appendMove(Context* c, BinaryOperation type, unsigned srcSize, Value* src,
|
appendMove(Context* c, BinaryOperation type, unsigned srcSize,
|
||||||
unsigned dstSize, Value* dst)
|
unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst)
|
||||||
{
|
{
|
||||||
bool thunk;
|
bool thunk;
|
||||||
uint8_t srcTypeMask;
|
uint8_t srcTypeMask;
|
||||||
@ -2673,7 +2691,7 @@ appendMove(Context* c, BinaryOperation type, unsigned srcSize, Value* src,
|
|||||||
|
|
||||||
append(c, new (c->zone->allocate(sizeof(MoveEvent)))
|
append(c, new (c->zone->allocate(sizeof(MoveEvent)))
|
||||||
MoveEvent
|
MoveEvent
|
||||||
(c, type, srcSize, src, dstSize, dst,
|
(c, type, srcSize, srcSelectSize, src, dstSize, dst,
|
||||||
SiteMask(srcTypeMask, srcRegisterMask, AnyFrameIndex),
|
SiteMask(srcTypeMask, srcRegisterMask, AnyFrameIndex),
|
||||||
SiteMask(srcTypeMask, srcRegisterMask >> 32, AnyFrameIndex),
|
SiteMask(srcTypeMask, srcRegisterMask >> 32, AnyFrameIndex),
|
||||||
SiteMask(dstTypeMask, dstRegisterMask, AnyFrameIndex),
|
SiteMask(dstTypeMask, dstRegisterMask, AnyFrameIndex),
|
||||||
@ -5058,23 +5076,29 @@ class MyCompiler: public Compiler {
|
|||||||
virtual void store(unsigned srcSize, Operand* src, unsigned dstSize,
|
virtual void store(unsigned srcSize, Operand* src, unsigned dstSize,
|
||||||
Operand* dst)
|
Operand* dst)
|
||||||
{
|
{
|
||||||
appendMove(&c, Move, srcSize, static_cast<Value*>(src),
|
appendMove(&c, Move, srcSize, srcSize, static_cast<Value*>(src),
|
||||||
dstSize, static_cast<Value*>(dst));
|
dstSize, static_cast<Value*>(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* load(unsigned srcSize, Operand* src, unsigned dstSize) {
|
virtual Operand* load(unsigned srcSize, unsigned srcSelectSize, Operand* src,
|
||||||
|
unsigned dstSize)
|
||||||
|
{
|
||||||
assert(&c, dstSize >= BytesPerWord);
|
assert(&c, dstSize >= BytesPerWord);
|
||||||
|
|
||||||
Value* dst = value(&c);
|
Value* dst = value(&c);
|
||||||
appendMove(&c, Move, srcSize, static_cast<Value*>(src), dstSize, dst);
|
appendMove(&c, Move, srcSize, srcSelectSize, static_cast<Value*>(src),
|
||||||
|
dstSize, dst);
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* loadz(unsigned srcSize, Operand* src, unsigned dstSize) {
|
virtual Operand* loadz(unsigned srcSize, unsigned srcSelectSize,
|
||||||
|
Operand* src, unsigned dstSize)
|
||||||
|
{
|
||||||
assert(&c, dstSize >= BytesPerWord);
|
assert(&c, dstSize >= BytesPerWord);
|
||||||
|
|
||||||
Value* dst = value(&c);
|
Value* dst = value(&c);
|
||||||
appendMove(&c, MoveZ, srcSize, static_cast<Value*>(src), dstSize, dst);
|
appendMove(&c, MoveZ, srcSize, srcSelectSize, static_cast<Value*>(src),
|
||||||
|
dstSize, dst);
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,8 +100,10 @@ class Compiler {
|
|||||||
|
|
||||||
virtual void store(unsigned srcSize, Operand* src, unsigned dstSize,
|
virtual void store(unsigned srcSize, Operand* src, unsigned dstSize,
|
||||||
Operand* dst) = 0;
|
Operand* dst) = 0;
|
||||||
virtual Operand* load(unsigned srcSize, Operand* src, unsigned dstSize) = 0;
|
virtual Operand* load(unsigned srcSize, unsigned srcSelectSize, Operand* src,
|
||||||
virtual Operand* loadz(unsigned size, Operand* src, unsigned dstSize) = 0;
|
unsigned dstSize) = 0;
|
||||||
|
virtual Operand* loadz(unsigned size, unsigned srcSelectSize, Operand* src,
|
||||||
|
unsigned dstSize) = 0;
|
||||||
virtual Operand* lcmp(Operand* a, Operand* b) = 0;
|
virtual Operand* lcmp(Operand* a, Operand* b) = 0;
|
||||||
virtual void cmp(unsigned size, Operand* a, Operand* b) = 0;
|
virtual void cmp(unsigned size, Operand* a, Operand* b) = 0;
|
||||||
virtual void jl(Operand* address) = 0;
|
virtual void jl(Operand* address) = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user