Hi,

div_int_const_optimize() in jit3 cannot handle
a negative dividend correctly.

Here is a simple testcase.

##################################################
class NegativeDivideConst
{
    static int div4(int n)
    {
        return n / 4;
    }

    static int div8(int n)
    {
        return n / 8;
    }

    static int div16(int n)
    {
        return n / 16;
    }

    public static void main(String args[])
    {
        System.out.println("div4(-3) = " + div4(-3));
        System.out.println("div8(-3) = " + div8(-3));
        System.out.println("div16(-3) = " + div16(-3));
    }
}
##################################################
>java NegativeDivideConst
div4(-3) = 0
div8(-3) = 0
div16(-3) = 0

>kaffe NegativeDivideConst
div4(-3) = -1
div8(-3) = -1
div16(-3) = -1
##################################################

Please refer to the following text for more details.
http://c2.com/cgi/wiki?ArithmeticShiftingConsideredHarmful

The attached patch also fixes a typo in check_div().


regards,
Rei
Index: kaffe/kaffevm/jit3/icode.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/jit3/icode.c,v
retrieving revision 1.51
diff -a -u -r1.51 icode.c
--- kaffe/kaffevm/jit3/icode.c  27 Dec 2004 16:09:48 -0000      1.51
+++ kaffe/kaffevm/jit3/icode.c  11 Apr 2005 16:14:23 -0000
@@ -1450,21 +1450,24 @@
                break;
        case 4:
                slot_alloctmp(tmp);
-               lshr_int_const(tmp, src, (sizeof(int) * 8 - 1));
+               ashr_int_const(tmp, src, 1);
+               lshr_int_const(tmp, tmp, (sizeof(int) * 8 - 2));
                add_int(tmp, tmp, src);
                ashr_int_const(dst, tmp, 2);
                slot_freetmp(tmp);
                break;
        case 8:
                slot_alloctmp(tmp);
-               lshr_int_const(tmp, src, (sizeof(int) * 8 - 1));
+               ashr_int_const(tmp, src, 2);
+               lshr_int_const(tmp, tmp, (sizeof(int) * 8 - 3));
                add_int(tmp, tmp, src);
                ashr_int_const(dst, tmp, 3);
                slot_freetmp(tmp);
                break;
        case 16:
                slot_alloctmp(tmp);
-               lshr_int_const(tmp, src, (sizeof(int) * 8 - 1));
+               ashr_int_const(tmp, src, 3);
+               lshr_int_const(tmp, tmp, (sizeof(int) * 8 - 4));
                add_int(tmp, tmp, src);
                ashr_int_const(dst, tmp, 4);
                slot_freetmp(tmp);
@@ -4693,7 +4696,7 @@
 {
 #if defined(HAVE_fakecall) || defined(HAVE_fakecall_constpool)
        if (!canCatch(ANY)) {
-               cbranch_int_const(obj, 0, newFakeCall(soft_divzero, pc), eq | 
blink);
+               cbranch_int_const(obj, 0, newFakeCall(soft_divzero, pc), beq | 
blink);
        }
        else
 #endif
Index: test/regression/NegativeDivideConst.java
===================================================================
RCS file: /cvs/kaffe/kaffe/test/regression/NegativeDivideConst.java,v
retrieving revision 1.1
diff -a -u -r1.1 NegativeDivideConst.java
--- test/regression/NegativeDivideConst.java    13 Mar 2003 23:20:49 -0000      
1.1
+++ test/regression/NegativeDivideConst.java    11 Apr 2005 16:14:29 -0000
@@ -13,33 +13,41 @@
     
     static int div8(int n)
     {
-       return n / 4;
+       return n / 8;
     }
     
     static int div16(int n)
     {
-       return n / 4;
+       return n / 16;
     }
     
     static int div32(int n)
     {
-       return n / 4;
+       return n / 32;
     }
     
     public static void main(String args[])
     {
-       System.out.println("div2 = " + div2(-1));
-       System.out.println("div4 = " + div4(-1));
-       System.out.println("div8 = " + div8(-1));
-       System.out.println("div16 = " + div16(-1));
-       System.out.println("div32 = " + div32(-1));
+       System.out.println("div2(-1) = " + div2(-1));
+       System.out.println("div4(-1) = " + div4(-1));
+       System.out.println("div8(-1) = " + div8(-1));
+       System.out.println("div16(-1) = " + div16(-1));
+       System.out.println("div32(-1) = " + div32(-1));
+       System.out.println("div4(-3) = " + div4(-3));
+       System.out.println("div8(-3) = " + div8(-3));
+       System.out.println("div16(-3) = " + div16(-3));
+       System.out.println("div32(-3) = " + div32(-3));
     }
 }
 
 /* Expected Output:
-div2 = 0
-div4 = 0
-div8 = 0
-div16 = 0
-div32 = 0
+div2(-1) = 0
+div4(-1) = 0
+div8(-1) = 0
+div16(-1) = 0
+div32(-1) = 0
+div4(-3) = 0
+div8(-3) = 0
+div16(-3) = 0
+div32(-3) = 0
 */
_______________________________________________
kaffe mailing list
[email protected]
http://kaffe.org/cgi-bin/mailman/listinfo/kaffe

Reply via email to