1 /* src/vm/jit/x86_64/emit.c - x86_64 code emitter functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008, 2009
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 #include "vm/jit/x86_64/codegen.h"
35 #include "vm/jit/x86_64/emit.h"
37 #include "mm/memory.hpp"
39 #include "threads/lock.hpp"
41 #include "vm/options.h"
43 #include "vm/jit/abi.h"
44 #include "vm/jit/abi-asm.h"
45 #include "vm/jit/asmpart.h"
46 #include "vm/jit/codegen-common.hpp"
47 #include "vm/jit/emit-common.hpp"
48 #include "vm/jit/jit.hpp"
49 #include "vm/jit/patcher-common.hpp"
50 #include "vm/jit/replace.hpp"
51 #include "vm/jit/trace.hpp"
52 #include "vm/jit/trap.hpp"
55 /* emit_load *******************************************************************
57 Emits a possible load of an operand.
59 *******************************************************************************/
61 s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
67 /* get required compiler data */
71 if (IS_INMEMORY(src->flags)) {
74 disp = src->vv.regoff;
78 M_ILD(tempreg, REG_SP, disp);
82 M_LLD(tempreg, REG_SP, disp);
85 M_FLD(tempreg, REG_SP, disp);
88 M_DLD(tempreg, REG_SP, disp);
91 vm_abort("emit_load: unknown type %d", src->type);
103 /* emit_store ******************************************************************
105 This function generates the code to store the result of an
106 operation back into a spilled pseudo-variable. If the
107 pseudo-variable has not been spilled in the first place, this
108 function will generate nothing.
110 *******************************************************************************/
112 void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
117 /* get required compiler data */
121 if (IS_INMEMORY(dst->flags)) {
124 disp = dst->vv.regoff;
130 M_LST(d, REG_SP, disp);
133 M_FST(d, REG_SP, disp);
136 M_DST(d, REG_SP, disp);
139 vm_abort("emit_store: unknown type %d", dst->type);
145 /* emit_copy *******************************************************************
147 Generates a register/memory to register/memory copy.
149 *******************************************************************************/
151 void emit_copy(jitdata *jd, instruction *iptr)
158 /* get required compiler data */
162 /* get source and destination variables */
164 src = VAROP(iptr->s1);
165 dst = VAROP(iptr->dst);
167 if ((src->vv.regoff != dst->vv.regoff) ||
168 ((src->flags ^ dst->flags) & INMEMORY)) {
170 if ((src->type == TYPE_RET) || (dst->type == TYPE_RET)) {
171 /* emit nothing, as the value won't be used anyway */
175 /* If one of the variables resides in memory, we can eliminate
176 the register move from/to the temporary register with the
177 order of getting the destination register and the load. */
179 if (IS_INMEMORY(src->flags)) {
180 d = codegen_reg_of_var(iptr->opc, dst, REG_IFTMP);
181 s1 = emit_load(jd, iptr, src, d);
184 s1 = emit_load(jd, iptr, src, REG_IFTMP);
185 d = codegen_reg_of_var(iptr->opc, dst, s1);
200 vm_abort("emit_copy: unknown type %d", src->type);
204 emit_store(jd, iptr, dst, d);
209 void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d)
212 switch (iptr->flags.fields.condition) {
237 * Emits code updating the condition register by comparing one integer
238 * register to an immediate integer value.
240 void emit_icmp_imm(codegendata* cd, int reg, int32_t value)
242 M_ICMP_IMM(value, reg);
246 /* emit_branch *****************************************************************
248 Emits the code for conditional and unconditional branchs.
250 *******************************************************************************/
252 void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 options)
256 /* NOTE: A displacement overflow cannot happen. */
258 /* check which branch to generate */
260 if (condition == BRANCH_UNCONDITIONAL) {
262 /* calculate the different displacements */
264 branchdisp = disp - BRANCH_UNCONDITIONAL_SIZE;
266 M_JMP_IMM(branchdisp);
269 /* calculate the different displacements */
271 branchdisp = disp - BRANCH_CONDITIONAL_SIZE;
305 vm_abort("emit_branch: unknown condition %d", condition);
311 /* emit_arithmetic_check *******************************************************
313 Emit an ArithmeticException check.
315 *******************************************************************************/
317 void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
319 if (INSTRUCTION_MUST_CHECK(iptr)) {
322 M_ALD_MEM(reg, TRAP_ArithmeticException);
327 /* emit_arrayindexoutofbounds_check ********************************************
329 Emit a ArrayIndexOutOfBoundsException check.
331 *******************************************************************************/
333 void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
335 if (INSTRUCTION_MUST_CHECK(iptr)) {
336 M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size));
337 M_ICMP(REG_ITMP3, s2);
339 M_ALD_MEM(s2, TRAP_ArrayIndexOutOfBoundsException);
344 /* emit_arraystore_check *******************************************************
346 Emit an ArrayStoreException check.
348 *******************************************************************************/
350 void emit_arraystore_check(codegendata *cd, instruction *iptr)
352 if (INSTRUCTION_MUST_CHECK(iptr)) {
355 M_ALD_MEM(REG_RESULT, TRAP_ArrayStoreException);
360 /* emit_classcast_check ********************************************************
362 Emit a ClassCastException check.
364 *******************************************************************************/
366 void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
368 if (INSTRUCTION_MUST_CHECK(iptr)) {
386 vm_abort("emit_classcast_check: unknown condition %d", condition);
388 M_ALD_MEM(s1, TRAP_ClassCastException);
393 /* emit_nullpointer_check ******************************************************
395 Emit a NullPointerException check.
397 *******************************************************************************/
399 void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
401 if (INSTRUCTION_MUST_CHECK(iptr)) {
404 M_ALD_MEM(reg, TRAP_NullPointerException);
409 /* emit_exception_check ********************************************************
411 Emit an Exception check.
413 *******************************************************************************/
415 void emit_exception_check(codegendata *cd, instruction *iptr)
417 if (INSTRUCTION_MUST_CHECK(iptr)) {
420 M_ALD_MEM(REG_RESULT, TRAP_CHECK_EXCEPTION);
425 /* emit_trap_compiler **********************************************************
427 Emit a trap instruction which calls the JIT compiler.
429 *******************************************************************************/
431 void emit_trap_compiler(codegendata *cd)
433 M_ALD_MEM(REG_METHODPTR, TRAP_COMPILER);
437 /* emit_patcher_alignment ******************************************************
439 Emit NOP to ensure placement at an even address.
441 *******************************************************************************/
443 void emit_patcher_alignment(codegendata *cd)
445 if ((uintptr_t) cd->mcodeptr & 1)
450 /* emit_trap *******************************************************************
452 Emit a trap instruction and return the original machine code.
454 *******************************************************************************/
456 uint32_t emit_trap(codegendata *cd)
460 /* Get machine code which is patched back in later. The trap is 2
463 mcode = *((uint16_t *) cd->mcodeptr);
465 /* XXX This needs to be change to INT3 when the debugging problems
466 with gdb are resolved. */
475 * Generates synchronization code to enter a monitor.
477 #if defined(ENABLE_THREADS)
478 void emit_monitor_enter(jitdata* jd, int32_t syncslot_offset)
482 // Get required compiler data.
483 methodinfo* m = jd->m;
484 codegendata* cd = jd->cd;
486 # if !defined(NDEBUG)
487 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
488 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
490 for (p = 0; p < INT_ARG_CNT; p++)
491 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
493 for (p = 0; p < FLT_ARG_CNT; p++)
494 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
496 syncslot_offset += (INT_ARG_CNT + FLT_ARG_CNT) * 8;
500 /* decide which monitor enter function to call */
502 if (m->flags & ACC_STATIC) {
503 M_MOV_IMM(&m->clazz->object.header, REG_A0);
508 M_ALD_MEM(REG_A0, TRAP_NullPointerException);
511 M_AST(REG_A0, REG_SP, syncslot_offset);
512 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
515 # if !defined(NDEBUG)
516 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
518 for (p = 0; p < INT_ARG_CNT; p++)
519 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
521 for (p = 0; p < FLT_ARG_CNT; p++)
522 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
524 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
532 * Generates synchronization code to leave a monitor.
534 #if defined(ENABLE_THREADS)
535 void emit_monitor_exit(jitdata* jd, int32_t syncslot_offset)
537 // Get required compiler data.
538 methodinfo* m = jd->m;
539 codegendata* cd = jd->cd;
541 M_ALD(REG_A0, REG_SP, syncslot_offset);
543 /* we need to save the proper return value */
545 methoddesc* md = m->parseddesc;
547 switch (md->returntype.type) {
551 M_LST(REG_RESULT, REG_SP, syncslot_offset);
555 M_DST(REG_FRESULT, REG_SP, syncslot_offset);
559 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
562 /* and now restore the proper return value */
564 switch (md->returntype.type) {
568 M_LLD(REG_RESULT, REG_SP, syncslot_offset);
572 M_DLD(REG_FRESULT, REG_SP, syncslot_offset);
580 * Emit profiling code for method frequency counting.
582 #if defined(ENABLE_PROFILING)
583 void emit_profile_method(codegendata* cd, codeinfo* code)
585 M_MOV_IMM(code, REG_ITMP3);
586 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
592 * Emit profiling code for basicblock frequency counting.
594 #if defined(ENABLE_PROFILING)
595 void emit_profile_basicblock(codegendata* cd, codeinfo* code, basicblock* bptr)
597 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
598 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
604 * Emit profiling code to start CPU cycle counting.
606 #if defined(ENABLE_PROFILING)
607 void emit_profile_cycle_start(codegendata* cd, codeinfo* code)
612 M_MOV_IMM(code, REG_ITMP3);
614 M_ISUB_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles));
615 M_ISBB_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4);
624 * Emit profiling code to stop CPU cycle counting.
626 #if defined(ENABLE_PROFILING)
627 void emit_profile_cycle_stop(codegendata* cd, codeinfo* code)
632 M_MOV_IMM(code, REG_ITMP3);
634 M_IADD_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles));
635 M_IADC_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4);
643 /* emit_verbosecall_enter ******************************************************
645 Generates the code for the call trace.
647 *******************************************************************************/
650 void emit_verbosecall_enter(jitdata *jd)
660 /* get required compiler data */
669 /* mark trace code */
673 /* keep 16-byte stack alignment */
675 stackframesize = md->paramcount + ARG_CNT + TMP_CNT;
676 ALIGN_2(stackframesize);
678 M_LSUB_IMM(stackframesize * 8, REG_SP);
680 /* save argument registers */
682 for (i = 0; i < md->paramcount; i++) {
683 if (!md->params[i].inmemory) {
684 s = md->params[i].regoff;
686 switch (md->paramtypes[i].type) {
690 M_LST(s, REG_SP, i * 8);
694 M_DST(s, REG_SP, i * 8);
700 /* save all argument and temporary registers for leaf methods */
702 if (code_is_leafmethod(code)) {
703 for (i = 0; i < INT_ARG_CNT; i++)
704 M_LST(abi_registers_integer_argument[i], REG_SP, (md->paramcount + i) * 8);
706 for (i = 0; i < FLT_ARG_CNT; i++)
707 M_DST(abi_registers_float_argument[i], REG_SP, (md->paramcount + INT_ARG_CNT + i) * 8);
709 for (i = 0; i < INT_TMP_CNT; i++)
710 M_LST(rd->tmpintregs[i], REG_SP, (md->paramcount + ARG_CNT + i) * 8);
712 for (i = 0; i < FLT_TMP_CNT; i++)
713 M_DST(rd->tmpfltregs[i], REG_SP, (md->paramcount + ARG_CNT + INT_TMP_CNT + i) * 8);
716 M_MOV_IMM(m, REG_A0);
717 M_MOV(REG_SP, REG_A1);
718 M_MOV(REG_SP, REG_A2);
719 M_AADD_IMM((stackframesize + cd->stackframesize + 1) * 8, REG_A2);
720 M_MOV_IMM(trace_java_call_enter, REG_ITMP1);
723 /* restore argument registers */
725 for (i = 0; i < md->paramcount; i++) {
726 if (!md->params[i].inmemory) {
727 s = md->params[i].regoff;
729 switch (md->paramtypes[i].type) {
733 M_LLD(s, REG_SP, i * 8);
737 M_DLD(s, REG_SP, i * 8);
744 /* restore all argument and temporary registers for leaf methods */
746 if (code_is_leafmethod(code)) {
747 for (i = 0; i < INT_ARG_CNT; i++)
748 M_LLD(abi_registers_integer_argument[i], REG_SP, (md->paramcount + i) * 8);
750 for (i = 0; i < FLT_ARG_CNT; i++)
751 M_DLD(abi_registers_float_argument[i], REG_SP, (md->paramcount + INT_ARG_CNT + i) * 8);
753 for (i = 0; i < INT_TMP_CNT; i++)
754 M_LLD(rd->tmpintregs[i], REG_SP, (md->paramcount + ARG_CNT + i) * 8);
756 for (i = 0; i < FLT_TMP_CNT; i++)
757 M_DLD(rd->tmpfltregs[i], REG_SP, (md->paramcount + ARG_CNT + INT_TMP_CNT + i) * 8);
760 M_LADD_IMM(stackframesize * 8, REG_SP);
762 /* mark trace code */
766 #endif /* !defined(NDEBUG) */
769 /* emit_verbosecall_exit *******************************************************
771 Generates the code for the call trace.
773 *******************************************************************************/
776 void emit_verbosecall_exit(jitdata *jd)
783 /* get required compiler data */
791 /* mark trace code */
795 /* keep 16-byte stack alignment */
797 M_ASUB_IMM(2 * 8, REG_SP);
799 /* save return value */
801 switch (md->returntype.type) {
805 M_LST(REG_RESULT, REG_SP, 0 * 8);
809 M_DST(REG_FRESULT, REG_SP, 0 * 8);
813 M_MOV_IMM(m, REG_A0);
814 M_MOV(REG_SP, REG_A1);
816 M_MOV_IMM(trace_java_call_exit, REG_ITMP1);
819 /* restore return value */
821 switch (md->returntype.type) {
825 M_LLD(REG_RESULT, REG_SP, 0 * 8);
829 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
833 M_AADD_IMM(2 * 8, REG_SP);
835 /* mark trace code */
839 #endif /* !defined(NDEBUG) */
842 /* code generation functions **************************************************/
844 static void emit_membase(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
846 if ((basereg == REG_SP) || (basereg == R12)) {
848 emit_address_byte(0, dreg, REG_SP);
849 emit_address_byte(0, REG_SP, REG_SP);
851 } else if (IS_IMM8(disp)) {
852 emit_address_byte(1, dreg, REG_SP);
853 emit_address_byte(0, REG_SP, REG_SP);
857 emit_address_byte(2, dreg, REG_SP);
858 emit_address_byte(0, REG_SP, REG_SP);
862 } else if ((disp) == 0 && (basereg) != RBP && (basereg) != R13) {
863 emit_address_byte(0,(dreg),(basereg));
865 } else if ((basereg) == RIP) {
866 emit_address_byte(0, dreg, RBP);
871 emit_address_byte(1, dreg, basereg);
875 emit_address_byte(2, dreg, basereg);
882 static void emit_membase32(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
884 if ((basereg == REG_SP) || (basereg == R12)) {
885 emit_address_byte(2, dreg, REG_SP);
886 emit_address_byte(0, REG_SP, REG_SP);
890 emit_address_byte(2, dreg, basereg);
896 static void emit_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
899 emit_address_byte(0, reg, 4);
900 emit_address_byte(scale, indexreg, 5);
903 else if ((disp == 0) && (basereg != RBP) && (basereg != R13)) {
904 emit_address_byte(0, reg, 4);
905 emit_address_byte(scale, indexreg, basereg);
907 else if (IS_IMM8(disp)) {
908 emit_address_byte(1, reg, 4);
909 emit_address_byte(scale, indexreg, basereg);
913 emit_address_byte(2, reg, 4);
914 emit_address_byte(scale, indexreg, basereg);
920 void emit_ishift(jitdata *jd, s4 shift_op, instruction *iptr)
923 varinfo *v_s1,*v_s2,*v_dst;
926 /* get required compiler data */
930 v_s1 = VAROP(iptr->s1);
931 v_s2 = VAROP(iptr->sx.s23.s2);
932 v_dst = VAROP(iptr->dst);
934 s1 = v_s1->vv.regoff;
935 s2 = v_s2->vv.regoff;
936 d = v_dst->vv.regoff;
938 M_INTMOVE(RCX, REG_ITMP1); /* save RCX */
940 if (IS_INMEMORY(v_dst->flags)) {
941 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
943 M_ILD(RCX, REG_SP, s2);
944 emit_shiftl_membase(cd, shift_op, REG_SP, d);
947 M_ILD(RCX, REG_SP, s2);
948 M_ILD(REG_ITMP2, REG_SP, s1);
949 emit_shiftl_reg(cd, shift_op, REG_ITMP2);
950 M_IST(REG_ITMP2, REG_SP, d);
953 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
954 /* s1 may be equal to RCX */
957 M_ILD(REG_ITMP1, REG_SP, s2);
958 M_IST(s1, REG_SP, d);
959 M_INTMOVE(REG_ITMP1, RCX);
962 M_IST(s1, REG_SP, d);
963 M_ILD(RCX, REG_SP, s2);
967 M_ILD(RCX, REG_SP, s2);
968 M_IST(s1, REG_SP, d);
971 emit_shiftl_membase(cd, shift_op, REG_SP, d);
973 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
976 emit_shiftl_membase(cd, shift_op, REG_SP, d);
980 M_ILD(REG_ITMP2, REG_SP, s1);
981 emit_shiftl_reg(cd, shift_op, REG_ITMP2);
982 M_IST(REG_ITMP2, REG_SP, d);
986 /* s1 may be equal to RCX */
987 M_IST(s1, REG_SP, d);
989 emit_shiftl_membase(cd, shift_op, REG_SP, d);
992 M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */
1000 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1001 M_ILD(RCX, REG_SP, s2);
1002 M_ILD(d, REG_SP, s1);
1003 emit_shiftl_reg(cd, shift_op, d);
1005 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
1006 /* s1 may be equal to RCX */
1008 M_ILD(RCX, REG_SP, s2);
1009 emit_shiftl_reg(cd, shift_op, d);
1011 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1013 M_ILD(d, REG_SP, s1);
1014 emit_shiftl_reg(cd, shift_op, d);
1017 /* s1 may be equal to RCX */
1020 /* d cannot be used to backup s1 since this would
1022 M_INTMOVE(s1, REG_ITMP3);
1024 M_INTMOVE(REG_ITMP3, d);
1032 /* d may be equal to s2 */
1036 emit_shiftl_reg(cd, shift_op, d);
1040 M_INTMOVE(REG_ITMP3, RCX);
1042 M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */
1047 void emit_lshift(jitdata *jd, s4 shift_op, instruction *iptr)
1049 s4 s1, s2, d, d_old;
1050 varinfo *v_s1,*v_s2,*v_dst;
1053 /* get required compiler data */
1057 v_s1 = VAROP(iptr->s1);
1058 v_s2 = VAROP(iptr->sx.s23.s2);
1059 v_dst = VAROP(iptr->dst);
1061 s1 = v_s1->vv.regoff;
1062 s2 = v_s2->vv.regoff;
1063 d = v_dst->vv.regoff;
1065 M_INTMOVE(RCX, REG_ITMP1); /* save RCX */
1067 if (IS_INMEMORY(v_dst->flags)) {
1068 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1070 M_ILD(RCX, REG_SP, s2);
1071 emit_shift_membase(cd, shift_op, REG_SP, d);
1074 M_ILD(RCX, REG_SP, s2);
1075 M_LLD(REG_ITMP2, REG_SP, s1);
1076 emit_shift_reg(cd, shift_op, REG_ITMP2);
1077 M_LST(REG_ITMP2, REG_SP, d);
1080 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
1081 /* s1 may be equal to RCX */
1084 M_ILD(REG_ITMP1, REG_SP, s2);
1085 M_LST(s1, REG_SP, d);
1086 M_INTMOVE(REG_ITMP1, RCX);
1089 M_LST(s1, REG_SP, d);
1090 M_ILD(RCX, REG_SP, s2);
1094 M_ILD(RCX, REG_SP, s2);
1095 M_LST(s1, REG_SP, d);
1098 emit_shift_membase(cd, shift_op, REG_SP, d);
1100 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1103 emit_shift_membase(cd, shift_op, REG_SP, d);
1107 M_LLD(REG_ITMP2, REG_SP, s1);
1108 emit_shift_reg(cd, shift_op, REG_ITMP2);
1109 M_LST(REG_ITMP2, REG_SP, d);
1113 /* s1 may be equal to RCX */
1114 M_LST(s1, REG_SP, d);
1116 emit_shift_membase(cd, shift_op, REG_SP, d);
1119 M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */
1127 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1128 M_ILD(RCX, REG_SP, s2);
1129 M_LLD(d, REG_SP, s1);
1130 emit_shift_reg(cd, shift_op, d);
1132 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
1133 /* s1 may be equal to RCX */
1135 M_ILD(RCX, REG_SP, s2);
1136 emit_shift_reg(cd, shift_op, d);
1138 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1140 M_LLD(d, REG_SP, s1);
1141 emit_shift_reg(cd, shift_op, d);
1144 /* s1 may be equal to RCX */
1147 /* d cannot be used to backup s1 since this would
1149 M_INTMOVE(s1, REG_ITMP3);
1151 M_INTMOVE(REG_ITMP3, d);
1159 /* d may be equal to s2 */
1163 emit_shift_reg(cd, shift_op, d);
1167 M_INTMOVE(REG_ITMP3, RCX);
1169 M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */
1174 /* low-level code emitter functions *******************************************/
1176 void emit_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1178 emit_rex(1,(reg),0,(dreg));
1179 *(cd->mcodeptr++) = 0x89;
1180 emit_reg((reg),(dreg));
1184 void emit_mov_imm_reg(codegendata *cd, s8 imm, s8 reg)
1186 emit_rex(1,0,0,(reg));
1187 *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
1192 void emit_movl_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1194 emit_rex(0,(reg),0,(dreg));
1195 *(cd->mcodeptr++) = 0x89;
1196 emit_reg((reg),(dreg));
1200 void emit_movl_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1201 emit_rex(0,0,0,(reg));
1202 *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
1207 void emit_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1208 emit_rex(1,(reg),0,(basereg));
1209 *(cd->mcodeptr++) = 0x8b;
1210 emit_membase(cd, (basereg),(disp),(reg));
1215 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
1216 * constant membase immediate length of 32bit
1218 void emit_mov_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1219 emit_rex(1,(reg),0,(basereg));
1220 *(cd->mcodeptr++) = 0x8b;
1221 emit_membase32(cd, (basereg),(disp),(reg));
1225 void emit_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
1227 emit_rex(0,(reg),0,(basereg));
1228 *(cd->mcodeptr++) = 0x8b;
1229 emit_membase(cd, (basereg),(disp),(reg));
1233 /* ATTENTION: Always emit a REX byte, because the instruction size can
1234 be smaller when all register indexes are smaller than 7. */
1235 void emit_movl_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
1237 emit_byte_rex((reg),0,(basereg));
1238 *(cd->mcodeptr++) = 0x8b;
1239 emit_membase32(cd, (basereg),(disp),(reg));
1243 void emit_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1244 emit_rex(1,(reg),0,(basereg));
1245 *(cd->mcodeptr++) = 0x89;
1246 emit_membase(cd, (basereg),(disp),(reg));
1250 void emit_mov_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1251 emit_rex(1,(reg),0,(basereg));
1252 *(cd->mcodeptr++) = 0x89;
1253 emit_membase32(cd, (basereg),(disp),(reg));
1257 void emit_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1258 emit_rex(0,(reg),0,(basereg));
1259 *(cd->mcodeptr++) = 0x89;
1260 emit_membase(cd, (basereg),(disp),(reg));
1264 /* Always emit a REX byte, because the instruction size can be smaller when */
1265 /* all register indexes are smaller than 7. */
1266 void emit_movl_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1267 emit_byte_rex((reg),0,(basereg));
1268 *(cd->mcodeptr++) = 0x89;
1269 emit_membase32(cd, (basereg),(disp),(reg));
1273 void emit_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1274 emit_rex(1,(reg),(indexreg),(basereg));
1275 *(cd->mcodeptr++) = 0x8b;
1276 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1280 void emit_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1281 emit_rex(0,(reg),(indexreg),(basereg));
1282 *(cd->mcodeptr++) = 0x8b;
1283 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1287 void emit_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1288 emit_rex(1,(reg),(indexreg),(basereg));
1289 *(cd->mcodeptr++) = 0x89;
1290 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1294 void emit_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1295 emit_rex(0,(reg),(indexreg),(basereg));
1296 *(cd->mcodeptr++) = 0x89;
1297 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1301 void emit_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1302 *(cd->mcodeptr++) = 0x66;
1303 emit_rex(0,(reg),(indexreg),(basereg));
1304 *(cd->mcodeptr++) = 0x89;
1305 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1309 void emit_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1310 emit_byte_rex((reg),(indexreg),(basereg));
1311 *(cd->mcodeptr++) = 0x88;
1312 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1316 void emit_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1317 emit_rex(1,0,0,(basereg));
1318 *(cd->mcodeptr++) = 0xc7;
1319 emit_membase(cd, (basereg),(disp),0);
1324 void emit_mov_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1325 emit_rex(1,0,0,(basereg));
1326 *(cd->mcodeptr++) = 0xc7;
1327 emit_membase32(cd, (basereg),(disp),0);
1332 void emit_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1333 emit_rex(0,0,0,(basereg));
1334 *(cd->mcodeptr++) = 0xc7;
1335 emit_membase(cd, (basereg),(disp),0);
1340 /* Always emit a REX byte, because the instruction size can be smaller when */
1341 /* all register indexes are smaller than 7. */
1342 void emit_movl_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1343 emit_byte_rex(0,0,(basereg));
1344 *(cd->mcodeptr++) = 0xc7;
1345 emit_membase32(cd, (basereg),(disp),0);
1350 void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1352 emit_rex(1,(dreg),0,(reg));
1353 *(cd->mcodeptr++) = 0x0f;
1354 *(cd->mcodeptr++) = 0xbe;
1355 /* XXX: why do reg and dreg have to be exchanged */
1356 emit_reg((dreg),(reg));
1360 void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1362 emit_rex(1,(dreg),0,(reg));
1363 *(cd->mcodeptr++) = 0x0f;
1364 *(cd->mcodeptr++) = 0xbf;
1365 /* XXX: why do reg and dreg have to be exchanged */
1366 emit_reg((dreg),(reg));
1370 void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1372 emit_rex(1,(dreg),0,(reg));
1373 *(cd->mcodeptr++) = 0x63;
1374 /* XXX: why do reg and dreg have to be exchanged */
1375 emit_reg((dreg),(reg));
1379 void emit_movzbq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1381 emit_rex(1,(dreg),0,(reg));
1382 *(cd->mcodeptr++) = 0x0f;
1383 *(cd->mcodeptr++) = 0xb6;
1384 /* XXX: why do reg and dreg have to be exchanged */
1385 emit_reg((dreg),(reg));
1389 void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1391 emit_rex(1,(dreg),0,(reg));
1392 *(cd->mcodeptr++) = 0x0f;
1393 *(cd->mcodeptr++) = 0xb7;
1394 /* XXX: why do reg and dreg have to be exchanged */
1395 emit_reg((dreg),(reg));
1399 void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1400 emit_rex(1,(reg),(indexreg),(basereg));
1401 *(cd->mcodeptr++) = 0x0f;
1402 *(cd->mcodeptr++) = 0xbf;
1403 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1407 void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1408 emit_rex(1,(reg),(indexreg),(basereg));
1409 *(cd->mcodeptr++) = 0x0f;
1410 *(cd->mcodeptr++) = 0xbe;
1411 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1415 void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1416 emit_rex(1,(reg),(indexreg),(basereg));
1417 *(cd->mcodeptr++) = 0x0f;
1418 *(cd->mcodeptr++) = 0xb7;
1419 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1423 void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1425 emit_rex(1,0,(indexreg),(basereg));
1426 *(cd->mcodeptr++) = 0xc7;
1427 emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1432 void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1434 emit_rex(0,0,(indexreg),(basereg));
1435 *(cd->mcodeptr++) = 0xc7;
1436 emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1441 void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1443 *(cd->mcodeptr++) = 0x66;
1444 emit_rex(0,0,(indexreg),(basereg));
1445 *(cd->mcodeptr++) = 0xc7;
1446 emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1451 void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1453 emit_rex(0,0,(indexreg),(basereg));
1454 *(cd->mcodeptr++) = 0xc6;
1455 emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1460 void emit_mov_mem_reg(codegendata *cd, s4 disp, s4 dreg)
1462 emit_rex(1, dreg, 0, 0);
1463 *(cd->mcodeptr++) = 0x8b;
1464 emit_address_byte(0, dreg, 4);
1472 void emit_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1474 emit_rex(1,(reg),0,(dreg));
1475 *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1476 emit_reg((reg),(dreg));
1480 void emit_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1482 emit_rex(0,(reg),0,(dreg));
1483 *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1484 emit_reg((reg),(dreg));
1488 void emit_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
1490 emit_rex(1,(reg),0,(basereg));
1491 *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1492 emit_membase(cd, (basereg),(disp),(reg));
1496 void emit_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
1498 emit_rex(0,(reg),0,(basereg));
1499 *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1500 emit_membase(cd, (basereg),(disp),(reg));
1504 void emit_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
1506 emit_rex(1,(reg),0,(basereg));
1507 *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1508 emit_membase(cd, (basereg),(disp),(reg));
1512 void emit_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
1514 emit_rex(0,(reg),0,(basereg));
1515 *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1516 emit_membase(cd, (basereg),(disp),(reg));
1520 void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1522 emit_rex(1,0,0,(dreg));
1523 *(cd->mcodeptr++) = 0x83;
1524 emit_reg((opc),(dreg));
1527 emit_rex(1,0,0,(dreg));
1528 *(cd->mcodeptr++) = 0x81;
1529 emit_reg((opc),(dreg));
1535 void emit_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
1537 emit_rex(1,0,0,(dreg));
1538 *(cd->mcodeptr++) = 0x81;
1539 emit_reg((opc),(dreg));
1544 void emit_alul_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
1546 emit_rex(0,0,0,(dreg));
1547 *(cd->mcodeptr++) = 0x81;
1548 emit_reg((opc),(dreg));
1553 void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1555 emit_rex(0,0,0,(dreg));
1556 *(cd->mcodeptr++) = 0x83;
1557 emit_reg((opc),(dreg));
1560 emit_rex(0,0,0,(dreg));
1561 *(cd->mcodeptr++) = 0x81;
1562 emit_reg((opc),(dreg));
1568 void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1570 emit_rex(1,0,0,(basereg));
1571 *(cd->mcodeptr++) = 0x83;
1572 emit_membase(cd, (basereg),(disp),(opc));
1575 emit_rex(1,0,0,(basereg));
1576 *(cd->mcodeptr++) = 0x81;
1577 emit_membase(cd, (basereg),(disp),(opc));
1583 void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1585 emit_rex(0,0,0,(basereg));
1586 *(cd->mcodeptr++) = 0x83;
1587 emit_membase(cd, (basereg),(disp),(opc));
1590 emit_rex(0,0,0,(basereg));
1591 *(cd->mcodeptr++) = 0x81;
1592 emit_membase(cd, (basereg),(disp),(opc));
1597 void emit_alu_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
1599 emit_rex(1,(reg),(indexreg),(basereg));
1600 *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1601 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1604 void emit_alul_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
1606 emit_rex(0,(reg),(indexreg),(basereg));
1607 *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1608 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1611 void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1612 emit_rex(1,(reg),0,(dreg));
1613 *(cd->mcodeptr++) = 0x85;
1614 emit_reg((reg),(dreg));
1618 void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1619 emit_rex(0,(reg),0,(dreg));
1620 *(cd->mcodeptr++) = 0x85;
1621 emit_reg((reg),(dreg));
1625 void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1626 *(cd->mcodeptr++) = 0xf7;
1632 void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1633 *(cd->mcodeptr++) = 0x66;
1634 *(cd->mcodeptr++) = 0xf7;
1640 void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1641 *(cd->mcodeptr++) = 0xf6;
1647 void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1648 emit_rex(1,(reg),0,(basereg));
1649 *(cd->mcodeptr++) = 0x8d;
1650 emit_membase(cd, (basereg),(disp),(reg));
1654 void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1655 emit_rex(0,(reg),0,(basereg));
1656 *(cd->mcodeptr++) = 0x8d;
1657 emit_membase(cd, (basereg),(disp),(reg));
1661 void emit_incl_reg(codegendata *cd, s8 reg)
1663 *(cd->mcodeptr++) = 0xff;
1667 void emit_incq_reg(codegendata *cd, s8 reg)
1669 emit_rex(1,0,0,(reg));
1670 *(cd->mcodeptr++) = 0xff;
1674 void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp)
1676 emit_rex(0,0,0,(basereg));
1677 *(cd->mcodeptr++) = 0xff;
1678 emit_membase(cd, (basereg),(disp),0);
1681 void emit_incq_membase(codegendata *cd, s8 basereg, s8 disp)
1683 emit_rex(1,0,0,(basereg));
1684 *(cd->mcodeptr++) = 0xff;
1685 emit_membase(cd, (basereg),(disp),0);
1690 void emit_cltd(codegendata *cd) {
1691 *(cd->mcodeptr++) = 0x99;
1695 void emit_cqto(codegendata *cd) {
1697 *(cd->mcodeptr++) = 0x99;
1702 void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1703 emit_rex(1,(dreg),0,(reg));
1704 *(cd->mcodeptr++) = 0x0f;
1705 *(cd->mcodeptr++) = 0xaf;
1706 emit_reg((dreg),(reg));
1710 void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1711 emit_rex(0,(dreg),0,(reg));
1712 *(cd->mcodeptr++) = 0x0f;
1713 *(cd->mcodeptr++) = 0xaf;
1714 emit_reg((dreg),(reg));
1718 void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1719 emit_rex(1,(dreg),0,(basereg));
1720 *(cd->mcodeptr++) = 0x0f;
1721 *(cd->mcodeptr++) = 0xaf;
1722 emit_membase(cd, (basereg),(disp),(dreg));
1726 void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1727 emit_rex(0,(dreg),0,(basereg));
1728 *(cd->mcodeptr++) = 0x0f;
1729 *(cd->mcodeptr++) = 0xaf;
1730 emit_membase(cd, (basereg),(disp),(dreg));
1734 void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg) {
1735 if (IS_IMM8((imm))) {
1736 emit_rex(1,0,0,(dreg));
1737 *(cd->mcodeptr++) = 0x6b;
1741 emit_rex(1,0,0,(dreg));
1742 *(cd->mcodeptr++) = 0x69;
1749 void emit_imul_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1750 if (IS_IMM8((imm))) {
1751 emit_rex(1,(dreg),0,(reg));
1752 *(cd->mcodeptr++) = 0x6b;
1753 emit_reg((dreg),(reg));
1756 emit_rex(1,(dreg),0,(reg));
1757 *(cd->mcodeptr++) = 0x69;
1758 emit_reg((dreg),(reg));
1764 void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1765 if (IS_IMM8((imm))) {
1766 emit_rex(0,(dreg),0,(reg));
1767 *(cd->mcodeptr++) = 0x6b;
1768 emit_reg((dreg),(reg));
1771 emit_rex(0,(dreg),0,(reg));
1772 *(cd->mcodeptr++) = 0x69;
1773 emit_reg((dreg),(reg));
1779 void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1780 if (IS_IMM8((imm))) {
1781 emit_rex(1,(dreg),0,(basereg));
1782 *(cd->mcodeptr++) = 0x6b;
1783 emit_membase(cd, (basereg),(disp),(dreg));
1786 emit_rex(1,(dreg),0,(basereg));
1787 *(cd->mcodeptr++) = 0x69;
1788 emit_membase(cd, (basereg),(disp),(dreg));
1794 void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1795 if (IS_IMM8((imm))) {
1796 emit_rex(0,(dreg),0,(basereg));
1797 *(cd->mcodeptr++) = 0x6b;
1798 emit_membase(cd, (basereg),(disp),(dreg));
1801 emit_rex(0,(dreg),0,(basereg));
1802 *(cd->mcodeptr++) = 0x69;
1803 emit_membase(cd, (basereg),(disp),(dreg));
1809 void emit_idiv_reg(codegendata *cd, s8 reg) {
1810 emit_rex(1,0,0,(reg));
1811 *(cd->mcodeptr++) = 0xf7;
1816 void emit_idivl_reg(codegendata *cd, s8 reg) {
1817 emit_rex(0,0,0,(reg));
1818 *(cd->mcodeptr++) = 0xf7;
1827 void emit_shift_reg(codegendata *cd, s8 opc, s8 reg) {
1828 emit_rex(1,0,0,(reg));
1829 *(cd->mcodeptr++) = 0xd3;
1830 emit_reg((opc),(reg));
1834 void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg) {
1835 emit_rex(0,0,0,(reg));
1836 *(cd->mcodeptr++) = 0xd3;
1837 emit_reg((opc),(reg));
1841 void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1842 emit_rex(1,0,0,(basereg));
1843 *(cd->mcodeptr++) = 0xd3;
1844 emit_membase(cd, (basereg),(disp),(opc));
1848 void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1849 emit_rex(0,0,0,(basereg));
1850 *(cd->mcodeptr++) = 0xd3;
1851 emit_membase(cd, (basereg),(disp),(opc));
1855 void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1857 emit_rex(1,0,0,(dreg));
1858 *(cd->mcodeptr++) = 0xd1;
1859 emit_reg((opc),(dreg));
1861 emit_rex(1,0,0,(dreg));
1862 *(cd->mcodeptr++) = 0xc1;
1863 emit_reg((opc),(dreg));
1869 void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1871 emit_rex(0,0,0,(dreg));
1872 *(cd->mcodeptr++) = 0xd1;
1873 emit_reg((opc),(dreg));
1875 emit_rex(0,0,0,(dreg));
1876 *(cd->mcodeptr++) = 0xc1;
1877 emit_reg((opc),(dreg));
1883 void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1885 emit_rex(1,0,0,(basereg));
1886 *(cd->mcodeptr++) = 0xd1;
1887 emit_membase(cd, (basereg),(disp),(opc));
1889 emit_rex(1,0,0,(basereg));
1890 *(cd->mcodeptr++) = 0xc1;
1891 emit_membase(cd, (basereg),(disp),(opc));
1897 void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1899 emit_rex(0,0,0,(basereg));
1900 *(cd->mcodeptr++) = 0xd1;
1901 emit_membase(cd, (basereg),(disp),(opc));
1903 emit_rex(0,0,0,(basereg));
1904 *(cd->mcodeptr++) = 0xc1;
1905 emit_membase(cd, (basereg),(disp),(opc));
1915 void emit_jmp_imm(codegendata *cd, s8 imm) {
1916 *(cd->mcodeptr++) = 0xe9;
1920 /* like emit_jmp_imm but allows 8 bit optimization */
1921 void emit_jmp_imm2(codegendata *cd, s8 imm) {
1923 *(cd->mcodeptr++) = 0xeb;
1927 *(cd->mcodeptr++) = 0xe9;
1933 void emit_jmp_reg(codegendata *cd, s8 reg) {
1934 emit_rex(0,0,0,(reg));
1935 *(cd->mcodeptr++) = 0xff;
1940 void emit_jcc(codegendata *cd, s8 opc, s8 imm) {
1941 *(cd->mcodeptr++) = 0x0f;
1942 *(cd->mcodeptr++) = (0x80 + (opc));
1949 * conditional set and move operations
1952 /* we need the rex byte to get all low bytes */
1953 void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg)
1955 *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
1956 *(cd->mcodeptr++) = 0x0f;
1957 *(cd->mcodeptr++) = (0x90 + (opc));
1962 /* we need the rex byte to get all low bytes */
1963 void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
1965 *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
1966 *(cd->mcodeptr++) = 0x0f;
1967 *(cd->mcodeptr++) = (0x90 + (opc));
1968 emit_membase(cd, (basereg),(disp),0);
1972 void emit_cmovcc_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
1974 emit_rex(1,(dreg),0,(reg));
1975 *(cd->mcodeptr++) = 0x0f;
1976 *(cd->mcodeptr++) = (0x40 + (opc));
1977 emit_reg((dreg),(reg));
1981 void emit_cmovccl_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
1983 emit_rex(0,(dreg),0,(reg));
1984 *(cd->mcodeptr++) = 0x0f;
1985 *(cd->mcodeptr++) = (0x40 + (opc));
1986 emit_reg((dreg),(reg));
1990 void emit_neg_reg(codegendata *cd, s8 reg)
1992 emit_rex(1,0,0,(reg));
1993 *(cd->mcodeptr++) = 0xf7;
1998 void emit_negl_reg(codegendata *cd, s8 reg)
2000 emit_rex(0,0,0,(reg));
2001 *(cd->mcodeptr++) = 0xf7;
2006 void emit_push_reg(codegendata *cd, s8 reg) {
2007 emit_rex(0,0,0,(reg));
2008 *(cd->mcodeptr++) = 0x50 + (0x07 & (reg));
2012 void emit_push_imm(codegendata *cd, s8 imm) {
2013 *(cd->mcodeptr++) = 0x68;
2018 void emit_pop_reg(codegendata *cd, s8 reg) {
2019 emit_rex(0,0,0,(reg));
2020 *(cd->mcodeptr++) = 0x58 + (0x07 & (reg));
2024 void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2025 emit_rex(1,(reg),0,(dreg));
2026 *(cd->mcodeptr++) = 0x87;
2027 emit_reg((reg),(dreg));
2035 void emit_call_reg(codegendata *cd, s8 reg)
2037 emit_rex(0,0,0,(reg));
2038 *(cd->mcodeptr++) = 0xff;
2043 void emit_call_imm(codegendata *cd, s8 imm)
2045 *(cd->mcodeptr++) = 0xe8;
2050 void emit_call_mem(codegendata *cd, ptrint mem)
2052 *(cd->mcodeptr++) = 0xff;
2059 * floating point instructions (SSE2)
2061 void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2062 *(cd->mcodeptr++) = 0xf2;
2063 emit_rex(0,(dreg),0,(reg));
2064 *(cd->mcodeptr++) = 0x0f;
2065 *(cd->mcodeptr++) = 0x58;
2066 emit_reg((dreg),(reg));
2070 void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2071 *(cd->mcodeptr++) = 0xf3;
2072 emit_rex(0,(dreg),0,(reg));
2073 *(cd->mcodeptr++) = 0x0f;
2074 *(cd->mcodeptr++) = 0x58;
2075 emit_reg((dreg),(reg));
2079 void emit_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2080 *(cd->mcodeptr++) = 0xf3;
2081 emit_rex(1,(dreg),0,(reg));
2082 *(cd->mcodeptr++) = 0x0f;
2083 *(cd->mcodeptr++) = 0x2a;
2084 emit_reg((dreg),(reg));
2088 void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2089 *(cd->mcodeptr++) = 0xf3;
2090 emit_rex(0,(dreg),0,(reg));
2091 *(cd->mcodeptr++) = 0x0f;
2092 *(cd->mcodeptr++) = 0x2a;
2093 emit_reg((dreg),(reg));
2097 void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2098 *(cd->mcodeptr++) = 0xf2;
2099 emit_rex(1,(dreg),0,(reg));
2100 *(cd->mcodeptr++) = 0x0f;
2101 *(cd->mcodeptr++) = 0x2a;
2102 emit_reg((dreg),(reg));
2106 void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2107 *(cd->mcodeptr++) = 0xf2;
2108 emit_rex(0,(dreg),0,(reg));
2109 *(cd->mcodeptr++) = 0x0f;
2110 *(cd->mcodeptr++) = 0x2a;
2111 emit_reg((dreg),(reg));
2115 void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2116 *(cd->mcodeptr++) = 0xf3;
2117 emit_rex(0,(dreg),0,(reg));
2118 *(cd->mcodeptr++) = 0x0f;
2119 *(cd->mcodeptr++) = 0x5a;
2120 emit_reg((dreg),(reg));
2124 void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2125 *(cd->mcodeptr++) = 0xf2;
2126 emit_rex(0,(dreg),0,(reg));
2127 *(cd->mcodeptr++) = 0x0f;
2128 *(cd->mcodeptr++) = 0x5a;
2129 emit_reg((dreg),(reg));
2133 void emit_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2134 *(cd->mcodeptr++) = 0xf3;
2135 emit_rex(1,(dreg),0,(reg));
2136 *(cd->mcodeptr++) = 0x0f;
2137 *(cd->mcodeptr++) = 0x2c;
2138 emit_reg((dreg),(reg));
2142 void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2143 *(cd->mcodeptr++) = 0xf3;
2144 emit_rex(0,(dreg),0,(reg));
2145 *(cd->mcodeptr++) = 0x0f;
2146 *(cd->mcodeptr++) = 0x2c;
2147 emit_reg((dreg),(reg));
2151 void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2152 *(cd->mcodeptr++) = 0xf2;
2153 emit_rex(1,(dreg),0,(reg));
2154 *(cd->mcodeptr++) = 0x0f;
2155 *(cd->mcodeptr++) = 0x2c;
2156 emit_reg((dreg),(reg));
2160 void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2161 *(cd->mcodeptr++) = 0xf2;
2162 emit_rex(0,(dreg),0,(reg));
2163 *(cd->mcodeptr++) = 0x0f;
2164 *(cd->mcodeptr++) = 0x2c;
2165 emit_reg((dreg),(reg));
2169 void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2170 *(cd->mcodeptr++) = 0xf3;
2171 emit_rex(0,(dreg),0,(reg));
2172 *(cd->mcodeptr++) = 0x0f;
2173 *(cd->mcodeptr++) = 0x5e;
2174 emit_reg((dreg),(reg));
2178 void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2179 *(cd->mcodeptr++) = 0xf2;
2180 emit_rex(0,(dreg),0,(reg));
2181 *(cd->mcodeptr++) = 0x0f;
2182 *(cd->mcodeptr++) = 0x5e;
2183 emit_reg((dreg),(reg));
2187 void emit_movd_reg_freg(codegendata *cd, s8 reg, s8 freg) {
2188 *(cd->mcodeptr++) = 0x66;
2189 emit_rex(1,(freg),0,(reg));
2190 *(cd->mcodeptr++) = 0x0f;
2191 *(cd->mcodeptr++) = 0x6e;
2192 emit_reg((freg),(reg));
2196 void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg) {
2197 *(cd->mcodeptr++) = 0x66;
2198 emit_rex(1,(freg),0,(reg));
2199 *(cd->mcodeptr++) = 0x0f;
2200 *(cd->mcodeptr++) = 0x7e;
2201 emit_reg((freg),(reg));
2205 void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2206 *(cd->mcodeptr++) = 0x66;
2207 emit_rex(0,(reg),0,(basereg));
2208 *(cd->mcodeptr++) = 0x0f;
2209 *(cd->mcodeptr++) = 0x7e;
2210 emit_membase(cd, (basereg),(disp),(reg));
2214 void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2215 *(cd->mcodeptr++) = 0x66;
2216 emit_rex(0,(reg),(indexreg),(basereg));
2217 *(cd->mcodeptr++) = 0x0f;
2218 *(cd->mcodeptr++) = 0x7e;
2219 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2223 void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2224 *(cd->mcodeptr++) = 0x66;
2225 emit_rex(1,(dreg),0,(basereg));
2226 *(cd->mcodeptr++) = 0x0f;
2227 *(cd->mcodeptr++) = 0x6e;
2228 emit_membase(cd, (basereg),(disp),(dreg));
2232 void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2233 *(cd->mcodeptr++) = 0x66;
2234 emit_rex(0,(dreg),0,(basereg));
2235 *(cd->mcodeptr++) = 0x0f;
2236 *(cd->mcodeptr++) = 0x6e;
2237 emit_membase(cd, (basereg),(disp),(dreg));
2241 void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2242 *(cd->mcodeptr++) = 0x66;
2243 emit_rex(0,(dreg),(indexreg),(basereg));
2244 *(cd->mcodeptr++) = 0x0f;
2245 *(cd->mcodeptr++) = 0x6e;
2246 emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2250 void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2251 *(cd->mcodeptr++) = 0xf3;
2252 emit_rex(0,(dreg),0,(reg));
2253 *(cd->mcodeptr++) = 0x0f;
2254 *(cd->mcodeptr++) = 0x7e;
2255 emit_reg((dreg),(reg));
2259 void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2260 *(cd->mcodeptr++) = 0x66;
2261 emit_rex(0,(reg),0,(basereg));
2262 *(cd->mcodeptr++) = 0x0f;
2263 *(cd->mcodeptr++) = 0xd6;
2264 emit_membase(cd, (basereg),(disp),(reg));
2268 void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2269 *(cd->mcodeptr++) = 0xf3;
2270 emit_rex(0,(dreg),0,(basereg));
2271 *(cd->mcodeptr++) = 0x0f;
2272 *(cd->mcodeptr++) = 0x7e;
2273 emit_membase(cd, (basereg),(disp),(dreg));
2277 void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2278 *(cd->mcodeptr++) = 0xf3;
2279 emit_rex(0,(reg),0,(dreg));
2280 *(cd->mcodeptr++) = 0x0f;
2281 *(cd->mcodeptr++) = 0x10;
2282 emit_reg((reg),(dreg));
2286 void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2287 *(cd->mcodeptr++) = 0xf2;
2288 emit_rex(0,(reg),0,(dreg));
2289 *(cd->mcodeptr++) = 0x0f;
2290 *(cd->mcodeptr++) = 0x10;
2291 emit_reg((reg),(dreg));
2295 void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2296 *(cd->mcodeptr++) = 0xf3;
2297 emit_rex(0,(reg),0,(basereg));
2298 *(cd->mcodeptr++) = 0x0f;
2299 *(cd->mcodeptr++) = 0x11;
2300 emit_membase(cd, (basereg),(disp),(reg));
2304 /* Always emit a REX byte, because the instruction size can be smaller when */
2305 /* all register indexes are smaller than 7. */
2306 void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2307 *(cd->mcodeptr++) = 0xf3;
2308 emit_byte_rex((reg),0,(basereg));
2309 *(cd->mcodeptr++) = 0x0f;
2310 *(cd->mcodeptr++) = 0x11;
2311 emit_membase32(cd, (basereg),(disp),(reg));
2315 void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2316 *(cd->mcodeptr++) = 0xf2;
2317 emit_rex(0,(reg),0,(basereg));
2318 *(cd->mcodeptr++) = 0x0f;
2319 *(cd->mcodeptr++) = 0x11;
2320 emit_membase(cd, (basereg),(disp),(reg));
2324 /* Always emit a REX byte, because the instruction size can be smaller when */
2325 /* all register indexes are smaller than 7. */
2326 void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2327 *(cd->mcodeptr++) = 0xf2;
2328 emit_byte_rex((reg),0,(basereg));
2329 *(cd->mcodeptr++) = 0x0f;
2330 *(cd->mcodeptr++) = 0x11;
2331 emit_membase32(cd, (basereg),(disp),(reg));
2335 void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2336 *(cd->mcodeptr++) = 0xf3;
2337 emit_rex(0,(dreg),0,(basereg));
2338 *(cd->mcodeptr++) = 0x0f;
2339 *(cd->mcodeptr++) = 0x10;
2340 emit_membase(cd, (basereg),(disp),(dreg));
2344 /* Always emit a REX byte, because the instruction size can be smaller when */
2345 /* all register indexes are smaller than 7. */
2346 void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2347 *(cd->mcodeptr++) = 0xf3;
2348 emit_byte_rex((dreg),0,(basereg));
2349 *(cd->mcodeptr++) = 0x0f;
2350 *(cd->mcodeptr++) = 0x10;
2351 emit_membase32(cd, (basereg),(disp),(dreg));
2355 void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2357 emit_rex(0,(dreg),0,(basereg));
2358 *(cd->mcodeptr++) = 0x0f;
2359 *(cd->mcodeptr++) = 0x12;
2360 emit_membase(cd, (basereg),(disp),(dreg));
2364 void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2366 emit_rex(0,(reg),0,(basereg));
2367 *(cd->mcodeptr++) = 0x0f;
2368 *(cd->mcodeptr++) = 0x13;
2369 emit_membase(cd, (basereg),(disp),(reg));
2373 void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2374 *(cd->mcodeptr++) = 0xf2;
2375 emit_rex(0,(dreg),0,(basereg));
2376 *(cd->mcodeptr++) = 0x0f;
2377 *(cd->mcodeptr++) = 0x10;
2378 emit_membase(cd, (basereg),(disp),(dreg));
2382 /* Always emit a REX byte, because the instruction size can be smaller when */
2383 /* all register indexes are smaller than 7. */
2384 void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2385 *(cd->mcodeptr++) = 0xf2;
2386 emit_byte_rex((dreg),0,(basereg));
2387 *(cd->mcodeptr++) = 0x0f;
2388 *(cd->mcodeptr++) = 0x10;
2389 emit_membase32(cd, (basereg),(disp),(dreg));
2393 void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2395 *(cd->mcodeptr++) = 0x66;
2396 emit_rex(0,(dreg),0,(basereg));
2397 *(cd->mcodeptr++) = 0x0f;
2398 *(cd->mcodeptr++) = 0x12;
2399 emit_membase(cd, (basereg),(disp),(dreg));
2403 void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2405 *(cd->mcodeptr++) = 0x66;
2406 emit_rex(0,(reg),0,(basereg));
2407 *(cd->mcodeptr++) = 0x0f;
2408 *(cd->mcodeptr++) = 0x13;
2409 emit_membase(cd, (basereg),(disp),(reg));
2413 void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2414 *(cd->mcodeptr++) = 0xf3;
2415 emit_rex(0,(reg),(indexreg),(basereg));
2416 *(cd->mcodeptr++) = 0x0f;
2417 *(cd->mcodeptr++) = 0x11;
2418 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2422 void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2423 *(cd->mcodeptr++) = 0xf2;
2424 emit_rex(0,(reg),(indexreg),(basereg));
2425 *(cd->mcodeptr++) = 0x0f;
2426 *(cd->mcodeptr++) = 0x11;
2427 emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2431 void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2432 *(cd->mcodeptr++) = 0xf3;
2433 emit_rex(0,(dreg),(indexreg),(basereg));
2434 *(cd->mcodeptr++) = 0x0f;
2435 *(cd->mcodeptr++) = 0x10;
2436 emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2440 void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2441 *(cd->mcodeptr++) = 0xf2;
2442 emit_rex(0,(dreg),(indexreg),(basereg));
2443 *(cd->mcodeptr++) = 0x0f;
2444 *(cd->mcodeptr++) = 0x10;
2445 emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2449 void emit_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2450 *(cd->mcodeptr++) = 0xf3;
2451 emit_rex(0,(dreg),0,(reg));
2452 *(cd->mcodeptr++) = 0x0f;
2453 *(cd->mcodeptr++) = 0x59;
2454 emit_reg((dreg),(reg));
2458 void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2459 *(cd->mcodeptr++) = 0xf2;
2460 emit_rex(0,(dreg),0,(reg));
2461 *(cd->mcodeptr++) = 0x0f;
2462 *(cd->mcodeptr++) = 0x59;
2463 emit_reg((dreg),(reg));
2467 void emit_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2468 *(cd->mcodeptr++) = 0xf3;
2469 emit_rex(0,(dreg),0,(reg));
2470 *(cd->mcodeptr++) = 0x0f;
2471 *(cd->mcodeptr++) = 0x5c;
2472 emit_reg((dreg),(reg));
2476 void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2477 *(cd->mcodeptr++) = 0xf2;
2478 emit_rex(0,(dreg),0,(reg));
2479 *(cd->mcodeptr++) = 0x0f;
2480 *(cd->mcodeptr++) = 0x5c;
2481 emit_reg((dreg),(reg));
2485 void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2486 emit_rex(0,(dreg),0,(reg));
2487 *(cd->mcodeptr++) = 0x0f;
2488 *(cd->mcodeptr++) = 0x2e;
2489 emit_reg((dreg),(reg));
2493 void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2494 *(cd->mcodeptr++) = 0x66;
2495 emit_rex(0,(dreg),0,(reg));
2496 *(cd->mcodeptr++) = 0x0f;
2497 *(cd->mcodeptr++) = 0x2e;
2498 emit_reg((dreg),(reg));
2502 void emit_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2503 emit_rex(0,(dreg),0,(reg));
2504 *(cd->mcodeptr++) = 0x0f;
2505 *(cd->mcodeptr++) = 0x57;
2506 emit_reg((dreg),(reg));
2510 void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2511 emit_rex(0,(dreg),0,(basereg));
2512 *(cd->mcodeptr++) = 0x0f;
2513 *(cd->mcodeptr++) = 0x57;
2514 emit_membase(cd, (basereg),(disp),(dreg));
2518 void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2519 *(cd->mcodeptr++) = 0x66;
2520 emit_rex(0,(dreg),0,(reg));
2521 *(cd->mcodeptr++) = 0x0f;
2522 *(cd->mcodeptr++) = 0x57;
2523 emit_reg((dreg),(reg));
2527 void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2528 *(cd->mcodeptr++) = 0x66;
2529 emit_rex(0,(dreg),0,(basereg));
2530 *(cd->mcodeptr++) = 0x0f;
2531 *(cd->mcodeptr++) = 0x57;
2532 emit_membase(cd, (basereg),(disp),(dreg));
2536 /* system instructions ********************************************************/
2538 void emit_rdtsc(codegendata *cd)
2540 *(cd->mcodeptr++) = 0x0f;
2541 *(cd->mcodeptr++) = 0x31;
2546 * These are local overrides for various environment variables in Emacs.
2547 * Please do not remove this and leave it at the end of the file, where
2548 * Emacs will automagically detect them.
2549 * ---------------------------------------------------------------------
2552 * indent-tabs-mode: t