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

Generated by: LCOV version 1.11