* src/vm/jit/codegen-common.cpp (codegen_emit): Fixed temporary registers in
[cacao.git] / src / vm / jit / codegen-common.cpp
index b9dffac2d126f0a114f264966429fe90e3123258..a44c52fb3b6da56571e88a9262d095303d62a255 100644 (file)
@@ -92,7 +92,7 @@
 #include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trace.hpp"
 
-#include "vm/jit/optimizing/profile.h"
+#include "vm/jit/optimizing/profile.hpp"
 
 #if defined(ENABLE_SSA)
 # include "vm/jit/optimizing/lsra.h"
@@ -1098,10 +1098,8 @@ bool codegen_emit(jitdata *jd)
                // Count method frequency.
                emit_profile_method(cd, code);
 
-# if defined(__X86_64__)
                // Start CPU cycle counting.
-               emit_profile_cycle_start();
-# endif
+               emit_profile_cycle_start(cd, code);
        }
 #endif
 
@@ -1166,11 +1164,9 @@ bool codegen_emit(jitdata *jd)
                        // Count basicblock frequency.
                        emit_profile_basicblock(cd, code, bptr);
 
-# if defined(__X86_64__)
                        // If this is an exception handler, start profiling again.
                        if (bptr->type == BBTYPE_EXH)
-                               emit_profile_cycle_start();
-# endif
+                               emit_profile_cycle_start(cd, code);
                }
 #endif
 
@@ -1254,6 +1250,13 @@ bool codegen_emit(jitdata *jd)
                                emit_nullpointer_check(cd, iptr, s1);
                                break;
 
+                       case ICMD_BREAKPOINT: /* ...  ==> ...                             */
+                                             /* sx.val.anyptr = Breakpoint               */
+
+                               patcher_add_patch_ref(jd, PATCHER_breakpoint, iptr->sx.val.anyptr, 0);
+                               PATCHER_NOPS;
+                               break;
+
 #if defined(ENABLE_SSA)
                        case ICMD_GETEXCEPTION:
 
@@ -1353,9 +1356,13 @@ bool codegen_emit(jitdata *jd)
                        case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2    */
                        case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant    */
                                              /* sx.val.i = constant                      */
+                       case ICMD_IMULPOW2:   /* ..., value  ==> ..., value * (2 ^ constant) */
+                                             /* sx.val.i = constant                      */
                        case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2    */
                        case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant    */
                                              /* sx.val.l = constant                      */
+                       case ICMD_LMULPOW2:   /* ..., value  ==> ..., value * (2 ^ constant) */
+                                             /* sx.val.l = constant                      */
                        case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2    */
                        case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2    */
                        case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value >> constant   */
@@ -1524,7 +1531,6 @@ bool codegen_emit(jitdata *jd)
                                /* This approach is much faster than moving the field
                                   address inline into a register. */
 
-                               // XXX ARM: M_DSEG_LOAD(REG_ITMP3, disp);
                                M_ALD_DSEG(REG_ITMP1, disp);
 
                                switch (fieldtype) {
@@ -1582,7 +1588,6 @@ bool codegen_emit(jitdata *jd)
                                /* This approach is much faster than moving the field
                                   address inline into a register. */
 
-                               // XXX ARM: M_DSEG_LOAD(REG_ITMP3, disp);
                                M_ALD_DSEG(REG_ITMP1, disp);
 
                                switch (fieldtype) {
@@ -1836,16 +1841,22 @@ bool codegen_emit(jitdata *jd)
 
                                REPLACEMENT_POINT_RETURN(cd, iptr);
                                s1 = emit_load_s1(jd, iptr, REG_FRESULT);
-                               // XXX ARM: Here this was M_CAST_F2I(s1, REG_RESULT);
+#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
                                emit_fmove(cd, s1, REG_FRESULT);
+#else
+                               M_CAST_F2I(s1, REG_RESULT);
+#endif
                                goto nowperformreturn;
 
                        case ICMD_DRETURN:    /* ..., retvalue ==> ...                    */
 
                                REPLACEMENT_POINT_RETURN(cd, iptr);
                                s1 = emit_load_s1(jd, iptr, REG_FRESULT);
-                               // XXX ARM: Here this was M_CAST_D2L(s1, REG_RESULT_PACKED);
+#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
                                emit_dmove(cd, s1, REG_FRESULT);
+#else
+                               M_CAST_D2L(s1, REG_LRESULT);
+#endif
                                goto nowperformreturn;
 
 nowperformreturn:
@@ -1891,6 +1902,32 @@ nowperformreturn:
                                }
 #endif
 
+                               // Emit the fast-path if available.
+                               if (bte->emit_fastpath != NULL) {
+                                       void (*emit_fastpath)(jitdata* jd, instruction* iptr, int d);
+                                       emit_fastpath = (void (*)(jitdata* jd, instruction* iptr, int d)) bte->emit_fastpath;
+
+                                       assert(md->returntype.type == TYPE_VOID);
+                                       d = REG_ITMP1;
+
+                                       // Actually call the fast-path emitter.
+                                       emit_fastpath(jd, iptr, d);
+
+                                       // If fast-path succeeded, jump to the end of the builtin
+                                       // invocation.
+                                       // XXX Actually the slow-path block below should be moved
+                                       // out of the instruction stream and the jump below should be
+                                       // inverted.
+#if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
+                                       os::abort("codegen_emit: Implement jump over slow-path for this configuration.");
+#elif SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
+                                       M_TEST(d);
+                                       emit_label_bne(cd, BRANCH_LABEL_10);
+#else
+# error Unable to generate code for this configuration!
+#endif
+                               }
+
                                goto gen_method;
 
                        case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...        */
@@ -1925,36 +1962,36 @@ gen_method:
                                                continue;
 
                                        if (!md->params[i].inmemory) {
-                                               assert(ARG_CNT > 0);
-                                               s1 = emit_load(jd, iptr, var, d);
-
                                                switch (var->type) {
                                                case TYPE_ADR:
                                                case TYPE_INT:
-                                                       assert(INT_ARG_CNT > 0);
+                                                       s1 = emit_load(jd, iptr, var, d);
                                                        emit_imove(cd, s1, d);
                                                        break;
 
-#if 0 //XXX For ARM:
-if (!md->params[s3].inmemory) {
-       s1 = emit_load(jd, iptr, var, REG_FTMP1);
-       if (IS_2_WORD_TYPE(var->type))
-               M_CAST_D2L(s1, d);
-       else
-               M_CAST_F2I(s1, d);
-}
-#endif //XXX End of ARM!
-
                                                case TYPE_LNG:
+                                                       s1 = emit_load(jd, iptr, var, d);
                                                        emit_lmove(cd, s1, d);
                                                        break;
 
                                                case TYPE_FLT:
+#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
+                                                       s1 = emit_load(jd, iptr, var, d);
                                                        emit_fmove(cd, s1, d);
+#else
+                                                       s1 = emit_load(jd, iptr, var, REG_FTMP1);
+                                                       M_CAST_F2I(s1, d);
+#endif
                                                        break;
 
                                                case TYPE_DBL:
+#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
+                                                       s1 = emit_load(jd, iptr, var, d);
                                                        emit_dmove(cd, s1, d);
+#else
+                                                       s1 = emit_load(jd, iptr, var, REG_FTMP1);
+                                                       M_CAST_D2L(s1, d);
+#endif
                                                        break;
                                                }
                                        }
@@ -2042,27 +2079,25 @@ if (!md->params[s3].inmemory) {
                                        emit_store_dst(jd, iptr, s1);
                                        break;
 
-#if 0 //XXX For ARM!!!
-#if !defined(ENABLE_SOFTFLOAT)
-                               } else {
-                                       s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
-                                       if (IS_2_WORD_TYPE(d))
-                                               M_CAST_L2D(REG_RESULT_PACKED, s1);
-                                       else
-                                               M_CAST_I2F(REG_RESULT, s1);
-                               }
-#endif /* !defined(ENABLE_SOFTFLOAT) */
-#endif //XXX End of ARM
-
                                case TYPE_FLT:
+#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
                                        s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
                                        emit_fmove(cd, REG_FRESULT, s1);
+#else
+                                       s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+                                       M_CAST_I2F(REG_RESULT, s1);
+#endif
                                        emit_store_dst(jd, iptr, s1);
                                        break;
 
                                case TYPE_DBL:
+#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
                                        s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
                                        emit_dmove(cd, REG_FRESULT, s1);
+#else
+                                       s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+                                       M_CAST_L2D(REG_LRESULT, s1);
+#endif
                                        emit_store_dst(jd, iptr, s1);
                                        break;
 
@@ -2070,6 +2105,12 @@ if (!md->params[s3].inmemory) {
                                        break;
                                }
 
+                               // If we are emitting a fast-path block, this is the label for
+                               // successful fast-path execution.
+                               if ((iptr->opc == ICMD_BUILTIN) && (bte->emit_fastpath != NULL)) {
+                                       emit_label(cd, BRANCH_LABEL_10);
+                               }
+
                                break;
 
                        case ICMD_TABLESWITCH:  /* ..., index ==> ...                     */