/* src/vm/jit/codegen-common.h - architecture independent code generator stuff
- Copyright (C) 1996-2005 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) 1996-2005, 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.
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., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
-
- Contact: cacao@complang.tuwien.ac.at
-
- Authors: Christian Thalinger
-
- Changes: Christian Ullrich
-
- $Id: codegen-common.h 4160 2006-01-12 21:35:59Z twisti $
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
*/
/* forward typedefs ***********************************************************/
-typedef struct codegendata codegendata;
-typedef struct branchref branchref;
-typedef struct threadcritnodetemp threadcritnodetemp;
+typedef struct codegendata codegendata;
+typedef struct branchref branchref;
+typedef struct branch_label_ref_t branch_label_ref_t;
+typedef struct critical_section_ref_t critical_section_ref_t;
+typedef struct jumpref jumpref;
+typedef struct dataref dataref;
+typedef struct exceptionref exceptionref;
+typedef struct linenumberref linenumberref;
#include "config.h"
#include "vm/types.h"
+#include "vm/builtin.h"
#include "vm/global.h"
-#include "vm/references.h"
-#include "vm/method.h"
+
#include "vm/jit/dseg.h"
#include "vm/jit/jit.h"
#include "vm/jit/reg.h"
-#include "vm/jit/inline/inline.h"
+#include "vm/jit/code.h"
+#include "vm/jit/replace.h"
+
+#include "vmcore/descriptor.h"
+#include "vmcore/method.h"
+#include "vmcore/references.h"
#define MCODEINITSIZE (1<<15) /* 32 Kbyte code area initialization size */
/* Register Pack/Unpack Macros ************************************************/
/* ATTENTION: Don't change the order where low and high bits are
- stored! At least mips32 relys in one case on that order. */
+ stored! At least mips32 relies in one case on that order. */
#define PACK_REGS(low,high) \
( (((high) & 0x0000ffff) << 16) | ((low) & 0x0000ffff) )
#define GET_HIGH_REG(a) (((a) & 0xffff0000) >> 16)
-/************************* critical sections *********************************/
+/* branch conditions **********************************************************/
-struct threadcritnodetemp {
- threadcritnodetemp *next;
- s4 mcodebegin;
- s4 mcodeend;
- s4 mcoderestart;
-};
+#define BRANCH_UNCONDITIONAL -1
+
+#define BRANCH_EQ (ICMD_IFEQ - ICMD_IFEQ)
+#define BRANCH_NE (ICMD_IFNE - ICMD_IFEQ)
+#define BRANCH_LT (ICMD_IFLT - ICMD_IFEQ)
+#define BRANCH_GE (ICMD_IFGE - ICMD_IFEQ)
+#define BRANCH_GT (ICMD_IFGT - ICMD_IFEQ)
+#define BRANCH_LE (ICMD_IFLE - ICMD_IFEQ)
+#define BRANCH_ULT 256
+#define BRANCH_ULE 257
+#define BRANCH_UGE 258
+#define BRANCH_UGT 259
+
+#define BRANCH_NAN 260
+
+
+/* common branch options ******************************************************/
+
+#define BRANCH_OPT_NONE 0
+
+
+/* codegendata ****************************************************************/
struct codegendata {
+ u4 flags; /* code generator flags */
u1 *mcodebase; /* base pointer of code area */
- s4 *mcodeend; /* pointer to end of code area */
+ u1 *mcodeend; /* pointer to end of code area */
s4 mcodesize; /* complete size of code area (bytes) */
u1 *mcodeptr; /* code generation pointer */
-
-#if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(ENABLE_INTRP)
u1 *lastmcodeptr; /* last patcher position of basic block */
-#endif
#if defined(ENABLE_INTRP)
u1 *ncodebase; /* base pointer of native code area */
struct superstart *superstarts; /* list of supers without patchers */
#endif
- u1 *dsegtop; /* pointer to top (end) of data area */
- s4 dsegsize; /* complete size of data area (bytes) */
+ dsegentry *dseg; /* chain of data segment entries */
s4 dseglen; /* used size of data area (bytes) */
/* data area grows from top to bottom */
jumpref *jumpreferences; /* list of jumptable target addresses */
+
+#if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP) || defined(__S390__)
dataref *datareferences; /* list of data segment references */
- branchref *xboundrefs; /* list of bound check branches */
- branchref *xnullrefs; /* list of null check branches */
- branchref *xcastrefs; /* list of cast check branches */
- branchref *xstorerefs; /* list of array store check branches */
- branchref *xdivrefs; /* list of divide by zero branches */
- branchref *xexceptionrefs; /* list of exception branches */
- patchref *patchrefs;
-
- linenumberref *linenumberreferences; /* list of line numbers and the */
- /* program counters of their first */
- /* instruction */
- s4 linenumbertablesizepos;
- s4 linenumbertablestartpos;
- s4 linenumbertab;
+#endif
+
+ list_t *brancheslabel;
+ list_t *listcritical; /* list of critical sections */
+ list_t *linenumbers; /* list of line numbers */
methodinfo *method;
- s4 exceptiontablelength; /* exceptiontable length */
- exceptiontable *exceptiontable; /* the exceptiontable */
- threadcritnodetemp *threadcrit; /* List of critical code regions */
- threadcritnodetemp threadcritcurrent;
- s4 threadcritcount; /* Number of critical regions */
+ s4 stackframesize; /* stackframe size of this method */
- s4 maxstack;
- s4 maxlocals;
+#if defined(ENABLE_REPLACEMENT)
+ rplpoint *replacementpoint; /* current replacement point */
+#endif
};
-/***************** forward references in branch instructions ******************/
+#define CODEGENDATA_FLAG_ERROR 0x00000001
+#define CODEGENDATA_FLAG_LONGBRANCHES 0x00000002
+
+
+#define CODEGENDATA_HAS_FLAG_ERROR(cd) \
+ ((cd)->flags & CODEGENDATA_FLAG_ERROR)
+
+#define CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd) \
+ ((cd)->flags & CODEGENDATA_FLAG_LONGBRANCHES)
+
+
+/* branchref *****************************************************************/
struct branchref {
- s4 branchpos; /* patching position in code segment */
- s4 reg; /* used for ArrayIndexOutOfBounds index reg */
+ s4 branchmpc; /* patching position in code segment */
+ s4 condition; /* conditional branch condition */
+ s4 reg; /* register number to check */
+ u4 options; /* branch options */
branchref *next; /* next element in branchref list */
};
-#if defined(__I386__) || defined(__X86_64__) || defined(ENABLE_INTRP) || defined(DISABLE_GC)
-typedef struct _methodtree_element methodtree_element;
+/* branch_label_ref_t *********************************************************/
+
+struct branch_label_ref_t {
+ s4 mpc; /* position in code segment */
+ s4 label; /* label number */
+ s4 condition; /* conditional branch condition */
+ s4 reg; /* register number to check */
+ u4 options; /* branch options */
+ listnode_t linkage;
+};
-struct _methodtree_element {
+
+/* critical_section_ref_t *****************************************************/
+
+struct critical_section_ref_t {
+ s4 start; /* relative offset to method entry-point */
+ s4 end;
+ s4 restart;
+ listnode_t linkage;
+};
+
+
+/* jumpref ********************************************************************/
+
+struct jumpref {
+ s4 tablepos; /* patching position in data segment */
+ basicblock *target; /* target basic block */
+ jumpref *next; /* next element in jumpref list */
+};
+
+
+/* dataref ********************************************************************/
+
+struct dataref {
+ s4 datapos; /* patching position in generated code */
+ dataref *next; /* next element in dataref list */
+};
+
+
+/* linenumberref **************************************************************/
+
+struct linenumberref {
+ s4 tablepos; /* patching position in data segment */
+ s4 linenumber; /* line number, used for inserting into the */
+ /* table and for validity checking */
+ /* -1......start of inlined body */
+ /* -2......end of inlined body */
+ /* <= -3...special entry with methodinfo * */
+ /* (see doc/inlining_stacktrace.txt) */
+ ptrint targetmpc; /* machine code program counter of first */
+ /* instruction for given line */
+ /* NOTE: for linenumber <= -3 this is a the */
+ /* (methodinfo *) of the inlined method */
+ linenumberref *next; /* next element in linenumberref list */
+};
+
+
+/* methodtree_element *********************************************************/
+
+typedef struct methodtree_element methodtree_element;
+
+struct methodtree_element {
u1 *startpc;
u1 *endpc;
};
-#endif
/* function prototypes ********************************************************/
void codegen_init(void);
-void codegen_setup(methodinfo *m, codegendata *cd, t_inlining_globals *e);
+void codegen_setup(jitdata *jd);
+
+bool codegen_generate(jitdata *jd);
+bool codegen_emit(jitdata *jd);
+
+#if defined(ENABLE_INTRP)
+bool intrp_codegen(jitdata *jd);
+#endif
-void codegen_free(methodinfo *m, codegendata *cd);
void codegen_close(void);
-s4 *codegen_increase(codegendata *cd, u1 *mcodeptr);
+void codegen_increase(codegendata *cd);
#if defined(ENABLE_INTRP)
u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr);
#endif
-void codegen_addreference(codegendata *cd, basicblock *target, void *branchptr);
-
-void codegen_addxboundrefs(codegendata *cd, void *branchptr, s4 reg);
-void codegen_addxcastrefs(codegendata *cd, void *branchptr);
-void codegen_addxdivrefs(codegendata *cd, void *branchptr);
-void codegen_addxstorerefs(codegendata *cd, void *branchptr);
-void codegen_addxnullrefs(codegendata *cd, void *branchptr);
-void codegen_addxexceptionrefs(codegendata *cd, void *branchptr);
+void codegen_add_branch_ref(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options);
+void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr);
-void codegen_addpatchref(codegendata *cd, voidptr branchptr,
- functionptr patcher, voidptr ref, s4 disp);
+void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options);
void codegen_insertmethod(u1 *startpc, u1 *endpc);
-u1 *codegen_findmethod(u1 *pc);
+u1 *codegen_get_pv_from_pc(u1 *pc);
+u1 *codegen_get_pv_from_pc_nocheck(u1 *pc);
+
+#if defined(ENABLE_REPLACEMENT)
+#if !defined(NDEBUG)
+void codegen_set_replacement_point_notrap(codegendata *cd, s4 type);
+void codegen_set_replacement_point(codegendata *cd, s4 type);
+#else
+void codegen_set_replacement_point_notrap(codegendata *cd);
+void codegen_set_replacement_point(codegendata *cd);
+#endif
+#endif /* defined(ENABLE_REPLACEMENT) */
-void codegen_finish(methodinfo *m, codegendata *cd, s4 mcodelen);
+void codegen_finish(jitdata *jd);
-u1 *codegen_createnativestub(functionptr f, methodinfo *m);
-void codegen_disassemble_nativestub(methodinfo *m, u1 *start, u1 *end);
+#if defined(ENABLE_DISASSEMBLER)
+void codegen_disassemble_stub(methodinfo *m, u1 *start, u1 *end);
+#endif
+
+/* stub functions */
-void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra);
-void codegen_finish_native_call(u1 *datasp);
+u1 *codegen_generate_stub_compiler(methodinfo *m);
+void codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte);
+codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f);
-u1 *createcompilerstub(methodinfo *m);
-u1 *createnativestub(functionptr f, methodinfo *m, codegendata *cd,
- registerdata *rd, methoddesc *md);
+#if !defined(JIT_COMPILER_VIA_SIGNAL)
+void codegen_emit_stub_compiler(jitdata *jd);
+#endif
+void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams);
#if defined(ENABLE_INTRP)
u1 *intrp_createcompilerstub(methodinfo *m);
-u1 *intrp_createnativestub(functionptr f, methodinfo *m, codegendata *cd,
- registerdata *rd, methoddesc *md);
+u1 *intrp_createnativestub(functionptr f, jitdata *jd, methoddesc *md);
#endif
void removecompilerstub(u1 *stub);
void removenativestub(u1 *stub);
-s4 reg_of_var(registerdata *rd, stackptr v, s4 tempregnum);
+java_handle_t *codegen_start_native_call(u1 *currentsp, u1 *pv);
+java_object_t *codegen_finish_native_call(u1 *currentsp, u1 *pv);
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-void codegen_threadcritrestart(codegendata *cd, int offset);
-void codegen_threadcritstart(codegendata *cd, int offset);
-void codegen_threadcritstop(codegendata *cd, int offset);
-#endif
+s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum);
+s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum);
-/* machine dependent functions */
-u1 *md_codegen_findmethod(u1 *ra);
-bool codegen(methodinfo *m, codegendata *cd, registerdata *rd);
+#if defined(ENABLE_THREADS)
+void codegen_critical_section_new(codegendata *cd);
+void codegen_critical_section_start(codegendata *cd);
+void codegen_critical_section_end(codegendata *cd);
-#if defined(ENABLE_INTRP)
-bool intrp_codegen(methodinfo *m, codegendata *cd, registerdata *rd);
+# define CODEGEN_CRITICAL_SECTION_NEW codegen_critical_section_new(cd)
+# define CODEGEN_CRITICAL_SECTION_START codegen_critical_section_start(cd)
+# define CODEGEN_CRITICAL_SECTION_END codegen_critical_section_end(cd)
+#else
+# define CODEGEN_CRITICAL_SECTION_NEW /* no-op */
+# define CODEGEN_CRITICAL_SECTION_START /* no-op */
+# define CODEGEN_CRITICAL_SECTION_END /* no-op */
+#endif
+
+#if defined(ENABLE_SSA)
+void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr);
#endif
#endif /* _CODEGEN_COMMON_H */
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/