* src/vm/jit/powerpc64/codegen.c (codegen): Various more fixes all
authortbfg <none@none>
Mon, 6 Nov 2006 16:38:31 +0000 (16:38 +0000)
committertbfg <none@none>
Mon, 6 Nov 2006 16:38:31 +0000 (16:38 +0000)
over the place. jctest is now successfull for ppc64.

* src/vm/jit/powerpc64/codegen.h (M_DIV): Changed used opcode.
(M_SLL_IMM): Fixed.

src/vm/jit/powerpc64/codegen.c
src/vm/jit/powerpc64/codegen.h

index 2d49d3e94929d47622337c6b92839177bdb34512..f131e30ce5c3f8e438480b1a0f53993e1a599da8 100644 (file)
@@ -32,7 +32,7 @@
             Edwin Steiner
            Roland Lezuo
 
-   $Id: codegen.c 5899 2006-11-04 15:46:18Z tbfg $
+   $Id: codegen.c 5928 2006-11-06 16:38:31Z tbfg $
 
 */
 
@@ -394,6 +394,7 @@ bool codegen(jitdata *jd)
                currentline = 0;
                        
                for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
+                       bool sign_ext = false;
                        if (iptr->line != currentline) {
                                dseg_addlinenumber(cd, iptr->line);
                                currentline = iptr->line;
@@ -497,20 +498,15 @@ bool codegen(jitdata *jd)
                /* integer operations *************************************************/
 
                case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
-
+                       sign_ext = true;
+               case ICMD_LNEG:    
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        M_NEG(s1, d);
+                       if (sign_ext) M_EXTSW(d, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
-               case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_NEG(s1, d); /* XXX */
-                       emit_store_dst(jd, iptr, d);
-                       break;
 
                case ICMD_I2L:        /* ..., value  ==> ..., value                   */
 
@@ -621,8 +617,8 @@ bool codegen(jitdata *jd)
                        } else {
                                ICONST(REG_ITMP2, iptr->sx.val.i);
                                M_SUB(s1, REG_ITMP2, d);
-                               M_EXTSW(d, d);
                        }
+                       M_EXTSW(d, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -651,6 +647,7 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_IDIV:
+                       sign_ext = true;
                case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
@@ -661,11 +658,20 @@ bool codegen(jitdata *jd)
                        codegen_add_arithmeticexception_ref(cd);
 
                        M_DIV(s1, s2, d);
-
+                       /* we need to test if divident was 0x8000000000000, bit OV is set in XER in this case */
+                       /* we only need to check this if we did a LDIV, not for IDIV */
+                       if (!sign_ext)  {
+                               M_MFXER(REG_ITMP2);
+                               M_ANDIS(REG_ITMP2, 0x4000, REG_ITMP2);  /* test OV */
+                               M_BLE(1);
+                               M_MOV(s1, d);                           /* java specs says result == dividend */
+                       }
+                       if (sign_ext) M_EXTSW(d, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
                case ICMD_IREM:
+                       sign_ext = true;
                case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
@@ -673,22 +679,33 @@ bool codegen(jitdata *jd)
                        M_BEQ(0);
                        codegen_add_arithmeticexception_ref(cd);
 
-                       /* FIXME s1 == -2^63 && s2 == -1 does not work that way */
                        M_DIV(s1, s2,  REG_ITMP3);      
+                       /* we need to test if divident was 0x8000000000000, bit OV is set in XER in this case */
+                       /* we only need to check this if we did a LDIV, not for IDIV */
+                       if (!sign_ext)  {
+                               M_MFXER(REG_ITMP2);
+                               M_ANDIS(REG_ITMP2, 0x4000, REG_ITMP2);  /* test OV */
+                               M_BLE(2); 
+                               LCONST(REG_ITMP3, 0);                   /* result == 0 in this case */
+                               M_BR(2);
+                       }
                        M_MUL(REG_ITMP3, s2, REG_ITMP2);
                        M_SUB(s1, REG_ITMP2,  REG_ITMP3);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+
                        M_MOV(REG_ITMP3, d);
                        emit_store_dst(jd, iptr, REG_ITMP1);
                        break;
 
                
                case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
+                       sign_ext = true;
                case ICMD_LMUL:
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        M_MUL(s1, s2, d);
+                       if (sign_ext) M_EXTSW(d, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -703,6 +720,7 @@ bool codegen(jitdata *jd)
                                ICONST(REG_ITMP3, iptr->sx.val.i);
                                M_MUL(s1, REG_ITMP3, d);
                        }
+                       M_EXTSW(d, d);
                        emit_store_dst(jd, iptr, d);
                        break;
                case ICMD_LMULCONST:
@@ -733,6 +751,7 @@ bool codegen(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        M_AND_IMM(s2, 0x1f, REG_ITMP3);
                        M_SLL(s1, REG_ITMP3, d);
+                       M_EXTSW(d, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -741,8 +760,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       ICONST(REG_ITMP3, iptr->sx.val.i);
-                       M_SLL(s1, REG_ITMP3, d);
+                       M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
+                       M_EXTSW(d,d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -839,7 +858,6 @@ bool codegen(jitdata *jd)
 
                case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
                                      /* sx.val.i = constant                             */
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        M_MOV(s1, REG_ITMP2);
@@ -859,6 +877,7 @@ bool codegen(jitdata *jd)
                                M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
                        }
                        M_SUB(s1, REG_ITMP2, d);
+                       M_EXTSW(d, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
index 71242da5e9a8aee80784bd0bc0f3971a3cbdb329..254e81fcc24a37b2b94c684cb637629cb2f181cf 100644 (file)
@@ -31,7 +31,7 @@
    Changes: Christian Thalinger
             Christian Ullrich
 
-   $Id: codegen.h 5899 2006-11-04 15:46:18Z tbfg $
+   $Id: codegen.h 5928 2006-11-06 16:38:31Z tbfg $
 
 */
 
 
 #define M_MUL(a,b,c)                   M_OP3(31, 233, 0, 0, c, a, b)
 #define M_MUL_IMM(a,b,c)               M_OP2_IMM(7, c, a, b)
-#define M_DIV(a,b,c)                   M_OP3(31, 489, 0, 0, c, a, b)
+#define M_DIV(a,b,c)                   M_OP3(31, 489, 1, 0, c, a, b)
 
 #define M_NEG(a,b)                      M_OP3(31, 104, 0, 0, b, a, 0)
 #define M_NOT(a,b)                      M_OP3(31, 124, 0, 0, a, b, a)
 #define M_SUBFZE(a,b)                   M_OP3(31, 200, 0, 0, b, a, 0)
 #define M_RLWINM(a,b,c,d,e)             M_OP4(21, d, 0, a, e, b, c)
 #define M_ADDZE(a,b)                    M_OP3(31, 202, 0, 0, b, a, 0)
-#define M_SLL_IMM(a,b,c)                M_OP3(30, 0, 0, 0, a, c, b)    /* RLDICL/ROTLDI FIXME: b is a split field */
+#define M_SLL_IMM(a,b,c)                M_OP3(30, ((b)&0x20 ? 1:0), 0, ((((63-(b))&0x1f)<<6) | (((63-(b))&0x20 ? 1:0)<<5) | 0x04), a, c, (b)&0x1f);    /* RLDICR is said to be turing complete, this seems right */
 #define M_SRL_IMM(a,b,c)                M_RLWINM(a,32-(b),b,31,c)
 #define M_ADDIS(a,b,c)                  M_OP2_IMM(15, c, a, b)
 #define M_STFIWX(a,b,c)                 M_OP3(31, 983, 0, 0, a, b, c)