* src/vm/jit/sparc64/asmpart.S: added exception handling code.
authorajordan <none@none>
Tue, 31 Oct 2006 21:57:57 +0000 (21:57 +0000)
committerajordan <none@none>
Tue, 31 Oct 2006 21:57:57 +0000 (21:57 +0000)
* src/vm/jit/sparc64/md-asm.h: Likewise.

* src/vm/jit/sparc64/*: implemented createnativestub, added functions for param allocation following the ABI.

src/vm/jit/sparc64/asmpart.S
src/vm/jit/sparc64/codegen.c
src/vm/jit/sparc64/codegen.h
src/vm/jit/sparc64/emit.c
src/vm/jit/sparc64/md-abi.c
src/vm/jit/sparc64/md-abi.h
src/vm/jit/sparc64/md-asm.h
src/vm/jit/sparc64/md.c
src/vm/jit/sparc64/patcher.c

index 08b60f24a19e5f63b6a8c3bd5ab71f5de9b0b94d..718f90de05879e2618a9698cd4af3bfa540c5968 100644 (file)
@@ -36,6 +36,8 @@
 
 
 #include "config.h"
+
+#include "vm/jit/sparc64/md-abi.h"
 #include "offsets.h"
 #include "md-asm.h"
 
@@ -162,8 +164,10 @@ calljava_return:
 
 
 asm_vm_call_method_exception_handler:
+       
        mov             itmp1,%o0
        call    builtin_throw_exception
+       nop
        return  %i7 + 8                          /* implicit window restore */
        nop
        
@@ -212,6 +216,7 @@ asm_call_jit_compiler:
 
 
        brz     pv_caller,L_asm_call_jit_compiler_exception
+       nop
 
        /* synchronise instruction cache moved somewhere else           */
 
@@ -225,12 +230,14 @@ L_asm_call_jit_compiler_exception:
        mov     ra_caller,xpc_itmp3   /* save return address (xpc)                */
        
        call    exceptions_get_and_clear_exception
+       nop
 
        mov     xpc_itmp3,ra_caller   /* restore return address (xpc)             */
 
        mov     %o0,xptr_itmp2        /* get exception                            */
        sub     ra_caller,4,xpc_itmp3 /* exception address is ra - 4              */
        ba      L_asm_handle_nat_exception
+       nop
 
 
 
@@ -247,11 +254,69 @@ L_asm_call_jit_compiler_exception:
 
 asm_handle_nat_exception:
 L_asm_handle_nat_exception:       /* required for PIC code                    */
+L_asm_handle_exception_stack_loop:
+       /* exception handling assumes that the current java method saved       */
+       /* the caller's window                                                 */
+
+       /* get ra and pv before saving the window */
+       mov     ra_callee,itmp1
+       mov     pv_callee,%g4
+
+       save    %sp,-176,%sp
+       mov     xptr_itmp2,%l0              /* save exception pointer             */
+       mov     xpc_itmp3,%l1               /* save exception pc                  */
+       mov     zero,%l2                    /* save maybe-leaf flag (cleared)     */
+
+       mov     %l0,%o0                     /* pass xptr                          */
+       mov     %l1,%o1                     /* pass xpc                           */
+       mov     %g4,%o2                     /* pass PV                            */
+       mov     %fp,%o3                     /* pass Java SP                       */
+
 asm_handle_exception:
+       mov     pv_callee,%g4
+
+       /* save bigger stack frame for float args and temps */
+       save    %sp,(FLT_ARG_CNT+FLT_TMP_CNT+ABICALL_OFF)*8,%sp
+
+       SAVE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF)
+       SAVE_FLOAT_TEMPORARY_REGISTERS(ABICALL_OFF+FLT_ARG_CNT)
+
+       mov     xptr_itmp2,%l0              /* save exception pointer             */
+       add     zero,1,%l2                  /* set maybe-leaf flag                */
+
+       mov     %l0,%o0                     /* pass xptr                          */
+       mov     xpc_itmp3,%o1               /* pass xpc                           */
+       mov     %g4,%o2                     /* pass PV                            */
+       mov     %fp,%o3                     /* pass Java SP                       */
+
+L_asm_handle_exception_continue:
+       call    exceptions_handle_exception
+
+       brz     %o0,L_asm_handle_exception_not_caught
+
+       mov     %o0,xpc_itmp3               /* move handlerpc into xpc            */
+       mov     %l0,xptr_itmp2              /* restore exception pointer          */
+
+       brz     %l2,L_asm_handle_exception_no_leaf
+
+       RESTORE_FLOAT_ARGUMENT_REGISTERS(ABICALL_OFF)
+       RESTORE_FLOAT_TEMPORARY_REGISTERS(ABICALL_OFF+FLT_ARG_CNT)
+       
+L_asm_handle_exception_no_leaf:
+       /* restore java window and stackframe (ra and pv are in there) */
+       restore
+       jmpl    xpc_itmp3, zero             /* jump to the handler                */
+
+L_asm_handle_exception_not_caught:
+       mov     %l0,xptr_itmp2              /* restore xptr                       */
+       restore                             /* free our stackframe and window     */
+       /* maybe leaf flag gets cleared after branch to _loop */
+       
+       restore                             /* unwind stack and window            */
+       ba      L_asm_handle_exception_stack_loop
+       mov     xpc_itmp3,ra_caller         /* the new xpc is ra (delay)          */
        
-       /* nothing here */
 
-       restore zero,0,zero
 
 
 /* asm_abstractmethoderror *****************************************************
index 05cf1901f05627b595a2040cc457a15f1bae72c1..8553317cd885139524a7254b0806ca0208947c86 100644 (file)
@@ -212,6 +212,7 @@ bool codegen(jitdata *jd)
                if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
                        if (!md->params[p].inmemory) {           /* register arguments    */
                                s2 = rd->argintregs[s1];
+                               s2 = REG_WINDOW_TRANSPOSE(s2);
                                if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
                                        M_INTMOVE(s2, var->vv.regoff);
 
@@ -1793,8 +1794,9 @@ bool codegen(jitdata *jd)
                                codegen_addpatchref(cd, PATCHER_athrow_areturn,
                                                                        iptr->sx.s23.s2.uc, 0);
 
-                               if (opt_showdisassemble)
-                                       M_NOP;
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP;
+                               }
                        }
 #endif /* ENABLE_VERIFIER */
 
@@ -2213,8 +2215,9 @@ bool codegen(jitdata *jd)
                                codegen_addpatchref(cd, PATCHER_athrow_areturn,
                                                                        iptr->sx.s23.s2.uc, 0);
 
-                               if (opt_showdisassemble)
-                                       M_NOP;
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP;
+                               }
                        }
 #endif /* ENABLE_VERIFIER */
                        goto nowperformreturn;
@@ -2266,7 +2269,7 @@ nowperformreturn:
 
 
 
-                       M_RETURN(REG_RA_CALLEE); /* implicit window restore */
+                       M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
                        M_NOP;
                        ALIGNCODENOP;
                        }
@@ -2430,33 +2433,20 @@ gen_method:
 
                        switch (iptr->opc) {
                        case ICMD_BUILTIN:
-               /* XXX needs manual attention! */
                                disp = dseg_addaddress(cd, bte->fp);
-                               d = md->returntype.type;
-
-                               M_ALD(REG_ITMP3, REG_PV, disp);  /* built-in-function pointer */
-                               M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
-                               M_NOP;
-/* XXX: how do builtins handle the register window? */
-/*                             disp = (s4) (cd->mcodeptr - cd->mcodebase);*/
-/*                             M_LDA(REG_PV, REG_RA, -disp);*/
 
+                               M_ALD(REG_PV_CALLER, REG_PV, disp);  /* built-in-function pointer */
+                               s1 = REG_PV_CALLER;
 
-                               if (INSTRUCTION_MUST_CHECK(iptr)) {
-                                       M_BEQZ(REG_RESULT_CALLER, 0);
-                                       codegen_add_fillinstacktrace_ref(cd);
-                                       M_NOP;
-                               }
                                break;
 
                        case ICMD_INVOKESPECIAL:
-                               M_BEQZ(REG_A0, 0);
+                               M_BEQZ(REG_OUT0, 0);
                                codegen_add_nullpointerexception_ref(cd);
                                M_NOP;
                                /* fall through */
 
                        case ICMD_INVOKESTATIC:
-               /* XXX needs manual attention! */
                                if (lm == NULL) {
                                        disp = dseg_addaddress(cd, NULL);
 
@@ -2470,14 +2460,12 @@ gen_method:
                                else
                                        disp = dseg_addaddress(cd, lm->stubroutine);
 
-                               M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in callee pv */
-                               M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
-                               M_NOP;
-/* XXX no need to restore PV, when its in the regs  */
+                               M_ALD(REG_PV_CALLER, REG_PV, disp);          /* method pointer in pv */
+                               s1 = REG_PV_CALLER;
                                break;
 
                        case ICMD_INVOKEVIRTUAL:
-                               gen_nullptr_check(REG_A0);
+                               gen_nullptr_check(REG_OUT0);
 
                                if (lm == NULL) {
                                        codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
@@ -2492,16 +2480,13 @@ gen_method:
                                        s1 = OFFSET(vftbl_t, table[0]) +
                                                sizeof(methodptr) * lm->vftblindex;
 
-                               M_ALD(REG_METHODPTR, REG_A0,
+                               M_ALD(REG_METHODPTR, REG_OUT0,
                                          OFFSET(java_objectheader, vftbl));
                                M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
-                               M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
-                               M_NOP;
-/* XXX no need to restore PV, when its in the regs  */
+                               s1 = REG_PV_CALLER;
                                break;
 
                        case ICMD_INVOKEINTERFACE:
-               /* XXX needs manual attention! */
                                gen_nullptr_check(rd->argintregs[0]);
 
                                if (lm == NULL) {
@@ -2521,17 +2506,33 @@ gen_method:
                                        s2 = sizeof(methodptr) * (lm - lm->class->methods);
                                }
 
-                               M_ALD(REG_METHODPTR, REG_A0,
+                               M_ALD(REG_METHODPTR, REG_OUT0,
                                          OFFSET(java_objectheader, vftbl));
                                M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
                                M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
-                               M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
-                               M_NOP;
-/* XXX no need to restore PV, when its in the regs  */
+                               s1 = REG_PV_CALLER;
                                break;
                        }
 
-                       /* d contains return type */
+                       /* generate the actual call */
+
+                       M_JMP(REG_RA_CALLER, s1, REG_ZERO);
+                       M_NOP;
+                       disp = (s4) (cd->mcodeptr - cd->mcodebase);
+                       /* REG_RA holds the value of the jmp instruction, therefore +8 */
+                       M_LDA(REG_PV, REG_RA_CALLER, -disp + 8); 
+
+                       /* actually only used for ICMD_BUILTIN */
+
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               M_BEQZ(REG_RESULT_CALLER, 0);
+                               codegen_add_fillinstacktrace_ref(cd);
+                               M_NOP;
+                       }
+
+                       /* store return value */
+
+                       d = md->returntype.type;
 
                        if (d != TYPE_VOID) {
                                if (IS_INT_LNG_TYPE(d)) {
@@ -2856,9 +2857,236 @@ u1 *createcompilerstub(methodinfo *m)
 
 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 {
-       /* fabort("help me!"); */
-       printf("createnativestub not implemented\n");
-       return NULL;
+       methodinfo   *m;
+       codeinfo     *code;
+       codegendata  *cd;
+       registerdata *rd;
+       methoddesc   *md;
+       s4            nativeparams;
+       s4            i, j;                 /* count variables                    */
+       s4            t;
+       s4            s1, s2, disp;
+       s4            funcdisp;             /* displacement of the function       */
+
+       /* get required compiler data */
+
+       m    = jd->m;
+       code = jd->code;
+       cd   = jd->cd;
+       rd   = jd->rd;
+
+       /* rewrite registers and params */
+       md_native_reg_setup(jd);
+       md_native_param_alloc(nmd);
+
+       /* initialize variables */
+
+       md = m->parseddesc;
+       nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
+
+       /* calculate stack frame size */
+
+       cd->stackframesize =
+               sizeof(stackframeinfo) / SIZEOF_VOID_P +
+               sizeof(localref_table) / SIZEOF_VOID_P +
+               md->paramcount +                /* for saving arguments over calls    */
+               nmd->memuse +  /* nmd knows about the native stackframe layout */
+               WINSAVE_CNT;
+
+       /* create method header */
+
+       (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
+       (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
+       (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
+       (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
+       (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
+       (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
+       (void) dseg_addlinenumbertablesize(cd);
+       (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
+
+       /* generate stub code */
+
+       M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe    */
+
+#if !defined(NDEBUG)
+       if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
+               emit_verbosecall_enter(jd);
+#endif
+
+       /* get function address (this must happen before the stackframeinfo) */
+
+       funcdisp = dseg_addaddress(cd, f);
+
+#if !defined(WITH_STATIC_CLASSPATH)
+       if (f == NULL) {
+               codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
+
+               if (opt_showdisassemble) {
+                       M_NOP; M_NOP;
+               }
+       }
+#endif
+
+       /* save float argument registers */
+
+       for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
+               if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
+                       M_DST(rd->argfltregs[i], REG_SP, j * 8);
+                       j++;
+               }
+       }
+
+       /* prepare data structures for native function call */
+
+       M_MOV(REG_FP, REG_OUT0); /* top of the stack frame */
+       M_MOV(REG_PV_CALLEE, REG_OUT1);
+       M_MOV(REG_FP, REG_OUT2); /* java sp */
+       M_MOV(REG_RA_CALLEE, REG_OUT3);
+       disp = dseg_addaddress(cd, codegen_start_native_call);
+       M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
+       M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
+       M_NOP; /* XXX fill me! */
+
+       /* restore float argument registers */
+
+       for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
+               if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
+                       M_DLD(rd->argfltregs[i], REG_SP, j * 8);
+                       j++;
+               }
+       }
+
+       /* copy or spill arguments to new locations */
+
+       for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
+               t = md->paramtypes[i].type;
+
+               if (IS_INT_LNG_TYPE(t)) {
+                       if (!md->params[i].inmemory) {
+                               s1 = rd->argintregs[md->params[i].regoff];
+                               /* s1 refers to the old window, transpose */
+                               s1 = REG_WINDOW_TRANSPOSE(s1);
+
+                               if (!nmd->params[j].inmemory) {
+                                       s2 = rd->argintregs[nmd->params[j].regoff];
+                                       M_INTMOVE(s1, s2);
+                               } else {
+                                       s2 = nmd->params[j].regoff;
+                                       M_AST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
+                               }
+
+                       } else {
+                               s1 = md->params[i].regoff + cd->stackframesize;
+                               s2 = nmd->params[j].regoff;
+                               M_ALD(REG_ITMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
+                               M_AST(REG_ITMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
+                       }
+
+               } else {
+                       if (!md->params[i].inmemory) {
+                               s1 = rd->argfltregs[md->params[i].regoff];
+
+                               if (!nmd->params[j].inmemory) {
+                                       s2 = rd->argfltregs[nmd->params[j].regoff];
+                                       if (IS_2_WORD_TYPE(t))
+                                               M_DMOV(s1, s2);
+                                       else
+                                               M_DMOV(s1, s2);
+
+                               } else {
+                                       s2 = nmd->params[j].regoff;
+                                       if (IS_2_WORD_TYPE(t))
+                                               M_DST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
+                                       else
+                                               M_FST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
+                               }
+
+                       } else {
+                               s1 = md->params[i].regoff + cd->stackframesize;
+                               s2 = nmd->params[j].regoff;
+                               if (IS_2_WORD_TYPE(t)) {
+                                       M_DLD(REG_FTMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
+                                       M_DST(REG_FTMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
+                               } else {
+                                       M_FLD(REG_FTMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
+                                       M_FST(REG_FTMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
+                               }
+                       }
+               }
+       }
+
+
+       /* put class into second argument register */
+
+       if (m->flags & ACC_STATIC) {
+               disp = dseg_addaddress(cd, m->class);
+               M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
+       }
+
+       /* put env into first argument register */
+
+       disp = dseg_addaddress(cd, _Jv_env);
+       M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
+
+       /* do the native function call */
+
+       M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method       */
+       M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method                 */
+       M_NOP;                              /* delay slot                         */
+
+       /* save return value */
+
+       if (md->returntype.type != TYPE_VOID) {
+               if (IS_INT_LNG_TYPE(md->returntype.type))
+                       M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
+               else
+                       M_DST(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+       }
+
+#if !defined(NDEBUG)
+       if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
+               emit_verbosecall_exit(jd);
+#endif
+
+       /* remove native stackframe info */
+
+       M_MOV(REG_FP, REG_OUT0);
+       disp = dseg_addaddress(cd, codegen_finish_native_call);
+       M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
+       M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
+       M_NOP; /* XXX fill me! */
+       M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
+
+       /* restore float return value, int return value already in our return reg */
+
+       if (md->returntype.type != TYPE_VOID) {
+               if (IS_FLT_DBL_TYPE(md->returntype.type)) {
+                       M_DLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+               }
+       }
+
+       /* check for exception */
+
+       M_BNEZ(REG_ITMP2_XPTR, 4);          /* if no exception then return        */
+       M_RESTORE(REG_ZERO, REG_ZERO, REG_ZERO); /* restore callers window (DELAY)*/
+
+       M_RET(REG_RA_CALLER, 8);            /* return to caller                   */
+       M_NOP;                              /* DELAY SLOT                         */
+
+       /* handle exception */
+       
+       disp = dseg_addaddress(cd, asm_handle_nat_exception);
+       M_ALD(REG_ITMP3, REG_PV, disp);     /* load asm exception handler address */
+       M_JMP(REG_ZERO, REG_ITMP3, REG_ZERO);/* jump to asm exception handler     */
+       M_MOV(REG_RA_CALLER, REG_ITMP3_XPC); /* get exception address (DELAY)    */
+
+       /* generate patcher stubs */
+
+       emit_patcher_stubs(jd);
+
+       codegen_finish(jd);
+
+       return code->entrypoint;
 }
 
 /*
index faa2fa422be79e045a697151b4e4ab8f307fadb5..e1587fe00523bb9055ae5788c31fb82a7825b00b 100644 (file)
 
 
 #define M_SAVE(rs1,rs2,rd)      M_OP3(0x02,0x3c,rd,rs1,rs2,IMM)
-#define M_REST(rs1,rs2,rd)      M_OP3(0x02,0x37,rd,rs1,rs2,IMM)
+#define M_RESTORE(rs1,rs2,rd)   M_OP3(0x02,0x37,rd,rs1,rs2,IMM)
 
 
 
 #define M_JMP(rd,rs1,rs2)       M_OP3(0x02,0x38,rd, rs1,rs2,REG)  /* jump to rs1+rs2, adr of instr. saved to rd */
 #define M_JMP_IMM(rd,rs1,rs2)   M_OP3(0x02,0x38,rd, rs1,rs2,IMM)
-#define M_RET(rs)                              M_OP3(0x02,0x38,REG_ZERO,rs,REG_ZERO,REG)
+#define M_RET(rs1,imm)          M_OP3(0x02,0x38,REG_ZERO,rs1,imm,IMM) /* a jump which discards the current pc */
 
-#define M_RETURN(rs)            M_OP3(0x02,0x39,0,rs,REG_ZERO,REG) /* like ret, but does window restore */
+#define M_RETURN(rs1,imm)       M_OP3(0x02,0x39,0,rs1,imm,IMM) /* like ret, but does window restore */
  
 /**** floating point operations **/
 
index 30982adc8feca48d2880b86e708dcdd535f232ed..5a95661e5dd10de8e06ba6b618f205b8ee2206fc 100644 (file)
@@ -253,12 +253,13 @@ void emit_verbosecall_enter(jitdata *jd)
 
        M_NOP;
 
-       M_LDA(REG_SP, REG_SP, -(1 + WINSAVE_CNT + FLT_ARG_CNT) * 8);
+       /* we're calling a c function allocate paramter array */
+       M_LDA(REG_SP, REG_SP, -(1 + FLT_ARG_CNT + ABI_PARAMARRAY_SLOTS) * 8);
 
        /* save float argument registers */
 
        for (i = 0; i < FLT_ARG_CNT; i++)
-               M_DST(rd->argfltregs[i], REG_SP, BIAS + (WINSAVE_CNT + 1 + i) * 8);
+               M_DST(rd->argfltregs[i], REG_SP, USESTACK_PARAMS + (1 + i) * 8);
 
        /* save temporary registers for leaf methods */
 /* XXX no leaf optimization yet
@@ -270,35 +271,39 @@ void emit_verbosecall_enter(jitdata *jd)
                        M_DST(rd->tmpfltregs[i], REG_SP, (2 + ARG_CNT + INT_TMP_CNT + i) * 8);
        }
 */
-       /* load float arguments into integer registers */
+       /* load int/float arguments into integer argument registers */
 
        for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
                t = md->paramtypes[i].type;
 
-               if (IS_FLT_DBL_TYPE(t)) {
+               if (IS_INT_LNG_TYPE(t)) {
+                       M_INTMOVE(REG_WINDOW_TRANSPOSE(rd->argintregs[i]), rd->argintregs[i]);
+               }
+               else {
                        if (IS_2_WORD_TYPE(t)) {
-                               M_DST(rd->argfltregs[i], REG_SP, USESTACK);
-                               M_LDX(rd->argintregs[i], REG_SP, USESTACK);
+                               M_DST(rd->argfltregs[i], REG_SP, USESTACK_PARAMS);
+                               M_LDX(rd->argintregs[i], REG_SP, USESTACK_PARAMS);
                        }
                        else {
-                               M_DST(rd->argfltregs[i], REG_SP, USESTACK);
-                               M_LDX(rd->argintregs[i], REG_SP, USESTACK);
+                               M_DST(rd->argfltregs[i], REG_SP, USESTACK_PARAMS);
+                               M_LDX(rd->argintregs[i], REG_SP, USESTACK_PARAMS);
                        }
                }
        }
-
+       
+       
+       /* method info pointer is passed in argument register 5 */
        disp = dseg_add_address(cd, m);
-       M_ALD(REG_ITMP1, REG_PV_CALLEE, disp);
-       M_AST(REG_ITMP1, REG_SP, USESTACK);
+       M_ALD(REG_OUT5, REG_PV_CALLEE, disp);
        disp = dseg_add_functionptr(cd, builtin_trace_args);
-       M_ALD(REG_PV_CALLER, REG_PV_CALLEE, disp);
-       M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
+       M_ALD(REG_ITMP1, REG_PV_CALLEE, disp);
+       M_JMP(REG_RA_CALLER, REG_ITMP1, REG_ZERO);
        M_NOP;
 
        /* restore float argument registers */
 
        for (i = 0; i < FLT_ARG_CNT; i++)
-               M_DLD(rd->argfltregs[i], REG_SP, BIAS + (WINSAVE_CNT + 1 + i) * 8);
+               M_DLD(rd->argfltregs[i], REG_SP, USESTACK_PARAMS + (1 + i) * 8);
 
        /* restore temporary registers for leaf methods */
 /* XXX no leaf optimization yet
@@ -310,7 +315,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 + WINSAVE_CNT + FLT_ARG_CNT) * 8);
+       M_LDA(REG_SP, REG_SP, (1 + FLT_ARG_CNT + ABI_PARAMARRAY_SLOTS) * 8);
 
        /* mark trace code */
 
@@ -342,10 +347,11 @@ void emit_verbosecall_exit(jitdata *jd)
        /* mark trace code */
 
        M_NOP;
+       
+       /* we're calling a c function allocate paramter array */
+       M_LDA(REG_SP, REG_SP, -(1 + ABI_PARAMARRAY_SLOTS) * 8);
 
-       M_LDA(REG_SP, REG_SP, -2 * 8);           /* keep stack 16-byte aligned ???*/
-
-       M_DST(REG_FRESULT, REG_SP, USESTACK + (1 * 8));
+       M_DST(REG_FRESULT, REG_SP, USESTACK_PARAMS);
 
        disp = dseg_add_address(cd, m);
        M_ALD(rd->argintregs[0], REG_PV_CALLEE, disp);
@@ -359,9 +365,9 @@ void emit_verbosecall_exit(jitdata *jd)
        M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
        M_NOP;
 
-       M_DLD(REG_FRESULT, REG_SP, USESTACK + (1 * 8));
+       M_DLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
 
-       M_LDA(REG_SP, REG_SP, 2 * 8);
+       M_LDA(REG_SP, REG_SP, (1 + ABI_PARAMARRAY_SLOTS) * 8);
 
        /* mark trace code */
 
index f68e03ba5347c1e951f794ff0341370c93ad435d..619abe4dc6bcc1060fff98009bef22f9c93be9f7 100644 (file)
 #include "vm/global.h"
 #include "vm/jit/abi.h"
 
+/* temp */
+#include "mm/memory.h"
+#include <assert.h>
+
 
 /* register descripton array **************************************************/
 
-/* callee point-of-view, after SAVE has been called */
+/* callee point-of-view, after SAVE has been called. */
 s4 nregdescint[] = {
        /* zero  itmp1/g1 itmp2/g2 itmp3/g3 temp/g4  temp/g5  sys/g6   sys/g7 */  
-       REG_RES, REG_RES, REG_RES, REG_RES, REG_TMP, REG_TMP, REG_RES, REG_RES,
+       REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
        
        /* o0    o1       o2       o3       o4       pv/o5    sp/o6    o7/ra  */
        REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_RES, REG_RES, REG_RES,
@@ -56,23 +60,34 @@ s4 nregdescint[] = {
        /* l0    l1       l2       l3       l4       l5       l6       l7     */
        REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
        
-       /* i0    i1       i2       i3       i4       pv/i5    fp/i6    ra/i7  */
+       /* i0/v0 i1       i2       i3       i4       pv/i5    fp/i6    ra/i7  */
        REG_RET, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_RES, REG_RES, REG_RES,
        REG_END
        
-       /* XXX i1 - i4: SAV OR ARG ??? */
+
 };
 
 s4 nregdescfloat[] = {
        REG_RET, REG_RES, REG_RES, REG_RES, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
-       REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
+       REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
        REG_END
 };
 
 
 /* md_param_alloc **************************************************************
 
-   XXX
+   Allocate Arguments to Stackslots according the Calling Conventions
+
+   --- in
+   md->paramcount:           Number of arguments for this method
+   md->paramtypes[].type:    Argument types
+
+   --- out
+   md->params[].inmemory:    Argument spilled on stack
+   md->params[].regoff:      Stack offset or rd->arg[int|flt]regs index
+   md->memuse:               Stackslots needed for argument spilling
+   md->argintreguse:         max number of integer arguments used
+   md->argfltreguse:         max number of float arguments used
 
 *******************************************************************************/
 
@@ -124,12 +139,130 @@ void md_param_alloc(methoddesc *md)
                        break;
                }
        }
+       
+       /* Since O0 is used for passing return values, this */
+       /* argument register usage has to be regarded, too                        */
+       if (IS_INT_LNG_TYPE(md->returntype.type)) {
+               if (reguse < 1)
+                       md->argintreguse = 1;
+       }
+
+       /* fill register and stack usage */
+
+       md->memuse = stacksize;
+}
+
+/* md_native_param_alloc **************************************************************
+
+   XXX
+
+*******************************************************************************/
+
+void md_native_param_alloc(methoddesc *md)
+{
+       paramdesc *pd;
+       s4         i;
+       s4         reguse;
+       s4         stacksize;
+
+       /* set default values */
+
+       reguse = 0;
+       stacksize = 6;
+
+       /* get params field of methoddesc */
+
+       pd = md->params;
+
+       for (i = 0; i < md->paramcount; i++, pd++) {
+               switch (md->paramtypes[i].type) {
+               case TYPE_INT:
+               case TYPE_ADR:
+               case TYPE_LNG:
+                       if (i < INT_NATARG_CNT) {
+                               pd->inmemory = false;
+                               pd->regoff = reguse;
+                               reguse++;
+                               md->argintreguse = reguse;
+
+                       } else {
+                               pd->inmemory = true;
+                               pd->regoff = reguse;
+                               reguse++;
+                               stacksize++;
+                       }
+                       break;
+               case TYPE_FLT:
+               case TYPE_DBL:
+                       if (i < FLT_NATARG_CNT) {
+                               pd->inmemory = false;
+                               pd->regoff = reguse;
+                               reguse++;
+                               md->argfltreguse = reguse;
+                       } else {
+                               pd->inmemory = true;
+                               pd->regoff = reguse;
+                               reguse++;
+                               stacksize++;
+                       }
+                       break;
+               }
+       }
+       
+       /* Since O0 is used for passing return values, this */
+       /* argument register usage has to be regarded, too                        */
+       if (IS_INT_LNG_TYPE(md->returntype.type)) {
+               if (reguse < 1)
+                       md->argintreguse = 1;
+       }
 
        /* fill register and stack usage */
 
        md->memuse = stacksize;
 }
 
+/* reg_setup *******************************************************************
+
+   TODO
+
+*******************************************************************************/
+
+void md_native_reg_setup(jitdata *jd)
+{
+       methodinfo   *m;
+       registerdata *rd;
+       s4            i;
+
+       /* get required compiler data */
+
+       m  = jd->m;
+       rd = jd->rd;
+
+       /* setup the integer register table */
+
+
+       rd->argintregs = DMNEW(s4, INT_NATARG_CNT);
+       rd->argintreguse = 0;
+
+       for (rd->argintreguse = 0, i = 8; rd->argintreguse < INT_NATARG_CNT; i++) {
+               rd->argintregs[rd->argintreguse++] = i;
+       }
+       
+       assert(rd->argintreguse == INT_NATARG_CNT);
+               
+       /* setup the float register table */
+
+       rd->argfltregs = DMNEW(s4, FLT_NATARG_CNT);
+
+       rd->argfltreguse = 0;
+
+
+       for (rd->argfltreguse = 0, i = 0; rd->argfltreguse < FLT_NATARG_CNT; i++) {
+               rd->argfltregs[rd->argfltreguse++] = i;
+       }
+       assert(rd->argfltreguse == FLT_NATARG_CNT);
+
+}
 
 /* md_return_alloc *************************************************************
 
@@ -158,6 +291,8 @@ void md_return_alloc(jitdata *jd, stackptr stackslot)
 {
        methodinfo *m;
        methoddesc *md;
+       
+       assert(0);
 
        /* get required compiler data */
 
index 6ccfacd2bb41c10114c43ed0a3be892152f8fbb7..5564b21aac1e6ccc7e9ee34dfdf574912695a0d4 100644 (file)
 #define REG_FP          30   /* frame pointer                                 */
 #define REG_ZERO         0   /* always zero                                   */
 
-#define REG_A0           8   /* define some argument registers                */
-#define REG_A1           9
-#define REG_A2          10
-#define REG_A3          11
+#define REG_OUT0         8   /* define some argument registers                */
+#define REG_OUT1         9
+#define REG_OUT2        10
+#define REG_OUT3        11
+#define REG_OUT4        12
+#define REG_OUT5        13
 
 /* floating point registers */
 /* only using the lower half of the floating registers for now */
 #define INT_REG_CNT     32   /* number of integer registers                   */
 #define INT_SAV_CNT     12   /* number of int callee saved registers          */
 #define INT_ARG_CNT      5   /* number of int argument registers (-1 for PV)  */
-#define INT_TMP_CNT      2   /* int temp registers (%g4-%g5)                  */
-#define INT_RES_CNT     12   /* number of reserved integer registers          */
+#define INT_TMP_CNT      0   /* int temp registers (%g4-%g5)                  */
+#define INT_RES_CNT     14   /* number of reserved integer registers          */
                              /* pv, zero, %g6, %g7, sp, ra                    */
 
 #define FLT_REG_CNT     16   /* number of float registers                     */
-#define FLT_SAV_CNT      4   /* number of flt callee saved registers          */
+#define FLT_SAV_CNT      0   /* number of flt callee saved registers          */
 #define FLT_ARG_CNT      4   /* number of flt argument registers              */
-#define FLT_TMP_CNT      4   /* number of flt temp registers                  */
+#define FLT_TMP_CNT      8   /* number of flt temp registers                  */
 #define FLT_RES_CNT      3   /* number of reserved float registers            */
                              /* the one "missing" register is the return reg  */
+                             
+/* different argument counts when following the ABI for native functions */
+#define INT_NATARG_CNT   6
+#define FLT_NATARG_CNT  16
 
 #define TRACE_ARGS_NUM   5
 
-/* helpers for stack addressing */
+/* helpers for stack addressing and window handling */
+
+/* SPARC ABI always wants argument slots on the stack, even when not used */
+#define ABI_PARAMARRAY_SLOTS    6
+
+#define WINSAVE_CNT     16    /* number of regs that SPARC saves onto stack    */
+#define ABICALL_OFF     22    /* 8-byte slots for save regs and arg slots      */
+#define BIAS          2047
+#define USESTACK      (WINSAVE_CNT * 8 + BIAS)
+#define USESTACK_PARAMS ((WINSAVE_CNT + ABI_PARAMARRAY_SLOTS) * 8 + BIAS)
+
+
 
-#define WINSAVE_CNT   16    /* number of regs that SPARC saves onto stack    */
-#define BIAS        2047
-#define USESTACK    (WINSAVE_CNT * 8 + BIAS)
+/* applies only when caller's window was saved */
+#define REG_WINDOW_TRANSPOSE(reg) \
+       (reg + 16)
 
 #endif /* _MD_ABI_H */
 
index 0dcf47593fb5a51986ea1f7d88404ccae477f0e3..88a371397ac7a1d9cce784da3204b863b5a006e0 100644 (file)
 #define fa1     %f18
 #define fa2     %f20
 #define fa3     %f22
-#define fs0     %f24
-#define fs1     %f26
-#define fs2     %f28
-#define fs3     %f30
+#define ft7     %f24
+#define ft8     %f26
+#define ft9     %f28
+#define ft10    %f30
 
 
 #define bias    2047
        std     fa0,[%sp + bias + ((0+(off))*8)] ; \
        std     fa1,[%sp + bias + ((1+(off))*8)] ; \
        std     fa2,[%sp + bias + ((2+(off))*8)] ; \
-       std     fa3,[%sp + bias + ((3+(off))*8)]
+       std     fa3,[%sp + bias + ((3+(off))*8)] ;
 
 
 #define RESTORE_FLOAT_ARGUMENT_REGISTERS(off) \
        ldd     [%sp + bias + ((0+(off))*8)],fa0 ; \
        ldd     [%sp + bias + ((1+(off))*8)],fa1 ; \
        ldd     [%sp + bias + ((2+(off))*8)],fa2 ; \
-       ldd     [%sp + bias + ((3+(off))*8)],fa3 ; \
+       ldd     [%sp + bias + ((3+(off))*8)],fa3 ;
+       
+#define SAVE_FLOAT_TEMPORARY_REGISTERS(off) \
+       std     ft0,[%sp + bias + ((0+(off))*8)] ; \
+       std     ft1,[%sp + bias + ((1+(off))*8)] ; \
+       std     ft2,[%sp + bias + ((2+(off))*8)] ; \
+       std     ft3,[%sp + bias + ((3+(off))*8)] ; \
+       std     ft4,[%sp + bias + ((4+(off))*8)] ; \
+       std     ft5,[%sp + bias + ((5+(off))*8)] ; \
+       std     ft6,[%sp + bias + ((6+(off))*8)] ; \
+       std     ft7,[%sp + bias + ((7+(off))*8)] ; \
+       std     ft8,[%sp + bias + ((8+(off))*8)] ; \
+       std     ft9,[%sp + bias + ((9+(off))*8)] ; \
+       std     ft10,[%sp + bias + ((10+(off))*8)] ;
+
+#define RESTORE_FLOAT_TEMPORARY_REGISTERS(off) \
+       ldd     [%sp + bias + ((0+(off))*8)],ft0 ; \
+       ldd     [%sp + bias + ((1+(off))*8)],ft1 ; \
+       ldd     [%sp + bias + ((2+(off))*8)],ft2 ; \
+       ldd     [%sp + bias + ((3+(off))*8)],ft3 ; \
+       ldd     [%sp + bias + ((4+(off))*8)],ft4 ; \
+       ldd     [%sp + bias + ((5+(off))*8)],ft5 ; \
+       ldd     [%sp + bias + ((6+(off))*8)],ft6 ; \
+       ldd     [%sp + bias + ((7+(off))*8)],ft7 ; \
+       ldd     [%sp + bias + ((8+(off))*8)],ft8 ; \
+       ldd     [%sp + bias + ((9+(off))*8)],ft9 ; \
+       ldd     [%sp + bias + ((10+(off))*8)],ft10 ;
        
        
        
-
 #endif /* _MD_ASM_H */
 
 
index 52e0de93449b4e0b77537de387625afe7e33944c..313e3e5c6a1a54115a017ad5d5eb78b869ccc641 100644 (file)
@@ -130,6 +130,10 @@ u1 *md_codegen_get_pv_from_pc(u1 *ra)
 
                pv += offset;
        }
+       else
+       {
+               assert(0);
+       }
 
        return pv;
 }
@@ -218,6 +222,8 @@ u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
 
                        assert(mcode_masked  == 0x0602fb);
 
+                       printf("data segment: pv=0x%08x, offset=%d\n", sfi->pv, offset);
+
                        /* and get the final data segment address */
 
                        pa = sfi->pv + offset;
index 835c2826b74462bcb9264ca324216cd4d8aa154f..39091476ea18a17615ed3decb0c660ae6ea2ddbf 100644 (file)
@@ -72,6 +72,8 @@ java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
        functionptr        f;
        bool               result;
        java_objectheader *e;
+       
+       assert(0);
 
        /* define the patcher function */