/* void builtin_verbosecall_exit(s8 l, double d, float f, methodinfo *m); */
+ /* void trace_java_call_exit(methodinfo *m, uint64_t *return_regs) */
/* mark trace code */
M_NOP;
-#if !defined(ENABLE_SOFTFLOAT)
- M_AADD_IMM(-8, REG_SP);
- M_FSTORE(REG_D1, REG_SP, 0);
-#endif
+ /* to store result on stack */
+ M_AADD_IMM(-8, REG_SP); /* create space for array */
- M_IPUSH_IMM(m); /* push methodinfo */
+ switch (md->returntype.type) {
+ case TYPE_ADR:
+ case TYPE_INT:
+ #if defined(ENABLE_SOFTFLOAT)
+ case TYPE_FLT:
+ #endif
+ M_IST(REG_D0, REG_SP, 0);
+ break;
-#if !defined(ENABLE_SOFTFLOAT)
- M_AADD_IMM(-3*4, REG_SP);
- M_FST(REG_D0, REG_SP, 8);
- M_DST(REG_D0, REG_SP, 0);
-#else
- M_IPUSH_IMM(0);
+ case TYPE_LNG:
+ #if defined(ENABLE_SOFTFLOAT)
+ case TYPE_DBL:
+ #endif
+ M_LST(REG_D1, REG_SP, 0);
+ break;
- M_IPUSH_IMM(0);
- M_IPUSH_IMM(0);
-#endif
+ #if !defined(ENABLE_SOFTFLOAT)
+ case TYPE_FLT: /* FIXME */
+ case TYPE_DBL: /* FIXME */
+ #endif
+
+ case TYPE_VOID: /* nothing */
+ break;
- M_IPUSH(GET_HIGH_REG(REG_RESULT_PACKED))
- M_IPUSH(GET_LOW_REG(REG_RESULT_PACKED)) /* push long result */
+ default:
+ assert(0);
+ }
- M_JSR_IMM(builtin_verbosecall_exit);
+ M_APUSH(REG_SP); /* push address of array */
+ M_IPUSH_IMM(m); /* push methodinfo */
+ M_JSR_IMM(trace_java_call_exit);
+ M_AADD_IMM(8, REG_SP); /* remove args */
/* poping result registers from stack */
- M_IPOP(GET_LOW_REG(REG_RESULT_PACKED))
- M_IPOP(GET_HIGH_REG(REG_RESULT_PACKED))
+ switch (md->returntype.type) {
+ case TYPE_ADR:
+ case TYPE_INT:
+ #if defined(ENABLE_SOFTFLOAT)
+ case TYPE_FLT:
+ #endif
+ M_ILD(REG_D0, REG_SP, 0);
+ break;
-#if !defined(ENABLE_SOFTFLOAT)
- M_DLD(REG_D0, REG_SP, 0)
- M_FLD(REG_D0, REG_SP, 8)
-#endif
- M_AADD_IMM(3*4 + 4, REG_SP);
+ case TYPE_LNG:
+ #if defined(ENABLE_SOFTFLOAT)
+ case TYPE_DBL:
+ #endif
+ M_LLD(REG_D1, REG_SP, 0);
+ break;
-#if !defined(ENABLE_SOFTFLOAT)
- M_FLOAD(REG_D1, REG_SP, 0)
- M_AADD_IMM(8, REG_SP);
-#endif
+ #if !defined(ENABLE_SOFTFLOAT)
+ case TYPE_FLT: /* FIXME */
+ case TYPE_DBL: /* FIXME */
+ #endif
+
+ case TYPE_VOID: /* nothing */
+ break;
+
+ default:
+ assert(0);
+ }
+
+ M_AADD_IMM(8, REG_SP); /* remove space for array */
M_NOP;
}
uint32_t emit_trap(codegendata *cd)
{
- uint16_t mcode;
+ uint32_t mcode;
/* Get machine code which is patched back in later. The
trap is 2 bytes long. */
- mcode = *((uint16_t *) cd->mcodeptr);
+ mcode = *((uint32_t *) cd->mcodeptr);
M_TRAP(EXCEPTION_HARDWARE_PATCHER);
- return (uint32_t) mcode;
+ return mcode;
}
break;
case EXCEPTION_HARDWARE_PATCHER:
xpc -= 2;
+ ra = xpc;
break;
default: assert(0);
p = signal_handle(type, regval, pv, (void*)sp, (void*)ra, (void*)xpc, _p);
- if (type == EXCEPTION_HARDWARE_COMPILER) {
- if (p == NULL) {
- /* exception when compiling the method */
- java_object_t *o = exceptions_get_and_clear_exceptions();
+ switch (type) {
+ case EXCEPTION_HARDWARE_COMPILER:
+ if (p == NULL) {
+ /* exception when compiling the method */
+ java_object_t *o = exceptions_get_and_clear_exceptions();
- _mc->gregs[R_SP] = sp; /* remove RA from stack */
+ _mc->gregs[R_SP] = sp; /* remove RA from stack */
- _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP1] = (intptr_t) o;
- _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP2_XPC] = (intptr_t) xpc;
- _mc->gregs[R_PC] = (intptr_t) asm_handle_exception;
+ _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP1] = (intptr_t) o;
+ _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP2_XPC] = (intptr_t) xpc;
+ _mc->gregs[R_PC] = (intptr_t) asm_handle_exception;
- } else {
- /* compilation ok, execute */
- _mc->gregs[R_PC] = p;
- }
+ } else {
+ /* compilation ok, execute */
+ _mc->gregs[R_PC] = p;
+ }
+ break;
- } else {
- _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP1] = (intptr_t) p;
- _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP2_XPC] = (intptr_t) xpc;
- _mc->gregs[R_PC] = (intptr_t) asm_handle_exception;
+ case EXCEPTION_HARDWARE_PATCHER:
+ if (p == NULL) {
+ /* no expcetion while patching, continue */
+ _mc->gregs[R_PC] = xpc;
+ return;
+ }
+ /* fall-through in case of exception */
+ default:
+ /* a normal exception with normal expcetion handling */
+ _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP1] = (intptr_t) p;
+ _mc->gregs[GREGS_ADRREG_OFF + REG_ATMP2_XPC] = (intptr_t) xpc;
+ _mc->gregs[R_PC] = (intptr_t) asm_handle_exception;
}
}
#include "codegen.h"
-/* patcher_wrapper *************************************************************
-
- Wrapper for all patchers. It also creates the stackframe info
- structure.
-
- If the return value of the patcher function is false, it gets the
- exception object, clears the exception pointer and returns the
- exception.
-
-*******************************************************************************/
-
-#if 0
-java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
-{
- stackframeinfo_t sfi;
- u1 *xpc;
- java_objectheader *o;
- functionptr f;
- bool result;
- java_objectheader *e;
-
- /* define the patcher function */
-
- bool (*patcher_function)(u1 *);
-
- /* get stuff from the stack */
-
- xpc = (u1 *) *((ptrint *) (sp + 6 * 4));
- /* REG_ITMP3 sp + 5 * 4 */
- o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
- /*mcode = *((u4*) (sp + 3 * 4));*/
- /*xmcode = *((u4*) (sp + 2 * 4));*/
- /* unresolved file sp + 1 * 4 */
- f = (functionptr) *((ptrint *) (sp + 0 * 4));
-
-
- /* calculate and set the new return address */
- xpc = xpc - PATCHER_CALL_SIZE;
- *((ptrint *) (sp + 6 * 4)) = (ptrint) xpc;
-
-
- /* cast the passed function to a patcher function */
- patcher_function = (bool (*)(u1 *)) (ptrint) f;
-
- /* enter a monitor on the patching position */
- PATCHER_MONITORENTER;
-
- /* create the stackframeinfo */
-
- /* RA is passed as NULL, but the XPC is correct and can be used in
- stacktrace_stackframeinfo_add for md_codegen_get_pv_from_pc. */
-
- /*
- fprintf(stderr, "EXT STACKFRAME: sfi=%x pv=%x, sp=%x, xpc=%x\n", &sfi, pv, sp+7*4, xpc);
- */
- stacktrace_stackframeinfo_add(&sfi, pv, sp + 7 * 4, xpc, xpc);
-
- /* call the proper patcher function */
- result = (patcher_function)(sp);
-
-
- /* remove the stackframeinfo */
- stacktrace_stackframeinfo_remove(&sfi);
-
- /* check for return value and exit accordingly */
- if (result == false) {
- e = exceptions_get_and_clear_exception();
-
- PATCHER_MONITOREXIT;
-
- return e;
- }
- PATCHER_MARK_PATCHED_MONITOREXIT;
-
- return NULL;
-}
-#endif
-
-
-#define PATCH_BACK_ORIGINAL_MCODE *((u8*)(pr->mpc)) = pr->mcode
+#define PATCH_BACK_ORIGINAL_MCODE *((u4*)(pr->mpc)) = pr->mcode
/* patcher_initialize_class ****************************************************
#endif
PATCH_BACK_ORIGINAL_MCODE;
- md_icacheflush((void*)pr->mpc, 8);
+ md_icacheflush((void*)pr->mpc, 2);
}
*((s2 *) (ra + 10)) = disp;
/* synchronize instruction cache */
- md_icacheflush(ra + 10, 2);
+ md_icacheflush(pr->mpc, 10 + 2 + PATCHER_CALL_SIZE);
return true;
}
/* synchronize inst cache */
- md_icacheflush((void*)(disp+2), SIZEOF_VOID_P);
+ md_icacheflush(pr->mpc, PATCHER_CALL_SIZE+2+SIZEOF_VOID_P);
return true;
}
-#if 0
-/* patcher_resolve_class *******************************************************
-
- Resolves a given unresolved_class pointer. This function does not
- patch any data.
-
-*******************************************************************************/
-
-#ifdef ENABLE_VERIFIER
-bool patcher_resolve_class(patchref_t *pr)
-{
- unresolved_class *uc;
- classinfo *c;
- s4 disp;
-
- /* get stuff from the stack */
- uc = (unresolved_class *) *((ptrint *) (sp + 1 * 4));
- disp = *((s4 *) (sp + 6 * 4));
-
- /* resolve the class */
- if (!resolve_class(uc, resolveEager, false, &c))
- return false;
-
- /* patch back original code */
- PATCH_BACK_ORIGINAL_MCODE;
-
- return true;
-}
-#endif /* ENABLE_VERIFIER */
-#endif
-
/* patcher_resolve_classref_to_classinfo ***************************************
ACONST:
0x4028f2ca: 2479 0000 0000 moveal 0x00000000,%a2
*((ptrint *) (disp+2)) = (ptrint) c;
/* synchronize inst cache */
- md_icacheflush(disp+2, SIZEOF_VOID_P);
+ md_icacheflush(pr->mpc, PATCHER_CALL_SIZE + 2 + SIZEOF_VOID_P);
return true;
}
/* patch back original code */
PATCH_BACK_ORIGINAL_MCODE;
+ md_icacheflush(pr->mpc, 2);
/* patch the field value's address */
if (opt_shownops) disp += PATCHER_CALL_SIZE;
/* patch back original code */
PATCH_BACK_ORIGINAL_MCODE;
+ md_icacheflush(pr->mpc, 2);
/* if we show NOPs, we have to skip them */
if (opt_shownops) ra += PATCHER_CALL_SIZE;
/* patch back original code */
PATCH_BACK_ORIGINAL_MCODE;
+ md_icacheflush(pr->mpc, 2);
/* patch class flags */
if (opt_shownops) disp += PATCHER_CALL_SIZE;
/* patch back original code */
PATCH_BACK_ORIGINAL_MCODE;
+ md_icacheflush(pr->mpc, 2);
/* patch super class' vftbl */
if (opt_shownops) disp += PATCHER_CALL_SIZE;
/* patch back original code */
PATCH_BACK_ORIGINAL_MCODE;
+ md_icacheflush(pr->mpc, 2);
/* if we show NOPs, we have to skip them */
if (opt_shownops) ra += PATCHER_CALL_SIZE;
/* patch back original code */
PATCH_BACK_ORIGINAL_MCODE;
+ md_icacheflush(pr->mpc, 2);
/* if we show NOPs, we have to skip them */
if (opt_shownops) ra += PATCHER_CALL_SIZE;
/* patch back original code */
PATCH_BACK_ORIGINAL_MCODE;
+ md_icacheflush(pr->mpc, 2);
/* patch native function pointer */
if (opt_shownops) disp += PATCHER_CALL_SIZE;
/* patch back original code */
PATCH_BACK_ORIGINAL_MCODE;
+ md_icacheflush(pr->mpc, 2);
/* if we show NOPs, we have to skip them */
if (opt_shownops) ra += PATCHER_CALL_SIZE;