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 1735 2004-12-07 14:33:27Z twisti $
34 #include "vm/jit/jit.h"
35 #include "vm/jit/i386/emitfuncs.h"
36 #include "vm/jit/i386/codegen.h"
37 #include "vm/jit/i386/types.h"
40 void i386_emit_ialu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
42 if (iptr->dst->flags & INMEMORY) {
43 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
44 if (src->regoff == iptr->dst->regoff) {
45 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
46 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
48 } else if (src->prev->regoff == iptr->dst->regoff) {
49 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
50 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
53 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
54 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
55 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
58 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
59 if (src->regoff == iptr->dst->regoff) {
60 i386_alu_reg_membase(cd, alu_op, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
63 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
64 i386_alu_reg_reg(cd, alu_op, src->prev->regoff, REG_ITMP1);
65 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
68 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
69 if (src->prev->regoff == iptr->dst->regoff) {
70 i386_alu_reg_membase(cd, alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
73 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
74 i386_alu_reg_reg(cd, alu_op, src->regoff, REG_ITMP1);
75 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
79 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
80 i386_alu_reg_membase(cd, alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
84 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
85 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
86 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
88 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
89 if (src->prev->regoff != iptr->dst->regoff)
90 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
92 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
94 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
95 if (src->regoff != iptr->dst->regoff)
96 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
98 i386_alu_membase_reg(cd, alu_op, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
101 if (src->regoff == iptr->dst->regoff) {
102 i386_alu_reg_reg(cd, alu_op, src->prev->regoff, iptr->dst->regoff);
105 if (src->prev->regoff != iptr->dst->regoff)
106 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
108 i386_alu_reg_reg(cd, alu_op, src->regoff, iptr->dst->regoff);
115 void i386_emit_ialuconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
117 if (iptr->dst->flags & INMEMORY) {
118 if (src->flags & INMEMORY) {
119 if (src->regoff == iptr->dst->regoff) {
120 i386_alu_imm_membase(cd, alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
123 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
124 i386_alu_imm_reg(cd, alu_op, iptr->val.i, REG_ITMP1);
125 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
129 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
130 i386_alu_imm_membase(cd, alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
134 if (src->flags & INMEMORY) {
135 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
136 i386_alu_imm_reg(cd, alu_op, iptr->val.i, iptr->dst->regoff);
139 if (src->regoff != iptr->dst->regoff)
140 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
142 /* `inc reg' is slower on p4's (regarding to ia32 optimization */
143 /* reference manual and benchmarks) and as fast on athlon's. */
144 i386_alu_imm_reg(cd, alu_op, iptr->val.i, iptr->dst->regoff);
150 void i386_emit_lalu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
152 if (iptr->dst->flags & INMEMORY) {
153 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
154 if (src->regoff == iptr->dst->regoff) {
155 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
156 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
157 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
158 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
160 } else if (src->prev->regoff == iptr->dst->regoff) {
161 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
162 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
163 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
164 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
167 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
168 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
169 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
170 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
171 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
172 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
179 void i386_emit_laluconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
181 if (iptr->dst->flags & INMEMORY) {
182 if (src->flags & INMEMORY) {
183 if (src->regoff == iptr->dst->regoff) {
184 i386_alu_imm_membase(cd, alu_op, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
185 i386_alu_imm_membase(cd, alu_op, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
188 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
189 i386_alu_imm_reg(cd, alu_op, iptr->val.l, REG_ITMP1);
190 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
191 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
192 i386_alu_imm_reg(cd, alu_op, iptr->val.l >> 32, REG_ITMP1);
193 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
200 void i386_emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
202 if (iptr->dst->flags & INMEMORY) {
203 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
204 if (src->prev->regoff == iptr->dst->regoff) {
205 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
206 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 8);
209 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
210 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
211 i386_shift_reg(cd, shift_op, REG_ITMP1);
212 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
215 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
216 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
217 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
218 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 8);
220 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
221 if (src->prev->regoff == iptr->dst->regoff) {
222 if (src->regoff != ECX)
223 i386_mov_reg_reg(cd, src->regoff, ECX);
225 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 8);
228 if (src->regoff != ECX)
229 i386_mov_reg_reg(cd, src->regoff, ECX);
231 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
232 i386_shift_reg(cd, shift_op, REG_ITMP1);
233 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
237 if (src->regoff != ECX)
238 i386_mov_reg_reg(cd, src->regoff, ECX);
240 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
241 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 8);
245 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
246 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
247 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
248 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
250 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
251 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
253 if (src->prev->regoff != iptr->dst->regoff)
254 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
256 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
258 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
259 if (src->regoff != ECX)
260 i386_mov_reg_reg(cd, src->regoff, ECX);
262 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
263 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
266 if (src->regoff != ECX)
267 i386_mov_reg_reg(cd, src->regoff, ECX);
269 if (src->prev->regoff != iptr->dst->regoff)
270 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
272 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
278 void i386_emit_ishiftconst(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
280 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
281 if (src->regoff == iptr->dst->regoff) {
282 i386_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
285 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
286 i386_shift_imm_reg(cd, shift_op, iptr->val.i, REG_ITMP1);
287 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
290 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
291 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
292 i386_shift_imm_reg(cd, shift_op, iptr->val.i, iptr->dst->regoff);
294 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
295 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
296 i386_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
299 if (src->regoff != iptr->dst->regoff)
300 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
302 i386_shift_imm_reg(cd, shift_op, iptr->val.i, iptr->dst->regoff);
307 void i386_emit_ifcc_iconst(codegendata *cd, s4 if_op, stackptr src, instruction *iptr)
309 if (iptr->dst->flags & INMEMORY) {
312 if (src->flags & INMEMORY) {
313 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
316 i386_test_reg_reg(cd, src->regoff, src->regoff);
320 CALCOFFSETBYTES(offset, REG_SP, iptr->dst->regoff * 8);
322 i386_jcc(cd, if_op, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
323 i386_mov_imm_membase(cd, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
325 if (iptr[1].opc == ICMD_ELSE_ICONST) {
326 i386_jmp_imm(cd, offset);
327 i386_mov_imm_membase(cd, iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
331 if (src->flags & INMEMORY) {
332 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
335 i386_test_reg_reg(cd, src->regoff, src->regoff);
338 i386_jcc(cd, if_op, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
339 i386_mov_imm_reg(cd, iptr->val.i, iptr->dst->regoff);
341 if (iptr[1].opc == ICMD_ELSE_ICONST) {
343 i386_mov_imm_reg(cd, iptr[1].val.i, iptr->dst->regoff);
353 void i386_mov_reg_reg(codegendata *cd, s4 reg, s4 dreg)
355 *(cd->mcodeptr++) = 0x89;
356 i386_emit_reg((reg),(dreg));
360 void i386_mov_imm_reg(codegendata *cd, s4 imm, s4 reg)
362 *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
363 i386_emit_imm32((imm));
367 void i386_movb_imm_reg(codegendata *cd, s4 imm, s4 reg)
369 *(cd->mcodeptr++) = 0xc6;
370 i386_emit_reg(0,(reg));
371 i386_emit_imm8((imm));
375 void i386_mov_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
377 *(cd->mcodeptr++) = 0x8b;
378 i386_emit_membase((basereg),(disp),(reg));
383 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
384 * constant membase immediate length of 32bit
386 void i386_mov_membase32_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
388 *(cd->mcodeptr++) = 0x8b;
389 i386_address_byte(2, (reg), (basereg));
390 i386_emit_imm32((disp));
394 void i386_mov_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
396 *(cd->mcodeptr++) = 0x89;
397 i386_emit_membase((basereg),(disp),(reg));
401 void i386_mov_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
403 *(cd->mcodeptr++) = 0x8b;
404 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
408 void i386_mov_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
410 *(cd->mcodeptr++) = 0x89;
411 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
415 void i386_movw_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
417 *(cd->mcodeptr++) = 0x66;
418 *(cd->mcodeptr++) = 0x89;
419 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
423 void i386_movb_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
425 *(cd->mcodeptr++) = 0x88;
426 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
430 void i386_mov_reg_mem(codegendata *cd, s4 reg, s4 mem)
432 *(cd->mcodeptr++) = 0x89;
433 i386_emit_mem((reg),(mem));
437 void i386_mov_mem_reg(codegendata *cd, s4 mem, s4 dreg)
439 *(cd->mcodeptr++) = 0x8b;
440 i386_emit_mem((dreg),(mem));
444 void i386_mov_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
446 *(cd->mcodeptr++) = 0xc7;
447 i386_emit_membase((basereg),(disp),0);
448 i386_emit_imm32((imm));
452 void i386_movb_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
454 *(cd->mcodeptr++) = 0xc6;
455 i386_emit_membase((basereg),(disp),0);
456 i386_emit_imm8((imm));
460 void i386_movsbl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
462 *(cd->mcodeptr++) = 0x0f;
463 *(cd->mcodeptr++) = 0xbe;
464 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
468 void i386_movswl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
470 *(cd->mcodeptr++) = 0x0f;
471 *(cd->mcodeptr++) = 0xbf;
472 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
476 void i386_movzwl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
478 *(cd->mcodeptr++) = 0x0f;
479 *(cd->mcodeptr++) = 0xb7;
480 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
484 void i386_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
486 *(cd->mcodeptr++) = 0xc7;
487 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
488 i386_emit_imm32((imm));
492 void i386_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
494 *(cd->mcodeptr++) = 0x66;
495 *(cd->mcodeptr++) = 0xc7;
496 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
497 i386_emit_imm16((imm));
501 void i386_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
503 *(cd->mcodeptr++) = 0xc6;
504 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
505 i386_emit_imm8((imm));
512 void i386_alu_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
514 *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
515 i386_emit_reg((reg),(dreg));
519 void i386_alu_reg_membase(codegendata *cd, s4 opc, s4 reg, s4 basereg, s4 disp)
521 *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
522 i386_emit_membase((basereg),(disp),(reg));
526 void i386_alu_membase_reg(codegendata *cd, s4 opc, s4 basereg, s4 disp, s4 reg)
528 *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 3;
529 i386_emit_membase((basereg),(disp),(reg));
533 void i386_alu_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
535 if (i386_is_imm8(imm)) {
536 *(cd->mcodeptr++) = 0x83;
537 i386_emit_reg((opc),(dreg));
538 i386_emit_imm8((imm));
540 *(cd->mcodeptr++) = 0x81;
541 i386_emit_reg((opc),(dreg));
542 i386_emit_imm32((imm));
547 void i386_alu_imm_membase(codegendata *cd, s4 opc, s4 imm, s4 basereg, s4 disp)
549 if (i386_is_imm8(imm)) {
550 *(cd->mcodeptr++) = 0x83;
551 i386_emit_membase((basereg),(disp),(opc));
552 i386_emit_imm8((imm));
554 *(cd->mcodeptr++) = 0x81;
555 i386_emit_membase((basereg),(disp),(opc));
556 i386_emit_imm32((imm));
561 void i386_test_reg_reg(codegendata *cd, s4 reg, s4 dreg)
563 *(cd->mcodeptr++) = 0x85;
564 i386_emit_reg((reg),(dreg));
568 void i386_test_imm_reg(codegendata *cd, s4 imm, s4 reg)
570 *(cd->mcodeptr++) = 0xf7;
571 i386_emit_reg(0,(reg));
572 i386_emit_imm32((imm));
578 * inc, dec operations
580 void i386_dec_mem(codegendata *cd, s4 mem)
582 *(cd->mcodeptr++) = 0xff;
583 i386_emit_mem(1,(mem));
587 void i386_cltd(codegendata *cd)
589 *(cd->mcodeptr++) = 0x99;
593 void i386_imul_reg_reg(codegendata *cd, s4 reg, s4 dreg)
595 *(cd->mcodeptr++) = 0x0f;
596 *(cd->mcodeptr++) = 0xaf;
597 i386_emit_reg((dreg),(reg));
601 void i386_imul_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
603 *(cd->mcodeptr++) = 0x0f;
604 *(cd->mcodeptr++) = 0xaf;
605 i386_emit_membase((basereg),(disp),(dreg));
609 void i386_imul_imm_reg(codegendata *cd, s4 imm, s4 dreg)
611 if (i386_is_imm8((imm))) {
612 *(cd->mcodeptr++) = 0x6b;
613 i386_emit_reg(0,(dreg));
614 i386_emit_imm8((imm));
616 *(cd->mcodeptr++) = 0x69;
617 i386_emit_reg(0,(dreg));
618 i386_emit_imm32((imm));
623 void i386_imul_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
625 if (i386_is_imm8((imm))) {
626 *(cd->mcodeptr++) = 0x6b;
627 i386_emit_reg((dreg),(reg));
628 i386_emit_imm8((imm));
630 *(cd->mcodeptr++) = 0x69;
631 i386_emit_reg((dreg),(reg));
632 i386_emit_imm32((imm));
637 void i386_imul_imm_membase_reg(codegendata *cd, s4 imm, s4 basereg, s4 disp, s4 dreg)
639 if (i386_is_imm8((imm))) {
640 *(cd->mcodeptr++) = 0x6b;
641 i386_emit_membase((basereg),(disp),(dreg));
642 i386_emit_imm8((imm));
644 *(cd->mcodeptr++) = 0x69;
645 i386_emit_membase((basereg),(disp),(dreg));
646 i386_emit_imm32((imm));
651 void i386_mul_membase(codegendata *cd, s4 basereg, s4 disp)
653 *(cd->mcodeptr++) = 0xf7;
654 i386_emit_membase((basereg),(disp),4);
658 void i386_idiv_reg(codegendata *cd, s4 reg)
660 *(cd->mcodeptr++) = 0xf7;
661 i386_emit_reg(7,(reg));
665 void i386_ret(codegendata *cd)
667 *(cd->mcodeptr++) = 0xc3;
675 void i386_shift_reg(codegendata *cd, s4 opc, s4 reg)
677 *(cd->mcodeptr++) = 0xd3;
678 i386_emit_reg((opc),(reg));
682 void i386_shift_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
684 *(cd->mcodeptr++) = 0xd3;
685 i386_emit_membase((basereg),(disp),(opc));
689 void i386_shift_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
692 *(cd->mcodeptr++) = 0xd1;
693 i386_emit_reg((opc),(dreg));
695 *(cd->mcodeptr++) = 0xc1;
696 i386_emit_reg((opc),(dreg));
697 i386_emit_imm8((imm));
702 void i386_shift_imm_membase(codegendata *cd, s4 opc, s4 imm, s4 basereg, s4 disp)
705 *(cd->mcodeptr++) = 0xd1;
706 i386_emit_membase((basereg),(disp),(opc));
708 *(cd->mcodeptr++) = 0xc1;
709 i386_emit_membase((basereg),(disp),(opc));
710 i386_emit_imm8((imm));
715 void i386_shld_reg_reg(codegendata *cd, s4 reg, s4 dreg)
717 *(cd->mcodeptr++) = 0x0f;
718 *(cd->mcodeptr++) = 0xa5;
719 i386_emit_reg((reg),(dreg));
723 void i386_shld_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
725 *(cd->mcodeptr++) = 0x0f;
726 *(cd->mcodeptr++) = 0xa4;
727 i386_emit_reg((reg),(dreg));
728 i386_emit_imm8((imm));
732 void i386_shld_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
734 *(cd->mcodeptr++) = 0x0f;
735 *(cd->mcodeptr++) = 0xa5;
736 i386_emit_membase((basereg),(disp),(reg));
740 void i386_shrd_reg_reg(codegendata *cd, s4 reg, s4 dreg)
742 *(cd->mcodeptr++) = 0x0f;
743 *(cd->mcodeptr++) = 0xad;
744 i386_emit_reg((reg),(dreg));
748 void i386_shrd_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
750 *(cd->mcodeptr++) = 0x0f;
751 *(cd->mcodeptr++) = 0xac;
752 i386_emit_reg((reg),(dreg));
753 i386_emit_imm8((imm));
757 void i386_shrd_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
759 *(cd->mcodeptr++) = 0x0f;
760 *(cd->mcodeptr++) = 0xad;
761 i386_emit_membase((basereg),(disp),(reg));
769 void i386_jmp_imm(codegendata *cd, s4 imm)
771 *(cd->mcodeptr++) = 0xe9;
772 i386_emit_imm32((imm));
776 void i386_jmp_reg(codegendata *cd, s4 reg)
778 *(cd->mcodeptr++) = 0xff;
779 i386_emit_reg(4,(reg));
783 void i386_jcc(codegendata *cd, s4 opc, s4 imm)
785 *(cd->mcodeptr++) = 0x0f;
786 *(cd->mcodeptr++) = 0x80 + (u1) (opc);
787 i386_emit_imm32((imm));
793 * conditional set operations
795 void i386_setcc_reg(codegendata *cd, s4 opc, s4 reg)
797 *(cd->mcodeptr++) = 0x0f;
798 *(cd->mcodeptr++) = 0x90 + (u1) (opc);
799 i386_emit_reg(0,(reg));
803 void i386_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
805 *(cd->mcodeptr++) = 0x0f;
806 *(cd->mcodeptr++) = 0x90 + (u1) (opc);
807 i386_emit_membase((basereg),(disp),0);
811 void i386_xadd_reg_mem(codegendata *cd, s4 reg, s4 mem)
813 *(cd->mcodeptr++) = 0x0f;
814 *(cd->mcodeptr++) = 0xc1;
815 i386_emit_mem((reg),(mem));
819 void i386_neg_reg(codegendata *cd, s4 reg)
821 *(cd->mcodeptr++) = 0xf7;
822 i386_emit_reg(3,(reg));
826 void i386_neg_membase(codegendata *cd, s4 basereg, s4 disp)
828 *(cd->mcodeptr++) = 0xf7;
829 i386_emit_membase((basereg),(disp),3);
834 void i386_push_imm(codegendata *cd, s4 imm)
836 *(cd->mcodeptr++) = 0x68;
837 i386_emit_imm32((imm));
841 void i386_pop_reg(codegendata *cd, s4 reg)
843 *(cd->mcodeptr++) = 0x58 + (0x07 & (u1) (reg));
847 void i386_push_reg(codegendata *cd, s4 reg)
849 *(cd->mcodeptr++) = 0x50 + (0x07 & (u1) (reg));
853 void i386_nop(codegendata *cd)
855 *(cd->mcodeptr++) = 0x90;
859 void i386_lock(codegendata *cd)
861 *(cd->mcodeptr++) = 0xf0;
868 void i386_call_reg(codegendata *cd, s4 reg)
870 *(cd->mcodeptr++) = 0xff;
871 i386_emit_reg(2,(reg));
875 void i386_call_imm(codegendata *cd, s4 imm)
877 *(cd->mcodeptr++) = 0xe8;
878 i386_emit_imm32((imm));
882 void i386_call_mem(codegendata *cd, s4 mem)
884 *(cd->mcodeptr++) = 0xff;
885 i386_emit_mem(2,(mem));
891 * floating point instructions
893 void i386_fld1(codegendata *cd)
895 *(cd->mcodeptr++) = 0xd9;
896 *(cd->mcodeptr++) = 0xe8;
900 void i386_fldz(codegendata *cd)
902 *(cd->mcodeptr++) = 0xd9;
903 *(cd->mcodeptr++) = 0xee;
907 void i386_fld_reg(codegendata *cd, s4 reg)
909 *(cd->mcodeptr++) = 0xd9;
910 *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
914 void i386_flds_membase(codegendata *cd, s4 basereg, s4 disp)
916 *(cd->mcodeptr++) = 0xd9;
917 i386_emit_membase((basereg),(disp),0);
921 void i386_fldl_membase(codegendata *cd, s4 basereg, s4 disp)
923 *(cd->mcodeptr++) = 0xdd;
924 i386_emit_membase((basereg),(disp),0);
928 void i386_fldt_membase(codegendata *cd, s4 basereg, s4 disp)
930 *(cd->mcodeptr++) = 0xdb;
931 i386_emit_membase((basereg),(disp),5);
935 void i386_flds_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
937 *(cd->mcodeptr++) = 0xd9;
938 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
942 void i386_fldl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
944 *(cd->mcodeptr++) = 0xdd;
945 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
949 void i386_flds_mem(codegendata *cd, s4 mem)
951 *(cd->mcodeptr++) = 0xd9;
952 i386_emit_mem(0,(mem));
956 void i386_fldl_mem(codegendata *cd, s4 mem)
958 *(cd->mcodeptr++) = 0xdd;
959 i386_emit_mem(0,(mem));
963 void i386_fildl_membase(codegendata *cd, s4 basereg, s4 disp)
965 *(cd->mcodeptr++) = 0xdb;
966 i386_emit_membase((basereg),(disp),0);
970 void i386_fildll_membase(codegendata *cd, s4 basereg, s4 disp)
972 *(cd->mcodeptr++) = 0xdf;
973 i386_emit_membase((basereg),(disp),5);
977 void i386_fst_reg(codegendata *cd, s4 reg)
979 *(cd->mcodeptr++) = 0xdd;
980 *(cd->mcodeptr++) = 0xd0 + (0x07 & (u1) (reg));
984 void i386_fsts_membase(codegendata *cd, s4 basereg, s4 disp)
986 *(cd->mcodeptr++) = 0xd9;
987 i386_emit_membase((basereg),(disp),2);
991 void i386_fstl_membase(codegendata *cd, s4 basereg, s4 disp)
993 *(cd->mcodeptr++) = 0xdd;
994 i386_emit_membase((basereg),(disp),2);
998 void i386_fsts_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1000 *(cd->mcodeptr++) = 0xd9;
1001 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
1005 void i386_fstl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1007 *(cd->mcodeptr++) = 0xdd;
1008 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
1012 void i386_fstp_reg(codegendata *cd, s4 reg)
1014 *(cd->mcodeptr++) = 0xdd;
1015 *(cd->mcodeptr++) = 0xd8 + (0x07 & (u1) (reg));
1019 void i386_fstps_membase(codegendata *cd, s4 basereg, s4 disp)
1021 *(cd->mcodeptr++) = 0xd9;
1022 i386_emit_membase((basereg),(disp),3);
1026 void i386_fstpl_membase(codegendata *cd, s4 basereg, s4 disp)
1028 *(cd->mcodeptr++) = 0xdd;
1029 i386_emit_membase((basereg),(disp),3);
1033 void i386_fstpt_membase(codegendata *cd, s4 basereg, s4 disp)
1035 *(cd->mcodeptr++) = 0xdb;
1036 i386_emit_membase((basereg),(disp),7);
1040 void i386_fstps_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1042 *(cd->mcodeptr++) = 0xd9;
1043 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
1047 void i386_fstpl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1049 *(cd->mcodeptr++) = 0xdd;
1050 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
1054 void i386_fstps_mem(codegendata *cd, s4 mem)
1056 *(cd->mcodeptr++) = 0xd9;
1057 i386_emit_mem(3,(mem));
1061 void i386_fstpl_mem(codegendata *cd, s4 mem)
1063 *(cd->mcodeptr++) = 0xdd;
1064 i386_emit_mem(3,(mem));
1068 void i386_fistl_membase(codegendata *cd, s4 basereg, s4 disp)
1070 *(cd->mcodeptr++) = 0xdb;
1071 i386_emit_membase((basereg),(disp),2);
1075 void i386_fistpl_membase(codegendata *cd, s4 basereg, s4 disp)
1077 *(cd->mcodeptr++) = 0xdb;
1078 i386_emit_membase((basereg),(disp),3);
1082 void i386_fistpll_membase(codegendata *cd, s4 basereg, s4 disp)
1084 *(cd->mcodeptr++) = 0xdf;
1085 i386_emit_membase((basereg),(disp),7);
1089 void i386_fchs(codegendata *cd)
1091 *(cd->mcodeptr++) = 0xd9;
1092 *(cd->mcodeptr++) = 0xe0;
1096 void i386_faddp(codegendata *cd)
1098 *(cd->mcodeptr++) = 0xde;
1099 *(cd->mcodeptr++) = 0xc1;
1103 void i386_fadd_reg_st(codegendata *cd, s4 reg)
1105 *(cd->mcodeptr++) = 0xd8;
1106 *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1110 void i386_fadd_st_reg(codegendata *cd, s4 reg)
1112 *(cd->mcodeptr++) = 0xdc;
1113 *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1117 void i386_faddp_st_reg(codegendata *cd, s4 reg)
1119 *(cd->mcodeptr++) = 0xde;
1120 *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1124 void i386_fadds_membase(codegendata *cd, s4 basereg, s4 disp)
1126 *(cd->mcodeptr++) = 0xd8;
1127 i386_emit_membase((basereg),(disp),0);
1131 void i386_faddl_membase(codegendata *cd, s4 basereg, s4 disp)
1133 *(cd->mcodeptr++) = 0xdc;
1134 i386_emit_membase((basereg),(disp),0);
1138 void i386_fsub_reg_st(codegendata *cd, s4 reg)
1140 *(cd->mcodeptr++) = 0xd8;
1141 *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1145 void i386_fsub_st_reg(codegendata *cd, s4 reg)
1147 *(cd->mcodeptr++) = 0xdc;
1148 *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1152 void i386_fsubp_st_reg(codegendata *cd, s4 reg)
1154 *(cd->mcodeptr++) = 0xde;
1155 *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1159 void i386_fsubp(codegendata *cd)
1161 *(cd->mcodeptr++) = 0xde;
1162 *(cd->mcodeptr++) = 0xe9;
1166 void i386_fsubs_membase(codegendata *cd, s4 basereg, s4 disp)
1168 *(cd->mcodeptr++) = 0xd8;
1169 i386_emit_membase((basereg),(disp),4);
1173 void i386_fsubl_membase(codegendata *cd, s4 basereg, s4 disp)
1175 *(cd->mcodeptr++) = 0xdc;
1176 i386_emit_membase((basereg),(disp),4);
1180 void i386_fmul_reg_st(codegendata *cd, s4 reg)
1182 *(cd->mcodeptr++) = 0xd8;
1183 *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1187 void i386_fmul_st_reg(codegendata *cd, s4 reg)
1189 *(cd->mcodeptr++) = 0xdc;
1190 *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1194 void i386_fmulp(codegendata *cd)
1196 *(cd->mcodeptr++) = 0xde;
1197 *(cd->mcodeptr++) = 0xc9;
1201 void i386_fmulp_st_reg(codegendata *cd, s4 reg)
1203 *(cd->mcodeptr++) = 0xde;
1204 *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1208 void i386_fmuls_membase(codegendata *cd, s4 basereg, s4 disp)
1210 *(cd->mcodeptr++) = 0xd8;
1211 i386_emit_membase((basereg),(disp),1);
1215 void i386_fmull_membase(codegendata *cd, s4 basereg, s4 disp)
1217 *(cd->mcodeptr++) = 0xdc;
1218 i386_emit_membase((basereg),(disp),1);
1222 void i386_fdiv_reg_st(codegendata *cd, s4 reg)
1224 *(cd->mcodeptr++) = 0xd8;
1225 *(cd->mcodeptr++) = 0xf0 + (0x07 & (u1) (reg));
1229 void i386_fdiv_st_reg(codegendata *cd, s4 reg)
1231 *(cd->mcodeptr++) = 0xdc;
1232 *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1236 void i386_fdivp(codegendata *cd)
1238 *(cd->mcodeptr++) = 0xde;
1239 *(cd->mcodeptr++) = 0xf9;
1243 void i386_fdivp_st_reg(codegendata *cd, s4 reg)
1245 *(cd->mcodeptr++) = 0xde;
1246 *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1250 void i386_fxch(codegendata *cd)
1252 *(cd->mcodeptr++) = 0xd9;
1253 *(cd->mcodeptr++) = 0xc9;
1257 void i386_fxch_reg(codegendata *cd, s4 reg)
1259 *(cd->mcodeptr++) = 0xd9;
1260 *(cd->mcodeptr++) = 0xc8 + (0x07 & (reg));
1264 void i386_fprem(codegendata *cd)
1266 *(cd->mcodeptr++) = 0xd9;
1267 *(cd->mcodeptr++) = 0xf8;
1271 void i386_fprem1(codegendata *cd)
1273 *(cd->mcodeptr++) = 0xd9;
1274 *(cd->mcodeptr++) = 0xf5;
1278 void i386_fucom(codegendata *cd)
1280 *(cd->mcodeptr++) = 0xdd;
1281 *(cd->mcodeptr++) = 0xe1;
1285 void i386_fucom_reg(codegendata *cd, s4 reg)
1287 *(cd->mcodeptr++) = 0xdd;
1288 *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1292 void i386_fucomp_reg(codegendata *cd, s4 reg)
1294 *(cd->mcodeptr++) = 0xdd;
1295 *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1299 void i386_fucompp(codegendata *cd)
1301 *(cd->mcodeptr++) = 0xda;
1302 *(cd->mcodeptr++) = 0xe9;
1306 void i386_fnstsw(codegendata *cd)
1308 *(cd->mcodeptr++) = 0xdf;
1309 *(cd->mcodeptr++) = 0xe0;
1313 void i386_sahf(codegendata *cd)
1315 *(cd->mcodeptr++) = 0x9e;
1319 void i386_finit(codegendata *cd)
1321 *(cd->mcodeptr++) = 0x9b;
1322 *(cd->mcodeptr++) = 0xdb;
1323 *(cd->mcodeptr++) = 0xe3;
1327 void i386_fldcw_mem(codegendata *cd, s4 mem)
1329 *(cd->mcodeptr++) = 0xd9;
1330 i386_emit_mem(5,(mem));
1334 void i386_fldcw_membase(codegendata *cd, s4 basereg, s4 disp)
1336 *(cd->mcodeptr++) = 0xd9;
1337 i386_emit_membase((basereg),(disp),5);
1341 void i386_wait(codegendata *cd)
1343 *(cd->mcodeptr++) = 0x9b;
1347 void i386_ffree_reg(codegendata *cd, s4 reg)
1349 *(cd->mcodeptr++) = 0xdd;
1350 *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
1354 void i386_fdecstp(codegendata *cd)
1356 *(cd->mcodeptr++) = 0xd9;
1357 *(cd->mcodeptr++) = 0xf6;
1361 void i386_fincstp(codegendata *cd)
1363 *(cd->mcodeptr++) = 0xd9;
1364 *(cd->mcodeptr++) = 0xf7;
1369 * These are local overrides for various environment variables in Emacs.
1370 * Please do not remove this and leave it at the end of the file, where
1371 * Emacs will automagically detect them.
1372 * ---------------------------------------------------------------------
1375 * indent-tabs-mode: t