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 2356 2005-04-22 17:33:35Z christian $
33 #include "vm/statistics.h"
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 #define COUNT(a) (a)++
46 void i386_emit_ialu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
48 if (iptr->dst->flags & INMEMORY) {
49 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
50 if (src->regoff == iptr->dst->regoff) {
51 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
52 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
54 } else if (src->prev->regoff == iptr->dst->regoff) {
55 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
56 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
59 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
60 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4, REG_ITMP1);
61 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
64 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
65 if (src->regoff == iptr->dst->regoff) {
66 i386_alu_reg_membase(cd, alu_op, src->prev->regoff, REG_SP, iptr->dst->regoff * 4);
69 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
70 i386_alu_reg_reg(cd, alu_op, src->prev->regoff, REG_ITMP1);
71 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
74 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
75 if (src->prev->regoff == iptr->dst->regoff) {
76 i386_alu_reg_membase(cd, alu_op, src->regoff, REG_SP, iptr->dst->regoff * 4);
79 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
80 i386_alu_reg_reg(cd, alu_op, src->regoff, REG_ITMP1);
81 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
85 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 4);
86 i386_alu_reg_membase(cd, alu_op, src->regoff, REG_SP, iptr->dst->regoff * 4);
90 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
91 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, iptr->dst->regoff);
92 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4, iptr->dst->regoff);
94 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
95 if (src->prev->regoff != iptr->dst->regoff)
96 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
98 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4, iptr->dst->regoff);
100 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
101 if (src->regoff != iptr->dst->regoff)
102 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
104 i386_alu_membase_reg(cd, alu_op, REG_SP, src->prev->regoff * 4, iptr->dst->regoff);
107 if (src->regoff == iptr->dst->regoff) {
108 i386_alu_reg_reg(cd, alu_op, src->prev->regoff, iptr->dst->regoff);
111 if (src->prev->regoff != iptr->dst->regoff)
112 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
114 i386_alu_reg_reg(cd, alu_op, src->regoff, iptr->dst->regoff);
121 void i386_emit_ialuconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
123 if (iptr->dst->flags & INMEMORY) {
124 if (src->flags & INMEMORY) {
125 if (src->regoff == iptr->dst->regoff) {
126 i386_alu_imm_membase(cd, alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
129 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
130 i386_alu_imm_reg(cd, alu_op, iptr->val.i, REG_ITMP1);
131 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
135 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 4);
136 i386_alu_imm_membase(cd, alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
140 if (src->flags & INMEMORY) {
141 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, iptr->dst->regoff);
142 i386_alu_imm_reg(cd, alu_op, iptr->val.i, iptr->dst->regoff);
145 if (src->regoff != iptr->dst->regoff)
146 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
148 /* `inc reg' is slower on p4's (regarding to ia32 optimization */
149 /* reference manual and benchmarks) and as fast on athlon's. */
150 i386_alu_imm_reg(cd, alu_op, iptr->val.i, iptr->dst->regoff);
156 void i386_emit_lalu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
158 if (iptr->dst->flags & INMEMORY) {
159 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
160 if (src->regoff == iptr->dst->regoff) {
161 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
162 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
163 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4 + 4, REG_ITMP1);
164 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4 + 4);
166 } else if (src->prev->regoff == iptr->dst->regoff) {
167 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
168 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
169 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP1);
170 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4 + 4);
173 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
174 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4, REG_ITMP1);
175 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
176 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4 + 4, REG_ITMP1);
177 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4 + 4, REG_ITMP1);
178 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4 + 4);
185 void i386_emit_laluconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
187 if (iptr->dst->flags & INMEMORY) {
188 if (src->flags & INMEMORY) {
189 if (src->regoff == iptr->dst->regoff) {
190 i386_alu_imm_membase(cd, alu_op, iptr->val.l, REG_SP, iptr->dst->regoff * 4);
191 i386_alu_imm_membase(cd, alu_op, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 4 + 4);
194 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
195 i386_alu_imm_reg(cd, alu_op, iptr->val.l, REG_ITMP1);
196 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
197 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP1);
198 i386_alu_imm_reg(cd, alu_op, iptr->val.l >> 32, REG_ITMP1);
199 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4 + 4);
206 void i386_emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
208 if (iptr->dst->flags & INMEMORY) {
209 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
210 if (src->prev->regoff == iptr->dst->regoff) {
211 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
212 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 4);
215 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
216 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
217 i386_shift_reg(cd, shift_op, REG_ITMP1);
218 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
221 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
222 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
223 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 4);
224 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 4);
226 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
227 if (src->prev->regoff == iptr->dst->regoff) {
228 if (src->regoff != ECX)
229 i386_mov_reg_reg(cd, src->regoff, ECX);
231 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 4);
234 if (src->regoff != ECX)
235 i386_mov_reg_reg(cd, src->regoff, ECX);
237 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
238 i386_shift_reg(cd, shift_op, REG_ITMP1);
239 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
243 if (src->regoff != ECX)
244 i386_mov_reg_reg(cd, src->regoff, ECX);
246 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 4);
247 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 4);
251 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
252 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
253 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, iptr->dst->regoff);
254 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
256 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
257 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
259 if (src->prev->regoff != iptr->dst->regoff)
260 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
262 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
264 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
265 if (src->regoff != ECX)
266 i386_mov_reg_reg(cd, src->regoff, ECX);
268 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, iptr->dst->regoff);
269 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
272 if (src->regoff != ECX)
273 i386_mov_reg_reg(cd, src->regoff, ECX);
275 if (src->prev->regoff != iptr->dst->regoff)
276 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
278 i386_shift_reg(cd, shift_op, iptr->dst->regoff);
284 void i386_emit_ishiftconst(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
286 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
287 if (src->regoff == iptr->dst->regoff) {
288 i386_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
291 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
292 i386_shift_imm_reg(cd, shift_op, iptr->val.i, REG_ITMP1);
293 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
296 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
297 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, iptr->dst->regoff);
298 i386_shift_imm_reg(cd, shift_op, iptr->val.i, iptr->dst->regoff);
300 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
301 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 4);
302 i386_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
305 if (src->regoff != iptr->dst->regoff)
306 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
308 i386_shift_imm_reg(cd, shift_op, iptr->val.i, iptr->dst->regoff);
313 void i386_emit_ifcc_iconst(codegendata *cd, s4 if_op, stackptr src, instruction *iptr)
315 if (iptr->dst->flags & INMEMORY) {
318 if (src->flags & INMEMORY) {
319 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 4);
322 i386_test_reg_reg(cd, src->regoff, src->regoff);
326 CALCOFFSETBYTES(offset, REG_SP, iptr->dst->regoff * 4);
328 i386_jcc(cd, if_op, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
329 i386_mov_imm_membase(cd, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
331 if (iptr[1].opc == ICMD_ELSE_ICONST) {
332 i386_jmp_imm(cd, offset);
333 i386_mov_imm_membase(cd, iptr[1].val.i, REG_SP, iptr->dst->regoff * 4);
337 if (src->flags & INMEMORY) {
338 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 4);
341 i386_test_reg_reg(cd, src->regoff, src->regoff);
344 i386_jcc(cd, if_op, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
345 i386_mov_imm_reg(cd, iptr->val.i, iptr->dst->regoff);
347 if (iptr[1].opc == ICMD_ELSE_ICONST) {
349 i386_mov_imm_reg(cd, iptr[1].val.i, iptr->dst->regoff);
359 void i386_mov_reg_reg(codegendata *cd, s4 reg, s4 dreg)
361 COUNT(count_mov_reg_reg);
362 *(cd->mcodeptr++) = 0x89;
363 i386_emit_reg((reg),(dreg));
367 void i386_mov_imm_reg(codegendata *cd, s4 imm, s4 reg)
369 *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
370 i386_emit_imm32((imm));
374 void i386_movb_imm_reg(codegendata *cd, s4 imm, s4 reg)
376 *(cd->mcodeptr++) = 0xc6;
377 i386_emit_reg(0,(reg));
378 i386_emit_imm8((imm));
382 void i386_mov_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
384 COUNT(count_mov_mem_reg);
385 *(cd->mcodeptr++) = 0x8b;
386 i386_emit_membase((basereg),(disp),(reg));
391 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
392 * constant membase immediate length of 32bit
394 void i386_mov_membase32_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
396 COUNT(count_mov_mem_reg);
397 *(cd->mcodeptr++) = 0x8b;
398 i386_emit_membase32((basereg),(disp),(reg));
402 void i386_mov_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
404 COUNT(count_mov_reg_mem);
405 *(cd->mcodeptr++) = 0x89;
406 i386_emit_membase((basereg),(disp),(reg));
410 void i386_mov_reg_membase32(codegendata *cd, s4 reg, s4 basereg, s4 disp)
412 COUNT(count_mov_reg_mem);
413 *(cd->mcodeptr++) = 0x89;
414 i386_emit_membase32((basereg),(disp),(reg));
418 void i386_mov_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
420 COUNT(count_mov_mem_reg);
421 *(cd->mcodeptr++) = 0x8b;
422 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
426 void i386_mov_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
428 COUNT(count_mov_reg_mem);
429 *(cd->mcodeptr++) = 0x89;
430 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
434 void i386_movw_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
436 COUNT(count_mov_reg_mem);
437 *(cd->mcodeptr++) = 0x66;
438 *(cd->mcodeptr++) = 0x89;
439 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
443 void i386_movb_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
445 COUNT(count_mov_reg_mem);
446 *(cd->mcodeptr++) = 0x88;
447 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
451 void i386_mov_reg_mem(codegendata *cd, s4 reg, s4 mem)
453 COUNT(count_mov_reg_mem);
454 *(cd->mcodeptr++) = 0x89;
455 i386_emit_mem((reg),(mem));
459 void i386_mov_mem_reg(codegendata *cd, s4 mem, s4 dreg)
461 COUNT(count_mov_mem_reg);
462 *(cd->mcodeptr++) = 0x8b;
463 i386_emit_mem((dreg),(mem));
467 void i386_mov_imm_mem(codegendata *cd, s4 imm, s4 mem)
469 *(cd->mcodeptr++) = 0xc7;
470 i386_emit_mem(0, mem);
471 i386_emit_imm32(imm);
475 void i386_mov_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
477 *(cd->mcodeptr++) = 0xc7;
478 i386_emit_membase((basereg),(disp),0);
479 i386_emit_imm32((imm));
483 void i386_mov_imm_membase32(codegendata *cd, s4 imm, s4 basereg, s4 disp)
485 *(cd->mcodeptr++) = 0xc7;
486 i386_emit_membase32((basereg),(disp),0);
487 i386_emit_imm32((imm));
491 void i386_movb_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
493 *(cd->mcodeptr++) = 0xc6;
494 i386_emit_membase((basereg),(disp),0);
495 i386_emit_imm8((imm));
499 void i386_movsbl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
501 COUNT(count_mov_mem_reg);
502 *(cd->mcodeptr++) = 0x0f;
503 *(cd->mcodeptr++) = 0xbe;
504 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
508 void i386_movswl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
510 COUNT(count_mov_mem_reg);
511 *(cd->mcodeptr++) = 0x0f;
512 *(cd->mcodeptr++) = 0xbf;
513 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
517 void i386_movzwl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
519 COUNT(count_mov_mem_reg);
520 *(cd->mcodeptr++) = 0x0f;
521 *(cd->mcodeptr++) = 0xb7;
522 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
526 void i386_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
528 *(cd->mcodeptr++) = 0xc7;
529 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
530 i386_emit_imm32((imm));
534 void i386_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
536 *(cd->mcodeptr++) = 0x66;
537 *(cd->mcodeptr++) = 0xc7;
538 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
539 i386_emit_imm16((imm));
543 void i386_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
545 *(cd->mcodeptr++) = 0xc6;
546 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
547 i386_emit_imm8((imm));
554 void i386_alu_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
556 *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
557 i386_emit_reg((reg),(dreg));
561 void i386_alu_reg_membase(codegendata *cd, s4 opc, s4 reg, s4 basereg, s4 disp)
563 *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
564 i386_emit_membase((basereg),(disp),(reg));
568 void i386_alu_membase_reg(codegendata *cd, s4 opc, s4 basereg, s4 disp, s4 reg)
570 *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 3;
571 i386_emit_membase((basereg),(disp),(reg));
575 void i386_alu_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
577 if (i386_is_imm8(imm)) {
578 *(cd->mcodeptr++) = 0x83;
579 i386_emit_reg((opc),(dreg));
580 i386_emit_imm8((imm));
582 *(cd->mcodeptr++) = 0x81;
583 i386_emit_reg((opc),(dreg));
584 i386_emit_imm32((imm));
589 void i386_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
591 *(cd->mcodeptr++) = 0x81;
592 i386_emit_reg((opc),(dreg));
593 i386_emit_imm32((imm));
597 void i386_alu_imm_membase(codegendata *cd, s4 opc, s4 imm, s4 basereg, s4 disp)
599 if (i386_is_imm8(imm)) {
600 *(cd->mcodeptr++) = 0x83;
601 i386_emit_membase((basereg),(disp),(opc));
602 i386_emit_imm8((imm));
604 *(cd->mcodeptr++) = 0x81;
605 i386_emit_membase((basereg),(disp),(opc));
606 i386_emit_imm32((imm));
611 void i386_test_reg_reg(codegendata *cd, s4 reg, s4 dreg)
613 *(cd->mcodeptr++) = 0x85;
614 i386_emit_reg((reg),(dreg));
618 void i386_test_imm_reg(codegendata *cd, s4 imm, s4 reg)
620 *(cd->mcodeptr++) = 0xf7;
621 i386_emit_reg(0,(reg));
622 i386_emit_imm32((imm));
628 * inc, dec operations
630 void i386_dec_mem(codegendata *cd, s4 mem)
632 *(cd->mcodeptr++) = 0xff;
633 i386_emit_mem(1,(mem));
637 void i386_cltd(codegendata *cd)
639 *(cd->mcodeptr++) = 0x99;
643 void i386_imul_reg_reg(codegendata *cd, s4 reg, s4 dreg)
645 *(cd->mcodeptr++) = 0x0f;
646 *(cd->mcodeptr++) = 0xaf;
647 i386_emit_reg((dreg),(reg));
651 void i386_imul_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
653 *(cd->mcodeptr++) = 0x0f;
654 *(cd->mcodeptr++) = 0xaf;
655 i386_emit_membase((basereg),(disp),(dreg));
659 void i386_imul_imm_reg(codegendata *cd, s4 imm, s4 dreg)
661 if (i386_is_imm8((imm))) {
662 *(cd->mcodeptr++) = 0x6b;
663 i386_emit_reg(0,(dreg));
664 i386_emit_imm8((imm));
666 *(cd->mcodeptr++) = 0x69;
667 i386_emit_reg(0,(dreg));
668 i386_emit_imm32((imm));
673 void i386_imul_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
675 if (i386_is_imm8((imm))) {
676 *(cd->mcodeptr++) = 0x6b;
677 i386_emit_reg((dreg),(reg));
678 i386_emit_imm8((imm));
680 *(cd->mcodeptr++) = 0x69;
681 i386_emit_reg((dreg),(reg));
682 i386_emit_imm32((imm));
687 void i386_imul_imm_membase_reg(codegendata *cd, s4 imm, s4 basereg, s4 disp, s4 dreg)
689 if (i386_is_imm8((imm))) {
690 *(cd->mcodeptr++) = 0x6b;
691 i386_emit_membase((basereg),(disp),(dreg));
692 i386_emit_imm8((imm));
694 *(cd->mcodeptr++) = 0x69;
695 i386_emit_membase((basereg),(disp),(dreg));
696 i386_emit_imm32((imm));
701 void i386_mul_membase(codegendata *cd, s4 basereg, s4 disp)
703 *(cd->mcodeptr++) = 0xf7;
704 i386_emit_membase((basereg),(disp),4);
708 void i386_idiv_reg(codegendata *cd, s4 reg)
710 *(cd->mcodeptr++) = 0xf7;
711 i386_emit_reg(7,(reg));
715 void i386_ret(codegendata *cd)
717 *(cd->mcodeptr++) = 0xc3;
725 void i386_shift_reg(codegendata *cd, s4 opc, s4 reg)
727 *(cd->mcodeptr++) = 0xd3;
728 i386_emit_reg((opc),(reg));
732 void i386_shift_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
734 *(cd->mcodeptr++) = 0xd3;
735 i386_emit_membase((basereg),(disp),(opc));
739 void i386_shift_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
742 *(cd->mcodeptr++) = 0xd1;
743 i386_emit_reg((opc),(dreg));
745 *(cd->mcodeptr++) = 0xc1;
746 i386_emit_reg((opc),(dreg));
747 i386_emit_imm8((imm));
752 void i386_shift_imm_membase(codegendata *cd, s4 opc, s4 imm, s4 basereg, s4 disp)
755 *(cd->mcodeptr++) = 0xd1;
756 i386_emit_membase((basereg),(disp),(opc));
758 *(cd->mcodeptr++) = 0xc1;
759 i386_emit_membase((basereg),(disp),(opc));
760 i386_emit_imm8((imm));
765 void i386_shld_reg_reg(codegendata *cd, s4 reg, s4 dreg)
767 *(cd->mcodeptr++) = 0x0f;
768 *(cd->mcodeptr++) = 0xa5;
769 i386_emit_reg((reg),(dreg));
773 void i386_shld_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
775 *(cd->mcodeptr++) = 0x0f;
776 *(cd->mcodeptr++) = 0xa4;
777 i386_emit_reg((reg),(dreg));
778 i386_emit_imm8((imm));
782 void i386_shld_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
784 *(cd->mcodeptr++) = 0x0f;
785 *(cd->mcodeptr++) = 0xa5;
786 i386_emit_membase((basereg),(disp),(reg));
790 void i386_shrd_reg_reg(codegendata *cd, s4 reg, s4 dreg)
792 *(cd->mcodeptr++) = 0x0f;
793 *(cd->mcodeptr++) = 0xad;
794 i386_emit_reg((reg),(dreg));
798 void i386_shrd_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
800 *(cd->mcodeptr++) = 0x0f;
801 *(cd->mcodeptr++) = 0xac;
802 i386_emit_reg((reg),(dreg));
803 i386_emit_imm8((imm));
807 void i386_shrd_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
809 *(cd->mcodeptr++) = 0x0f;
810 *(cd->mcodeptr++) = 0xad;
811 i386_emit_membase((basereg),(disp),(reg));
819 void i386_jmp_imm(codegendata *cd, s4 imm)
821 *(cd->mcodeptr++) = 0xe9;
822 i386_emit_imm32((imm));
826 void i386_jmp_reg(codegendata *cd, s4 reg)
828 *(cd->mcodeptr++) = 0xff;
829 i386_emit_reg(4,(reg));
833 void i386_jcc(codegendata *cd, s4 opc, s4 imm)
835 *(cd->mcodeptr++) = 0x0f;
836 *(cd->mcodeptr++) = 0x80 + (u1) (opc);
837 i386_emit_imm32((imm));
843 * conditional set operations
845 void i386_setcc_reg(codegendata *cd, s4 opc, s4 reg)
847 *(cd->mcodeptr++) = 0x0f;
848 *(cd->mcodeptr++) = 0x90 + (u1) (opc);
849 i386_emit_reg(0,(reg));
853 void i386_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
855 *(cd->mcodeptr++) = 0x0f;
856 *(cd->mcodeptr++) = 0x90 + (u1) (opc);
857 i386_emit_membase((basereg),(disp),0);
861 void i386_xadd_reg_mem(codegendata *cd, s4 reg, s4 mem)
863 *(cd->mcodeptr++) = 0x0f;
864 *(cd->mcodeptr++) = 0xc1;
865 i386_emit_mem((reg),(mem));
869 void i386_neg_reg(codegendata *cd, s4 reg)
871 *(cd->mcodeptr++) = 0xf7;
872 i386_emit_reg(3,(reg));
876 void i386_neg_membase(codegendata *cd, s4 basereg, s4 disp)
878 *(cd->mcodeptr++) = 0xf7;
879 i386_emit_membase((basereg),(disp),3);
884 void i386_push_imm(codegendata *cd, s4 imm)
886 *(cd->mcodeptr++) = 0x68;
887 i386_emit_imm32((imm));
891 void i386_pop_reg(codegendata *cd, s4 reg)
893 *(cd->mcodeptr++) = 0x58 + (0x07 & (u1) (reg));
897 void i386_push_reg(codegendata *cd, s4 reg)
899 *(cd->mcodeptr++) = 0x50 + (0x07 & (u1) (reg));
903 void i386_nop(codegendata *cd)
905 *(cd->mcodeptr++) = 0x90;
909 void i386_lock(codegendata *cd)
911 *(cd->mcodeptr++) = 0xf0;
918 void i386_call_reg(codegendata *cd, s4 reg)
920 *(cd->mcodeptr++) = 0xff;
921 i386_emit_reg(2,(reg));
925 void i386_call_imm(codegendata *cd, s4 imm)
927 *(cd->mcodeptr++) = 0xe8;
928 i386_emit_imm32((imm));
932 void i386_call_mem(codegendata *cd, s4 mem)
934 *(cd->mcodeptr++) = 0xff;
935 i386_emit_mem(2,(mem));
941 * floating point instructions
943 void i386_fld1(codegendata *cd)
945 *(cd->mcodeptr++) = 0xd9;
946 *(cd->mcodeptr++) = 0xe8;
950 void i386_fldz(codegendata *cd)
952 *(cd->mcodeptr++) = 0xd9;
953 *(cd->mcodeptr++) = 0xee;
957 void i386_fld_reg(codegendata *cd, s4 reg)
959 *(cd->mcodeptr++) = 0xd9;
960 *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
964 void i386_flds_membase(codegendata *cd, s4 basereg, s4 disp)
966 *(cd->mcodeptr++) = 0xd9;
967 i386_emit_membase((basereg),(disp),0);
971 void i386_flds_membase32(codegendata *cd, s4 basereg, s4 disp)
973 *(cd->mcodeptr++) = 0xd9;
974 i386_emit_membase32((basereg),(disp),0);
978 void i386_fldl_membase(codegendata *cd, s4 basereg, s4 disp)
980 *(cd->mcodeptr++) = 0xdd;
981 i386_emit_membase((basereg),(disp),0);
985 void i386_fldl_membase32(codegendata *cd, s4 basereg, s4 disp)
987 *(cd->mcodeptr++) = 0xdd;
988 i386_emit_membase32((basereg),(disp),0);
992 void i386_fldt_membase(codegendata *cd, s4 basereg, s4 disp)
994 *(cd->mcodeptr++) = 0xdb;
995 i386_emit_membase((basereg),(disp),5);
999 void i386_flds_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1001 *(cd->mcodeptr++) = 0xd9;
1002 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1006 void i386_fldl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1008 *(cd->mcodeptr++) = 0xdd;
1009 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1013 void i386_flds_mem(codegendata *cd, s4 mem)
1015 *(cd->mcodeptr++) = 0xd9;
1016 i386_emit_mem(0,(mem));
1020 void i386_fldl_mem(codegendata *cd, s4 mem)
1022 *(cd->mcodeptr++) = 0xdd;
1023 i386_emit_mem(0,(mem));
1027 void i386_fildl_membase(codegendata *cd, s4 basereg, s4 disp)
1029 *(cd->mcodeptr++) = 0xdb;
1030 i386_emit_membase((basereg),(disp),0);
1034 void i386_fildll_membase(codegendata *cd, s4 basereg, s4 disp)
1036 *(cd->mcodeptr++) = 0xdf;
1037 i386_emit_membase((basereg),(disp),5);
1041 void i386_fst_reg(codegendata *cd, s4 reg)
1043 *(cd->mcodeptr++) = 0xdd;
1044 *(cd->mcodeptr++) = 0xd0 + (0x07 & (u1) (reg));
1048 void i386_fsts_membase(codegendata *cd, s4 basereg, s4 disp)
1050 *(cd->mcodeptr++) = 0xd9;
1051 i386_emit_membase((basereg),(disp),2);
1055 void i386_fstl_membase(codegendata *cd, s4 basereg, s4 disp)
1057 *(cd->mcodeptr++) = 0xdd;
1058 i386_emit_membase((basereg),(disp),2);
1062 void i386_fsts_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1064 *(cd->mcodeptr++) = 0xd9;
1065 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
1069 void i386_fstl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1071 *(cd->mcodeptr++) = 0xdd;
1072 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
1076 void i386_fstp_reg(codegendata *cd, s4 reg)
1078 *(cd->mcodeptr++) = 0xdd;
1079 *(cd->mcodeptr++) = 0xd8 + (0x07 & (u1) (reg));
1083 void i386_fstps_membase(codegendata *cd, s4 basereg, s4 disp)
1085 *(cd->mcodeptr++) = 0xd9;
1086 i386_emit_membase((basereg),(disp),3);
1090 void i386_fstps_membase32(codegendata *cd, s4 basereg, s4 disp)
1092 *(cd->mcodeptr++) = 0xd9;
1093 i386_emit_membase32((basereg),(disp),3);
1097 void i386_fstpl_membase(codegendata *cd, s4 basereg, s4 disp)
1099 *(cd->mcodeptr++) = 0xdd;
1100 i386_emit_membase((basereg),(disp),3);
1104 void i386_fstpl_membase32(codegendata *cd, s4 basereg, s4 disp)
1106 *(cd->mcodeptr++) = 0xdd;
1107 i386_emit_membase32((basereg),(disp),3);
1111 void i386_fstpt_membase(codegendata *cd, s4 basereg, s4 disp)
1113 *(cd->mcodeptr++) = 0xdb;
1114 i386_emit_membase((basereg),(disp),7);
1118 void i386_fstps_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1120 *(cd->mcodeptr++) = 0xd9;
1121 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
1125 void i386_fstpl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1127 *(cd->mcodeptr++) = 0xdd;
1128 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
1132 void i386_fstps_mem(codegendata *cd, s4 mem)
1134 *(cd->mcodeptr++) = 0xd9;
1135 i386_emit_mem(3,(mem));
1139 void i386_fstpl_mem(codegendata *cd, s4 mem)
1141 *(cd->mcodeptr++) = 0xdd;
1142 i386_emit_mem(3,(mem));
1146 void i386_fistl_membase(codegendata *cd, s4 basereg, s4 disp)
1148 *(cd->mcodeptr++) = 0xdb;
1149 i386_emit_membase((basereg),(disp),2);
1153 void i386_fistpl_membase(codegendata *cd, s4 basereg, s4 disp)
1155 *(cd->mcodeptr++) = 0xdb;
1156 i386_emit_membase((basereg),(disp),3);
1160 void i386_fistpll_membase(codegendata *cd, s4 basereg, s4 disp)
1162 *(cd->mcodeptr++) = 0xdf;
1163 i386_emit_membase((basereg),(disp),7);
1167 void i386_fchs(codegendata *cd)
1169 *(cd->mcodeptr++) = 0xd9;
1170 *(cd->mcodeptr++) = 0xe0;
1174 void i386_faddp(codegendata *cd)
1176 *(cd->mcodeptr++) = 0xde;
1177 *(cd->mcodeptr++) = 0xc1;
1181 void i386_fadd_reg_st(codegendata *cd, s4 reg)
1183 *(cd->mcodeptr++) = 0xd8;
1184 *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1188 void i386_fadd_st_reg(codegendata *cd, s4 reg)
1190 *(cd->mcodeptr++) = 0xdc;
1191 *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1195 void i386_faddp_st_reg(codegendata *cd, s4 reg)
1197 *(cd->mcodeptr++) = 0xde;
1198 *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1202 void i386_fadds_membase(codegendata *cd, s4 basereg, s4 disp)
1204 *(cd->mcodeptr++) = 0xd8;
1205 i386_emit_membase((basereg),(disp),0);
1209 void i386_faddl_membase(codegendata *cd, s4 basereg, s4 disp)
1211 *(cd->mcodeptr++) = 0xdc;
1212 i386_emit_membase((basereg),(disp),0);
1216 void i386_fsub_reg_st(codegendata *cd, s4 reg)
1218 *(cd->mcodeptr++) = 0xd8;
1219 *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1223 void i386_fsub_st_reg(codegendata *cd, s4 reg)
1225 *(cd->mcodeptr++) = 0xdc;
1226 *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1230 void i386_fsubp_st_reg(codegendata *cd, s4 reg)
1232 *(cd->mcodeptr++) = 0xde;
1233 *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1237 void i386_fsubp(codegendata *cd)
1239 *(cd->mcodeptr++) = 0xde;
1240 *(cd->mcodeptr++) = 0xe9;
1244 void i386_fsubs_membase(codegendata *cd, s4 basereg, s4 disp)
1246 *(cd->mcodeptr++) = 0xd8;
1247 i386_emit_membase((basereg),(disp),4);
1251 void i386_fsubl_membase(codegendata *cd, s4 basereg, s4 disp)
1253 *(cd->mcodeptr++) = 0xdc;
1254 i386_emit_membase((basereg),(disp),4);
1258 void i386_fmul_reg_st(codegendata *cd, s4 reg)
1260 *(cd->mcodeptr++) = 0xd8;
1261 *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1265 void i386_fmul_st_reg(codegendata *cd, s4 reg)
1267 *(cd->mcodeptr++) = 0xdc;
1268 *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1272 void i386_fmulp(codegendata *cd)
1274 *(cd->mcodeptr++) = 0xde;
1275 *(cd->mcodeptr++) = 0xc9;
1279 void i386_fmulp_st_reg(codegendata *cd, s4 reg)
1281 *(cd->mcodeptr++) = 0xde;
1282 *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1286 void i386_fmuls_membase(codegendata *cd, s4 basereg, s4 disp)
1288 *(cd->mcodeptr++) = 0xd8;
1289 i386_emit_membase((basereg),(disp),1);
1293 void i386_fmull_membase(codegendata *cd, s4 basereg, s4 disp)
1295 *(cd->mcodeptr++) = 0xdc;
1296 i386_emit_membase((basereg),(disp),1);
1300 void i386_fdiv_reg_st(codegendata *cd, s4 reg)
1302 *(cd->mcodeptr++) = 0xd8;
1303 *(cd->mcodeptr++) = 0xf0 + (0x07 & (u1) (reg));
1307 void i386_fdiv_st_reg(codegendata *cd, s4 reg)
1309 *(cd->mcodeptr++) = 0xdc;
1310 *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1314 void i386_fdivp(codegendata *cd)
1316 *(cd->mcodeptr++) = 0xde;
1317 *(cd->mcodeptr++) = 0xf9;
1321 void i386_fdivp_st_reg(codegendata *cd, s4 reg)
1323 *(cd->mcodeptr++) = 0xde;
1324 *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1328 void i386_fxch(codegendata *cd)
1330 *(cd->mcodeptr++) = 0xd9;
1331 *(cd->mcodeptr++) = 0xc9;
1335 void i386_fxch_reg(codegendata *cd, s4 reg)
1337 *(cd->mcodeptr++) = 0xd9;
1338 *(cd->mcodeptr++) = 0xc8 + (0x07 & (reg));
1342 void i386_fprem(codegendata *cd)
1344 *(cd->mcodeptr++) = 0xd9;
1345 *(cd->mcodeptr++) = 0xf8;
1349 void i386_fprem1(codegendata *cd)
1351 *(cd->mcodeptr++) = 0xd9;
1352 *(cd->mcodeptr++) = 0xf5;
1356 void i386_fucom(codegendata *cd)
1358 *(cd->mcodeptr++) = 0xdd;
1359 *(cd->mcodeptr++) = 0xe1;
1363 void i386_fucom_reg(codegendata *cd, s4 reg)
1365 *(cd->mcodeptr++) = 0xdd;
1366 *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1370 void i386_fucomp_reg(codegendata *cd, s4 reg)
1372 *(cd->mcodeptr++) = 0xdd;
1373 *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1377 void i386_fucompp(codegendata *cd)
1379 *(cd->mcodeptr++) = 0xda;
1380 *(cd->mcodeptr++) = 0xe9;
1384 void i386_fnstsw(codegendata *cd)
1386 *(cd->mcodeptr++) = 0xdf;
1387 *(cd->mcodeptr++) = 0xe0;
1391 void i386_sahf(codegendata *cd)
1393 *(cd->mcodeptr++) = 0x9e;
1397 void i386_finit(codegendata *cd)
1399 *(cd->mcodeptr++) = 0x9b;
1400 *(cd->mcodeptr++) = 0xdb;
1401 *(cd->mcodeptr++) = 0xe3;
1405 void i386_fldcw_mem(codegendata *cd, s4 mem)
1407 *(cd->mcodeptr++) = 0xd9;
1408 i386_emit_mem(5,(mem));
1412 void i386_fldcw_membase(codegendata *cd, s4 basereg, s4 disp)
1414 *(cd->mcodeptr++) = 0xd9;
1415 i386_emit_membase((basereg),(disp),5);
1419 void i386_wait(codegendata *cd)
1421 *(cd->mcodeptr++) = 0x9b;
1425 void i386_ffree_reg(codegendata *cd, s4 reg)
1427 *(cd->mcodeptr++) = 0xdd;
1428 *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
1432 void i386_fdecstp(codegendata *cd)
1434 *(cd->mcodeptr++) = 0xd9;
1435 *(cd->mcodeptr++) = 0xf6;
1439 void i386_fincstp(codegendata *cd)
1441 *(cd->mcodeptr++) = 0xd9;
1442 *(cd->mcodeptr++) = 0xf7;
1447 * These are local overrides for various environment variables in Emacs.
1448 * Please do not remove this and leave it at the end of the file, where
1449 * Emacs will automagically detect them.
1450 * ---------------------------------------------------------------------
1453 * indent-tabs-mode: t