Merged revisions 8245-8298 via svnmerge from
[cacao.git] / src / vm / jit / codegen-common.h
index 4df1e391a7d094408e75ad911843c2002f608317..94792a8d9a7051e0e0b60204c69091c164488829 100644 (file)
@@ -1,9 +1,9 @@
 /* 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.
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
-
-   Authors: Christian Thalinger
-
-   Changes: Christian Ullrich
-
-   $Id: codegen-common.h 4118 2006-01-10 10:59:20Z twisti $
+   $Id: codegen-common.h 8299 2007-08-13 08:41:18Z michi $
 
 */
 
 
 /* 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 patchref               patchref;
+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 */
@@ -64,7 +69,7 @@ typedef struct threadcritnodetemp threadcritnodetemp;
 /* 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) )
@@ -73,25 +78,39 @@ typedef struct threadcritnodetemp threadcritnodetemp;
 #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       */
@@ -106,20 +125,20 @@ struct codegendata {
        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             */
+#endif
+
+/*     list_t         *patchrefs; */
        patchref       *patchrefs;
+       list_t         *brancheslabel;
+       list_t         *listcritical;   /* list of critical sections              */
 
        linenumberref  *linenumberreferences; /* list of line numbers and the     */
                                        /* program counters of their first        */
@@ -129,92 +148,215 @@ struct codegendata {
        s4              linenumbertab;
 
        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;
+};
+
+
+/* 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 _methodtree_element {
+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               */
+};
+
+
+/* patchref *******************************************************************/
+
+struct patchref {
+       s4           branchpos;     /* relative offset to method entrypoint       */
+       s4           disp;          /* displacement of ref in the data segment    */
+       functionptr  patcher;       /* patcher function to call                   */
+       voidptr      ref;           /* reference passed                           */
+/*     listnode     linkage; */
+       patchref    *next;
+};
+
+
+/* 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_add_branch_ref(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options);
+void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr);
 
-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_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options);
 
-void codegen_addpatchref(codegendata *cd, voidptr branchptr,
-                                                functionptr patcher, voidptr ref, s4 disp);
+
+void codegen_add_patch_ref(codegendata *cd, functionptr patcher, voidptr ref,
+                                                  s4 disp);
+/* XXX REMOVE ME: don't-break-trunk macro */
+#define codegen_addpatchref codegen_add_patch_ref
 
 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);
+#if defined(ENABLE_DISASSEMBLER)
 void codegen_disassemble_nativestub(methodinfo *m, u1 *start, u1 *end);
+#endif
 
-void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra);
-void codegen_finish_native_call(u1 *datasp);
+/* stub functions */
 
-u1 *createcompilerstub(methodinfo *m);
-u1 *createnativestub(functionptr f, methodinfo *m, codegendata *cd,
-                                        registerdata *rd, methoddesc *md);
+u1       *codegen_generate_stub_compiler(methodinfo *m);
+void      codegen_generate_stub_builtin(builtintable_entry *bte);
+codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f);
+
+void      codegen_emit_stub_compiler(jitdata *jd);
+void      codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte);
+void      codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f);
+
+#if defined(ENABLE_INTRP)
+u1 *intrp_createcompilerstub(methodinfo *m);
+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);
+void codegen_stub_builtin_enter(u1 *datasp, u1 *pv, u1 *sp, u1 *ra);
+void codegen_stub_builtin_exit(u1 *datasp);
 
-#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);
+void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra);
+java_object_t *codegen_finish_native_call(u1 *datasp);
+
+s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum);
+s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum);
+
+#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);
+
+# 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
 
 /* machine dependent functions */
-u1 *md_codegen_findmethod(u1 *ra);
-bool codegen(methodinfo *m, codegendata *cd, registerdata *rd);
+u1 *md_codegen_get_pv_from_pc(u1 *ra);
+
+
+#if defined(ENABLE_SSA)
+void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr);
+#endif
 
 #endif /* _CODEGEN_COMMON_H */
 
@@ -230,4 +372,5 @@ bool codegen(methodinfo *m, codegendata *cd, registerdata *rd);
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */