1 /* src/vm/jit/x86_64/emitfuncs.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: emitfuncs.c 4789 2006-04-18 20:34:52Z twisti $
40 #include "vm/jit/codegen-common.h"
41 #include "vm/jit/jit.h"
42 #include "vm/jit/x86_64/codegen.h"
43 #include "vm/jit/x86_64/emitfuncs.h"
46 /* code generation functions **************************************************/
48 /* emit_load_s1 ****************************************************************
50 Emits a possible load of the first source operand.
52 *******************************************************************************/
54 s4 emit_load_s1(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
60 /* get required compiler data */
64 if (src->flags & INMEMORY) {
67 disp = src->regoff * 8;
69 if (IS_FLT_DBL_TYPE(src->type)) {
70 M_DLD(tempreg, REG_SP, disp);
73 if (IS_INT_TYPE(src->type))
74 M_ILD(tempreg, REG_SP, disp);
76 M_LLD(tempreg, REG_SP, disp);
87 /* emit_load_s2 ****************************************************************
89 Emits a possible load of the second source operand.
91 *******************************************************************************/
93 s4 emit_load_s2(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
99 /* get required compiler data */
103 if (src->flags & INMEMORY) {
106 disp = src->regoff * 8;
108 if (IS_FLT_DBL_TYPE(src->type)) {
109 M_DLD(tempreg, REG_SP, disp);
112 if (IS_INT_TYPE(src->type))
113 M_ILD(tempreg, REG_SP, disp);
115 M_LLD(tempreg, REG_SP, disp);
126 /* emit_load_s3 ****************************************************************
128 Emits a possible load of the third source operand.
130 *******************************************************************************/
132 s4 emit_load_s3(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
138 /* get required compiler data */
142 if (src->flags & INMEMORY) {
145 disp = src->regoff * 8;
147 if (IS_FLT_DBL_TYPE(src->type)) {
148 M_DLD(tempreg, REG_SP, disp);
151 if (IS_INT_TYPE(src->type))
152 M_ILD(tempreg, REG_SP, disp);
154 M_LLD(tempreg, REG_SP, disp);
165 /* emit_store ******************************************************************
167 This function generates the code to store the result of an
168 operation back into a spilled pseudo-variable. If the
169 pseudo-variable has not been spilled in the first place, this
170 function will generate nothing.
172 *******************************************************************************/
174 void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
182 /* get required compiler data */
187 /* do we have to generate a conditional move? */
189 if ((iptr != NULL) && (iptr->opc & ICMD_CONDITION_MASK)) {
190 /* the passed register d is actually the source register */
194 /* Only pass the opcode to codegen_reg_of_var to get the real
195 destination register. */
197 opcode = iptr->opc & ICMD_OPCODE_MASK;
199 /* get the real destination register */
201 d = codegen_reg_of_var(rd, opcode, dst, REG_ITMP1);
203 /* and emit the conditional move */
205 emit_cmovxx(cd, iptr, s, d);
208 if (dst->flags & INMEMORY) {
211 disp = dst->regoff * 8;
213 if (IS_FLT_DBL_TYPE(dst->type))
214 M_DST(d, REG_SP, disp);
216 M_LST(d, REG_SP, disp);
221 /* emit_copy *******************************************************************
225 *******************************************************************************/
227 void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst)
233 /* get required compiler data */
238 if ((src->regoff != dst->regoff) ||
239 ((src->flags ^ dst->flags) & INMEMORY)) {
240 d = codegen_reg_of_var(rd, iptr->opc, dst, REG_IFTMP);
241 s1 = emit_load_s1(jd, iptr, src, d);
244 if (IS_FLT_DBL_TYPE(src->type))
250 emit_store(jd, iptr, dst, d);
255 void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d)
257 switch ((iptr->opc & ICMD_CONDITION_MASK) >> 8) {
280 /* code generation functions */
282 void x86_64_emit_ialu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
284 s4 s1 = src->prev->regoff;
286 s4 d = iptr->dst->regoff;
288 if (iptr->dst->flags & INMEMORY) {
289 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
291 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
292 x86_64_alul_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
294 } else if (s1 == d) {
295 x86_64_movl_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
296 x86_64_alul_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
299 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
300 x86_64_alul_membase_reg(cd, alu_op, REG_SP, s2 * 8, REG_ITMP1);
301 x86_64_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
304 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
306 x86_64_alul_reg_membase(cd, alu_op, s1, REG_SP, d * 8);
309 x86_64_movl_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
310 x86_64_alul_reg_reg(cd, alu_op, s1, REG_ITMP1);
311 x86_64_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
314 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
316 x86_64_alul_reg_membase(cd, alu_op, s2, REG_SP, d * 8);
319 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
320 x86_64_alul_reg_reg(cd, alu_op, s2, REG_ITMP1);
321 x86_64_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
325 x86_64_movl_reg_membase(cd, s1, REG_SP, d * 8);
326 x86_64_alul_reg_membase(cd, alu_op, s2, REG_SP, d * 8);
330 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
331 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, d);
332 x86_64_alul_membase_reg(cd, alu_op, REG_SP, s2 * 8, d);
334 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
336 x86_64_alul_membase_reg(cd, alu_op, REG_SP, s2 * 8, d);
338 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
340 x86_64_alul_membase_reg(cd, alu_op, REG_SP, s1 * 8, d);
344 x86_64_alul_reg_reg(cd, alu_op, s1, d);
348 x86_64_alul_reg_reg(cd, alu_op, s2, d);
355 void x86_64_emit_lalu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
357 s4 s1 = src->prev->regoff;
359 s4 d = iptr->dst->regoff;
361 if (iptr->dst->flags & INMEMORY) {
362 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
364 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
365 x86_64_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
367 } else if (s1 == d) {
368 x86_64_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
369 x86_64_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
372 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
373 x86_64_alu_membase_reg(cd, alu_op, REG_SP, s2 * 8, REG_ITMP1);
374 x86_64_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
377 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
379 x86_64_alu_reg_membase(cd, alu_op, s1, REG_SP, d * 8);
382 x86_64_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
383 x86_64_alu_reg_reg(cd, alu_op, s1, REG_ITMP1);
384 x86_64_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
387 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
389 x86_64_alu_reg_membase(cd, alu_op, s2, REG_SP, d * 8);
392 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
393 x86_64_alu_reg_reg(cd, alu_op, s2, REG_ITMP1);
394 x86_64_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
398 x86_64_mov_reg_membase(cd, s1, REG_SP, d * 8);
399 x86_64_alu_reg_membase(cd, alu_op, s2, REG_SP, d * 8);
403 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
404 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, d);
405 x86_64_alu_membase_reg(cd, alu_op, REG_SP, s2 * 8, d);
407 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
409 x86_64_alu_membase_reg(cd, alu_op, REG_SP, s2 * 8, d);
411 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
413 x86_64_alu_membase_reg(cd, alu_op, REG_SP, s1 * 8, d);
417 x86_64_alu_reg_reg(cd, alu_op, s1, d);
421 x86_64_alu_reg_reg(cd, alu_op, s2, d);
428 void x86_64_emit_ialuconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
431 s4 d = iptr->dst->regoff;
433 if (iptr->dst->flags & INMEMORY) {
434 if (src->flags & INMEMORY) {
436 x86_64_alul_imm_membase(cd, alu_op, iptr->val.i, REG_SP, d * 8);
439 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
440 x86_64_alul_imm_reg(cd, alu_op, iptr->val.i, REG_ITMP1);
441 x86_64_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
445 x86_64_movl_reg_membase(cd, s1, REG_SP, d * 8);
446 x86_64_alul_imm_membase(cd, alu_op, iptr->val.i, REG_SP, d * 8);
450 if (src->flags & INMEMORY) {
451 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, d);
452 x86_64_alul_imm_reg(cd, alu_op, iptr->val.i, d);
457 x86_64_alul_imm_reg(cd, alu_op, iptr->val.i, d);
459 /* lea addition optimization */
461 if ((alu_op == X86_64_ADD) && (s1 != d)) {
462 M_ILEA(s1, iptr->val.i, d);
466 x86_64_alul_imm_reg(cd, alu_op, iptr->val.i, d);
474 void x86_64_emit_laluconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
477 s4 d = iptr->dst->regoff;
479 if (iptr->dst->flags & INMEMORY) {
480 if (src->flags & INMEMORY) {
482 if (IS_IMM32(iptr->val.l)) {
483 x86_64_alu_imm_membase(cd, alu_op, iptr->val.l, REG_SP, d * 8);
486 x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
487 x86_64_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
491 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
493 if (IS_IMM32(iptr->val.l)) {
494 x86_64_alu_imm_reg(cd, alu_op, iptr->val.l, REG_ITMP1);
497 x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP2);
498 x86_64_alu_reg_reg(cd, alu_op, REG_ITMP2, REG_ITMP1);
500 x86_64_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
504 x86_64_mov_reg_membase(cd, s1, REG_SP, d * 8);
506 if (IS_IMM32(iptr->val.l)) {
507 x86_64_alu_imm_membase(cd, alu_op, iptr->val.l, REG_SP, d * 8);
510 x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
511 x86_64_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
517 if (src->flags & INMEMORY) {
518 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, d);
524 if (IS_IMM32(iptr->val.l)) {
525 x86_64_alu_imm_reg(cd, alu_op, iptr->val.l, d);
528 x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
529 x86_64_alu_reg_reg(cd, alu_op, REG_ITMP1, d);
532 if (src->flags & INMEMORY) {
533 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, d);
535 if (IS_IMM32(iptr->val.l)) {
536 x86_64_alu_imm_reg(cd, alu_op, iptr->val.l, d);
539 x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
540 x86_64_alu_reg_reg(cd, alu_op, REG_ITMP1, d);
544 if (IS_IMM32(iptr->val.l)) {
545 /* lea addition optimization */
547 if ((alu_op == X86_64_ADD) && (s1 != d)) {
548 M_LLEA(s1, iptr->val.l, d);
552 x86_64_alu_imm_reg(cd, alu_op, iptr->val.l, d);
557 x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
558 x86_64_alu_reg_reg(cd, alu_op, REG_ITMP1, d);
566 void x86_64_emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
568 s4 s1 = src->prev->regoff;
570 s4 d = iptr->dst->regoff;
573 M_INTMOVE(RCX, REG_ITMP1); /* save RCX */
575 if (iptr->dst->flags & INMEMORY) {
576 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
578 M_ILD(RCX, REG_SP, s2 * 8);
579 x86_64_shiftl_membase(cd, shift_op, REG_SP, d * 8);
582 M_ILD(RCX, REG_SP, s2 * 8);
583 M_ILD(REG_ITMP2, REG_SP, s1 * 8);
584 x86_64_shiftl_reg(cd, shift_op, REG_ITMP2);
585 M_IST(REG_ITMP2, REG_SP, d * 8);
588 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
589 /* s1 may be equal to RCX */
592 M_ILD(REG_ITMP1, REG_SP, s2 * 8);
593 M_IST(s1, REG_SP, d * 8);
594 M_INTMOVE(REG_ITMP1, RCX);
597 M_IST(s1, REG_SP, d * 8);
598 M_ILD(RCX, REG_SP, s2 * 8);
602 M_ILD(RCX, REG_SP, s2 * 8);
603 M_IST(s1, REG_SP, d * 8);
606 x86_64_shiftl_membase(cd, shift_op, REG_SP, d * 8);
608 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
611 x86_64_shiftl_membase(cd, shift_op, REG_SP, d * 8);
615 M_ILD(REG_ITMP2, REG_SP, s1 * 8);
616 x86_64_shiftl_reg(cd, shift_op, REG_ITMP2);
617 M_IST(REG_ITMP2, REG_SP, d * 8);
621 /* s1 may be equal to RCX */
622 M_IST(s1, REG_SP, d * 8);
624 x86_64_shiftl_membase(cd, shift_op, REG_SP, d * 8);
627 M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */
635 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
636 M_ILD(RCX, REG_SP, s2 * 8);
637 M_ILD(d, REG_SP, s1 * 8);
638 x86_64_shiftl_reg(cd, shift_op, d);
640 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
641 /* s1 may be equal to RCX */
643 M_ILD(RCX, REG_SP, s2 * 8);
644 x86_64_shiftl_reg(cd, shift_op, d);
646 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
648 M_ILD(d, REG_SP, s1 * 8);
649 x86_64_shiftl_reg(cd, shift_op, d);
652 /* s1 may be equal to RCX */
655 /* d cannot be used to backup s1 since this would
657 M_INTMOVE(s1, REG_ITMP3);
659 M_INTMOVE(REG_ITMP3, d);
667 /* d may be equal to s2 */
671 x86_64_shiftl_reg(cd, shift_op, d);
675 M_INTMOVE(REG_ITMP3, RCX);
677 M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */
682 void x86_64_emit_lshift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
684 s4 s1 = src->prev->regoff;
686 s4 d = iptr->dst->regoff;
689 M_INTMOVE(RCX, REG_ITMP1); /* save RCX */
691 if (iptr->dst->flags & INMEMORY) {
692 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
694 M_ILD(RCX, REG_SP, s2 * 8);
695 x86_64_shift_membase(cd, shift_op, REG_SP, d * 8);
698 M_ILD(RCX, REG_SP, s2 * 8);
699 M_LLD(REG_ITMP2, REG_SP, s1 * 8);
700 x86_64_shift_reg(cd, shift_op, REG_ITMP2);
701 M_LST(REG_ITMP2, REG_SP, d * 8);
704 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
705 /* s1 may be equal to RCX */
708 M_ILD(REG_ITMP1, REG_SP, s2 * 8);
709 M_LST(s1, REG_SP, d * 8);
710 M_INTMOVE(REG_ITMP1, RCX);
713 M_LST(s1, REG_SP, d * 8);
714 M_ILD(RCX, REG_SP, s2 * 8);
718 M_ILD(RCX, REG_SP, s2 * 8);
719 M_LST(s1, REG_SP, d * 8);
722 x86_64_shift_membase(cd, shift_op, REG_SP, d * 8);
724 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
727 x86_64_shift_membase(cd, shift_op, REG_SP, d * 8);
731 M_LLD(REG_ITMP2, REG_SP, s1 * 8);
732 x86_64_shift_reg(cd, shift_op, REG_ITMP2);
733 M_LST(REG_ITMP2, REG_SP, d * 8);
737 /* s1 may be equal to RCX */
738 M_LST(s1, REG_SP, d * 8);
740 x86_64_shift_membase(cd, shift_op, REG_SP, d * 8);
743 M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */
751 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
752 M_ILD(RCX, REG_SP, s2 * 8);
753 M_LLD(d, REG_SP, s1 * 8);
754 x86_64_shift_reg(cd, shift_op, d);
756 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
757 /* s1 may be equal to RCX */
759 M_ILD(RCX, REG_SP, s2 * 8);
760 x86_64_shift_reg(cd, shift_op, d);
762 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
764 M_LLD(d, REG_SP, s1 * 8);
765 x86_64_shift_reg(cd, shift_op, d);
768 /* s1 may be equal to RCX */
771 /* d cannot be used to backup s1 since this would
773 M_INTMOVE(s1, REG_ITMP3);
775 M_INTMOVE(REG_ITMP3, d);
783 /* d may be equal to s2 */
787 x86_64_shift_reg(cd, shift_op, d);
791 M_INTMOVE(REG_ITMP3, RCX);
793 M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */
798 void x86_64_emit_ishiftconst(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
801 s4 d = iptr->dst->regoff;
803 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
805 x86_64_shiftl_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8);
808 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
809 x86_64_shiftl_imm_reg(cd, shift_op, iptr->val.i, REG_ITMP1);
810 x86_64_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
813 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
814 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, d);
815 x86_64_shiftl_imm_reg(cd, shift_op, iptr->val.i, d);
817 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
818 x86_64_movl_reg_membase(cd, s1, REG_SP, d * 8);
819 x86_64_shiftl_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8);
823 x86_64_shiftl_imm_reg(cd, shift_op, iptr->val.i, d);
828 void x86_64_emit_lshiftconst(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
831 s4 d = iptr->dst->regoff;
833 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
835 x86_64_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8);
838 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
839 x86_64_shift_imm_reg(cd, shift_op, iptr->val.i, REG_ITMP1);
840 x86_64_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
843 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
844 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, d);
845 x86_64_shift_imm_reg(cd, shift_op, iptr->val.i, d);
847 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
848 x86_64_mov_reg_membase(cd, s1, REG_SP, d * 8);
849 x86_64_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8);
853 x86_64_shift_imm_reg(cd, shift_op, iptr->val.i, d);
858 void x86_64_emit_ifcc(codegendata *cd, s4 if_op, stackptr src, instruction *iptr)
860 if (src->flags & INMEMORY)
861 M_ICMP_IMM_MEMBASE(iptr->val.i, REG_SP, src->regoff * 8);
863 if (iptr->val.i == 0)
864 M_ITEST(src->regoff);
866 M_ICMP_IMM(iptr->val.i, src->regoff);
869 /* If the conditional branch is part of an if-converted block,
870 don't generate the actual branch. */
872 if ((iptr->opc & ICMD_CONDITION_MASK) == 0) {
873 x86_64_jcc(cd, if_op, 0);
874 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
879 void x86_64_emit_if_lcc(codegendata *cd, s4 if_op, stackptr src, instruction *iptr)
883 if (src->flags & INMEMORY) {
884 if (IS_IMM32(iptr->val.l)) {
885 x86_64_alu_imm_membase(cd, X86_64_CMP, iptr->val.l, REG_SP, s1 * 8);
888 x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
889 x86_64_alu_reg_membase(cd, X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
893 if (iptr->val.l == 0) {
894 x86_64_test_reg_reg(cd, s1, s1);
897 if (IS_IMM32(iptr->val.l)) {
898 x86_64_alu_imm_reg(cd, X86_64_CMP, iptr->val.l, s1);
901 x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
902 x86_64_alu_reg_reg(cd, X86_64_CMP, REG_ITMP1, s1);
906 x86_64_jcc(cd, if_op, 0);
907 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
911 /* emit_if_icmpcc **************************************************************
913 Generate ICMD_IF_ICMPxx instructions.
915 *******************************************************************************/
917 void x86_64_emit_if_icmpcc(codegendata *cd, s4 if_op, stackptr src,
920 s4 s1 = src->prev->regoff;
923 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
924 x86_64_movl_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
925 x86_64_alul_reg_membase(cd, X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
927 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
928 x86_64_alul_membase_reg(cd, X86_64_CMP, REG_SP, s2 * 8, s1);
930 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
931 x86_64_alul_reg_membase(cd, X86_64_CMP, s2, REG_SP, s1 * 8);
934 x86_64_alul_reg_reg(cd, X86_64_CMP, s2, s1);
938 /* If the conditional branch is part of an if-converted block,
939 don't generate the actual branch. */
941 if ((iptr->opc & ICMD_CONDITION_MASK) == 0) {
942 x86_64_jcc(cd, if_op, 0);
943 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
948 void x86_64_emit_if_lcmpcc(codegendata *cd, s4 if_op, stackptr src, instruction *iptr)
950 s4 s1 = src->prev->regoff;
953 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
954 x86_64_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
955 x86_64_alu_reg_membase(cd, X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
957 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
958 x86_64_alu_membase_reg(cd, X86_64_CMP, REG_SP, s2 * 8, s1);
960 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
961 x86_64_alu_reg_membase(cd, X86_64_CMP, s2, REG_SP, s1 * 8);
964 x86_64_alu_reg_reg(cd, X86_64_CMP, s2, s1);
966 x86_64_jcc(cd, if_op, 0);
967 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
971 /* low-level code emitter functions *******************************************/
973 void x86_64_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
974 x86_64_emit_rex(1,(reg),0,(dreg));
975 *(cd->mcodeptr++) = 0x89;
976 x86_64_emit_reg((reg),(dreg));
980 void x86_64_mov_imm_reg(codegendata *cd, s8 imm, s8 reg) {
981 x86_64_emit_rex(1,0,0,(reg));
982 *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
983 x86_64_emit_imm64((imm));
987 void x86_64_movl_imm_reg(codegendata *cd, s8 imm, s8 reg) {
988 x86_64_emit_rex(0,0,0,(reg));
989 *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
990 x86_64_emit_imm32((imm));
994 void x86_64_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
995 x86_64_emit_rex(1,(reg),0,(basereg));
996 *(cd->mcodeptr++) = 0x8b;
997 x86_64_emit_membase((basereg),(disp),(reg));
1002 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
1003 * constant membase immediate length of 32bit
1005 void x86_64_mov_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1006 x86_64_emit_rex(1,(reg),0,(basereg));
1007 *(cd->mcodeptr++) = 0x8b;
1008 x86_64_emit_membase32((basereg),(disp),(reg));
1012 void x86_64_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
1014 x86_64_emit_rex(0,(reg),0,(basereg));
1015 *(cd->mcodeptr++) = 0x8b;
1016 x86_64_emit_membase((basereg),(disp),(reg));
1020 /* ATTENTION: Always emit a REX byte, because the instruction size can
1021 be smaller when all register indexes are smaller than 7. */
1022 void x86_64_movl_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
1024 x86_64_emit_byte_rex((reg),0,(basereg));
1025 *(cd->mcodeptr++) = 0x8b;
1026 x86_64_emit_membase32((basereg),(disp),(reg));
1030 void x86_64_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1031 x86_64_emit_rex(1,(reg),0,(basereg));
1032 *(cd->mcodeptr++) = 0x89;
1033 x86_64_emit_membase((basereg),(disp),(reg));
1037 void x86_64_mov_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1038 x86_64_emit_rex(1,(reg),0,(basereg));
1039 *(cd->mcodeptr++) = 0x89;
1040 x86_64_emit_membase32((basereg),(disp),(reg));
1044 void x86_64_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1045 x86_64_emit_rex(0,(reg),0,(basereg));
1046 *(cd->mcodeptr++) = 0x89;
1047 x86_64_emit_membase((basereg),(disp),(reg));
1051 /* Always emit a REX byte, because the instruction size can be smaller when */
1052 /* all register indexes are smaller than 7. */
1053 void x86_64_movl_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1054 x86_64_emit_byte_rex((reg),0,(basereg));
1055 *(cd->mcodeptr++) = 0x89;
1056 x86_64_emit_membase32((basereg),(disp),(reg));
1060 void x86_64_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1061 x86_64_emit_rex(1,(reg),(indexreg),(basereg));
1062 *(cd->mcodeptr++) = 0x8b;
1063 x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1067 void x86_64_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1068 x86_64_emit_rex(0,(reg),(indexreg),(basereg));
1069 *(cd->mcodeptr++) = 0x8b;
1070 x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1074 void x86_64_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1075 x86_64_emit_rex(1,(reg),(indexreg),(basereg));
1076 *(cd->mcodeptr++) = 0x89;
1077 x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1081 void x86_64_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1082 x86_64_emit_rex(0,(reg),(indexreg),(basereg));
1083 *(cd->mcodeptr++) = 0x89;
1084 x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1088 void x86_64_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1089 *(cd->mcodeptr++) = 0x66;
1090 x86_64_emit_rex(0,(reg),(indexreg),(basereg));
1091 *(cd->mcodeptr++) = 0x89;
1092 x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1096 void x86_64_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1097 x86_64_emit_byte_rex((reg),(indexreg),(basereg));
1098 *(cd->mcodeptr++) = 0x88;
1099 x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1103 void x86_64_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1104 x86_64_emit_rex(1,0,0,(basereg));
1105 *(cd->mcodeptr++) = 0xc7;
1106 x86_64_emit_membase((basereg),(disp),0);
1107 x86_64_emit_imm32((imm));
1111 void x86_64_mov_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1112 x86_64_emit_rex(1,0,0,(basereg));
1113 *(cd->mcodeptr++) = 0xc7;
1114 x86_64_emit_membase32((basereg),(disp),0);
1115 x86_64_emit_imm32((imm));
1119 void x86_64_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1120 x86_64_emit_rex(0,0,0,(basereg));
1121 *(cd->mcodeptr++) = 0xc7;
1122 x86_64_emit_membase((basereg),(disp),0);
1123 x86_64_emit_imm32((imm));
1127 /* Always emit a REX byte, because the instruction size can be smaller when */
1128 /* all register indexes are smaller than 7. */
1129 void x86_64_movl_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1130 x86_64_emit_byte_rex(0,0,(basereg));
1131 *(cd->mcodeptr++) = 0xc7;
1132 x86_64_emit_membase32((basereg),(disp),0);
1133 x86_64_emit_imm32((imm));
1137 void x86_64_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1138 x86_64_emit_rex(1,(dreg),0,(reg));
1139 *(cd->mcodeptr++) = 0x0f;
1140 *(cd->mcodeptr++) = 0xbe;
1141 /* XXX: why do reg and dreg have to be exchanged */
1142 x86_64_emit_reg((dreg),(reg));
1146 void x86_64_movsbq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1147 x86_64_emit_rex(1,(dreg),0,(basereg));
1148 *(cd->mcodeptr++) = 0x0f;
1149 *(cd->mcodeptr++) = 0xbe;
1150 x86_64_emit_membase((basereg),(disp),(dreg));
1154 void x86_64_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1155 x86_64_emit_rex(1,(dreg),0,(reg));
1156 *(cd->mcodeptr++) = 0x0f;
1157 *(cd->mcodeptr++) = 0xbf;
1158 /* XXX: why do reg and dreg have to be exchanged */
1159 x86_64_emit_reg((dreg),(reg));
1163 void x86_64_movswq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1164 x86_64_emit_rex(1,(dreg),0,(basereg));
1165 *(cd->mcodeptr++) = 0x0f;
1166 *(cd->mcodeptr++) = 0xbf;
1167 x86_64_emit_membase((basereg),(disp),(dreg));
1171 void x86_64_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1172 x86_64_emit_rex(1,(dreg),0,(reg));
1173 *(cd->mcodeptr++) = 0x63;
1174 /* XXX: why do reg and dreg have to be exchanged */
1175 x86_64_emit_reg((dreg),(reg));
1179 void x86_64_movslq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1180 x86_64_emit_rex(1,(dreg),0,(basereg));
1181 *(cd->mcodeptr++) = 0x63;
1182 x86_64_emit_membase((basereg),(disp),(dreg));
1186 void x86_64_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1187 x86_64_emit_rex(1,(dreg),0,(reg));
1188 *(cd->mcodeptr++) = 0x0f;
1189 *(cd->mcodeptr++) = 0xb7;
1190 /* XXX: why do reg and dreg have to be exchanged */
1191 x86_64_emit_reg((dreg),(reg));
1195 void x86_64_movzwq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1196 x86_64_emit_rex(1,(dreg),0,(basereg));
1197 *(cd->mcodeptr++) = 0x0f;
1198 *(cd->mcodeptr++) = 0xb7;
1199 x86_64_emit_membase((basereg),(disp),(dreg));
1203 void x86_64_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1204 x86_64_emit_rex(1,(reg),(indexreg),(basereg));
1205 *(cd->mcodeptr++) = 0x0f;
1206 *(cd->mcodeptr++) = 0xbf;
1207 x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1211 void x86_64_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1212 x86_64_emit_rex(1,(reg),(indexreg),(basereg));
1213 *(cd->mcodeptr++) = 0x0f;
1214 *(cd->mcodeptr++) = 0xbe;
1215 x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1219 void x86_64_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1220 x86_64_emit_rex(1,(reg),(indexreg),(basereg));
1221 *(cd->mcodeptr++) = 0x0f;
1222 *(cd->mcodeptr++) = 0xb7;
1223 x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1227 void x86_64_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1229 x86_64_emit_rex(1,0,(indexreg),(basereg));
1230 *(cd->mcodeptr++) = 0xc7;
1231 x86_64_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1232 x86_64_emit_imm32((imm));
1236 void x86_64_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1238 x86_64_emit_rex(0,0,(indexreg),(basereg));
1239 *(cd->mcodeptr++) = 0xc7;
1240 x86_64_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1241 x86_64_emit_imm32((imm));
1245 void x86_64_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1247 *(cd->mcodeptr++) = 0x66;
1248 x86_64_emit_rex(0,0,(indexreg),(basereg));
1249 *(cd->mcodeptr++) = 0xc7;
1250 x86_64_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1251 x86_64_emit_imm16((imm));
1255 void x86_64_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1257 x86_64_emit_rex(0,0,(indexreg),(basereg));
1258 *(cd->mcodeptr++) = 0xc6;
1259 x86_64_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1260 x86_64_emit_imm8((imm));
1267 void x86_64_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg) {
1268 x86_64_emit_rex(1,(reg),0,(dreg));
1269 *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1270 x86_64_emit_reg((reg),(dreg));
1274 void x86_64_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg) {
1275 x86_64_emit_rex(0,(reg),0,(dreg));
1276 *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1277 x86_64_emit_reg((reg),(dreg));
1281 void x86_64_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp) {
1282 x86_64_emit_rex(1,(reg),0,(basereg));
1283 *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1284 x86_64_emit_membase((basereg),(disp),(reg));
1288 void x86_64_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp) {
1289 x86_64_emit_rex(0,(reg),0,(basereg));
1290 *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1291 x86_64_emit_membase((basereg),(disp),(reg));
1295 void x86_64_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg) {
1296 x86_64_emit_rex(1,(reg),0,(basereg));
1297 *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1298 x86_64_emit_membase((basereg),(disp),(reg));
1302 void x86_64_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg) {
1303 x86_64_emit_rex(0,(reg),0,(basereg));
1304 *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1305 x86_64_emit_membase((basereg),(disp),(reg));
1309 void x86_64_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1311 x86_64_emit_rex(1,0,0,(dreg));
1312 *(cd->mcodeptr++) = 0x83;
1313 x86_64_emit_reg((opc),(dreg));
1314 x86_64_emit_imm8((imm));
1316 x86_64_emit_rex(1,0,0,(dreg));
1317 *(cd->mcodeptr++) = 0x81;
1318 x86_64_emit_reg((opc),(dreg));
1319 x86_64_emit_imm32((imm));
1324 void x86_64_alu_imm32_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1325 x86_64_emit_rex(1,0,0,(dreg));
1326 *(cd->mcodeptr++) = 0x81;
1327 x86_64_emit_reg((opc),(dreg));
1328 x86_64_emit_imm32((imm));
1332 void x86_64_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1334 x86_64_emit_rex(0,0,0,(dreg));
1335 *(cd->mcodeptr++) = 0x83;
1336 x86_64_emit_reg((opc),(dreg));
1337 x86_64_emit_imm8((imm));
1339 x86_64_emit_rex(0,0,0,(dreg));
1340 *(cd->mcodeptr++) = 0x81;
1341 x86_64_emit_reg((opc),(dreg));
1342 x86_64_emit_imm32((imm));
1347 void x86_64_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1349 x86_64_emit_rex(1,(basereg),0,0);
1350 *(cd->mcodeptr++) = 0x83;
1351 x86_64_emit_membase((basereg),(disp),(opc));
1352 x86_64_emit_imm8((imm));
1354 x86_64_emit_rex(1,(basereg),0,0);
1355 *(cd->mcodeptr++) = 0x81;
1356 x86_64_emit_membase((basereg),(disp),(opc));
1357 x86_64_emit_imm32((imm));
1362 void x86_64_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1364 x86_64_emit_rex(0,(basereg),0,0);
1365 *(cd->mcodeptr++) = 0x83;
1366 x86_64_emit_membase((basereg),(disp),(opc));
1367 x86_64_emit_imm8((imm));
1369 x86_64_emit_rex(0,(basereg),0,0);
1370 *(cd->mcodeptr++) = 0x81;
1371 x86_64_emit_membase((basereg),(disp),(opc));
1372 x86_64_emit_imm32((imm));
1377 void x86_64_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1378 x86_64_emit_rex(1,(reg),0,(dreg));
1379 *(cd->mcodeptr++) = 0x85;
1380 x86_64_emit_reg((reg),(dreg));
1384 void x86_64_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1385 x86_64_emit_rex(0,(reg),0,(dreg));
1386 *(cd->mcodeptr++) = 0x85;
1387 x86_64_emit_reg((reg),(dreg));
1391 void x86_64_test_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1392 *(cd->mcodeptr++) = 0xf7;
1393 x86_64_emit_reg(0,(reg));
1394 x86_64_emit_imm32((imm));
1398 void x86_64_testw_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1399 *(cd->mcodeptr++) = 0x66;
1400 *(cd->mcodeptr++) = 0xf7;
1401 x86_64_emit_reg(0,(reg));
1402 x86_64_emit_imm16((imm));
1406 void x86_64_testb_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1407 *(cd->mcodeptr++) = 0xf6;
1408 x86_64_emit_reg(0,(reg));
1409 x86_64_emit_imm8((imm));
1413 void x86_64_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1414 x86_64_emit_rex(1,(reg),0,(basereg));
1415 *(cd->mcodeptr++) = 0x8d;
1416 x86_64_emit_membase((basereg),(disp),(reg));
1420 void x86_64_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1421 x86_64_emit_rex(0,(reg),0,(basereg));
1422 *(cd->mcodeptr++) = 0x8d;
1423 x86_64_emit_membase((basereg),(disp),(reg));
1429 * inc, dec operations
1431 void x86_64_inc_reg(codegendata *cd, s8 reg) {
1432 x86_64_emit_rex(1,0,0,(reg));
1433 *(cd->mcodeptr++) = 0xff;
1434 x86_64_emit_reg(0,(reg));
1438 void x86_64_incl_reg(codegendata *cd, s8 reg) {
1439 x86_64_emit_rex(0,0,0,(reg));
1440 *(cd->mcodeptr++) = 0xff;
1441 x86_64_emit_reg(0,(reg));
1445 void x86_64_inc_membase(codegendata *cd, s8 basereg, s8 disp)
1447 x86_64_emit_rex(1,0,0,(basereg));
1448 *(cd->mcodeptr++) = 0xff;
1449 x86_64_emit_membase((basereg),(disp),0);
1453 void x86_64_incl_membase(codegendata *cd, s8 basereg, s8 disp)
1455 x86_64_emit_rex(0,0,0,(basereg));
1456 *(cd->mcodeptr++) = 0xff;
1457 x86_64_emit_membase((basereg),(disp),0);
1461 void x86_64_dec_reg(codegendata *cd, s8 reg) {
1462 x86_64_emit_rex(1,0,0,(reg));
1463 *(cd->mcodeptr++) = 0xff;
1464 x86_64_emit_reg(1,(reg));
1468 void x86_64_decl_reg(codegendata *cd, s8 reg) {
1469 x86_64_emit_rex(0,0,0,(reg));
1470 *(cd->mcodeptr++) = 0xff;
1471 x86_64_emit_reg(1,(reg));
1475 void x86_64_dec_membase(codegendata *cd, s8 basereg, s8 disp) {
1476 x86_64_emit_rex(1,(basereg),0,0);
1477 *(cd->mcodeptr++) = 0xff;
1478 x86_64_emit_membase((basereg),(disp),1);
1482 void x86_64_decl_membase(codegendata *cd, s8 basereg, s8 disp) {
1483 x86_64_emit_rex(0,(basereg),0,0);
1484 *(cd->mcodeptr++) = 0xff;
1485 x86_64_emit_membase((basereg),(disp),1);
1491 void x86_64_cltd(codegendata *cd) {
1492 *(cd->mcodeptr++) = 0x99;
1496 void x86_64_cqto(codegendata *cd) {
1497 x86_64_emit_rex(1,0,0,0);
1498 *(cd->mcodeptr++) = 0x99;
1503 void x86_64_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1504 x86_64_emit_rex(1,(dreg),0,(reg));
1505 *(cd->mcodeptr++) = 0x0f;
1506 *(cd->mcodeptr++) = 0xaf;
1507 x86_64_emit_reg((dreg),(reg));
1511 void x86_64_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1512 x86_64_emit_rex(0,(dreg),0,(reg));
1513 *(cd->mcodeptr++) = 0x0f;
1514 *(cd->mcodeptr++) = 0xaf;
1515 x86_64_emit_reg((dreg),(reg));
1519 void x86_64_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1520 x86_64_emit_rex(1,(dreg),0,(basereg));
1521 *(cd->mcodeptr++) = 0x0f;
1522 *(cd->mcodeptr++) = 0xaf;
1523 x86_64_emit_membase((basereg),(disp),(dreg));
1527 void x86_64_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1528 x86_64_emit_rex(0,(dreg),0,(basereg));
1529 *(cd->mcodeptr++) = 0x0f;
1530 *(cd->mcodeptr++) = 0xaf;
1531 x86_64_emit_membase((basereg),(disp),(dreg));
1535 void x86_64_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg) {
1536 if (IS_IMM8((imm))) {
1537 x86_64_emit_rex(1,0,0,(dreg));
1538 *(cd->mcodeptr++) = 0x6b;
1539 x86_64_emit_reg(0,(dreg));
1540 x86_64_emit_imm8((imm));
1542 x86_64_emit_rex(1,0,0,(dreg));
1543 *(cd->mcodeptr++) = 0x69;
1544 x86_64_emit_reg(0,(dreg));
1545 x86_64_emit_imm32((imm));
1550 void x86_64_imul_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1551 if (IS_IMM8((imm))) {
1552 x86_64_emit_rex(1,(dreg),0,(reg));
1553 *(cd->mcodeptr++) = 0x6b;
1554 x86_64_emit_reg((dreg),(reg));
1555 x86_64_emit_imm8((imm));
1557 x86_64_emit_rex(1,(dreg),0,(reg));
1558 *(cd->mcodeptr++) = 0x69;
1559 x86_64_emit_reg((dreg),(reg));
1560 x86_64_emit_imm32((imm));
1565 void x86_64_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1566 if (IS_IMM8((imm))) {
1567 x86_64_emit_rex(0,(dreg),0,(reg));
1568 *(cd->mcodeptr++) = 0x6b;
1569 x86_64_emit_reg((dreg),(reg));
1570 x86_64_emit_imm8((imm));
1572 x86_64_emit_rex(0,(dreg),0,(reg));
1573 *(cd->mcodeptr++) = 0x69;
1574 x86_64_emit_reg((dreg),(reg));
1575 x86_64_emit_imm32((imm));
1580 void x86_64_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1581 if (IS_IMM8((imm))) {
1582 x86_64_emit_rex(1,(dreg),0,(basereg));
1583 *(cd->mcodeptr++) = 0x6b;
1584 x86_64_emit_membase((basereg),(disp),(dreg));
1585 x86_64_emit_imm8((imm));
1587 x86_64_emit_rex(1,(dreg),0,(basereg));
1588 *(cd->mcodeptr++) = 0x69;
1589 x86_64_emit_membase((basereg),(disp),(dreg));
1590 x86_64_emit_imm32((imm));
1595 void x86_64_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1596 if (IS_IMM8((imm))) {
1597 x86_64_emit_rex(0,(dreg),0,(basereg));
1598 *(cd->mcodeptr++) = 0x6b;
1599 x86_64_emit_membase((basereg),(disp),(dreg));
1600 x86_64_emit_imm8((imm));
1602 x86_64_emit_rex(0,(dreg),0,(basereg));
1603 *(cd->mcodeptr++) = 0x69;
1604 x86_64_emit_membase((basereg),(disp),(dreg));
1605 x86_64_emit_imm32((imm));
1610 void x86_64_idiv_reg(codegendata *cd, s8 reg) {
1611 x86_64_emit_rex(1,0,0,(reg));
1612 *(cd->mcodeptr++) = 0xf7;
1613 x86_64_emit_reg(7,(reg));
1617 void x86_64_idivl_reg(codegendata *cd, s8 reg) {
1618 x86_64_emit_rex(0,0,0,(reg));
1619 *(cd->mcodeptr++) = 0xf7;
1620 x86_64_emit_reg(7,(reg));
1625 void x86_64_ret(codegendata *cd) {
1626 *(cd->mcodeptr++) = 0xc3;
1634 void x86_64_shift_reg(codegendata *cd, s8 opc, s8 reg) {
1635 x86_64_emit_rex(1,0,0,(reg));
1636 *(cd->mcodeptr++) = 0xd3;
1637 x86_64_emit_reg((opc),(reg));
1641 void x86_64_shiftl_reg(codegendata *cd, s8 opc, s8 reg) {
1642 x86_64_emit_rex(0,0,0,(reg));
1643 *(cd->mcodeptr++) = 0xd3;
1644 x86_64_emit_reg((opc),(reg));
1648 void x86_64_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1649 x86_64_emit_rex(1,0,0,(basereg));
1650 *(cd->mcodeptr++) = 0xd3;
1651 x86_64_emit_membase((basereg),(disp),(opc));
1655 void x86_64_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1656 x86_64_emit_rex(0,0,0,(basereg));
1657 *(cd->mcodeptr++) = 0xd3;
1658 x86_64_emit_membase((basereg),(disp),(opc));
1662 void x86_64_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1664 x86_64_emit_rex(1,0,0,(dreg));
1665 *(cd->mcodeptr++) = 0xd1;
1666 x86_64_emit_reg((opc),(dreg));
1668 x86_64_emit_rex(1,0,0,(dreg));
1669 *(cd->mcodeptr++) = 0xc1;
1670 x86_64_emit_reg((opc),(dreg));
1671 x86_64_emit_imm8((imm));
1676 void x86_64_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1678 x86_64_emit_rex(0,0,0,(dreg));
1679 *(cd->mcodeptr++) = 0xd1;
1680 x86_64_emit_reg((opc),(dreg));
1682 x86_64_emit_rex(0,0,0,(dreg));
1683 *(cd->mcodeptr++) = 0xc1;
1684 x86_64_emit_reg((opc),(dreg));
1685 x86_64_emit_imm8((imm));
1690 void x86_64_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1692 x86_64_emit_rex(1,0,0,(basereg));
1693 *(cd->mcodeptr++) = 0xd1;
1694 x86_64_emit_membase((basereg),(disp),(opc));
1696 x86_64_emit_rex(1,0,0,(basereg));
1697 *(cd->mcodeptr++) = 0xc1;
1698 x86_64_emit_membase((basereg),(disp),(opc));
1699 x86_64_emit_imm8((imm));
1704 void x86_64_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1706 x86_64_emit_rex(0,0,0,(basereg));
1707 *(cd->mcodeptr++) = 0xd1;
1708 x86_64_emit_membase((basereg),(disp),(opc));
1710 x86_64_emit_rex(0,0,0,(basereg));
1711 *(cd->mcodeptr++) = 0xc1;
1712 x86_64_emit_membase((basereg),(disp),(opc));
1713 x86_64_emit_imm8((imm));
1722 void x86_64_jmp_imm(codegendata *cd, s8 imm) {
1723 *(cd->mcodeptr++) = 0xe9;
1724 x86_64_emit_imm32((imm));
1728 void x86_64_jmp_reg(codegendata *cd, s8 reg) {
1729 x86_64_emit_rex(0,0,0,(reg));
1730 *(cd->mcodeptr++) = 0xff;
1731 x86_64_emit_reg(4,(reg));
1735 void x86_64_jcc(codegendata *cd, s8 opc, s8 imm) {
1736 *(cd->mcodeptr++) = 0x0f;
1737 *(cd->mcodeptr++) = (0x80 + (opc));
1738 x86_64_emit_imm32((imm));
1744 * conditional set and move operations
1747 /* we need the rex byte to get all low bytes */
1748 void x86_64_setcc_reg(codegendata *cd, s8 opc, s8 reg) {
1749 *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
1750 *(cd->mcodeptr++) = 0x0f;
1751 *(cd->mcodeptr++) = (0x90 + (opc));
1752 x86_64_emit_reg(0,(reg));
1756 /* we need the rex byte to get all low bytes */
1757 void x86_64_setcc_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1758 *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
1759 *(cd->mcodeptr++) = 0x0f;
1760 *(cd->mcodeptr++) = (0x90 + (opc));
1761 x86_64_emit_membase((basereg),(disp),0);
1765 void x86_64_cmovcc_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1767 x86_64_emit_rex(1,(dreg),0,(reg));
1768 *(cd->mcodeptr++) = 0x0f;
1769 *(cd->mcodeptr++) = (0x40 + (opc));
1770 x86_64_emit_reg((dreg),(reg));
1774 void x86_64_cmovccl_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1776 x86_64_emit_rex(0,(dreg),0,(reg));
1777 *(cd->mcodeptr++) = 0x0f;
1778 *(cd->mcodeptr++) = (0x40 + (opc));
1779 x86_64_emit_reg((dreg),(reg));
1784 void x86_64_neg_reg(codegendata *cd, s8 reg) {
1785 x86_64_emit_rex(1,0,0,(reg));
1786 *(cd->mcodeptr++) = 0xf7;
1787 x86_64_emit_reg(3,(reg));
1791 void x86_64_negl_reg(codegendata *cd, s8 reg) {
1792 x86_64_emit_rex(0,0,0,(reg));
1793 *(cd->mcodeptr++) = 0xf7;
1794 x86_64_emit_reg(3,(reg));
1798 void x86_64_neg_membase(codegendata *cd, s8 basereg, s8 disp) {
1799 x86_64_emit_rex(1,0,0,(basereg));
1800 *(cd->mcodeptr++) = 0xf7;
1801 x86_64_emit_membase((basereg),(disp),3);
1805 void x86_64_negl_membase(codegendata *cd, s8 basereg, s8 disp) {
1806 x86_64_emit_rex(0,0,0,(basereg));
1807 *(cd->mcodeptr++) = 0xf7;
1808 x86_64_emit_membase((basereg),(disp),3);
1812 void x86_64_push_reg(codegendata *cd, s8 reg) {
1813 x86_64_emit_rex(0,0,0,(reg));
1814 *(cd->mcodeptr++) = 0x50 + (0x07 & (reg));
1818 void x86_64_push_imm(codegendata *cd, s8 imm) {
1819 *(cd->mcodeptr++) = 0x68;
1820 x86_64_emit_imm32((imm));
1824 void x86_64_pop_reg(codegendata *cd, s8 reg) {
1825 x86_64_emit_rex(0,0,0,(reg));
1826 *(cd->mcodeptr++) = 0x58 + (0x07 & (reg));
1830 void x86_64_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1831 x86_64_emit_rex(1,(reg),0,(dreg));
1832 *(cd->mcodeptr++) = 0x87;
1833 x86_64_emit_reg((reg),(dreg));
1837 void x86_64_nop(codegendata *cd) {
1838 *(cd->mcodeptr++) = 0x90;
1846 void x86_64_call_reg(codegendata *cd, s8 reg) {
1847 x86_64_emit_rex(1,0,0,(reg));
1848 *(cd->mcodeptr++) = 0xff;
1849 x86_64_emit_reg(2,(reg));
1853 void x86_64_call_imm(codegendata *cd, s8 imm) {
1854 *(cd->mcodeptr++) = 0xe8;
1855 x86_64_emit_imm32((imm));
1859 void x86_64_call_mem(codegendata *cd, ptrint mem)
1861 *(cd->mcodeptr++) = 0xff;
1862 x86_64_emit_mem(2,(mem));
1868 * floating point instructions (SSE2)
1870 void x86_64_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1871 *(cd->mcodeptr++) = 0xf2;
1872 x86_64_emit_rex(0,(dreg),0,(reg));
1873 *(cd->mcodeptr++) = 0x0f;
1874 *(cd->mcodeptr++) = 0x58;
1875 x86_64_emit_reg((dreg),(reg));
1879 void x86_64_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1880 *(cd->mcodeptr++) = 0xf3;
1881 x86_64_emit_rex(0,(dreg),0,(reg));
1882 *(cd->mcodeptr++) = 0x0f;
1883 *(cd->mcodeptr++) = 0x58;
1884 x86_64_emit_reg((dreg),(reg));
1888 void x86_64_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1889 *(cd->mcodeptr++) = 0xf3;
1890 x86_64_emit_rex(1,(dreg),0,(reg));
1891 *(cd->mcodeptr++) = 0x0f;
1892 *(cd->mcodeptr++) = 0x2a;
1893 x86_64_emit_reg((dreg),(reg));
1897 void x86_64_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1898 *(cd->mcodeptr++) = 0xf3;
1899 x86_64_emit_rex(0,(dreg),0,(reg));
1900 *(cd->mcodeptr++) = 0x0f;
1901 *(cd->mcodeptr++) = 0x2a;
1902 x86_64_emit_reg((dreg),(reg));
1906 void x86_64_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1907 *(cd->mcodeptr++) = 0xf2;
1908 x86_64_emit_rex(1,(dreg),0,(reg));
1909 *(cd->mcodeptr++) = 0x0f;
1910 *(cd->mcodeptr++) = 0x2a;
1911 x86_64_emit_reg((dreg),(reg));
1915 void x86_64_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1916 *(cd->mcodeptr++) = 0xf2;
1917 x86_64_emit_rex(0,(dreg),0,(reg));
1918 *(cd->mcodeptr++) = 0x0f;
1919 *(cd->mcodeptr++) = 0x2a;
1920 x86_64_emit_reg((dreg),(reg));
1924 void x86_64_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1925 *(cd->mcodeptr++) = 0xf3;
1926 x86_64_emit_rex(0,(dreg),0,(reg));
1927 *(cd->mcodeptr++) = 0x0f;
1928 *(cd->mcodeptr++) = 0x5a;
1929 x86_64_emit_reg((dreg),(reg));
1933 void x86_64_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1934 *(cd->mcodeptr++) = 0xf2;
1935 x86_64_emit_rex(0,(dreg),0,(reg));
1936 *(cd->mcodeptr++) = 0x0f;
1937 *(cd->mcodeptr++) = 0x5a;
1938 x86_64_emit_reg((dreg),(reg));
1942 void x86_64_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1943 *(cd->mcodeptr++) = 0xf3;
1944 x86_64_emit_rex(1,(dreg),0,(reg));
1945 *(cd->mcodeptr++) = 0x0f;
1946 *(cd->mcodeptr++) = 0x2c;
1947 x86_64_emit_reg((dreg),(reg));
1951 void x86_64_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1952 *(cd->mcodeptr++) = 0xf3;
1953 x86_64_emit_rex(0,(dreg),0,(reg));
1954 *(cd->mcodeptr++) = 0x0f;
1955 *(cd->mcodeptr++) = 0x2c;
1956 x86_64_emit_reg((dreg),(reg));
1960 void x86_64_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1961 *(cd->mcodeptr++) = 0xf2;
1962 x86_64_emit_rex(1,(dreg),0,(reg));
1963 *(cd->mcodeptr++) = 0x0f;
1964 *(cd->mcodeptr++) = 0x2c;
1965 x86_64_emit_reg((dreg),(reg));
1969 void x86_64_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1970 *(cd->mcodeptr++) = 0xf2;
1971 x86_64_emit_rex(0,(dreg),0,(reg));
1972 *(cd->mcodeptr++) = 0x0f;
1973 *(cd->mcodeptr++) = 0x2c;
1974 x86_64_emit_reg((dreg),(reg));
1978 void x86_64_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1979 *(cd->mcodeptr++) = 0xf3;
1980 x86_64_emit_rex(0,(dreg),0,(reg));
1981 *(cd->mcodeptr++) = 0x0f;
1982 *(cd->mcodeptr++) = 0x5e;
1983 x86_64_emit_reg((dreg),(reg));
1987 void x86_64_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1988 *(cd->mcodeptr++) = 0xf2;
1989 x86_64_emit_rex(0,(dreg),0,(reg));
1990 *(cd->mcodeptr++) = 0x0f;
1991 *(cd->mcodeptr++) = 0x5e;
1992 x86_64_emit_reg((dreg),(reg));
1996 void x86_64_movd_reg_freg(codegendata *cd, s8 reg, s8 freg) {
1997 *(cd->mcodeptr++) = 0x66;
1998 x86_64_emit_rex(1,(freg),0,(reg));
1999 *(cd->mcodeptr++) = 0x0f;
2000 *(cd->mcodeptr++) = 0x6e;
2001 x86_64_emit_reg((freg),(reg));
2005 void x86_64_movd_freg_reg(codegendata *cd, s8 freg, s8 reg) {
2006 *(cd->mcodeptr++) = 0x66;
2007 x86_64_emit_rex(1,(freg),0,(reg));
2008 *(cd->mcodeptr++) = 0x0f;
2009 *(cd->mcodeptr++) = 0x7e;
2010 x86_64_emit_reg((freg),(reg));
2014 void x86_64_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2015 *(cd->mcodeptr++) = 0x66;
2016 x86_64_emit_rex(0,(reg),0,(basereg));
2017 *(cd->mcodeptr++) = 0x0f;
2018 *(cd->mcodeptr++) = 0x7e;
2019 x86_64_emit_membase((basereg),(disp),(reg));
2023 void x86_64_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2024 *(cd->mcodeptr++) = 0x66;
2025 x86_64_emit_rex(0,(reg),(indexreg),(basereg));
2026 *(cd->mcodeptr++) = 0x0f;
2027 *(cd->mcodeptr++) = 0x7e;
2028 x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
2032 void x86_64_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2033 *(cd->mcodeptr++) = 0x66;
2034 x86_64_emit_rex(1,(dreg),0,(basereg));
2035 *(cd->mcodeptr++) = 0x0f;
2036 *(cd->mcodeptr++) = 0x6e;
2037 x86_64_emit_membase((basereg),(disp),(dreg));
2041 void x86_64_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2042 *(cd->mcodeptr++) = 0x66;
2043 x86_64_emit_rex(0,(dreg),0,(basereg));
2044 *(cd->mcodeptr++) = 0x0f;
2045 *(cd->mcodeptr++) = 0x6e;
2046 x86_64_emit_membase((basereg),(disp),(dreg));
2050 void x86_64_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2051 *(cd->mcodeptr++) = 0x66;
2052 x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
2053 *(cd->mcodeptr++) = 0x0f;
2054 *(cd->mcodeptr++) = 0x6e;
2055 x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
2059 void x86_64_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2060 *(cd->mcodeptr++) = 0xf3;
2061 x86_64_emit_rex(0,(dreg),0,(reg));
2062 *(cd->mcodeptr++) = 0x0f;
2063 *(cd->mcodeptr++) = 0x7e;
2064 x86_64_emit_reg((dreg),(reg));
2068 void x86_64_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2069 *(cd->mcodeptr++) = 0x66;
2070 x86_64_emit_rex(0,(reg),0,(basereg));
2071 *(cd->mcodeptr++) = 0x0f;
2072 *(cd->mcodeptr++) = 0xd6;
2073 x86_64_emit_membase((basereg),(disp),(reg));
2077 void x86_64_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2078 *(cd->mcodeptr++) = 0xf3;
2079 x86_64_emit_rex(0,(dreg),0,(basereg));
2080 *(cd->mcodeptr++) = 0x0f;
2081 *(cd->mcodeptr++) = 0x7e;
2082 x86_64_emit_membase((basereg),(disp),(dreg));
2086 void x86_64_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2087 *(cd->mcodeptr++) = 0xf3;
2088 x86_64_emit_rex(0,(reg),0,(dreg));
2089 *(cd->mcodeptr++) = 0x0f;
2090 *(cd->mcodeptr++) = 0x10;
2091 x86_64_emit_reg((reg),(dreg));
2095 void x86_64_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2096 *(cd->mcodeptr++) = 0xf2;
2097 x86_64_emit_rex(0,(reg),0,(dreg));
2098 *(cd->mcodeptr++) = 0x0f;
2099 *(cd->mcodeptr++) = 0x10;
2100 x86_64_emit_reg((reg),(dreg));
2104 void x86_64_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2105 *(cd->mcodeptr++) = 0xf3;
2106 x86_64_emit_rex(0,(reg),0,(basereg));
2107 *(cd->mcodeptr++) = 0x0f;
2108 *(cd->mcodeptr++) = 0x11;
2109 x86_64_emit_membase((basereg),(disp),(reg));
2113 /* Always emit a REX byte, because the instruction size can be smaller when */
2114 /* all register indexes are smaller than 7. */
2115 void x86_64_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2116 *(cd->mcodeptr++) = 0xf3;
2117 x86_64_emit_byte_rex((reg),0,(basereg));
2118 *(cd->mcodeptr++) = 0x0f;
2119 *(cd->mcodeptr++) = 0x11;
2120 x86_64_emit_membase32((basereg),(disp),(reg));
2124 void x86_64_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2125 *(cd->mcodeptr++) = 0xf2;
2126 x86_64_emit_rex(0,(reg),0,(basereg));
2127 *(cd->mcodeptr++) = 0x0f;
2128 *(cd->mcodeptr++) = 0x11;
2129 x86_64_emit_membase((basereg),(disp),(reg));
2133 /* Always emit a REX byte, because the instruction size can be smaller when */
2134 /* all register indexes are smaller than 7. */
2135 void x86_64_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2136 *(cd->mcodeptr++) = 0xf2;
2137 x86_64_emit_byte_rex((reg),0,(basereg));
2138 *(cd->mcodeptr++) = 0x0f;
2139 *(cd->mcodeptr++) = 0x11;
2140 x86_64_emit_membase32((basereg),(disp),(reg));
2144 void x86_64_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2145 *(cd->mcodeptr++) = 0xf3;
2146 x86_64_emit_rex(0,(dreg),0,(basereg));
2147 *(cd->mcodeptr++) = 0x0f;
2148 *(cd->mcodeptr++) = 0x10;
2149 x86_64_emit_membase((basereg),(disp),(dreg));
2153 /* Always emit a REX byte, because the instruction size can be smaller when */
2154 /* all register indexes are smaller than 7. */
2155 void x86_64_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2156 *(cd->mcodeptr++) = 0xf3;
2157 x86_64_emit_byte_rex((dreg),0,(basereg));
2158 *(cd->mcodeptr++) = 0x0f;
2159 *(cd->mcodeptr++) = 0x10;
2160 x86_64_emit_membase32((basereg),(disp),(dreg));
2164 void x86_64_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2165 x86_64_emit_rex(0,(dreg),0,(basereg));
2166 *(cd->mcodeptr++) = 0x0f;
2167 *(cd->mcodeptr++) = 0x12;
2168 x86_64_emit_membase((basereg),(disp),(dreg));
2172 void x86_64_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2173 *(cd->mcodeptr++) = 0xf2;
2174 x86_64_emit_rex(0,(dreg),0,(basereg));
2175 *(cd->mcodeptr++) = 0x0f;
2176 *(cd->mcodeptr++) = 0x10;
2177 x86_64_emit_membase((basereg),(disp),(dreg));
2181 /* Always emit a REX byte, because the instruction size can be smaller when */
2182 /* all register indexes are smaller than 7. */
2183 void x86_64_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2184 *(cd->mcodeptr++) = 0xf2;
2185 x86_64_emit_byte_rex((dreg),0,(basereg));
2186 *(cd->mcodeptr++) = 0x0f;
2187 *(cd->mcodeptr++) = 0x10;
2188 x86_64_emit_membase32((basereg),(disp),(dreg));
2192 void x86_64_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2193 *(cd->mcodeptr++) = 0x66;
2194 x86_64_emit_rex(0,(dreg),0,(basereg));
2195 *(cd->mcodeptr++) = 0x0f;
2196 *(cd->mcodeptr++) = 0x12;
2197 x86_64_emit_membase((basereg),(disp),(dreg));
2201 void x86_64_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2202 *(cd->mcodeptr++) = 0xf3;
2203 x86_64_emit_rex(0,(reg),(indexreg),(basereg));
2204 *(cd->mcodeptr++) = 0x0f;
2205 *(cd->mcodeptr++) = 0x11;
2206 x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
2210 void x86_64_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2211 *(cd->mcodeptr++) = 0xf2;
2212 x86_64_emit_rex(0,(reg),(indexreg),(basereg));
2213 *(cd->mcodeptr++) = 0x0f;
2214 *(cd->mcodeptr++) = 0x11;
2215 x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
2219 void x86_64_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2220 *(cd->mcodeptr++) = 0xf3;
2221 x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
2222 *(cd->mcodeptr++) = 0x0f;
2223 *(cd->mcodeptr++) = 0x10;
2224 x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
2228 void x86_64_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2229 *(cd->mcodeptr++) = 0xf2;
2230 x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
2231 *(cd->mcodeptr++) = 0x0f;
2232 *(cd->mcodeptr++) = 0x10;
2233 x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
2237 void x86_64_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2238 *(cd->mcodeptr++) = 0xf3;
2239 x86_64_emit_rex(0,(dreg),0,(reg));
2240 *(cd->mcodeptr++) = 0x0f;
2241 *(cd->mcodeptr++) = 0x59;
2242 x86_64_emit_reg((dreg),(reg));
2246 void x86_64_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2247 *(cd->mcodeptr++) = 0xf2;
2248 x86_64_emit_rex(0,(dreg),0,(reg));
2249 *(cd->mcodeptr++) = 0x0f;
2250 *(cd->mcodeptr++) = 0x59;
2251 x86_64_emit_reg((dreg),(reg));
2255 void x86_64_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2256 *(cd->mcodeptr++) = 0xf3;
2257 x86_64_emit_rex(0,(dreg),0,(reg));
2258 *(cd->mcodeptr++) = 0x0f;
2259 *(cd->mcodeptr++) = 0x5c;
2260 x86_64_emit_reg((dreg),(reg));
2264 void x86_64_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2265 *(cd->mcodeptr++) = 0xf2;
2266 x86_64_emit_rex(0,(dreg),0,(reg));
2267 *(cd->mcodeptr++) = 0x0f;
2268 *(cd->mcodeptr++) = 0x5c;
2269 x86_64_emit_reg((dreg),(reg));
2273 void x86_64_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2274 x86_64_emit_rex(0,(dreg),0,(reg));
2275 *(cd->mcodeptr++) = 0x0f;
2276 *(cd->mcodeptr++) = 0x2e;
2277 x86_64_emit_reg((dreg),(reg));
2281 void x86_64_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2282 *(cd->mcodeptr++) = 0x66;
2283 x86_64_emit_rex(0,(dreg),0,(reg));
2284 *(cd->mcodeptr++) = 0x0f;
2285 *(cd->mcodeptr++) = 0x2e;
2286 x86_64_emit_reg((dreg),(reg));
2290 void x86_64_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2291 x86_64_emit_rex(0,(dreg),0,(reg));
2292 *(cd->mcodeptr++) = 0x0f;
2293 *(cd->mcodeptr++) = 0x57;
2294 x86_64_emit_reg((dreg),(reg));
2298 void x86_64_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2299 x86_64_emit_rex(0,(dreg),0,(basereg));
2300 *(cd->mcodeptr++) = 0x0f;
2301 *(cd->mcodeptr++) = 0x57;
2302 x86_64_emit_membase((basereg),(disp),(dreg));
2306 void x86_64_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2307 *(cd->mcodeptr++) = 0x66;
2308 x86_64_emit_rex(0,(dreg),0,(reg));
2309 *(cd->mcodeptr++) = 0x0f;
2310 *(cd->mcodeptr++) = 0x57;
2311 x86_64_emit_reg((dreg),(reg));
2315 void x86_64_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2316 *(cd->mcodeptr++) = 0x66;
2317 x86_64_emit_rex(0,(dreg),0,(basereg));
2318 *(cd->mcodeptr++) = 0x0f;
2319 *(cd->mcodeptr++) = 0x57;
2320 x86_64_emit_membase((basereg),(disp),(dreg));
2324 /* system instructions ********************************************************/
2326 void emit_rdtsc(codegendata *cd)
2328 *(cd->mcodeptr++) = 0x0f;
2329 *(cd->mcodeptr++) = 0x31;
2334 * These are local overrides for various environment variables in Emacs.
2335 * Please do not remove this and leave it at the end of the file, where
2336 * Emacs will automagically detect them.
2337 * ---------------------------------------------------------------------
2340 * indent-tabs-mode: t