Index: vm/jitrino/src/jet/cg_ia32.cpp =================================================================== --- vm/jitrino/src/jet/cg_ia32.cpp (revision 537699) +++ vm/jitrino/src/jet/cg_ia32.cpp (working copy) @@ -37,6 +37,10 @@ namespace Jitrino { namespace Jet { +/** + * Provides fine-tuned implementation for IDIV/IREM operations on IA32-compatible platforms, + * in replacement of common arithmetic helper (see arith_rt.h). + */ bool CodeGen::gen_a_platf(JavaByteCodes op, jtype jt) { if (jt != i32) return false; @@ -58,18 +62,16 @@ alu(alu_cmp, v2.as_opnd(), Opnd(-1)); unsigned br_normal = br(ne, 0, 0); alu(alu_cmp, v1.as_opnd(), Opnd(INT_MIN)); - unsigned br_cont = NOTHING, br_exit = NOTHING; + unsigned br_exit = NOTHING; if (op == OPCODE_IREM) { - br_cont = br(ne, 0, 0); - br_exit = br(cond_none, 0, 0); + do_mov(edx, Opnd(0)); // prepare exit value for the corner case + br_exit = br(eq, 0, 0); } else { + do_mov(eax, v1); br_exit = br(eq, 0, 0); } patch(br_normal, ip()); - if (br_cont != NOTHING) { - patch(br_cont, ip()); - } do_mov(eax, v1); // // The method is supposed to be platform-depended, and may not have @@ -84,9 +86,8 @@ EncoderBase::Operands args(RegName_EDX, RegName_EAX, devirt(v2.reg(), i32)); ip(EncoderBase::encode(ip(), Mnemonic_IDIV, args)); - if (br_exit != NOTHING) { - patch(br_exit, ip()); - } + patch(br_exit, ip()); + vpop(); vpop(); vpush(op == OPCODE_IREM ? edx : eax); Index: src/test/regression/H1852/run.test.xml =================================================================== --- src/test/regression/H1852/run.test.xml (revision 0) +++ src/test/regression/H1852/run.test.xml (revision 0) @@ -0,0 +1,9 @@ + + + + + + + Index: src/test/regression/H1852/DivIntTest.java =================================================================== --- src/test/regression/H1852/DivIntTest.java (revision 0) +++ src/test/regression/H1852/DivIntTest.java (revision 0) @@ -0,0 +1,22 @@ +package org.apache.harmony.drlvm.tests.regression.h1852; + +import junit.framework.TestCase; + +public class DivIntTest extends TestCase { + + public void testIDIV() { + int i_min = Integer.MIN_VALUE; + int i_1 = -1; + int res = i_min / i_1; + + assertEquals(Integer.MIN_VALUE, res); + } + + public void testIREM() { + int i_min = Integer.MIN_VALUE; + int i_1 = -1; + int res = i_min % i_1; + + assertEquals(0, res); + } +}