1 /* vm/jit/i386/emitfuncs.c - i386 code emitter functions
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6 S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Christian Thalinger
30 $Id: emitfuncs.c 1623 2004-11-30 14:18:19Z twisti $
35 #include "vm/jit/jit.h"
36 #include "vm/jit/i386/emitfuncs.h"
37 #include "vm/jit/i386/codegen.h"
38 #include "vm/jit/i386/types.h"
41 void i386_emit_ialu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
43 if (iptr->dst->flags & INMEMORY) {
44 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
45 if (src->regoff == iptr->dst->regoff) {
46 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
47 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
49 } else if (src->prev->regoff == iptr->dst->regoff) {
50 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
51 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
54 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
55 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
56 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
59 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
60 if (src->regoff == iptr->dst->regoff) {
61 i386_alu_reg_membase(cd, alu_op, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
64 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
65 i386_alu_reg_reg(cd, alu_op, src->prev->regoff, REG_ITMP1);
66 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
69 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
70 if (src->prev->regoff == iptr->dst->regoff) {
71 i386_alu_reg_membase(cd, alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
74 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
75 i386_alu_reg_reg(cd, alu_op, src->regoff, REG_ITMP1);
76 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
80 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
81 i386_alu_reg_membase(cd, alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
85 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
86 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
87 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
89 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
90 if (src->prev->regoff != iptr->dst->regoff)
91 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
93 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
95 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
96 if (src->regoff != iptr->dst->regoff)
97 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
99 i386_alu_membase_reg(cd, alu_op, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
102 if (src->regoff == iptr->dst->regoff) {
103 i386_alu_reg_reg(cd, alu_op, src->prev->regoff, iptr->dst->regoff);
106 if (src->prev->regoff != iptr->dst->regoff)
107 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
109 i386_alu_reg_reg(cd, alu_op, src->regoff, iptr->dst->regoff);
116 void i386_emit_ialuconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
118 if (iptr->dst->flags & INMEMORY) {
119 if (src->flags & INMEMORY) {
120 if (src->regoff == iptr->dst->regoff) {
121 i386_alu_imm_membase(cd, alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
124 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
125 i386_alu_imm_reg(cd, alu_op, iptr->val.i, REG_ITMP1);
126 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
130 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
131 i386_alu_imm_membase(cd, alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
135 if (src->flags & INMEMORY) {
136 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
137 i386_alu_imm_reg(cd, alu_op, iptr->val.i, iptr->dst->regoff);
140 if (src->regoff != iptr->dst->regoff)
141 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
143 /* `inc reg' is slower on p4's (regarding to ia32 optimization */
144 /* reference manual and benchmarks) and as fast on athlon's. */
145 i386_alu_imm_reg(cd, alu_op, iptr->val.i, iptr->dst->regoff);
151 void i386_emit_lalu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
153 if (iptr->dst->flags & INMEMORY) {
154 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
155 if (src->regoff == iptr->dst->regoff) {
156 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
157 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
158 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
159 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
161 } else if (src->prev->regoff == iptr->dst->regoff) {
162 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
163 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
164 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
165 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
168 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
169 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
170 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
171 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
172 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
173 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
180 void i386_emit_laluconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
182 if (iptr->dst->flags & INMEMORY) {
183 if (src->flags & INMEMORY) {
184 if (src->regoff == iptr->dst->regoff) {
185 i386_alu_imm_membase(cd, alu_op, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
186 i386_alu_imm_membase(cd, alu_op, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
189 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
190 i386_alu_imm_reg(cd, alu_op, iptr->val.l, REG_ITMP1);
191 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
192 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
193 i386_alu_imm_reg(cd, alu_op, iptr->val.l >> 32, REG_ITMP1);
194 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
201 void i386_emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
203 if (iptr->dst->flags & INMEMORY) {
204 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
205 if (src->prev->regoff == iptr->dst->regoff) {
206 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
207 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 8);
210 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
211 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
212 i386_shift_reg(cd, shift_op, REG_ITMP1);
213 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
216 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
217 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
218 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
219 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 8);
221 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
222 if (src->prev->regoff == iptr->dst->regoff) {
223 if (src->regoff != ECX)
224 i386_mov_reg_reg(cd, src->regoff, ECX);
226 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 8);
229 if (src->regoff != ECX)
230 i386_mov_reg_reg(cd, src->regoff, ECX);
232 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
233 i386_shift_reg(cd, shift_op, REG_ITMP1);
234 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
238 if (src->regoff != ECX)
239 i386_mov_reg_reg(cd, src->regoff, ECX);
241 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
242 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 8);
246 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
247 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
248 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
249 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
251 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
252 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
254 if (src->prev->regoff != iptr->dst->regoff)
255 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
257 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
259 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
260 if (src->regoff != ECX)
261 i386_mov_reg_reg(cd, src->regoff, ECX);
263 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
264 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
267 if (src->regoff != ECX)
268 i386_mov_reg_reg(cd, src->regoff, ECX);
270 if (src->prev->regoff != iptr->dst->regoff)
271 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
273 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
279 void i386_emit_ishiftconst(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
281 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
282 if (src->regoff == iptr->dst->regoff) {
283 i386_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
286 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
287 i386_shift_imm_reg(cd, shift_op, iptr->val.i, REG_ITMP1);
288 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
291 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
292 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
293 i386_shift_imm_reg(cd, shift_op, iptr->val.i, iptr->dst->regoff);
295 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
296 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
297 i386_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
300 if (src->regoff != iptr->dst->regoff)
301 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
303 i386_shift_imm_reg(cd, shift_op, iptr->val.i, iptr->dst->regoff);
308 void i386_emit_ifcc_iconst(codegendata *cd, s4 if_op, stackptr src, instruction *iptr)
310 if (iptr->dst->flags & INMEMORY) {
313 if (src->flags & INMEMORY) {
314 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
317 i386_test_reg_reg(cd, src->regoff, src->regoff);
321 CALCOFFSETBYTES(offset, REG_SP, iptr->dst->regoff * 8);
323 i386_jcc(cd, if_op, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
324 i386_mov_imm_membase(cd, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
326 if (iptr[1].opc == ICMD_ELSE_ICONST) {
327 i386_jmp_imm(cd, offset);
328 i386_mov_imm_membase(cd, iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
332 if (src->flags & INMEMORY) {
333 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
336 i386_test_reg_reg(cd, src->regoff, src->regoff);
339 i386_jcc(cd, if_op, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
340 i386_mov_imm_reg(cd, iptr->val.i, iptr->dst->regoff);
342 if (iptr[1].opc == ICMD_ELSE_ICONST) {
344 i386_mov_imm_reg(cd, iptr[1].val.i, iptr->dst->regoff);
354 void i386_mov_reg_reg(codegendata *cd, s4 reg, s4 dreg)
356 *(cd->mcodeptr++) = 0x89;
357 i386_emit_reg((reg),(dreg));
361 void i386_mov_imm_reg(codegendata *cd, s4 imm, s4 reg)
363 *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
364 i386_emit_imm32((imm));
368 void i386_movb_imm_reg(codegendata *cd, s4 imm, s4 reg)
370 *(cd->mcodeptr++) = 0xc6;
371 i386_emit_reg(0,(reg));
372 i386_emit_imm8((imm));
376 void i386_mov_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
378 *(cd->mcodeptr++) = 0x8b;
379 i386_emit_membase((basereg),(disp),(reg));
384 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
385 * constant membase immediate length of 32bit
387 void i386_mov_membase32_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
389 *(cd->mcodeptr++) = 0x8b;
390 i386_address_byte(2, (reg), (basereg));
391 i386_emit_imm32((disp));
395 void i386_mov_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
397 *(cd->mcodeptr++) = 0x89;
398 i386_emit_membase((basereg),(disp),(reg));
402 void i386_mov_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
404 *(cd->mcodeptr++) = 0x8b;
405 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
409 void i386_mov_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
411 *(cd->mcodeptr++) = 0x89;
412 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
416 void i386_movw_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
418 *(cd->mcodeptr++) = 0x66;
419 *(cd->mcodeptr++) = 0x89;
420 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
424 void i386_movb_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
426 *(cd->mcodeptr++) = 0x88;
427 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
431 void i386_mov_reg_mem(codegendata *cd, s4 reg, s4 mem)
433 *(cd->mcodeptr++) = 0x89;
434 i386_emit_mem((reg),(mem));
438 void i386_mov_mem_reg(codegendata *cd, s4 mem, s4 dreg)
440 *(cd->mcodeptr++) = 0x8b;
441 i386_emit_mem((dreg),(mem));
445 void i386_mov_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
447 *(cd->mcodeptr++) = 0xc7;
448 i386_emit_membase((basereg),(disp),0);
449 i386_emit_imm32((imm));
453 void i386_movb_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
455 *(cd->mcodeptr++) = 0xc6;
456 i386_emit_membase((basereg),(disp),0);
457 i386_emit_imm8((imm));
461 void i386_movsbl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
463 *(cd->mcodeptr++) = 0x0f;
464 *(cd->mcodeptr++) = 0xbe;
465 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
469 void i386_movswl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
471 *(cd->mcodeptr++) = 0x0f;
472 *(cd->mcodeptr++) = 0xbf;
473 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
477 void i386_movzwl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
479 *(cd->mcodeptr++) = 0x0f;
480 *(cd->mcodeptr++) = 0xb7;
481 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
485 void i386_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
487 *(cd->mcodeptr++) = 0xc7;
488 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
489 i386_emit_imm32((imm));
493 void i386_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
495 *(cd->mcodeptr++) = 0x66;
496 *(cd->mcodeptr++) = 0xc7;
497 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
498 i386_emit_imm16((imm));
502 void i386_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
504 *(cd->mcodeptr++) = 0xc6;
505 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
506 i386_emit_imm8((imm));
513 void i386_alu_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
515 *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
516 i386_emit_reg((reg),(dreg));
520 void i386_alu_reg_membase(codegendata *cd, s4 opc, s4 reg, s4 basereg, s4 disp)
522 *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
523 i386_emit_membase((basereg),(disp),(reg));
527 void i386_alu_membase_reg(codegendata *cd, s4 opc, s4 basereg, s4 disp, s4 reg)
529 *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 3;
530 i386_emit_membase((basereg),(disp),(reg));
534 void i386_alu_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
536 if (i386_is_imm8(imm)) {
537 *(cd->mcodeptr++) = 0x83;
538 i386_emit_reg((opc),(dreg));
539 i386_emit_imm8((imm));
541 *(cd->mcodeptr++) = 0x81;
542 i386_emit_reg((opc),(dreg));
543 i386_emit_imm32((imm));
548 void i386_alu_imm_membase(codegendata *cd, s4 opc, s4 imm, s4 basereg, s4 disp)
550 if (i386_is_imm8(imm)) {
551 *(cd->mcodeptr++) = 0x83;
552 i386_emit_membase((basereg),(disp),(opc));
553 i386_emit_imm8((imm));
555 *(cd->mcodeptr++) = 0x81;
556 i386_emit_membase((basereg),(disp),(opc));
557 i386_emit_imm32((imm));
562 void i386_test_reg_reg(codegendata *cd, s4 reg, s4 dreg)
564 *(cd->mcodeptr++) = 0x85;
565 i386_emit_reg((reg),(dreg));
569 void i386_test_imm_reg(codegendata *cd, s4 imm, s4 reg)
571 *(cd->mcodeptr++) = 0xf7;
572 i386_emit_reg(0,(reg));
573 i386_emit_imm32((imm));
579 * inc, dec operations
581 void i386_dec_mem(codegendata *cd, s4 mem)
583 *(cd->mcodeptr++) = 0xff;
584 i386_emit_mem(1,(mem));
588 void i386_cltd(codegendata *cd)
590 *(cd->mcodeptr++) = 0x99;
594 void i386_imul_reg_reg(codegendata *cd, s4 reg, s4 dreg)
596 *(cd->mcodeptr++) = 0x0f;
597 *(cd->mcodeptr++) = 0xaf;
598 i386_emit_reg((dreg),(reg));
602 void i386_imul_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
604 *(cd->mcodeptr++) = 0x0f;
605 *(cd->mcodeptr++) = 0xaf;
606 i386_emit_membase((basereg),(disp),(dreg));
610 void i386_imul_imm_reg(codegendata *cd, s4 imm, s4 dreg)
612 if (i386_is_imm8((imm))) {
613 *(cd->mcodeptr++) = 0x6b;
614 i386_emit_reg(0,(dreg));
615 i386_emit_imm8((imm));
617 *(cd->mcodeptr++) = 0x69;
618 i386_emit_reg(0,(dreg));
619 i386_emit_imm32((imm));
624 void i386_imul_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
626 if (i386_is_imm8((imm))) {
627 *(cd->mcodeptr++) = 0x6b;
628 i386_emit_reg((dreg),(reg));
629 i386_emit_imm8((imm));
631 *(cd->mcodeptr++) = 0x69;
632 i386_emit_reg((dreg),(reg));
633 i386_emit_imm32((imm));
638 void i386_imul_imm_membase_reg(codegendata *cd, s4 imm, s4 basereg, s4 disp, s4 dreg)
640 if (i386_is_imm8((imm))) {
641 *(cd->mcodeptr++) = 0x6b;
642 i386_emit_membase((basereg),(disp),(dreg));
643 i386_emit_imm8((imm));
645 *(cd->mcodeptr++) = 0x69;
646 i386_emit_membase((basereg),(disp),(dreg));
647 i386_emit_imm32((imm));
652 void i386_mul_membase(codegendata *cd, s4 basereg, s4 disp)
654 *(cd->mcodeptr++) = 0xf7;
655 i386_emit_membase((basereg),(disp),4);
659 void i386_idiv_reg(codegendata *cd, s4 reg)
661 *(cd->mcodeptr++) = 0xf7;
662 i386_emit_reg(7,(reg));
666 void i386_ret(codegendata *cd)
668 *(cd->mcodeptr++) = 0xc3;
676 void i386_shift_reg(codegendata *cd, s4 opc, s4 reg)
678 *(cd->mcodeptr++) = 0xd3;
679 i386_emit_reg((opc),(reg));
683 void i386_shift_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
685 *(cd->mcodeptr++) = 0xd3;
686 i386_emit_membase((basereg),(disp),(opc));
690 void i386_shift_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
693 *(cd->mcodeptr++) = 0xd1;
694 i386_emit_reg((opc),(dreg));
696 *(cd->mcodeptr++) = 0xc1;
697 i386_emit_reg((opc),(dreg));
698 i386_emit_imm8((imm));
703 void i386_shift_imm_membase(codegendata *cd, s4 opc, s4 imm, s4 basereg, s4 disp)
706 *(cd->mcodeptr++) = 0xd1;
707 i386_emit_membase((basereg),(disp),(opc));
709 *(cd->mcodeptr++) = 0xc1;
710 i386_emit_membase((basereg),(disp),(opc));
711 i386_emit_imm8((imm));
716 void i386_shld_reg_reg(codegendata *cd, s4 reg, s4 dreg)
718 *(cd->mcodeptr++) = 0x0f;
719 *(cd->mcodeptr++) = 0xa5;
720 i386_emit_reg((reg),(dreg));
724 void i386_shld_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
726 *(cd->mcodeptr++) = 0x0f;
727 *(cd->mcodeptr++) = 0xa4;
728 i386_emit_reg((reg),(dreg));
729 i386_emit_imm8((imm));
733 void i386_shld_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
735 *(cd->mcodeptr++) = 0x0f;
736 *(cd->mcodeptr++) = 0xa5;
737 i386_emit_membase((basereg),(disp),(reg));
741 void i386_shrd_reg_reg(codegendata *cd, s4 reg, s4 dreg)
743 *(cd->mcodeptr++) = 0x0f;
744 *(cd->mcodeptr++) = 0xad;
745 i386_emit_reg((reg),(dreg));
749 void i386_shrd_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
751 *(cd->mcodeptr++) = 0x0f;
752 *(cd->mcodeptr++) = 0xac;
753 i386_emit_reg((reg),(dreg));
754 i386_emit_imm8((imm));
758 void i386_shrd_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
760 *(cd->mcodeptr++) = 0x0f;
761 *(cd->mcodeptr++) = 0xad;
762 i386_emit_membase((basereg),(disp),(reg));
770 void i386_jmp_imm(codegendata *cd, s4 imm)
772 *(cd->mcodeptr++) = 0xe9;
773 i386_emit_imm32((imm));
777 void i386_jmp_reg(codegendata *cd, s4 reg)
779 *(cd->mcodeptr++) = 0xff;
780 i386_emit_reg(4,(reg));
784 void i386_jcc(codegendata *cd, s4 opc, s4 imm)
786 *(cd->mcodeptr++) = 0x0f;
787 *(cd->mcodeptr++) = 0x80 + (u1) (opc);
788 i386_emit_imm32((imm));
794 * conditional set operations
796 void i386_setcc_reg(codegendata *cd, s4 opc, s4 reg)
798 *(cd->mcodeptr++) = 0x0f;
799 *(cd->mcodeptr++) = 0x90 + (u1) (opc);
800 i386_emit_reg(0,(reg));
804 void i386_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
806 *(cd->mcodeptr++) = 0x0f;
807 *(cd->mcodeptr++) = 0x90 + (u1) (opc);
808 i386_emit_membase((basereg),(disp),0);
812 void i386_xadd_reg_mem(codegendata *cd, s4 reg, s4 mem)
814 *(cd->mcodeptr++) = 0x0f;
815 *(cd->mcodeptr++) = 0xc1;
816 i386_emit_mem((reg),(mem));
820 void i386_neg_reg(codegendata *cd, s4 reg)
822 *(cd->mcodeptr++) = 0xf7;
823 i386_emit_reg(3,(reg));
827 void i386_neg_membase(codegendata *cd, s4 basereg, s4 disp)
829 *(cd->mcodeptr++) = 0xf7;
830 i386_emit_membase((basereg),(disp),3);
835 void i386_push_imm(codegendata *cd, s4 imm)
837 *(cd->mcodeptr++) = 0x68;
838 i386_emit_imm32((imm));
842 void i386_pop_reg(codegendata *cd, s4 reg)
844 *(cd->mcodeptr++) = 0x58 + (0x07 & (u1) (reg));
848 void i386_push_reg(codegendata *cd, s4 reg)
850 *(cd->mcodeptr++) = 0x50 + (0x07 & (u1) (reg));
854 void i386_nop(codegendata *cd)
856 *(cd->mcodeptr++) = 0x90;
860 void i386_lock(codegendata *cd)
862 *(cd->mcodeptr++) = 0xf0;
869 void i386_call_reg(codegendata *cd, s4 reg)
871 *(cd->mcodeptr++) = 0xff;
872 i386_emit_reg(2,(reg));
876 void i386_call_imm(codegendata *cd, s4 imm)
878 *(cd->mcodeptr++) = 0xe8;
879 i386_emit_imm32((imm));
883 void i386_call_mem(codegendata *cd, s4 mem)
885 *(cd->mcodeptr++) = 0xff;
886 i386_emit_mem(2,(mem));
892 * floating point instructions
894 void i386_fld1(codegendata *cd)
896 *(cd->mcodeptr++) = 0xd9;
897 *(cd->mcodeptr++) = 0xe8;
901 void i386_fldz(codegendata *cd)
903 *(cd->mcodeptr++) = 0xd9;
904 *(cd->mcodeptr++) = 0xee;
908 void i386_fld_reg(codegendata *cd, s4 reg)
910 *(cd->mcodeptr++) = 0xd9;
911 *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
915 void i386_flds_membase(codegendata *cd, s4 basereg, s4 disp)
917 *(cd->mcodeptr++) = 0xd9;
918 i386_emit_membase((basereg),(disp),0);
922 void i386_fldl_membase(codegendata *cd, s4 basereg, s4 disp)
924 *(cd->mcodeptr++) = 0xdd;
925 i386_emit_membase((basereg),(disp),0);
929 void i386_fldt_membase(codegendata *cd, s4 basereg, s4 disp)
931 *(cd->mcodeptr++) = 0xdb;
932 i386_emit_membase((basereg),(disp),5);
936 void i386_flds_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
938 *(cd->mcodeptr++) = 0xd9;
939 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
943 void i386_fldl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
945 *(cd->mcodeptr++) = 0xdd;
946 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
950 void i386_flds_mem(codegendata *cd, s4 mem)
952 *(cd->mcodeptr++) = 0xd9;
953 i386_emit_mem(0,(mem));
957 void i386_fldl_mem(codegendata *cd, s4 mem)
959 *(cd->mcodeptr++) = 0xdd;
960 i386_emit_mem(0,(mem));
964 void i386_fildl_membase(codegendata *cd, s4 basereg, s4 disp)
966 *(cd->mcodeptr++) = 0xdb;
967 i386_emit_membase((basereg),(disp),0);
971 void i386_fildll_membase(codegendata *cd, s4 basereg, s4 disp)
973 *(cd->mcodeptr++) = 0xdf;
974 i386_emit_membase((basereg),(disp),5);
978 void i386_fst_reg(codegendata *cd, s4 reg)
980 *(cd->mcodeptr++) = 0xdd;
981 *(cd->mcodeptr++) = 0xd0 + (0x07 & (u1) (reg));
985 void i386_fsts_membase(codegendata *cd, s4 basereg, s4 disp)
987 *(cd->mcodeptr++) = 0xd9;
988 i386_emit_membase((basereg),(disp),2);
992 void i386_fstl_membase(codegendata *cd, s4 basereg, s4 disp)
994 *(cd->mcodeptr++) = 0xdd;
995 i386_emit_membase((basereg),(disp),2);
999 void i386_fsts_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1001 *(cd->mcodeptr++) = 0xd9;
1002 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
1006 void i386_fstl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1008 *(cd->mcodeptr++) = 0xdd;
1009 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
1013 void i386_fstp_reg(codegendata *cd, s4 reg)
1015 *(cd->mcodeptr++) = 0xdd;
1016 *(cd->mcodeptr++) = 0xd8 + (0x07 & (u1) (reg));
1020 void i386_fstps_membase(codegendata *cd, s4 basereg, s4 disp)
1022 *(cd->mcodeptr++) = 0xd9;
1023 i386_emit_membase((basereg),(disp),3);
1027 void i386_fstpl_membase(codegendata *cd, s4 basereg, s4 disp)
1029 *(cd->mcodeptr++) = 0xdd;
1030 i386_emit_membase((basereg),(disp),3);
1034 void i386_fstpt_membase(codegendata *cd, s4 basereg, s4 disp)
1036 *(cd->mcodeptr++) = 0xdb;
1037 i386_emit_membase((basereg),(disp),7);
1041 void i386_fstps_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1043 *(cd->mcodeptr++) = 0xd9;
1044 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
1048 void i386_fstpl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1050 *(cd->mcodeptr++) = 0xdd;
1051 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
1055 void i386_fstps_mem(codegendata *cd, s4 mem)
1057 *(cd->mcodeptr++) = 0xd9;
1058 i386_emit_mem(3,(mem));
1062 void i386_fstpl_mem(codegendata *cd, s4 mem)
1064 *(cd->mcodeptr++) = 0xdd;
1065 i386_emit_mem(3,(mem));
1069 void i386_fistl_membase(codegendata *cd, s4 basereg, s4 disp)
1071 *(cd->mcodeptr++) = 0xdb;
1072 i386_emit_membase((basereg),(disp),2);
1076 void i386_fistpl_membase(codegendata *cd, s4 basereg, s4 disp)
1078 *(cd->mcodeptr++) = 0xdb;
1079 i386_emit_membase((basereg),(disp),3);
1083 void i386_fistpll_membase(codegendata *cd, s4 basereg, s4 disp)
1085 *(cd->mcodeptr++) = 0xdf;
1086 i386_emit_membase((basereg),(disp),7);
1090 void i386_fchs(codegendata *cd)
1092 *(cd->mcodeptr++) = 0xd9;
1093 *(cd->mcodeptr++) = 0xe0;
1097 void i386_faddp(codegendata *cd)
1099 *(cd->mcodeptr++) = 0xde;
1100 *(cd->mcodeptr++) = 0xc1;
1104 void i386_fadd_reg_st(codegendata *cd, s4 reg)
1106 *(cd->mcodeptr++) = 0xd8;
1107 *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1111 void i386_fadd_st_reg(codegendata *cd, s4 reg)
1113 *(cd->mcodeptr++) = 0xdc;
1114 *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1118 void i386_faddp_st_reg(codegendata *cd, s4 reg)
1120 *(cd->mcodeptr++) = 0xde;
1121 *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1125 void i386_fadds_membase(codegendata *cd, s4 basereg, s4 disp)
1127 *(cd->mcodeptr++) = 0xd8;
1128 i386_emit_membase((basereg),(disp),0);
1132 void i386_faddl_membase(codegendata *cd, s4 basereg, s4 disp)
1134 *(cd->mcodeptr++) = 0xdc;
1135 i386_emit_membase((basereg),(disp),0);
1139 void i386_fsub_reg_st(codegendata *cd, s4 reg)
1141 *(cd->mcodeptr++) = 0xd8;
1142 *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1146 void i386_fsub_st_reg(codegendata *cd, s4 reg)
1148 *(cd->mcodeptr++) = 0xdc;
1149 *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1153 void i386_fsubp_st_reg(codegendata *cd, s4 reg)
1155 *(cd->mcodeptr++) = 0xde;
1156 *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1160 void i386_fsubp(codegendata *cd)
1162 *(cd->mcodeptr++) = 0xde;
1163 *(cd->mcodeptr++) = 0xe9;
1167 void i386_fsubs_membase(codegendata *cd, s4 basereg, s4 disp)
1169 *(cd->mcodeptr++) = 0xd8;
1170 i386_emit_membase((basereg),(disp),4);
1174 void i386_fsubl_membase(codegendata *cd, s4 basereg, s4 disp)
1176 *(cd->mcodeptr++) = 0xdc;
1177 i386_emit_membase((basereg),(disp),4);
1181 void i386_fmul_reg_st(codegendata *cd, s4 reg)
1183 *(cd->mcodeptr++) = 0xd8;
1184 *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1188 void i386_fmul_st_reg(codegendata *cd, s4 reg)
1190 *(cd->mcodeptr++) = 0xdc;
1191 *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1195 void i386_fmulp(codegendata *cd)
1197 *(cd->mcodeptr++) = 0xde;
1198 *(cd->mcodeptr++) = 0xc9;
1202 void i386_fmulp_st_reg(codegendata *cd, s4 reg)
1204 *(cd->mcodeptr++) = 0xde;
1205 *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1209 void i386_fmuls_membase(codegendata *cd, s4 basereg, s4 disp)
1211 *(cd->mcodeptr++) = 0xd8;
1212 i386_emit_membase((basereg),(disp),1);
1216 void i386_fmull_membase(codegendata *cd, s4 basereg, s4 disp)
1218 *(cd->mcodeptr++) = 0xdc;
1219 i386_emit_membase((basereg),(disp),1);
1223 void i386_fdiv_reg_st(codegendata *cd, s4 reg)
1225 *(cd->mcodeptr++) = 0xd8;
1226 *(cd->mcodeptr++) = 0xf0 + (0x07 & (u1) (reg));
1230 void i386_fdiv_st_reg(codegendata *cd, s4 reg)
1232 *(cd->mcodeptr++) = 0xdc;
1233 *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1237 void i386_fdivp(codegendata *cd)
1239 *(cd->mcodeptr++) = 0xde;
1240 *(cd->mcodeptr++) = 0xf9;
1244 void i386_fdivp_st_reg(codegendata *cd, s4 reg)
1246 *(cd->mcodeptr++) = 0xde;
1247 *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1251 void i386_fxch(codegendata *cd)
1253 *(cd->mcodeptr++) = 0xd9;
1254 *(cd->mcodeptr++) = 0xc9;
1258 void i386_fxch_reg(codegendata *cd, s4 reg)
1260 *(cd->mcodeptr++) = 0xd9;
1261 *(cd->mcodeptr++) = 0xc8 + (0x07 & (reg));
1265 void i386_fprem(codegendata *cd)
1267 *(cd->mcodeptr++) = 0xd9;
1268 *(cd->mcodeptr++) = 0xf8;
1272 void i386_fprem1(codegendata *cd)
1274 *(cd->mcodeptr++) = 0xd9;
1275 *(cd->mcodeptr++) = 0xf5;
1279 void i386_fucom(codegendata *cd)
1281 *(cd->mcodeptr++) = 0xdd;
1282 *(cd->mcodeptr++) = 0xe1;
1286 void i386_fucom_reg(codegendata *cd, s4 reg)
1288 *(cd->mcodeptr++) = 0xdd;
1289 *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1293 void i386_fucomp_reg(codegendata *cd, s4 reg)
1295 *(cd->mcodeptr++) = 0xdd;
1296 *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1300 void i386_fucompp(codegendata *cd)
1302 *(cd->mcodeptr++) = 0xda;
1303 *(cd->mcodeptr++) = 0xe9;
1307 void i386_fnstsw(codegendata *cd)
1309 *(cd->mcodeptr++) = 0xdf;
1310 *(cd->mcodeptr++) = 0xe0;
1314 void i386_sahf(codegendata *cd)
1316 *(cd->mcodeptr++) = 0x9e;
1320 void i386_finit(codegendata *cd)
1322 *(cd->mcodeptr++) = 0x9b;
1323 *(cd->mcodeptr++) = 0xdb;
1324 *(cd->mcodeptr++) = 0xe3;
1328 void i386_fldcw_mem(codegendata *cd, s4 mem)
1330 *(cd->mcodeptr++) = 0xd9;
1331 i386_emit_mem(5,(mem));
1335 void i386_fldcw_membase(codegendata *cd, s4 basereg, s4 disp)
1337 *(cd->mcodeptr++) = 0xd9;
1338 i386_emit_membase((basereg),(disp),5);
1342 void i386_wait(codegendata *cd)
1344 *(cd->mcodeptr++) = 0x9b;
1348 void i386_ffree_reg(codegendata *cd, s4 reg)
1350 *(cd->mcodeptr++) = 0xdd;
1351 *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
1355 void i386_fdecstp(codegendata *cd)
1357 *(cd->mcodeptr++) = 0xd9;
1358 *(cd->mcodeptr++) = 0xf6;
1362 void i386_fincstp(codegendata *cd)
1364 *(cd->mcodeptr++) = 0xd9;
1365 *(cd->mcodeptr++) = 0xf7;
1370 * These are local overrides for various environment variables in Emacs.
1371 * Please do not remove this and leave it at the end of the file, where
1372 * Emacs will automagically detect them.
1373 * ---------------------------------------------------------------------
1376 * indent-tabs-mode: t