From: Christian Thalinger Date: Tue, 26 Aug 2008 09:11:11 +0000 (+0200) Subject: * src/vm/jit/emit-common.c: Moved to .cpp. X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=9407b72fb4989b4cf816b303d14890f75757658a;p=cacao.git * src/vm/jit/emit-common.c: Moved to .cpp. * src/vm/jit/emit-common.h: Likewise. * src/vm/jit/emit-common.cpp: New file. * src/vm/jit/emit-common.hpp: Likewise. * src/vm/jit/Makefile.am, src/vm/jit/alpha/codegen.c, src/vm/jit/alpha/emit.c, src/vm/jit/arm/codegen.c, src/vm/jit/arm/emit.c, src/vm/jit/codegen-common.c, src/vm/jit/i386/codegen.c, src/vm/jit/i386/emit.c, src/vm/jit/m68k/codegen.c, src/vm/jit/m68k/emit.c, src/vm/jit/mips/codegen.c, src/vm/jit/mips/emit.c, src/vm/jit/powerpc/codegen.c, src/vm/jit/powerpc/emit.c, src/vm/jit/powerpc64/codegen.c, src/vm/jit/powerpc64/emit.c, src/vm/jit/s390/codegen.c, src/vm/jit/s390/emit.c, src/vm/jit/sparc64/codegen.c, src/vm/jit/sparc64/emit.c, src/vm/jit/stubs.cpp, src/vm/jit/x86_64/codegen.c, src/vm/jit/x86_64/emit.c: Related changes. --HG-- rename : src/vm/jit/emit-common.c => src/vm/jit/emit-common.cpp rename : src/vm/jit/emit-common.h => src/vm/jit/emit-common.hpp --- diff --git a/src/vm/jit/Makefile.am b/src/vm/jit/Makefile.am index 3e9b34e4c..ca4879870 100644 --- a/src/vm/jit/Makefile.am +++ b/src/vm/jit/Makefile.am @@ -161,8 +161,8 @@ libjit_la_SOURCES = \ $(DISASS_SOURCES) \ dseg.c \ dseg.h \ - emit-common.c \ - emit-common.h \ + emit-common.cpp \ + emit-common.hpp \ exceptiontable.c \ exceptiontable.h \ executionstate.c \ diff --git a/src/vm/jit/alpha/codegen.c b/src/vm/jit/alpha/codegen.c index 369567029..ef63f752e 100644 --- a/src/vm/jit/alpha/codegen.c +++ b/src/vm/jit/alpha/codegen.c @@ -54,7 +54,7 @@ #include "vm/jit/asmpart.h" #include "vm/jit/codegen-common.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/linenumbertable.h" #include "vm/jit/parse.h" diff --git a/src/vm/jit/alpha/emit.c b/src/vm/jit/alpha/emit.c index 0fc5314db..cdb00c327 100644 --- a/src/vm/jit/alpha/emit.c +++ b/src/vm/jit/alpha/emit.c @@ -43,7 +43,7 @@ #include "vm/jit/abi-asm.h" #include "vm/jit/asmpart.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/patcher-common.h" #include "vm/jit/replace.hpp" diff --git a/src/vm/jit/arm/codegen.c b/src/vm/jit/arm/codegen.c index 19ca2733f..caf895697 100644 --- a/src/vm/jit/arm/codegen.c +++ b/src/vm/jit/arm/codegen.c @@ -53,7 +53,7 @@ #include "vm/jit/asmpart.h" #include "vm/jit/codegen-common.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/linenumbertable.h" #include "vm/jit/methodheader.h" diff --git a/src/vm/jit/arm/emit.c b/src/vm/jit/arm/emit.c index b3efb40d2..3fffcdb2b 100644 --- a/src/vm/jit/arm/emit.c +++ b/src/vm/jit/arm/emit.c @@ -42,7 +42,7 @@ #include "vm/jit/abi.h" #include "vm/jit/asmpart.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/patcher-common.h" #include "vm/jit/replace.hpp" diff --git a/src/vm/jit/codegen-common.c b/src/vm/jit/codegen-common.c index 6c006a9a3..a5f830bbc 100644 --- a/src/vm/jit/codegen-common.c +++ b/src/vm/jit/codegen-common.c @@ -82,7 +82,7 @@ #endif #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/linenumbertable.h" #include "vm/jit/methodheader.h" diff --git a/src/vm/jit/emit-common.c b/src/vm/jit/emit-common.c deleted file mode 100644 index 32001deb3..000000000 --- a/src/vm/jit/emit-common.c +++ /dev/null @@ -1,731 +0,0 @@ -/* src/vm/jit/emit-common.c - common code emitter functions - - Copyright (C) 2006, 2007, 2008 - CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO - - This file is part of CACAO. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. - -*/ - - -#include "config.h" - -#include -#include - -#include "vm/types.h" - -#include "arch.h" -#include "codegen.h" - -#include "vm/options.h" -#include "vm/statistics.h" - -#include "vm/jit/emit-common.h" -#include "vm/jit/jit.hpp" -#include "vm/jit/patcher-common.h" - - -/* emit_load_s1 **************************************************************** - - Emits a possible load of the first source operand. - -*******************************************************************************/ - -s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg) -{ - varinfo *src; - s4 reg; - - src = VAROP(iptr->s1); - - reg = emit_load(jd, iptr, src, tempreg); - - return reg; -} - - -/* emit_load_s2 **************************************************************** - - Emits a possible load of the second source operand. - -*******************************************************************************/ - -s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg) -{ - varinfo *src; - s4 reg; - - src = VAROP(iptr->sx.s23.s2); - - reg = emit_load(jd, iptr, src, tempreg); - - return reg; -} - - -/* emit_load_s3 **************************************************************** - - Emits a possible load of the third source operand. - -*******************************************************************************/ - -s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg) -{ - varinfo *src; - s4 reg; - - src = VAROP(iptr->sx.s23.s3); - - reg = emit_load(jd, iptr, src, tempreg); - - return reg; -} - - -/* emit_load_s1_low ************************************************************ - - Emits a possible load of the low 32-bits of the first long source - operand. - -*******************************************************************************/ - -#if SIZEOF_VOID_P == 4 -s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg) -{ - varinfo *src; - s4 reg; - - src = VAROP(iptr->s1); - - reg = emit_load_low(jd, iptr, src, tempreg); - - return reg; -} -#endif - - -/* emit_load_s2_low ************************************************************ - - Emits a possible load of the low 32-bits of the second long source - operand. - -*******************************************************************************/ - -#if SIZEOF_VOID_P == 4 -s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg) -{ - varinfo *src; - s4 reg; - - src = VAROP(iptr->sx.s23.s2); - - reg = emit_load_low(jd, iptr, src, tempreg); - - return reg; -} -#endif - - -/* emit_load_s3_low ************************************************************ - - Emits a possible load of the low 32-bits of the third long source - operand. - -*******************************************************************************/ - -#if SIZEOF_VOID_P == 4 -s4 emit_load_s3_low(jitdata *jd, instruction *iptr, s4 tempreg) -{ - varinfo *src; - s4 reg; - - src = VAROP(iptr->sx.s23.s3); - - reg = emit_load_low(jd, iptr, src, tempreg); - - return reg; -} -#endif - - -/* emit_load_s1_high *********************************************************** - - Emits a possible load of the high 32-bits of the first long source - operand. - -*******************************************************************************/ - -#if SIZEOF_VOID_P == 4 -s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg) -{ - varinfo *src; - s4 reg; - - src = VAROP(iptr->s1); - - reg = emit_load_high(jd, iptr, src, tempreg); - - return reg; -} -#endif - - -/* emit_load_s2_high *********************************************************** - - Emits a possible load of the high 32-bits of the second long source - operand. - -*******************************************************************************/ - -#if SIZEOF_VOID_P == 4 -s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg) -{ - varinfo *src; - s4 reg; - - src = VAROP(iptr->sx.s23.s2); - - reg = emit_load_high(jd, iptr, src, tempreg); - - return reg; -} -#endif - - -/* emit_load_s3_high *********************************************************** - - Emits a possible load of the high 32-bits of the third long source - operand. - -*******************************************************************************/ - -#if SIZEOF_VOID_P == 4 -s4 emit_load_s3_high(jitdata *jd, instruction *iptr, s4 tempreg) -{ - varinfo *src; - s4 reg; - - src = VAROP(iptr->sx.s23.s3); - - reg = emit_load_high(jd, iptr, src, tempreg); - - return reg; -} -#endif - - -/* emit_store_dst ************************************************************** - - This function generates the code to store the result of an - operation back into a spilled pseudo-variable. If the - pseudo-variable has not been spilled in the first place, this - function will generate nothing. - -*******************************************************************************/ - -void emit_store_dst(jitdata *jd, instruction *iptr, s4 d) -{ - emit_store(jd, iptr, VAROP(iptr->dst), d); -} - - -/* 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 - regiseters. - -*******************************************************************************/ - -void emit_bccz(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options) -{ - s4 branchmpc; - s4 disp; - - /* Target basic block already has an PC, so we can generate the - branch immediately. */ - - if ((target->mpc >= 0)) { - STATISTICS(count_branches_resolved++); - - /* calculate the mpc of the branch instruction */ - - 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 { - /* current mcodeptr is the correct position, - afterwards emit the NOPs */ - - codegen_add_branch_ref(cd, target, condition, reg, options); - - /* generate NOPs as placeholder for branch code */ - - BRANCH_NOPS; - } -} - - -/* emit_bcc ******************************************************************** - - Emit conditional and unconditional branch instructions on condition - codes. - -*******************************************************************************/ - -void emit_bcc(codegendata *cd, basicblock *target, s4 condition, u4 options) -{ - emit_bccz(cd, target, condition, -1, options); -} - - -/* emit_br ********************************************************************* - - Wrapper for unconditional branches. - -*******************************************************************************/ - -void emit_br(codegendata *cd, basicblock *target) -{ - emit_bcc(cd, target, BRANCH_UNCONDITIONAL, BRANCH_OPT_NONE); -} - - -/* emit_bxxz ******************************************************************* - - Wrappers for branches on one integer register. - -*******************************************************************************/ - -#if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER - -void emit_beqz(codegendata *cd, basicblock *target, s4 reg) -{ - emit_bccz(cd, target, BRANCH_EQ, reg, BRANCH_OPT_NONE); -} - -void emit_bnez(codegendata *cd, basicblock *target, s4 reg) -{ - emit_bccz(cd, target, BRANCH_NE, reg, BRANCH_OPT_NONE); -} - -void emit_bltz(codegendata *cd, basicblock *target, s4 reg) -{ - emit_bccz(cd, target, BRANCH_LT, reg, BRANCH_OPT_NONE); -} - -void emit_bgez(codegendata *cd, basicblock *target, s4 reg) -{ - emit_bccz(cd, target, BRANCH_GE, reg, BRANCH_OPT_NONE); -} - -void emit_bgtz(codegendata *cd, basicblock *target, s4 reg) -{ - emit_bccz(cd, target, BRANCH_GT, reg, BRANCH_OPT_NONE); -} - -void emit_blez(codegendata *cd, basicblock *target, s4 reg) -{ - emit_bccz(cd, target, BRANCH_LE, reg, BRANCH_OPT_NONE); -} - -#endif /* SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER */ - - -/* emit_bxx ******************************************************************** - - Wrappers for 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_beq(codegendata *cd, basicblock *target, s4 s1, s4 s2) -{ - emit_bccz(cd, target, BRANCH_EQ, PACK_REGS(s1, s2), BRANCH_OPT_NONE); -} - -void emit_bne(codegendata *cd, basicblock *target, s4 s1, s4 s2) -{ - emit_bccz(cd, target, BRANCH_NE, PACK_REGS(s1, s2), BRANCH_OPT_NONE); -} - -#endif /* SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS */ - - -/* emit_bxx ******************************************************************** - - Wrappers for branches on condition codes. - -*******************************************************************************/ - -#if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER - -void emit_beq(codegendata *cd, basicblock *target) -{ - emit_bcc(cd, target, BRANCH_EQ, BRANCH_OPT_NONE); -} - -void emit_bne(codegendata *cd, basicblock *target) -{ - emit_bcc(cd, target, BRANCH_NE, BRANCH_OPT_NONE); -} - -void emit_blt(codegendata *cd, basicblock *target) -{ - emit_bcc(cd, target, BRANCH_LT, BRANCH_OPT_NONE); -} - -void emit_bge(codegendata *cd, basicblock *target) -{ - emit_bcc(cd, target, BRANCH_GE, BRANCH_OPT_NONE); -} - -void emit_bgt(codegendata *cd, basicblock *target) -{ - emit_bcc(cd, target, BRANCH_GT, BRANCH_OPT_NONE); -} - -void emit_ble(codegendata *cd, basicblock *target) -{ - emit_bcc(cd, target, BRANCH_LE, BRANCH_OPT_NONE); -} - -#if SUPPORT_BRANCH_CONDITIONAL_UNSIGNED_CONDITIONS -void emit_bult(codegendata *cd, basicblock *target) -{ - emit_bcc(cd, target, BRANCH_ULT, BRANCH_OPT_NONE); -} - -void emit_bule(codegendata *cd, basicblock *target) -{ - emit_bcc(cd, target, BRANCH_ULE, BRANCH_OPT_NONE); -} - -void emit_buge(codegendata *cd, basicblock *target) -{ - emit_bcc(cd, target, BRANCH_UGE, BRANCH_OPT_NONE); -} - -void emit_bugt(codegendata *cd, basicblock *target) -{ - emit_bcc(cd, target, BRANCH_UGT, BRANCH_OPT_NONE); -} -#endif - -#if defined(__POWERPC__) || defined(__POWERPC64__) -void emit_bnan(codegendata *cd, basicblock *target) -{ - emit_bcc(cd, target, BRANCH_NAN, BRANCH_OPT_NONE); -} -#endif - -#endif /* SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER */ - - -/* emit_label_bccz ************************************************************* - - Emit a branch to a label. Possibly emit the branch, if it is a - backward branch. - -*******************************************************************************/ - -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 */ - - for (br = list_first(list); br != NULL; br = list_next(list, br)) { - /* is this entry the correct label? */ - - if (br->label == label) - break; - } - - if (br == NULL) { - /* current mcodeptr is the correct position, - afterwards emit the NOPs */ - - codegen_branch_label_add(cd, label, condition, reg, options); - - /* 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); -} - - -/* emit_label ****************************************************************** - - Emit a label for a branch. Possibly emit the branch, if it is a - forward branch. - -*******************************************************************************/ - -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 */ - - list = cd->brancheslabel; - - /* search if the label is already in the list */ - - for (br = list_first(list); br != NULL; br = list_next(list, br)) { - /* is this entry the correct label? */ - - if (br->label == label) - break; - } - - if (br == NULL) { - /* No branch reference found, add the label to the list (use - invalid values for condition and register). */ - - codegen_branch_label_add(cd, label, -1, -1, BRANCH_OPT_NONE ); - return; - } - - /* Branch reference was found. */ - - /* calculate the mpc of the branch instruction */ - - mpc = cd->mcodeptr - cd->mcodebase; - disp = mpc - br->mpc; - - /* temporary set the mcodeptr */ - - mcodeptr = cd->mcodeptr; - cd->mcodeptr = cd->mcodebase + br->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, br->condition, br->reg, br->options); - - /* restore mcodeptr */ - - cd->mcodeptr = mcodeptr; - - /* now remove the branch reference */ - - list_remove(list, br); -} - - -/* emit_label_bcc ************************************************************** - - Emit conditional and unconditional label-branch instructions on - condition codes. - -*******************************************************************************/ - -void emit_label_bcc(codegendata *cd, s4 label, s4 condition, u4 options) -{ - emit_label_bccz(cd, label, condition, -1, options); -} - - -/* emit_label_br *************************************************************** - - Wrapper for unconditional label-branches. - -*******************************************************************************/ - -void emit_label_br(codegendata *cd, s4 label) -{ - emit_label_bcc(cd, label, BRANCH_UNCONDITIONAL, BRANCH_OPT_NONE); -} - - -/* emit_label_bxxz ************************************************************* - - Wrappers for label-branches on one integer register. - -*******************************************************************************/ - -#if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER - -void emit_label_beqz(codegendata *cd, s4 label, s4 reg) -{ - emit_label_bccz(cd, label, BRANCH_EQ, reg, BRANCH_OPT_NONE); -} - -#endif /* SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER */ - - -/* emit_label_bxx ************************************************************** - - Wrappers for label-branches on condition codes. - -*******************************************************************************/ - -#if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER - -void emit_label_beq(codegendata *cd, s4 label) -{ - emit_label_bcc(cd, label, BRANCH_EQ, BRANCH_OPT_NONE); -} - -void emit_label_bne(codegendata *cd, s4 label) -{ - emit_label_bcc(cd, label, BRANCH_NE, BRANCH_OPT_NONE); -} - -void emit_label_blt(codegendata *cd, s4 label) -{ - emit_label_bcc(cd, label, BRANCH_LT, BRANCH_OPT_NONE); -} - -void emit_label_bge(codegendata *cd, s4 label) -{ - emit_label_bcc(cd, label, BRANCH_GE, BRANCH_OPT_NONE); -} - -void emit_label_bgt(codegendata *cd, s4 label) -{ - emit_label_bcc(cd, label, BRANCH_GT, BRANCH_OPT_NONE); -} - -void emit_label_ble(codegendata *cd, s4 label) -{ - emit_label_bcc(cd, label, BRANCH_LE, BRANCH_OPT_NONE); -} - -#endif /* SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER */ - - -/* - * These are local overrides for various environment variables in Emacs. - * Please do not remove this and leave it at the end of the file, where - * Emacs will automagically detect them. - * --------------------------------------------------------------------- - * Local variables: - * mode: c - * indent-tabs-mode: t - * c-basic-offset: 4 - * tab-width: 4 - * End: - * vim:noexpandtab:sw=4:ts=4: - */ diff --git a/src/vm/jit/emit-common.cpp b/src/vm/jit/emit-common.cpp new file mode 100644 index 000000000..0535e0276 --- /dev/null +++ b/src/vm/jit/emit-common.cpp @@ -0,0 +1,731 @@ +/* src/vm/jit/emit-common.cpp - common code emitter functions + + Copyright (C) 2006, 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO + + This file is part of CACAO. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + +*/ + + +#include "config.h" + +#include +#include + +#include "vm/types.h" + +#include "arch.h" +#include "codegen.h" + +#include "vm/options.h" +#include "vm/statistics.h" + +#include "vm/jit/emit-common.hpp" +#include "vm/jit/jit.hpp" +#include "vm/jit/patcher-common.h" + + +/* emit_load_s1 **************************************************************** + + Emits a possible load of the first source operand. + +*******************************************************************************/ + +s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg) +{ + varinfo *src; + s4 reg; + + src = VAROP(iptr->s1); + + reg = emit_load(jd, iptr, src, tempreg); + + return reg; +} + + +/* emit_load_s2 **************************************************************** + + Emits a possible load of the second source operand. + +*******************************************************************************/ + +s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg) +{ + varinfo *src; + s4 reg; + + src = VAROP(iptr->sx.s23.s2); + + reg = emit_load(jd, iptr, src, tempreg); + + return reg; +} + + +/* emit_load_s3 **************************************************************** + + Emits a possible load of the third source operand. + +*******************************************************************************/ + +s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg) +{ + varinfo *src; + s4 reg; + + src = VAROP(iptr->sx.s23.s3); + + reg = emit_load(jd, iptr, src, tempreg); + + return reg; +} + + +/* emit_load_s1_low ************************************************************ + + Emits a possible load of the low 32-bits of the first long source + operand. + +*******************************************************************************/ + +#if SIZEOF_VOID_P == 4 +s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg) +{ + varinfo *src; + s4 reg; + + src = VAROP(iptr->s1); + + reg = emit_load_low(jd, iptr, src, tempreg); + + return reg; +} +#endif + + +/* emit_load_s2_low ************************************************************ + + Emits a possible load of the low 32-bits of the second long source + operand. + +*******************************************************************************/ + +#if SIZEOF_VOID_P == 4 +s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg) +{ + varinfo *src; + s4 reg; + + src = VAROP(iptr->sx.s23.s2); + + reg = emit_load_low(jd, iptr, src, tempreg); + + return reg; +} +#endif + + +/* emit_load_s3_low ************************************************************ + + Emits a possible load of the low 32-bits of the third long source + operand. + +*******************************************************************************/ + +#if SIZEOF_VOID_P == 4 +s4 emit_load_s3_low(jitdata *jd, instruction *iptr, s4 tempreg) +{ + varinfo *src; + s4 reg; + + src = VAROP(iptr->sx.s23.s3); + + reg = emit_load_low(jd, iptr, src, tempreg); + + return reg; +} +#endif + + +/* emit_load_s1_high *********************************************************** + + Emits a possible load of the high 32-bits of the first long source + operand. + +*******************************************************************************/ + +#if SIZEOF_VOID_P == 4 +s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg) +{ + varinfo *src; + s4 reg; + + src = VAROP(iptr->s1); + + reg = emit_load_high(jd, iptr, src, tempreg); + + return reg; +} +#endif + + +/* emit_load_s2_high *********************************************************** + + Emits a possible load of the high 32-bits of the second long source + operand. + +*******************************************************************************/ + +#if SIZEOF_VOID_P == 4 +s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg) +{ + varinfo *src; + s4 reg; + + src = VAROP(iptr->sx.s23.s2); + + reg = emit_load_high(jd, iptr, src, tempreg); + + return reg; +} +#endif + + +/* emit_load_s3_high *********************************************************** + + Emits a possible load of the high 32-bits of the third long source + operand. + +*******************************************************************************/ + +#if SIZEOF_VOID_P == 4 +s4 emit_load_s3_high(jitdata *jd, instruction *iptr, s4 tempreg) +{ + varinfo *src; + s4 reg; + + src = VAROP(iptr->sx.s23.s3); + + reg = emit_load_high(jd, iptr, src, tempreg); + + return reg; +} +#endif + + +/* emit_store_dst ************************************************************** + + This function generates the code to store the result of an + operation back into a spilled pseudo-variable. If the + pseudo-variable has not been spilled in the first place, this + function will generate nothing. + +*******************************************************************************/ + +void emit_store_dst(jitdata *jd, instruction *iptr, s4 d) +{ + emit_store(jd, iptr, VAROP(iptr->dst), d); +} + + +/* 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 = (patchref_t*) list_first(code->patchers); pr != NULL; pr = (patchref_t*) 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 + regiseters. + +*******************************************************************************/ + +void emit_bccz(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options) +{ + s4 branchmpc; + s4 disp; + + /* Target basic block already has an PC, so we can generate the + branch immediately. */ + + if ((target->mpc >= 0)) { + STATISTICS(count_branches_resolved++); + + /* calculate the mpc of the branch instruction */ + + 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 { + /* current mcodeptr is the correct position, + afterwards emit the NOPs */ + + codegen_add_branch_ref(cd, target, condition, reg, options); + + /* generate NOPs as placeholder for branch code */ + + BRANCH_NOPS; + } +} + + +/* emit_bcc ******************************************************************** + + Emit conditional and unconditional branch instructions on condition + codes. + +*******************************************************************************/ + +void emit_bcc(codegendata *cd, basicblock *target, s4 condition, u4 options) +{ + emit_bccz(cd, target, condition, -1, options); +} + + +/* emit_br ********************************************************************* + + Wrapper for unconditional branches. + +*******************************************************************************/ + +void emit_br(codegendata *cd, basicblock *target) +{ + emit_bcc(cd, target, BRANCH_UNCONDITIONAL, BRANCH_OPT_NONE); +} + + +/* emit_bxxz ******************************************************************* + + Wrappers for branches on one integer register. + +*******************************************************************************/ + +#if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER + +void emit_beqz(codegendata *cd, basicblock *target, s4 reg) +{ + emit_bccz(cd, target, BRANCH_EQ, reg, BRANCH_OPT_NONE); +} + +void emit_bnez(codegendata *cd, basicblock *target, s4 reg) +{ + emit_bccz(cd, target, BRANCH_NE, reg, BRANCH_OPT_NONE); +} + +void emit_bltz(codegendata *cd, basicblock *target, s4 reg) +{ + emit_bccz(cd, target, BRANCH_LT, reg, BRANCH_OPT_NONE); +} + +void emit_bgez(codegendata *cd, basicblock *target, s4 reg) +{ + emit_bccz(cd, target, BRANCH_GE, reg, BRANCH_OPT_NONE); +} + +void emit_bgtz(codegendata *cd, basicblock *target, s4 reg) +{ + emit_bccz(cd, target, BRANCH_GT, reg, BRANCH_OPT_NONE); +} + +void emit_blez(codegendata *cd, basicblock *target, s4 reg) +{ + emit_bccz(cd, target, BRANCH_LE, reg, BRANCH_OPT_NONE); +} + +#endif /* SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER */ + + +/* emit_bxx ******************************************************************** + + Wrappers for 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_beq(codegendata *cd, basicblock *target, s4 s1, s4 s2) +{ + emit_bccz(cd, target, BRANCH_EQ, PACK_REGS(s1, s2), BRANCH_OPT_NONE); +} + +void emit_bne(codegendata *cd, basicblock *target, s4 s1, s4 s2) +{ + emit_bccz(cd, target, BRANCH_NE, PACK_REGS(s1, s2), BRANCH_OPT_NONE); +} + +#endif /* SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS */ + + +/* emit_bxx ******************************************************************** + + Wrappers for branches on condition codes. + +*******************************************************************************/ + +#if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER + +void emit_beq(codegendata *cd, basicblock *target) +{ + emit_bcc(cd, target, BRANCH_EQ, BRANCH_OPT_NONE); +} + +void emit_bne(codegendata *cd, basicblock *target) +{ + emit_bcc(cd, target, BRANCH_NE, BRANCH_OPT_NONE); +} + +void emit_blt(codegendata *cd, basicblock *target) +{ + emit_bcc(cd, target, BRANCH_LT, BRANCH_OPT_NONE); +} + +void emit_bge(codegendata *cd, basicblock *target) +{ + emit_bcc(cd, target, BRANCH_GE, BRANCH_OPT_NONE); +} + +void emit_bgt(codegendata *cd, basicblock *target) +{ + emit_bcc(cd, target, BRANCH_GT, BRANCH_OPT_NONE); +} + +void emit_ble(codegendata *cd, basicblock *target) +{ + emit_bcc(cd, target, BRANCH_LE, BRANCH_OPT_NONE); +} + +#if SUPPORT_BRANCH_CONDITIONAL_UNSIGNED_CONDITIONS +void emit_bult(codegendata *cd, basicblock *target) +{ + emit_bcc(cd, target, BRANCH_ULT, BRANCH_OPT_NONE); +} + +void emit_bule(codegendata *cd, basicblock *target) +{ + emit_bcc(cd, target, BRANCH_ULE, BRANCH_OPT_NONE); +} + +void emit_buge(codegendata *cd, basicblock *target) +{ + emit_bcc(cd, target, BRANCH_UGE, BRANCH_OPT_NONE); +} + +void emit_bugt(codegendata *cd, basicblock *target) +{ + emit_bcc(cd, target, BRANCH_UGT, BRANCH_OPT_NONE); +} +#endif + +#if defined(__POWERPC__) || defined(__POWERPC64__) +void emit_bnan(codegendata *cd, basicblock *target) +{ + emit_bcc(cd, target, BRANCH_NAN, BRANCH_OPT_NONE); +} +#endif + +#endif /* SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER */ + + +/* emit_label_bccz ************************************************************* + + Emit a branch to a label. Possibly emit the branch, if it is a + backward branch. + +*******************************************************************************/ + +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 */ + + 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) { + /* current mcodeptr is the correct position, + afterwards emit the NOPs */ + + codegen_branch_label_add(cd, label, condition, reg, options); + + /* 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); +} + + +/* emit_label ****************************************************************** + + Emit a label for a branch. Possibly emit the branch, if it is a + forward branch. + +*******************************************************************************/ + +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 */ + + list = cd->brancheslabel; + + /* 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) { + /* No branch reference found, add the label to the list (use + invalid values for condition and register). */ + + codegen_branch_label_add(cd, label, -1, -1, BRANCH_OPT_NONE ); + return; + } + + /* Branch reference was found. */ + + /* calculate the mpc of the branch instruction */ + + mpc = cd->mcodeptr - cd->mcodebase; + disp = mpc - br->mpc; + + /* temporary set the mcodeptr */ + + mcodeptr = cd->mcodeptr; + cd->mcodeptr = cd->mcodebase + br->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, br->condition, br->reg, br->options); + + /* restore mcodeptr */ + + cd->mcodeptr = mcodeptr; + + /* now remove the branch reference */ + + list_remove(list, br); +} + + +/* emit_label_bcc ************************************************************** + + Emit conditional and unconditional label-branch instructions on + condition codes. + +*******************************************************************************/ + +void emit_label_bcc(codegendata *cd, s4 label, s4 condition, u4 options) +{ + emit_label_bccz(cd, label, condition, -1, options); +} + + +/* emit_label_br *************************************************************** + + Wrapper for unconditional label-branches. + +*******************************************************************************/ + +void emit_label_br(codegendata *cd, s4 label) +{ + emit_label_bcc(cd, label, BRANCH_UNCONDITIONAL, BRANCH_OPT_NONE); +} + + +/* emit_label_bxxz ************************************************************* + + Wrappers for label-branches on one integer register. + +*******************************************************************************/ + +#if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER + +void emit_label_beqz(codegendata *cd, s4 label, s4 reg) +{ + emit_label_bccz(cd, label, BRANCH_EQ, reg, BRANCH_OPT_NONE); +} + +#endif /* SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER */ + + +/* emit_label_bxx ************************************************************** + + Wrappers for label-branches on condition codes. + +*******************************************************************************/ + +#if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER + +void emit_label_beq(codegendata *cd, s4 label) +{ + emit_label_bcc(cd, label, BRANCH_EQ, BRANCH_OPT_NONE); +} + +void emit_label_bne(codegendata *cd, s4 label) +{ + emit_label_bcc(cd, label, BRANCH_NE, BRANCH_OPT_NONE); +} + +void emit_label_blt(codegendata *cd, s4 label) +{ + emit_label_bcc(cd, label, BRANCH_LT, BRANCH_OPT_NONE); +} + +void emit_label_bge(codegendata *cd, s4 label) +{ + emit_label_bcc(cd, label, BRANCH_GE, BRANCH_OPT_NONE); +} + +void emit_label_bgt(codegendata *cd, s4 label) +{ + emit_label_bcc(cd, label, BRANCH_GT, BRANCH_OPT_NONE); +} + +void emit_label_ble(codegendata *cd, s4 label) +{ + emit_label_bcc(cd, label, BRANCH_LE, BRANCH_OPT_NONE); +} + +#endif /* SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER */ + + +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c++ + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + * vim:noexpandtab:sw=4:ts=4: + */ diff --git a/src/vm/jit/emit-common.h b/src/vm/jit/emit-common.h deleted file mode 100644 index 3fec792ab..000000000 --- a/src/vm/jit/emit-common.h +++ /dev/null @@ -1,212 +0,0 @@ -/* src/vm/jit/emit-common.h - 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 - - This file is part of CACAO. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. - -*/ - - -#ifndef _EMIT_COMMON_H -#define _EMIT_COMMON_H - -#include "config.h" -#include "vm/types.h" - -#include "arch.h" - -#include "vm/jit/codegen-common.h" -#include "vm/jit/jit.hpp" - - -/* branch labels **************************************************************/ - -#define BRANCH_LABEL_1 1 -#define BRANCH_LABEL_2 2 -#define BRANCH_LABEL_3 3 -#define BRANCH_LABEL_4 4 -#define BRANCH_LABEL_5 5 -#define BRANCH_LABEL_6 6 - - -/* constant range macros ******************************************************/ - -#if SIZEOF_VOID_P == 8 - -# define IS_IMM8(c) \ - (((s8) (c) >= -128) && ((s8) (c) <= 127)) - -# define IS_IMM32(c) \ - (((s8) (c) >= (-2147483647-1)) && ((s8) (c) <= 2147483647)) - -#else - -# define IS_IMM8(c) \ - (((s4) (c) >= -128) && ((s4) (c) <= 127)) - -# define IS_IMM16(c) \ - (((s4) (c) >= -32768) && ((s4) (c) <= 32767)) - -#endif - - -/* code generation functions **************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg); -s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg); -s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg); -s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg); - -#if SIZEOF_VOID_P == 4 -s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg); -s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg); -s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg); -s4 emit_load_s3_low(jitdata *jd, instruction *iptr, s4 tempreg); - -s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg); -s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg); -s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg); -s4 emit_load_s3_high(jitdata *jd, instruction *iptr, s4 tempreg); -#endif - -void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d); -void emit_store_dst(jitdata *jd, instruction *iptr, s4 d); - -#if SIZEOF_VOID_P == 4 -void emit_store_low(jitdata *jd, instruction *iptr, varinfo *dst, s4 d); -void emit_store_high(jitdata *jd, instruction *iptr, varinfo *dst, s4 d); -#endif - -void emit_copy(jitdata *jd, instruction *iptr); - -void emit_iconst(codegendata *cd, s4 d, s4 value); -void emit_lconst(codegendata *cd, s4 d, s8 value); - -/* branch-emitting functions */ -void emit_bccz(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options); -void emit_bcc(codegendata *cd, basicblock *target, s4 condition, u4 options); - -/* wrapper for unconditional branches */ -void emit_br(codegendata *cd, basicblock *target); - -/* wrappers for branches on one integer register */ - -#if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER -void emit_beqz(codegendata *cd, basicblock *target, s4 reg); -void emit_bnez(codegendata *cd, basicblock *target, s4 reg); -void emit_bltz(codegendata *cd, basicblock *target, s4 reg); -void emit_bgez(codegendata *cd, basicblock *target, s4 reg); -void emit_bgtz(codegendata *cd, basicblock *target, s4 reg); -void emit_blez(codegendata *cd, basicblock *target, s4 reg); -#endif - -/* wrappers for branches on two integer registers */ - -#if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS -void emit_beq(codegendata *cd, basicblock *target, s4 s1, s4 s2); -void emit_bne(codegendata *cd, basicblock *target, s4 s1, s4 s2); -#endif - -/* wrappers for branches on condition codes */ - -#if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER -void emit_beq(codegendata *cd, basicblock *target); -void emit_bne(codegendata *cd, basicblock *target); -void emit_blt(codegendata *cd, basicblock *target); -void emit_bge(codegendata *cd, basicblock *target); -void emit_bgt(codegendata *cd, basicblock *target); -void emit_ble(codegendata *cd, basicblock *target); -#endif - -#if SUPPORT_BRANCH_CONDITIONAL_UNSIGNED_CONDITIONS -void emit_bult(codegendata *cd, basicblock *target); -void emit_bule(codegendata *cd, basicblock *target); -void emit_buge(codegendata *cd, basicblock *target); -void emit_bugt(codegendata *cd, basicblock *target); -#endif - -#if defined(__POWERPC__) || defined(__POWERPC64__) -void emit_bnan(codegendata *cd, basicblock *target); -#endif - -/* label-branches */ -void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options); -void emit_label(codegendata *cd, s4 label); -void emit_label_bcc(codegendata *cd, s4 label, s4 condition, u4 options); - -void emit_label_br(codegendata *cd, s4 label); - -#if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER -void emit_label_beqz(codegendata *cd, s4 label, s4 reg); -#endif - -#if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER -void emit_label_beq(codegendata *cd, s4 label); -void emit_label_bne(codegendata *cd, s4 label); -void emit_label_blt(codegendata *cd, s4 label); -void emit_label_bge(codegendata *cd, s4 label); -void emit_label_bgt(codegendata *cd, s4 label); -void emit_label_ble(codegendata *cd, s4 label); -#endif - -/* machine dependent branch-emitting function */ -void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 options); - -void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg); -void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2); -void emit_arraystore_check(codegendata *cd, instruction *iptr); -void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1); -void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg); -void emit_exception_check(codegendata *cd, instruction *iptr); - -void emit_trap_compiler(codegendata *cd); -void emit_trap_countdown(codegendata *cd, s4 *counter); -uint32_t emit_trap(codegendata *cd); - -void emit_patcher_traps(jitdata *jd); - -void emit_verbosecall_enter(jitdata *jd); -void emit_verbosecall_exit(jitdata *jd); - -#ifdef __cplusplus -} -#endif - -#endif /* _EMIT_COMMON_H */ - - -/* - * These are local overrides for various environment variables in Emacs. - * Please do not remove this and leave it at the end of the file, where - * Emacs will automagically detect them. - * --------------------------------------------------------------------- - * Local variables: - * mode: c - * indent-tabs-mode: t - * c-basic-offset: 4 - * tab-width: 4 - * End: - * vim:noexpandtab:sw=4:ts=4: - */ diff --git a/src/vm/jit/emit-common.hpp b/src/vm/jit/emit-common.hpp new file mode 100644 index 000000000..f5d350ff1 --- /dev/null +++ b/src/vm/jit/emit-common.hpp @@ -0,0 +1,212 @@ +/* src/vm/jit/emit-common.hpp - 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 + + This file is part of CACAO. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + +*/ + + +#ifndef _EMIT_COMMON_H +#define _EMIT_COMMON_H + +#include "config.h" +#include "vm/types.h" + +#include "arch.h" + +#include "vm/jit/codegen-common.h" +#include "vm/jit/jit.hpp" + + +/* branch labels **************************************************************/ + +#define BRANCH_LABEL_1 1 +#define BRANCH_LABEL_2 2 +#define BRANCH_LABEL_3 3 +#define BRANCH_LABEL_4 4 +#define BRANCH_LABEL_5 5 +#define BRANCH_LABEL_6 6 + + +/* constant range macros ******************************************************/ + +#if SIZEOF_VOID_P == 8 + +# define IS_IMM8(c) \ + (((s8) (c) >= -128) && ((s8) (c) <= 127)) + +# define IS_IMM32(c) \ + (((s8) (c) >= (-2147483647-1)) && ((s8) (c) <= 2147483647)) + +#else + +# define IS_IMM8(c) \ + (((s4) (c) >= -128) && ((s4) (c) <= 127)) + +# define IS_IMM16(c) \ + (((s4) (c) >= -32768) && ((s4) (c) <= 32767)) + +#endif + + +/* code generation functions **************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg); +s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg); +s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg); +s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg); + +#if SIZEOF_VOID_P == 4 +s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg); +s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg); +s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg); +s4 emit_load_s3_low(jitdata *jd, instruction *iptr, s4 tempreg); + +s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg); +s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg); +s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg); +s4 emit_load_s3_high(jitdata *jd, instruction *iptr, s4 tempreg); +#endif + +void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d); +void emit_store_dst(jitdata *jd, instruction *iptr, s4 d); + +#if SIZEOF_VOID_P == 4 +void emit_store_low(jitdata *jd, instruction *iptr, varinfo *dst, s4 d); +void emit_store_high(jitdata *jd, instruction *iptr, varinfo *dst, s4 d); +#endif + +void emit_copy(jitdata *jd, instruction *iptr); + +void emit_iconst(codegendata *cd, s4 d, s4 value); +void emit_lconst(codegendata *cd, s4 d, s8 value); + +/* branch-emitting functions */ +void emit_bccz(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options); +void emit_bcc(codegendata *cd, basicblock *target, s4 condition, u4 options); + +/* wrapper for unconditional branches */ +void emit_br(codegendata *cd, basicblock *target); + +/* wrappers for branches on one integer register */ + +#if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER +void emit_beqz(codegendata *cd, basicblock *target, s4 reg); +void emit_bnez(codegendata *cd, basicblock *target, s4 reg); +void emit_bltz(codegendata *cd, basicblock *target, s4 reg); +void emit_bgez(codegendata *cd, basicblock *target, s4 reg); +void emit_bgtz(codegendata *cd, basicblock *target, s4 reg); +void emit_blez(codegendata *cd, basicblock *target, s4 reg); +#endif + +/* wrappers for branches on two integer registers */ + +#if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS +void emit_beq(codegendata *cd, basicblock *target, s4 s1, s4 s2); +void emit_bne(codegendata *cd, basicblock *target, s4 s1, s4 s2); +#endif + +/* wrappers for branches on condition codes */ + +#if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER +void emit_beq(codegendata *cd, basicblock *target); +void emit_bne(codegendata *cd, basicblock *target); +void emit_blt(codegendata *cd, basicblock *target); +void emit_bge(codegendata *cd, basicblock *target); +void emit_bgt(codegendata *cd, basicblock *target); +void emit_ble(codegendata *cd, basicblock *target); +#endif + +#if SUPPORT_BRANCH_CONDITIONAL_UNSIGNED_CONDITIONS +void emit_bult(codegendata *cd, basicblock *target); +void emit_bule(codegendata *cd, basicblock *target); +void emit_buge(codegendata *cd, basicblock *target); +void emit_bugt(codegendata *cd, basicblock *target); +#endif + +#if defined(__POWERPC__) || defined(__POWERPC64__) +void emit_bnan(codegendata *cd, basicblock *target); +#endif + +/* label-branches */ +void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options); +void emit_label(codegendata *cd, s4 label); +void emit_label_bcc(codegendata *cd, s4 label, s4 condition, u4 options); + +void emit_label_br(codegendata *cd, s4 label); + +#if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER +void emit_label_beqz(codegendata *cd, s4 label, s4 reg); +#endif + +#if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER +void emit_label_beq(codegendata *cd, s4 label); +void emit_label_bne(codegendata *cd, s4 label); +void emit_label_blt(codegendata *cd, s4 label); +void emit_label_bge(codegendata *cd, s4 label); +void emit_label_bgt(codegendata *cd, s4 label); +void emit_label_ble(codegendata *cd, s4 label); +#endif + +/* machine dependent branch-emitting function */ +void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 options); + +void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg); +void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2); +void emit_arraystore_check(codegendata *cd, instruction *iptr); +void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1); +void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg); +void emit_exception_check(codegendata *cd, instruction *iptr); + +void emit_trap_compiler(codegendata *cd); +void emit_trap_countdown(codegendata *cd, s4 *counter); +uint32_t emit_trap(codegendata *cd); + +void emit_patcher_traps(jitdata *jd); + +void emit_verbosecall_enter(jitdata *jd); +void emit_verbosecall_exit(jitdata *jd); + +#ifdef __cplusplus +} +#endif + +#endif /* _EMIT_COMMON_H */ + + +/* + * These are local overrides for various environment variables in Emacs. + * Please do not remove this and leave it at the end of the file, where + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + * vim:noexpandtab:sw=4:ts=4: + */ diff --git a/src/vm/jit/i386/codegen.c b/src/vm/jit/i386/codegen.c index 55b34cb98..96986f91d 100644 --- a/src/vm/jit/i386/codegen.c +++ b/src/vm/jit/i386/codegen.c @@ -56,7 +56,7 @@ #include "vm/jit/asmpart.h" #include "vm/jit/codegen-common.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/linenumbertable.h" #include "vm/jit/parse.h" diff --git a/src/vm/jit/i386/emit.c b/src/vm/jit/i386/emit.c index 2d63231c6..5a1f886e3 100644 --- a/src/vm/jit/i386/emit.c +++ b/src/vm/jit/i386/emit.c @@ -43,7 +43,7 @@ #include "vm/jit/abi.h" #include "vm/jit/asmpart.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/patcher-common.h" #include "vm/jit/replace.hpp" diff --git a/src/vm/jit/m68k/codegen.c b/src/vm/jit/m68k/codegen.c index 1087c6273..67c554329 100644 --- a/src/vm/jit/m68k/codegen.c +++ b/src/vm/jit/m68k/codegen.c @@ -54,7 +54,7 @@ #include "vm/jit/patcher-common.h" #include "vm/jit/dseg.h" #include "vm/jit/linenumbertable.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/abi.h" #include "vm/jit/parse.h" diff --git a/src/vm/jit/m68k/emit.c b/src/vm/jit/m68k/emit.c index 258fa6f17..81fc1288f 100644 --- a/src/vm/jit/m68k/emit.c +++ b/src/vm/jit/m68k/emit.c @@ -35,7 +35,7 @@ #include "vm/jit/builtin.hpp" #include "vm/jit/asmpart.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/trace.hpp" #include "vm/jit/trap.h" diff --git a/src/vm/jit/mips/codegen.c b/src/vm/jit/mips/codegen.c index 57b600293..19f1706a9 100644 --- a/src/vm/jit/mips/codegen.c +++ b/src/vm/jit/mips/codegen.c @@ -52,7 +52,7 @@ #include "vm/jit/asmpart.h" #include "vm/jit/codegen-common.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/linenumbertable.h" #include "vm/jit/patcher-common.h" diff --git a/src/vm/jit/mips/emit.c b/src/vm/jit/mips/emit.c index 917733138..c7eea5e8d 100644 --- a/src/vm/jit/mips/emit.c +++ b/src/vm/jit/mips/emit.c @@ -43,7 +43,7 @@ #include "vm/jit/abi-asm.h" #include "vm/jit/asmpart.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/patcher-common.h" #include "vm/jit/replace.hpp" diff --git a/src/vm/jit/powerpc/codegen.c b/src/vm/jit/powerpc/codegen.c index f4f0cf0bd..0d2918427 100644 --- a/src/vm/jit/powerpc/codegen.c +++ b/src/vm/jit/powerpc/codegen.c @@ -55,7 +55,7 @@ #include "vm/jit/asmpart.h" #include "vm/jit/codegen-common.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/linenumbertable.h" #include "vm/jit/methodheader.h" diff --git a/src/vm/jit/powerpc/emit.c b/src/vm/jit/powerpc/emit.c index 2ef0d7d1c..c52c86146 100644 --- a/src/vm/jit/powerpc/emit.c +++ b/src/vm/jit/powerpc/emit.c @@ -44,7 +44,7 @@ #include "vm/jit/asmpart.h" #include "vm/jit/codegen-common.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/replace.hpp" #include "vm/jit/trace.hpp" diff --git a/src/vm/jit/powerpc64/codegen.c b/src/vm/jit/powerpc64/codegen.c index af3f008bf..d3a5ba495 100644 --- a/src/vm/jit/powerpc64/codegen.c +++ b/src/vm/jit/powerpc64/codegen.c @@ -56,7 +56,7 @@ #include "vm/jit/asmpart.h" #include "vm/jit/codegen-common.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/linenumbertable.h" #include "vm/jit/parse.h" diff --git a/src/vm/jit/powerpc64/emit.c b/src/vm/jit/powerpc64/emit.c index 088eeb750..5eb86886a 100644 --- a/src/vm/jit/powerpc64/emit.c +++ b/src/vm/jit/powerpc64/emit.c @@ -41,7 +41,7 @@ #include "vm/jit/abi.h" #include "vm/jit/asmpart.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/trace.hpp" #include "vm/jit/trap.h" diff --git a/src/vm/jit/s390/codegen.c b/src/vm/jit/s390/codegen.c index 26daf82bb..7b42a7e8f 100644 --- a/src/vm/jit/s390/codegen.c +++ b/src/vm/jit/s390/codegen.c @@ -57,7 +57,7 @@ #include "vm/jit/asmpart.h" #include "vm/jit/codegen-common.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/linenumbertable.h" #include "vm/jit/methodheader.h" diff --git a/src/vm/jit/s390/emit.c b/src/vm/jit/s390/emit.c index 46ffbc430..e5b049a8b 100644 --- a/src/vm/jit/s390/emit.c +++ b/src/vm/jit/s390/emit.c @@ -44,7 +44,7 @@ #include "vm/jit/abi-asm.h" #include "vm/jit/asmpart.h" #include "vm/jit/codegen-common.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/patcher-common.h" #include "vm/jit/replace.hpp" diff --git a/src/vm/jit/sparc64/codegen.c b/src/vm/jit/sparc64/codegen.c index 91d3025ae..e8dd622a7 100644 --- a/src/vm/jit/sparc64/codegen.c +++ b/src/vm/jit/sparc64/codegen.c @@ -52,7 +52,7 @@ #include "vm/jit/asmpart.h" #include "vm/jit/codegen-common.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/linenumbertable.h" #include "vm/jit/parse.h" diff --git a/src/vm/jit/sparc64/emit.c b/src/vm/jit/sparc64/emit.c index 0b4f66491..e7f8f379e 100644 --- a/src/vm/jit/sparc64/emit.c +++ b/src/vm/jit/sparc64/emit.c @@ -42,7 +42,7 @@ #include "vm/jit/abi-asm.h" #include "vm/jit/asmpart.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/replace.hpp" diff --git a/src/vm/jit/stubs.cpp b/src/vm/jit/stubs.cpp index 6827c3859..98e00bb58 100644 --- a/src/vm/jit/stubs.cpp +++ b/src/vm/jit/stubs.cpp @@ -40,7 +40,7 @@ #include "vm/jit/code.h" #include "vm/jit/codegen-common.h" #include "vm/jit/disass.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/show.h" #include "vm/jit/stubs.hpp" diff --git a/src/vm/jit/x86_64/codegen.c b/src/vm/jit/x86_64/codegen.c index 8934b6d83..6835e0886 100644 --- a/src/vm/jit/x86_64/codegen.c +++ b/src/vm/jit/x86_64/codegen.c @@ -59,7 +59,7 @@ #include "vm/jit/code.h" #include "vm/jit/codegen-common.h" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/linenumbertable.h" #include "vm/jit/methodheader.h" diff --git a/src/vm/jit/x86_64/emit.c b/src/vm/jit/x86_64/emit.c index fe9a944d9..0395d09b1 100644 --- a/src/vm/jit/x86_64/emit.c +++ b/src/vm/jit/x86_64/emit.c @@ -43,7 +43,7 @@ #include "vm/jit/abi-asm.h" #include "vm/jit/asmpart.h" #include "vm/jit/codegen-common.h" -#include "vm/jit/emit-common.h" +#include "vm/jit/emit-common.hpp" #include "vm/jit/jit.hpp" #include "vm/jit/patcher-common.h" #include "vm/jit/replace.hpp"