1 /* vm/jit/i386/emitfuncs.c - i386 code emitter functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Christian Thalinger
29 $Id: emitfuncs.c 3994 2005-12-22 14:00:06Z twisti $
37 #include "vm/statistics.h"
38 #include "vm/jit/jit.h"
39 #include "vm/jit/i386/md-abi.h"
40 #include "vm/jit/i386/emitfuncs.h"
41 #include "vm/jit/i386/codegen.h"
44 void i386_emit_ialu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
46 if (iptr->dst->flags & INMEMORY) {
47 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
48 if (src->regoff == iptr->dst->regoff) {
49 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
50 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
52 } else if (src->prev->regoff == iptr->dst->regoff) {
53 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
54 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
57 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
58 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4, REG_ITMP1);
59 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
62 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
63 if (src->regoff == iptr->dst->regoff) {
64 i386_alu_reg_membase(cd, alu_op, src->prev->regoff, REG_SP, iptr->dst->regoff * 4);
67 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
68 i386_alu_reg_reg(cd, alu_op, src->prev->regoff, REG_ITMP1);
69 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
72 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
73 if (src->prev->regoff == iptr->dst->regoff) {
74 i386_alu_reg_membase(cd, alu_op, src->regoff, REG_SP, iptr->dst->regoff * 4);
77 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
78 i386_alu_reg_reg(cd, alu_op, src->regoff, REG_ITMP1);
79 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
83 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 4);
84 i386_alu_reg_membase(cd, alu_op, src->regoff, REG_SP, iptr->dst->regoff * 4);
88 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
89 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, iptr->dst->regoff);
90 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4, iptr->dst->regoff);
92 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
93 if (src->prev->regoff != iptr->dst->regoff)
94 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
96 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4, iptr->dst->regoff);
98 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
99 if (src->regoff != iptr->dst->regoff)
100 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
102 i386_alu_membase_reg(cd, alu_op, REG_SP, src->prev->regoff * 4, iptr->dst->regoff);
105 if (src->regoff == iptr->dst->regoff) {
106 i386_alu_reg_reg(cd, alu_op, src->prev->regoff, iptr->dst->regoff);
109 if (src->prev->regoff != iptr->dst->regoff)
110 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
112 i386_alu_reg_reg(cd, alu_op, src->regoff, iptr->dst->regoff);
119 void i386_emit_ialuconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
121 if (iptr->dst->flags & INMEMORY) {
122 if (src->flags & INMEMORY) {
123 if (src->regoff == iptr->dst->regoff) {
124 i386_alu_imm_membase(cd, alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
127 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
128 i386_alu_imm_reg(cd, alu_op, iptr->val.i, REG_ITMP1);
129 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
133 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 4);
134 i386_alu_imm_membase(cd, alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
138 if (src->flags & INMEMORY) {
139 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, iptr->dst->regoff);
140 i386_alu_imm_reg(cd, alu_op, iptr->val.i, iptr->dst->regoff);
143 if (src->regoff != iptr->dst->regoff)
144 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
146 /* `inc reg' is slower on p4's (regarding to ia32 optimization */
147 /* reference manual and benchmarks) and as fast on athlon's. */
148 i386_alu_imm_reg(cd, alu_op, iptr->val.i, iptr->dst->regoff);
154 void i386_emit_lalu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
156 if (iptr->dst->flags & INMEMORY) {
157 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
158 if (src->regoff == iptr->dst->regoff) {
159 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
160 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
161 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4 + 4, REG_ITMP1);
162 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4 + 4);
164 } else if (src->prev->regoff == iptr->dst->regoff) {
165 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
166 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
167 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP1);
168 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4 + 4);
171 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
172 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4, REG_ITMP1);
173 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
174 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4 + 4, REG_ITMP1);
175 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4 + 4, REG_ITMP1);
176 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4 + 4);
183 void i386_emit_laluconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
185 if (iptr->dst->flags & INMEMORY) {
186 if (src->flags & INMEMORY) {
187 if (src->regoff == iptr->dst->regoff) {
188 i386_alu_imm_membase(cd, alu_op, iptr->val.l, REG_SP, iptr->dst->regoff * 4);
189 i386_alu_imm_membase(cd, alu_op, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 4 + 4);
192 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
193 i386_alu_imm_reg(cd, alu_op, iptr->val.l, REG_ITMP1);
194 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
195 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP1);
196 i386_alu_imm_reg(cd, alu_op, iptr->val.l >> 32, REG_ITMP1);
197 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4 + 4);
204 void i386_emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
206 if (iptr->dst->flags & INMEMORY) {
207 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
208 if (src->prev->regoff == iptr->dst->regoff) {
209 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
210 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 4);
213 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
214 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
215 i386_shift_reg(cd, shift_op, REG_ITMP1);
216 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
219 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
220 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
221 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 4);
222 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 4);
224 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
225 if (src->prev->regoff == iptr->dst->regoff) {
226 if (src->regoff != ECX)
227 i386_mov_reg_reg(cd, src->regoff, ECX);
229 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 4);
232 if (src->regoff != ECX)
233 i386_mov_reg_reg(cd, src->regoff, ECX);
235 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
236 i386_shift_reg(cd, shift_op, REG_ITMP1);
237 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
241 if (src->regoff != ECX)
242 i386_mov_reg_reg(cd, src->regoff, ECX);
244 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 4);
245 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 4);
249 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
250 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
251 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, iptr->dst->regoff);
252 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
254 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
255 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
257 if (src->prev->regoff != iptr->dst->regoff)
258 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
260 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
262 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
263 if (src->regoff != ECX)
264 i386_mov_reg_reg(cd, src->regoff, ECX);
266 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, iptr->dst->regoff);
267 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
270 if (src->regoff != ECX)
271 i386_mov_reg_reg(cd, src->regoff, ECX);
273 if (src->prev->regoff != iptr->dst->regoff)
274 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
276 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
282 void i386_emit_ishiftconst(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
284 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
285 if (src->regoff == iptr->dst->regoff) {
286 i386_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
289 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
290 i386_shift_imm_reg(cd, shift_op, iptr->val.i, REG_ITMP1);
291 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
294 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
295 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, iptr->dst->regoff);
296 i386_shift_imm_reg(cd, shift_op, iptr->val.i, iptr->dst->regoff);
298 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
299 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 4);
300 i386_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
303 if (src->regoff != iptr->dst->regoff)
304 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
306 i386_shift_imm_reg(cd, shift_op, iptr->val.i, iptr->dst->regoff);
311 void i386_emit_ifcc_iconst(codegendata *cd, s4 if_op, stackptr src, instruction *iptr)
313 if (iptr->dst->flags & INMEMORY) {
316 if (src->flags & INMEMORY) {
317 i386_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, src->regoff * 4);
320 i386_test_reg_reg(cd, src->regoff, src->regoff);
324 CALCOFFSETBYTES(offset, REG_SP, iptr->dst->regoff * 4);
326 i386_jcc(cd, if_op, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
327 i386_mov_imm_membase(cd, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
329 if (iptr[1].opc == ICMD_ELSE_ICONST) {
330 i386_jmp_imm(cd, offset);
331 i386_mov_imm_membase(cd, iptr[1].val.i, REG_SP, iptr->dst->regoff * 4);
335 if (src->flags & INMEMORY) {
336 i386_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, src->regoff * 4);
339 i386_test_reg_reg(cd, src->regoff, src->regoff);
342 i386_jcc(cd, if_op, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
343 i386_mov_imm_reg(cd, iptr->val.i, iptr->dst->regoff);
345 if (iptr[1].opc == ICMD_ELSE_ICONST) {
347 i386_mov_imm_reg(cd, iptr[1].val.i, iptr->dst->regoff);
357 void i386_mov_reg_reg(codegendata *cd, s4 reg, s4 dreg)
359 COUNT(count_mov_reg_reg);
360 *(cd->mcodeptr++) = 0x89;
361 i386_emit_reg((reg),(dreg));
365 void i386_mov_imm_reg(codegendata *cd, s4 imm, s4 reg)
367 *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
368 i386_emit_imm32((imm));
372 void i386_movb_imm_reg(codegendata *cd, s4 imm, s4 reg)
374 *(cd->mcodeptr++) = 0xc6;
375 i386_emit_reg(0,(reg));
376 i386_emit_imm8((imm));
380 void i386_mov_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
382 COUNT(count_mov_mem_reg);
383 *(cd->mcodeptr++) = 0x8b;
384 i386_emit_membase((basereg),(disp),(reg));
389 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
390 * constant membase immediate length of 32bit
392 void i386_mov_membase32_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
394 COUNT(count_mov_mem_reg);
395 *(cd->mcodeptr++) = 0x8b;
396 i386_emit_membase32((basereg),(disp),(reg));
400 void i386_mov_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
402 COUNT(count_mov_reg_mem);
403 *(cd->mcodeptr++) = 0x89;
404 i386_emit_membase((basereg),(disp),(reg));
408 void i386_mov_reg_membase32(codegendata *cd, s4 reg, s4 basereg, s4 disp)
410 COUNT(count_mov_reg_mem);
411 *(cd->mcodeptr++) = 0x89;
412 i386_emit_membase32((basereg),(disp),(reg));
416 void i386_mov_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
418 COUNT(count_mov_mem_reg);
419 *(cd->mcodeptr++) = 0x8b;
420 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
424 void i386_mov_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
426 COUNT(count_mov_reg_mem);
427 *(cd->mcodeptr++) = 0x89;
428 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
432 void i386_movw_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
434 COUNT(count_mov_reg_mem);
435 *(cd->mcodeptr++) = 0x66;
436 *(cd->mcodeptr++) = 0x89;
437 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
441 void i386_movb_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
443 COUNT(count_mov_reg_mem);
444 *(cd->mcodeptr++) = 0x88;
445 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
449 void i386_mov_reg_mem(codegendata *cd, s4 reg, s4 mem)
451 COUNT(count_mov_reg_mem);
452 *(cd->mcodeptr++) = 0x89;
453 i386_emit_mem((reg),(mem));
457 void i386_mov_mem_reg(codegendata *cd, s4 mem, s4 dreg)
459 COUNT(count_mov_mem_reg);
460 *(cd->mcodeptr++) = 0x8b;
461 i386_emit_mem((dreg),(mem));
465 void i386_mov_imm_mem(codegendata *cd, s4 imm, s4 mem)
467 *(cd->mcodeptr++) = 0xc7;
468 i386_emit_mem(0, mem);
469 i386_emit_imm32(imm);
473 void i386_mov_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
475 *(cd->mcodeptr++) = 0xc7;
476 i386_emit_membase((basereg),(disp),0);
477 i386_emit_imm32((imm));
481 void i386_mov_imm_membase32(codegendata *cd, s4 imm, s4 basereg, s4 disp)
483 *(cd->mcodeptr++) = 0xc7;
484 i386_emit_membase32((basereg),(disp),0);
485 i386_emit_imm32((imm));
489 void i386_movb_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
491 *(cd->mcodeptr++) = 0xc6;
492 i386_emit_membase((basereg),(disp),0);
493 i386_emit_imm8((imm));
497 void i386_movsbl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
499 COUNT(count_mov_mem_reg);
500 *(cd->mcodeptr++) = 0x0f;
501 *(cd->mcodeptr++) = 0xbe;
502 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
506 void i386_movswl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
508 COUNT(count_mov_mem_reg);
509 *(cd->mcodeptr++) = 0x0f;
510 *(cd->mcodeptr++) = 0xbf;
511 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
515 void i386_movzwl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
517 COUNT(count_mov_mem_reg);
518 *(cd->mcodeptr++) = 0x0f;
519 *(cd->mcodeptr++) = 0xb7;
520 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
524 void i386_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
526 *(cd->mcodeptr++) = 0xc7;
527 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
528 i386_emit_imm32((imm));
532 void i386_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
534 *(cd->mcodeptr++) = 0x66;
535 *(cd->mcodeptr++) = 0xc7;
536 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
537 i386_emit_imm16((imm));
541 void i386_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
543 *(cd->mcodeptr++) = 0xc6;
544 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
545 i386_emit_imm8((imm));
552 void i386_alu_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
554 *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
555 i386_emit_reg((reg),(dreg));
559 void i386_alu_reg_membase(codegendata *cd, s4 opc, s4 reg, s4 basereg, s4 disp)
561 *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
562 i386_emit_membase((basereg),(disp),(reg));
566 void i386_alu_membase_reg(codegendata *cd, s4 opc, s4 basereg, s4 disp, s4 reg)
568 *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 3;
569 i386_emit_membase((basereg),(disp),(reg));
573 void i386_alu_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
575 if (i386_is_imm8(imm)) {
576 *(cd->mcodeptr++) = 0x83;
577 i386_emit_reg((opc),(dreg));
578 i386_emit_imm8((imm));
580 *(cd->mcodeptr++) = 0x81;
581 i386_emit_reg((opc),(dreg));
582 i386_emit_imm32((imm));
587 void i386_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
589 *(cd->mcodeptr++) = 0x81;
590 i386_emit_reg((opc),(dreg));
591 i386_emit_imm32((imm));
595 void i386_alu_imm_membase(codegendata *cd, s4 opc, s4 imm, s4 basereg, s4 disp)
597 if (i386_is_imm8(imm)) {
598 *(cd->mcodeptr++) = 0x83;
599 i386_emit_membase((basereg),(disp),(opc));
600 i386_emit_imm8((imm));
602 *(cd->mcodeptr++) = 0x81;
603 i386_emit_membase((basereg),(disp),(opc));
604 i386_emit_imm32((imm));
609 void i386_test_reg_reg(codegendata *cd, s4 reg, s4 dreg)
611 *(cd->mcodeptr++) = 0x85;
612 i386_emit_reg((reg),(dreg));
616 void i386_test_imm_reg(codegendata *cd, s4 imm, s4 reg)
618 *(cd->mcodeptr++) = 0xf7;
619 i386_emit_reg(0,(reg));
620 i386_emit_imm32((imm));
626 * inc, dec operations
628 void i386_dec_mem(codegendata *cd, s4 mem)
630 *(cd->mcodeptr++) = 0xff;
631 i386_emit_mem(1,(mem));
635 void i386_cltd(codegendata *cd)
637 *(cd->mcodeptr++) = 0x99;
641 void i386_imul_reg_reg(codegendata *cd, s4 reg, s4 dreg)
643 *(cd->mcodeptr++) = 0x0f;
644 *(cd->mcodeptr++) = 0xaf;
645 i386_emit_reg((dreg),(reg));
649 void i386_imul_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
651 *(cd->mcodeptr++) = 0x0f;
652 *(cd->mcodeptr++) = 0xaf;
653 i386_emit_membase((basereg),(disp),(dreg));
657 void i386_imul_imm_reg(codegendata *cd, s4 imm, s4 dreg)
659 if (i386_is_imm8((imm))) {
660 *(cd->mcodeptr++) = 0x6b;
661 i386_emit_reg(0,(dreg));
662 i386_emit_imm8((imm));
664 *(cd->mcodeptr++) = 0x69;
665 i386_emit_reg(0,(dreg));
666 i386_emit_imm32((imm));
671 void i386_imul_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
673 if (i386_is_imm8((imm))) {
674 *(cd->mcodeptr++) = 0x6b;
675 i386_emit_reg((dreg),(reg));
676 i386_emit_imm8((imm));
678 *(cd->mcodeptr++) = 0x69;
679 i386_emit_reg((dreg),(reg));
680 i386_emit_imm32((imm));
685 void i386_imul_imm_membase_reg(codegendata *cd, s4 imm, s4 basereg, s4 disp, s4 dreg)
687 if (i386_is_imm8((imm))) {
688 *(cd->mcodeptr++) = 0x6b;
689 i386_emit_membase((basereg),(disp),(dreg));
690 i386_emit_imm8((imm));
692 *(cd->mcodeptr++) = 0x69;
693 i386_emit_membase((basereg),(disp),(dreg));
694 i386_emit_imm32((imm));
699 void i386_mul_membase(codegendata *cd, s4 basereg, s4 disp)
701 *(cd->mcodeptr++) = 0xf7;
702 i386_emit_membase((basereg),(disp),4);
706 void i386_idiv_reg(codegendata *cd, s4 reg)
708 *(cd->mcodeptr++) = 0xf7;
709 i386_emit_reg(7,(reg));
713 void i386_ret(codegendata *cd)
715 *(cd->mcodeptr++) = 0xc3;
723 void i386_shift_reg(codegendata *cd, s4 opc, s4 reg)
725 *(cd->mcodeptr++) = 0xd3;
726 i386_emit_reg((opc),(reg));
730 void i386_shift_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
732 *(cd->mcodeptr++) = 0xd3;
733 i386_emit_membase((basereg),(disp),(opc));
737 void i386_shift_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
740 *(cd->mcodeptr++) = 0xd1;
741 i386_emit_reg((opc),(dreg));
743 *(cd->mcodeptr++) = 0xc1;
744 i386_emit_reg((opc),(dreg));
745 i386_emit_imm8((imm));
750 void i386_shift_imm_membase(codegendata *cd, s4 opc, s4 imm, s4 basereg, s4 disp)
753 *(cd->mcodeptr++) = 0xd1;
754 i386_emit_membase((basereg),(disp),(opc));
756 *(cd->mcodeptr++) = 0xc1;
757 i386_emit_membase((basereg),(disp),(opc));
758 i386_emit_imm8((imm));
763 void i386_shld_reg_reg(codegendata *cd, s4 reg, s4 dreg)
765 *(cd->mcodeptr++) = 0x0f;
766 *(cd->mcodeptr++) = 0xa5;
767 i386_emit_reg((reg),(dreg));
771 void i386_shld_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
773 *(cd->mcodeptr++) = 0x0f;
774 *(cd->mcodeptr++) = 0xa4;
775 i386_emit_reg((reg),(dreg));
776 i386_emit_imm8((imm));
780 void i386_shld_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
782 *(cd->mcodeptr++) = 0x0f;
783 *(cd->mcodeptr++) = 0xa5;
784 i386_emit_membase((basereg),(disp),(reg));
788 void i386_shrd_reg_reg(codegendata *cd, s4 reg, s4 dreg)
790 *(cd->mcodeptr++) = 0x0f;
791 *(cd->mcodeptr++) = 0xad;
792 i386_emit_reg((reg),(dreg));
796 void i386_shrd_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
798 *(cd->mcodeptr++) = 0x0f;
799 *(cd->mcodeptr++) = 0xac;
800 i386_emit_reg((reg),(dreg));
801 i386_emit_imm8((imm));
805 void i386_shrd_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
807 *(cd->mcodeptr++) = 0x0f;
808 *(cd->mcodeptr++) = 0xad;
809 i386_emit_membase((basereg),(disp),(reg));
817 void i386_jmp_imm(codegendata *cd, s4 imm)
819 *(cd->mcodeptr++) = 0xe9;
820 i386_emit_imm32((imm));
824 void i386_jmp_reg(codegendata *cd, s4 reg)
826 *(cd->mcodeptr++) = 0xff;
827 i386_emit_reg(4,(reg));
831 void i386_jcc(codegendata *cd, s4 opc, s4 imm)
833 *(cd->mcodeptr++) = 0x0f;
834 *(cd->mcodeptr++) = 0x80 + (u1) (opc);
835 i386_emit_imm32((imm));
841 * conditional set operations
843 void i386_setcc_reg(codegendata *cd, s4 opc, s4 reg)
845 *(cd->mcodeptr++) = 0x0f;
846 *(cd->mcodeptr++) = 0x90 + (u1) (opc);
847 i386_emit_reg(0,(reg));
851 void i386_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
853 *(cd->mcodeptr++) = 0x0f;
854 *(cd->mcodeptr++) = 0x90 + (u1) (opc);
855 i386_emit_membase((basereg),(disp),0);
859 void i386_xadd_reg_mem(codegendata *cd, s4 reg, s4 mem)
861 *(cd->mcodeptr++) = 0x0f;
862 *(cd->mcodeptr++) = 0xc1;
863 i386_emit_mem((reg),(mem));
867 void i386_neg_reg(codegendata *cd, s4 reg)
869 *(cd->mcodeptr++) = 0xf7;
870 i386_emit_reg(3,(reg));
874 void i386_neg_membase(codegendata *cd, s4 basereg, s4 disp)
876 *(cd->mcodeptr++) = 0xf7;
877 i386_emit_membase((basereg),(disp),3);
882 void i386_push_imm(codegendata *cd, s4 imm)
884 *(cd->mcodeptr++) = 0x68;
885 i386_emit_imm32((imm));
889 void i386_pop_reg(codegendata *cd, s4 reg)
891 *(cd->mcodeptr++) = 0x58 + (0x07 & (u1) (reg));
895 void i386_push_reg(codegendata *cd, s4 reg)
897 *(cd->mcodeptr++) = 0x50 + (0x07 & (u1) (reg));
901 void i386_nop(codegendata *cd)
903 *(cd->mcodeptr++) = 0x90;
907 void i386_lock(codegendata *cd)
909 *(cd->mcodeptr++) = 0xf0;
916 void i386_call_reg(codegendata *cd, s4 reg)
918 *(cd->mcodeptr++) = 0xff;
919 i386_emit_reg(2,(reg));
923 void i386_call_imm(codegendata *cd, s4 imm)
925 *(cd->mcodeptr++) = 0xe8;
926 i386_emit_imm32((imm));
930 void i386_call_mem(codegendata *cd, s4 mem)
932 *(cd->mcodeptr++) = 0xff;
933 i386_emit_mem(2,(mem));
939 * floating point instructions
941 void i386_fld1(codegendata *cd)
943 *(cd->mcodeptr++) = 0xd9;
944 *(cd->mcodeptr++) = 0xe8;
948 void i386_fldz(codegendata *cd)
950 *(cd->mcodeptr++) = 0xd9;
951 *(cd->mcodeptr++) = 0xee;
955 void i386_fld_reg(codegendata *cd, s4 reg)
957 *(cd->mcodeptr++) = 0xd9;
958 *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
962 void i386_flds_membase(codegendata *cd, s4 basereg, s4 disp)
964 *(cd->mcodeptr++) = 0xd9;
965 i386_emit_membase((basereg),(disp),0);
969 void i386_flds_membase32(codegendata *cd, s4 basereg, s4 disp)
971 *(cd->mcodeptr++) = 0xd9;
972 i386_emit_membase32((basereg),(disp),0);
976 void i386_fldl_membase(codegendata *cd, s4 basereg, s4 disp)
978 *(cd->mcodeptr++) = 0xdd;
979 i386_emit_membase((basereg),(disp),0);
983 void i386_fldl_membase32(codegendata *cd, s4 basereg, s4 disp)
985 *(cd->mcodeptr++) = 0xdd;
986 i386_emit_membase32((basereg),(disp),0);
990 void i386_fldt_membase(codegendata *cd, s4 basereg, s4 disp)
992 *(cd->mcodeptr++) = 0xdb;
993 i386_emit_membase((basereg),(disp),5);
997 void i386_flds_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
999 *(cd->mcodeptr++) = 0xd9;
1000 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1004 void i386_fldl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1006 *(cd->mcodeptr++) = 0xdd;
1007 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1011 void i386_flds_mem(codegendata *cd, s4 mem)
1013 *(cd->mcodeptr++) = 0xd9;
1014 i386_emit_mem(0,(mem));
1018 void i386_fldl_mem(codegendata *cd, s4 mem)
1020 *(cd->mcodeptr++) = 0xdd;
1021 i386_emit_mem(0,(mem));
1025 void i386_fildl_membase(codegendata *cd, s4 basereg, s4 disp)
1027 *(cd->mcodeptr++) = 0xdb;
1028 i386_emit_membase((basereg),(disp),0);
1032 void i386_fildll_membase(codegendata *cd, s4 basereg, s4 disp)
1034 *(cd->mcodeptr++) = 0xdf;
1035 i386_emit_membase((basereg),(disp),5);
1039 void i386_fst_reg(codegendata *cd, s4 reg)
1041 *(cd->mcodeptr++) = 0xdd;
1042 *(cd->mcodeptr++) = 0xd0 + (0x07 & (u1) (reg));
1046 void i386_fsts_membase(codegendata *cd, s4 basereg, s4 disp)
1048 *(cd->mcodeptr++) = 0xd9;
1049 i386_emit_membase((basereg),(disp),2);
1053 void i386_fstl_membase(codegendata *cd, s4 basereg, s4 disp)
1055 *(cd->mcodeptr++) = 0xdd;
1056 i386_emit_membase((basereg),(disp),2);
1060 void i386_fsts_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1062 *(cd->mcodeptr++) = 0xd9;
1063 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
1067 void i386_fstl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1069 *(cd->mcodeptr++) = 0xdd;
1070 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
1074 void i386_fstp_reg(codegendata *cd, s4 reg)
1076 *(cd->mcodeptr++) = 0xdd;
1077 *(cd->mcodeptr++) = 0xd8 + (0x07 & (u1) (reg));
1081 void i386_fstps_membase(codegendata *cd, s4 basereg, s4 disp)
1083 *(cd->mcodeptr++) = 0xd9;
1084 i386_emit_membase((basereg),(disp),3);
1088 void i386_fstps_membase32(codegendata *cd, s4 basereg, s4 disp)
1090 *(cd->mcodeptr++) = 0xd9;
1091 i386_emit_membase32((basereg),(disp),3);
1095 void i386_fstpl_membase(codegendata *cd, s4 basereg, s4 disp)
1097 *(cd->mcodeptr++) = 0xdd;
1098 i386_emit_membase((basereg),(disp),3);
1102 void i386_fstpl_membase32(codegendata *cd, s4 basereg, s4 disp)
1104 *(cd->mcodeptr++) = 0xdd;
1105 i386_emit_membase32((basereg),(disp),3);
1109 void i386_fstpt_membase(codegendata *cd, s4 basereg, s4 disp)
1111 *(cd->mcodeptr++) = 0xdb;
1112 i386_emit_membase((basereg),(disp),7);
1116 void i386_fstps_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1118 *(cd->mcodeptr++) = 0xd9;
1119 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
1123 void i386_fstpl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1125 *(cd->mcodeptr++) = 0xdd;
1126 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
1130 void i386_fstps_mem(codegendata *cd, s4 mem)
1132 *(cd->mcodeptr++) = 0xd9;
1133 i386_emit_mem(3,(mem));
1137 void i386_fstpl_mem(codegendata *cd, s4 mem)
1139 *(cd->mcodeptr++) = 0xdd;
1140 i386_emit_mem(3,(mem));
1144 void i386_fistl_membase(codegendata *cd, s4 basereg, s4 disp)
1146 *(cd->mcodeptr++) = 0xdb;
1147 i386_emit_membase((basereg),(disp),2);
1151 void i386_fistpl_membase(codegendata *cd, s4 basereg, s4 disp)
1153 *(cd->mcodeptr++) = 0xdb;
1154 i386_emit_membase((basereg),(disp),3);
1158 void i386_fistpll_membase(codegendata *cd, s4 basereg, s4 disp)
1160 *(cd->mcodeptr++) = 0xdf;
1161 i386_emit_membase((basereg),(disp),7);
1165 void i386_fchs(codegendata *cd)
1167 *(cd->mcodeptr++) = 0xd9;
1168 *(cd->mcodeptr++) = 0xe0;
1172 void i386_faddp(codegendata *cd)
1174 *(cd->mcodeptr++) = 0xde;
1175 *(cd->mcodeptr++) = 0xc1;
1179 void i386_fadd_reg_st(codegendata *cd, s4 reg)
1181 *(cd->mcodeptr++) = 0xd8;
1182 *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1186 void i386_fadd_st_reg(codegendata *cd, s4 reg)
1188 *(cd->mcodeptr++) = 0xdc;
1189 *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1193 void i386_faddp_st_reg(codegendata *cd, s4 reg)
1195 *(cd->mcodeptr++) = 0xde;
1196 *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1200 void i386_fadds_membase(codegendata *cd, s4 basereg, s4 disp)
1202 *(cd->mcodeptr++) = 0xd8;
1203 i386_emit_membase((basereg),(disp),0);
1207 void i386_faddl_membase(codegendata *cd, s4 basereg, s4 disp)
1209 *(cd->mcodeptr++) = 0xdc;
1210 i386_emit_membase((basereg),(disp),0);
1214 void i386_fsub_reg_st(codegendata *cd, s4 reg)
1216 *(cd->mcodeptr++) = 0xd8;
1217 *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1221 void i386_fsub_st_reg(codegendata *cd, s4 reg)
1223 *(cd->mcodeptr++) = 0xdc;
1224 *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1228 void i386_fsubp_st_reg(codegendata *cd, s4 reg)
1230 *(cd->mcodeptr++) = 0xde;
1231 *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1235 void i386_fsubp(codegendata *cd)
1237 *(cd->mcodeptr++) = 0xde;
1238 *(cd->mcodeptr++) = 0xe9;
1242 void i386_fsubs_membase(codegendata *cd, s4 basereg, s4 disp)
1244 *(cd->mcodeptr++) = 0xd8;
1245 i386_emit_membase((basereg),(disp),4);
1249 void i386_fsubl_membase(codegendata *cd, s4 basereg, s4 disp)
1251 *(cd->mcodeptr++) = 0xdc;
1252 i386_emit_membase((basereg),(disp),4);
1256 void i386_fmul_reg_st(codegendata *cd, s4 reg)
1258 *(cd->mcodeptr++) = 0xd8;
1259 *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1263 void i386_fmul_st_reg(codegendata *cd, s4 reg)
1265 *(cd->mcodeptr++) = 0xdc;
1266 *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1270 void i386_fmulp(codegendata *cd)
1272 *(cd->mcodeptr++) = 0xde;
1273 *(cd->mcodeptr++) = 0xc9;
1277 void i386_fmulp_st_reg(codegendata *cd, s4 reg)
1279 *(cd->mcodeptr++) = 0xde;
1280 *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1284 void i386_fmuls_membase(codegendata *cd, s4 basereg, s4 disp)
1286 *(cd->mcodeptr++) = 0xd8;
1287 i386_emit_membase((basereg),(disp),1);
1291 void i386_fmull_membase(codegendata *cd, s4 basereg, s4 disp)
1293 *(cd->mcodeptr++) = 0xdc;
1294 i386_emit_membase((basereg),(disp),1);
1298 void i386_fdiv_reg_st(codegendata *cd, s4 reg)
1300 *(cd->mcodeptr++) = 0xd8;
1301 *(cd->mcodeptr++) = 0xf0 + (0x07 & (u1) (reg));
1305 void i386_fdiv_st_reg(codegendata *cd, s4 reg)
1307 *(cd->mcodeptr++) = 0xdc;
1308 *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1312 void i386_fdivp(codegendata *cd)
1314 *(cd->mcodeptr++) = 0xde;
1315 *(cd->mcodeptr++) = 0xf9;
1319 void i386_fdivp_st_reg(codegendata *cd, s4 reg)
1321 *(cd->mcodeptr++) = 0xde;
1322 *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1326 void i386_fxch(codegendata *cd)
1328 *(cd->mcodeptr++) = 0xd9;
1329 *(cd->mcodeptr++) = 0xc9;
1333 void i386_fxch_reg(codegendata *cd, s4 reg)
1335 *(cd->mcodeptr++) = 0xd9;
1336 *(cd->mcodeptr++) = 0xc8 + (0x07 & (reg));
1340 void i386_fprem(codegendata *cd)
1342 *(cd->mcodeptr++) = 0xd9;
1343 *(cd->mcodeptr++) = 0xf8;
1347 void i386_fprem1(codegendata *cd)
1349 *(cd->mcodeptr++) = 0xd9;
1350 *(cd->mcodeptr++) = 0xf5;
1354 void i386_fucom(codegendata *cd)
1356 *(cd->mcodeptr++) = 0xdd;
1357 *(cd->mcodeptr++) = 0xe1;
1361 void i386_fucom_reg(codegendata *cd, s4 reg)
1363 *(cd->mcodeptr++) = 0xdd;
1364 *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1368 void i386_fucomp_reg(codegendata *cd, s4 reg)
1370 *(cd->mcodeptr++) = 0xdd;
1371 *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1375 void i386_fucompp(codegendata *cd)
1377 *(cd->mcodeptr++) = 0xda;
1378 *(cd->mcodeptr++) = 0xe9;
1382 void i386_fnstsw(codegendata *cd)
1384 *(cd->mcodeptr++) = 0xdf;
1385 *(cd->mcodeptr++) = 0xe0;
1389 void i386_sahf(codegendata *cd)
1391 *(cd->mcodeptr++) = 0x9e;
1395 void i386_finit(codegendata *cd)
1397 *(cd->mcodeptr++) = 0x9b;
1398 *(cd->mcodeptr++) = 0xdb;
1399 *(cd->mcodeptr++) = 0xe3;
1403 void i386_fldcw_mem(codegendata *cd, s4 mem)
1405 *(cd->mcodeptr++) = 0xd9;
1406 i386_emit_mem(5,(mem));
1410 void i386_fldcw_membase(codegendata *cd, s4 basereg, s4 disp)
1412 *(cd->mcodeptr++) = 0xd9;
1413 i386_emit_membase((basereg),(disp),5);
1417 void i386_wait(codegendata *cd)
1419 *(cd->mcodeptr++) = 0x9b;
1423 void i386_ffree_reg(codegendata *cd, s4 reg)
1425 *(cd->mcodeptr++) = 0xdd;
1426 *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
1430 void i386_fdecstp(codegendata *cd)
1432 *(cd->mcodeptr++) = 0xd9;
1433 *(cd->mcodeptr++) = 0xf6;
1437 void i386_fincstp(codegendata *cd)
1439 *(cd->mcodeptr++) = 0xd9;
1440 *(cd->mcodeptr++) = 0xf7;
1445 * These are local overrides for various environment variables in Emacs.
1446 * Please do not remove this and leave it at the end of the file, where
1447 * Emacs will automagically detect them.
1448 * ---------------------------------------------------------------------
1451 * indent-tabs-mode: t