LCOV - code coverage report
Current view: top level - vm/jit/x86_64 - emit.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 929 1484 62.6 %
Date: 2017-07-14 10:03:36 Functions: 126 181 69.6 %

          Line data    Source code
       1             : /* src/vm/jit/x86_64/emit.cpp - x86_64 code emitter functions
       2             : 
       3             :    Copyright (C) 1996-2014
       4             :    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
       5             : 
       6             :    This file is part of CACAO.
       7             : 
       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.
      12             : 
      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.
      17             : 
      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
      21             :    02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : #include "config.h"
      26             : 
      27             : #include <cassert>
      28             : 
      29             : #include "vm/types.hpp"
      30             : #include "vm/os.hpp"
      31             : 
      32             : #include "md-abi.hpp"
      33             : 
      34             : #include "vm/jit/x86_64/codegen.hpp"
      35             : #include "vm/jit/x86_64/emit.hpp"
      36             : 
      37             : #include "mm/memory.hpp"
      38             : 
      39             : #include "threads/lock.hpp"
      40             : 
      41             : #include "vm/descriptor.hpp"            // for typedesc, methoddesc, etc
      42             : #include "vm/options.hpp"
      43             : 
      44             : #include "vm/jit/abi.hpp"
      45             : #include "vm/jit/abi-asm.hpp"
      46             : #include "vm/jit/asmpart.hpp"
      47             : #include "vm/jit/builtin.hpp"
      48             : #include "vm/jit/code.hpp"
      49             : #include "vm/jit/codegen-common.hpp"
      50             : #include "vm/jit/dseg.hpp"
      51             : #include "vm/jit/emit-common.hpp"
      52             : #include "vm/jit/jit.hpp"
      53             : #include "vm/jit/patcher-common.hpp"
      54             : #include "vm/jit/replace.hpp"
      55             : #include "vm/jit/trace.hpp"
      56             : #include "vm/jit/trap.hpp"
      57             : 
      58             : #include "vm/jit/ir/instruction.hpp"
      59             : 
      60             : 
      61             : /* emit_load *******************************************************************
      62             : 
      63             :    Emits a possible load of an operand.
      64             : 
      65             : *******************************************************************************/
      66             : 
      67     2335281 : s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
      68             : {
      69             :         codegendata  *cd;
      70             :         s4            disp;
      71             :         s4            reg;
      72             : 
      73             :         /* get required compiler data */
      74             : 
      75     2335281 :         cd = jd->cd;
      76             : 
      77     2335281 :         if (IS_INMEMORY(src->flags)) {
      78             :                 COUNT_SPILLS;
      79             : 
      80      110611 :                 disp = src->vv.regoff;
      81             : 
      82      110611 :                 switch (src->type) {
      83             :                 case TYPE_INT:
      84       43467 :                         M_ILD(tempreg, REG_SP, disp);
      85       43467 :                         break;
      86             :                 case TYPE_LNG:
      87             :                 case TYPE_ADR:
      88       64009 :                         M_LLD(tempreg, REG_SP, disp);
      89       64009 :                         break;
      90             :                 case TYPE_FLT:
      91        2766 :                         M_FLD(tempreg, REG_SP, disp);
      92        2766 :                         break;
      93             :                 case TYPE_DBL:
      94         369 :                         M_DLD(tempreg, REG_SP, disp);
      95         369 :                         break;
      96             :                 default:
      97           0 :                         vm_abort("emit_load: unknown type %d", src->type);
      98             :                         break;
      99             :                 }
     100             : 
     101      110611 :                 reg = tempreg;
     102             :         }
     103             :         else
     104     2224670 :                 reg = src->vv.regoff;
     105             : 
     106     2335281 :         return reg;
     107             : }
     108             : 
     109             : 
     110             : /* emit_store ******************************************************************
     111             : 
     112             :    This function generates the code to store the result of an
     113             :    operation back into a spilled pseudo-variable.  If the
     114             :    pseudo-variable has not been spilled in the first place, this
     115             :    function will generate nothing.
     116             :     
     117             : *******************************************************************************/
     118             : 
     119     1401358 : void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
     120             : {
     121             :         codegendata  *cd;
     122             :         s4            disp;
     123             : 
     124             :         /* get required compiler data */
     125             : 
     126     1401358 :         cd = jd->cd;
     127             : 
     128     1401358 :         if (IS_INMEMORY(dst->flags)) {
     129             :                 COUNT_SPILLS;
     130             : 
     131       56059 :                 disp = dst->vv.regoff;
     132             : 
     133       56059 :                 switch (dst->type) {
     134             :                 case TYPE_INT:
     135             :                 case TYPE_LNG:
     136             :                 case TYPE_ADR:
     137       55786 :                         M_LST(d, REG_SP, disp);
     138       55786 :                         break;
     139             :                 case TYPE_FLT:
     140         192 :                         M_FST(d, REG_SP, disp);
     141         192 :                         break;
     142             :                 case TYPE_DBL:
     143          81 :                         M_DST(d, REG_SP, disp);
     144          81 :                         break;
     145             :                 default:
     146           0 :                         vm_abort("emit_store: unknown type %d", dst->type);
     147             :                         break;
     148             :                 }
     149             :         }
     150     1401358 : }
     151             : 
     152             : 
     153             : /* emit_copy *******************************************************************
     154             : 
     155             :    Generates a register/memory to register/memory copy.
     156             : 
     157             : *******************************************************************************/
     158             : 
     159     1255932 : void emit_copy(jitdata *jd, instruction *iptr)
     160             : {
     161             :         codegendata *cd;
     162             :         varinfo     *src;
     163             :         varinfo     *dst;
     164             :         s4           s1, d;
     165             : 
     166             :         /* get required compiler data */
     167             : 
     168     1255932 :         cd = jd->cd;
     169             : 
     170             :         /* get source and destination variables */
     171             : 
     172     1255932 :         src = VAROP(iptr->s1);
     173     1255932 :         dst = VAROP(iptr->dst);
     174             : 
     175     1255932 :         if ((src->vv.regoff != dst->vv.regoff) ||
     176             :                 ((src->flags ^ dst->flags) & INMEMORY)) {
     177             : 
     178       75453 :                 if ((src->type == TYPE_RET) || (dst->type == TYPE_RET)) {
     179             :                         /* emit nothing, as the value won't be used anyway */
     180           1 :                         return;
     181             :                 }
     182             : 
     183             :                 /* If one of the variables resides in memory, we can eliminate
     184             :                    the register move from/to the temporary register with the
     185             :                    order of getting the destination register and the load. */
     186             : 
     187       75452 :                 if (IS_INMEMORY(src->flags)) {
     188        3079 :                         d  = codegen_reg_of_var(iptr->opc, dst, REG_IFTMP);
     189        3079 :                         s1 = emit_load(jd, iptr, src, d);
     190             :                 }
     191             :                 else {
     192       72373 :                         s1 = emit_load(jd, iptr, src, REG_IFTMP);
     193       72373 :                         d  = codegen_reg_of_var(iptr->opc, dst, s1);
     194             :                 }
     195             : 
     196       75452 :                 if (s1 != d) {
     197       62365 :                         switch (src->type) {
     198             :                         case TYPE_INT:
     199             :                         case TYPE_LNG:
     200             :                         case TYPE_ADR:
     201       61363 :                                 M_MOV(s1, d);
     202       61363 :                                 break;
     203             :                         case TYPE_FLT:
     204             :                         case TYPE_DBL:
     205        1002 :                                 M_FMOV(s1, d);
     206        1002 :                                 break;
     207             :                         default:
     208           0 :                                 vm_abort("emit_copy: unknown type %d", src->type);
     209             :                                 break;
     210             :                         }
     211             :                 }
     212             : 
     213       75452 :                 emit_store(jd, iptr, dst, d);
     214             :         }
     215             : }
     216             : 
     217             : 
     218           0 : void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d)
     219             : {
     220             : #if 0
     221             :         switch (iptr->flags.fields.condition) {
     222             :         case ICMD_IFEQ:
     223             :                 M_CMOVEQ(s, d);
     224             :                 break;
     225             :         case ICMD_IFNE:
     226             :                 M_CMOVNE(s, d);
     227             :                 break;
     228             :         case ICMD_IFLT:
     229             :                 M_CMOVLT(s, d);
     230             :                 break;
     231             :         case ICMD_IFGE:
     232             :                 M_CMOVGE(s, d);
     233             :                 break;
     234             :         case ICMD_IFGT:
     235             :                 M_CMOVGT(s, d);
     236             :                 break;
     237             :         case ICMD_IFLE:
     238             :                 M_CMOVLE(s, d);
     239             :                 break;
     240             :         }
     241             : #endif
     242           0 : }
     243             : 
     244             : 
     245             : /**
     246             :  * Emits code updating the condition register by comparing one integer
     247             :  * register to an immediate integer value.
     248             :  */
     249       57898 : void emit_icmp_imm(codegendata* cd, int reg, int32_t value)
     250             : {
     251       57898 :         M_ICMP_IMM(value, reg);
     252       57898 : }
     253             : 
     254             : 
     255             : /* emit_branch *****************************************************************
     256             : 
     257             :    Emits the code for conditional and unconditional branchs.
     258             : 
     259             : *******************************************************************************/
     260             : 
     261      171295 : void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 options)
     262             : {
     263             :         s4 branchdisp;
     264             : 
     265             :         /* NOTE: A displacement overflow cannot happen. */
     266             : 
     267             :         /* check which branch to generate */
     268             : 
     269      171295 :         if (condition == BRANCH_UNCONDITIONAL) {
     270             : 
     271             :                 /* calculate the different displacements */
     272             : 
     273       37090 :                 branchdisp = disp - BRANCH_UNCONDITIONAL_SIZE;
     274             : 
     275       37090 :                 M_JMP_IMM(branchdisp);
     276             :         }
     277             :         else {
     278             :                 /* calculate the different displacements */
     279             : 
     280      134205 :                 branchdisp = disp - BRANCH_CONDITIONAL_SIZE;
     281             : 
     282      134205 :                 switch (condition) {
     283             :                 case BRANCH_EQ:
     284       51195 :                         M_BEQ(branchdisp);
     285       51195 :                         break;
     286             :                 case BRANCH_NE:
     287       49872 :                         M_BNE(branchdisp);
     288       49872 :                         break;
     289             :                 case BRANCH_LT:
     290        9878 :                         M_BLT(branchdisp);
     291        9878 :                         break;
     292             :                 case BRANCH_GE:
     293        9028 :                         M_BGE(branchdisp);
     294        9028 :                         break;
     295             :                 case BRANCH_GT:
     296        6174 :                         M_BGT(branchdisp);
     297        6174 :                         break;
     298             :                 case BRANCH_LE:
     299        7986 :                         M_BLE(branchdisp);
     300        7986 :                         break;
     301             :                 case BRANCH_ULT:
     302           0 :                         M_BULT(branchdisp);
     303           0 :                         break;
     304             :                 case BRANCH_ULE:
     305           0 :                         M_BULE(branchdisp);
     306           0 :                         break;
     307             :                 case BRANCH_UGE:
     308           0 :                         M_BUGE(branchdisp);
     309           0 :                         break;
     310             :                 case BRANCH_UGT:
     311          72 :                         M_BUGT(branchdisp);
     312          72 :                         break;
     313             :                 default:
     314           0 :                         vm_abort("emit_branch: unknown condition %d", condition);
     315             :                         break;
     316             :                 }
     317             :         }
     318      171295 : }
     319             : 
     320             : 
     321             : /* emit_arithmetic_check *******************************************************
     322             : 
     323             :    Emit an ArithmeticException check.
     324             : 
     325             : *******************************************************************************/
     326             : 
     327        1946 : void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
     328             : {
     329        1946 :         if (INSTRUCTION_MUST_CHECK(iptr)) {
     330           0 :                 M_TEST(reg);
     331           0 :                 M_BNE(8);
     332           0 :                 M_ALD_MEM(reg, TRAP_ArithmeticException);
     333             :         }
     334        1946 : }
     335             : 
     336             : 
     337             : /* emit_arrayindexoutofbounds_check ********************************************
     338             : 
     339             :    Emit a ArrayIndexOutOfBoundsException check.
     340             : 
     341             : *******************************************************************************/
     342             : 
     343      606100 : void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
     344             : {
     345      606100 :         if (checkbounds && INSTRUCTION_MUST_CHECK(iptr)) {
     346      606100 :         M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size));
     347      606100 :         M_ICMP(REG_ITMP3, s2);
     348      606100 :                 M_BULT(8);
     349      606100 :                 M_ALD_MEM(s2, TRAP_ArrayIndexOutOfBoundsException);
     350             :         }
     351      606100 : }
     352             : 
     353             : 
     354             : /* emit_arraystore_check *******************************************************
     355             : 
     356             :    Emit an ArrayStoreException check.
     357             : 
     358             : *******************************************************************************/
     359             : 
     360       64566 : void emit_arraystore_check(codegendata *cd, instruction *iptr)
     361             : {
     362       64566 :         if (INSTRUCTION_MUST_CHECK(iptr)) {
     363       64566 :                 M_TEST(REG_RESULT);
     364       64566 :                 M_BNE(8);
     365       64566 :                 M_ALD_MEM(REG_RESULT, TRAP_ArrayStoreException);
     366             :         }
     367       64566 : }
     368             : 
     369             : 
     370             : /* emit_classcast_check ********************************************************
     371             : 
     372             :    Emit a ClassCastException check.
     373             : 
     374             : *******************************************************************************/
     375             : 
     376       11142 : void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
     377             : {
     378       11142 :         if (INSTRUCTION_MUST_CHECK(iptr)) {
     379       11142 :                 switch (condition) {
     380             :                 case BRANCH_LE:
     381        2093 :                         M_BGT(8);
     382        2093 :                         break;
     383             :                 case BRANCH_GE:
     384           0 :                         M_BLT(8);
     385           0 :                         break;
     386             :                 case BRANCH_EQ:
     387        3052 :                         M_BNE(8);
     388        3052 :                         break;
     389             :                 case BRANCH_NE:
     390        5997 :                         M_BEQ(8);
     391        5997 :                         break;
     392             :                 case BRANCH_UGT:
     393           0 :                         M_BULE(8);
     394           0 :                         break;
     395             :                 default:
     396           0 :                         vm_abort("emit_classcast_check: unknown condition %d", condition);
     397             :                         break;
     398             :                 }
     399       11142 :                 M_ALD_MEM(s1, TRAP_ClassCastException);
     400             :         }
     401       11142 : }
     402             : 
     403             : 
     404             : /* emit_nullpointer_check ******************************************************
     405             : 
     406             :    Emit a NullPointerException check.
     407             : 
     408             : *******************************************************************************/
     409             : 
     410       98529 : void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
     411             : {
     412       98529 :         if (INSTRUCTION_MUST_CHECK(iptr)) {
     413       98529 :                 M_TEST(reg);
     414       98529 :                 M_BNE(8);
     415       98529 :                 M_ALD_MEM(reg, TRAP_NullPointerException);
     416             :         }
     417       98529 : }
     418             : 
     419             : 
     420             : /* emit_exception_check ********************************************************
     421             : 
     422             :    Emit an Exception check.
     423             : 
     424             : *******************************************************************************/
     425             : 
     426          15 : void emit_exception_check(codegendata *cd, instruction *iptr)
     427             : {
     428          15 :         if (INSTRUCTION_MUST_CHECK(iptr)) {
     429          15 :                 M_TEST(REG_RESULT);
     430          15 :                 M_BNE(8);
     431          15 :                 M_ALD_MEM(REG_RESULT, TRAP_CHECK_EXCEPTION);
     432             :         }
     433          15 : }
     434             : 
     435             : 
     436             : /* emit_trap_compiler **********************************************************
     437             : 
     438             :    Emit a trap instruction which calls the JIT compiler.
     439             : 
     440             : *******************************************************************************/
     441             : 
     442      422722 : void emit_trap_compiler(codegendata *cd)
     443             : {
     444      422722 :         M_ALD_MEM(REG_METHODPTR, TRAP_COMPILER);
     445      422722 : }
     446             : 
     447         163 : void emit_abstractmethoderror_trap(codegendata *cd)
     448             : {
     449         163 :         M_ALD_MEM(REG_METHODPTR, TRAP_AbstractMethodError);
     450         163 : }
     451             : 
     452             : 
     453             : /* emit_patcher_alignment ******************************************************
     454             : 
     455             :    Emit NOP to ensure placement at an even address.
     456             : 
     457             : *******************************************************************************/
     458             : 
     459      142524 : void emit_patcher_alignment(codegendata *cd)
     460             : {
     461      142524 :         if ((uintptr_t) cd->mcodeptr & 1)
     462       87557 :                 M_NOP;
     463      142524 : }
     464             : 
     465             : 
     466             : /* emit_trap *******************************************************************
     467             : 
     468             :    Emit a trap instruction and return the original machine code.
     469             : 
     470             : *******************************************************************************/
     471             : 
     472      142524 : uint32_t emit_trap(codegendata *cd)
     473             : {
     474             :         uint16_t mcode;
     475             : 
     476             :         /* Get machine code which is patched back in later. The trap is 2
     477             :            bytes long. */
     478             : 
     479      142524 :         mcode = *((uint16_t *) cd->mcodeptr);
     480             : 
     481             :         /* XXX This needs to be change to INT3 when the debugging problems
     482             :            with gdb are resolved. */
     483             : 
     484      142524 :         M_UD2;
     485             : 
     486      142524 :         return mcode;
     487             : }
     488             : 
     489             : 
     490             : /**
     491             :  * Generates fast-path code for the below builtin.
     492             :  *   Function:  LOCK_monitor_enter
     493             :  *   Signature: (Ljava/lang/Object;)V
     494             :  *   Slow-path: bool lock_monitor_enter(java_handle_t*);
     495             :  */
     496        2549 : void emit_fastpath_monitor_enter(jitdata* jd, instruction* iptr, int d)
     497             : {
     498             :         // Get required compiler data.
     499        2549 :         codegendata* cd = jd->cd;
     500             : 
     501             :         // XXX Currently the fast-path always fails. Implement me!
     502        2549 :         M_CLR(d);
     503        2549 : }
     504             : 
     505             : 
     506             : /**
     507             :  * Generates fast-path code for the below builtin.
     508             :  *   Function:  LOCK_monitor_exit
     509             :  *   Signature: (Ljava/lang/Object;)V
     510             :  *   Slow-path: bool lock_monitor_exit(java_handle_t*);
     511             :  */
     512        5462 : void emit_fastpath_monitor_exit(jitdata* jd, instruction* iptr, int d)
     513             : {
     514             :         // Get required compiler data.
     515        5462 :         codegendata* cd = jd->cd;
     516             : 
     517             :         // XXX Currently the fast-path always fails. Implement me!
     518        5462 :         M_CLR(d);
     519        5462 : }
     520             : 
     521             : 
     522             : /**
     523             :  * Generates synchronization code to enter a monitor.
     524             :  */
     525        3217 : void emit_monitor_enter(jitdata* jd, int32_t syncslot_offset)
     526             : {
     527             :         // Get required compiler data.
     528        3217 :         methodinfo*  m  = jd->m;
     529        3217 :         codegendata* cd = jd->cd;
     530             : 
     531             : #ifndef NDEBUG
     532        3217 :         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
     533           0 :                 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
     534             : 
     535           0 :                 for (int32_t p = 0; p < INT_ARG_CNT; p++)
     536           0 :                         M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
     537             : 
     538           0 :                 for (int32_t p = 0; p < FLT_ARG_CNT; p++)
     539           0 :                         M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
     540             : 
     541           0 :                 syncslot_offset += (INT_ARG_CNT + FLT_ARG_CNT) * 8;
     542             :         }
     543             : #endif
     544             : 
     545             :         /* decide which monitor enter function to call */
     546             : 
     547        3217 :         if (m->flags & ACC_STATIC) {
     548         306 :                 M_MOV_IMM(&m->clazz->object.header, REG_A0);
     549             :         }
     550             :         else {
     551        2911 :                 M_TEST(REG_A0);
     552        2911 :                 M_BNE(8);
     553        2911 :                 M_ALD_MEM(REG_A0, TRAP_NullPointerException);
     554             :         }
     555             : 
     556        3217 :         M_AST(REG_A0, REG_SP, syncslot_offset);
     557        3217 :         M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
     558        3217 :         M_CALL(REG_ITMP1);
     559             : 
     560             : #ifndef NDEBUG
     561        3217 :         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
     562             : 
     563           0 :                 for (int32_t p = 0; p < INT_ARG_CNT; p++)
     564           0 :                         M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
     565             : 
     566           0 :                 for (int32_t p = 0; p < FLT_ARG_CNT; p++)
     567           0 :                         M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
     568             : 
     569           0 :                 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
     570             :         }
     571             : #endif
     572        3217 : }
     573             : 
     574             : 
     575             : /**
     576             :  * Generates synchronization code to leave a monitor.
     577             :  */
     578        4574 : void emit_monitor_exit(jitdata* jd, int32_t syncslot_offset)
     579             : {
     580             :         // Get required compiler data.
     581        4574 :         methodinfo*  m  = jd->m;
     582        4574 :         codegendata* cd = jd->cd;
     583             : 
     584        4574 :         M_ALD(REG_A0, REG_SP, syncslot_offset);
     585             : 
     586             :         /* we need to save the proper return value */
     587             : 
     588        4574 :         methoddesc* md = m->parseddesc;
     589             : 
     590        4574 :         switch (md->returntype.type) {
     591             :         case TYPE_INT:
     592             :         case TYPE_ADR:
     593             :         case TYPE_LNG:
     594        3316 :                 M_LST(REG_RESULT, REG_SP, syncslot_offset);
     595        3316 :                 break;
     596             :         case TYPE_FLT:
     597             :         case TYPE_DBL:
     598           0 :                 M_DST(REG_FRESULT, REG_SP, syncslot_offset);
     599           0 :                 break;
     600             :         case TYPE_VOID:
     601        1258 :                 break;
     602             :         default:
     603           0 :                 assert(false);
     604             :                 break;
     605             :         }
     606             : 
     607        4574 :         M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
     608        4574 :         M_CALL(REG_ITMP1);
     609             : 
     610             :         /* and now restore the proper return value */
     611             : 
     612        4574 :         switch (md->returntype.type) {
     613             :         case TYPE_INT:
     614             :         case TYPE_ADR:
     615             :         case TYPE_LNG:
     616        3316 :                 M_LLD(REG_RESULT, REG_SP, syncslot_offset);
     617        3316 :                 break;
     618             :         case TYPE_FLT:
     619             :         case TYPE_DBL:
     620           0 :                 M_DLD(REG_FRESULT, REG_SP, syncslot_offset);
     621           0 :                 break;
     622             :         case TYPE_VOID:
     623        1258 :                 break;
     624             :         default:
     625           0 :                 assert(false);
     626             :                 break;
     627             :         }
     628        4574 : }
     629             : 
     630             : 
     631             : /**
     632             :  * Emit profiling code for method frequency counting.
     633             :  */
     634             : #if defined(ENABLE_PROFILING)
     635             : void emit_profile_method(codegendata* cd, codeinfo* code)
     636             : {
     637             :         M_MOV_IMM(code, REG_ITMP3);
     638             :         M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
     639             : }
     640             : #endif
     641             : 
     642             : 
     643             : /**
     644             :  * Emit profiling code for basicblock frequency counting.
     645             :  */
     646             : #if defined(ENABLE_PROFILING)
     647             : void emit_profile_basicblock(codegendata* cd, codeinfo* code, basicblock* bptr)
     648             : {
     649             :         M_MOV_IMM(code->bbfrequency, REG_ITMP3);
     650             :         M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
     651             : }
     652             : #endif
     653             : 
     654             : 
     655             : /**
     656             :  * Emit profiling code to start CPU cycle counting.
     657             :  */
     658             : #if defined(ENABLE_PROFILING)
     659             : void emit_profile_cycle_start(codegendata* cd, codeinfo* code)
     660             : {
     661             :         M_PUSH(RAX);
     662             :         M_PUSH(RDX);
     663             : 
     664             :         M_MOV_IMM(code, REG_ITMP3);
     665             :         M_RDTSC;
     666             :         M_ISUB_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles));
     667             :         M_ISBB_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4);
     668             : 
     669             :         M_POP(RDX);
     670             :         M_POP(RAX);
     671             : }
     672             : #endif
     673             : 
     674             : 
     675             : /**
     676             :  * Emit profiling code to stop CPU cycle counting.
     677             :  */
     678             : #if defined(ENABLE_PROFILING)
     679             : void emit_profile_cycle_stop(codegendata* cd, codeinfo* code)
     680             : {
     681             :         M_PUSH(RAX);
     682             :         M_PUSH(RDX);
     683             : 
     684             :         M_MOV_IMM(code, REG_ITMP3);
     685             :         M_RDTSC;
     686             :         M_IADD_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles));
     687             :         M_IADC_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4);
     688             : 
     689             :         M_POP(RDX);
     690             :         M_POP(RAX);
     691             : }
     692             : #endif
     693             : 
     694             : 
     695             : /* emit_verbosecall_enter ******************************************************
     696             : 
     697             :    Generates the code for the call trace.
     698             : 
     699             : *******************************************************************************/
     700             : 
     701             : #if !defined(NDEBUG)
     702           0 : void emit_verbosecall_enter(jitdata *jd)
     703             : {
     704             :         methodinfo   *m;
     705             :         codeinfo     *code;
     706             :         codegendata  *cd;
     707             :         registerdata *rd;
     708             :         methoddesc   *md;
     709             :         s4            stackframesize;
     710             :         s4            i, s;
     711             : 
     712             :         /* get required compiler data */
     713             : 
     714           0 :         m    = jd->m;
     715           0 :         code = jd->code;
     716           0 :         cd   = jd->cd;
     717           0 :         rd   = jd->rd;
     718             : 
     719           0 :         md = m->parseddesc;
     720             : 
     721             :         /* mark trace code */
     722             : 
     723           0 :         M_NOP;
     724             : 
     725             :         /* keep 16-byte stack alignment */
     726             : 
     727           0 :         stackframesize = md->paramcount + ARG_CNT + TMP_CNT;
     728           0 :         ALIGN_2(stackframesize);
     729             : 
     730           0 :         M_LSUB_IMM(stackframesize * 8, REG_SP);
     731             : 
     732             :         /* save argument registers */
     733             : 
     734           0 :         for (i = 0; i < md->paramcount; i++) {
     735           0 :                 if (!md->params[i].inmemory) {
     736           0 :                         s = md->params[i].regoff;
     737             : 
     738           0 :                         switch (md->paramtypes[i].type) {
     739             :                         case TYPE_ADR:
     740             :                         case TYPE_INT:
     741             :                         case TYPE_LNG:
     742           0 :                                 M_LST(s, REG_SP, i * 8);
     743           0 :                                 break;
     744             :                         case TYPE_FLT:
     745             :                         case TYPE_DBL:
     746           0 :                                 M_DST(s, REG_SP, i * 8);
     747           0 :                                 break;
     748             :                         default:
     749           0 :                                 assert(false);
     750             :                                 break;
     751             :                         }
     752             :                 }
     753             :         }
     754             : 
     755             :         /* save all argument and temporary registers for leaf methods */
     756             : 
     757           0 :         if (code_is_leafmethod(code)) {
     758           0 :                 for (i = 0; i < INT_ARG_CNT; i++)
     759           0 :                         M_LST(abi_registers_integer_argument[i], REG_SP, (md->paramcount + i) * 8);
     760             : 
     761           0 :                 for (i = 0; i < FLT_ARG_CNT; i++)
     762           0 :                         M_DST(abi_registers_float_argument[i], REG_SP, (md->paramcount + INT_ARG_CNT + i) * 8);
     763             : 
     764           0 :                 for (i = 0; i < INT_TMP_CNT; i++)
     765           0 :                         M_LST(rd->tmpintregs[i], REG_SP, (md->paramcount + ARG_CNT + i) * 8);
     766             : 
     767           0 :                 for (i = 0; i < FLT_TMP_CNT; i++)
     768           0 :                         M_DST(rd->tmpfltregs[i], REG_SP, (md->paramcount + ARG_CNT + INT_TMP_CNT + i) * 8);
     769             :         }
     770             : 
     771           0 :         M_MOV_IMM(m, REG_A0);
     772           0 :         M_MOV(REG_SP, REG_A1);
     773           0 :         M_MOV(REG_SP, REG_A2);
     774           0 :         M_AADD_IMM((stackframesize + cd->stackframesize + 1) * 8, REG_A2);
     775           0 :         M_MOV_IMM(trace_java_call_enter, REG_ITMP1);
     776           0 :         M_CALL(REG_ITMP1);
     777             : 
     778             :         /* restore argument registers */
     779             : 
     780           0 :         for (i = 0; i < md->paramcount; i++) {
     781           0 :                 if (!md->params[i].inmemory) {
     782           0 :                         s = md->params[i].regoff;
     783             : 
     784           0 :                         switch (md->paramtypes[i].type) {
     785             :                         case TYPE_ADR:
     786             :                         case TYPE_INT:
     787             :                         case TYPE_LNG:
     788           0 :                                 M_LLD(s, REG_SP, i * 8);
     789           0 :                                 break;
     790             :                         case TYPE_FLT:
     791             :                         case TYPE_DBL:
     792           0 :                                 M_DLD(s, REG_SP, i * 8);
     793           0 :                                 break;
     794             :                         default:
     795           0 :                                 assert(false);
     796             :                                 break;
     797             :                         }
     798             :                 }
     799             :         }
     800             : 
     801             : 
     802             :         /* restore all argument and temporary registers for leaf methods */
     803             : 
     804           0 :         if (code_is_leafmethod(code)) {
     805           0 :                 for (i = 0; i < INT_ARG_CNT; i++)
     806           0 :                         M_LLD(abi_registers_integer_argument[i], REG_SP, (md->paramcount + i) * 8);
     807             : 
     808           0 :                 for (i = 0; i < FLT_ARG_CNT; i++)
     809           0 :                         M_DLD(abi_registers_float_argument[i], REG_SP, (md->paramcount + INT_ARG_CNT + i) * 8);
     810             : 
     811           0 :                 for (i = 0; i < INT_TMP_CNT; i++)
     812           0 :                         M_LLD(rd->tmpintregs[i], REG_SP, (md->paramcount + ARG_CNT + i) * 8);
     813             : 
     814           0 :                 for (i = 0; i < FLT_TMP_CNT; i++)
     815           0 :                         M_DLD(rd->tmpfltregs[i], REG_SP, (md->paramcount + ARG_CNT + INT_TMP_CNT + i) * 8);
     816             :         }
     817             : 
     818           0 :         M_LADD_IMM(stackframesize * 8, REG_SP);
     819             : 
     820             :         /* mark trace code */
     821             : 
     822           0 :         M_NOP;
     823           0 : }
     824             : #endif /* !defined(NDEBUG) */
     825             : 
     826             : 
     827             : /* emit_verbosecall_exit *******************************************************
     828             : 
     829             :    Generates the code for the call trace.
     830             : 
     831             : *******************************************************************************/
     832             : 
     833             : #if !defined(NDEBUG)
     834           0 : void emit_verbosecall_exit(jitdata *jd)
     835             : {
     836             :         methodinfo   *m;
     837             :         codegendata  *cd;
     838             :         //registerdata *rd;
     839             :         methoddesc   *md;
     840             : 
     841             :         /* get required compiler data */
     842             : 
     843           0 :         m  = jd->m;
     844           0 :         cd = jd->cd;
     845             :         //rd = jd->rd;
     846             : 
     847           0 :         md = m->parseddesc;
     848             : 
     849             :         /* mark trace code */
     850             : 
     851           0 :         M_NOP;
     852             : 
     853             :         /* keep 16-byte stack alignment */
     854             : 
     855           0 :         M_ASUB_IMM(2 * 8, REG_SP);
     856             : 
     857             :         /* save return value */
     858             : 
     859           0 :         switch (md->returntype.type) {
     860             :         case TYPE_ADR:
     861             :         case TYPE_INT:
     862             :         case TYPE_LNG:
     863           0 :                 M_LST(REG_RESULT, REG_SP, 0 * 8);
     864           0 :                 break;
     865             :         case TYPE_FLT:
     866             :         case TYPE_DBL:
     867           0 :                 M_DST(REG_FRESULT, REG_SP, 0 * 8);
     868           0 :                 break;
     869             :         case TYPE_VOID:
     870           0 :                 break;
     871             :         default:
     872           0 :                 assert(false);
     873             :                 break;
     874             :         }
     875             : 
     876           0 :         M_MOV_IMM(m, REG_A0);
     877           0 :         M_MOV(REG_SP, REG_A1);
     878             : 
     879           0 :         M_MOV_IMM(trace_java_call_exit, REG_ITMP1);
     880           0 :         M_CALL(REG_ITMP1);
     881             : 
     882             :         /* restore return value */
     883             : 
     884           0 :         switch (md->returntype.type) {
     885             :         case TYPE_ADR:
     886             :         case TYPE_INT:
     887             :         case TYPE_LNG:
     888           0 :                 M_LLD(REG_RESULT, REG_SP, 0 * 8);
     889           0 :                 break;
     890             :         case TYPE_FLT:
     891             :         case TYPE_DBL:
     892           0 :                 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
     893           0 :                 break;
     894             :         case TYPE_VOID:
     895           0 :                 break;
     896             :         default:
     897           0 :                 assert(false);
     898             :                 break;
     899             :         }
     900             : 
     901           0 :         M_AADD_IMM(2 * 8, REG_SP);
     902             : 
     903             :         /* mark trace code */
     904             : 
     905           0 :         M_NOP;
     906           0 : }
     907             : #endif /* !defined(NDEBUG) */
     908             : 
     909             : 
     910             : /* code generation functions **************************************************/
     911             : 
     912     1977812 : static void emit_membase(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
     913             : {
     914     2678970 :         if ((basereg == REG_SP) || (basereg == R12)) {
     915      701158 :                 if (disp == 0) {
     916      181628 :                         emit_address_byte(0, dreg, REG_SP);
     917      181628 :                         emit_address_byte(0, REG_SP, REG_SP);
     918             : 
     919     1024738 :                 } else if (IS_IMM8(disp)) {
     920      505208 :                         emit_address_byte(1, dreg, REG_SP);
     921      505208 :                         emit_address_byte(0, REG_SP, REG_SP);
     922      505208 :                         emit_imm8(disp);
     923             : 
     924             :                 } else {
     925       14322 :                         emit_address_byte(2, dreg, REG_SP);
     926       14322 :                         emit_address_byte(0, REG_SP, REG_SP);
     927       14322 :                         emit_imm32(disp);
     928             :                 }
     929             : 
     930     1485586 :         } else if ((disp) == 0 && (basereg) != RBP && (basereg) != R13) {
     931      208932 :                 emit_address_byte(0,(dreg),(basereg));
     932             : 
     933     1067722 :         } else if ((basereg) == RIP) {
     934      434175 :                 emit_address_byte(0, dreg, RBP);
     935      434175 :                 emit_imm32(disp);
     936             : 
     937             :         } else {
     938     1266964 :                 if (IS_IMM8(disp)) {
     939      633417 :                         emit_address_byte(1, dreg, basereg);
     940      633417 :                         emit_imm8(disp);
     941             : 
     942             :                 } else {
     943         130 :                         emit_address_byte(2, dreg, basereg);
     944         130 :                         emit_imm32(disp);
     945             :                 }
     946             :         }
     947     1977812 : }
     948             : 
     949             : 
     950      287872 : static void emit_membase32(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
     951             : {
     952      290944 :         if ((basereg == REG_SP) || (basereg == R12)) {
     953        3072 :                 emit_address_byte(2, dreg, REG_SP);
     954        3072 :                 emit_address_byte(0, REG_SP, REG_SP);
     955        3072 :                 emit_imm32(disp);
     956             :         }
     957             :         else {
     958      284800 :                 emit_address_byte(2, dreg, basereg);
     959      284800 :                 emit_imm32(disp);
     960             :         }
     961      287872 : }
     962             : 
     963             : 
     964      610432 : static void emit_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
     965             : {
     966      610432 :         if (basereg == -1) {
     967           0 :                 emit_address_byte(0, reg, 4);
     968           0 :                 emit_address_byte(scale, indexreg, 5);
     969           0 :                 emit_imm32(disp);
     970             :         }
     971      612562 :         else if ((disp == 0) && (basereg != RBP) && (basereg != R13)) {
     972        2130 :                 emit_address_byte(0, reg, 4);
     973        2130 :                 emit_address_byte(scale, indexreg, basereg);
     974             :         }
     975     1216557 :         else if (IS_IMM8(disp)) {
     976      608255 :                 emit_address_byte(1, reg, 4);
     977      608255 :                 emit_address_byte(scale, indexreg, basereg);
     978      608255 :                 emit_imm8(disp);
     979             :         }
     980             :         else {
     981          47 :                 emit_address_byte(2, reg, 4);
     982          47 :                 emit_address_byte(scale, indexreg, basereg);
     983          47 :                 emit_imm32(disp);
     984             :         }
     985      610432 : }
     986             : 
     987             : 
     988         318 : void emit_ishift(jitdata *jd, s4 shift_op, instruction *iptr)
     989             : {
     990             :         s4 s1, s2, d, d_old;
     991             :         varinfo *v_s1,*v_s2,*v_dst;
     992             :         codegendata *cd;
     993             : 
     994             :         /* get required compiler data */
     995             : 
     996         318 :         cd = jd->cd;
     997             : 
     998         318 :         v_s1  = VAROP(iptr->s1);
     999         318 :         v_s2  = VAROP(iptr->sx.s23.s2);
    1000         318 :         v_dst = VAROP(iptr->dst);
    1001             : 
    1002         318 :         s1 = v_s1->vv.regoff;
    1003         318 :         s2 = v_s2->vv.regoff;
    1004         318 :         d  = v_dst->vv.regoff;
    1005             : 
    1006         318 :         M_INTMOVE(RCX, REG_ITMP1);                                    /* save RCX */
    1007             : 
    1008         318 :         if (IS_INMEMORY(v_dst->flags)) {
    1009          18 :                 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
    1010           0 :                         if (s1 == d) {
    1011           0 :                                 M_ILD(RCX, REG_SP, s2);
    1012           0 :                                 emit_shiftl_membase(cd, shift_op, REG_SP, d);
    1013             : 
    1014             :                         } else {
    1015           0 :                                 M_ILD(RCX, REG_SP, s2);
    1016           0 :                                 M_ILD(REG_ITMP2, REG_SP, s1);
    1017           0 :                                 emit_shiftl_reg(cd, shift_op, REG_ITMP2);
    1018           0 :                                 M_IST(REG_ITMP2, REG_SP, d);
    1019             :                         }
    1020             : 
    1021          18 :                 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
    1022             :                         /* s1 may be equal to RCX */
    1023           0 :                         if (s1 == RCX) {
    1024           0 :                                 if (s2 == d) {
    1025           0 :                                         M_ILD(REG_ITMP1, REG_SP, s2);
    1026           0 :                                         M_IST(s1, REG_SP, d);
    1027           0 :                                         M_INTMOVE(REG_ITMP1, RCX);
    1028             : 
    1029             :                                 } else {
    1030           0 :                                         M_IST(s1, REG_SP, d);
    1031           0 :                                         M_ILD(RCX, REG_SP, s2);
    1032             :                                 }
    1033             : 
    1034             :                         } else {
    1035           0 :                                 M_ILD(RCX, REG_SP, s2);
    1036           0 :                                 M_IST(s1, REG_SP, d);
    1037             :                         }
    1038             : 
    1039           0 :                         emit_shiftl_membase(cd, shift_op, REG_SP, d);
    1040             : 
    1041          18 :                 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
    1042           0 :                         if (s1 == d) {
    1043           0 :                                 M_INTMOVE(s2, RCX);
    1044           0 :                                 emit_shiftl_membase(cd, shift_op, REG_SP, d);
    1045             : 
    1046             :                         } else {
    1047           0 :                                 M_INTMOVE(s2, RCX);
    1048           0 :                                 M_ILD(REG_ITMP2, REG_SP, s1);
    1049           0 :                                 emit_shiftl_reg(cd, shift_op, REG_ITMP2);
    1050           0 :                                 M_IST(REG_ITMP2, REG_SP, d);
    1051             :                         }
    1052             : 
    1053             :                 } else {
    1054             :                         /* s1 may be equal to RCX */
    1055          18 :                         M_IST(s1, REG_SP, d);
    1056          18 :                         M_INTMOVE(s2, RCX);
    1057          18 :                         emit_shiftl_membase(cd, shift_op, REG_SP, d);
    1058             :                 }
    1059             : 
    1060          18 :                 M_INTMOVE(REG_ITMP1, RCX);                             /* restore RCX */
    1061             : 
    1062             :         } else {
    1063         300 :                 d_old = d;
    1064         300 :                 if (d == RCX) {
    1065         153 :                         d = REG_ITMP3;
    1066             :                 }
    1067             :                                         
    1068         300 :                 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
    1069           0 :                         M_ILD(RCX, REG_SP, s2);
    1070           0 :                         M_ILD(d, REG_SP, s1);
    1071           0 :                         emit_shiftl_reg(cd, shift_op, d);
    1072             : 
    1073         300 :                 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
    1074             :                         /* s1 may be equal to RCX */
    1075          12 :                         M_INTMOVE(s1, d);
    1076          12 :                         M_ILD(RCX, REG_SP, s2);
    1077          12 :                         emit_shiftl_reg(cd, shift_op, d);
    1078             : 
    1079         288 :                 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
    1080           0 :                         M_INTMOVE(s2, RCX);
    1081           0 :                         M_ILD(d, REG_SP, s1);
    1082           0 :                         emit_shiftl_reg(cd, shift_op, d);
    1083             : 
    1084             :                 } else {
    1085             :                         /* s1 may be equal to RCX */
    1086         288 :                         if (s1 == RCX) {
    1087          12 :                                 if (s2 == d) {
    1088             :                                         /* d cannot be used to backup s1 since this would
    1089             :                                            overwrite s2. */
    1090           0 :                                         M_INTMOVE(s1, REG_ITMP3);
    1091           0 :                                         M_INTMOVE(s2, RCX);
    1092           0 :                                         M_INTMOVE(REG_ITMP3, d);
    1093             : 
    1094             :                                 } else {
    1095          12 :                                         M_INTMOVE(s1, d);
    1096          12 :                                         M_INTMOVE(s2, RCX);
    1097             :                                 }
    1098             : 
    1099             :                         } else {
    1100             :                                 /* d may be equal to s2 */
    1101         276 :                                 M_INTMOVE(s2, RCX);
    1102         276 :                                 M_INTMOVE(s1, d);
    1103             :                         }
    1104         288 :                         emit_shiftl_reg(cd, shift_op, d);
    1105             :                 }
    1106             : 
    1107         300 :                 if (d_old == RCX)
    1108         153 :                         M_INTMOVE(REG_ITMP3, RCX);
    1109             :                 else
    1110         147 :                         M_INTMOVE(REG_ITMP1, RCX);                         /* restore RCX */
    1111             :         }
    1112         318 : }
    1113             : 
    1114             : 
    1115          31 : void emit_lshift(jitdata *jd, s4 shift_op, instruction *iptr)
    1116             : {
    1117             :         s4 s1, s2, d, d_old;
    1118             :         varinfo *v_s1,*v_s2,*v_dst;
    1119             :         codegendata *cd;
    1120             : 
    1121             :         /* get required compiler data */
    1122             : 
    1123          31 :         cd = jd->cd;
    1124             : 
    1125          31 :         v_s1  = VAROP(iptr->s1);
    1126          31 :         v_s2  = VAROP(iptr->sx.s23.s2);
    1127          31 :         v_dst = VAROP(iptr->dst);
    1128             : 
    1129          31 :         s1 = v_s1->vv.regoff;
    1130          31 :         s2 = v_s2->vv.regoff;
    1131          31 :         d  = v_dst->vv.regoff;
    1132             :         
    1133          31 :         M_INTMOVE(RCX, REG_ITMP1);                                    /* save RCX */
    1134             : 
    1135          31 :         if (IS_INMEMORY(v_dst->flags)) {
    1136           0 :                 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
    1137           0 :                         if (s1 == d) {
    1138           0 :                                 M_ILD(RCX, REG_SP, s2);
    1139           0 :                                 emit_shift_membase(cd, shift_op, REG_SP, d);
    1140             : 
    1141             :                         } else {
    1142           0 :                                 M_ILD(RCX, REG_SP, s2);
    1143           0 :                                 M_LLD(REG_ITMP2, REG_SP, s1);
    1144           0 :                                 emit_shift_reg(cd, shift_op, REG_ITMP2);
    1145           0 :                                 M_LST(REG_ITMP2, REG_SP, d);
    1146             :                         }
    1147             : 
    1148           0 :                 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
    1149             :                         /* s1 may be equal to RCX */
    1150           0 :                         if (s1 == RCX) {
    1151           0 :                                 if (s2 == d) {
    1152           0 :                                         M_ILD(REG_ITMP1, REG_SP, s2);
    1153           0 :                                         M_LST(s1, REG_SP, d);
    1154           0 :                                         M_INTMOVE(REG_ITMP1, RCX);
    1155             : 
    1156             :                                 } else {
    1157           0 :                                         M_LST(s1, REG_SP, d);
    1158           0 :                                         M_ILD(RCX, REG_SP, s2);
    1159             :                                 }
    1160             : 
    1161             :                         } else {
    1162           0 :                                 M_ILD(RCX, REG_SP, s2);
    1163           0 :                                 M_LST(s1, REG_SP, d);
    1164             :                         }
    1165             : 
    1166           0 :                         emit_shift_membase(cd, shift_op, REG_SP, d);
    1167             : 
    1168           0 :                 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
    1169           0 :                         if (s1 == d) {
    1170           0 :                                 M_INTMOVE(s2, RCX);
    1171           0 :                                 emit_shift_membase(cd, shift_op, REG_SP, d);
    1172             : 
    1173             :                         } else {
    1174           0 :                                 M_INTMOVE(s2, RCX);
    1175           0 :                                 M_LLD(REG_ITMP2, REG_SP, s1);
    1176           0 :                                 emit_shift_reg(cd, shift_op, REG_ITMP2);
    1177           0 :                                 M_LST(REG_ITMP2, REG_SP, d);
    1178             :                         }
    1179             : 
    1180             :                 } else {
    1181             :                         /* s1 may be equal to RCX */
    1182           0 :                         M_LST(s1, REG_SP, d);
    1183           0 :                         M_INTMOVE(s2, RCX);
    1184           0 :                         emit_shift_membase(cd, shift_op, REG_SP, d);
    1185             :                 }
    1186             : 
    1187           0 :                 M_INTMOVE(REG_ITMP1, RCX);                             /* restore RCX */
    1188             : 
    1189             :         } else {
    1190          31 :                 d_old = d;
    1191          31 :                 if (d == RCX) {
    1192           6 :                         d = REG_ITMP3;
    1193             :                 }
    1194             : 
    1195          31 :                 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
    1196           0 :                         M_ILD(RCX, REG_SP, s2);
    1197           0 :                         M_LLD(d, REG_SP, s1);
    1198           0 :                         emit_shift_reg(cd, shift_op, d);
    1199             : 
    1200          31 :                 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
    1201             :                         /* s1 may be equal to RCX */
    1202           0 :                         M_INTMOVE(s1, d);
    1203           0 :                         M_ILD(RCX, REG_SP, s2);
    1204           0 :                         emit_shift_reg(cd, shift_op, d);
    1205             : 
    1206          31 :                 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
    1207           0 :                         M_INTMOVE(s2, RCX);
    1208           0 :                         M_LLD(d, REG_SP, s1);
    1209           0 :                         emit_shift_reg(cd, shift_op, d);
    1210             : 
    1211             :                 } else {
    1212             :                         /* s1 may be equal to RCX */
    1213          31 :                         if (s1 == RCX) {
    1214           6 :                                 if (s2 == d) {
    1215             :                                         /* d cannot be used to backup s1 since this would
    1216             :                                            overwrite s2. */
    1217           0 :                                         M_INTMOVE(s1, REG_ITMP3);
    1218           0 :                                         M_INTMOVE(s2, RCX);
    1219           0 :                                         M_INTMOVE(REG_ITMP3, d);
    1220             : 
    1221             :                                 } else {
    1222           6 :                                         M_INTMOVE(s1, d);
    1223           6 :                                         M_INTMOVE(s2, RCX);
    1224             :                                 }
    1225             : 
    1226             :                         } else {
    1227             :                                 /* d may be equal to s2 */
    1228          25 :                                 M_INTMOVE(s2, RCX);
    1229          25 :                                 M_INTMOVE(s1, d);
    1230             :                         }
    1231          31 :                         emit_shift_reg(cd, shift_op, d);
    1232             :                 }
    1233             : 
    1234          31 :                 if (d_old == RCX)
    1235           6 :                         M_INTMOVE(REG_ITMP3, RCX);
    1236             :                 else
    1237          25 :                         M_INTMOVE(REG_ITMP1, RCX);                         /* restore RCX */
    1238             :         }
    1239          31 : }
    1240             : 
    1241             : 
    1242             : /* low-level code emitter functions *******************************************/
    1243             : 
    1244      295745 : void emit_nop(codegendata *cd, int length)
    1245             : {
    1246      295745 :     assert(length >= 1 && length <= 9);
    1247      295745 :     switch (length) {
    1248             :     case 1:
    1249       20205 :         *(cd->mcodeptr++) = 0x90;
    1250       20205 :         break;
    1251             :     case 2:
    1252      178601 :         *(cd->mcodeptr++) = 0x66;
    1253      178601 :         *(cd->mcodeptr++) = 0x90;
    1254      178601 :         break;
    1255             :     case 3:
    1256       18296 :         *(cd->mcodeptr++) = 0x0f;
    1257       18296 :         *(cd->mcodeptr++) = 0x1f;
    1258       18296 :         *(cd->mcodeptr++) = 0x00;
    1259       18296 :         break;
    1260             :     case 4:
    1261       21865 :         *(cd->mcodeptr++) = 0x0f;
    1262       21865 :         *(cd->mcodeptr++) = 0x1f;
    1263       21865 :         *(cd->mcodeptr++) = 0x40;
    1264       21865 :         *(cd->mcodeptr++) = 0x00;
    1265       21865 :         break;
    1266             :     case 5:
    1267       18728 :         *(cd->mcodeptr++) = 0x0f;
    1268       18728 :         *(cd->mcodeptr++) = 0x1f;
    1269       18728 :         *(cd->mcodeptr++) = 0x44;
    1270       18728 :         *(cd->mcodeptr++) = 0x00;
    1271       18728 :         *(cd->mcodeptr++) = 0x00;
    1272       18728 :         break;
    1273             :     case 6:
    1274       18653 :         *(cd->mcodeptr++) = 0x66;
    1275       18653 :         *(cd->mcodeptr++) = 0x0f;
    1276       18653 :         *(cd->mcodeptr++) = 0x1f;
    1277       18653 :         *(cd->mcodeptr++) = 0x44;
    1278       18653 :         *(cd->mcodeptr++) = 0x00;
    1279       18653 :         *(cd->mcodeptr++) = 0x00;
    1280       18653 :         break;
    1281             :     case 7:
    1282       19397 :         *(cd->mcodeptr++) = 0x0f;
    1283       19397 :         *(cd->mcodeptr++) = 0x1f;
    1284       19397 :         *(cd->mcodeptr++) = 0x80;
    1285       19397 :         *(cd->mcodeptr++) = 0x00;
    1286       19397 :         *(cd->mcodeptr++) = 0x00;
    1287       19397 :         *(cd->mcodeptr++) = 0x00;
    1288       19397 :         *(cd->mcodeptr++) = 0x00;
    1289       19397 :         break;
    1290             :     case 8:
    1291           0 :         *(cd->mcodeptr++) = 0x0f;
    1292           0 :         *(cd->mcodeptr++) = 0x1f;
    1293           0 :         *(cd->mcodeptr++) = 0x84;
    1294           0 :         *(cd->mcodeptr++) = 0x00;
    1295           0 :         *(cd->mcodeptr++) = 0x00;
    1296           0 :         *(cd->mcodeptr++) = 0x00;
    1297           0 :         *(cd->mcodeptr++) = 0x00;
    1298           0 :         *(cd->mcodeptr++) = 0x00;
    1299           0 :         break;
    1300             :     case 9:
    1301           0 :         *(cd->mcodeptr++) = 0x66;
    1302           0 :         *(cd->mcodeptr++) = 0x0f;
    1303           0 :         *(cd->mcodeptr++) = 0x1f;
    1304           0 :         *(cd->mcodeptr++) = 0x84;
    1305           0 :         *(cd->mcodeptr++) = 0x00;
    1306           0 :         *(cd->mcodeptr++) = 0x00;
    1307           0 :         *(cd->mcodeptr++) = 0x00;
    1308           0 :         *(cd->mcodeptr++) = 0x00;
    1309           0 :         *(cd->mcodeptr++) = 0x00;
    1310             :         break;
    1311             :     }
    1312      295745 : }
    1313             :  
    1314       29486 : void emit_arbitrary_nop(codegendata *cd, int disp)
    1315             : {
    1316       76232 :         while (disp) {
    1317       17260 :                 int x = disp < 9 ? disp : 9;
    1318       17260 :                 emit_nop(cd, x);
    1319       17260 :                 disp -= x;
    1320             :         }
    1321       29486 : }
    1322             : 
    1323      955103 : void emit_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg)
    1324             : {
    1325      955103 :         emit_rex(1,(reg),0,(dreg));
    1326      955103 :         *(cd->mcodeptr++) = 0x89;
    1327      955103 :         emit_reg((reg),(dreg));
    1328      955103 : }
    1329             : 
    1330             : 
    1331      200932 : void emit_mov_imm_reg(codegendata *cd, s8 imm, s8 reg)
    1332             : {
    1333      200932 :         emit_rex(1,0,0,(reg));
    1334      200932 :         *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
    1335      200932 :         emit_imm64((imm));
    1336      200932 : }
    1337             : 
    1338             : 
    1339         267 : void emit_movl_reg_reg(codegendata *cd, s8 reg, s8 dreg)
    1340             : {
    1341         267 :         emit_rex(0,(reg),0,(dreg));
    1342         267 :         *(cd->mcodeptr++) = 0x89;
    1343         267 :         emit_reg((reg),(dreg));
    1344         267 : }
    1345             : 
    1346             : 
    1347      621565 : void emit_movl_imm_reg(codegendata *cd, s8 imm, s8 reg) {
    1348      621565 :         emit_rex(0,0,0,(reg));
    1349      621565 :         *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
    1350      621565 :         emit_imm32((imm));
    1351      621565 : }
    1352             : 
    1353             : 
    1354      937429 : void emit_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
    1355      937429 :         emit_rex(1,(reg),0,(basereg));
    1356      937429 :         *(cd->mcodeptr++) = 0x8b;
    1357      937429 :         emit_membase(cd, (basereg),(disp),(reg));
    1358      937429 : }
    1359             : 
    1360             : 
    1361             : /*
    1362             :  * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
    1363             :  * constant membase immediate length of 32bit
    1364             :  */
    1365      198112 : void emit_mov_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
    1366      198112 :         emit_rex(1,(reg),0,(basereg));
    1367      198112 :         *(cd->mcodeptr++) = 0x8b;
    1368      198112 :         emit_membase32(cd, (basereg),(disp),(reg));
    1369      198112 : }
    1370             : 
    1371             : 
    1372      669586 : void emit_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
    1373             : {
    1374      669586 :         emit_rex(0,(reg),0,(basereg));
    1375      669586 :         *(cd->mcodeptr++) = 0x8b;
    1376      669586 :         emit_membase(cd, (basereg),(disp),(reg));
    1377      669586 : }
    1378             : 
    1379             : 
    1380             : /* ATTENTION: Always emit a REX byte, because the instruction size can
    1381             :    be smaller when all register indexes are smaller than 7. */
    1382       40872 : void emit_movl_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
    1383             : {
    1384       40872 :         emit_byte_rex((reg),0,(basereg));
    1385       40872 :         *(cd->mcodeptr++) = 0x8b;
    1386       40872 :         emit_membase32(cd, (basereg),(disp),(reg));
    1387       40872 : }
    1388             : 
    1389             : 
    1390      319941 : void emit_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
    1391      319941 :         emit_rex(1,(reg),0,(basereg));
    1392      319941 :         *(cd->mcodeptr++) = 0x89;
    1393      319941 :         emit_membase(cd, (basereg),(disp),(reg));
    1394      319941 : }
    1395             : 
    1396             : 
    1397       25882 : void emit_mov_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
    1398       25882 :         emit_rex(1,(reg),0,(basereg));
    1399       25882 :         *(cd->mcodeptr++) = 0x89;
    1400       25882 :         emit_membase32(cd, (basereg),(disp),(reg));
    1401       25882 : }
    1402             : 
    1403             : 
    1404        1552 : void emit_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
    1405        1552 :         emit_rex(0,(reg),0,(basereg));
    1406        1552 :         *(cd->mcodeptr++) = 0x89;
    1407        1552 :         emit_membase(cd, (basereg),(disp),(reg));
    1408        1552 : }
    1409             : 
    1410             : 
    1411             : /* Always emit a REX byte, because the instruction size can be smaller when   */
    1412             : /* all register indexes are smaller than 7.                                   */
    1413       13573 : void emit_movl_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
    1414       13573 :         emit_byte_rex((reg),0,(basereg));
    1415       13573 :         *(cd->mcodeptr++) = 0x89;
    1416       13573 :         emit_membase32(cd, (basereg),(disp),(reg));
    1417       13573 : }
    1418             : 
    1419             : 
    1420       21338 : void emit_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
    1421       21338 :         emit_rex(1,(reg),(indexreg),(basereg));
    1422       21338 :         *(cd->mcodeptr++) = 0x8b;
    1423       21338 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    1424       21338 : }
    1425             : 
    1426             : 
    1427         301 : void emit_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
    1428         301 :         emit_rex(0,(reg),(indexreg),(basereg));
    1429         301 :         *(cd->mcodeptr++) = 0x8b;
    1430         301 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    1431         301 : }
    1432             : 
    1433             : 
    1434       64576 : void emit_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
    1435       64576 :         emit_rex(1,(reg),(indexreg),(basereg));
    1436       64576 :         *(cd->mcodeptr++) = 0x89;
    1437       64576 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    1438       64576 : }
    1439             : 
    1440             : 
    1441          86 : void emit_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
    1442          86 :         emit_rex(0,(reg),(indexreg),(basereg));
    1443          86 :         *(cd->mcodeptr++) = 0x89;
    1444          86 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    1445          86 : }
    1446             : 
    1447             : 
    1448        1084 : void emit_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
    1449        1084 :         *(cd->mcodeptr++) = 0x66;
    1450        1084 :         emit_rex(0,(reg),(indexreg),(basereg));
    1451        1084 :         *(cd->mcodeptr++) = 0x89;
    1452        1084 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    1453        1084 : }
    1454             : 
    1455             : 
    1456         360 : void emit_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
    1457         360 :         emit_byte_rex((reg),(indexreg),(basereg));
    1458         360 :         *(cd->mcodeptr++) = 0x88;
    1459         360 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    1460         360 : }
    1461             : 
    1462             : 
    1463         295 : void emit_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
    1464         295 :         emit_rex(1,0,0,(basereg));
    1465         295 :         *(cd->mcodeptr++) = 0xc7;
    1466         295 :         emit_membase(cd, (basereg),(disp),0);
    1467         295 :         emit_imm32((imm));
    1468         295 : }
    1469             : 
    1470             : 
    1471           0 : void emit_mov_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
    1472           0 :         emit_rex(1,0,0,(basereg));
    1473           0 :         *(cd->mcodeptr++) = 0xc7;
    1474           0 :         emit_membase32(cd, (basereg),(disp),0);
    1475           0 :         emit_imm32((imm));
    1476           0 : }
    1477             : 
    1478             : 
    1479         514 : void emit_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
    1480         514 :         emit_rex(0,0,0,(basereg));
    1481         514 :         *(cd->mcodeptr++) = 0xc7;
    1482         514 :         emit_membase(cd, (basereg),(disp),0);
    1483         514 :         emit_imm32((imm));
    1484         514 : }
    1485             : 
    1486             : 
    1487             : /* Always emit a REX byte, because the instruction size can be smaller when   */
    1488             : /* all register indexes are smaller than 7.                                   */
    1489        8296 : void emit_movl_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
    1490        8296 :         emit_byte_rex(0,0,(basereg));
    1491        8296 :         *(cd->mcodeptr++) = 0xc7;
    1492        8296 :         emit_membase32(cd, (basereg),(disp),0);
    1493        8296 :         emit_imm32((imm));
    1494        8296 : }
    1495             : 
    1496             : 
    1497         272 : void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
    1498             : {
    1499         272 :         emit_rex(1,(dreg),0,(reg));
    1500         272 :         *(cd->mcodeptr++) = 0x0f;
    1501         272 :         *(cd->mcodeptr++) = 0xbe;
    1502             :         /* XXX: why do reg and dreg have to be exchanged */
    1503         272 :         emit_reg((dreg),(reg));
    1504         272 : }
    1505             : 
    1506             : 
    1507         144 : void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
    1508             : {
    1509         144 :         emit_rex(1,(dreg),0,(reg));
    1510         144 :         *(cd->mcodeptr++) = 0x0f;
    1511         144 :         *(cd->mcodeptr++) = 0xbf;
    1512             :         /* XXX: why do reg and dreg have to be exchanged */
    1513         144 :         emit_reg((dreg),(reg));
    1514         144 : }
    1515             : 
    1516             : 
    1517         370 : void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
    1518             : {
    1519         370 :         emit_rex(1,(dreg),0,(reg));
    1520         370 :         *(cd->mcodeptr++) = 0x63;
    1521             :         /* XXX: why do reg and dreg have to be exchanged */
    1522         370 :         emit_reg((dreg),(reg));
    1523         370 : }
    1524             : 
    1525             : 
    1526         494 : void emit_movzbq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
    1527             : {
    1528         494 :         emit_rex(1,(dreg),0,(reg));
    1529         494 :         *(cd->mcodeptr++) = 0x0f;
    1530         494 :         *(cd->mcodeptr++) = 0xb6;
    1531             :         /* XXX: why do reg and dreg have to be exchanged */
    1532         494 :         emit_reg((dreg),(reg));
    1533         494 : }
    1534             : 
    1535             : 
    1536        1037 : void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
    1537             : {
    1538        1037 :         emit_rex(1,(dreg),0,(reg));
    1539        1037 :         *(cd->mcodeptr++) = 0x0f;
    1540        1037 :         *(cd->mcodeptr++) = 0xb7;
    1541             :         /* XXX: why do reg and dreg have to be exchanged */
    1542        1037 :         emit_reg((dreg),(reg));
    1543        1037 : }
    1544             : 
    1545             : 
    1546          55 : void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
    1547          55 :         emit_rex(1,(reg),(indexreg),(basereg));
    1548          55 :         *(cd->mcodeptr++) = 0x0f;
    1549          55 :         *(cd->mcodeptr++) = 0xbf;
    1550          55 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    1551          55 : }
    1552             : 
    1553             : 
    1554         160 : void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
    1555         160 :         emit_rex(1,(reg),(indexreg),(basereg));
    1556         160 :         *(cd->mcodeptr++) = 0x0f;
    1557         160 :         *(cd->mcodeptr++) = 0xbe;
    1558         160 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    1559         160 : }
    1560             : 
    1561             : 
    1562        3526 : void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
    1563        3526 :         emit_rex(1,(reg),(indexreg),(basereg));
    1564        3526 :         *(cd->mcodeptr++) = 0x0f;
    1565        3526 :         *(cd->mcodeptr++) = 0xb7;
    1566        3526 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    1567        3526 : }
    1568             : 
    1569             : 
    1570         592 : void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
    1571             : {
    1572         592 :         emit_rex(1,0,(indexreg),(basereg));
    1573         592 :         *(cd->mcodeptr++) = 0xc7;
    1574         592 :         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
    1575         592 :         emit_imm32((imm));
    1576         592 : }
    1577             : 
    1578             : 
    1579        4735 : void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
    1580             : {
    1581        4735 :         emit_rex(0,0,(indexreg),(basereg));
    1582        4735 :         *(cd->mcodeptr++) = 0xc7;
    1583        4735 :         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
    1584        4735 :         emit_imm32((imm));
    1585        4735 : }
    1586             : 
    1587             : 
    1588      508618 : void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
    1589             : {
    1590      508618 :         *(cd->mcodeptr++) = 0x66;
    1591      508618 :         emit_rex(0,0,(indexreg),(basereg));
    1592      508618 :         *(cd->mcodeptr++) = 0xc7;
    1593      508618 :         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
    1594      508618 :         emit_imm16((imm));
    1595      508618 : }
    1596             : 
    1597             : 
    1598         725 : void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
    1599             : {
    1600         725 :         emit_rex(0,0,(indexreg),(basereg));
    1601         725 :         *(cd->mcodeptr++) = 0xc6;
    1602         725 :         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
    1603         725 :         emit_imm8((imm));
    1604         725 : }
    1605             : 
    1606             : 
    1607     1239484 : void emit_mov_mem_reg(codegendata *cd, s4 disp, s4 dreg)
    1608             : {
    1609     1239484 :         emit_rex(1, dreg, 0, 0);
    1610     1239484 :         *(cd->mcodeptr++) = 0x8b;
    1611     1239484 :         emit_address_byte(0, dreg, 4);
    1612     1239484 :         emit_mem(4, disp);
    1613     1239484 : }
    1614             : 
    1615             : 
    1616             : /*
    1617             :  * alu operations
    1618             :  */
    1619       62720 : void emit_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
    1620             : {
    1621       62720 :         emit_rex(1,(reg),0,(dreg));
    1622       62720 :         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
    1623       62720 :         emit_reg((reg),(dreg));
    1624       62720 : }
    1625             : 
    1626             : 
    1627      634264 : void emit_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
    1628             : {
    1629      634264 :         emit_rex(0,(reg),0,(dreg));
    1630      634264 :         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
    1631      634264 :         emit_reg((reg),(dreg));
    1632      634264 : }
    1633             : 
    1634             : 
    1635           0 : void emit_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
    1636             : {
    1637           0 :         emit_rex(1,(reg),0,(basereg));
    1638           0 :         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
    1639           0 :         emit_membase(cd, (basereg),(disp),(reg));
    1640           0 : }
    1641             : 
    1642             : 
    1643           0 : void emit_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
    1644             : {
    1645           0 :         emit_rex(0,(reg),0,(basereg));
    1646           0 :         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
    1647           0 :         emit_membase(cd, (basereg),(disp),(reg));
    1648           0 : }
    1649             : 
    1650             : 
    1651        6898 : void emit_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
    1652             : {
    1653        6898 :         emit_rex(1,(reg),0,(basereg));
    1654        6898 :         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
    1655        6898 :         emit_membase(cd, (basereg),(disp),(reg));
    1656        6898 : }
    1657             : 
    1658             : 
    1659        2130 : void emit_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
    1660             : {
    1661        2130 :         emit_rex(0,(reg),0,(basereg));
    1662        2130 :         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
    1663        2130 :         emit_membase(cd, (basereg),(disp),(reg));
    1664        2130 : }
    1665             : 
    1666             : 
    1667      196454 : void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
    1668      365331 :         if (IS_IMM8(imm)) {
    1669      168877 :                 emit_rex(1,0,0,(dreg));
    1670      168877 :                 *(cd->mcodeptr++) = 0x83;
    1671      168877 :                 emit_reg((opc),(dreg));
    1672      168877 :                 emit_imm8((imm));
    1673             :         } else {
    1674       27577 :                 emit_rex(1,0,0,(dreg));
    1675       27577 :                 *(cd->mcodeptr++) = 0x81;
    1676       27577 :                 emit_reg((opc),(dreg));
    1677       27577 :                 emit_imm32((imm));
    1678             :         }
    1679      196454 : }
    1680             : 
    1681             : 
    1682           0 : void emit_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
    1683             : {
    1684           0 :         emit_rex(1,0,0,(dreg));
    1685           0 :         *(cd->mcodeptr++) = 0x81;
    1686           0 :         emit_reg((opc),(dreg));
    1687           0 :         emit_imm32((imm));
    1688           0 : }
    1689             : 
    1690             : 
    1691        2518 : void emit_alul_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
    1692             : {
    1693        2518 :         emit_rex(0,0,0,(dreg));
    1694        2518 :         *(cd->mcodeptr++) = 0x81;
    1695        2518 :         emit_reg((opc),(dreg));
    1696        2518 :         emit_imm32((imm));
    1697        2518 : }
    1698             : 
    1699             : 
    1700       89782 : void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
    1701      174567 :         if (IS_IMM8(imm)) {
    1702       84785 :                 emit_rex(0,0,0,(dreg));
    1703       84785 :                 *(cd->mcodeptr++) = 0x83;
    1704       84785 :                 emit_reg((opc),(dreg));
    1705       84785 :                 emit_imm8((imm));
    1706             :         } else {
    1707        4997 :                 emit_rex(0,0,0,(dreg));
    1708        4997 :                 *(cd->mcodeptr++) = 0x81;
    1709        4997 :                 emit_reg((opc),(dreg));
    1710        4997 :                 emit_imm32((imm));
    1711             :         }
    1712       89782 : }
    1713             : 
    1714             : 
    1715           0 : void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
    1716           0 :         if (IS_IMM8(imm)) {
    1717           0 :                 emit_rex(1,0,0,(basereg));
    1718           0 :                 *(cd->mcodeptr++) = 0x83;
    1719           0 :                 emit_membase(cd, (basereg),(disp),(opc));
    1720           0 :                 emit_imm8((imm));
    1721             :         } else {
    1722           0 :                 emit_rex(1,0,0,(basereg));
    1723           0 :                 *(cd->mcodeptr++) = 0x81;
    1724           0 :                 emit_membase(cd, (basereg),(disp),(opc));
    1725           0 :                 emit_imm32((imm));
    1726             :         }
    1727           0 : }
    1728             : 
    1729             : 
    1730           0 : void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
    1731           0 :         if (IS_IMM8(imm)) {
    1732           0 :                 emit_rex(0,0,0,(basereg));
    1733           0 :                 *(cd->mcodeptr++) = 0x83;
    1734           0 :                 emit_membase(cd, (basereg),(disp),(opc));
    1735           0 :                 emit_imm8((imm));
    1736             :         } else {
    1737           0 :                 emit_rex(0,0,0,(basereg));
    1738           0 :                 *(cd->mcodeptr++) = 0x81;
    1739           0 :                 emit_membase(cd, (basereg),(disp),(opc));
    1740           0 :                 emit_imm32((imm));
    1741             :         }
    1742           0 : }
    1743             : 
    1744           0 : void emit_alu_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
    1745             : {
    1746           0 :         emit_rex(1,(reg),(indexreg),(basereg));
    1747           0 :         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
    1748           0 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    1749           0 : }
    1750             : 
    1751        4260 : void emit_alul_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
    1752             : {
    1753        4260 :         emit_rex(0,(reg),(indexreg),(basereg));
    1754        4260 :         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
    1755        4260 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    1756        4260 : }
    1757             : 
    1758      228868 : void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    1759      228868 :         emit_rex(1,(reg),0,(dreg));
    1760      228868 :         *(cd->mcodeptr++) = 0x85;
    1761      228868 :         emit_reg((reg),(dreg));
    1762      228868 : }
    1763             : 
    1764             : 
    1765           0 : void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    1766           0 :         emit_rex(0,(reg),0,(dreg));
    1767           0 :         *(cd->mcodeptr++) = 0x85;
    1768           0 :         emit_reg((reg),(dreg));
    1769           0 : }
    1770             : 
    1771             : 
    1772           0 : void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg) {
    1773           0 :         *(cd->mcodeptr++) = 0xf7;
    1774           0 :         emit_reg(0,(reg));
    1775           0 :         emit_imm32((imm));
    1776           0 : }
    1777             : 
    1778             : 
    1779           0 : void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg) {
    1780           0 :         *(cd->mcodeptr++) = 0x66;
    1781           0 :         *(cd->mcodeptr++) = 0xf7;
    1782           0 :         emit_reg(0,(reg));
    1783           0 :         emit_imm16((imm));
    1784           0 : }
    1785             : 
    1786             : 
    1787           0 : void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg) {
    1788           0 :         *(cd->mcodeptr++) = 0xf6;
    1789           0 :         emit_reg(0,(reg));
    1790           0 :         emit_imm8((imm));
    1791           0 : }
    1792             : 
    1793             : 
    1794       26175 : void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
    1795       26175 :         emit_rex(1,(reg),0,(basereg));
    1796       26175 :         *(cd->mcodeptr++) = 0x8d;
    1797       26175 :         emit_membase(cd, (basereg),(disp),(reg));
    1798       26175 : }
    1799             : 
    1800             : 
    1801          82 : void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
    1802          82 :         emit_rex(0,(reg),0,(basereg));
    1803          82 :         *(cd->mcodeptr++) = 0x8d;
    1804          82 :         emit_membase(cd, (basereg),(disp),(reg));
    1805          82 : }
    1806             : 
    1807             : 
    1808           0 : void emit_incl_reg(codegendata *cd, s8 reg)
    1809             : {
    1810           0 :         *(cd->mcodeptr++) = 0xff;
    1811           0 :         emit_reg(0,(reg));
    1812           0 : }
    1813             : 
    1814         274 : void emit_incq_reg(codegendata *cd, s8 reg)
    1815             : {
    1816         274 :         emit_rex(1,0,0,(reg));
    1817         274 :         *(cd->mcodeptr++) = 0xff;
    1818         274 :         emit_reg(0,(reg));
    1819         274 : }
    1820             : 
    1821           0 : void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp)
    1822             : {
    1823           0 :         emit_rex(0,0,0,(basereg));
    1824           0 :         *(cd->mcodeptr++) = 0xff;
    1825           0 :         emit_membase(cd, (basereg),(disp),0);
    1826           0 : }
    1827             : 
    1828           0 : void emit_incq_membase(codegendata *cd, s8 basereg, s8 disp)
    1829             : {
    1830           0 :         emit_rex(1,0,0,(basereg));
    1831           0 :         *(cd->mcodeptr++) = 0xff;
    1832           0 :         emit_membase(cd, (basereg),(disp),0);
    1833           0 : }
    1834             : 
    1835             : 
    1836             : 
    1837        1885 : void emit_cltd(codegendata *cd) {
    1838        1885 :     *(cd->mcodeptr++) = 0x99;
    1839        1885 : }
    1840             : 
    1841             : 
    1842          61 : void emit_cqto(codegendata *cd) {
    1843          61 :         emit_rex(1,0,0,0);
    1844          61 :         *(cd->mcodeptr++) = 0x99;
    1845          61 : }
    1846             : 
    1847             : 
    1848             : 
    1849           9 : void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    1850           9 :         emit_rex(1,(dreg),0,(reg));
    1851           9 :         *(cd->mcodeptr++) = 0x0f;
    1852           9 :         *(cd->mcodeptr++) = 0xaf;
    1853           9 :         emit_reg((dreg),(reg));
    1854           9 : }
    1855             : 
    1856             : 
    1857         100 : void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    1858         100 :         emit_rex(0,(dreg),0,(reg));
    1859         100 :         *(cd->mcodeptr++) = 0x0f;
    1860         100 :         *(cd->mcodeptr++) = 0xaf;
    1861         100 :         emit_reg((dreg),(reg));
    1862         100 : }
    1863             : 
    1864             : 
    1865           0 : void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
    1866           0 :         emit_rex(1,(dreg),0,(basereg));
    1867           0 :         *(cd->mcodeptr++) = 0x0f;
    1868           0 :         *(cd->mcodeptr++) = 0xaf;
    1869           0 :         emit_membase(cd, (basereg),(disp),(dreg));
    1870           0 : }
    1871             : 
    1872             : 
    1873           0 : void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
    1874           0 :         emit_rex(0,(dreg),0,(basereg));
    1875           0 :         *(cd->mcodeptr++) = 0x0f;
    1876           0 :         *(cd->mcodeptr++) = 0xaf;
    1877           0 :         emit_membase(cd, (basereg),(disp),(dreg));
    1878           0 : }
    1879             : 
    1880             : 
    1881           0 : void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg) {
    1882           0 :         if (IS_IMM8((imm))) {
    1883           0 :                 emit_rex(1,0,0,(dreg));
    1884           0 :                 *(cd->mcodeptr++) = 0x6b;
    1885           0 :                 emit_reg(0,(dreg));
    1886           0 :                 emit_imm8((imm));
    1887             :         } else {
    1888           0 :                 emit_rex(1,0,0,(dreg));
    1889           0 :                 *(cd->mcodeptr++) = 0x69;
    1890           0 :                 emit_reg(0,(dreg));
    1891           0 :                 emit_imm32((imm));
    1892             :         }
    1893           0 : }
    1894             : 
    1895             : 
    1896          10 : void emit_imul_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
    1897          12 :         if (IS_IMM8((imm))) {
    1898           2 :                 emit_rex(1,(dreg),0,(reg));
    1899           2 :                 *(cd->mcodeptr++) = 0x6b;
    1900           2 :                 emit_reg((dreg),(reg));
    1901           2 :                 emit_imm8((imm));
    1902             :         } else {
    1903           8 :                 emit_rex(1,(dreg),0,(reg));
    1904           8 :                 *(cd->mcodeptr++) = 0x69;
    1905           8 :                 emit_reg((dreg),(reg));
    1906           8 :                 emit_imm32((imm));
    1907             :         }
    1908          10 : }
    1909             : 
    1910             : 
    1911         310 : void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
    1912         471 :         if (IS_IMM8((imm))) {
    1913         161 :                 emit_rex(0,(dreg),0,(reg));
    1914         161 :                 *(cd->mcodeptr++) = 0x6b;
    1915         161 :                 emit_reg((dreg),(reg));
    1916         161 :                 emit_imm8((imm));
    1917             :         } else {
    1918         149 :                 emit_rex(0,(dreg),0,(reg));
    1919         149 :                 *(cd->mcodeptr++) = 0x69;
    1920         149 :                 emit_reg((dreg),(reg));
    1921         149 :                 emit_imm32((imm));
    1922             :         }
    1923         310 : }
    1924             : 
    1925             : 
    1926           0 : void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
    1927           0 :         if (IS_IMM8((imm))) {
    1928           0 :                 emit_rex(1,(dreg),0,(basereg));
    1929           0 :                 *(cd->mcodeptr++) = 0x6b;
    1930           0 :                 emit_membase(cd, (basereg),(disp),(dreg));
    1931           0 :                 emit_imm8((imm));
    1932             :         } else {
    1933           0 :                 emit_rex(1,(dreg),0,(basereg));
    1934           0 :                 *(cd->mcodeptr++) = 0x69;
    1935           0 :                 emit_membase(cd, (basereg),(disp),(dreg));
    1936           0 :                 emit_imm32((imm));
    1937             :         }
    1938           0 : }
    1939             : 
    1940             : 
    1941           0 : void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
    1942           0 :         if (IS_IMM8((imm))) {
    1943           0 :                 emit_rex(0,(dreg),0,(basereg));
    1944           0 :                 *(cd->mcodeptr++) = 0x6b;
    1945           0 :                 emit_membase(cd, (basereg),(disp),(dreg));
    1946           0 :                 emit_imm8((imm));
    1947             :         } else {
    1948           0 :                 emit_rex(0,(dreg),0,(basereg));
    1949           0 :                 *(cd->mcodeptr++) = 0x69;
    1950           0 :                 emit_membase(cd, (basereg),(disp),(dreg));
    1951           0 :                 emit_imm32((imm));
    1952             :         }
    1953           0 : }
    1954             : 
    1955             : 
    1956          61 : void emit_idiv_reg(codegendata *cd, s8 reg) {
    1957          61 :         emit_rex(1,0,0,(reg));
    1958          61 :         *(cd->mcodeptr++) = 0xf7;
    1959          61 :         emit_reg(7,(reg));
    1960          61 : }
    1961             : 
    1962             : 
    1963        1885 : void emit_idivl_reg(codegendata *cd, s8 reg) {
    1964        1885 :         emit_rex(0,0,0,(reg));
    1965        1885 :         *(cd->mcodeptr++) = 0xf7;
    1966        1885 :         emit_reg(7,(reg));
    1967        1885 : }
    1968             : 
    1969             : 
    1970             : 
    1971             : /*
    1972             :  * shift ops
    1973             :  */
    1974          31 : void emit_shift_reg(codegendata *cd, s8 opc, s8 reg) {
    1975          31 :         emit_rex(1,0,0,(reg));
    1976          31 :         *(cd->mcodeptr++) = 0xd3;
    1977          31 :         emit_reg((opc),(reg));
    1978          31 : }
    1979             : 
    1980             : 
    1981         300 : void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg) {
    1982         300 :         emit_rex(0,0,0,(reg));
    1983         300 :         *(cd->mcodeptr++) = 0xd3;
    1984         300 :         emit_reg((opc),(reg));
    1985         300 : }
    1986             : 
    1987             : 
    1988           0 : void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
    1989           0 :         emit_rex(1,0,0,(basereg));
    1990           0 :         *(cd->mcodeptr++) = 0xd3;
    1991           0 :         emit_membase(cd, (basereg),(disp),(opc));
    1992           0 : }
    1993             : 
    1994             : 
    1995          18 : void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
    1996          18 :         emit_rex(0,0,0,(basereg));
    1997          18 :         *(cd->mcodeptr++) = 0xd3;
    1998          18 :         emit_membase(cd, (basereg),(disp),(opc));
    1999          18 : }
    2000             : 
    2001             : 
    2002          84 : void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
    2003          84 :         if ((imm) == 1) {
    2004           6 :                 emit_rex(1,0,0,(dreg));
    2005           6 :                 *(cd->mcodeptr++) = 0xd1;
    2006           6 :                 emit_reg((opc),(dreg));
    2007             :         } else {
    2008          78 :                 emit_rex(1,0,0,(dreg));
    2009          78 :                 *(cd->mcodeptr++) = 0xc1;
    2010          78 :                 emit_reg((opc),(dreg));
    2011          78 :                 emit_imm8((imm));
    2012             :         }
    2013          84 : }
    2014             : 
    2015             : 
    2016        1619 : void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
    2017        1619 :         if ((imm) == 1) {
    2018         736 :                 emit_rex(0,0,0,(dreg));
    2019         736 :                 *(cd->mcodeptr++) = 0xd1;
    2020         736 :                 emit_reg((opc),(dreg));
    2021             :         } else {
    2022         883 :                 emit_rex(0,0,0,(dreg));
    2023         883 :                 *(cd->mcodeptr++) = 0xc1;
    2024         883 :                 emit_reg((opc),(dreg));
    2025         883 :                 emit_imm8((imm));
    2026             :         }
    2027        1619 : }
    2028             : 
    2029             : 
    2030           0 : void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
    2031           0 :         if ((imm) == 1) {
    2032           0 :                 emit_rex(1,0,0,(basereg));
    2033           0 :                 *(cd->mcodeptr++) = 0xd1;
    2034           0 :                 emit_membase(cd, (basereg),(disp),(opc));
    2035             :         } else {
    2036           0 :                 emit_rex(1,0,0,(basereg));
    2037           0 :                 *(cd->mcodeptr++) = 0xc1;
    2038           0 :                 emit_membase(cd, (basereg),(disp),(opc));
    2039           0 :                 emit_imm8((imm));
    2040             :         }
    2041           0 : }
    2042             : 
    2043             : 
    2044           0 : void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
    2045           0 :         if ((imm) == 1) {
    2046           0 :                 emit_rex(0,0,0,(basereg));
    2047           0 :                 *(cd->mcodeptr++) = 0xd1;
    2048           0 :                 emit_membase(cd, (basereg),(disp),(opc));
    2049             :         } else {
    2050           0 :                 emit_rex(0,0,0,(basereg));
    2051           0 :                 *(cd->mcodeptr++) = 0xc1;
    2052           0 :                 emit_membase(cd, (basereg),(disp),(opc));
    2053           0 :                 emit_imm8((imm));
    2054             :         }
    2055           0 : }
    2056             : 
    2057             : 
    2058             : 
    2059             : /*
    2060             :  * jump operations
    2061             :  */
    2062       37090 : void emit_jmp_imm(codegendata *cd, s8 imm) {
    2063       37090 :         *(cd->mcodeptr++) = 0xe9;
    2064       37090 :         emit_imm32((imm));
    2065       37090 : }
    2066             : 
    2067             : /* like emit_jmp_imm but allows 8 bit optimization */
    2068           0 : void emit_jmp_imm2(codegendata *cd, s8 imm) {
    2069           0 :         if (IS_IMM8(imm)) {
    2070           0 :                 *(cd->mcodeptr++) = 0xeb;
    2071           0 :                 emit_imm8((imm));
    2072             :         }
    2073             :         else {
    2074           0 :                 *(cd->mcodeptr++) = 0xe9;
    2075           0 :                 emit_imm32((imm));
    2076             :         }
    2077           0 : }
    2078             : 
    2079             : 
    2080          72 : void emit_jmp_reg(codegendata *cd, s8 reg) {
    2081          72 :         emit_rex(0,0,0,(reg));
    2082          72 :         *(cd->mcodeptr++) = 0xff;
    2083          72 :         emit_reg(4,(reg));
    2084          72 : }
    2085             : 
    2086             : 
    2087      934842 : void emit_jcc(codegendata *cd, s8 opc, s8 imm) {
    2088      934842 :         *(cd->mcodeptr++) = 0x0f;
    2089      934842 :         *(cd->mcodeptr++) = (0x80 + (opc));
    2090      934842 :         emit_imm32((imm));
    2091      934842 : }
    2092             : 
    2093             : 
    2094             : 
    2095             : /*
    2096             :  * conditional set and move operations
    2097             :  */
    2098             : 
    2099             : /* we need the rex byte to get all low bytes */
    2100        1539 : void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg)
    2101             : {
    2102        1539 :         *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
    2103        1539 :         *(cd->mcodeptr++) = 0x0f;
    2104        1539 :         *(cd->mcodeptr++) = (0x90 + (opc));
    2105        1539 :         emit_reg(0,(reg));
    2106        1539 : }
    2107             : 
    2108             : 
    2109             : /* we need the rex byte to get all low bytes */
    2110           0 : void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
    2111             : {
    2112           0 :         *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
    2113           0 :         *(cd->mcodeptr++) = 0x0f;
    2114           0 :         *(cd->mcodeptr++) = (0x90 + (opc));
    2115           0 :         emit_membase(cd, (basereg),(disp),0);
    2116           0 : }
    2117             : 
    2118             : 
    2119        5902 : void emit_cmovcc_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
    2120             : {
    2121        5902 :         emit_rex(1,(dreg),0,(reg));
    2122        5902 :         *(cd->mcodeptr++) = 0x0f;
    2123        5902 :         *(cd->mcodeptr++) = (0x40 + (opc));
    2124        5902 :         emit_reg((dreg),(reg));
    2125        5902 : }
    2126             : 
    2127             : 
    2128          82 : void emit_cmovccl_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
    2129             : {
    2130          82 :         emit_rex(0,(dreg),0,(reg));
    2131          82 :         *(cd->mcodeptr++) = 0x0f;
    2132          82 :         *(cd->mcodeptr++) = (0x40 + (opc));
    2133          82 :         emit_reg((dreg),(reg));
    2134          82 : }
    2135             : 
    2136             : 
    2137          50 : void emit_neg_reg(codegendata *cd, s8 reg)
    2138             : {
    2139          50 :         emit_rex(1,0,0,(reg));
    2140          50 :         *(cd->mcodeptr++) = 0xf7;
    2141          50 :         emit_reg(3,(reg));
    2142          50 : }
    2143             : 
    2144             : 
    2145         756 : void emit_negl_reg(codegendata *cd, s8 reg)
    2146             : {
    2147         756 :         emit_rex(0,0,0,(reg));
    2148         756 :         *(cd->mcodeptr++) = 0xf7;
    2149         756 :         emit_reg(3,(reg));
    2150         756 : }
    2151             : 
    2152             : 
    2153           0 : void emit_push_reg(codegendata *cd, s8 reg) {
    2154           0 :         emit_rex(0,0,0,(reg));
    2155           0 :         *(cd->mcodeptr++) = 0x50 + (0x07 & (reg));
    2156           0 : }
    2157             : 
    2158             : 
    2159           0 : void emit_push_imm(codegendata *cd, s8 imm) {
    2160           0 :         *(cd->mcodeptr++) = 0x68;
    2161           0 :         emit_imm32((imm));
    2162           0 : }
    2163             : 
    2164             : 
    2165           0 : void emit_pop_reg(codegendata *cd, s8 reg) {
    2166           0 :         emit_rex(0,0,0,(reg));
    2167           0 :         *(cd->mcodeptr++) = 0x58 + (0x07 & (reg));
    2168           0 : }
    2169             : 
    2170             : 
    2171           0 : void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2172           0 :         emit_rex(1,(reg),0,(dreg));
    2173           0 :         *(cd->mcodeptr++) = 0x87;
    2174           0 :         emit_reg((reg),(dreg));
    2175           0 : }
    2176             : 
    2177             : 
    2178             : 
    2179             : /*
    2180             :  * call instructions
    2181             :  */
    2182      471904 : void emit_call_reg(codegendata *cd, s8 reg)
    2183             : {
    2184      471904 :         emit_rex(0,0,0,(reg));
    2185      471904 :         *(cd->mcodeptr++) = 0xff;
    2186      471904 :         emit_reg(2,(reg));
    2187      471904 : }
    2188             : 
    2189             : 
    2190           0 : void emit_call_imm(codegendata *cd, s8 imm)
    2191             : {
    2192           0 :         *(cd->mcodeptr++) = 0xe8;
    2193           0 :         emit_imm32((imm));
    2194           0 : }
    2195             : 
    2196             : 
    2197           0 : void emit_call_mem(codegendata *cd, ptrint mem)
    2198             : {
    2199           0 :         *(cd->mcodeptr++) = 0xff;
    2200           0 :         emit_mem(2,(mem));
    2201           0 : }
    2202             : 
    2203             : 
    2204             : 
    2205             : /*
    2206             :  * floating point instructions (SSE2)
    2207             :  */
    2208           7 : void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2209           7 :         *(cd->mcodeptr++) = 0xf2;
    2210           7 :         emit_rex(0,(dreg),0,(reg));
    2211           7 :         *(cd->mcodeptr++) = 0x0f;
    2212           7 :         *(cd->mcodeptr++) = 0x58;
    2213           7 :         emit_reg((dreg),(reg));
    2214           7 : }
    2215             : 
    2216             : 
    2217        1006 : void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2218        1006 :         *(cd->mcodeptr++) = 0xf3;
    2219        1006 :         emit_rex(0,(dreg),0,(reg));
    2220        1006 :         *(cd->mcodeptr++) = 0x0f;
    2221        1006 :         *(cd->mcodeptr++) = 0x58;
    2222        1006 :         emit_reg((dreg),(reg));
    2223        1006 : }
    2224             : 
    2225             : 
    2226           1 : void emit_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2227           1 :         *(cd->mcodeptr++) = 0xf3;
    2228           1 :         emit_rex(1,(dreg),0,(reg));
    2229           1 :         *(cd->mcodeptr++) = 0x0f;
    2230           1 :         *(cd->mcodeptr++) = 0x2a;
    2231           1 :         emit_reg((dreg),(reg));
    2232           1 : }
    2233             : 
    2234             : 
    2235        1278 : void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2236        1278 :         *(cd->mcodeptr++) = 0xf3;
    2237        1278 :         emit_rex(0,(dreg),0,(reg));
    2238        1278 :         *(cd->mcodeptr++) = 0x0f;
    2239        1278 :         *(cd->mcodeptr++) = 0x2a;
    2240        1278 :         emit_reg((dreg),(reg));
    2241        1278 : }
    2242             : 
    2243             : 
    2244           3 : void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2245           3 :         *(cd->mcodeptr++) = 0xf2;
    2246           3 :         emit_rex(1,(dreg),0,(reg));
    2247           3 :         *(cd->mcodeptr++) = 0x0f;
    2248           3 :         *(cd->mcodeptr++) = 0x2a;
    2249           3 :         emit_reg((dreg),(reg));
    2250           3 : }
    2251             : 
    2252             : 
    2253           8 : void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2254           8 :         *(cd->mcodeptr++) = 0xf2;
    2255           8 :         emit_rex(0,(dreg),0,(reg));
    2256           8 :         *(cd->mcodeptr++) = 0x0f;
    2257           8 :         *(cd->mcodeptr++) = 0x2a;
    2258           8 :         emit_reg((dreg),(reg));
    2259           8 : }
    2260             : 
    2261             : 
    2262          19 : void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2263          19 :         *(cd->mcodeptr++) = 0xf3;
    2264          19 :         emit_rex(0,(dreg),0,(reg));
    2265          19 :         *(cd->mcodeptr++) = 0x0f;
    2266          19 :         *(cd->mcodeptr++) = 0x5a;
    2267          19 :         emit_reg((dreg),(reg));
    2268          19 : }
    2269             : 
    2270             : 
    2271           5 : void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2272           5 :         *(cd->mcodeptr++) = 0xf2;
    2273           5 :         emit_rex(0,(dreg),0,(reg));
    2274           5 :         *(cd->mcodeptr++) = 0x0f;
    2275           5 :         *(cd->mcodeptr++) = 0x5a;
    2276           5 :         emit_reg((dreg),(reg));
    2277           5 : }
    2278             : 
    2279             : 
    2280           0 : void emit_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2281           0 :         *(cd->mcodeptr++) = 0xf3;
    2282           0 :         emit_rex(1,(dreg),0,(reg));
    2283           0 :         *(cd->mcodeptr++) = 0x0f;
    2284           0 :         *(cd->mcodeptr++) = 0x2c;
    2285           0 :         emit_reg((dreg),(reg));
    2286           0 : }
    2287             : 
    2288             : 
    2289           0 : void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2290           0 :         *(cd->mcodeptr++) = 0xf3;
    2291           0 :         emit_rex(0,(dreg),0,(reg));
    2292           0 :         *(cd->mcodeptr++) = 0x0f;
    2293           0 :         *(cd->mcodeptr++) = 0x2c;
    2294           0 :         emit_reg((dreg),(reg));
    2295           0 : }
    2296             : 
    2297             : 
    2298           0 : void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2299           0 :         *(cd->mcodeptr++) = 0xf2;
    2300           0 :         emit_rex(1,(dreg),0,(reg));
    2301           0 :         *(cd->mcodeptr++) = 0x0f;
    2302           0 :         *(cd->mcodeptr++) = 0x2c;
    2303           0 :         emit_reg((dreg),(reg));
    2304           0 : }
    2305             : 
    2306             : 
    2307           0 : void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2308           0 :         *(cd->mcodeptr++) = 0xf2;
    2309           0 :         emit_rex(0,(dreg),0,(reg));
    2310           0 :         *(cd->mcodeptr++) = 0x0f;
    2311           0 :         *(cd->mcodeptr++) = 0x2c;
    2312           0 :         emit_reg((dreg),(reg));
    2313           0 : }
    2314             : 
    2315             : 
    2316           5 : void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2317           5 :         *(cd->mcodeptr++) = 0xf3;
    2318           5 :         emit_rex(0,(dreg),0,(reg));
    2319           5 :         *(cd->mcodeptr++) = 0x0f;
    2320           5 :         *(cd->mcodeptr++) = 0x5e;
    2321           5 :         emit_reg((dreg),(reg));
    2322           5 : }
    2323             : 
    2324             : 
    2325           7 : void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2326           7 :         *(cd->mcodeptr++) = 0xf2;
    2327           7 :         emit_rex(0,(dreg),0,(reg));
    2328           7 :         *(cd->mcodeptr++) = 0x0f;
    2329           7 :         *(cd->mcodeptr++) = 0x5e;
    2330           7 :         emit_reg((dreg),(reg));
    2331           7 : }
    2332             : 
    2333             : 
    2334           0 : void emit_movd_reg_freg(codegendata *cd, s8 reg, s8 freg) {
    2335           0 :         *(cd->mcodeptr++) = 0x66;
    2336           0 :         emit_rex(1,(freg),0,(reg));
    2337           0 :         *(cd->mcodeptr++) = 0x0f;
    2338           0 :         *(cd->mcodeptr++) = 0x6e;
    2339           0 :         emit_reg((freg),(reg));
    2340           0 : }
    2341             : 
    2342             : 
    2343           0 : void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg) {
    2344           0 :         *(cd->mcodeptr++) = 0x66;
    2345           0 :         emit_rex(1,(freg),0,(reg));
    2346           0 :         *(cd->mcodeptr++) = 0x0f;
    2347           0 :         *(cd->mcodeptr++) = 0x7e;
    2348           0 :         emit_reg((freg),(reg));
    2349           0 : }
    2350             : 
    2351             : 
    2352           0 : void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
    2353           0 :         *(cd->mcodeptr++) = 0x66;
    2354           0 :         emit_rex(0,(reg),0,(basereg));
    2355           0 :         *(cd->mcodeptr++) = 0x0f;
    2356           0 :         *(cd->mcodeptr++) = 0x7e;
    2357           0 :         emit_membase(cd, (basereg),(disp),(reg));
    2358           0 : }
    2359             : 
    2360             : 
    2361           0 : void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
    2362           0 :         *(cd->mcodeptr++) = 0x66;
    2363           0 :         emit_rex(0,(reg),(indexreg),(basereg));
    2364           0 :         *(cd->mcodeptr++) = 0x0f;
    2365           0 :         *(cd->mcodeptr++) = 0x7e;
    2366           0 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    2367           0 : }
    2368             : 
    2369             : 
    2370         233 : void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
    2371         233 :         *(cd->mcodeptr++) = 0x66;
    2372         233 :         emit_rex(1,(dreg),0,(basereg));
    2373         233 :         *(cd->mcodeptr++) = 0x0f;
    2374         233 :         *(cd->mcodeptr++) = 0x6e;
    2375         233 :         emit_membase(cd, (basereg),(disp),(dreg));
    2376         233 : }
    2377             : 
    2378             : 
    2379        4946 : void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
    2380        4946 :         *(cd->mcodeptr++) = 0x66;
    2381        4946 :         emit_rex(0,(dreg),0,(basereg));
    2382        4946 :         *(cd->mcodeptr++) = 0x0f;
    2383        4946 :         *(cd->mcodeptr++) = 0x6e;
    2384        4946 :         emit_membase(cd, (basereg),(disp),(dreg));
    2385        4946 : }
    2386             : 
    2387             : 
    2388           0 : void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
    2389           0 :         *(cd->mcodeptr++) = 0x66;
    2390           0 :         emit_rex(0,(dreg),(indexreg),(basereg));
    2391           0 :         *(cd->mcodeptr++) = 0x0f;
    2392           0 :         *(cd->mcodeptr++) = 0x6e;
    2393           0 :         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
    2394           0 : }
    2395             : 
    2396             : 
    2397        3077 : void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2398        3077 :         *(cd->mcodeptr++) = 0xf3;
    2399        3077 :         emit_rex(0,(dreg),0,(reg));
    2400        3077 :         *(cd->mcodeptr++) = 0x0f;
    2401        3077 :         *(cd->mcodeptr++) = 0x7e;
    2402        3077 :         emit_reg((dreg),(reg));
    2403        3077 : }
    2404             : 
    2405             : 
    2406           0 : void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
    2407           0 :         *(cd->mcodeptr++) = 0x66;
    2408           0 :         emit_rex(0,(reg),0,(basereg));
    2409           0 :         *(cd->mcodeptr++) = 0x0f;
    2410           0 :         *(cd->mcodeptr++) = 0xd6;
    2411           0 :         emit_membase(cd, (basereg),(disp),(reg));
    2412           0 : }
    2413             : 
    2414             : 
    2415           0 : void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
    2416           0 :         *(cd->mcodeptr++) = 0xf3;
    2417           0 :         emit_rex(0,(dreg),0,(basereg));
    2418           0 :         *(cd->mcodeptr++) = 0x0f;
    2419           0 :         *(cd->mcodeptr++) = 0x7e;
    2420           0 :         emit_membase(cd, (basereg),(disp),(dreg));
    2421           0 : }
    2422             : 
    2423             : 
    2424           0 : void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2425           0 :         *(cd->mcodeptr++) = 0xf3;
    2426           0 :         emit_rex(0,(reg),0,(dreg));
    2427           0 :         *(cd->mcodeptr++) = 0x0f;
    2428           0 :         *(cd->mcodeptr++) = 0x10;
    2429           0 :         emit_reg((reg),(dreg));
    2430           0 : }
    2431             : 
    2432             : 
    2433           0 : void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2434           0 :         *(cd->mcodeptr++) = 0xf2;
    2435           0 :         emit_rex(0,(reg),0,(dreg));
    2436           0 :         *(cd->mcodeptr++) = 0x0f;
    2437           0 :         *(cd->mcodeptr++) = 0x10;
    2438           0 :         emit_reg((reg),(dreg));
    2439           0 : }
    2440             : 
    2441             : 
    2442        1238 : void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
    2443        1238 :         *(cd->mcodeptr++) = 0xf3;
    2444        1238 :         emit_rex(0,(reg),0,(basereg));
    2445        1238 :         *(cd->mcodeptr++) = 0x0f;
    2446        1238 :         *(cd->mcodeptr++) = 0x11;
    2447        1238 :         emit_membase(cd, (basereg),(disp),(reg));
    2448        1238 : }
    2449             : 
    2450             : 
    2451             : /* Always emit a REX byte, because the instruction size can be smaller when   */
    2452             : /* all register indexes are smaller than 7.                                   */
    2453         624 : void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
    2454         624 :         *(cd->mcodeptr++) = 0xf3;
    2455         624 :         emit_byte_rex((reg),0,(basereg));
    2456         624 :         *(cd->mcodeptr++) = 0x0f;
    2457         624 :         *(cd->mcodeptr++) = 0x11;
    2458         624 :         emit_membase32(cd, (basereg),(disp),(reg));
    2459         624 : }
    2460             : 
    2461             : 
    2462        1535 : void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
    2463        1535 :         *(cd->mcodeptr++) = 0xf2;
    2464        1535 :         emit_rex(0,(reg),0,(basereg));
    2465        1535 :         *(cd->mcodeptr++) = 0x0f;
    2466        1535 :         *(cd->mcodeptr++) = 0x11;
    2467        1535 :         emit_membase(cd, (basereg),(disp),(reg));
    2468        1535 : }
    2469             : 
    2470             : 
    2471             : /* Always emit a REX byte, because the instruction size can be smaller when   */
    2472             : /* all register indexes are smaller than 7.                                   */
    2473          38 : void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
    2474          38 :         *(cd->mcodeptr++) = 0xf2;
    2475          38 :         emit_byte_rex((reg),0,(basereg));
    2476          38 :         *(cd->mcodeptr++) = 0x0f;
    2477          38 :         *(cd->mcodeptr++) = 0x11;
    2478          38 :         emit_membase32(cd, (basereg),(disp),(reg));
    2479          38 : }
    2480             : 
    2481             : 
    2482        4795 : void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
    2483        4795 :         *(cd->mcodeptr++) = 0xf3;
    2484        4795 :         emit_rex(0,(dreg),0,(basereg));
    2485        4795 :         *(cd->mcodeptr++) = 0x0f;
    2486        4795 :         *(cd->mcodeptr++) = 0x10;
    2487        4795 :         emit_membase(cd, (basereg),(disp),(dreg));
    2488        4795 : }
    2489             : 
    2490             : 
    2491             : /* Always emit a REX byte, because the instruction size can be smaller when   */
    2492             : /* all register indexes are smaller than 7.                                   */
    2493         454 : void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
    2494         454 :         *(cd->mcodeptr++) = 0xf3;
    2495         454 :         emit_byte_rex((dreg),0,(basereg));
    2496         454 :         *(cd->mcodeptr++) = 0x0f;
    2497         454 :         *(cd->mcodeptr++) = 0x10;
    2498         454 :         emit_membase32(cd, (basereg),(disp),(dreg));
    2499         454 : }
    2500             : 
    2501             : 
    2502           0 : void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
    2503             : {
    2504           0 :         emit_rex(0,(dreg),0,(basereg));
    2505           0 :         *(cd->mcodeptr++) = 0x0f;
    2506           0 :         *(cd->mcodeptr++) = 0x12;
    2507           0 :         emit_membase(cd, (basereg),(disp),(dreg));
    2508           0 : }
    2509             : 
    2510             : 
    2511           0 : void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
    2512             : {
    2513           0 :         emit_rex(0,(reg),0,(basereg));
    2514           0 :         *(cd->mcodeptr++) = 0x0f;
    2515           0 :         *(cd->mcodeptr++) = 0x13;
    2516           0 :         emit_membase(cd, (basereg),(disp),(reg));
    2517           0 : }
    2518             : 
    2519             : 
    2520         445 : void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
    2521         445 :         *(cd->mcodeptr++) = 0xf2;
    2522         445 :         emit_rex(0,(dreg),0,(basereg));
    2523         445 :         *(cd->mcodeptr++) = 0x0f;
    2524         445 :         *(cd->mcodeptr++) = 0x10;
    2525         445 :         emit_membase(cd, (basereg),(disp),(dreg));
    2526         445 : }
    2527             : 
    2528             : 
    2529             : /* Always emit a REX byte, because the instruction size can be smaller when   */
    2530             : /* all register indexes are smaller than 7.                                   */
    2531          21 : void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
    2532          21 :         *(cd->mcodeptr++) = 0xf2;
    2533          21 :         emit_byte_rex((dreg),0,(basereg));
    2534          21 :         *(cd->mcodeptr++) = 0x0f;
    2535          21 :         *(cd->mcodeptr++) = 0x10;
    2536          21 :         emit_membase32(cd, (basereg),(disp),(dreg));
    2537          21 : }
    2538             : 
    2539             : 
    2540           0 : void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
    2541             : {
    2542           0 :         *(cd->mcodeptr++) = 0x66;
    2543           0 :         emit_rex(0,(dreg),0,(basereg));
    2544           0 :         *(cd->mcodeptr++) = 0x0f;
    2545           0 :         *(cd->mcodeptr++) = 0x12;
    2546           0 :         emit_membase(cd, (basereg),(disp),(dreg));
    2547           0 : }
    2548             : 
    2549             : 
    2550           0 : void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
    2551             : {
    2552           0 :         *(cd->mcodeptr++) = 0x66;
    2553           0 :         emit_rex(0,(reg),0,(basereg));
    2554           0 :         *(cd->mcodeptr++) = 0x0f;
    2555           0 :         *(cd->mcodeptr++) = 0x13;
    2556           0 :         emit_membase(cd, (basereg),(disp),(reg));
    2557           0 : }
    2558             : 
    2559             : 
    2560           6 : void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
    2561           6 :         *(cd->mcodeptr++) = 0xf3;
    2562           6 :         emit_rex(0,(reg),(indexreg),(basereg));
    2563           6 :         *(cd->mcodeptr++) = 0x0f;
    2564           6 :         *(cd->mcodeptr++) = 0x11;
    2565           6 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    2566           6 : }
    2567             : 
    2568             : 
    2569           4 : void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
    2570           4 :         *(cd->mcodeptr++) = 0xf2;
    2571           4 :         emit_rex(0,(reg),(indexreg),(basereg));
    2572           4 :         *(cd->mcodeptr++) = 0x0f;
    2573           4 :         *(cd->mcodeptr++) = 0x11;
    2574           4 :         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
    2575           4 : }
    2576             : 
    2577             : 
    2578           3 : void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
    2579           3 :         *(cd->mcodeptr++) = 0xf3;
    2580           3 :         emit_rex(0,(dreg),(indexreg),(basereg));
    2581           3 :         *(cd->mcodeptr++) = 0x0f;
    2582           3 :         *(cd->mcodeptr++) = 0x10;
    2583           3 :         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
    2584           3 : }
    2585             : 
    2586             : 
    2587           3 : void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
    2588           3 :         *(cd->mcodeptr++) = 0xf2;
    2589           3 :         emit_rex(0,(dreg),(indexreg),(basereg));
    2590           3 :         *(cd->mcodeptr++) = 0x0f;
    2591           3 :         *(cd->mcodeptr++) = 0x10;
    2592           3 :         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
    2593           3 : }
    2594             : 
    2595             : 
    2596         999 : void emit_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2597         999 :         *(cd->mcodeptr++) = 0xf3;
    2598         999 :         emit_rex(0,(dreg),0,(reg));
    2599         999 :         *(cd->mcodeptr++) = 0x0f;
    2600         999 :         *(cd->mcodeptr++) = 0x59;
    2601         999 :         emit_reg((dreg),(reg));
    2602         999 : }
    2603             : 
    2604             : 
    2605          10 : void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2606          10 :         *(cd->mcodeptr++) = 0xf2;
    2607          10 :         emit_rex(0,(dreg),0,(reg));
    2608          10 :         *(cd->mcodeptr++) = 0x0f;
    2609          10 :         *(cd->mcodeptr++) = 0x59;
    2610          10 :         emit_reg((dreg),(reg));
    2611          10 : }
    2612             : 
    2613             : 
    2614           3 : void emit_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2615           3 :         *(cd->mcodeptr++) = 0xf3;
    2616           3 :         emit_rex(0,(dreg),0,(reg));
    2617           3 :         *(cd->mcodeptr++) = 0x0f;
    2618           3 :         *(cd->mcodeptr++) = 0x5c;
    2619           3 :         emit_reg((dreg),(reg));
    2620           3 : }
    2621             : 
    2622             : 
    2623           5 : void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2624           5 :         *(cd->mcodeptr++) = 0xf2;
    2625           5 :         emit_rex(0,(dreg),0,(reg));
    2626           5 :         *(cd->mcodeptr++) = 0x0f;
    2627           5 :         *(cd->mcodeptr++) = 0x5c;
    2628           5 :         emit_reg((dreg),(reg));
    2629           5 : }
    2630             : 
    2631             : 
    2632        1890 : void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2633        1890 :         emit_rex(0,(dreg),0,(reg));
    2634        1890 :         *(cd->mcodeptr++) = 0x0f;
    2635        1890 :         *(cd->mcodeptr++) = 0x2e;
    2636        1890 :         emit_reg((dreg),(reg));
    2637        1890 : }
    2638             : 
    2639             : 
    2640          57 : void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2641          57 :         *(cd->mcodeptr++) = 0x66;
    2642          57 :         emit_rex(0,(dreg),0,(reg));
    2643          57 :         *(cd->mcodeptr++) = 0x0f;
    2644          57 :         *(cd->mcodeptr++) = 0x2e;
    2645          57 :         emit_reg((dreg),(reg));
    2646          57 : }
    2647             : 
    2648             : 
    2649           0 : void emit_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2650           0 :         emit_rex(0,(dreg),0,(reg));
    2651           0 :         *(cd->mcodeptr++) = 0x0f;
    2652           0 :         *(cd->mcodeptr++) = 0x57;
    2653           0 :         emit_reg((dreg),(reg));
    2654           0 : }
    2655             : 
    2656             : 
    2657           0 : void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
    2658           0 :         emit_rex(0,(dreg),0,(basereg));
    2659           0 :         *(cd->mcodeptr++) = 0x0f;
    2660           0 :         *(cd->mcodeptr++) = 0x57;
    2661           0 :         emit_membase(cd, (basereg),(disp),(dreg));
    2662           0 : }
    2663             : 
    2664             : 
    2665           0 : void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
    2666           0 :         *(cd->mcodeptr++) = 0x66;
    2667           0 :         emit_rex(0,(dreg),0,(reg));
    2668           0 :         *(cd->mcodeptr++) = 0x0f;
    2669           0 :         *(cd->mcodeptr++) = 0x57;
    2670           0 :         emit_reg((dreg),(reg));
    2671           0 : }
    2672             : 
    2673             : 
    2674           0 : void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
    2675           0 :         *(cd->mcodeptr++) = 0x66;
    2676           0 :         emit_rex(0,(dreg),0,(basereg));
    2677           0 :         *(cd->mcodeptr++) = 0x0f;
    2678           0 :         *(cd->mcodeptr++) = 0x57;
    2679           0 :         emit_membase(cd, (basereg),(disp),(dreg));
    2680           0 : }
    2681             : 
    2682             : 
    2683             : /* system instructions ********************************************************/
    2684             : 
    2685           0 : void emit_rdtsc(codegendata *cd)
    2686             : {
    2687           0 :         *(cd->mcodeptr++) = 0x0f;
    2688           0 :         *(cd->mcodeptr++) = 0x31;
    2689           0 : }
    2690             : 
    2691        3142 : void emit_mfence(codegendata *cd)
    2692             : {
    2693        3142 :         *(cd->mcodeptr++) = 0x0f;
    2694        3142 :         *(cd->mcodeptr++) = 0xae;
    2695        3142 :         *(cd->mcodeptr++) = 0xf0;
    2696        3142 : }
    2697             : 
    2698             : 
    2699             : /*
    2700             :  * These are local overrides for various environment variables in Emacs.
    2701             :  * Please do not remove this and leave it at the end of the file, where
    2702             :  * Emacs will automagically detect them.
    2703             :  * ---------------------------------------------------------------------
    2704             :  * Local variables:
    2705             :  * mode: c++
    2706             :  * indent-tabs-mode: t
    2707             :  * c-basic-offset: 4
    2708             :  * tab-width: 4
    2709             :  * End:
    2710             :  * vim:noexpandtab:sw=4:ts=4:
    2711             :  */

Generated by: LCOV version 1.11