1 /* src/vm/jit/x86_64/emit.c - x86_64 code emitter functions
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Christian Thalinger
31 $Id: emit.c 4853 2006-04-27 12:33:20Z twisti $
40 #include "vm/jit/codegen-common.h"
41 #include "vm/jit/emit.h"
42 #include "vm/jit/jit.h"
43 #include "vm/jit/x86_64/codegen.h"
44 #include "vm/jit/x86_64/md-emit.h"
47 /* code generation functions **************************************************/
49 /* emit_load_s1 ****************************************************************
51 Emits a possible load of the first source operand.
53 *******************************************************************************/
55 s4 emit_load_s1(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
61 /* get required compiler data */
65 if (src->flags & INMEMORY) {
68 disp = src->regoff * 8;
70 if (IS_FLT_DBL_TYPE(src->type)) {
71 M_DLD(tempreg, REG_SP, disp);
74 if (IS_INT_TYPE(src->type))
75 M_ILD(tempreg, REG_SP, disp);
77 M_LLD(tempreg, REG_SP, disp);
88 /* emit_load_s2 ****************************************************************
90 Emits a possible load of the second source operand.
92 *******************************************************************************/
94 s4 emit_load_s2(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
100 /* get required compiler data */
104 if (src->flags & INMEMORY) {
107 disp = src->regoff * 8;
109 if (IS_FLT_DBL_TYPE(src->type)) {
110 M_DLD(tempreg, REG_SP, disp);
113 if (IS_INT_TYPE(src->type))
114 M_ILD(tempreg, REG_SP, disp);
116 M_LLD(tempreg, REG_SP, disp);
127 /* emit_load_s3 ****************************************************************
129 Emits a possible load of the third source operand.
131 *******************************************************************************/
133 s4 emit_load_s3(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
139 /* get required compiler data */
143 if (src->flags & INMEMORY) {
146 disp = src->regoff * 8;
148 if (IS_FLT_DBL_TYPE(src->type)) {
149 M_DLD(tempreg, REG_SP, disp);
152 if (IS_INT_TYPE(src->type))
153 M_ILD(tempreg, REG_SP, disp);
155 M_LLD(tempreg, REG_SP, disp);
166 /* emit_store ******************************************************************
168 This function generates the code to store the result of an
169 operation back into a spilled pseudo-variable. If the
170 pseudo-variable has not been spilled in the first place, this
171 function will generate nothing.
173 *******************************************************************************/
175 void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
183 /* get required compiler data */
188 /* do we have to generate a conditional move? */
190 if ((iptr != NULL) && (iptr->opc & ICMD_CONDITION_MASK)) {
191 /* the passed register d is actually the source register */
195 /* Only pass the opcode to codegen_reg_of_var to get the real
196 destination register. */
198 opcode = iptr->opc & ICMD_OPCODE_MASK;
200 /* get the real destination register */
202 d = codegen_reg_of_var(rd, opcode, dst, REG_ITMP1);
204 /* and emit the conditional move */
206 emit_cmovxx(cd, iptr, s, d);
209 if (dst->flags & INMEMORY) {
212 disp = dst->regoff * 8;
214 if (IS_FLT_DBL_TYPE(dst->type))
215 M_DST(d, REG_SP, disp);
217 M_LST(d, REG_SP, disp);
222 /* emit_copy *******************************************************************
226 *******************************************************************************/
228 void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst)
234 /* get required compiler data */
239 if ((src->regoff != dst->regoff) ||
240 ((src->flags ^ dst->flags) & INMEMORY)) {
241 d = codegen_reg_of_var(rd, iptr->opc, dst, REG_IFTMP);
242 s1 = emit_load_s1(jd, iptr, src, d);
245 if (IS_FLT_DBL_TYPE(src->type))
251 emit_store(jd, iptr, dst, d);
256 void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d)
258 switch ((iptr->opc & ICMD_CONDITION_MASK) >> 8) {
281 /* code generation functions **************************************************/
283 void emit_ialu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
285 s4 s1 = src->prev->regoff;
287 s4 d = iptr->dst->regoff;
289 if (iptr->dst->flags & INMEMORY) {
290 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
292 emit_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
293 emit_alul_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
295 } else if (s1 == d) {
296 emit_movl_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
297 emit_alul_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
300 emit_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
301 emit_alul_membase_reg(cd, alu_op, REG_SP, s2 * 8, REG_ITMP1);
302 emit_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
305 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
307 emit_alul_reg_membase(cd, alu_op, s1, REG_SP, d * 8);
310 emit_movl_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
311 emit_alul_reg_reg(cd, alu_op, s1, REG_ITMP1);
312 emit_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
315 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
317 emit_alul_reg_membase(cd, alu_op, s2, REG_SP, d * 8);
320 emit_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
321 emit_alul_reg_reg(cd, alu_op, s2, REG_ITMP1);
322 emit_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
326 emit_movl_reg_membase(cd, s1, REG_SP, d * 8);
327 emit_alul_reg_membase(cd, alu_op, s2, REG_SP, d * 8);
331 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
332 emit_movl_membase_reg(cd, REG_SP, s1 * 8, d);
333 emit_alul_membase_reg(cd, alu_op, REG_SP, s2 * 8, d);
335 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
337 emit_alul_membase_reg(cd, alu_op, REG_SP, s2 * 8, d);
339 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
341 emit_alul_membase_reg(cd, alu_op, REG_SP, s1 * 8, d);
345 emit_alul_reg_reg(cd, alu_op, s1, d);
349 emit_alul_reg_reg(cd, alu_op, s2, d);
356 void emit_lalu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
358 s4 s1 = src->prev->regoff;
360 s4 d = iptr->dst->regoff;
362 if (iptr->dst->flags & INMEMORY) {
363 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
365 emit_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
366 emit_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
368 } else if (s1 == d) {
369 emit_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
370 emit_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
373 emit_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
374 emit_alu_membase_reg(cd, alu_op, REG_SP, s2 * 8, REG_ITMP1);
375 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
378 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
380 emit_alu_reg_membase(cd, alu_op, s1, REG_SP, d * 8);
383 emit_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
384 emit_alu_reg_reg(cd, alu_op, s1, REG_ITMP1);
385 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
388 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
390 emit_alu_reg_membase(cd, alu_op, s2, REG_SP, d * 8);
393 emit_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
394 emit_alu_reg_reg(cd, alu_op, s2, REG_ITMP1);
395 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
399 emit_mov_reg_membase(cd, s1, REG_SP, d * 8);
400 emit_alu_reg_membase(cd, alu_op, s2, REG_SP, d * 8);
404 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
405 emit_mov_membase_reg(cd, REG_SP, s1 * 8, d);
406 emit_alu_membase_reg(cd, alu_op, REG_SP, s2 * 8, d);
408 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
410 emit_alu_membase_reg(cd, alu_op, REG_SP, s2 * 8, d);
412 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
414 emit_alu_membase_reg(cd, alu_op, REG_SP, s1 * 8, d);
418 emit_alu_reg_reg(cd, alu_op, s1, d);
422 emit_alu_reg_reg(cd, alu_op, s2, d);
429 void emit_ialuconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
432 s4 d = iptr->dst->regoff;
434 if (iptr->dst->flags & INMEMORY) {
435 if (src->flags & INMEMORY) {
437 emit_alul_imm_membase(cd, alu_op, iptr->val.i, REG_SP, d * 8);
440 emit_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
441 emit_alul_imm_reg(cd, alu_op, iptr->val.i, REG_ITMP1);
442 emit_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
446 emit_movl_reg_membase(cd, s1, REG_SP, d * 8);
447 emit_alul_imm_membase(cd, alu_op, iptr->val.i, REG_SP, d * 8);
451 if (src->flags & INMEMORY) {
452 emit_movl_membase_reg(cd, REG_SP, s1 * 8, d);
453 emit_alul_imm_reg(cd, alu_op, iptr->val.i, d);
458 emit_alul_imm_reg(cd, alu_op, iptr->val.i, d);
460 /* lea addition optimization */
462 if ((alu_op == ALU_ADD) && (s1 != d)) {
463 M_ILEA(s1, iptr->val.i, d);
467 emit_alul_imm_reg(cd, alu_op, iptr->val.i, d);
475 void emit_laluconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
478 s4 d = iptr->dst->regoff;
480 if (iptr->dst->flags & INMEMORY) {
481 if (src->flags & INMEMORY) {
483 if (IS_IMM32(iptr->val.l)) {
484 emit_alu_imm_membase(cd, alu_op, iptr->val.l, REG_SP, d * 8);
487 emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
488 emit_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
492 emit_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
494 if (IS_IMM32(iptr->val.l)) {
495 emit_alu_imm_reg(cd, alu_op, iptr->val.l, REG_ITMP1);
498 emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP2);
499 emit_alu_reg_reg(cd, alu_op, REG_ITMP2, REG_ITMP1);
501 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
505 emit_mov_reg_membase(cd, s1, REG_SP, d * 8);
507 if (IS_IMM32(iptr->val.l)) {
508 emit_alu_imm_membase(cd, alu_op, iptr->val.l, REG_SP, d * 8);
511 emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
512 emit_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
518 if (src->flags & INMEMORY) {
519 emit_mov_membase_reg(cd, REG_SP, s1 * 8, d);
525 if (IS_IMM32(iptr->val.l)) {
526 emit_alu_imm_reg(cd, alu_op, iptr->val.l, d);
529 emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
530 emit_alu_reg_reg(cd, alu_op, REG_ITMP1, d);
533 if (src->flags & INMEMORY) {
534 emit_mov_membase_reg(cd, REG_SP, s1 * 8, d);
536 if (IS_IMM32(iptr->val.l)) {
537 emit_alu_imm_reg(cd, alu_op, iptr->val.l, d);
540 emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
541 emit_alu_reg_reg(cd, alu_op, REG_ITMP1, d);
545 if (IS_IMM32(iptr->val.l)) {
546 /* lea addition optimization */
548 if ((alu_op == ALU_ADD) && (s1 != d)) {
549 M_LLEA(s1, iptr->val.l, d);
553 emit_alu_imm_reg(cd, alu_op, iptr->val.l, d);
558 emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
559 emit_alu_reg_reg(cd, alu_op, REG_ITMP1, d);
567 void emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
569 s4 s1 = src->prev->regoff;
571 s4 d = iptr->dst->regoff;
574 M_INTMOVE(RCX, REG_ITMP1); /* save RCX */
576 if (iptr->dst->flags & INMEMORY) {
577 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
579 M_ILD(RCX, REG_SP, s2 * 8);
580 emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
583 M_ILD(RCX, REG_SP, s2 * 8);
584 M_ILD(REG_ITMP2, REG_SP, s1 * 8);
585 emit_shiftl_reg(cd, shift_op, REG_ITMP2);
586 M_IST(REG_ITMP2, REG_SP, d * 8);
589 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
590 /* s1 may be equal to RCX */
593 M_ILD(REG_ITMP1, REG_SP, s2 * 8);
594 M_IST(s1, REG_SP, d * 8);
595 M_INTMOVE(REG_ITMP1, RCX);
598 M_IST(s1, REG_SP, d * 8);
599 M_ILD(RCX, REG_SP, s2 * 8);
603 M_ILD(RCX, REG_SP, s2 * 8);
604 M_IST(s1, REG_SP, d * 8);
607 emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
609 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
612 emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
616 M_ILD(REG_ITMP2, REG_SP, s1 * 8);
617 emit_shiftl_reg(cd, shift_op, REG_ITMP2);
618 M_IST(REG_ITMP2, REG_SP, d * 8);
622 /* s1 may be equal to RCX */
623 M_IST(s1, REG_SP, d * 8);
625 emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
628 M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */
636 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
637 M_ILD(RCX, REG_SP, s2 * 8);
638 M_ILD(d, REG_SP, s1 * 8);
639 emit_shiftl_reg(cd, shift_op, d);
641 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
642 /* s1 may be equal to RCX */
644 M_ILD(RCX, REG_SP, s2 * 8);
645 emit_shiftl_reg(cd, shift_op, d);
647 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
649 M_ILD(d, REG_SP, s1 * 8);
650 emit_shiftl_reg(cd, shift_op, d);
653 /* s1 may be equal to RCX */
656 /* d cannot be used to backup s1 since this would
658 M_INTMOVE(s1, REG_ITMP3);
660 M_INTMOVE(REG_ITMP3, d);
668 /* d may be equal to s2 */
672 emit_shiftl_reg(cd, shift_op, d);
676 M_INTMOVE(REG_ITMP3, RCX);
678 M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */
683 void emit_lshift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
685 s4 s1 = src->prev->regoff;
687 s4 d = iptr->dst->regoff;
690 M_INTMOVE(RCX, REG_ITMP1); /* save RCX */
692 if (iptr->dst->flags & INMEMORY) {
693 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
695 M_ILD(RCX, REG_SP, s2 * 8);
696 emit_shift_membase(cd, shift_op, REG_SP, d * 8);
699 M_ILD(RCX, REG_SP, s2 * 8);
700 M_LLD(REG_ITMP2, REG_SP, s1 * 8);
701 emit_shift_reg(cd, shift_op, REG_ITMP2);
702 M_LST(REG_ITMP2, REG_SP, d * 8);
705 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
706 /* s1 may be equal to RCX */
709 M_ILD(REG_ITMP1, REG_SP, s2 * 8);
710 M_LST(s1, REG_SP, d * 8);
711 M_INTMOVE(REG_ITMP1, RCX);
714 M_LST(s1, REG_SP, d * 8);
715 M_ILD(RCX, REG_SP, s2 * 8);
719 M_ILD(RCX, REG_SP, s2 * 8);
720 M_LST(s1, REG_SP, d * 8);
723 emit_shift_membase(cd, shift_op, REG_SP, d * 8);
725 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
728 emit_shift_membase(cd, shift_op, REG_SP, d * 8);
732 M_LLD(REG_ITMP2, REG_SP, s1 * 8);
733 emit_shift_reg(cd, shift_op, REG_ITMP2);
734 M_LST(REG_ITMP2, REG_SP, d * 8);
738 /* s1 may be equal to RCX */
739 M_LST(s1, REG_SP, d * 8);
741 emit_shift_membase(cd, shift_op, REG_SP, d * 8);
744 M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */
752 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
753 M_ILD(RCX, REG_SP, s2 * 8);
754 M_LLD(d, REG_SP, s1 * 8);
755 emit_shift_reg(cd, shift_op, d);
757 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
758 /* s1 may be equal to RCX */
760 M_ILD(RCX, REG_SP, s2 * 8);
761 emit_shift_reg(cd, shift_op, d);
763 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
765 M_LLD(d, REG_SP, s1 * 8);
766 emit_shift_reg(cd, shift_op, d);
769 /* s1 may be equal to RCX */
772 /* d cannot be used to backup s1 since this would
774 M_INTMOVE(s1, REG_ITMP3);
776 M_INTMOVE(REG_ITMP3, d);
784 /* d may be equal to s2 */
788 emit_shift_reg(cd, shift_op, d);
792 M_INTMOVE(REG_ITMP3, RCX);
794 M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */
799 void emit_ishiftconst(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
802 s4 d = iptr->dst->regoff;
804 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
806 emit_shiftl_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8);
809 emit_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
810 emit_shiftl_imm_reg(cd, shift_op, iptr->val.i, REG_ITMP1);
811 emit_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
814 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
815 emit_movl_membase_reg(cd, REG_SP, s1 * 8, d);
816 emit_shiftl_imm_reg(cd, shift_op, iptr->val.i, d);
818 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
819 emit_movl_reg_membase(cd, s1, REG_SP, d * 8);
820 emit_shiftl_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8);
824 emit_shiftl_imm_reg(cd, shift_op, iptr->val.i, d);
829 void emit_lshiftconst(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
832 s4 d = iptr->dst->regoff;
834 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
836 emit_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8);
839 emit_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
840 emit_shift_imm_reg(cd, shift_op, iptr->val.i, REG_ITMP1);
841 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
844 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
845 emit_mov_membase_reg(cd, REG_SP, s1 * 8, d);
846 emit_shift_imm_reg(cd, shift_op, iptr->val.i, d);
848 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
849 emit_mov_reg_membase(cd, s1, REG_SP, d * 8);
850 emit_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8);
854 emit_shift_imm_reg(cd, shift_op, iptr->val.i, d);
859 void emit_ifcc(codegendata *cd, s4 if_op, stackptr src, instruction *iptr)
861 if (src->flags & INMEMORY)
862 M_ICMP_IMM_MEMBASE(iptr->val.i, REG_SP, src->regoff * 8);
864 if (iptr->val.i == 0)
865 M_ITEST(src->regoff);
867 M_ICMP_IMM(iptr->val.i, src->regoff);
870 /* If the conditional branch is part of an if-converted block,
871 don't generate the actual branch. */
873 if ((iptr->opc & ICMD_CONDITION_MASK) == 0) {
874 emit_jcc(cd, if_op, 0);
875 codegen_addreference(cd, (basicblock *) iptr->target);
880 void emit_if_lcc(codegendata *cd, s4 if_op, stackptr src, instruction *iptr)
884 if (src->flags & INMEMORY) {
885 if (IS_IMM32(iptr->val.l)) {
886 emit_alu_imm_membase(cd, ALU_CMP, iptr->val.l, REG_SP, s1 * 8);
889 emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
890 emit_alu_reg_membase(cd, ALU_CMP, REG_ITMP1, REG_SP, s1 * 8);
894 if (iptr->val.l == 0) {
895 emit_test_reg_reg(cd, s1, s1);
898 if (IS_IMM32(iptr->val.l)) {
899 emit_alu_imm_reg(cd, ALU_CMP, iptr->val.l, s1);
902 emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
903 emit_alu_reg_reg(cd, ALU_CMP, REG_ITMP1, s1);
907 emit_jcc(cd, if_op, 0);
908 codegen_addreference(cd, (basicblock *) iptr->target);
912 /* emit_if_icmpcc **************************************************************
914 Generate ICMD_IF_ICMPxx instructions.
916 *******************************************************************************/
918 void emit_if_icmpcc(codegendata *cd, s4 if_op, stackptr src,
921 s4 s1 = src->prev->regoff;
924 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
925 emit_movl_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
926 emit_alul_reg_membase(cd, ALU_CMP, REG_ITMP1, REG_SP, s1 * 8);
928 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
929 emit_alul_membase_reg(cd, ALU_CMP, REG_SP, s2 * 8, s1);
931 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
932 emit_alul_reg_membase(cd, ALU_CMP, s2, REG_SP, s1 * 8);
935 emit_alul_reg_reg(cd, ALU_CMP, s2, s1);
939 /* If the conditional branch is part of an if-converted block,
940 don't generate the actual branch. */
942 if ((iptr->opc & ICMD_CONDITION_MASK) == 0) {
943 emit_jcc(cd, if_op, 0);
944 codegen_addreference(cd, (basicblock *) iptr->target);
949 void emit_if_lcmpcc(codegendata *cd, s4 if_op, stackptr src, instruction *iptr)
951 s4 s1 = src->prev->regoff;
954 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
955 emit_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
956 emit_alu_reg_membase(cd, ALU_CMP, REG_ITMP1, REG_SP, s1 * 8);
958 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
959 emit_alu_membase_reg(cd, ALU_CMP, REG_SP, s2 * 8, s1);
961 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
962 emit_alu_reg_membase(cd, ALU_CMP, s2, REG_SP, s1 * 8);
965 emit_alu_reg_reg(cd, ALU_CMP, s2, s1);
967 emit_jcc(cd, if_op, 0);
968 codegen_addreference(cd, (basicblock *) iptr->target);
972 /* low-level code emitter functions *******************************************/
974 void emit_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg)
976 emit_rex(1,(reg),0,(dreg));
977 *(cd->mcodeptr++) = 0x89;
978 emit_reg((reg),(dreg));
982 void emit_mov_imm_reg(codegendata *cd, s8 imm, s8 reg)
984 emit_rex(1,0,0,(reg));
985 *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
990 void emit_movl_imm_reg(codegendata *cd, s8 imm, s8 reg) {
991 emit_rex(0,0,0,(reg));
992 *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
997 void emit_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
998 emit_rex(1,(reg),0,(basereg));
999 *(cd->mcodeptr++) = 0x8b;
1000 emit_membase((basereg),(disp),(reg));
1005 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
1006 * constant membase immediate length of 32bit
1008 void emit_mov_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1009 emit_rex(1,(reg),0,(basereg));
1010 *(cd->mcodeptr++) = 0x8b;
1011 emit_membase32((basereg),(disp),(reg));
1015 void emit_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
1017 emit_rex(0,(reg),0,(basereg));
1018 *(cd->mcodeptr++) = 0x8b;
1019 emit_membase((basereg),(disp),(reg));
1023 /* ATTENTION: Always emit a REX byte, because the instruction size can
1024 be smaller when all register indexes are smaller than 7. */
1025 void emit_movl_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
1027 emit_byte_rex((reg),0,(basereg));
1028 *(cd->mcodeptr++) = 0x8b;
1029 emit_membase32((basereg),(disp),(reg));
1033 void emit_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1034 emit_rex(1,(reg),0,(basereg));
1035 *(cd->mcodeptr++) = 0x89;
1036 emit_membase((basereg),(disp),(reg));
1040 void emit_mov_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1041 emit_rex(1,(reg),0,(basereg));
1042 *(cd->mcodeptr++) = 0x89;
1043 emit_membase32((basereg),(disp),(reg));
1047 void emit_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1048 emit_rex(0,(reg),0,(basereg));
1049 *(cd->mcodeptr++) = 0x89;
1050 emit_membase((basereg),(disp),(reg));
1054 /* Always emit a REX byte, because the instruction size can be smaller when */
1055 /* all register indexes are smaller than 7. */
1056 void emit_movl_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1057 emit_byte_rex((reg),0,(basereg));
1058 *(cd->mcodeptr++) = 0x89;
1059 emit_membase32((basereg),(disp),(reg));
1063 void emit_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1064 emit_rex(1,(reg),(indexreg),(basereg));
1065 *(cd->mcodeptr++) = 0x8b;
1066 emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1070 void emit_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1071 emit_rex(0,(reg),(indexreg),(basereg));
1072 *(cd->mcodeptr++) = 0x8b;
1073 emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1077 void emit_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1078 emit_rex(1,(reg),(indexreg),(basereg));
1079 *(cd->mcodeptr++) = 0x89;
1080 emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1084 void emit_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1085 emit_rex(0,(reg),(indexreg),(basereg));
1086 *(cd->mcodeptr++) = 0x89;
1087 emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1091 void emit_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1092 *(cd->mcodeptr++) = 0x66;
1093 emit_rex(0,(reg),(indexreg),(basereg));
1094 *(cd->mcodeptr++) = 0x89;
1095 emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1099 void emit_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1100 emit_byte_rex((reg),(indexreg),(basereg));
1101 *(cd->mcodeptr++) = 0x88;
1102 emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1106 void emit_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1107 emit_rex(1,0,0,(basereg));
1108 *(cd->mcodeptr++) = 0xc7;
1109 emit_membase((basereg),(disp),0);
1114 void emit_mov_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1115 emit_rex(1,0,0,(basereg));
1116 *(cd->mcodeptr++) = 0xc7;
1117 emit_membase32((basereg),(disp),0);
1122 void emit_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1123 emit_rex(0,0,0,(basereg));
1124 *(cd->mcodeptr++) = 0xc7;
1125 emit_membase((basereg),(disp),0);
1130 /* Always emit a REX byte, because the instruction size can be smaller when */
1131 /* all register indexes are smaller than 7. */
1132 void emit_movl_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1133 emit_byte_rex(0,0,(basereg));
1134 *(cd->mcodeptr++) = 0xc7;
1135 emit_membase32((basereg),(disp),0);
1140 void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1141 emit_rex(1,(dreg),0,(reg));
1142 *(cd->mcodeptr++) = 0x0f;
1143 *(cd->mcodeptr++) = 0xbe;
1144 /* XXX: why do reg and dreg have to be exchanged */
1145 emit_reg((dreg),(reg));
1149 void emit_movsbq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1150 emit_rex(1,(dreg),0,(basereg));
1151 *(cd->mcodeptr++) = 0x0f;
1152 *(cd->mcodeptr++) = 0xbe;
1153 emit_membase((basereg),(disp),(dreg));
1157 void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1158 emit_rex(1,(dreg),0,(reg));
1159 *(cd->mcodeptr++) = 0x0f;
1160 *(cd->mcodeptr++) = 0xbf;
1161 /* XXX: why do reg and dreg have to be exchanged */
1162 emit_reg((dreg),(reg));
1166 void emit_movswq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1167 emit_rex(1,(dreg),0,(basereg));
1168 *(cd->mcodeptr++) = 0x0f;
1169 *(cd->mcodeptr++) = 0xbf;
1170 emit_membase((basereg),(disp),(dreg));
1174 void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1175 emit_rex(1,(dreg),0,(reg));
1176 *(cd->mcodeptr++) = 0x63;
1177 /* XXX: why do reg and dreg have to be exchanged */
1178 emit_reg((dreg),(reg));
1182 void emit_movslq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1183 emit_rex(1,(dreg),0,(basereg));
1184 *(cd->mcodeptr++) = 0x63;
1185 emit_membase((basereg),(disp),(dreg));
1189 void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1190 emit_rex(1,(dreg),0,(reg));
1191 *(cd->mcodeptr++) = 0x0f;
1192 *(cd->mcodeptr++) = 0xb7;
1193 /* XXX: why do reg and dreg have to be exchanged */
1194 emit_reg((dreg),(reg));
1198 void emit_movzwq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1199 emit_rex(1,(dreg),0,(basereg));
1200 *(cd->mcodeptr++) = 0x0f;
1201 *(cd->mcodeptr++) = 0xb7;
1202 emit_membase((basereg),(disp),(dreg));
1206 void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1207 emit_rex(1,(reg),(indexreg),(basereg));
1208 *(cd->mcodeptr++) = 0x0f;
1209 *(cd->mcodeptr++) = 0xbf;
1210 emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1214 void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1215 emit_rex(1,(reg),(indexreg),(basereg));
1216 *(cd->mcodeptr++) = 0x0f;
1217 *(cd->mcodeptr++) = 0xbe;
1218 emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1222 void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1223 emit_rex(1,(reg),(indexreg),(basereg));
1224 *(cd->mcodeptr++) = 0x0f;
1225 *(cd->mcodeptr++) = 0xb7;
1226 emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1230 void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1232 emit_rex(1,0,(indexreg),(basereg));
1233 *(cd->mcodeptr++) = 0xc7;
1234 emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1239 void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1241 emit_rex(0,0,(indexreg),(basereg));
1242 *(cd->mcodeptr++) = 0xc7;
1243 emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1248 void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1250 *(cd->mcodeptr++) = 0x66;
1251 emit_rex(0,0,(indexreg),(basereg));
1252 *(cd->mcodeptr++) = 0xc7;
1253 emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1258 void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1260 emit_rex(0,0,(indexreg),(basereg));
1261 *(cd->mcodeptr++) = 0xc6;
1262 emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1270 void emit_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1272 emit_rex(1,(reg),0,(dreg));
1273 *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1274 emit_reg((reg),(dreg));
1278 void emit_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1280 emit_rex(0,(reg),0,(dreg));
1281 *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1282 emit_reg((reg),(dreg));
1286 void emit_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp) {
1287 emit_rex(1,(reg),0,(basereg));
1288 *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1289 emit_membase((basereg),(disp),(reg));
1293 void emit_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp) {
1294 emit_rex(0,(reg),0,(basereg));
1295 *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1296 emit_membase((basereg),(disp),(reg));
1300 void emit_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg) {
1301 emit_rex(1,(reg),0,(basereg));
1302 *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1303 emit_membase((basereg),(disp),(reg));
1307 void emit_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg) {
1308 emit_rex(0,(reg),0,(basereg));
1309 *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1310 emit_membase((basereg),(disp),(reg));
1314 void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1316 emit_rex(1,0,0,(dreg));
1317 *(cd->mcodeptr++) = 0x83;
1318 emit_reg((opc),(dreg));
1321 emit_rex(1,0,0,(dreg));
1322 *(cd->mcodeptr++) = 0x81;
1323 emit_reg((opc),(dreg));
1329 void emit_alu_imm32_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1330 emit_rex(1,0,0,(dreg));
1331 *(cd->mcodeptr++) = 0x81;
1332 emit_reg((opc),(dreg));
1337 void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1339 emit_rex(0,0,0,(dreg));
1340 *(cd->mcodeptr++) = 0x83;
1341 emit_reg((opc),(dreg));
1344 emit_rex(0,0,0,(dreg));
1345 *(cd->mcodeptr++) = 0x81;
1346 emit_reg((opc),(dreg));
1352 void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1354 emit_rex(1,(basereg),0,0);
1355 *(cd->mcodeptr++) = 0x83;
1356 emit_membase((basereg),(disp),(opc));
1359 emit_rex(1,(basereg),0,0);
1360 *(cd->mcodeptr++) = 0x81;
1361 emit_membase((basereg),(disp),(opc));
1367 void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1369 emit_rex(0,(basereg),0,0);
1370 *(cd->mcodeptr++) = 0x83;
1371 emit_membase((basereg),(disp),(opc));
1374 emit_rex(0,(basereg),0,0);
1375 *(cd->mcodeptr++) = 0x81;
1376 emit_membase((basereg),(disp),(opc));
1382 void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1383 emit_rex(1,(reg),0,(dreg));
1384 *(cd->mcodeptr++) = 0x85;
1385 emit_reg((reg),(dreg));
1389 void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1390 emit_rex(0,(reg),0,(dreg));
1391 *(cd->mcodeptr++) = 0x85;
1392 emit_reg((reg),(dreg));
1396 void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1397 *(cd->mcodeptr++) = 0xf7;
1403 void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1404 *(cd->mcodeptr++) = 0x66;
1405 *(cd->mcodeptr++) = 0xf7;
1411 void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1412 *(cd->mcodeptr++) = 0xf6;
1418 void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1419 emit_rex(1,(reg),0,(basereg));
1420 *(cd->mcodeptr++) = 0x8d;
1421 emit_membase((basereg),(disp),(reg));
1425 void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1426 emit_rex(0,(reg),0,(basereg));
1427 *(cd->mcodeptr++) = 0x8d;
1428 emit_membase((basereg),(disp),(reg));
1434 * inc, dec operations
1436 void emit_inc_reg(codegendata *cd, s8 reg) {
1437 emit_rex(1,0,0,(reg));
1438 *(cd->mcodeptr++) = 0xff;
1443 void emit_incl_reg(codegendata *cd, s8 reg) {
1444 emit_rex(0,0,0,(reg));
1445 *(cd->mcodeptr++) = 0xff;
1450 void emit_inc_membase(codegendata *cd, s8 basereg, s8 disp)
1452 emit_rex(1,0,0,(basereg));
1453 *(cd->mcodeptr++) = 0xff;
1454 emit_membase((basereg),(disp),0);
1458 void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp)
1460 emit_rex(0,0,0,(basereg));
1461 *(cd->mcodeptr++) = 0xff;
1462 emit_membase((basereg),(disp),0);
1466 void emit_dec_reg(codegendata *cd, s8 reg) {
1467 emit_rex(1,0,0,(reg));
1468 *(cd->mcodeptr++) = 0xff;
1473 void emit_decl_reg(codegendata *cd, s8 reg) {
1474 emit_rex(0,0,0,(reg));
1475 *(cd->mcodeptr++) = 0xff;
1480 void emit_dec_membase(codegendata *cd, s8 basereg, s8 disp) {
1481 emit_rex(1,(basereg),0,0);
1482 *(cd->mcodeptr++) = 0xff;
1483 emit_membase((basereg),(disp),1);
1487 void emit_decl_membase(codegendata *cd, s8 basereg, s8 disp) {
1488 emit_rex(0,(basereg),0,0);
1489 *(cd->mcodeptr++) = 0xff;
1490 emit_membase((basereg),(disp),1);
1496 void emit_cltd(codegendata *cd) {
1497 *(cd->mcodeptr++) = 0x99;
1501 void emit_cqto(codegendata *cd) {
1503 *(cd->mcodeptr++) = 0x99;
1508 void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1509 emit_rex(1,(dreg),0,(reg));
1510 *(cd->mcodeptr++) = 0x0f;
1511 *(cd->mcodeptr++) = 0xaf;
1512 emit_reg((dreg),(reg));
1516 void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1517 emit_rex(0,(dreg),0,(reg));
1518 *(cd->mcodeptr++) = 0x0f;
1519 *(cd->mcodeptr++) = 0xaf;
1520 emit_reg((dreg),(reg));
1524 void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1525 emit_rex(1,(dreg),0,(basereg));
1526 *(cd->mcodeptr++) = 0x0f;
1527 *(cd->mcodeptr++) = 0xaf;
1528 emit_membase((basereg),(disp),(dreg));
1532 void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1533 emit_rex(0,(dreg),0,(basereg));
1534 *(cd->mcodeptr++) = 0x0f;
1535 *(cd->mcodeptr++) = 0xaf;
1536 emit_membase((basereg),(disp),(dreg));
1540 void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg) {
1541 if (IS_IMM8((imm))) {
1542 emit_rex(1,0,0,(dreg));
1543 *(cd->mcodeptr++) = 0x6b;
1547 emit_rex(1,0,0,(dreg));
1548 *(cd->mcodeptr++) = 0x69;
1555 void emit_imul_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1556 if (IS_IMM8((imm))) {
1557 emit_rex(1,(dreg),0,(reg));
1558 *(cd->mcodeptr++) = 0x6b;
1559 emit_reg((dreg),(reg));
1562 emit_rex(1,(dreg),0,(reg));
1563 *(cd->mcodeptr++) = 0x69;
1564 emit_reg((dreg),(reg));
1570 void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1571 if (IS_IMM8((imm))) {
1572 emit_rex(0,(dreg),0,(reg));
1573 *(cd->mcodeptr++) = 0x6b;
1574 emit_reg((dreg),(reg));
1577 emit_rex(0,(dreg),0,(reg));
1578 *(cd->mcodeptr++) = 0x69;
1579 emit_reg((dreg),(reg));
1585 void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1586 if (IS_IMM8((imm))) {
1587 emit_rex(1,(dreg),0,(basereg));
1588 *(cd->mcodeptr++) = 0x6b;
1589 emit_membase((basereg),(disp),(dreg));
1592 emit_rex(1,(dreg),0,(basereg));
1593 *(cd->mcodeptr++) = 0x69;
1594 emit_membase((basereg),(disp),(dreg));
1600 void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1601 if (IS_IMM8((imm))) {
1602 emit_rex(0,(dreg),0,(basereg));
1603 *(cd->mcodeptr++) = 0x6b;
1604 emit_membase((basereg),(disp),(dreg));
1607 emit_rex(0,(dreg),0,(basereg));
1608 *(cd->mcodeptr++) = 0x69;
1609 emit_membase((basereg),(disp),(dreg));
1615 void emit_idiv_reg(codegendata *cd, s8 reg) {
1616 emit_rex(1,0,0,(reg));
1617 *(cd->mcodeptr++) = 0xf7;
1622 void emit_idivl_reg(codegendata *cd, s8 reg) {
1623 emit_rex(0,0,0,(reg));
1624 *(cd->mcodeptr++) = 0xf7;
1630 void emit_ret(codegendata *cd) {
1631 *(cd->mcodeptr++) = 0xc3;
1639 void emit_shift_reg(codegendata *cd, s8 opc, s8 reg) {
1640 emit_rex(1,0,0,(reg));
1641 *(cd->mcodeptr++) = 0xd3;
1642 emit_reg((opc),(reg));
1646 void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg) {
1647 emit_rex(0,0,0,(reg));
1648 *(cd->mcodeptr++) = 0xd3;
1649 emit_reg((opc),(reg));
1653 void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1654 emit_rex(1,0,0,(basereg));
1655 *(cd->mcodeptr++) = 0xd3;
1656 emit_membase((basereg),(disp),(opc));
1660 void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1661 emit_rex(0,0,0,(basereg));
1662 *(cd->mcodeptr++) = 0xd3;
1663 emit_membase((basereg),(disp),(opc));
1667 void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1669 emit_rex(1,0,0,(dreg));
1670 *(cd->mcodeptr++) = 0xd1;
1671 emit_reg((opc),(dreg));
1673 emit_rex(1,0,0,(dreg));
1674 *(cd->mcodeptr++) = 0xc1;
1675 emit_reg((opc),(dreg));
1681 void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1683 emit_rex(0,0,0,(dreg));
1684 *(cd->mcodeptr++) = 0xd1;
1685 emit_reg((opc),(dreg));
1687 emit_rex(0,0,0,(dreg));
1688 *(cd->mcodeptr++) = 0xc1;
1689 emit_reg((opc),(dreg));
1695 void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1697 emit_rex(1,0,0,(basereg));
1698 *(cd->mcodeptr++) = 0xd1;
1699 emit_membase((basereg),(disp),(opc));
1701 emit_rex(1,0,0,(basereg));
1702 *(cd->mcodeptr++) = 0xc1;
1703 emit_membase((basereg),(disp),(opc));
1709 void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1711 emit_rex(0,0,0,(basereg));
1712 *(cd->mcodeptr++) = 0xd1;
1713 emit_membase((basereg),(disp),(opc));
1715 emit_rex(0,0,0,(basereg));
1716 *(cd->mcodeptr++) = 0xc1;
1717 emit_membase((basereg),(disp),(opc));
1727 void emit_jmp_imm(codegendata *cd, s8 imm) {
1728 *(cd->mcodeptr++) = 0xe9;
1733 void emit_jmp_reg(codegendata *cd, s8 reg) {
1734 emit_rex(0,0,0,(reg));
1735 *(cd->mcodeptr++) = 0xff;
1740 void emit_jcc(codegendata *cd, s8 opc, s8 imm) {
1741 *(cd->mcodeptr++) = 0x0f;
1742 *(cd->mcodeptr++) = (0x80 + (opc));
1749 * conditional set and move operations
1752 /* we need the rex byte to get all low bytes */
1753 void emit_setcc_reg(codegendata *cd, s8 opc, s8 reg) {
1754 *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
1755 *(cd->mcodeptr++) = 0x0f;
1756 *(cd->mcodeptr++) = (0x90 + (opc));
1761 /* we need the rex byte to get all low bytes */
1762 void emit_setcc_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1763 *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
1764 *(cd->mcodeptr++) = 0x0f;
1765 *(cd->mcodeptr++) = (0x90 + (opc));
1766 emit_membase((basereg),(disp),0);
1770 void emit_cmovcc_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1772 emit_rex(1,(dreg),0,(reg));
1773 *(cd->mcodeptr++) = 0x0f;
1774 *(cd->mcodeptr++) = (0x40 + (opc));
1775 emit_reg((dreg),(reg));
1779 void emit_cmovccl_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1781 emit_rex(0,(dreg),0,(reg));
1782 *(cd->mcodeptr++) = 0x0f;
1783 *(cd->mcodeptr++) = (0x40 + (opc));
1784 emit_reg((dreg),(reg));
1789 void emit_neg_reg(codegendata *cd, s8 reg) {
1790 emit_rex(1,0,0,(reg));
1791 *(cd->mcodeptr++) = 0xf7;
1796 void emit_negl_reg(codegendata *cd, s8 reg) {
1797 emit_rex(0,0,0,(reg));
1798 *(cd->mcodeptr++) = 0xf7;
1803 void emit_neg_membase(codegendata *cd, s8 basereg, s8 disp) {
1804 emit_rex(1,0,0,(basereg));
1805 *(cd->mcodeptr++) = 0xf7;
1806 emit_membase((basereg),(disp),3);
1810 void emit_negl_membase(codegendata *cd, s8 basereg, s8 disp) {
1811 emit_rex(0,0,0,(basereg));
1812 *(cd->mcodeptr++) = 0xf7;
1813 emit_membase((basereg),(disp),3);
1817 void emit_push_reg(codegendata *cd, s8 reg) {
1818 emit_rex(0,0,0,(reg));
1819 *(cd->mcodeptr++) = 0x50 + (0x07 & (reg));
1823 void emit_push_imm(codegendata *cd, s8 imm) {
1824 *(cd->mcodeptr++) = 0x68;
1829 void emit_pop_reg(codegendata *cd, s8 reg) {
1830 emit_rex(0,0,0,(reg));
1831 *(cd->mcodeptr++) = 0x58 + (0x07 & (reg));
1835 void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1836 emit_rex(1,(reg),0,(dreg));
1837 *(cd->mcodeptr++) = 0x87;
1838 emit_reg((reg),(dreg));
1842 void emit_nop(codegendata *cd) {
1843 *(cd->mcodeptr++) = 0x90;
1851 void emit_call_reg(codegendata *cd, s8 reg) {
1852 emit_rex(1,0,0,(reg));
1853 *(cd->mcodeptr++) = 0xff;
1858 void emit_call_imm(codegendata *cd, s8 imm) {
1859 *(cd->mcodeptr++) = 0xe8;
1864 void emit_call_mem(codegendata *cd, ptrint mem)
1866 *(cd->mcodeptr++) = 0xff;
1873 * floating point instructions (SSE2)
1875 void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1876 *(cd->mcodeptr++) = 0xf2;
1877 emit_rex(0,(dreg),0,(reg));
1878 *(cd->mcodeptr++) = 0x0f;
1879 *(cd->mcodeptr++) = 0x58;
1880 emit_reg((dreg),(reg));
1884 void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1885 *(cd->mcodeptr++) = 0xf3;
1886 emit_rex(0,(dreg),0,(reg));
1887 *(cd->mcodeptr++) = 0x0f;
1888 *(cd->mcodeptr++) = 0x58;
1889 emit_reg((dreg),(reg));
1893 void emit_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1894 *(cd->mcodeptr++) = 0xf3;
1895 emit_rex(1,(dreg),0,(reg));
1896 *(cd->mcodeptr++) = 0x0f;
1897 *(cd->mcodeptr++) = 0x2a;
1898 emit_reg((dreg),(reg));
1902 void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1903 *(cd->mcodeptr++) = 0xf3;
1904 emit_rex(0,(dreg),0,(reg));
1905 *(cd->mcodeptr++) = 0x0f;
1906 *(cd->mcodeptr++) = 0x2a;
1907 emit_reg((dreg),(reg));
1911 void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1912 *(cd->mcodeptr++) = 0xf2;
1913 emit_rex(1,(dreg),0,(reg));
1914 *(cd->mcodeptr++) = 0x0f;
1915 *(cd->mcodeptr++) = 0x2a;
1916 emit_reg((dreg),(reg));
1920 void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1921 *(cd->mcodeptr++) = 0xf2;
1922 emit_rex(0,(dreg),0,(reg));
1923 *(cd->mcodeptr++) = 0x0f;
1924 *(cd->mcodeptr++) = 0x2a;
1925 emit_reg((dreg),(reg));
1929 void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1930 *(cd->mcodeptr++) = 0xf3;
1931 emit_rex(0,(dreg),0,(reg));
1932 *(cd->mcodeptr++) = 0x0f;
1933 *(cd->mcodeptr++) = 0x5a;
1934 emit_reg((dreg),(reg));
1938 void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1939 *(cd->mcodeptr++) = 0xf2;
1940 emit_rex(0,(dreg),0,(reg));
1941 *(cd->mcodeptr++) = 0x0f;
1942 *(cd->mcodeptr++) = 0x5a;
1943 emit_reg((dreg),(reg));
1947 void emit_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1948 *(cd->mcodeptr++) = 0xf3;
1949 emit_rex(1,(dreg),0,(reg));
1950 *(cd->mcodeptr++) = 0x0f;
1951 *(cd->mcodeptr++) = 0x2c;
1952 emit_reg((dreg),(reg));
1956 void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1957 *(cd->mcodeptr++) = 0xf3;
1958 emit_rex(0,(dreg),0,(reg));
1959 *(cd->mcodeptr++) = 0x0f;
1960 *(cd->mcodeptr++) = 0x2c;
1961 emit_reg((dreg),(reg));
1965 void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1966 *(cd->mcodeptr++) = 0xf2;
1967 emit_rex(1,(dreg),0,(reg));
1968 *(cd->mcodeptr++) = 0x0f;
1969 *(cd->mcodeptr++) = 0x2c;
1970 emit_reg((dreg),(reg));
1974 void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1975 *(cd->mcodeptr++) = 0xf2;
1976 emit_rex(0,(dreg),0,(reg));
1977 *(cd->mcodeptr++) = 0x0f;
1978 *(cd->mcodeptr++) = 0x2c;
1979 emit_reg((dreg),(reg));
1983 void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1984 *(cd->mcodeptr++) = 0xf3;
1985 emit_rex(0,(dreg),0,(reg));
1986 *(cd->mcodeptr++) = 0x0f;
1987 *(cd->mcodeptr++) = 0x5e;
1988 emit_reg((dreg),(reg));
1992 void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1993 *(cd->mcodeptr++) = 0xf2;
1994 emit_rex(0,(dreg),0,(reg));
1995 *(cd->mcodeptr++) = 0x0f;
1996 *(cd->mcodeptr++) = 0x5e;
1997 emit_reg((dreg),(reg));
2001 void emit_movd_reg_freg(codegendata *cd, s8 reg, s8 freg) {
2002 *(cd->mcodeptr++) = 0x66;
2003 emit_rex(1,(freg),0,(reg));
2004 *(cd->mcodeptr++) = 0x0f;
2005 *(cd->mcodeptr++) = 0x6e;
2006 emit_reg((freg),(reg));
2010 void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg) {
2011 *(cd->mcodeptr++) = 0x66;
2012 emit_rex(1,(freg),0,(reg));
2013 *(cd->mcodeptr++) = 0x0f;
2014 *(cd->mcodeptr++) = 0x7e;
2015 emit_reg((freg),(reg));
2019 void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2020 *(cd->mcodeptr++) = 0x66;
2021 emit_rex(0,(reg),0,(basereg));
2022 *(cd->mcodeptr++) = 0x0f;
2023 *(cd->mcodeptr++) = 0x7e;
2024 emit_membase((basereg),(disp),(reg));
2028 void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2029 *(cd->mcodeptr++) = 0x66;
2030 emit_rex(0,(reg),(indexreg),(basereg));
2031 *(cd->mcodeptr++) = 0x0f;
2032 *(cd->mcodeptr++) = 0x7e;
2033 emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
2037 void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2038 *(cd->mcodeptr++) = 0x66;
2039 emit_rex(1,(dreg),0,(basereg));
2040 *(cd->mcodeptr++) = 0x0f;
2041 *(cd->mcodeptr++) = 0x6e;
2042 emit_membase((basereg),(disp),(dreg));
2046 void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2047 *(cd->mcodeptr++) = 0x66;
2048 emit_rex(0,(dreg),0,(basereg));
2049 *(cd->mcodeptr++) = 0x0f;
2050 *(cd->mcodeptr++) = 0x6e;
2051 emit_membase((basereg),(disp),(dreg));
2055 void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2056 *(cd->mcodeptr++) = 0x66;
2057 emit_rex(0,(dreg),(indexreg),(basereg));
2058 *(cd->mcodeptr++) = 0x0f;
2059 *(cd->mcodeptr++) = 0x6e;
2060 emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
2064 void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2065 *(cd->mcodeptr++) = 0xf3;
2066 emit_rex(0,(dreg),0,(reg));
2067 *(cd->mcodeptr++) = 0x0f;
2068 *(cd->mcodeptr++) = 0x7e;
2069 emit_reg((dreg),(reg));
2073 void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2074 *(cd->mcodeptr++) = 0x66;
2075 emit_rex(0,(reg),0,(basereg));
2076 *(cd->mcodeptr++) = 0x0f;
2077 *(cd->mcodeptr++) = 0xd6;
2078 emit_membase((basereg),(disp),(reg));
2082 void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2083 *(cd->mcodeptr++) = 0xf3;
2084 emit_rex(0,(dreg),0,(basereg));
2085 *(cd->mcodeptr++) = 0x0f;
2086 *(cd->mcodeptr++) = 0x7e;
2087 emit_membase((basereg),(disp),(dreg));
2091 void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2092 *(cd->mcodeptr++) = 0xf3;
2093 emit_rex(0,(reg),0,(dreg));
2094 *(cd->mcodeptr++) = 0x0f;
2095 *(cd->mcodeptr++) = 0x10;
2096 emit_reg((reg),(dreg));
2100 void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2101 *(cd->mcodeptr++) = 0xf2;
2102 emit_rex(0,(reg),0,(dreg));
2103 *(cd->mcodeptr++) = 0x0f;
2104 *(cd->mcodeptr++) = 0x10;
2105 emit_reg((reg),(dreg));
2109 void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2110 *(cd->mcodeptr++) = 0xf3;
2111 emit_rex(0,(reg),0,(basereg));
2112 *(cd->mcodeptr++) = 0x0f;
2113 *(cd->mcodeptr++) = 0x11;
2114 emit_membase((basereg),(disp),(reg));
2118 /* Always emit a REX byte, because the instruction size can be smaller when */
2119 /* all register indexes are smaller than 7. */
2120 void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2121 *(cd->mcodeptr++) = 0xf3;
2122 emit_byte_rex((reg),0,(basereg));
2123 *(cd->mcodeptr++) = 0x0f;
2124 *(cd->mcodeptr++) = 0x11;
2125 emit_membase32((basereg),(disp),(reg));
2129 void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2130 *(cd->mcodeptr++) = 0xf2;
2131 emit_rex(0,(reg),0,(basereg));
2132 *(cd->mcodeptr++) = 0x0f;
2133 *(cd->mcodeptr++) = 0x11;
2134 emit_membase((basereg),(disp),(reg));
2138 /* Always emit a REX byte, because the instruction size can be smaller when */
2139 /* all register indexes are smaller than 7. */
2140 void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2141 *(cd->mcodeptr++) = 0xf2;
2142 emit_byte_rex((reg),0,(basereg));
2143 *(cd->mcodeptr++) = 0x0f;
2144 *(cd->mcodeptr++) = 0x11;
2145 emit_membase32((basereg),(disp),(reg));
2149 void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2150 *(cd->mcodeptr++) = 0xf3;
2151 emit_rex(0,(dreg),0,(basereg));
2152 *(cd->mcodeptr++) = 0x0f;
2153 *(cd->mcodeptr++) = 0x10;
2154 emit_membase((basereg),(disp),(dreg));
2158 /* Always emit a REX byte, because the instruction size can be smaller when */
2159 /* all register indexes are smaller than 7. */
2160 void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2161 *(cd->mcodeptr++) = 0xf3;
2162 emit_byte_rex((dreg),0,(basereg));
2163 *(cd->mcodeptr++) = 0x0f;
2164 *(cd->mcodeptr++) = 0x10;
2165 emit_membase32((basereg),(disp),(dreg));
2169 void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2170 emit_rex(0,(dreg),0,(basereg));
2171 *(cd->mcodeptr++) = 0x0f;
2172 *(cd->mcodeptr++) = 0x12;
2173 emit_membase((basereg),(disp),(dreg));
2177 void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2178 *(cd->mcodeptr++) = 0xf2;
2179 emit_rex(0,(dreg),0,(basereg));
2180 *(cd->mcodeptr++) = 0x0f;
2181 *(cd->mcodeptr++) = 0x10;
2182 emit_membase((basereg),(disp),(dreg));
2186 /* Always emit a REX byte, because the instruction size can be smaller when */
2187 /* all register indexes are smaller than 7. */
2188 void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2189 *(cd->mcodeptr++) = 0xf2;
2190 emit_byte_rex((dreg),0,(basereg));
2191 *(cd->mcodeptr++) = 0x0f;
2192 *(cd->mcodeptr++) = 0x10;
2193 emit_membase32((basereg),(disp),(dreg));
2197 void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2198 *(cd->mcodeptr++) = 0x66;
2199 emit_rex(0,(dreg),0,(basereg));
2200 *(cd->mcodeptr++) = 0x0f;
2201 *(cd->mcodeptr++) = 0x12;
2202 emit_membase((basereg),(disp),(dreg));
2206 void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2207 *(cd->mcodeptr++) = 0xf3;
2208 emit_rex(0,(reg),(indexreg),(basereg));
2209 *(cd->mcodeptr++) = 0x0f;
2210 *(cd->mcodeptr++) = 0x11;
2211 emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
2215 void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2216 *(cd->mcodeptr++) = 0xf2;
2217 emit_rex(0,(reg),(indexreg),(basereg));
2218 *(cd->mcodeptr++) = 0x0f;
2219 *(cd->mcodeptr++) = 0x11;
2220 emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
2224 void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2225 *(cd->mcodeptr++) = 0xf3;
2226 emit_rex(0,(dreg),(indexreg),(basereg));
2227 *(cd->mcodeptr++) = 0x0f;
2228 *(cd->mcodeptr++) = 0x10;
2229 emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
2233 void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2234 *(cd->mcodeptr++) = 0xf2;
2235 emit_rex(0,(dreg),(indexreg),(basereg));
2236 *(cd->mcodeptr++) = 0x0f;
2237 *(cd->mcodeptr++) = 0x10;
2238 emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
2242 void emit_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2243 *(cd->mcodeptr++) = 0xf3;
2244 emit_rex(0,(dreg),0,(reg));
2245 *(cd->mcodeptr++) = 0x0f;
2246 *(cd->mcodeptr++) = 0x59;
2247 emit_reg((dreg),(reg));
2251 void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2252 *(cd->mcodeptr++) = 0xf2;
2253 emit_rex(0,(dreg),0,(reg));
2254 *(cd->mcodeptr++) = 0x0f;
2255 *(cd->mcodeptr++) = 0x59;
2256 emit_reg((dreg),(reg));
2260 void emit_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2261 *(cd->mcodeptr++) = 0xf3;
2262 emit_rex(0,(dreg),0,(reg));
2263 *(cd->mcodeptr++) = 0x0f;
2264 *(cd->mcodeptr++) = 0x5c;
2265 emit_reg((dreg),(reg));
2269 void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2270 *(cd->mcodeptr++) = 0xf2;
2271 emit_rex(0,(dreg),0,(reg));
2272 *(cd->mcodeptr++) = 0x0f;
2273 *(cd->mcodeptr++) = 0x5c;
2274 emit_reg((dreg),(reg));
2278 void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2279 emit_rex(0,(dreg),0,(reg));
2280 *(cd->mcodeptr++) = 0x0f;
2281 *(cd->mcodeptr++) = 0x2e;
2282 emit_reg((dreg),(reg));
2286 void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2287 *(cd->mcodeptr++) = 0x66;
2288 emit_rex(0,(dreg),0,(reg));
2289 *(cd->mcodeptr++) = 0x0f;
2290 *(cd->mcodeptr++) = 0x2e;
2291 emit_reg((dreg),(reg));
2295 void emit_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2296 emit_rex(0,(dreg),0,(reg));
2297 *(cd->mcodeptr++) = 0x0f;
2298 *(cd->mcodeptr++) = 0x57;
2299 emit_reg((dreg),(reg));
2303 void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2304 emit_rex(0,(dreg),0,(basereg));
2305 *(cd->mcodeptr++) = 0x0f;
2306 *(cd->mcodeptr++) = 0x57;
2307 emit_membase((basereg),(disp),(dreg));
2311 void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2312 *(cd->mcodeptr++) = 0x66;
2313 emit_rex(0,(dreg),0,(reg));
2314 *(cd->mcodeptr++) = 0x0f;
2315 *(cd->mcodeptr++) = 0x57;
2316 emit_reg((dreg),(reg));
2320 void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2321 *(cd->mcodeptr++) = 0x66;
2322 emit_rex(0,(dreg),0,(basereg));
2323 *(cd->mcodeptr++) = 0x0f;
2324 *(cd->mcodeptr++) = 0x57;
2325 emit_membase((basereg),(disp),(dreg));
2329 /* system instructions ********************************************************/
2331 void emit_rdtsc(codegendata *cd)
2333 *(cd->mcodeptr++) = 0x0f;
2334 *(cd->mcodeptr++) = 0x31;
2339 * These are local overrides for various environment variables in Emacs.
2340 * Please do not remove this and leave it at the end of the file, where
2341 * Emacs will automagically detect them.
2342 * ---------------------------------------------------------------------
2345 * indent-tabs-mode: t