* src/vm/jit/s390/md-abi.h,
authorpm <none@none>
Thu, 29 Mar 2007 06:52:15 +0000 (06:52 +0000)
committerpm <none@none>
Thu, 29 Mar 2007 06:52:15 +0000 (06:52 +0000)
src/vm/jit/s390/emit.c,
src/vm/jit/s390/emit.h,
src/vm/jit/s390/codegen.c,
src/vm/jit/s390/codegen.h,
src/vm/jit/s390/arch.h: Changed a lot.

src/vm/jit/s390/arch.h
src/vm/jit/s390/codegen.c
src/vm/jit/s390/codegen.h
src/vm/jit/s390/emit.c
src/vm/jit/s390/emit.h
src/vm/jit/s390/md-abi.h

index 62fa6a64c829303c80dfa85300fdb9966f155db7..4a630f88f51aa2fc86caab1db3df2e0a0841dfa3 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: arch.h 7534 2007-03-16 23:00:18Z pm $
+   $Id: arch.h 7604 2007-03-29 06:52:15Z pm $
 
 */
 
@@ -37,7 +37,7 @@
 
 #define U8_AVAILABLE                     1
 
-/* #define USEBUILTINTABLE */
+#define USEBUILTINTABLE 
 
 #define SUPPORT_DIVISION                 1
 #define SUPPORT_LONG                     1
@@ -47,8 +47,6 @@
 #define SUPPORT_L2F                      1
 #define SUPPORT_L2D                      1
 
-/* ATTENTION: x86_64 architectures support these conversions, but we
-   need the builtin functions in corner cases */
 #define SUPPORT_F2I                      0
 #define SUPPORT_F2L                      0
 #define SUPPORT_D2I                      0
@@ -59,8 +57,8 @@
 #define SUPPORT_LONG_CMP_CONST           1
 #define SUPPORT_LONG_LOGICAL             1
 #define SUPPORT_LONG_SHIFT               1
-#define SUPPORT_LONG_MUL                 1
-#define SUPPORT_LONG_DIV                 1
+#define SUPPORT_LONG_MUL                 0
+#define SUPPORT_LONG_DIV                 0
 
 #define SUPPORT_LONG_DIV_POW2            1
 #define SUPPORT_LONG_REM_POW2            1
index bc7d5a5cb1da4c68265b8293181755793ee5ef68..a21ffec541f76fdd786780749ca2f7e54888b6ce 100644 (file)
@@ -29,7 +29,7 @@
             Christian Ullrich
             Edwin Steiner
 
-   $Id: codegen.c 7581 2007-03-26 07:23:16Z pm $
+   $Id: codegen.c 7604 2007-03-29 06:52:15Z pm $
 
 */
 
@@ -616,23 +616,25 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_I2L:        /* ..., value  ==> ..., value                   */
-                       OOPS();
-#if 0
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       M_ISEXT(s1, d);
+
+                       d = emit_alloc_dst_even_odd(jd, iptr, R0, REG_ITMP1, REG_ITMP2);
+                       s2 = emit_load_s2(jd, iptr, GET_HIGH_REG(d)); 
+
+                       M_INTMOVE(s2, GET_HIGH_REG(d));
+                       ICONST(GET_LOW_REG(d), 0);
+                       N_SRDA(GET_HIGH_REG(d), 32, RN);
+
+                       emit_copy_dst(jd, iptr, d);
                        emit_store_dst(jd, iptr, d);
-#endif
+                       emit_restore_dst_even_odd(jd, iptr, R0, REG_ITMP1, REG_ITMP2);
+
                        break;
 
                case ICMD_L2I:        /* ..., value  ==> ..., value                   */
-                       OOPS();
-#if 0
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
-                       M_IMOV(s1, d);
+                       M_INTMOVE(GET_LOW_REG(s1), d);
                        emit_store_dst(jd, iptr, d);
-#endif
                        break;
 
                case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
@@ -801,8 +803,7 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
-                       OOPS();
-#if 0
+
                        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);
@@ -813,7 +814,7 @@ bool codegen(jitdata *jd)
                                M_IMUL(s2, d);
                        }
                        emit_store_dst(jd, iptr, d);
-#endif
+
                        break;
 
                case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
@@ -833,39 +834,6 @@ bool codegen(jitdata *jd)
                        emit_store_dst(jd, iptr, d);
                        break;
 
-               case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
-                       OOPS();
-#if 0
-                       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);
-                       if (s2 == d)
-                               M_LMUL(s1, d);
-                       else {
-                               M_INTMOVE(s1, d);
-                               M_LMUL(s2, d);
-                       }
-                       emit_store_dst(jd, iptr, d);
-#endif
-                       break;
-
-               case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
-                                     /* sx.val.l = constant                             */
-                       OOPS();
-#if 0
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
-                       if (IS_IMM32(iptr->sx.val.l))
-                               M_LMUL_IMM(s1, iptr->sx.val.l, d);
-                       else {
-                               M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
-                               M_INTMOVE(s1, d);
-                               M_LMUL(REG_ITMP2, d);
-                       }
-                       emit_store_dst(jd, iptr, d);
-#endif
-                       break;
-
                case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
                case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
 
@@ -932,117 +900,6 @@ bool codegen(jitdata *jd)
                        break;
 
 
-               case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
-                       OOPS();
-#if 0
-                       var1 = VAROP(iptr->s1);
-                       var2 = VAROP(iptr->sx.s23.s2);
-                       dst  = VAROP(iptr->dst);
-
-                       d = codegen_reg_of_dst(jd, iptr, REG_NULL);
-
-               if (IS_INMEMORY(var1->flags))
-                               M_LLD(RAX, REG_SP, var1->vv.regoff * 8);
-                       else
-                               M_INTMOVE(var1->vv.regoff, RAX);
-                       
-                       if (IS_INMEMORY(var2->flags))
-                               M_LLD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
-                       else
-                               M_INTMOVE(var2->vv.regoff, REG_ITMP3);
-
-                       if (checknull) {
-                               M_TEST(REG_ITMP3);
-                               M_BEQ(0);
-                               codegen_add_arithmeticexception_ref(cd);
-                       }
-
-                       /* check as described in jvm spec */
-                       disp = dseg_add_s8(cd, 0x8000000000000000LL);
-                       M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
-                       M_BNE(4 + 6);
-                       M_LCMP_IMM(-1, REG_ITMP3);                              /* 4 bytes */
-                       M_BEQ(3 + 2 + 3);                                      /* 6 bytes */
-
-                       M_MOV(RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
-                       emit_cqto(cd);
-                       emit_idiv_reg(cd, REG_ITMP3);
-
-                       if (IS_INMEMORY(dst->flags)) {
-                               M_LST(RAX, REG_SP, dst->vv.regoff * 8);
-                               M_MOV(REG_ITMP2, RDX);                        /* restore %rdx */
-
-                       } else {
-                               M_INTMOVE(RAX, dst->vv.regoff);
-
-                               if (dst->vv.regoff != RDX) {
-                                       M_MOV(REG_ITMP2, RDX);                    /* restore %rdx */
-                               }
-                       }
-#endif
-                       break;
-
-               case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
-                       OOPS();
-#if 0
-                       var1 = VAROP(iptr->s1);
-                       var2 = VAROP(iptr->sx.s23.s2);
-                       dst  = VAROP(iptr->dst);
-
-                       d = codegen_reg_of_dst(jd, iptr, REG_NULL);
-                       
-                       if (IS_INMEMORY(var1->flags))
-                               M_LLD(REG_ITMP1, REG_SP, var1->vv.regoff * 8);
-                       else
-                               M_INTMOVE(var1->vv.regoff, REG_ITMP1);
-                       
-                       if (IS_INMEMORY(var2->flags))
-                               M_LLD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
-                       else
-                               M_INTMOVE(var2->vv.regoff, REG_ITMP3);
-                       /*
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       M_INTMOVE(s1, REG_ITMP1);
-                       s2 = emit_load_s2(jd, iptr, REG_ITMP3);
-                       M_INTMOVE(s2, REG_ITMP3);
-                       */
-                       if (checknull) {
-                               M_ITEST(REG_ITMP3);
-                               M_BEQ(0);
-                               codegen_add_arithmeticexception_ref(cd);
-                       }
-
-                       M_MOV(RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
-
-                       /* check as described in jvm spec */
-                       disp = dseg_add_s8(cd, 0x8000000000000000LL);
-                       M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
-                       M_BNE(3 + 4 + 6);
-
-#if 0
-                       emit_alul_reg_reg(cd, ALU_XOR, RDX, RDX);         /* 2 bytes */
-#endif
-                       M_LXOR(RDX, RDX);                                      /* 3 bytes */
-                       M_LCMP_IMM(-1, REG_ITMP3);                              /* 4 bytes */
-                       M_BEQ(2 + 3);                                          /* 6 bytes */
-
-                       emit_cqto(cd);
-                       emit_idiv_reg(cd, REG_ITMP3);
-
-                       if (IS_INMEMORY(dst->flags)) {
-                               M_LST(RDX, REG_SP, dst->vv.regoff * 8);
-                               M_MOV(REG_ITMP2, RDX);                        /* restore %rdx */
-
-                       } else {
-                               M_INTMOVE(RDX, dst->vv.regoff);
-
-                               if (dst->vv.regoff != RDX) {
-                                       M_MOV(REG_ITMP2, RDX);                    /* restore %rdx */
-                               }
-                       }
-#endif
-                       break;
-
                case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
                                      /* sx.val.i = constant                             */
                        OOPS();
@@ -1077,123 +934,144 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
-                       OOPS();
-#if 0
-                       d = codegen_reg_of_dst(jd, iptr, REG_NULL);
-                       emit_ishift(jd, SHIFT_SHL, iptr);
-#endif
-                       break;
+               case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
+               case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
 
-               case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
-                                     /* sx.val.i = constant                             */
-                       OOPS();
-#if 0
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
                        M_INTMOVE(s1, d);
-                       M_ISLL_IMM(iptr->sx.val.i, d);
+                       switch (iptr->opc) {
+                               case ICMD_ISHL:
+                                       N_SLA(d, 0, s2);
+                                       break;
+                               case ICMD_ISHR:
+                                       N_SRA(d, 0, s2);
+                                       break;
+                               case ICMD_IUSHR:
+                                       N_SRL(d, 0, s2);
+                                       break;
+                               default:
+                                       assert(0);
+                       }
                        emit_store_dst(jd, iptr, d);
-#endif
-                       break;
-
-               case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
-                       OOPS();
-#if 0
-                       d = codegen_reg_of_dst(jd, iptr, REG_NULL);
-                       emit_ishift(jd, SHIFT_SAR, iptr);
-#endif
                        break;
 
+               case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
+                                     /* sx.val.i = constant                             */
                case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
                                      /* sx.val.i = constant                             */
-                       OOPS();
-#if 0
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_INTMOVE(s1, d);
-                       M_ISRA_IMM(iptr->sx.val.i, d);
-                       emit_store_dst(jd, iptr, d);
-#endif
-                       break;
-
-               case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
-                       OOPS();
-#if 0
-                       d = codegen_reg_of_dst(jd, iptr, REG_NULL);
-                       emit_ishift(jd, SHIFT_SHR, iptr);
-#endif
-                       break;
-
                case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
                                      /* sx.val.i = constant                             */
-                       OOPS();
-#if 0
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_INTMOVE(s1, d);
-                       M_ISRL_IMM(iptr->sx.val.i, d);
-                       emit_store_dst(jd, iptr, d);
-#endif
-                       break;
-
-               case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
-                       OOPS();
-#if 0
-                       d = codegen_reg_of_dst(jd, iptr, REG_NULL);
-                       emit_lshift(jd, SHIFT_SHL, iptr);
-#endif
-                       break;
 
-        case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
-                                         /* sx.val.i = constant                             */
-                       OOPS();
-#if 0
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+
                        M_INTMOVE(s1, d);
-                       M_LSLL_IMM(iptr->sx.val.i, d);
+
+                       if (N_VALID_DISP(iptr->sx.val.i)) {
+                               disp = iptr->sx.val.i;
+                               s3 = RN;
+                       } else {
+                               ICONST(REG_ITMP3, iptr->sx.val.i);
+                               disp = 0;
+                               s3 = REG_ITMP3;
+                       }
+
+                       switch (iptr->opc) {
+                               case ICMD_ISHLCONST:
+                                       N_SLA(d, disp, s3);
+                                       break;
+                               case ICMD_ISHRCONST:
+                                       N_SRA(d, disp, s3);
+                                       break;
+                               case ICMD_IUSHRCONST:
+                                       N_SRL(d, disp, s3);
+                                       break;
+                               default:
+                                       assert(0);
+                       }
+
                        emit_store_dst(jd, iptr, d);
-#endif
                        break;
 
+               case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
+
                case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
-                       OOPS();
-#if 0
-                       d = codegen_reg_of_dst(jd, iptr, REG_NULL);
-                       emit_lshift(jd, SHIFT_SAR, iptr);
-#endif
-                       break;
 
-               case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
-                                     /* sx.val.i = constant                             */
-                       OOPS();
-#if 0
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_INTMOVE(s1, d);
-                       M_LSRA_IMM(iptr->sx.val.i, d);
+               case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
+
+                       d = emit_alloc_dst_even_odd(jd, iptr, R0, REG_ITMP1, REG_ITMP2);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP3); /* d wont contain REG_ITMP3 */
+
+                       if ((s2 == GET_LOW_REG(d)) || (s2 == GET_HIGH_REG(d))) {
+                               M_INTMOVE(s2, REG_ITMP3);
+                               s2 = REG_ITMP3;
+                       }
+
+                       s1 = emit_load_s1(jd, iptr, d);
+
+                       M_LNGMOVE(s1, d);
+
+                       switch (iptr->opc) {
+                               case ICMD_LSHL:
+                                       N_SLDA(GET_HIGH_REG(d), 0, s2);
+                                       break;
+                               case ICMD_LSHR:
+                                       N_SRDA(GET_HIGH_REG(d), 0, s2);
+                                       break;
+                               case ICMD_LUSHR:
+                                       N_SRDL(GET_HIGH_REG(d), 0, s2);
+                                       break;
+                               default:
+                                       assert(0);
+                       }
+
+                       emit_copy_dst(jd, iptr, d);
                        emit_store_dst(jd, iptr, d);
-#endif
-                       break;
+                       emit_restore_dst_even_odd(jd, iptr, R0, REG_ITMP1, REG_ITMP2);
 
-               case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
-                       OOPS();
-#if 0
-                       d = codegen_reg_of_dst(jd, iptr, REG_NULL);
-                       emit_lshift(jd, SHIFT_SHR, iptr);
-#endif
                        break;
 
+        case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
+                                         /* sx.val.i = constant                             */
+               case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
+                                     /* sx.val.i = constant                             */
                case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
                                      /* sx.val.l = constant                             */
-                       OOPS();
-#if 0
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_INTMOVE(s1, d);
-                       M_LSRL_IMM(iptr->sx.val.i, d);
+               
+                       d = emit_alloc_dst_even_odd(jd, iptr, R0, REG_ITMP1, REG_ITMP2); /* won't contain itmp3 */
+                       s1 = emit_load_s1(jd, iptr, d);
+               
+                       M_LNGMOVE(s1, d);
+
+                       if (N_VALID_DISP(iptr->sx.val.i)) {
+                               disp = iptr->sx.val.i;
+                               s3 = RN;
+                       } else {
+                               ICONST(REG_ITMP3, iptr->sx.val.i);
+                               disp = 0;
+                               s3 = REG_ITMP3;
+                       }
+
+                       switch (iptr->opc) {
+                               case ICMD_LSHLCONST:
+                                       N_SLDA(GET_HIGH_REG(d), disp, s3);
+                                       break;
+                               case ICMD_LSHRCONST:
+                                       N_SRDA(GET_HIGH_REG(d), disp, s3);
+                                       break;
+                               case ICMD_LUSHRCONST:
+                                       N_SRDL(GET_HIGH_REG(d), disp, s3);
+                                       break;
+                               default:
+                                       assert(0);
+                       }
+
+                       emit_copy_dst(jd, iptr, d);
                        emit_store_dst(jd, iptr, d);
-#endif
+                       emit_restore_dst_even_odd(jd, iptr, R0, REG_ITMP1, REG_ITMP2);
+
                        break;
 
                case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
@@ -1255,57 +1133,108 @@ bool codegen(jitdata *jd)
 #endif
                        break;
 
+               case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
+               case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
                case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
-                       OOPS();
-#if 0
-                       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);
-                       if (s2 == d)
-                               M_LAND(s1, d);
-                       else {
-                               M_INTMOVE(s1, d);
-                               M_LAND(s2, d);
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+
+                       s1 = emit_load_s1_low(jd, iptr, GET_LOW_REG(d));
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
+
+                       M_INTMOVE(s1, GET_LOW_REG(d));
+
+                       switch (iptr->opc) {
+                               case ICMD_LAND:
+                                       M_IAND(s2, GET_LOW_REG(d));
+                                       break;
+                               case ICMD_LXOR:
+                                       M_IXOR(s2, GET_LOW_REG(d));
+                                       break;
+                               case ICMD_LOR:
+                                       M_IOR(s2, GET_LOW_REG(d));
+                                       break;
+                               default:
+                                       assert(0);
                        }
+
+                       s1 = emit_load_s1_high(jd, iptr, GET_HIGH_REG(d));
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+
+                       M_INTMOVE(s1, GET_HIGH_REG(d));
+
+                       switch (iptr->opc) {
+                               case ICMD_LAND:
+                                       M_IAND(s2, GET_HIGH_REG(d));
+                                       break;
+                               case ICMD_LXOR:
+                                       M_IXOR(s2, GET_HIGH_REG(d));
+                                       break;
+                               case ICMD_LOR:
+                                       M_IOR(s2, GET_HIGH_REG(d));
+                                       break;
+                               default:
+                                       assert(0);
+                       }
+
                        emit_store_dst(jd, iptr, d);
-#endif
                        break;
 
+               case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
+                                     /* sx.val.l = constant                             */
+               case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
+                                     /* sx.val.l = constant                             */
                case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
                                      /* sx.val.l = constant                             */
 
-                       s3 = iptr->sx.val.l & 0xffffffff;
-                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       /* TODO should use memory operand to access data segment, not load */
+
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
-                       if ((s3 >= 0) && (s3 <= 65535))
-                               M_AND_IMM(s1, s3, GET_LOW_REG(d));
-                       else {
-                               ICONST(REG_ITMP3, s3);
-                               M_AND(s1, REG_ITMP3, GET_LOW_REG(d));
+
+                       s1 = emit_load_s1_low(jd, iptr, GET_LOW_REG(d));
+                       s3 = iptr->sx.val.l & 0xffffffff;
+
+                       M_INTMOVE(s1, GET_LOW_REG(d));
+
+                       ICONST(REG_ITMP3, s3);
+
+                       switch (iptr->opc) {
+                               case ICMD_LANDCONST:
+                                       M_IAND(REG_ITMP3, GET_LOW_REG(d));
+                                       break;
+                               case ICMD_LXORCONST:
+                                       M_IXOR(REG_ITMP3, GET_LOW_REG(d));
+                                       break;
+                               case ICMD_LORCONST:
+                                       M_IOR(REG_ITMP3, GET_LOW_REG(d));
+                                       break;
+                               default:
+                                       assert(0);
                        }
-                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+
+                       s1 = emit_load_s1_high(jd, iptr, GET_HIGH_REG(d));
                        s3 = iptr->sx.val.l >> 32;
-                       if ((s3 >= 0) && (s3 <= 65535))
-                               M_AND_IMM(s1, s3, GET_HIGH_REG(d));
-                       else {
-                               ICONST(REG_ITMP3, s3);                 /* don't use REG_ITMP2 */
-                               M_AND(s1, REG_ITMP3, GET_HIGH_REG(d));
-                       }
-                       emit_store_dst(jd, iptr, d);
 
-                       OOPS();
-#if 0
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
-                       M_INTMOVE(s1, d);
-                       if (IS_IMM32(iptr->sx.val.l))
-                               M_LAND_IMM(iptr->sx.val.l, d);
-                       else {
-                               M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
-                               M_LAND(REG_ITMP2, d);
+                       M_INTMOVE(s1, GET_HIGH_REG(d));
+
+                       ICONST(REG_ITMP3, s3);
+
+                       switch (iptr->opc) {
+                               case ICMD_LANDCONST:
+                                       M_IAND(REG_ITMP3, GET_HIGH_REG(d));
+                                       break;
+                               case ICMD_LXORCONST:
+                                       M_IXOR(REG_ITMP3, GET_HIGH_REG(d));
+                                       break;
+                               case ICMD_LORCONST:
+                                       M_IOR(REG_ITMP3, GET_HIGH_REG(d));
+                                       break;
+                               default:
+                                       assert(0);
                        }
+
                        emit_store_dst(jd, iptr, d);
-#endif
+
                        break;
 
                case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
@@ -1320,39 +1249,6 @@ bool codegen(jitdata *jd)
 #endif
                        break;
 
-               case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
-                       OOPS();
-#if 0
-                       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);
-                       if (s2 == d)
-                               M_LOR(s1, d);
-                       else {
-                               M_INTMOVE(s1, d);
-                               M_LOR(s2, d);
-                       }
-                       emit_store_dst(jd, iptr, d);
-#endif
-                       break;
-
-               case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
-                                     /* sx.val.l = constant                             */
-                       OOPS();
-#if 0
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
-                       M_INTMOVE(s1, d);
-                       if (IS_IMM32(iptr->sx.val.l))
-                               M_LOR_IMM(iptr->sx.val.l, d);
-                       else {
-                               M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
-                               M_LOR(REG_ITMP2, d);
-                       }
-                       emit_store_dst(jd, iptr, d);
-#endif
-                       break;
-
                case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
                                      /* sx.val.i = constant                             */
                        OOPS();
@@ -1365,39 +1261,6 @@ bool codegen(jitdata *jd)
 #endif
                        break;
 
-               case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
-                       OOPS();
-#if 0
-                       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);
-                       if (s2 == d)
-                               M_LXOR(s1, d);
-                       else {
-                               M_INTMOVE(s1, d);
-                               M_LXOR(s2, d);
-                       }
-                       emit_store_dst(jd, iptr, d);
-#endif
-                       break;
-
-               case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
-                                     /* sx.val.l = constant                             */
-                       OOPS();
-#if 0
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
-                       M_INTMOVE(s1, d);
-                       if (IS_IMM32(iptr->sx.val.l))
-                               M_LXOR_IMM(iptr->sx.val.l, d);
-                       else {
-                               M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
-                               M_LXOR(REG_ITMP2, d);
-                       }
-                       emit_store_dst(jd, iptr, d);
-#endif
-                       break;
-
 
                /* floating operations ************************************************/
 
@@ -1562,21 +1425,11 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_D2I:       /* ..., value  ==> ..., (int) value              */
-                       OOPS();
-#if 0
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
                        M_CVTDI(s1, d);
-                       M_ICMP_IMM(0x80000000, d);                        /* corner cases */
-                       disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
-                               ((REG_RESULT == d) ? 0 : 3);
-                       M_BNE(disp);
-                       M_FLTMOVE(s1, REG_FTMP1);
-                       M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
-                       M_CALL(REG_ITMP2);
-                       M_INTMOVE(REG_RESULT, d);
-                       emit_store_dst(jd, iptr, d);
-#endif
+                       emit_store_dst(jd, iptr, d);
+                       /* TODO: corner cases ? */
                        break;
 
                case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
@@ -1752,18 +1605,20 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
-                       OOPS();
-#if 0
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+
+                       s1 = emit_load_s1_notzero(jd, iptr, REG_ITMP3);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
-                       emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, d);
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       emit_array_checks(cd, iptr, s1, s2);
+                       
+                       M_INTMOVE(s2, REG_ITMP2);
+                       M_ISLL_IMM(3, REG_ITMP2); /* scale index by 8 */
+
+                       N_L(GET_HIGH_REG(d) /* evntl. itmp1 */, OFFSET(java_intarray, data[0]), REG_ITMP2, s1);
+                       N_L(GET_LOW_REG(d) /* evntl. itmp2 */, OFFSET(java_intarray, data[0]) + 4, REG_ITMP2, s1);
                        emit_store_dst(jd, iptr, d);
-#endif
+
                        break;
 
                case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
index 5228b5828273539494e70b57de6c377dafe84d7a..19c6a6daf14b0af25ab308c1133354b0ee9c2e21 100644 (file)
@@ -27,7 +27,7 @@
    Authors: Andreas Krall
             Christian Thalinger
 
-   $Id: codegen.h 7581 2007-03-26 07:23:16Z pm $
+   $Id: codegen.h 7604 2007-03-29 06:52:15Z pm $
 
 */
 
 #define M_DADD(a, dest) N_ADBR(dest, a)
 #define M_DDIV(a, dest) N_DDBR(dest, a)
 #define M_CVTFI(src, dst) N_CFEBR(dst, 5, src)
+#define M_CVTDI(src, dst) N_CFDBR(dst, 5, src)
 #define M_IADD(a, dest) N_AR(dest, a)
 #define M_ISUB(a, dest) N_SR(dest, a)
 #define M_IAND(a, dest) N_NR(dest, a)
 
 #define ICONST(reg, i) \
        do { \
-               if ((i) >= -32768 && (i) <= 32767) { \
+               if (N_VALID_IMM(i)) { \
                        N_LHI(reg, i); \
                } else { \
                        disp = dseg_add_s4(cd, (i)); \
 
 #define M_CVTLF(a,b) _DEPR( M_CVTLF(a,b) )
 #define M_CVTLD(a,b) _DEPR( M_CVTLD(a,b) )
-#define M_CVTDI(a,b) _DEPR( M_CVTDI(a,b) )
 #define M_CVTFL(a,b) _DEPR( M_CVTFL(a,b) )
 #define M_CVTDL(a,b) _DEPR( M_CVTDL(a,b) )
 
index 50b29fcb07aca4740a40f52028d674abc8ce33c0..a1f27a9e5551e1595a40ab5c2c975af277ab56a6 100644 (file)
@@ -26,7 +26,7 @@
 
    Authors: Christian Thalinger
 
-   $Id: emit.c 7581 2007-03-26 07:23:16Z pm $
+   $Id: emit.c 7604 2007-03-29 06:52:15Z pm $
 
 */
 
@@ -2493,6 +2493,112 @@ s4 emit_load_s2_but(jitdata *jd, instruction *iptr, s4 tempreg, s4 notreg) {
        }
 }
 
+s4 emit_alloc_dst_even_odd(jitdata *jd, instruction *iptr, s4 htmpreg, s4 ltmpreg, s4 breg) {
+       codegendata *cd;
+       s4           hr, lr;
+       varinfo     *dst;
+
+       /* (r0, r1)    
+        * (r2, r3)
+        * (r4, r5)
+        * (r6, r7)
+        * (r8, r9)
+        * (r10, r11)
+        * (r12, r13) Illegal, because r13 is PV
+        * (r14, r15) Illegal, because r15 is SP
+        */
+
+       cd = jd->cd;
+       dst = VAROP(iptr->dst);
+
+       if (IS_INMEMORY(dst->flags)) {
+               if (! IS_REG_ITMP(ltmpreg)) {
+                       M_INTMOVE(ltmpreg, breg);
+               }
+               if (! IS_REG_ITMP(htmpreg)) {
+                       M_INTMOVE(htmpreg, breg);
+               }
+               return PACK_REGS(ltmpreg, htmpreg);
+       } else {
+               hr = GET_HIGH_REG(dst->vv.regoff);
+               lr = GET_LOW_REG(dst->vv.regoff);
+               if (((hr % 2) == 0) && lr == (hr + 1)) {
+                       /* the result is already in a even-odd pair */
+                       return dst->vv.regoff;                  
+               } else if (((hr % 2) == 0) && (hr < R12)) {
+                       /* the high register is at a even position */
+                       M_INTMOVE(hr + 1, breg);
+                       return PACK_REGS(hr + 1, hr);
+               } else if (((lr % 2) == 1) && (lr < R12)) {
+                       /* the low register is at a odd position */
+                       M_INTMOVE(lr - 1, breg);
+                       return PACK_REGS(lr, lr - 1);
+               } else {
+                       /* no way to create an even-odd pair by 1 copy operation,
+                        * Use the temporary register pair.
+                        */
+                       if (! IS_REG_ITMP(ltmpreg)) {
+                               M_INTMOVE(ltmpreg, breg);
+                       }
+                       if (! IS_REG_ITMP(htmpreg)) {
+                               M_INTMOVE(htmpreg, breg);
+                       }
+                       return PACK_REGS(ltmpreg, htmpreg);
+               }
+       }
+}
+
+void emit_restore_dst_even_odd(jitdata *jd, instruction *iptr, s4 htmpreg, s4 ltmpreg, s4 breg) {
+       codegendata *cd;
+       s4           hr, lr;
+       varinfo     *dst;
+
+       cd = jd->cd;
+       dst = VAROP(iptr->dst);
+
+       if (IS_INMEMORY(dst->flags)) {
+               if (! IS_REG_ITMP(ltmpreg)) {
+                       M_INTMOVE(breg, ltmpreg);
+               }
+               if (! IS_REG_ITMP(htmpreg)) {
+                       M_INTMOVE(breg, htmpreg);
+               }
+       } else {
+               hr = GET_HIGH_REG(dst->vv.regoff);
+               lr = GET_LOW_REG(dst->vv.regoff);
+               if (((hr % 2) == 0) && (hr < R12)) {
+                       M_INTMOVE(breg, hr + 1);
+               } else if (((lr % 2) == 1) && (lr < R12)) {
+                       M_INTMOVE(breg, lr - 1);
+               } else {
+                       if (! IS_REG_ITMP(ltmpreg)) {
+                               M_INTMOVE(breg, ltmpreg);
+                       }
+                       if (! IS_REG_ITMP(htmpreg)) {
+                               M_INTMOVE(breg, htmpreg);
+                       }
+               }
+       }
+}
+
+void emit_copy_dst(jitdata *jd, instruction *iptr, s4 dtmpreg) {
+       codegendata *cd;
+       varinfo *dst;
+       cd = jd->cd;
+       dst = VAROP(iptr->dst);
+       if (! IS_INMEMORY(dst->flags)) {
+               if (dst->vv.regoff != dtmpreg) {
+                       if (IS_FLT_DBL_TYPE(dst->type)) {
+                               M_FLTMOVE(dtmpreg, dst->vv.regoff);
+                       } else if (IS_2_WORD_TYPE(dst->type)) {
+                               M_LNGMOVE(dtmpreg, dst->vv.regoff);
+                       } else {
+                               M_INTMOVE(dtmpreg, dst->vv.regoff);
+                       }
+               }
+       }
+}
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
index 13bfedba3822ccb2aebedbe8e65b2f00dfb8b5d3..f012ab206a35ce546a439641850f2d6aecd4353b 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: emit.h 7581 2007-03-26 07:23:16Z pm $
+   $Id: emit.h 7604 2007-03-29 06:52:15Z pm $
 
 */
 
@@ -363,6 +363,19 @@ s4 emit_load_s2_notzero(jitdata *jd, instruction *iptr, s4 tempreg);
 s4 emit_load_s1_but(jitdata *jd, instruction *iptr, s4 tempreg, s4 notreg);
 s4 emit_load_s2_but(jitdata *jd, instruction *iptr, s4 tempreg, s4 notreg);
 
+/* Allocate an even-odd register pair for the destination of an instruction.
+ *
+ */
+
+s4 emit_alloc_dst_even_odd(jitdata *jd, instruction *iptr, s4 htmpreg, s4 ltmpreg, s4 breg);
+
+void emit_restore_dst_even_odd(jitdata *jd, instruction *iptr, s4 htmpreg, s4 ltmpreg, s4 breg);
+
+/* If the destination operand is in a register, different than
+ * dtmpreg, a register copy is emitted.
+ */
+void emit_copy_dst(jitdata *jd, instruction *iptr, s4 dtmpreg);
+
 #endif /* _MD_EMIT_H */
 
 
index 7f74b788aeac871426f846db78a82fae29b36be6..1738c9eb055e4b255c4c6472666f0530c3db3b4b 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: md-abi.h 7581 2007-03-26 07:23:16Z pm $
+   $Id: md-abi.h 7604 2007-03-29 06:52:15Z pm $
 
 */
 
 #define REG_ITMP2       R12     /* temporary register and method pointer     */
 #define REG_ITMP3       R14     /* temporary register                        */
 
+#define IS_REG_ITMP(x) (((x) == REG_ITMP1) || ((x) == REG_ITMP2) || ((x) == REG_ITMP3))
+
 #define REG_ITMP12_PACKED    PACK_REGS(REG_ITMP2, REG_ITMP1)
 #define REG_ITMP23_PACKED    PACK_REGS(REG_ITMP3, REG_ITMP2)
 #define REG_RESULT_PACKED    PACK_REGS(REG_RESULT2, REG_RESULT)