CACAO
emit-common.hpp
Go to the documentation of this file.
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 */
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);
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);
208 
210 void emit_trap_countdown(codegendata *cd, s4 *counter);
211 uint32_t emit_trap(codegendata *cd);
213 
214 void emit_patcher_traps(jitdata *jd);
215 
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 
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 static inline void emit_imove(codegendata* cd, int s, int d)
242 {
243  if (s != d)
244 #if defined(__ARM__)
245  // XXX Fix this!!!
246  M_MOV(d, s);
247 #else
248  M_MOV(s, d);
249 #endif
250 }
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 static inline void emit_lmove(codegendata* cd, int s, int d)
258 {
259 #if SIZEOF_VOID_P == 8
260  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)));
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));
269  }
270 #endif
271 }
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 static inline void emit_fmove(codegendata* cd, int s, int d)
279 {
280  if (s != d)
281  M_FMOV(s, d);
282 }
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 static inline void emit_dmove(codegendata* cd, int s, int d)
290 {
291  if (s != d)
292  M_DMOV(s, d);
293 }
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  */
#define GET_HIGH_REG(a)
s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg)
Definition: emit-common.cpp:63
Definition: jit.hpp:126
void emit_monitor_exit(jitdata *jd, int32_t syncslot_offset)
Generates synchronization code to leave a monitor.
Definition: emit.cpp:565
void emit_monitor_enter(jitdata *jd, int32_t syncslot_offset)
Generates synchronization code to enter a monitor.
Definition: emit.cpp:507
void emit_bcc(codegendata *cd, basicblock *target, s4 condition, u4 options)
void emit_store_low(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
Definition: emit.cpp:234
static void emit_lmove(codegendata *cd, int s, int d)
Generates a long-move from register s to d.
void emit_label_bcc(codegendata *cd, s4 label, s4 condition, u4 options)
void emit_arraystore_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:380
int64_t s8
Definition: types.hpp:48
Definition: reg.hpp:43
void emit_recompute_pv(codegendata *cd)
Emit code to recompute the procedure vector.
Definition: emit.cpp:495
void emit_abstractmethoderror_trap(codegendata *cd)
Definition: emit.cpp:468
#define M_FMOV(b, c)
Definition: codegen.hpp:341
void emit_fastpath_monitor_enter(jitdata *jd, instruction *iptr, int d)
Generates fast-path code for the below builtin.
Definition: emit.cpp:496
void emit_verbosecall_enter(jitdata *jd)
Definition: emit.cpp:625
void emit_exception_check(codegendata *cd, instruction *iptr)
Definition: emit.cpp:447
#define GET_LOW_REG(a)
void emit_store_high(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
Definition: emit.cpp:258
void emit_lconst(codegendata *cd, s4 d, s8 value)
Definition: emit.cpp:233
void emit_patcher_traps(jitdata *jd)
s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
Definition: emit.cpp:174
void emit_label_br(codegendata *cd, s4 label)
s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
Definition: emit-common.cpp:82
void emit_trap_compiler(codegendata *cd)
Definition: emit.cpp:463
void emit_trap(codegendata *cd, u1 Xd, int type)
Definition: emit-asm.hpp:563
s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
Definition: emit.cpp:66
int32_t s4
Definition: types.hpp:45
void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
Definition: emit.cpp:113
void emit_fastpath_monitor_exit(jitdata *jd, instruction *iptr, int d)
Generates fast-path code for the below builtin.
Definition: emit.cpp:512
void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
Definition: emit.cpp:346
#define M_MOV(a, b)
Definition: codegen.hpp:340
void emit_icmp_imm(codegendata *cd, int reg, int32_t value)
Emits code comparing a single register.
Definition: emit.cpp:243
void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
void emit_copy(jitdata *jd, instruction *iptr)
Definition: emit.cpp:153
uint32_t u4
Definition: types.hpp:46
void emit_icmpeq_imm(codegendata *cd, int reg, int32_t value, int d)
Emits code comparing one integer register to an immediate value.
Definition: emit.cpp:253
void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
Definition: emit.cpp:136
void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
Definition: emit.cpp:396
void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 opt)
Definition: emit.cpp:263
int8_t s1
Definition: types.hpp:39
int16_t s2
Definition: types.hpp:42
void emit_iconst(codegendata *cd, s4 d, s4 value)
Definition: emit.cpp:220
static void emit_fmove(codegendata *cd, int s, int d)
Generates a float-move from register s to d.
BeginInst * target
void emit_label(codegendata *cd, s4 label)
void emit_bccz(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
Definition: emit.cpp:362
static void emit_dmove(codegendata *cd, int s, int d)
Generates an double-move from register s to d.
static void emit_imove(codegendata *cd, int s, int d)
Generates an integer-move from register s to d.
void emit_verbosecall_exit(jitdata *jd)
Definition: emit.cpp:766
void emit_br(codegendata *cd, basicblock *target)
void emit_trap_countdown(codegendata *cd, s4 *counter)
Definition: emit.cpp:565
void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
Definition: emit.cpp:431
#define M_DMOV(b, c)
Definition: codegen.hpp:342
double d
Definition: reg.hpp:51