* src/vm/jit/code.h (codeinfo) [ENABLE_PROFILING]: Made frequency,
[cacao.git] / src / vm / jit / sparc64 / emit.c
index a2e109ebe17fdc73902e81100dab8809b5775fea..0b609dfeb760eed90c5b71ab8f514f82cc2c36d8 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/sparc64/emit.c - Sparc code emitter functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Authors: Christian Thalinger
             Alexander Jordan
 
-   Changes: 
-
    $Id: emitfuncs.c 4398 2006-01-31 23:43:08Z twisti $
 
 */
 
-#include "vm/types.h"
 
-#include "md-abi.h"
+#include "config.h"
+#include "vm/types.h"
 
 #include "vm/jit/sparc64/codegen.h"
+#include "vm/jit/sparc64/md-abi.h"
+
+#include "mm/memory.h"
 
 #include "vm/exceptions.h"
+#include "vm/options.h"
 #include "vm/stringlocal.h" /* XXX for gen_resolvebranch */
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/asmpart.h"
+#include "vm/builtin.h"
 #include "vm/jit/dseg.h"
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
@@ -71,7 +74,7 @@ s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
        if (src->flags & INMEMORY) {
                COUNT_SPILLS;
 
-               disp = src->vv.regoff * 8;
+               disp = JITSTACK + src->vv.regoff * 8;
 
                if (IS_FLT_DBL_TYPE(src->type))
                        M_DLD(tempreg, REG_SP, disp);
@@ -105,7 +108,7 @@ void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
        if (dst->flags & INMEMORY) {
                COUNT_SPILLS;
 
-               disp = dst->vv.regoff * 8;
+               disp = JITSTACK + dst->vv.regoff * 8;
 
                if (IS_FLT_DBL_TYPE(dst->type))
                        M_DST(d, REG_SP, disp);
@@ -150,7 +153,7 @@ void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
 
                if (s1 != d) {
                        if (IS_FLT_DBL_TYPE(src->type))
-                               M_FMOV(s1, d);
+                               M_DMOV(s1, d);
                else
                                M_MOV(s1, d);
                }
@@ -171,7 +174,7 @@ void emit_iconst(codegendata *cd, s4 d, s4 value)
        s4 disp;
 
        if ((value >= -4096) && (value <= 4095)) {
-               M_XOR(REG_ZERO, value, d);
+               M_XOR_IMM(REG_ZERO, value, d);
        } else {
                disp = dseg_add_s4(cd, value);
                M_ILD(d, REG_PV_CALLEE, disp);
@@ -190,7 +193,7 @@ void emit_lconst(codegendata *cd, s4 d, s8 value)
        s4 disp;
 
        if ((value >= -4096) && (value <= 4095)) {
-               M_XOR(REG_ZERO, value, d);      
+               M_XOR_IMM(REG_ZERO, value, d);  
        } else {
                disp = dseg_add_s8(cd, value);
                M_LDX(d, REG_PV_CALLEE, disp);
@@ -198,6 +201,54 @@ void emit_lconst(codegendata *cd, s4 d, s8 value)
 }
 
 
+/* emit_arithmetic_check *******************************************************
+
+   Emit an ArithmeticException check.
+
+*******************************************************************************/
+
+void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
+{
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               M_BEQZ(reg, 0);
+               codegen_add_arithmeticexception_ref(cd);
+               M_NOP;
+       }
+}
+
+
+/* emit_arrayindexoutofbounds_check ********************************************
+
+   Emit an ArrayIndexOutOfBoundsException check.
+
+*******************************************************************************/
+
+void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
+{
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));
+               M_CMP(s2, REG_ITMP3);
+               M_XBUGE(0);
+               codegen_add_arrayindexoutofboundsexception_ref(cd, s2);
+               M_NOP;
+       }
+}
+
+/* emit_nullpointer_check ******************************************************
+
+   Emit a NullPointerException check.
+
+*******************************************************************************/
+
+void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
+{
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               M_BEQZ(reg, 0);
+               codegen_add_nullpointerexception_ref(cd);
+               M_NOP;
+       }
+}
+
 /* emit_exception_stubs ********************************************************
 
    Generates the code for the exception stubs.
@@ -257,16 +308,15 @@ void emit_patcher_stubs(jitdata *jd)
                disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) );
 
                if ((disp < (s4) 0xfffc0000) || (disp > (s4) 0x003ffff)) {
-                       *exceptionptr =
-                               new_internalerror("Jump offset is out of range: %d > +/-%d",
-                                                                 disp, 0x003ffff);
+                       vm_abort("Jump offset is out of range: %d > +/-%d",
+                                        disp, 0x003ffff);
                        return;
                }
 
                M_BR(disp);
                M_NOP;
 
-       cd->mcodeptr = savedmcodeptr;   /* restore the current mcodeptr   */
+               cd->mcodeptr = savedmcodeptr;   /* restore the current mcodeptr   */
 
                /* extend stack frame for wrapper data */
 
@@ -275,7 +325,7 @@ void emit_patcher_stubs(jitdata *jd)
                /* calculate return address and move it onto the stack */
 
                M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
-               M_AST(REG_ITMP3, REG_SP, USESTACK + 5 * 8);
+               M_AST(REG_ITMP3, REG_SP, JITSTACK + 5 * 8);
 
                /* move pointer to java_objectheader onto stack */
 
@@ -287,7 +337,7 @@ void emit_patcher_stubs(jitdata *jd)
                disp = dseg_add_unique_address(cd, NULL);                  /* vftbl   */
 
                M_LDA(REG_ITMP3, REG_PV, disp);
-               M_AST(REG_ITMP3, REG_SP, USESTACK + 4 * 8);
+               M_AST(REG_ITMP3, REG_SP, JITSTACK + 4 * 8);
 #else
                /* do nothing */
 #endif
@@ -296,29 +346,29 @@ void emit_patcher_stubs(jitdata *jd)
 
                disp = dseg_add_s4(cd, mcode[0]);
                M_ILD(REG_ITMP3, REG_PV, disp);
-               M_IST(REG_ITMP3, REG_SP, USESTACK + 3 * 8);
+               M_IST(REG_ITMP3, REG_SP, JITSTACK + 3 * 8);
 
                disp = dseg_add_s4(cd, mcode[1]);
                M_ILD(REG_ITMP3, REG_PV, disp);
-               M_IST(REG_ITMP3, REG_SP, USESTACK + 3 * 8 + 4);
+               M_IST(REG_ITMP3, REG_SP, JITSTACK + 3 * 8 + 4);
 
                /* move class/method/field reference onto stack */
 
                disp = dseg_add_address(cd, pref->ref);
                M_ALD(REG_ITMP3, REG_PV, disp);
-               M_AST(REG_ITMP3, REG_SP, USESTACK + 2 * 8);
+               M_AST(REG_ITMP3, REG_SP, JITSTACK + 2 * 8);
 
        /* move data segment displacement onto stack */
 
                disp = dseg_add_s4(cd, pref->disp);
                M_ILD(REG_ITMP3, REG_PV, disp);
-               M_IST(REG_ITMP3, REG_SP, USESTACK + 1 * 8);
+               M_IST(REG_ITMP3, REG_SP, JITSTACK + 1 * 8);
 
                /* move patcher function pointer onto stack */
 
                disp = dseg_add_address(cd, pref->patcher);
                M_ALD(REG_ITMP3, REG_PV, disp);
-               M_AST(REG_ITMP3, REG_SP, USESTACK + 0 * 8);
+               M_AST(REG_ITMP3, REG_SP, JITSTACK + 0 * 8);
 
                if (targetdisp == 0) {
                        targetdisp = ((u4 *) cd->mcodeptr) - ((u4 *) cd->mcodebase);
@@ -345,9 +395,11 @@ void emit_patcher_stubs(jitdata *jd)
 
 *******************************************************************************/
 
+#if defined(ENABLE_REPLACEMENT)
 void emit_replacement_stubs(jitdata *jd)
 {
 }
+#endif /* defined(ENABLE_REPLACEMENT) */
 
 /* emit_verbosecall_enter ******************************************************
 
@@ -377,13 +429,13 @@ void emit_verbosecall_enter(jitdata *jd)
 
        M_NOP;
 
-       /* we're calling a c function allocate paramter array */
-       M_LDA(REG_SP, REG_SP, -(1 + FLT_ARG_CNT + ABI_PARAMARRAY_SLOTS) * 8);
+       /* XXX jit-c-call */
+       M_LDA(REG_SP, REG_SP, -(1 + FLT_ARG_CNT) * 8);
 
        /* save float argument registers */
 
        for (i = 0; i < FLT_ARG_CNT; i++)
-               M_DST(rd->argfltregs[i], REG_SP, USESTACK_PARAMS + (1 + i) * 8);
+               M_DST(rd->argfltregs[i], REG_SP, JITSTACK + (1 + i) * 8);
 
        /* save temporary registers for leaf methods */
 /* XXX no leaf optimization yet
@@ -405,12 +457,12 @@ void emit_verbosecall_enter(jitdata *jd)
                }
                else {
                        if (IS_2_WORD_TYPE(t)) {
-                               M_DST(rd->argfltregs[i], REG_SP, USESTACK_PARAMS);
-                               M_LDX(rd->argintregs[i], REG_SP, USESTACK_PARAMS);
+                               M_DST(rd->argfltregs[i], REG_SP, JITSTACK);
+                               M_LDX(rd->argintregs[i], REG_SP, JITSTACK);
                        }
                        else {
-                               M_DST(rd->argfltregs[i], REG_SP, USESTACK_PARAMS);
-                               M_LDX(rd->argintregs[i], REG_SP, USESTACK_PARAMS);
+                               M_FST(rd->argfltregs[i], REG_SP, JITSTACK);
+                               M_ILD(rd->argintregs[i], REG_SP, JITSTACK);
                        }
                }
        }
@@ -427,7 +479,7 @@ void emit_verbosecall_enter(jitdata *jd)
        /* restore float argument registers */
 
        for (i = 0; i < FLT_ARG_CNT; i++)
-               M_DLD(rd->argfltregs[i], REG_SP, USESTACK_PARAMS + (1 + i) * 8);
+               M_DLD(rd->argfltregs[i], REG_SP, JITSTACK + (1 + i) * 8);
 
        /* restore temporary registers for leaf methods */
 /* XXX no leaf optimization yet
@@ -439,7 +491,7 @@ void emit_verbosecall_enter(jitdata *jd)
                        M_DLD(rd->tmpfltregs[i], REG_SP, (2 + ARG_CNT + INT_TMP_CNT + i) * 8);
        }
 */
-       M_LDA(REG_SP, REG_SP, (1 + FLT_ARG_CNT + ABI_PARAMARRAY_SLOTS) * 8);
+       M_LDA(REG_SP, REG_SP, (1 + FLT_ARG_CNT) * 8);
 
        /* mark trace code */
 
@@ -472,26 +524,25 @@ void emit_verbosecall_exit(jitdata *jd)
 
        M_NOP;
        
-       /* we're calling a c function allocate paramter array */
-       M_LDA(REG_SP, REG_SP, -(1 + ABI_PARAMARRAY_SLOTS) * 8);
+       /* XXX jit-c-call */
+       M_LDA(REG_SP, REG_SP, -(1 * 8));
 
-       M_DST(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+       M_DST(REG_FRESULT, REG_SP, JITSTACK);
 
        disp = dseg_add_address(cd, m);
        M_ALD(rd->argintregs[0], REG_PV_CALLEE, disp);
 
        M_MOV(REG_RESULT_CALLEE, rd->argintregs[1]);
-       M_DMOV(REG_FRESULT, rd->argfltregs[2]);
-       M_FMOV(REG_FRESULT, rd->argfltregs[3]);
+       M_DMOV(REG_FRESULT, 2); /* applies for flt and dbl values */
 
        disp = dseg_add_functionptr(cd, builtin_displaymethodstop);
        M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
        M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
        M_NOP;
 
-       M_DLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+       M_DLD(REG_FRESULT, REG_SP, JITSTACK);
 
-       M_LDA(REG_SP, REG_SP, (1 + ABI_PARAMARRAY_SLOTS) * 8);
+       M_LDA(REG_SP, REG_SP, 1 * 8);
 
        /* mark trace code */