Index: vm/jitrino/src/jet/cg_regs.cpp =================================================================== --- vm/jitrino/src/jet/cg_regs.cpp (revision 536815) +++ vm/jitrino/src/jet/cg_regs.cpp (working copy) @@ -165,11 +165,11 @@ for (unsigned i=0; is_gr(ar) && isize(); i++) { Val& s = m_jframe->dip(i); if (!s.is_mem() || !s.uses(ar)) { continue; }; - push(s.as_opnd(jobj)); + push(s.as_opnd()); rfree(s); s.to_mem(m_base, vstack_off(i)); rref(s); - Opnd stk(jobj, m_base, vstack_off(i)); + Opnd stk(s.jt(), m_base, vstack_off(i)); pop(stk); } if (is_set(DBG_TRACE_CG)) { dbg(";;>~spill\n"); } Index: vm/jitrino/src/jet/enc.cpp =================================================================== --- vm/jitrino/src/jet/enc.cpp (revision 536815) +++ vm/jitrino/src/jet/enc.cpp (working copy) @@ -437,7 +437,7 @@ int Encoder::push(const Opnd& op0) { if (is_trace_on()) { - trace("push", to_str(op0), ""); + trace("push", to_str(op0) + " : " + to_str(op0.jt()), ""); } return push_impl(op0); } @@ -445,7 +445,7 @@ int Encoder::pop(const Opnd& op0) { if (is_trace_on()) { - trace("pop", to_str(op0), ""); + trace("pop", to_str(op0) + " : " + to_str(op0.jt()), ""); } return pop_impl(op0); } Index: vm/jitrino/src/jet/enc_ia32.cpp =================================================================== --- vm/jitrino/src/jet/enc_ia32.cpp (revision 536815) +++ vm/jitrino/src/jet/enc_ia32.cpp (working copy) @@ -843,22 +843,60 @@ ip(EncoderBase::encode(ip(), mn, args)); } -int Encoder::push_impl(const Opnd& op0) +int Encoder::push_impl(const Opnd& op) { //assert(!is_f(gr)); - EncoderBase::Operands args; - add_args(args, op0); - ip(EncoderBase::encode(ip(), Mnemonic_PUSH, args)); - return STACK_SLOT_SIZE; + if (!is_ia32() || OpndSize_64 != to_sz(op.jt())) { + EncoderBase::Operands args; + add_args(args, op); + ip(EncoderBase::encode(ip(), Mnemonic_PUSH, args)); + return STACK_SLOT_SIZE; + } else { + /* + * The only case currently IA32 && 64-bit memory operand + * Emulate with double PUSH for hi & lo parts + */ + assert(op.is_mem()); + RegName base = op.base() != ar_x ? devirt(op.base()) : RegName_Null; + RegName idx = op.index() == ar_x ? RegName_Null : devirt(op.index()); + EncoderBase::Operand mem_lo(OpndSize_32, base, idx, op.scale(), op.disp()); + EncoderBase::Operands args(mem_lo); + ip(EncoderBase::encode(ip(), Mnemonic_PUSH, args)); + EncoderBase::Operand mem_hi(OpndSize_32, base, idx, op.scale(), op.disp() + 4); + args.clear(); + args.add(mem_hi); + ip(EncoderBase::encode(ip(), Mnemonic_PUSH, args)); + + return 8; + } } -int Encoder::pop_impl(const Opnd& op0) +int Encoder::pop_impl(const Opnd& op) { //assert(!is_f(gr)); - EncoderBase::Operands args; - add_args(args, op0); - ip(EncoderBase::encode(ip(), Mnemonic_POP, args)); - return STACK_SLOT_SIZE; + if (!is_ia32() || OpndSize_64 != to_sz(op.jt())) { + EncoderBase::Operands args; + add_args(args, op); + ip(EncoderBase::encode(ip(), Mnemonic_POP, args)); + return STACK_SLOT_SIZE; + } else { + /* + * The only case currently IA32 && 64-bit memory operand + * Emulate with double POP for hi & lo parts + */ + assert(op.is_mem()); + RegName base = op.base() != ar_x ? devirt(op.base()) : RegName_Null; + RegName idx = op.index() == ar_x ? RegName_Null : devirt(op.index()); + EncoderBase::Operand mem_hi(OpndSize_32, base, idx, op.scale(), op.disp() + 4); + EncoderBase::Operands args(mem_hi); + ip(EncoderBase::encode(ip(), Mnemonic_POP, args)); + EncoderBase::Operand mem_lo(OpndSize_32, base, idx, op.scale(), op.disp()); + args.clear(); + args.add(mem_lo); + ip(EncoderBase::encode(ip(), Mnemonic_POP, args)); + + return 8; + } } void Encoder::call_impl(const Opnd& target)