1 /* src/vm/jit/emit-common.hpp - common code emitter functions
3 Copyright (C) 2006, 2007, 2008, 2009
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 Copyright (C) 2009 Theobroma Systems Ltd.
7 This file is part of CACAO.
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.
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.
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
27 #ifndef _EMIT_COMMON_HPP
28 #define _EMIT_COMMON_HPP
36 #include "vm/jit/codegen-common.hpp"
37 #include "vm/jit/jit.hpp"
40 /* branch labels **************************************************************/
42 #define BRANCH_LABEL_1 1
43 #define BRANCH_LABEL_2 2
44 #define BRANCH_LABEL_3 3
45 #define BRANCH_LABEL_4 4
46 #define BRANCH_LABEL_5 5
47 #define BRANCH_LABEL_6 6
48 #define BRANCH_LABEL_7 7
49 #define BRANCH_LABEL_8 8
50 #define BRANCH_LABEL_9 9
51 #define BRANCH_LABEL_10 10
54 /* constant range macros ******************************************************/
56 #if SIZEOF_VOID_P == 8
59 (((s8) (c) >= -128) && ((s8) (c) <= 127))
61 # define IS_IMM32(c) \
62 (((s8) (c) >= (-2147483647-1)) && ((s8) (c) <= 2147483647))
67 (((s4) (c) >= -128) && ((s4) (c) <= 127))
69 # define IS_IMM16(c) \
70 (((s4) (c) >= -32768) && ((s4) (c) <= 32767))
75 /* code generation functions **************************************************/
81 s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg);
82 s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg);
83 s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg);
84 s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg);
86 #if SIZEOF_VOID_P == 4
87 s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg);
88 s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg);
89 s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg);
90 s4 emit_load_s3_low(jitdata *jd, instruction *iptr, s4 tempreg);
92 s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg);
93 s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg);
94 s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg);
95 s4 emit_load_s3_high(jitdata *jd, instruction *iptr, s4 tempreg);
98 void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d);
99 void emit_store_dst(jitdata *jd, instruction *iptr, s4 d);
101 #if SIZEOF_VOID_P == 4
102 void emit_store_low(jitdata *jd, instruction *iptr, varinfo *dst, s4 d);
103 void emit_store_high(jitdata *jd, instruction *iptr, varinfo *dst, s4 d);
106 void emit_copy(jitdata *jd, instruction *iptr);
108 void emit_iconst(codegendata *cd, s4 d, s4 value);
109 void emit_lconst(codegendata *cd, s4 d, s8 value);
111 /* compare-emitting functions targeting an integer register */
113 #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
114 void emit_icmpeq_imm(codegendata* cd, int reg, int32_t value, int d);
117 /* compare-emitting functions targeting the condition register */
119 #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
120 void emit_icmp_imm(codegendata* cd, int reg, int32_t value);
123 /* branch-emitting functions */
124 void emit_bccz(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options);
125 void emit_bcc(codegendata *cd, basicblock *target, s4 condition, u4 options);
127 /* wrapper for unconditional branches */
128 void emit_br(codegendata *cd, basicblock *target);
130 /* wrappers for branches on one integer register */
132 #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
133 void emit_beqz(codegendata *cd, basicblock *target, s4 reg);
134 void emit_bnez(codegendata *cd, basicblock *target, s4 reg);
135 void emit_bltz(codegendata *cd, basicblock *target, s4 reg);
136 void emit_bgez(codegendata *cd, basicblock *target, s4 reg);
137 void emit_bgtz(codegendata *cd, basicblock *target, s4 reg);
138 void emit_blez(codegendata *cd, basicblock *target, s4 reg);
141 /* wrappers for branches on two integer registers */
143 #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS
144 void emit_beq(codegendata *cd, basicblock *target, s4 s1, s4 s2);
145 void emit_bne(codegendata *cd, basicblock *target, s4 s1, s4 s2);
148 /* wrappers for branches on condition codes */
150 #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
151 void emit_beq(codegendata *cd, basicblock *target);
152 void emit_bne(codegendata *cd, basicblock *target);
153 void emit_blt(codegendata *cd, basicblock *target);
154 void emit_bge(codegendata *cd, basicblock *target);
155 void emit_bgt(codegendata *cd, basicblock *target);
156 void emit_ble(codegendata *cd, basicblock *target);
159 #if SUPPORT_BRANCH_CONDITIONAL_UNSIGNED_CONDITIONS
160 void emit_bult(codegendata *cd, basicblock *target);
161 void emit_bule(codegendata *cd, basicblock *target);
162 void emit_buge(codegendata *cd, basicblock *target);
163 void emit_bugt(codegendata *cd, basicblock *target);
166 #if defined(__POWERPC__) || defined(__POWERPC64__)
167 void emit_bnan(codegendata *cd, basicblock *target);
171 void emit_label_bccz(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options);
172 void emit_label(codegendata *cd, s4 label);
173 void emit_label_bcc(codegendata *cd, s4 label, s4 condition, u4 options);
175 void emit_label_br(codegendata *cd, s4 label);
177 #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
178 void emit_label_beqz(codegendata* cd, int label, int reg);
179 void emit_label_bnez(codegendata* cd, int label, int reg);
180 void emit_label_bltz(codegendata* cd, int label, int reg);
181 void emit_label_bgtz(codegendata* cd, int label, int reg);
184 #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS
185 void emit_label_beq(codegendata* cd, int label, int s1, int s2);
186 void emit_label_bne(codegendata* cd, int label, int s1, int s2);
189 #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
190 void emit_label_beq(codegendata *cd, s4 label);
191 void emit_label_bne(codegendata *cd, s4 label);
192 void emit_label_blt(codegendata *cd, s4 label);
193 void emit_label_bge(codegendata *cd, s4 label);
194 void emit_label_bgt(codegendata *cd, s4 label);
195 void emit_label_ble(codegendata *cd, s4 label);
198 /* machine dependent branch-emitting function */
199 void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 options);
201 void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg);
202 void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2);
203 void emit_arraystore_check(codegendata *cd, instruction *iptr);
204 void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1);
205 void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg);
206 void emit_exception_check(codegendata *cd, instruction *iptr);
208 void emit_trap_compiler(codegendata *cd);
209 void emit_trap_countdown(codegendata *cd, s4 *counter);
210 uint32_t emit_trap(codegendata *cd);
212 void emit_patcher_traps(jitdata *jd);
214 void emit_recompute_pv(codegendata* cd);
216 /* machine dependent faspath-emitting functions */
217 void emit_fastpath_monitor_enter(jitdata* jd, instruction* iptr, int d);
218 void emit_fastpath_monitor_exit(jitdata* jd, instruction* iptr, int d);
220 #if defined(ENABLE_THREADS)
221 void emit_monitor_enter(jitdata* jd, int32_t syncslot_offset);
222 void emit_monitor_exit(jitdata* jd, int32_t syncslot_offset);
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);
232 void emit_verbosecall_enter(jitdata *jd);
233 void emit_verbosecall_exit(jitdata *jd);
240 /* inline code generation functions *******************************************/
243 * Generates an integer-move from register s to d. If s and d are
244 * the same registers, no code will be generated.
246 static inline void emit_imove(codegendata* cd, int s, int d)
259 * Generates a long-move from register s to d. If s and d are
260 * the same registers, no code will be generated.
262 static inline void emit_lmove(codegendata* cd, int s, int d)
264 #if SIZEOF_VOID_P == 8
265 emit_imove(cd, s, d);
267 if (GET_HIGH_REG(s) == GET_LOW_REG(d)) {
268 assert((GET_LOW_REG(s) != GET_HIGH_REG(d)));
269 emit_imove(cd, GET_HIGH_REG(s), GET_HIGH_REG(d));
270 emit_imove(cd, GET_LOW_REG(s), GET_LOW_REG(d));
272 emit_imove(cd, GET_LOW_REG(s), GET_LOW_REG(d));
273 emit_imove(cd, GET_HIGH_REG(s), GET_HIGH_REG(d));
280 * Generates a float-move from register s to d. If s and d are
281 * the same registers, no code will be generated.
283 static inline void emit_fmove(codegendata* cd, int s, int d)
291 * Generates an double-move from register s to d. If s and d are
292 * the same registers, no code will be generated.
294 static inline void emit_dmove(codegendata* cd, int s, int d)
301 /* preserve compatibility with legacy code ************************************/
303 #define M_INTMOVE(a, b) emit_imove(cd, a, b)
304 #define M_LNGMOVE(a, b) emit_lmove(cd, a, b)
305 #define M_FLTMOVE(a, b) emit_fmove(cd, a, b)
306 #define M_DBLMOVE(a, b) emit_dmove(cd, a, b)
309 #endif /* _EMIT_COMMON_HPP */
313 * These are local overrides for various environment variables in Emacs.
314 * Please do not remove this and leave it at the end of the file, where
315 * Emacs will automagically detect them.
316 * ---------------------------------------------------------------------
319 * indent-tabs-mode: t
323 * vim:noexpandtab:sw=4:ts=4: