Line data Source code
1 : /* src/vm/jit/x86_64/emit.hpp - machine dependent emit function prototypes
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 MD_EMIT_HPP_
27 : #define MD_EMIT_HPP_ 1
28 :
29 : #include "config.h"
30 : #include "vm/types.hpp"
31 :
32 : #include "vm/jit/codegen-common.hpp"
33 :
34 : /* macros to create code ******************************************************/
35 :
36 : /* immediate data union */
37 :
38 : typedef union {
39 : s4 i;
40 : s8 l;
41 : float f;
42 : double d;
43 : void *a;
44 : u1 b[8];
45 : } imm_buf;
46 :
47 :
48 : /* opcodes for alu instructions */
49 :
50 : #define ALU_ADD 0
51 : #define ALU_OR 1
52 : #define ALU_ADC 2
53 : #define ALU_SBB 3
54 : #define ALU_AND 4
55 : #define ALU_SUB 5
56 : #define ALU_XOR 6
57 : #define ALU_CMP 7
58 :
59 :
60 : #define SHIFT_ROL 0
61 : #define SHIFT_ROR 1
62 : #define SHIFT_RCL 2
63 : #define SHIFT_RCR 3
64 : #define SHIFT_SHL 4
65 : #define SHIFT_SHR 5
66 : #define SHIFT_SAR 7
67 :
68 :
69 : #define CC_O 0
70 : #define CC_NO 1
71 : #define CC_B 2
72 : #define CC_C 2
73 : #define CC_NAE 2
74 : #define CC_AE 3
75 : #define CC_NB 3
76 : #define CC_NC 3
77 : #define CC_E 4
78 : #define CC_Z 4
79 : #define CC_NE 5
80 : #define CC_NZ 5
81 : #define CC_BE 6
82 : #define CC_NA 6
83 : #define CC_A 7
84 : #define CC_NBE 7
85 : #define CC_S 8
86 : #define CC_LZ 8
87 : #define CC_NS 9
88 : #define CC_GEZ 9
89 : #define CC_P 0x0a
90 : #define CC_PE 0x0a
91 : #define CC_NP 0x0b
92 : #define CC_PO 0x0b
93 : #define CC_L 0x0c
94 : #define CC_NGE 0x0c
95 : #define CC_GE 0x0d
96 : #define CC_NL 0x0d
97 : #define CC_LE 0x0e
98 : #define CC_NG 0x0e
99 : #define CC_G 0x0f
100 : #define CC_NLE 0x0f
101 :
102 :
103 : /* modrm and stuff */
104 :
105 : #define emit_address_byte(mod,reg,rm) \
106 : do { \
107 : *(cd->mcodeptr++) = ((((mod) & 0x03) << 6) | (((reg) & 0x07) << 3) | ((rm) & 0x07)); \
108 : } while (0);
109 :
110 :
111 : #define emit_rex(size,reg,index,rm) \
112 : do { \
113 : if (((size) == 1) || ((reg) > 7) || ((index) > 7) || ((rm) > 7)) \
114 : *(cd->mcodeptr++) = (0x40 | (((size) & 0x01) << 3) | ((((reg) >> 3) & 0x01) << 2) | ((((index) >> 3) & 0x01) << 1) | (((rm) >> 3) & 0x01)); \
115 : } while (0)
116 :
117 :
118 : #define emit_byte_rex(reg,index,rm) \
119 : do { \
120 : *(cd->mcodeptr++) = (0x40 | ((((reg) >> 3) & 0x01) << 2) | ((((index) >> 3) & 0x01) << 1) | (((rm) >> 3) & 0x01)); \
121 : } while (0)
122 :
123 :
124 : #define emit_mem(r,disp) \
125 : do { \
126 : emit_address_byte(0,(r),5); \
127 : emit_imm32((disp)); \
128 : } while (0)
129 :
130 :
131 : #define emit_imm8(imm) \
132 : do { \
133 : *(cd->mcodeptr++) = (u1) ((imm) & 0xff); \
134 : } while (0)
135 :
136 :
137 : #define emit_imm16(imm) \
138 : do { \
139 : imm_buf imb; \
140 : imb.i = (s4) (imm); \
141 : *(cd->mcodeptr++) = imb.b[0]; \
142 : *(cd->mcodeptr++) = imb.b[1]; \
143 : } while (0)
144 :
145 :
146 : #define emit_imm32(imm) \
147 : do { \
148 : imm_buf imb; \
149 : imb.i = (s4) (imm); \
150 : *(cd->mcodeptr++) = imb.b[0]; \
151 : *(cd->mcodeptr++) = imb.b[1]; \
152 : *(cd->mcodeptr++) = imb.b[2]; \
153 : *(cd->mcodeptr++) = imb.b[3]; \
154 : } while (0)
155 :
156 :
157 : #define emit_imm64(imm) \
158 : do { \
159 : imm_buf imb; \
160 : imb.l = (s8) (imm); \
161 : *(cd->mcodeptr++) = imb.b[0]; \
162 : *(cd->mcodeptr++) = imb.b[1]; \
163 : *(cd->mcodeptr++) = imb.b[2]; \
164 : *(cd->mcodeptr++) = imb.b[3]; \
165 : *(cd->mcodeptr++) = imb.b[4]; \
166 : *(cd->mcodeptr++) = imb.b[5]; \
167 : *(cd->mcodeptr++) = imb.b[6]; \
168 : *(cd->mcodeptr++) = imb.b[7]; \
169 : } while (0)
170 :
171 :
172 : /* convenience macros *********************************************************/
173 :
174 : #define emit_reg(reg,rm) emit_address_byte(3,(reg),(rm))
175 :
176 :
177 : /* function prototypes ********************************************************/
178 :
179 : void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d);
180 :
181 :
182 : /* code generation prototypes */
183 :
184 : void emit_ishift(jitdata *jd, s4 shift_op, instruction *iptr);
185 : void emit_lshift(jitdata *jd, s4 shift_op, instruction *iptr);
186 :
187 :
188 : /* integer instructions */
189 :
190 : void emit_nop(codegendata *cd, int length);
191 : void emit_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg);
192 : void emit_mov_imm_reg(codegendata *cd, s8 imm, s8 reg);
193 : void emit_movl_reg_reg(codegendata *cd, s8 reg, s8 dreg);
194 : void emit_movl_imm_reg(codegendata *cd, s8 imm, s8 reg);
195 : void emit_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
196 : void emit_mov_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
197 : void emit_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
198 : void emit_movl_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
199 : void emit_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
200 : void emit_mov_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp);
201 : void emit_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
202 : void emit_movl_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp);
203 : void emit_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
204 : void emit_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
205 : void emit_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
206 : void emit_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
207 : void emit_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
208 : void emit_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
209 : void emit_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp);
210 : void emit_mov_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp);
211 : void emit_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp);
212 : void emit_movl_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp);
213 : void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
214 : void emit_movsbq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
215 : void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
216 : void emit_movswq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
217 : void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
218 : void emit_movslq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
219 : void emit_movzbq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
220 : void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
221 : void emit_movzwq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
222 : void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
223 : void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
224 : void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
225 : void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale);
226 : void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale);
227 : void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale);
228 : void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale);
229 :
230 : void emit_mov_mem_reg(codegendata *cd, s4 disp, s4 dreg);
231 :
232 : void emit_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg);
233 : void emit_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg);
234 : void emit_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp);
235 : void emit_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp);
236 : void emit_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg);
237 : void emit_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg);
238 : void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
239 : void emit_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg);
240 : void emit_alul_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg);
241 : void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
242 : void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
243 : void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
244 : void emit_alu_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
245 : void emit_alul_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
246 : void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg);
247 : void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg);
248 : void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg);
249 : void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg);
250 : void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg);
251 : void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
252 : void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
253 :
254 : void emit_incl_reg(codegendata *cd, s8 reg);
255 : void emit_incq_reg(codegendata *cd, s8 reg);
256 : void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp);
257 : void emit_incq_membase(codegendata *cd, s8 basereg, s8 disp);
258 :
259 : void emit_decl_membase(codegendata *cd, s8 basereg, s8 disp);
260 :
261 : void emit_cltd(codegendata *cd);
262 : void emit_cqto(codegendata *cd);
263 : void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg);
264 : void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg);
265 : void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
266 : void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
267 : void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg);
268 : void emit_imul_imm_reg_reg(codegendata *cd, s8 imm,s8 reg, s8 dreg);
269 : void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg);
270 : void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg);
271 : void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg);
272 : void emit_idiv_reg(codegendata *cd, s8 reg);
273 : void emit_idivl_reg(codegendata *cd, s8 reg);
274 : void emit_shift_reg(codegendata *cd, s8 opc, s8 reg);
275 : void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg);
276 : void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp);
277 : void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp);
278 : void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
279 : void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
280 : void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
281 : void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
282 : void emit_jmp_imm(codegendata *cd, s8 imm);
283 : void emit_jmp_reg(codegendata *cd, s8 reg);
284 : void emit_jcc(codegendata *cd, s8 opc, s8 imm);
285 :
286 : void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg);
287 : void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp);
288 :
289 : void emit_cmovcc_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg);
290 : void emit_cmovccl_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg);
291 :
292 : void emit_neg_reg(codegendata *cd, s8 reg);
293 : void emit_negl_reg(codegendata *cd, s8 reg);
294 : void emit_neg_membase(codegendata *cd, s8 basereg, s8 disp);
295 : void emit_negl_membase(codegendata *cd, s8 basereg, s8 disp);
296 : void emit_push_reg(codegendata *cd, s8 reg);
297 : void emit_push_imm(codegendata *cd, s8 imm);
298 : void emit_pop_reg(codegendata *cd, s8 reg);
299 : void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg);
300 : void emit_call_reg(codegendata *cd, s8 reg);
301 : void emit_call_imm(codegendata *cd, s8 imm);
302 : void emit_call_mem(codegendata *cd, ptrint mem);
303 :
304 :
305 : /* floating point instructions (SSE2) */
306 :
307 : void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
308 : void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
309 : void emit_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
310 : void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
311 : void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
312 : void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
313 : void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
314 : void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
315 : void emit_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
316 : void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg);
317 : void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
318 : void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg);
319 : void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
320 : void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
321 : void emit_movd_reg_freg(codegendata *cd, s8 reg, s8 freg);
322 : void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg);
323 : void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
324 : void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
325 : void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
326 : void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
327 : void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
328 : void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
329 : void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
330 : void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
331 : void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
332 : void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
333 : void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
334 : void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp);
335 : void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
336 : void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp);
337 : void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
338 : void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
339 : void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
340 : void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
341 : void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
342 : void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
343 : void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
344 : void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
345 : void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
346 : void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
347 : void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
348 : void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
349 : void emit_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
350 : void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
351 : void emit_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
352 : void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
353 : void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
354 : void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
355 : void emit_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg);
356 : void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
357 : void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
358 : void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
359 :
360 :
361 : /* system instructions ********************************************************/
362 :
363 : void emit_rdtsc(codegendata *cd);
364 : void emit_mfence(codegendata *cd);
365 :
366 :
367 : /**
368 : * Emit code to recompute the procedure vector. This is a nop,
369 : * because we do not use a procedure vector.
370 : */
371 359402 : static inline void emit_recompute_pv(codegendata* cd) {}
372 :
373 : void emit_arbitrary_nop(codegendata *cd, int disp);
374 :
375 : #endif // MD_EMIT_HPP_
376 :
377 :
378 : /*
379 : * These are local overrides for various environment variables in Emacs.
380 : * Please do not remove this and leave it at the end of the file, where
381 : * Emacs will automagically detect them.
382 : * ---------------------------------------------------------------------
383 : * Local variables:
384 : * mode: c++
385 : * indent-tabs-mode: t
386 : * c-basic-offset: 4
387 : * tab-width: 4
388 : * End:
389 : * vim:noexpandtab:sw=4:ts=4:
390 : */
|