diff --git a/src/compile.cpp b/src/compile.cpp index 61bb5d3c99..ba7f3a2874 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -2137,35 +2137,36 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case aaload: frame->pushObject (c->load - (BytesPerWord, c->memory(array, ArrayBody, index, BytesPerWord), - BytesPerWord)); + (BytesPerWord, BytesPerWord, + c->memory(array, ArrayBody, index, BytesPerWord), BytesPerWord)); break; case faload: case iaload: frame->pushInt - (c->load(4, c->memory(array, ArrayBody, index, 4), BytesPerWord)); + (c->load(4, 4, c->memory(array, ArrayBody, index, 4), BytesPerWord)); break; case baload: frame->pushInt - (c->load(1, c->memory(array, ArrayBody, index, 1), BytesPerWord)); + (c->load(1, 1, c->memory(array, ArrayBody, index, 1), BytesPerWord)); break; case caload: frame->pushInt - (c->loadz(2, c->memory(array, ArrayBody, index, 2), BytesPerWord)); + (c->loadz(2, 2, c->memory(array, ArrayBody, index, 2), + BytesPerWord)); break; case daload: case laload: frame->pushLong - (c->load(8, c->memory(array, ArrayBody, index, 8), 8)); + (c->load(8, 8, c->memory(array, ArrayBody, index, 8), 8)); break; case saload: 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; @@ -2284,8 +2285,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case arraylength: { frame->pushInt (c->load - (BytesPerWord, c->memory(frame->popObject(), ArrayLength, 0, 1), - BytesPerWord)); + (BytesPerWord, BytesPerWord, + c->memory(frame->popObject(), ArrayLength, 0, 1), BytesPerWord)); } break; case astore: @@ -2648,40 +2649,40 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case ByteField: case BooleanField: frame->pushInt - (c->load - (1, c->memory(table, fieldOffset(t, field), 0, 1), BytesPerWord)); + (c->load(1, 1, c->memory(table, fieldOffset(t, field), 0, 1), + BytesPerWord)); break; case CharField: frame->pushInt - (c->loadz - (2, c->memory(table, fieldOffset(t, field), 0, 1), BytesPerWord)); + (c->loadz(2, 2, c->memory(table, fieldOffset(t, field), 0, 1), + BytesPerWord)); break; case ShortField: frame->pushInt - (c->load - (2, c->memory(table, fieldOffset(t, field), 0, 1), BytesPerWord)); + (c->load(2, 2, c->memory(table, fieldOffset(t, field), 0, 1), + BytesPerWord)); break; case FloatField: case IntField: frame->pushInt - (c->load - (4, c->memory(table, fieldOffset(t, field), 0, 1), BytesPerWord)); + (c->load(4, 4, c->memory(table, fieldOffset(t, field), 0, 1), + BytesPerWord)); break; case DoubleField: case LongField: 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; case ObjectField: frame->pushObject (c->load - (BytesPerWord, c->memory(table, fieldOffset(t, field), 0, 1), - BytesPerWord)); + (BytesPerWord, BytesPerWord, + c->memory(table, fieldOffset(t, field), 0, 1), BytesPerWord)); break; default: @@ -2721,11 +2722,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } break; case i2b: { - frame->pushInt(c->load(1, frame->popInt(), BytesPerWord)); + frame->pushInt(c->load(BytesPerWord, 1, frame->popInt(), BytesPerWord)); } break; case i2c: { - frame->pushInt(c->loadz(2, frame->popInt(), BytesPerWord)); + frame->pushInt(c->loadz(BytesPerWord, 2, frame->popInt(), BytesPerWord)); } break; case i2d: { @@ -2743,11 +2744,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } break; case i2l: - frame->pushLong(c->load(4, frame->popInt(), 8)); + frame->pushLong(c->load(BytesPerWord, 4, frame->popInt(), 8)); break; case i2s: { - frame->pushInt(c->load(2, frame->popInt(), BytesPerWord)); + frame->pushInt(c->load(BytesPerWord, 2, frame->popInt(), BytesPerWord)); } break; case iadd: { @@ -3201,7 +3202,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, } break; case l2i: - frame->pushInt(c->load(8, frame->popLong(), BytesPerWord)); + frame->pushInt(c->load(8, 8, frame->popLong(), BytesPerWord)); break; case ladd: { @@ -3729,7 +3730,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, 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), BytesPerWord), BytesPerWord)); diff --git a/src/compiler.cpp b/src/compiler.cpp index 4aef1d1f22..ef7b9fe3ff 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -2420,8 +2420,9 @@ addBuddy(Value* original, Value* buddy) } void -maybeMove(Context* c, BinaryOperation type, unsigned srcSize, Value* src, - unsigned dstSize, Value* dst, const SiteMask& dstMask) +maybeMove(Context* c, BinaryOperation type, unsigned srcSize, + unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst, + const SiteMask& dstMask) { Read* read = live(dst); bool isStore = read == 0; @@ -2437,16 +2438,24 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize, Value* src, unsigned cost = src->source->copyCost(c, target); - if (srcSize != dstSize) cost = 1; + if (srcSelectSize != dstSize) cost = 1; if (cost) { bool useTemporary = ((target->type(c) == MemoryOperand and src->source->type(c) == MemoryOperand) - or (srcSize != dstSize + or (srcSelectSize != dstSize and target->type(c) != RegisterOperand)); addSite(c, dst, target); + if (srcSize != srcSelectSize + and c->arch->bigEndian() + and src->source->type(c) == MemoryOperand) + { + static_cast(src->source)->offset + += (srcSize - srcSelectSize); + } + if (target->match(c, dstMask) and not useTemporary) { if (DebugMoves) { 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); } - apply(c, type, srcSize, src->source, 0, dstSize, target, 0); + apply(c, type, srcSelectSize, src->source, 0, dstSize, target, 0); } else { target->freeze(c, dst); @@ -2486,7 +2495,7 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize, Value* src, 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 (DebugMoves) { @@ -2562,15 +2571,18 @@ grow(Context* c, Value* v) class MoveEvent: public Event { public: - MoveEvent(Context* c, BinaryOperation type, unsigned srcSize, Value* src, - unsigned dstSize, Value* dst, + MoveEvent(Context* c, BinaryOperation type, unsigned srcSize, + unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst, const SiteMask& srcLowMask, const SiteMask& srcHighMask, const SiteMask& dstLowMask, const SiteMask& dstHighMask): - Event(c), type(type), srcSize(srcSize), src(src), dstSize(dstSize), - dst(dst), dstLowMask(dstLowMask), dstHighMask(dstHighMask) + Event(c), type(type), srcSize(srcSize), srcSelectSize(srcSelectSize), + src(src), dstSize(dstSize), dst(dst), dstLowMask(dstLowMask), + dstHighMask(dstHighMask) { + assert(c, srcSelectSize <= srcSize); + addRead(c, this, src, read(c, srcLowMask)); - if (srcSize > BytesPerWord) { + if (srcSelectSize > BytesPerWord) { maybeSplit(c, src); addRead(c, this, src->high, read(c, srcHighMask)); } @@ -2585,18 +2597,22 @@ class MoveEvent: public Event { } virtual void compile(Context* c) { - if (srcSize <= BytesPerWord and dstSize <= BytesPerWord) { - maybeMove(c, type, srcSize, src, dstSize, dst, dstLowMask); - } else if (srcSize == dstSize) { - maybeMove(c, Move, BytesPerWord, src, BytesPerWord, dst, dstLowMask); - maybeMove(c, Move, BytesPerWord, src->high, - BytesPerWord, dst->high, dstHighMask); + if (srcSelectSize <= BytesPerWord and dstSize <= BytesPerWord) { + maybeMove(c, type, srcSize, srcSelectSize, src, dstSize, dst, + dstLowMask); + } else if (srcSelectSize == dstSize) { + maybeMove(c, Move, BytesPerWord, BytesPerWord, src, BytesPerWord, dst, + dstLowMask); + maybeMove(c, Move, BytesPerWord, BytesPerWord, src->high, BytesPerWord, + dst->high, dstHighMask); } else if (srcSize > BytesPerWord) { assert(c, dstSize == BytesPerWord); - maybeMove(c, Move, BytesPerWord, src, BytesPerWord, dst, dstLowMask); + maybeMove(c, Move, BytesPerWord, BytesPerWord, src, BytesPerWord, dst, + dstLowMask); } else { assert(c, srcSize == BytesPerWord); + assert(c, srcSelectSize == BytesPerWord); if (dst->high->target or live(dst->high)) { assert(c, dstLowMask.typeMask & (1 << RegisterOperand)); @@ -2637,7 +2653,8 @@ class MoveEvent: public Event { apply(c, Move, BytesPerWord, low, 0, dstSize, low, high); } 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; unsigned srcSize; + unsigned srcSelectSize; Value* src; unsigned dstSize; Value* dst; @@ -2656,8 +2674,8 @@ class MoveEvent: public Event { }; void -appendMove(Context* c, BinaryOperation type, unsigned srcSize, Value* src, - unsigned dstSize, Value* dst) +appendMove(Context* c, BinaryOperation type, unsigned srcSize, + unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst) { bool thunk; uint8_t srcTypeMask; @@ -2673,7 +2691,7 @@ appendMove(Context* c, BinaryOperation type, unsigned srcSize, Value* src, append(c, new (c->zone->allocate(sizeof(MoveEvent))) MoveEvent - (c, type, srcSize, src, dstSize, dst, + (c, type, srcSize, srcSelectSize, src, dstSize, dst, SiteMask(srcTypeMask, srcRegisterMask, AnyFrameIndex), SiteMask(srcTypeMask, srcRegisterMask >> 32, AnyFrameIndex), SiteMask(dstTypeMask, dstRegisterMask, AnyFrameIndex), @@ -5058,23 +5076,29 @@ class MyCompiler: public Compiler { virtual void store(unsigned srcSize, Operand* src, unsigned dstSize, Operand* dst) { - appendMove(&c, Move, srcSize, static_cast(src), + appendMove(&c, Move, srcSize, srcSize, static_cast(src), dstSize, static_cast(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); Value* dst = value(&c); - appendMove(&c, Move, srcSize, static_cast(src), dstSize, dst); + appendMove(&c, Move, srcSize, srcSelectSize, static_cast(src), + dstSize, 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); Value* dst = value(&c); - appendMove(&c, MoveZ, srcSize, static_cast(src), dstSize, dst); + appendMove(&c, MoveZ, srcSize, srcSelectSize, static_cast(src), + dstSize, dst); return dst; } diff --git a/src/compiler.h b/src/compiler.h index bfcd5842c1..5cd902bd41 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -100,8 +100,10 @@ class Compiler { virtual void store(unsigned srcSize, Operand* src, unsigned dstSize, Operand* dst) = 0; - virtual Operand* load(unsigned srcSize, Operand* src, unsigned dstSize) = 0; - virtual Operand* loadz(unsigned size, Operand* src, unsigned dstSize) = 0; + virtual Operand* load(unsigned srcSize, unsigned srcSelectSize, Operand* src, + unsigned dstSize) = 0; + virtual Operand* loadz(unsigned size, unsigned srcSelectSize, Operand* src, + unsigned dstSize) = 0; virtual Operand* lcmp(Operand* a, Operand* b) = 0; virtual void cmp(unsigned size, Operand* a, Operand* b) = 0; virtual void jl(Operand* address) = 0;