/* src/vm/jit/emit-common.c - common code emitter functions
- Copyright (C) 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
+ Copyright (C) 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: emitfuncs.c 4398 2006-01-31 23:43:08Z twisti $
-
*/
#include "config.h"
#include <assert.h>
+#include <stdint.h>
#include "vm/types.h"
#include "vm/jit/emit-common.h"
#include "vm/jit/jit.h"
+#include "vm/jit/patcher-common.h"
#include "vmcore/options.h"
#include "vmcore/statistics.h"
}
+/* emit_patcher_traps **********************************************************
+
+ Generates the code for the patcher traps.
+
+*******************************************************************************/
+
+void emit_patcher_traps(jitdata *jd)
+{
+ codegendata *cd;
+ codeinfo *code;
+ patchref_t *pr;
+ u1 *savedmcodeptr;
+ u1 *tmpmcodeptr;
+ uint32_t mcode;
+
+ /* get required compiler data */
+
+ cd = jd->cd;
+ code = jd->code;
+
+ /* generate patcher traps code */
+
+ for (pr = list_first(code->patchers); pr != NULL; pr = list_next(code->patchers, pr)) {
+
+ /* Calculate the patch position where the original machine
+ code is located and the trap should be placed. */
+
+ tmpmcodeptr = (u1 *) (cd->mcodebase + pr->mpc);
+
+ /* Patch in the trap to call the signal handler (done at
+ compile time). */
+
+ savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
+ cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
+
+ mcode = emit_trap(cd);
+
+ cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
+
+ /* Remember the original machine code which is patched
+ back in later (done at runtime). */
+
+ pr->mcode = mcode;
+ }
+}
+
+
/* emit_bccz *******************************************************************
Emit conditional and unconditional branch instructions on integer
branchmpc = cd->mcodeptr - cd->mcodebase;
disp = target->mpc - branchmpc;
+#if defined(ENABLE_STATISTICS)
+ count_emit_branch++;
+ if ((int8_t)disp == disp) count_emit_branch_8bit++;
+ else if ((int16_t)disp == disp) count_emit_branch_16bit++;
+ else if ((int32_t)disp == disp) count_emit_branch_32bit++;
+# if SIZEOF_VOID_P == 8
+ else if ((int64_t)disp == disp) count_emit_branch_64bit++;
+# endif
+#endif
+
emit_branch(cd, disp, condition, reg, options);
}
else {
void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
{
- list *list;
+ list_t *list;
branch_label_ref_t *br;
s4 mpc;
s4 disp;
/* search if the label is already in the list */
- for (br = list_first_unsynced(list); br != NULL;
- br = list_next_unsynced(list, br)) {
+ for (br = list_first(list); br != NULL; br = list_next(list, br)) {
/* is this entry the correct label? */
if (br->label == label)
break;
}
- /* a branch reference was found */
-
- if (br != NULL) {
- /* calculate the mpc of the branch instruction */
-
- mpc = cd->mcodeptr - cd->mcodebase;
- disp = br->mpc - mpc;
-
- emit_branch(cd, disp, condition, reg, options);
-
- /* now remove the branch reference */
-
- list_remove_unsynced(list, br);
- }
- else {
+ if (br == NULL) {
/* current mcodeptr is the correct position,
afterwards emit the NOPs */
/* generate NOPs as placeholder for branch code */
BRANCH_NOPS;
+ return;
}
+
+ /* Branch reference was found. */
+
+ /* calculate the mpc of the branch instruction */
+
+ mpc = cd->mcodeptr - cd->mcodebase;
+ disp = br->mpc - mpc;
+
+#if defined(ENABLE_STATISTICS)
+ count_emit_branch++;
+ if ((int8_t)disp == disp) count_emit_branch_8bit++;
+ else if ((int16_t)disp == disp) count_emit_branch_16bit++;
+ else if ((int32_t)disp == disp) count_emit_branch_32bit++;
+# if SIZEOF_VOID_P == 8
+ else if ((int64_t)disp == disp) count_emit_branch_64bit++;
+# endif
+#endif
+
+ emit_branch(cd, disp, condition, reg, options);
+
+ /* now remove the branch reference */
+
+ list_remove(list, br);
}
void emit_label(codegendata *cd, s4 label)
{
- list *list;
+ list_t *list;
branch_label_ref_t *br;
s4 mpc;
s4 disp;
/* search if the label is already in the list */
- for (br = list_first_unsynced(list); br != NULL;
- br = list_next_unsynced(list, br)) {
+ for (br = list_first(list); br != NULL; br = list_next(list, br)) {
/* is this entry the correct label? */
if (br->label == label)
break;
}
- /* a branch reference was found */
+ if (br == NULL) {
+ /* No branch reference found, add the label to the list (use
+ invalid values for condition and register). */
- if (br != NULL) {
- /* calculate the mpc of the branch instruction */
+ codegen_branch_label_add(cd, label, -1, -1, BRANCH_OPT_NONE );
+ return;
+ }
+
+ /* Branch reference was found. */
- mpc = cd->mcodeptr - cd->mcodebase;
- disp = mpc - br->mpc;
+ /* calculate the mpc of the branch instruction */
- /* temporary set the mcodeptr */
+ mpc = cd->mcodeptr - cd->mcodebase;
+ disp = mpc - br->mpc;
- mcodeptr = cd->mcodeptr;
- cd->mcodeptr = cd->mcodebase + br->mpc;
+ /* temporary set the mcodeptr */
- emit_branch(cd, disp, br->condition, br->reg, br->options);
+ mcodeptr = cd->mcodeptr;
+ cd->mcodeptr = cd->mcodebase + br->mpc;
- /* restore mcodeptr */
+#if defined(ENABLE_STATISTICS)
+ count_emit_branch++;
+ if ((int8_t)disp == disp) count_emit_branch_8bit++;
+ else if ((int16_t)disp == disp) count_emit_branch_16bit++;
+ else if ((int32_t)disp == disp) count_emit_branch_32bit++;
+# if SIZEOF_VOID_P == 8
+ else if ((int64_t)disp == disp) count_emit_branch_64bit++;
+# endif
+#endif
- cd->mcodeptr = mcodeptr;
+ emit_branch(cd, disp, br->condition, br->reg, br->options);
- /* now remove the branch reference */
+ /* restore mcodeptr */
- list_remove_unsynced(list, br);
- }
- else {
- /* add the label to the list (use invalid values for condition
- and register) */
+ cd->mcodeptr = mcodeptr;
- codegen_branch_label_add(cd, label, -1, -1, BRANCH_OPT_NONE );
- }
+ /* now remove the branch reference */
+
+ list_remove(list, br);
}