Line data Source code
1 : /* src/vm/jit/emit-common.hpp - common code emitter functions
2 :
3 : Copyright (C) 1996-2013
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 : Copyright (C) 2009 Theobroma Systems Ltd.
6 :
7 : This file is part of CACAO.
8 :
9 : This program is free software; you can redistribute it and/or
10 : modify it under the terms of the GNU General Public License as
11 : published by the Free Software Foundation; either version 2, or (at
12 : your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful, but
15 : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program; if not, write to the Free Software
21 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 : 02110-1301, USA.
23 :
24 : */
25 :
26 :
27 : #ifndef EMIT_COMMON_HPP_
28 : #define EMIT_COMMON_HPP_ 1
29 :
30 : #include "config.h"
31 : #include <cassert> // for assert
32 : #include <stdint.h> // for int32_t, uint32_t
33 : #include "arch.hpp"
34 : #include "codegen.hpp"
35 : #include "vm/jit/codegen-common.hpp" // for codegendata
36 : #include "vm/types.hpp" // for s4, u4, s8
37 :
38 : struct basicblock;
39 : struct codegendata;
40 : struct codeinfo;
41 : struct instruction;
42 : struct jitdata;
43 : struct varinfo;
44 :
45 : /* branch labels **************************************************************/
46 :
47 : #define BRANCH_LABEL_1 1
48 : #define BRANCH_LABEL_2 2
49 : #define BRANCH_LABEL_3 3
50 : #define BRANCH_LABEL_4 4
51 : #define BRANCH_LABEL_5 5
52 : #define BRANCH_LABEL_6 6
53 : #define BRANCH_LABEL_7 7
54 : #define BRANCH_LABEL_8 8
55 : #define BRANCH_LABEL_9 9
56 : #define BRANCH_LABEL_10 10
57 :
58 :
59 : /* constant range macros ******************************************************/
60 :
61 : #if SIZEOF_VOID_P == 8
62 :
63 : # define IS_IMM8(c) \
64 : (((s8) (c) >= -128) && ((s8) (c) <= 127))
65 :
66 : # define IS_IMM32(c) \
67 : (((s8) (c) >= (-2147483647-1)) && ((s8) (c) <= 2147483647))
68 :
69 : #else
70 :
71 : # define IS_IMM8(c) \
72 : (((s4) (c) >= -128) && ((s4) (c) <= 127))
73 :
74 : # define IS_IMM16(c) \
75 : (((s4) (c) >= -32768) && ((s4) (c) <= 32767))
76 :
77 : #endif
78 :
79 :
80 : /* code generation functions **************************************************/
81 :
82 : s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg);
83 : s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg);
84 : s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg);
85 : s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg);
86 :
87 : #if SIZEOF_VOID_P == 4
88 : s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg);
89 : s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg);
90 : s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg);
91 : s4 emit_load_s3_low(jitdata *jd, instruction *iptr, s4 tempreg);
92 :
93 : s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg);
94 : s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg);
95 : s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg);
96 : s4 emit_load_s3_high(jitdata *jd, instruction *iptr, s4 tempreg);
97 : #endif
98 :
99 : void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d);
100 : void emit_store_dst(jitdata *jd, instruction *iptr, s4 d);
101 :
102 : #if SIZEOF_VOID_P == 4
103 : void emit_store_low(jitdata *jd, instruction *iptr, varinfo *dst, s4 d);
104 : void emit_store_high(jitdata *jd, instruction *iptr, varinfo *dst, s4 d);
105 : #endif
106 :
107 : void emit_copy(jitdata *jd, instruction *iptr);
108 :
109 : void emit_iconst(codegendata *cd, s4 d, s4 value);
110 : void emit_lconst(codegendata *cd, s4 d, s8 value);
111 :
112 : /* compare-emitting functions targeting an integer register */
113 :
114 : #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
115 : void emit_icmpeq_imm(codegendata* cd, int reg, int32_t value, int d);
116 : #endif
117 :
118 : /* compare-emitting functions targeting the condition register */
119 :
120 : #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
121 : void emit_icmp_imm(codegendata* cd, int reg, int32_t value);
122 : #endif
123 :
124 : /* branch-emitting functions */
125 : void emit_bccz(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options);
126 : void emit_bcc(codegendata *cd, basicblock *target, s4 condition, u4 options);
127 :
128 : /* wrapper for unconditional branches */
129 : void emit_br(codegendata *cd, basicblock *target);
130 :
131 : /* wrappers for branches on one integer register */
132 :
133 : #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
134 : void emit_beqz(codegendata *cd, basicblock *target, s4 reg);
135 : void emit_bnez(codegendata *cd, basicblock *target, s4 reg);
136 : void emit_bltz(codegendata *cd, basicblock *target, s4 reg);
137 : void emit_bgez(codegendata *cd, basicblock *target, s4 reg);
138 : void emit_bgtz(codegendata *cd, basicblock *target, s4 reg);
139 : void emit_blez(codegendata *cd, basicblock *target, s4 reg);
140 : #endif
141 :
142 : /* wrappers for branches on two integer registers */
143 :
144 : #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS
145 : void emit_beq(codegendata *cd, basicblock *target, s4 s1, s4 s2);
146 : void emit_bne(codegendata *cd, basicblock *target, s4 s1, s4 s2);
147 : #endif
148 :
149 : /* wrappers for branches on condition codes */
150 :
151 : #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
152 : void emit_beq(codegendata *cd, basicblock *target);
153 : void emit_bne(codegendata *cd, basicblock *target);
154 : void emit_blt(codegendata *cd, basicblock *target);
155 : void emit_bge(codegendata *cd, basicblock *target);
156 : void emit_bgt(codegendata *cd, basicblock *target);
157 : void emit_ble(codegendata *cd, basicblock *target);
158 : #endif
159 :
160 : #if SUPPORT_BRANCH_CONDITIONAL_UNSIGNED_CONDITIONS
161 : void emit_bult(codegendata *cd, basicblock *target);
162 : void emit_bule(codegendata *cd, basicblock *target);
163 : void emit_buge(codegendata *cd, basicblock *target);
164 : void emit_bugt(codegendata *cd, basicblock *target);
165 : #endif
166 :
167 : #if defined(__POWERPC__) || defined(__POWERPC64__)
168 : void emit_bnan(codegendata *cd, basicblock *target);
169 : #endif
170 :
171 : /* label-branches */
172 : void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options);
173 : void emit_label(codegendata *cd, s4 label);
174 : void emit_label_bcc(codegendata *cd, s4 label, s4 condition, u4 options);
175 :
176 : void emit_label_br(codegendata *cd, s4 label);
177 :
178 : #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
179 : void emit_label_beqz(codegendata* cd, int label, int reg);
180 : void emit_label_bnez(codegendata* cd, int label, int reg);
181 : void emit_label_bltz(codegendata* cd, int label, int reg);
182 : void emit_label_bgtz(codegendata* cd, int label, int reg);
183 : #endif
184 :
185 : #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS
186 : void emit_label_beq(codegendata* cd, int label, int s1, int s2);
187 : void emit_label_bne(codegendata* cd, int label, int s1, int s2);
188 : #endif
189 :
190 : #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
191 : void emit_label_beq(codegendata *cd, s4 label);
192 : void emit_label_bne(codegendata *cd, s4 label);
193 : void emit_label_blt(codegendata *cd, s4 label);
194 : void emit_label_bge(codegendata *cd, s4 label);
195 : void emit_label_bgt(codegendata *cd, s4 label);
196 : void emit_label_ble(codegendata *cd, s4 label);
197 : #endif
198 :
199 : /* machine dependent branch-emitting function */
200 : void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 options);
201 :
202 : void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg);
203 : void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2);
204 : void emit_arraystore_check(codegendata *cd, instruction *iptr);
205 : void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1);
206 : void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg);
207 : void emit_exception_check(codegendata *cd, instruction *iptr);
208 :
209 : void emit_trap_compiler(codegendata *cd);
210 : void emit_trap_countdown(codegendata *cd, s4 *counter);
211 : uint32_t emit_trap(codegendata *cd);
212 : void emit_abstractmethoderror_trap(codegendata *cd);
213 :
214 : void emit_patcher_traps(jitdata *jd);
215 :
216 : void emit_recompute_pv(codegendata* cd);
217 :
218 : /* machine dependent faspath-emitting functions */
219 : void emit_fastpath_monitor_enter(jitdata* jd, instruction* iptr, int d);
220 : void emit_fastpath_monitor_exit(jitdata* jd, instruction* iptr, int d);
221 :
222 : void emit_monitor_enter(jitdata* jd, int32_t syncslot_offset);
223 : void emit_monitor_exit(jitdata* jd, int32_t syncslot_offset);
224 :
225 : #if defined(ENABLE_PROFILING)
226 : void emit_profile_method(codegendata* cd, codeinfo* code);
227 : void emit_profile_basicblock(codegendata* cd, codeinfo* code, basicblock* bptr);
228 : void emit_profile_cycle_start(codegendata* cd, codeinfo* code);
229 : void emit_profile_cycle_stop(codegendata* cd, codeinfo* code);
230 : #endif
231 :
232 : void emit_verbosecall_enter(jitdata *jd);
233 : void emit_verbosecall_exit(jitdata *jd);
234 :
235 : /* inline code generation functions *******************************************/
236 :
237 : /**
238 : * Generates an integer-move from register s to d. If s and d are
239 : * the same registers, no code will be generated.
240 : */
241 802517 : static inline void emit_imove(codegendata* cd, int s, int d)
242 : {
243 802517 : if (s != d)
244 : #if defined(__ARM__)
245 : // XXX Fix this!!!
246 : M_MOV(d, s);
247 : #else
248 699030 : M_MOV(s, d);
249 : #endif
250 802517 : }
251 :
252 :
253 : /**
254 : * Generates a long-move from register s to d. If s and d are
255 : * the same registers, no code will be generated.
256 : */
257 1027 : static inline void emit_lmove(codegendata* cd, int s, int d)
258 : {
259 : #if SIZEOF_VOID_P == 8
260 1027 : emit_imove(cd, s, d);
261 : #else
262 : if (GET_HIGH_REG(s) == GET_LOW_REG(d)) {
263 : assert((GET_LOW_REG(s) != GET_HIGH_REG(d)));
264 : emit_imove(cd, GET_HIGH_REG(s), GET_HIGH_REG(d));
265 : emit_imove(cd, GET_LOW_REG(s), GET_LOW_REG(d));
266 : } else {
267 : emit_imove(cd, GET_LOW_REG(s), GET_LOW_REG(d));
268 : emit_imove(cd, GET_HIGH_REG(s), GET_HIGH_REG(d));
269 : }
270 : #endif
271 1027 : }
272 :
273 :
274 : /**
275 : * Generates a float-move from register s to d. If s and d are
276 : * the same registers, no code will be generated.
277 : */
278 4487 : static inline void emit_fmove(codegendata* cd, int s, int d)
279 : {
280 4487 : if (s != d)
281 2062 : M_FMOV(s, d);
282 4487 : }
283 :
284 :
285 : /**
286 : * Generates an double-move from register s to d. If s and d are
287 : * the same registers, no code will be generated.
288 : */
289 295 : static inline void emit_dmove(codegendata* cd, int s, int d)
290 : {
291 295 : if (s != d)
292 13 : M_DMOV(s, d);
293 295 : }
294 :
295 :
296 : /* preserve compatibility with legacy code ************************************/
297 :
298 : #define M_INTMOVE(a, b) emit_imove(cd, a, b)
299 : #define M_LNGMOVE(a, b) emit_lmove(cd, a, b)
300 : #define M_FLTMOVE(a, b) emit_fmove(cd, a, b)
301 : #define M_DBLMOVE(a, b) emit_dmove(cd, a, b)
302 :
303 :
304 : #endif // EMIT_COMMON_HPP_
305 :
306 :
307 : /*
308 : * These are local overrides for various environment variables in Emacs.
309 : * Please do not remove this and leave it at the end of the file, where
310 : * Emacs will automagically detect them.
311 : * ---------------------------------------------------------------------
312 : * Local variables:
313 : * mode: c++
314 : * indent-tabs-mode: t
315 : * c-basic-offset: 4
316 : * tab-width: 4
317 : * End:
318 : * vim:noexpandtab:sw=4:ts=4:
319 : */
|