#include <assert.h>
#include <stdint.h>
+#include <algorithm>
+
#include "vm/types.h"
#include "arch.h"
#include "codegen.h"
+#include "toolbox/list.hpp"
+
#include "vm/options.h"
#include "vm/statistics.h"
{
codegendata *cd;
codeinfo *code;
- patchref_t *pr;
u1 *savedmcodeptr;
u1 *tmpmcodeptr;
uint32_t mcode;
cd = jd->cd;
code = jd->code;
- /* generate patcher traps code */
-
- for (pr = (patchref_t*) list_first(code->patchers); pr != NULL; pr = (patchref_t*) list_next(code->patchers, pr)) {
+ // Generate patcher traps code.
+ for (List<patchref_t>::iterator it = code->patchers->begin(); it != code->patchers->end(); it++) {
+ patchref_t& pr = *it;
/* Calculate the patch position where the original machine
code is located and the trap should be placed. */
- tmpmcodeptr = (u1 *) (cd->mcodebase + pr->mpc);
+ tmpmcodeptr = (u1 *) (cd->mcodebase + pr.mpc);
/* Patch in the trap to call the signal handler (done at
compile time). */
/* Remember the original machine code which is patched
back in later (done at runtime). */
- pr->mcode = mcode;
+ pr.mcode = mcode;
}
}
void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
{
- list_t *list;
- branch_label_ref_t *br;
- s4 mpc;
- s4 disp;
-
- /* get the label list */
-
- list = cd->brancheslabel;
+ // Search if the label is already in the list.
+ DumpList<branch_label_ref_t*>::iterator it;
+ for (it = cd->brancheslabel->begin(); it != cd->brancheslabel->end(); it++) {
+ branch_label_ref_t* br = *it;
- /* search if the label is already in the list */
-
- for (br = (branch_label_ref_t*) list_first(list); br != NULL; br = (branch_label_ref_t*) list_next(list, br)) {
/* is this entry the correct label? */
if (br->label == label)
break;
}
- if (br == NULL) {
+ if (it == cd->brancheslabel->end()) {
/* current mcodeptr is the correct position,
afterwards emit the NOPs */
return;
}
- /* Branch reference was found. */
+ // Branch reference was found.
+ branch_label_ref_t* br = *it;
/* calculate the mpc of the branch instruction */
- mpc = cd->mcodeptr - cd->mcodebase;
- disp = br->mpc - mpc;
+ int32_t mpc = cd->mcodeptr - cd->mcodebase;
+ int32_t disp = br->mpc - mpc;
#if defined(ENABLE_STATISTICS)
count_emit_branch++;
emit_branch(cd, disp, condition, reg, options);
- /* now remove the branch reference */
-
- list_remove(list, br);
+ // Now remove the branch reference.
+ cd->brancheslabel->remove(br);
}
void emit_label(codegendata *cd, s4 label)
{
- list_t *list;
- branch_label_ref_t *br;
- s4 mpc;
- s4 disp;
- u1 *mcodeptr;
-
- /* get the label list */
+ u1* mcodeptr;
- list = cd->brancheslabel;
+ // Search if the label is already in the list.
+ DumpList<branch_label_ref_t*>::iterator it;
+ for (it = cd->brancheslabel->begin(); it != cd->brancheslabel->end(); it++) {
+ branch_label_ref_t* br = *it;
- /* search if the label is already in the list */
-
- for (br = (branch_label_ref_t*) list_first(list); br != NULL; br = (branch_label_ref_t*) list_next(list, br)) {
/* is this entry the correct label? */
if (br->label == label)
break;
}
- if (br == NULL) {
+ if (it == cd->brancheslabel->end()) {
/* No branch reference found, add the label to the list (use
invalid values for condition and register). */
return;
}
- /* Branch reference was found. */
+ // Branch reference was found.
+ branch_label_ref_t* br = *it;
- /* calculate the mpc of the branch instruction */
-
- mpc = cd->mcodeptr - cd->mcodebase;
- disp = mpc - br->mpc;
+ // Calculate the mpc of the branch instruction.
+ int32_t mpc = cd->mcodeptr - cd->mcodebase;
+ int32_t disp = mpc - br->mpc;
/* temporary set the mcodeptr */
cd->mcodeptr = mcodeptr;
- /* now remove the branch reference */
-
- list_remove(list, br);
+ // Now remove the branch reference.
+ cd->brancheslabel->remove(br);
}
#if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
-void emit_label_beqz(codegendata *cd, s4 label, s4 reg)
+void emit_label_beqz(codegendata* cd, int label, int reg)
{
emit_label_bccz(cd, label, BRANCH_EQ, reg, BRANCH_OPT_NONE);
}
-void emit_label_bnez(codegendata *cd, s4 label, s4 reg)
+void emit_label_bnez(codegendata* cd, int label, int reg)
{
emit_label_bccz(cd, label, BRANCH_NE, reg, BRANCH_OPT_NONE);
}
+void emit_label_bltz(codegendata* cd, int label, int reg)
+{
+ emit_label_bccz(cd, label, BRANCH_LT, reg, BRANCH_OPT_NONE);
+}
+
+void emit_label_bgtz(codegendata* cd, int label, int reg)
+{
+ emit_label_bccz(cd, label, BRANCH_GT, reg, BRANCH_OPT_NONE);
+}
+
#endif /* SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER */
+/* emit_label_bxx **************************************************************
+
+ Wrappers for label-branches on two integer registers.
+
+ We use PACK_REGS here, so we don't have to change the branchref
+ data structure and the emit_bccz function.
+
+*******************************************************************************/
+
+#if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS
+
+void emit_label_beq(codegendata* cd, int label, int s1, int s2)
+{
+ emit_label_bccz(cd, label, BRANCH_EQ, PACK_REGS(s1, s2), BRANCH_OPT_NONE);
+}
+
+void emit_label_bne(codegendata* cd, int label, int s1, int s2)
+{
+ emit_label_bccz(cd, label, BRANCH_NE, PACK_REGS(s1, s2), BRANCH_OPT_NONE);
+}
+
+#endif /* SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS */
+
+
/* emit_label_bxx **************************************************************
Wrappers for label-branches on condition codes.