CACAO
codegen-common.hpp
Go to the documentation of this file.
1 /* src/vm/jit/codegen-common.hpp - architecture independent code generator stuff
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #ifndef CODEGEN_COMMON_HPP_
27 #define CODEGEN_COMMON_HPP_ 1
28 
29 #include "config.h"
30 #include "arch.hpp"
31 #include "md-abi.hpp" // for REG_ITMP1, REG_ITMP2, etc
32 #include "vm/global.hpp" // for functionptr, java_handle_t, etc
33 #include "vm/types.hpp" // for s4, u1, u4, u2
34 
35 class Linenumber;
36 struct basicblock;
37 struct branch_label_ref_t;
38 struct branchref;
39 struct codegendata;
40 struct dataref;
41 struct dsegentry;
42 struct fieldinfo;
43 struct instruction;
44 struct jitdata;
45 struct jumpref;
46 struct methoddesc;
47 struct methodinfo;
48 struct patchref_t;
49 struct rplpoint;
50 struct varinfo;
51 template <class T> class DumpList;
52 
53 #define MCODEINITSIZE (1<<15) /* 32 Kbyte code area initialization size */
54 #define DSEGINITSIZE (1<<12) /* 4 Kbyte data area initialization size */
55 
56 #define NCODEINITSIZE (1<<15) /* 32 Kbyte code area initialization size */
57 
58 
59 /* Register Pack/Unpack Macros ************************************************/
60 
61 /* ATTENTION: Don't change the order where low and high bits are
62  stored! At least mips32 relies in one case on that order. */
63 
64 #define PACK_REGS(low,high) \
65  ( (((high) & 0x0000ffff) << 16) | ((low) & 0x0000ffff) )
66 
67 #define GET_LOW_REG(a) ((a) & 0x0000ffff)
68 #define GET_HIGH_REG(a) (((a) & 0xffff0000) >> 16)
69 
70 /* All 32-bit machines we support use packed registers to store
71  return values and temporary values. */
72 
73 #if SIZEOF_VOID_P == 8
74 # define REG_LRESULT REG_RESULT
75 # define REG_LTMP12 REG_ITMP1
76 # define REG_LTMP23 REG_ITMP2
77 #else
78 # define REG_LRESULT REG_RESULT_PACKED
79 # define REG_LTMP12 REG_ITMP12_PACKED
80 # define REG_LTMP23 REG_ITMP23_PACKED
81 #endif
82 
83 
84 /* branch conditions **********************************************************/
85 
86 #define BRANCH_UNCONDITIONAL -1
87 
88 #define BRANCH_EQ (ICMD_IFEQ - ICMD_IFEQ)
89 #define BRANCH_NE (ICMD_IFNE - ICMD_IFEQ)
90 #define BRANCH_LT (ICMD_IFLT - ICMD_IFEQ)
91 #define BRANCH_GE (ICMD_IFGE - ICMD_IFEQ)
92 #define BRANCH_GT (ICMD_IFGT - ICMD_IFEQ)
93 #define BRANCH_LE (ICMD_IFLE - ICMD_IFEQ)
94 
95 #define BRANCH_ULT 256
96 #define BRANCH_ULE 257
97 #define BRANCH_UGE 258
98 #define BRANCH_UGT 259
99 
100 #define BRANCH_NAN 260
101 
102 
103 /* common branch options ******************************************************/
104 
105 #define BRANCH_OPT_NONE 0
106 
107 
108 /* codegendata ****************************************************************/
109 
110 struct codegendata {
111  u4 flags; /* code generator flags */
112  u1 *mcodebase; /* base pointer of code area */
113  u1 *mcodeend; /* pointer to end of code area */
114  s4 mcodesize; /* complete size of code area (bytes) */
115  u1 *mcodeptr; /* code generation pointer */
116  u1 *lastmcodeptr; /* last patcher position of basic block */
117 
118 #if defined(ENABLE_INTRP)
119  u1 *ncodebase; /* base pointer of native code area */
120  s4 ncodesize; /* complete size of native code area */
121  u1 *ncodeptr; /* native code generation pointer */
122 
123  u4 lastinstwithoutdispatch; /* ~0 if there was a dispatch */
124 
125  s4 lastpatcheroffset; /* -1 if current super has no patcher */
126  s4 dynsuperm; /* offsets of start of current dynamic ...*/
127  s4 dynsupern; /* ... superinstruction starts */
128  struct superstart *superstarts; /* list of supers without patchers */
129 #endif
130 
131  dsegentry *dseg; /* chain of data segment entries */
132  s4 dseglen; /* used size of data area (bytes) */
133  /* data area grows from top to bottom */
134 
135  jumpref *jumpreferences; /* list of jumptable target addresses */
136 
137 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP) || defined(__S390__)
138  dataref *datareferences; /* list of data segment references */
139 #endif
140 
142  DumpList<Linenumber>* linenumbers; ///< List of line numbers.
143 
145 
146  s4 stackframesize; /* stackframe size of this method */
147 
148 #if defined(ENABLE_REPLACEMENT)
149  rplpoint *replacementpoint; /* current replacement point */
150 #endif
151 };
152 
153 
154 #define CODEGENDATA_FLAG_ERROR 0x00000001
155 #define CODEGENDATA_FLAG_LONGBRANCHES 0x00000002
156 
157 
158 #define CODEGENDATA_HAS_FLAG_ERROR(cd) \
159  ((cd)->flags & CODEGENDATA_FLAG_ERROR)
160 
161 #define CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd) \
162  ((cd)->flags & CODEGENDATA_FLAG_LONGBRANCHES)
163 
164 
165 /* branchref *****************************************************************/
166 
167 struct branchref {
168  s4 branchmpc; /* patching position in code segment */
169  s4 condition; /* conditional branch condition */
170  s4 reg; /* register number to check */
171  u4 options; /* branch options */
172  branchref *next; /* next element in branchref list */
173 };
174 
175 
176 /* branch_label_ref_t *********************************************************/
177 
179  s4 mpc; /* position in code segment */
180  s4 label; /* label number */
181  s4 condition; /* conditional branch condition */
182  s4 reg; /* register number to check */
183  u4 options; /* branch options */
184 /* listnode_t linkage; */
185 };
186 
187 
188 /* jumpref ********************************************************************/
189 
190 struct jumpref {
191  s4 tablepos; /* patching position in data segment */
192  basicblock *target; /* target basic block */
193  jumpref *next; /* next element in jumpref list */
194 };
195 
196 
197 /* dataref ********************************************************************/
198 
199 struct dataref {
200  s4 datapos; /* patching position in generated code */
201  dataref *next; /* next element in dataref list */
202 };
203 
204 
205 /* function prototypes ********************************************************/
206 
207 void codegen_init(void);
208 void codegen_setup(jitdata *jd);
209 
210 bool codegen_generate(jitdata *jd);
211 bool codegen_emit(jitdata *jd);
212 
213 void codegen_emit_prolog(jitdata* jd);
214 void codegen_emit_epilog(jitdata* jd);
216 
217 #if defined(USES_PATCHABLE_MEMORY_BARRIER)
219 #endif
220 
221 #if defined(ENABLE_INTRP)
222 bool intrp_codegen(jitdata *jd);
223 #endif
224 
225 void codegen_close(void);
226 
227 void codegen_increase(codegendata *cd);
228 
229 #if defined(ENABLE_INTRP)
230 u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr);
231 #endif
232 
233 void codegen_add_branch_ref(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options);
235 
236 void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options);
237 
238 #if defined(ENABLE_REPLACEMENT)
239 #if !defined(NDEBUG)
240 void codegen_set_replacement_point_notrap(codegendata *cd, s4 type);
241 void codegen_set_replacement_point(codegendata *cd, s4 type);
242 #else
243 void codegen_set_replacement_point_notrap(codegendata *cd);
244 void codegen_set_replacement_point(codegendata *cd);
245 #endif
246 #endif /* defined(ENABLE_REPLACEMENT) */
247 
248 void codegen_finish(jitdata *jd);
249 
252 
253 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum);
254 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum);
255 
256 #if defined(ENABLE_SSA)
257 void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr);
258 #endif
259 
260 // REMOVEME
262 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams);
263 
264 #endif // CODEGEN_COMMON_HPP_
265 
266 
267 /*
268  * These are local overrides for various environment variables in Emacs.
269  * Please do not remove this and leave it at the end of the file, where
270  * Emacs will automagically detect them.
271  * ---------------------------------------------------------------------
272  * Local variables:
273  * mode: c++
274  * indent-tabs-mode: t
275  * c-basic-offset: 4
276  * tab-width: 4
277  * End:
278  * vim:noexpandtab:sw=4:ts=4:
279  */
void codegen_emit_instruction(jitdata *jd, instruction *iptr)
Generates machine code for one ICMD.
Definition: codegen.cpp:217
#define pv
Definition: md-asm.hpp:65
basicblock * target
DumpList< Linenumber > * linenumbers
List of line numbers.
void codegen_close(void)
Definition: jit.hpp:126
dataref * next
jumpref * next
s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
Definition: codegen.cpp:2010
void codegen_init(void)
uint8_t u1
Definition: types.hpp:40
void codegen_increase(codegendata *cd)
java_object_t * codegen_finish_native_call(u1 *sp, u1 *pv)
Definition: reg.hpp:43
void(* functionptr)(void)
Definition: global.hpp:39
java_handle_t * codegen_start_native_call(u1 *sp, u1 *pv)
s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr)
uint16_t u2
Definition: types.hpp:43
jumpref * jumpreferences
int32_t s4
Definition: types.hpp:45
DumpList< branch_label_ref_t * > * brancheslabel
void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
uint32_t u4
Definition: types.hpp:46
void codegen_setup(jitdata *jd)
void codegen_emit_stub_compiler(jitdata *jd)
Definition: codegen.cpp:2474
void codegen_emit_epilog(jitdata *jd)
Generates machine code for the method epilog.
Definition: codegen.cpp:174
void codegen_add_branch_ref(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
List implementation with dump memory.
Definition: list.hpp:80
void codegen_emit_prolog(jitdata *jd)
Generates machine code for the method prolog.
Definition: codegen.cpp:73
BeginInst * target
branchref * next
bool codegen_generate(jitdata *jd)
bool intrp_codegen(jitdata *jd)
Definition: codegen.c:281
dsegentry * dseg
void codegen_emit_patchable_barrier(instruction *iptr, codegendata *cd, patchref_t *pr, fieldinfo *fi)
Generates a memory barrier to be used after volatile writes.
Definition: codegen.cpp:197
bool codegen_emit(jitdata *jd)
Generates machine code.
methodinfo * method
void codegen_finish(jitdata *jd)
Represents a Java line number.