fix endianness issues when loading values smaller than BytesPerWord from the stack

This commit is contained in:
Joel Dice 2009-03-06 10:56:11 -07:00
parent ca0d4b44c1
commit 7388da6282
3 changed files with 82 additions and 55 deletions

View File

@ -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));

View File

@ -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;
} }

View File

@ -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;