diff --git a/include/avian/codegen/compiler.h b/include/avian/codegen/compiler.h index 8597d97604..3512d87847 100644 --- a/include/avian/codegen/compiler.h +++ b/include/avian/codegen/compiler.h @@ -107,6 +107,11 @@ class Compiler { virtual void checkBounds(Operand* object, unsigned lengthOffset, Operand* index, intptr_t handler) = 0; + virtual Operand* truncateThenExtend(ir::SignExtendMode signExtend, + ir::Type extendType, + ir::Type truncateType, + Operand* src) = 0; + virtual void store(ir::Type srcType, Operand* src, Operand* dst) = 0; diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 307cbeb6cb..11a7b27b72 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -2609,6 +2609,22 @@ class MyCompiler: public Compiler { static_cast(index), handler); } + virtual Operand* truncateThenExtend(ir::SignExtendMode signExtend, + ir::Type extendType, + ir::Type truncateType, + Operand* src) + { + Value* dst = value(&c, extendType); + appendMove(&c, + signExtend == ir::SignExtend ? lir::Move : lir::MoveZ, + TargetBytesPerWord, + truncateType.size(), + static_cast(src), + extendType.size(), + dst); + return dst; + } + virtual void store(ir::Type srcType, Operand* src, Operand* dst) diff --git a/src/compile.cpp b/src/compile.cpp index 05bd158c8c..3862635a11 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -4831,8 +4831,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, } break; case i2l: - frame->pushLong(c->load( - ir::SignExtend, types.address, types.i4, frame->popInt(), types.i8)); + frame->pushLong(c->truncateThenExtend( + ir::SignExtend, types.i8, types.i4, frame->popInt())); break; case i2s: {