Search
lxdream.org :: lxdream/src/xlat/x86/x86op.h
lxdream 0.9.1
released Jun 29
Download Now
filename src/xlat/x86/x86op.h
changeset 1112:4cac5e474d4c
prev1071:182cfe43c09e
next1147:e04e4af64626
author nkeynes
date Tue Jul 13 18:23:16 2010 +1000 (13 years ago)
permissions -rw-r--r--
last change Rearrange the main translation loop to allow translated blocks to jump
directly to their successors without needing to return to the main loop
in between. Shaves about 6% off the core runtime.
file annotate diff log raw
nkeynes@991
     1
/**
nkeynes@991
     2
 * $Id$
nkeynes@991
     3
 * 
nkeynes@995
     4
 * x86/x86-64 Instruction generator
nkeynes@991
     5
 *
nkeynes@991
     6
 * Copyright (c) 2009 Nathan Keynes.
nkeynes@991
     7
 *
nkeynes@991
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@991
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@991
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@991
    11
 * (at your option) any later version.
nkeynes@991
    12
 *
nkeynes@991
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@991
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@991
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@991
    16
 * GNU General Public License for more details.
nkeynes@991
    17
 */
nkeynes@995
    18
nkeynes@995
    19
#ifndef lxdream_x86op_H
nkeynes@995
    20
#define lxdream_x86op_H
nkeynes@995
    21
nkeynes@991
    22
#include <stdint.h>
nkeynes@991
    23
#include <assert.h>
nkeynes@991
    24
nkeynes@991
    25
/******************************** Constants *****************************/
nkeynes@991
    26
nkeynes@991
    27
#define REG_NONE -1
nkeynes@991
    28
nkeynes@991
    29
/* 64-bit general-purpose regs */
nkeynes@991
    30
#define REG_RAX 0
nkeynes@991
    31
#define REG_RCX 1
nkeynes@991
    32
#define REG_RDX 2
nkeynes@991
    33
#define REG_RBX 3
nkeynes@991
    34
#define REG_RSP 4
nkeynes@991
    35
#define REG_RBP 5
nkeynes@991
    36
#define REG_RSI 6 
nkeynes@991
    37
#define REG_RDI 7
nkeynes@991
    38
#define REG_R8  8
nkeynes@991
    39
#define REG_R9  9
nkeynes@991
    40
#define REG_R10 10
nkeynes@991
    41
#define REG_R11 11
nkeynes@991
    42
#define REG_R12 12
nkeynes@991
    43
#define REG_R13 13
nkeynes@991
    44
#define REG_R14 14
nkeynes@991
    45
#define REG_R15 15
nkeynes@991
    46
nkeynes@991
    47
/* 32-bit general-purpose regs */
nkeynes@991
    48
#define REG_EAX  0
nkeynes@991
    49
#define REG_ECX  1
nkeynes@991
    50
#define REG_EDX  2
nkeynes@991
    51
#define REG_EBX  3
nkeynes@991
    52
#define REG_ESP  4
nkeynes@991
    53
#define REG_EBP  5
nkeynes@991
    54
#define REG_ESI  6 
nkeynes@991
    55
#define REG_EDI  7
nkeynes@991
    56
#define REG_R8D  8
nkeynes@991
    57
#define REG_R9D  9
nkeynes@991
    58
#define REG_R10D 10
nkeynes@991
    59
#define REG_R11D 11
nkeynes@991
    60
#define REG_R12D 12
nkeynes@991
    61
#define REG_R13D 13
nkeynes@991
    62
#define REG_R14D 14
nkeynes@991
    63
#define REG_R15D 15
nkeynes@991
    64
nkeynes@991
    65
/* 8-bit general-purpose regs (no-rex prefix) */
nkeynes@991
    66
#define REG_AL   0
nkeynes@991
    67
#define REG_CL   1
nkeynes@991
    68
#define REG_DL   2
nkeynes@991
    69
#define REG_BL   3
nkeynes@991
    70
#define REG_AH   4
nkeynes@991
    71
#define REG_CH   5
nkeynes@991
    72
#define REG_DH   6
nkeynes@991
    73
#define REG_BH   7
nkeynes@991
    74
nkeynes@991
    75
/* 8-bit general-purpose regs (rex-prefix) */
nkeynes@991
    76
#define REG_SPL  4
nkeynes@991
    77
#define REG_BPL  5
nkeynes@991
    78
#define REG_SIL  6
nkeynes@991
    79
#define REG_DIL  7
nkeynes@991
    80
#define REG_R8L  8
nkeynes@991
    81
#define REG_R9L  9
nkeynes@991
    82
#define REG_R10L 10
nkeynes@991
    83
#define REG_R11L 11
nkeynes@991
    84
#define REG_R12L 12
nkeynes@991
    85
#define REG_R13L 13
nkeynes@991
    86
#define REG_R14L 14
nkeynes@991
    87
#define REG_R15L 15
nkeynes@991
    88
nkeynes@991
    89
/* Condition flag variants */
nkeynes@991
    90
#define X86_COND_O   0x00  /* OF=1 */
nkeynes@991
    91
#define X86_COND_NO  0x01  /* OF=0 */
nkeynes@991
    92
#define X86_COND_B   0x02  /* CF=1 */
nkeynes@991
    93
#define X86_COND_C   0x02  /* CF=1 */
nkeynes@991
    94
#define X86_CONF_NAE 0x02  /* CF=1 */
nkeynes@991
    95
#define X86_COND_AE  0x03  /* CF=0 */
nkeynes@991
    96
#define X86_COND_NB  0x03  /* CF=0 */
nkeynes@991
    97
#define X86_COND_NC  0x03  /* CF=0 */
nkeynes@991
    98
#define X86_COND_E   0x04  /* ZF=1 */
nkeynes@991
    99
#define X86_COND_Z   0x04  /* ZF=1 */
nkeynes@991
   100
#define X86_COND_NE  0x05  /* ZF=0 */
nkeynes@991
   101
#define X86_COND_NZ  0x05  /* ZF=0 */
nkeynes@991
   102
#define X86_COND_BE  0x06  /* CF=1 || ZF=1 */
nkeynes@991
   103
#define X86_COND_NA  0x06  /* CF=1 || ZF=1 */
nkeynes@991
   104
#define X86_COND_A   0x07  /* CF=0 && ZF=0 */
nkeynes@991
   105
#define X86_COND_NBE 0x07  /* CF=0 && ZF=0 */
nkeynes@991
   106
#define X86_COND_S   0x08  /* SF=1 */
nkeynes@991
   107
#define X86_COND_NS  0x09  /* SF=0 */
nkeynes@991
   108
#define X86_COND_P   0x0A  /* PF=1 */
nkeynes@991
   109
#define X86_COND_PE  0x0A  /* PF=1 */
nkeynes@991
   110
#define X86_COND_NP  0x0B  /* PF=0 */
nkeynes@991
   111
#define X86_COND_PO  0x0B  /* PF=0 */
nkeynes@991
   112
#define X86_COND_L   0x0C  /* SF!=OF */
nkeynes@991
   113
#define X86_COND_NGE 0x0C  /* SF!=OF */
nkeynes@991
   114
#define X86_COND_GE  0x0D  /* SF=OF */
nkeynes@991
   115
#define X86_COND_NL  0x0D  /* SF=OF */
nkeynes@991
   116
#define X86_COND_LE  0x0E  /* ZF=1 || SF!=OF */
nkeynes@991
   117
#define X86_COND_NG  0x0E  /* ZF=1 || SF!=OF */
nkeynes@991
   118
#define X86_COND_G   0x0F  /* ZF=0 && SF=OF */
nkeynes@991
   119
#define X86_COND_NLE 0x0F  /* ZF=0 && SF=OF */
nkeynes@991
   120
nkeynes@991
   121
/* SSE floating pointer comparison variants */
nkeynes@991
   122
#define SSE_CMP_EQ    0x00
nkeynes@991
   123
#define SSE_CMP_LT    0x01
nkeynes@991
   124
#define SSE_CMP_LE    0x02
nkeynes@991
   125
#define SSE_CMP_UNORD 0x03
nkeynes@991
   126
#define SSE_CMP_NE    0x04
nkeynes@991
   127
#define SSE_CMP_NLT   0x05
nkeynes@991
   128
#define SSE_CMP_NLE   0x06
nkeynes@991
   129
#define SSE_CMP_ORD   0x07
nkeynes@991
   130
nkeynes@991
   131
/************************** Internal definitions ***************************/
nkeynes@991
   132
#define PREF_REXB 0x41
nkeynes@991
   133
#define PREF_REXX 0x42
nkeynes@991
   134
#define PREF_REXR 0x44
nkeynes@991
   135
#define PREF_REXW 0x48
nkeynes@991
   136
nkeynes@995
   137
/* PREF_REXW if required for pointer operations, otherwise 0 */
nkeynes@995
   138
#define PREF_PTR     ((sizeof(void *) == 8) ? PREF_REXW : 0) 
nkeynes@995
   139
nkeynes@991
   140
extern unsigned char *xlat_output;
nkeynes@991
   141
nkeynes@991
   142
#define OP(x) *xlat_output++ = (x)
nkeynes@991
   143
#define OP16(x) *((uint16_t *)xlat_output) = (x); xlat_output+=2
nkeynes@991
   144
#define OP32(x) *((uint32_t *)xlat_output) = (x); xlat_output+=4
nkeynes@991
   145
#define OP64(x) *((uint64_t *)xlat_output) = (x); xlat_output+=8
nkeynes@991
   146
#define OPPTR(x) *((void **)xlat_output) = ((void *)x); xlat_output+=(sizeof(void*))
nkeynes@991
   147
nkeynes@991
   148
/* Primary opcode emitter, eg OPCODE(0x0FBE) for MOVSX */
nkeynes@1071
   149
#define OPCODE(x) if( (x) > 0xFFFF ) { OP((x)>>16); OP(((x)>>8)&0xFF); OP((x)&0xFF); } else if( (x) > 0xFF ) { OP((x)>>8); OP((x)&0xFF); } else { OP(x); }
nkeynes@991
   150
nkeynes@991
   151
/* Test if immediate value is representable as a signed 8-bit integer */
nkeynes@991
   152
#define IS_INT8(imm) ((imm) >= INT8_MIN && (imm) <= INT8_MAX)
nkeynes@991
   153
nkeynes@991
   154
/**
nkeynes@991
   155
 * Encode opcode+reg with no mod/rm (eg MOV imm64, r32)
nkeynes@991
   156
 */
nkeynes@991
   157
static void x86_encode_opcodereg( int rexw, uint32_t opcode, int reg )
nkeynes@991
   158
{
nkeynes@991
   159
    int rex = rexw;
nkeynes@991
   160
    reg &= 0x0F;
nkeynes@991
   161
    if( reg >= 8 ) {
nkeynes@991
   162
        rex |= PREF_REXB;
nkeynes@991
   163
        reg -= 8;
nkeynes@991
   164
    }
nkeynes@991
   165
    if( rex != 0 ) {
nkeynes@991
   166
        OP(rex);
nkeynes@991
   167
    }
nkeynes@991
   168
    OPCODE(opcode + reg);
nkeynes@991
   169
}
nkeynes@991
   170
nkeynes@991
   171
/**
nkeynes@991
   172
 * Encode opcode with mod/rm reg-reg operation.
nkeynes@991
   173
 * @param opcode primary instruction opcode
nkeynes@991
   174
 * @param rr reg field 
nkeynes@991
   175
 * @param rb r/m field
nkeynes@991
   176
 */
nkeynes@1071
   177
static void x86_encode_reg_rm( int rexw, uint32_t opcode, int rr, int rb )
nkeynes@991
   178
{
nkeynes@991
   179
    int rex = rexw;
nkeynes@991
   180
    rr &= 0x0F;
nkeynes@991
   181
    rb &= 0x0F;
nkeynes@991
   182
    if( rr >= 8 ) {
nkeynes@991
   183
        rex |= PREF_REXR;
nkeynes@991
   184
        rr -= 8;
nkeynes@991
   185
    }
nkeynes@991
   186
    if( rb >= 8 ) {
nkeynes@991
   187
        rex |= PREF_REXB;
nkeynes@991
   188
        rb -= 8;
nkeynes@991
   189
    }
nkeynes@991
   190
    if( rex != 0 ) {
nkeynes@991
   191
        OP(rex);
nkeynes@991
   192
    }
nkeynes@991
   193
    OPCODE(opcode);
nkeynes@991
   194
    OP(0xC0|(rr<<3)|rb);
nkeynes@991
   195
}
nkeynes@991
   196
nkeynes@991
   197
/**
nkeynes@991
   198
 * Encode opcode + 32-bit mod/rm memory address. (RIP-relative not supported here)
nkeynes@991
   199
 * @param rexw REX.W prefix is required, otherwise 0
nkeynes@991
   200
 * @param rr Reg-field register (required). 
nkeynes@991
   201
 * @param rb Base (unscaled) register, or -1 for no base register. 
nkeynes@991
   202
 * @param rx Index (scaled) register, or -1 for no index register
nkeynes@991
   203
 * @param ss Scale shift (0..3) applied to index register (ignored if no index register)
nkeynes@991
   204
 * @param disp32 Signed displacement (0 for none)
nkeynes@991
   205
 */ 
nkeynes@991
   206
static void x86_encode_modrm( int rexw, uint32_t opcode, int rr, int rb, int rx, int ss, int32_t disp32 )
nkeynes@991
   207
{
nkeynes@991
   208
    /* Construct the rex prefix where necessary */
nkeynes@991
   209
    int rex = rexw;
nkeynes@991
   210
    rr &= 0x0F;
nkeynes@991
   211
    if( rr >= 8 ) {
nkeynes@991
   212
        rex |= PREF_REXR;
nkeynes@991
   213
        rr -= 8;
nkeynes@991
   214
    }
nkeynes@991
   215
    if( rb != -1 ) {
nkeynes@991
   216
        rb &= 0x0F;
nkeynes@991
   217
        if( rb >= 8 ) {
nkeynes@991
   218
            rex |= PREF_REXB;
nkeynes@991
   219
            rb -= 8;
nkeynes@991
   220
        }
nkeynes@991
   221
    }
nkeynes@991
   222
    if( rx != -1 ) {
nkeynes@991
   223
        rx &= 0x0F;
nkeynes@991
   224
        if( rx >= 8 ) {
nkeynes@991
   225
            rex |= PREF_REXX;
nkeynes@991
   226
            rx -= 8;
nkeynes@991
   227
        }
nkeynes@991
   228
    }
nkeynes@991
   229
    
nkeynes@991
   230
    if( rex != 0 ) {
nkeynes@991
   231
        OP(rex);
nkeynes@991
   232
    }
nkeynes@991
   233
    OPCODE(opcode);
nkeynes@991
   234
    
nkeynes@991
   235
    if( rx == -1 ) {
nkeynes@991
   236
        if( rb == -1 ) {
nkeynes@991
   237
            /* [disp32] displacement only - use SIB form for 64-bit mode safety */
nkeynes@991
   238
            OP(0x04|(rr<<3));
nkeynes@991
   239
            OP(0x25);
nkeynes@991
   240
            OP32(disp32);
nkeynes@991
   241
        } else if( rb == REG_ESP ) { /* [%esp + disp32] - SIB is mandatory for %esp/%r12 encodings */
nkeynes@991
   242
            if( disp32 == 0 ) {
nkeynes@991
   243
                OP(0x04|(rr<<3));
nkeynes@991
   244
                OP(0x24);
nkeynes@991
   245
            } else if( IS_INT8(disp32) ) {
nkeynes@991
   246
                OP(0x44|(rr<<3));
nkeynes@991
   247
                OP(0x24);
nkeynes@991
   248
                OP((int8_t)disp32);
nkeynes@991
   249
            } else {
nkeynes@991
   250
                OP(0x84|(rr<<3));
nkeynes@991
   251
                OP(0x24);
nkeynes@991
   252
                OP32(disp32);
nkeynes@991
   253
            }
nkeynes@991
   254
        } else {
nkeynes@991
   255
            if( disp32 == 0 && rb != REG_EBP ) { /* [%ebp] is encoded as [%ebp+0] */
nkeynes@991
   256
                OP((rr<<3)|rb);
nkeynes@991
   257
            } else if( IS_INT8(disp32) ) {
nkeynes@991
   258
                OP(0x40|(rr<<3)|rb);
nkeynes@991
   259
                OP((int8_t)disp32);
nkeynes@991
   260
            } else {
nkeynes@991
   261
                OP(0x80|(rr<<3)|rb);
nkeynes@991
   262
                OP32(disp32);
nkeynes@991
   263
            }
nkeynes@991
   264
        }
nkeynes@991
   265
    } else { /* We have a scaled index. Goody */
nkeynes@991
   266
        assert( ((rx != REG_ESP) || (rex&PREF_REXX)) && "Bug: attempt to index through %esp" ); /* Indexing by %esp is impossible */
nkeynes@991
   267
        if( rb == -1 ) { /* [disp32 + rx << ss] */
nkeynes@991
   268
            OP(0x04|(rr<<3));
nkeynes@991
   269
            OP(0x05|(ss<<6)|(rx<<3));
nkeynes@991
   270
            OP32(disp32);
nkeynes@991
   271
        } else if( disp32 == 0 && rb != REG_EBP ) { /* [rb + rx << ss]. (Again, %ebp needs to be %ebp+0) */
nkeynes@991
   272
            OP(0x04|(rr<<3));
nkeynes@991
   273
            OP((ss<<6)|(rx<<3)|rb);
nkeynes@991
   274
        } else if( IS_INT8(disp32) ) {
nkeynes@991
   275
            OP(0x44|(rr<<3));
nkeynes@991
   276
            OP((ss<<6)|(rx<<3)|rb);
nkeynes@991
   277
            OP((int8_t)disp32);
nkeynes@991
   278
        } else {
nkeynes@991
   279
            OP(0x84|(rr<<3));
nkeynes@991
   280
            OP((ss<<6)|(rx<<3)|rb);
nkeynes@991
   281
            OP32(disp32);
nkeynes@991
   282
        }
nkeynes@991
   283
    }
nkeynes@991
   284
}
nkeynes@991
   285
nkeynes@991
   286
/**
nkeynes@991
   287
 * Encode opcode + RIP-relative mod/rm (64-bit mode only)
nkeynes@991
   288
 * @param rexw PREF_REXW or 0
nkeynes@991
   289
 * @param opcode primary instruction opcode
nkeynes@991
   290
 * @param rr mod/rm reg field
nkeynes@991
   291
 * @param disp32 RIP-relative displacement
nkeynes@991
   292
 */
nkeynes@991
   293
static void x86_encode_modrm_rip(int rexw, uint32_t opcode, int rr, int32_t disp32)
nkeynes@991
   294
{
nkeynes@991
   295
    int rex = rexw;
nkeynes@991
   296
    rr &= 0x0F;
nkeynes@991
   297
    if( rr >= 8 ) {
nkeynes@991
   298
        rex |= PREF_REXR;
nkeynes@991
   299
        rr -= 8;
nkeynes@991
   300
    }
nkeynes@991
   301
    if( rex != 0 ) {
nkeynes@991
   302
        OP(rex);
nkeynes@991
   303
    }
nkeynes@991
   304
    OPCODE(opcode);
nkeynes@991
   305
    OP(0x05|(rr<<3));
nkeynes@991
   306
    OP32(disp32);
nkeynes@991
   307
}
nkeynes@991
   308
nkeynes@991
   309
/* 32/64-bit op emitters. 64-bit versions include a rex.w prefix. Note that any
nkeynes@991
   310
 * other prefixes (mandatory or otherwise) need to be emitted prior to these 
nkeynes@991
   311
 * functions
nkeynes@991
   312
 */ 
nkeynes@991
   313
#define x86_encode_opcode64(opcode,reg) x86_encode_opcodereg(PREF_REXW, opcode,reg)
nkeynes@991
   314
#define x86_encode_opcode32(opcode,reg) x86_encode_opcodereg(0,opcode,reg)
nkeynes@991
   315
#define x86_encode_r32_rm32(opcode,rr,rb) x86_encode_reg_rm(0,opcode,rr,rb)
nkeynes@991
   316
#define x86_encode_r64_rm64(opcode,rr,rb) x86_encode_reg_rm(PREF_REXW,opcode,rr,rb)
nkeynes@1112
   317
#define x86_encode_rptr_rmptr(opcode,rr,rb) x86_encode_reg_rm(PREF_PTR,opcode,rr,rb)
nkeynes@991
   318
#define x86_encode_r32_mem32(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(0,opcode,rr,rb,rx,ss,disp32)
nkeynes@991
   319
#define x86_encode_r64_mem64(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,rb,rx,ss,disp32)
nkeynes@995
   320
#define x86_encode_rptr_memptr(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(PREF_PTR,opcode,rr,rb,rx,ss,disp32)
nkeynes@991
   321
#define x86_encode_r32_mem32disp32(opcode,rr,rb,disp32) x86_encode_modrm(0,opcode,rr,rb,-1,0,disp32)
nkeynes@991
   322
#define x86_encode_r64_mem64disp64(opcode,rr,rb,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,rb,-1,0,disp32)
nkeynes@991
   323
#define x86_encode_r32_ripdisp32(opcode,rr,disp32) x86_encode_modrm_rip(0,opcode,rr,disp32)
nkeynes@991
   324
#define x86_encode_r64_ripdisp64(opcode,rr,disp32) x86_encode_modrm_rip(PREF_REXW,opcode,rr,disp32)
nkeynes@991
   325
nkeynes@991
   326
/* Convenience versions for the common rbp/rsp relative displacements */
nkeynes@991
   327
#define x86_encode_r32_rbpdisp32(opcode,rr,disp32) x86_encode_modrm(0,opcode,rr,REG_RBP,-1,0,disp32)
nkeynes@991
   328
#define x86_encode_r64_rbpdisp64(opcode,rr,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,REG_RBP,-1,0,disp32)
nkeynes@991
   329
#define x86_encode_r32_rspdisp32(opcode,rr,disp32) x86_encode_modrm(0,opcode,rr,REG_RSP,-1,0,disp32)
nkeynes@991
   330
#define x86_encode_r64_rspdisp64(opcode,rr,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,REG_RSP,-1,0,disp32)
nkeynes@991
   331
nkeynes@991
   332
/* Immediate-selection variants (for instructions with imm8s/imm32 variants) */
nkeynes@991
   333
#define x86_encode_imms_rm32(opcode8,opcode32,reg,imm,rb) \
nkeynes@991
   334
    if( IS_INT8(((int32_t)imm)) ) { x86_encode_r32_rm32(opcode8,reg,rb); OP((int8_t)imm); \
nkeynes@991
   335
                } else { x86_encode_r32_rm32(opcode32,reg,rb); OP32(imm); }
nkeynes@991
   336
#define x86_encode_imms_rm64(opcode8,opcode32,reg,imm,rb) \
nkeynes@991
   337
    if( IS_INT8(((int32_t)imm)) ) { x86_encode_r64_rm64(opcode8,reg,rb); OP((int8_t)imm); \
nkeynes@991
   338
                } else { x86_encode_r64_rm64(opcode32,reg,rb); OP32(imm); }
nkeynes@995
   339
#define x86_encode_imms_rmptr(opcode8,opcode32,reg,imm,rb) \
nkeynes@995
   340
    if( IS_INT8(((int32_t)imm)) ) { x86_encode_reg_rm( PREF_PTR, opcode8,reg,rb); OP((int8_t)imm); \
nkeynes@995
   341
                } else { x86_encode_reg_rm( PREF_PTR, opcode32,reg,rb); OP32(imm); }
nkeynes@991
   342
#define x86_encode_imms_rbpdisp32(opcode8,opcode32,reg,imm,disp) \
nkeynes@991
   343
    if( IS_INT8(((int32_t)imm)) ) { x86_encode_r32_rbpdisp32(opcode8,reg,disp); OP((int8_t)imm); \
nkeynes@991
   344
                } else { x86_encode_r32_rbpdisp32(opcode32,reg,disp); OP32(imm); }
nkeynes@991
   345
#define x86_encode_imms_r32disp32(opcode8,opcode32,reg,imm,rb,disp) \
nkeynes@991
   346
    if( IS_INT8(((int32_t)imm)) ) { x86_encode_r32_mem32disp32(opcode8,reg,rb,disp); OP((int8_t)imm); \
nkeynes@991
   347
                } else { x86_encode_r32_mem32disp32(opcode32,reg,rb,disp); OP32(imm); }
nkeynes@991
   348
#define x86_encode_imms_rbpdisp64(opcode8,opcode32,reg,imm,disp) \
nkeynes@991
   349
    if( IS_INT8(((int32_t)imm)) ) { x86_encode_r64_rbpdisp64(opcode8,reg,disp); OP((int8_t)imm); \
nkeynes@991
   350
                } else { x86_encode_r64_rbpdisp64(opcode32,reg,disp); OP32(imm); }
nkeynes@991
   351
nkeynes@991
   352
/*************************** Instruction definitions ***********************/
nkeynes@991
   353
/* Note this does not try to be an exhaustive definition of the instruction -
nkeynes@991
   354
 * it generally only has the forms that we actually need here.
nkeynes@991
   355
 */
nkeynes@991
   356
/* Core Integer instructions */
nkeynes@991
   357
#define ADCB_imms_r8(imm,r1)         x86_encode_r32_rm32(0x80, 2, r1); OP(imm)
nkeynes@991
   358
#define ADCB_r8_r8(r1,r2)            x86_encode_r32_rm32(0x10, r1, r2)
nkeynes@991
   359
#define ADCL_imms_r32(imm,r1)        x86_encode_imms_rm32(0x83, 0x81, 2, imm, r1)
nkeynes@991
   360
#define ADCL_imms_rbpdisp(imm,disp)  x86_encode_imms_rbpdisp32(0x83, 0x81, 2, imm, disp)
nkeynes@991
   361
#define ADCL_r32_r32(r1,r2)          x86_encode_r32_rm32(0x11, r1, r2)
nkeynes@991
   362
#define ADCL_r32_rbpdisp(r1,disp)    x86_encode_r32_rbpdisp32(0x11, r1, disp)
nkeynes@991
   363
#define ADCL_rbpdisp_r32(disp,r1)    x86_encode_r32_rbpdisp32(0x13, r1, disp)
nkeynes@991
   364
#define ADCQ_imms_r64(imm,r1)        x86_encode_imms_rm64(0x83, 0x81, 2, imm, r1)
nkeynes@991
   365
#define ADCQ_r64_r64(r1,r2)          x86_encode_r64_rm64(0x11, r1, r2)
nkeynes@991
   366
nkeynes@991
   367
#define ADDB_imms_r8(imm,r1)         x86_encode_r32_rm32(0x80, 0, r1); OP(imm)
nkeynes@991
   368
#define ADDB_r8_r8(r1,r2)            x86_encode_r32_rm32(0x00, r1, r2)
nkeynes@991
   369
#define ADDL_imms_r32(imm,r1)        x86_encode_imms_rm32(0x83, 0x81, 0, imm, r1)
nkeynes@991
   370
#define ADDL_imms_r32disp(imm,rb,d)  x86_encode_imms_r32disp32(0x83, 0x81, 0, imm, rb, d)
nkeynes@991
   371
#define ADDL_imms_rbpdisp(imm,disp)  x86_encode_imms_rbpdisp32(0x83, 0x81, 0, imm, disp)
nkeynes@991
   372
#define ADDL_r32_r32(r1,r2)          x86_encode_r32_rm32(0x01, r1, r2)
nkeynes@991
   373
#define ADDL_r32_rbpdisp(r1,disp)    x86_encode_r32_rbpdisp32(0x01, r1, disp)
nkeynes@991
   374
#define ADDL_r32_r32disp(r1,r2,dsp)  x86_encode_r32_mem32disp32(0x01, r1, r2, dsp)
nkeynes@991
   375
#define ADDL_rbpdisp_r32(disp,r1)    x86_encode_r32_rbpdisp32(0x03, r1, disp)
nkeynes@991
   376
#define ADDQ_imms_r64(imm,r1)        x86_encode_imms_rm64(0x83, 0x81, 0, imm, r1)
nkeynes@991
   377
#define ADDQ_r64_r64(r1,r2)          x86_encode_r64_rm64(0x01, r1, r2)
nkeynes@991
   378
nkeynes@991
   379
#define ANDB_imms_r8(imm,r1)         x86_encode_r32_rm32(0x80, 4, r1); OP(imm)
nkeynes@991
   380
#define ANDB_r8_r8(r1,r2)            x86_encode_r32_rm32(0x20, r1, r2)
nkeynes@991
   381
#define ANDL_imms_r32(imm,r1)        x86_encode_imms_rm32(0x83, 0x81, 4, imm, r1)
nkeynes@991
   382
#define ANDL_imms_rbpdisp(imm,disp)  x86_encode_imms_rbpdisp32(0x83,0x81,4,imm,disp)
nkeynes@991
   383
#define ANDL_r32_r32(r1,r2)          x86_encode_r32_rm32(0x21, r1, r2)
nkeynes@991
   384
#define ANDL_r32_rbpdisp(r1,disp)    x86_encode_r32_rbpdisp32(0x21, r1, disp)
nkeynes@991
   385
#define ANDL_rbpdisp_r32(disp,r1)    x86_encode_r32_rbpdisp32(0x23, r1, disp)
nkeynes@991
   386
#define ANDQ_r64_r64(r1,r2)          x86_encode_r64_rm64(0x21, r1, r2)
nkeynes@991
   387
#define ANDQ_imms_r64(imm,r1)        x86_encode_imms_rm64(0x83, 0x81, 4, imm, r1)
nkeynes@995
   388
#define ANDP_imms_rptr(imm,r1)       x86_encode_imms_rmptr(0x83, 0x81, 4, imm, r1)       
nkeynes@991
   389
nkeynes@991
   390
#define CLC()                        OP(0xF8)
nkeynes@991
   391
#define CLD()                        OP(0xFC)
nkeynes@991
   392
#define CMC()                        OP(0xF5)
nkeynes@991
   393
nkeynes@991
   394
#define CMOVCCL_cc_r32_r32(cc,r1,r2) x86_encode_r32_rm32(0x0F40+(cc), r2, r1)
nkeynes@991
   395
#define CMOVCCL_cc_rbpdisp_r32(cc,d,r1) x86_encode_r32_rbpdisp32(0x0F40+(cc), r1, d)
nkeynes@991
   396
nkeynes@991
   397
#define CMPB_imms_r8(imm,r1)         x86_encode_r32_rm32(0x80, 7, r1); OP(imm)
nkeynes@991
   398
#define CMPB_imms_rbpdisp(imm,disp)  x86_encode_r32_rbpdisp32(0x80, 7, disp); OP(imm)
nkeynes@991
   399
#define CMPB_r8_r8(r1,r2)            x86_encode_r32_rm32(0x38, r1, r2)
nkeynes@991
   400
#define CMPL_imms_r32(imm,r1)        x86_encode_imms_rm32(0x83, 0x81, 7, imm, r1)
nkeynes@1112
   401
#define CMPL_imms_r32disp(imm,rb,d)  x86_encode_imms_r32disp32(0x83, 0x81, 7, imm, rb, d)
nkeynes@991
   402
#define CMPL_imms_rbpdisp(imm,disp)  x86_encode_imms_rbpdisp32(0x83, 0x81, 7, imm, disp)
nkeynes@991
   403
#define CMPL_r32_r32(r1,r2)          x86_encode_r32_rm32(0x39, r1, r2)
nkeynes@1112
   404
#define CMPL_r32_r32disp(r1,r2,dsp)  x86_encode_r32_mem32disp32(0x39, r1, r2, dsp)
nkeynes@991
   405
#define CMPL_r32_rbpdisp(r1,disp)    x86_encode_r32_rbpdisp32(0x39, r1, disp)
nkeynes@991
   406
#define CMPL_rbpdisp_r32(disp,r1)    x86_encode_r32_rbpdisp32(0x3B, r1, disp)
nkeynes@991
   407
#define CMPQ_imms_r64(imm,r1)        x86_encode_imms_rm64(0x83, 0x81, 7, imm, r1)
nkeynes@991
   408
#define CMPQ_r64_r64(r1,r2)          x86_encode_r64_rm64(0x39, r1, r2)
nkeynes@991
   409
nkeynes@991
   410
#define IDIVL_r32(r1)                x86_encode_r32_rm32(0xF7, 7, r1)
nkeynes@991
   411
#define IDIVL_rbpdisp(disp)          x86_encode_r32_rbpdisp32(0xF7, 7, disp)
nkeynes@991
   412
#define IDIVQ_r64(r1)                x86_encode_r64_rm64(0xF7, 7, r1)
nkeynes@991
   413
nkeynes@991
   414
#define IMULL_imms_r32(imm,r1)       x86_encode_imms_rm32(0x6B,0x69, r1, imm, r1)
nkeynes@991
   415
#define IMULL_r32(r1)                x86_encode_r32_rm32(0xF7, 5, r1)
nkeynes@991
   416
#define IMULL_r32_r32(r1,r2)         x86_encode_r32_rm32(0x0FAF, r2, r1)
nkeynes@991
   417
#define IMULL_rbpdisp(disp)          x86_encode_r32_rbpdisp32(0xF7, 5, disp)
nkeynes@991
   418
#define IMULL_rbpdisp_r32(disp,r1)   x86_encode_r32_rbpdisp32(0x0FAF, r1, disp)
nkeynes@991
   419
#define IMULL_rspdisp(disp)          x86_encode_r32_rspdisp32(0xF7, 5, disp)
nkeynes@991
   420
#define IMULL_rspdisp_r32(disp,r1)   x86_encode_r32_rspdisp32(0x0FAF, r1, disp)
nkeynes@991
   421
#define IMULQ_imms_r64(imm,r1)       x86_encode_imms_rm64(0x6B,0x69, r1, imm, r1)
nkeynes@991
   422
#define IMULQ_r64_r64(r1,r2)         x86_encode_r64_rm64(0x0FAF, r2, r1)
nkeynes@991
   423
nkeynes@991
   424
#define LEAL_r32disp_r32(r1,disp,r2) x86_encode_r32_mem32(0x8D, r2, r1, -1, 0, disp)
nkeynes@991
   425
#define LEAL_rbpdisp_r32(disp,r1)    x86_encode_r32_rbpdisp32(0x8D, r1, disp)
nkeynes@991
   426
#define LEAL_sib_r32(ss,ii,bb,d,r1)  x86_encode_r32_mem32(0x8D, r1, bb, ii, ss, d)
nkeynes@991
   427
#define LEAQ_r64disp_r64(r1,disp,r2) x86_encode_r64_mem64(0x8D, r2, r1, -1, 0, disp)
nkeynes@991
   428
#define LEAQ_rbpdisp_r64(disp,r1)    x86_encode_r64_rbpdisp64(0x8D, r1, disp)
nkeynes@1112
   429
#define LEAP_rptrdisp_rptr(r1,d,r2)  x86_encode_rptr_memptr(0x8D, r2, r1, -1, 0, d)
nkeynes@991
   430
#define LEAP_rbpdisp_rptr(disp,r1)   x86_encode_rptr_memptr(0x8D, r1, REG_RBP, -1, 0, disp)
nkeynes@991
   431
#define LEAP_sib_rptr(ss,ii,bb,d,r1) x86_encode_rptr_memptr(0x8D, r1, bb, ii, ss, d)
nkeynes@991
   432
nkeynes@991
   433
#define MOVB_r8_r8(r1,r2)            x86_encode_r32_rm32(0x88, r1, r2)
nkeynes@991
   434
#define MOVL_imm32_r32(i32,r1)       x86_encode_opcode32(0xB8, r1); OP32(i32)
nkeynes@991
   435
#define MOVL_imm32_rbpdisp(i,disp)   x86_encode_r32_rbpdisp32(0xC7,0,disp); OP32(i)
nkeynes@991
   436
#define MOVL_imm32_rspdisp(i,disp)   x86_encode_r32_rspdisp32(0xC7,0,disp); OP32(i)
nkeynes@991
   437
#define MOVL_moffptr_eax(p)          OP(0xA1); OPPTR(p)
nkeynes@991
   438
#define MOVL_r32_r32(r1,r2)          x86_encode_r32_rm32(0x89, r1, r2)
nkeynes@991
   439
#define MOVL_r32_r32disp(r1,r2,dsp)  x86_encode_r32_mem32disp32(0x89, r1, r2, dsp)
nkeynes@991
   440
#define MOVL_r32_rbpdisp(r1,disp)    x86_encode_r32_rbpdisp32(0x89, r1, disp)
nkeynes@991
   441
#define MOVL_r32_rspdisp(r1,disp)    x86_encode_r32_rspdisp32(0x89, r1, disp)
nkeynes@991
   442
#define MOVL_r32_sib(r1,ss,ii,bb,d)  x86_encode_r32_mem32(0x89, r1, bb, ii, ss, d)
nkeynes@991
   443
#define MOVL_r32disp_r32(r1,dsp,r2)  x86_encode_r32_mem32disp32(0x8B, r2, r1, dsp)
nkeynes@991
   444
#define MOVL_rbpdisp_r32(disp,r1)    x86_encode_r32_rbpdisp32(0x8B, r1, disp)
nkeynes@991
   445
#define MOVL_rspdisp_r32(disp,r1)    x86_encode_r32_rspdisp32(0x8B, r1, disp)
nkeynes@991
   446
#define MOVL_sib_r32(ss,ii,bb,d,r1)  x86_encode_r32_mem32(0x8B, r1, bb, ii, ss, d)
nkeynes@991
   447
#define MOVQ_imm64_r64(i64,r1)       x86_encode_opcode64(0xB8, r1); OP64(i64)
nkeynes@991
   448
#define MOVQ_moffptr_rax(p)          OP(PREF_REXW); OP(0xA1); OPPTR(p)
nkeynes@991
   449
#define MOVQ_r64_r64(r1,r2)          x86_encode_r64_rm64(0x89, r1, r2)
nkeynes@991
   450
#define MOVQ_r64_rbpdisp(r1,disp)    x86_encode_r64_rbpdisp64(0x89, r1, disp)
nkeynes@991
   451
#define MOVQ_r64_rspdisp(r1,disp)    x86_encode_r64_rspdisp64(0x89, r1, disp)
nkeynes@991
   452
#define MOVQ_rbpdisp_r64(disp,r1)    x86_encode_r64_rbpdisp64(0x8B, r1, disp)
nkeynes@991
   453
#define MOVQ_rspdisp_r64(disp,r1)    x86_encode_r64_rspdisp64(0x8B, r1, disp)
nkeynes@995
   454
#define MOVP_immptr_rptr(p,r1)       x86_encode_opcodereg( PREF_PTR, 0xB8, r1); OPPTR(p)
nkeynes@991
   455
#define MOVP_moffptr_rax(p)          if( sizeof(void*)==8 ) { OP(PREF_REXW); } OP(0xA1); OPPTR(p)
nkeynes@995
   456
#define MOVP_rptr_rptr(r1,r2)        x86_encode_reg_rm(PREF_PTR, 0x89, r1, r2)
nkeynes@991
   457
#define MOVP_sib_rptr(ss,ii,bb,d,r1) x86_encode_rptr_memptr(0x8B, r1, bb, ii, ss, d)
nkeynes@991
   458
nkeynes@991
   459
#define MOVSXL_r8_r32(r1,r2)         x86_encode_r32_rm32(0x0FBE, r2, r1)
nkeynes@991
   460
#define MOVSXL_r16_r32(r1,r2)        x86_encode_r32_rm32(0x0FBF, r2, r1)
nkeynes@991
   461
#define MOVSXL_rbpdisp8_r32(disp,r1) x86_encode_r32_rbpdisp32(0x0FBE, r1, disp) 
nkeynes@991
   462
#define MOVSXL_rbpdisp16_r32(dsp,r1) x86_encode_r32_rbpdisp32(0x0FBF, r1, dsp) 
nkeynes@991
   463
#define MOVSXQ_imm32_r64(i32,r1)     x86_encode_r64_rm64(0xC7, 0, r1); OP32(i32) /* Technically a MOV */
nkeynes@991
   464
#define MOVSXQ_r8_r64(r1,r2)         x86_encode_r64_rm64(0x0FBE, r2, r1)
nkeynes@991
   465
#define MOVSXQ_r16_r64(r1,r2)        x86_encode_r64_rm64(0x0FBF, r2, r1)
nkeynes@991
   466
#define MOVSXQ_r32_r64(r1,r2)        x86_encode_r64_rm64(0x63, r2, r1)
nkeynes@991
   467
#define MOVSXQ_rbpdisp32_r64(dsp,r1) x86_encode_r64_rbpdisp64(0x63, r1, dsp)
nkeynes@991
   468
nkeynes@991
   469
#define MOVZXL_r8_r32(r1,r2)         x86_encode_r32_rm32(0x0FB6, r2, r1)
nkeynes@991
   470
#define MOVZXL_r16_r32(r1,r2)        x86_encode_r32_rm32(0x0FB7, r2, r1)
nkeynes@991
   471
#define MOVZXL_rbpdisp8_r32(disp,r1) x86_encode_r32_rbpdisp32(0x0FB6, r1, disp)
nkeynes@991
   472
#define MOVZXL_rbpdisp16_r32(dsp,r1) x86_encode_r32_rbpdisp32(0x0FB7, r1, dsp)
nkeynes@991
   473
nkeynes@991
   474
#define MULL_r32(r1)                 x86_encode_r32_rm32(0xF7, 4, r1)
nkeynes@991
   475
#define MULL_rbpdisp(disp)           x86_encode_r32_rbpdisp32(0xF7,4,disp)
nkeynes@991
   476
#define MULL_rspdisp(disp)           x86_encode_r32_rspdisp32(0xF7,4,disp)
nkeynes@991
   477
nkeynes@991
   478
#define NEGB_r8(r1)                  x86_encode_r32_rm32(0xF6, 3, r1)
nkeynes@991
   479
#define NEGL_r32(r1)                 x86_encode_r32_rm32(0xF7, 3, r1)
nkeynes@991
   480
#define NEGL_rbpdisp(r1)             x86_encode_r32_rbspdisp32(0xF7, 3, disp)
nkeynes@991
   481
#define NEGQ_r64(r1)                 x86_encode_r64_rm64(0xF7, 3, r1)
nkeynes@991
   482
nkeynes@991
   483
#define NOTB_r8(r1)                  x86_encode_r32_rm32(0xF6, 2, r1)
nkeynes@991
   484
#define NOTL_r32(r1)                 x86_encode_r32_rm32(0xF7, 2, r1)
nkeynes@991
   485
#define NOTL_rbpdisp(r1)             x86_encode_r32_rbspdisp32(0xF7, 2, disp)
nkeynes@991
   486
#define NOTQ_r64(r1)                 x86_encode_r64_rm64(0xF7, 2, r1)
nkeynes@991
   487
nkeynes@991
   488
#define ORB_imms_r8(imm,r1)          x86_encode_r32_rm32(0x80, 1, r1); OP(imm)
nkeynes@991
   489
#define ORB_r8_r8(r1,r2)             x86_encode_r32_rm32(0x08, r1, r2)
nkeynes@991
   490
#define ORL_imms_r32(imm,r1)         x86_encode_imms_rm32(0x83, 0x81, 1, imm, r1)
nkeynes@991
   491
#define ORL_imms_rbpdisp(imm,disp)   x86_encode_imms_rbpdisp32(0x83,0x81,1,imm,disp)
nkeynes@991
   492
#define ORL_r32_r32(r1,r2)           x86_encode_r32_rm32(0x09, r1, r2)
nkeynes@991
   493
#define ORL_r32_rbpdisp(r1,disp)     x86_encode_r32_rbpdisp32(0x09, r1, disp)
nkeynes@991
   494
#define ORL_rbpdisp_r32(disp,r1)     x86_encode_r32_rbpdisp32(0x0B, r1, disp)
nkeynes@991
   495
#define ORQ_imms_r64(imm,r1)         x86_encode_imms_rm64(0x83, 0x81, 1, imm, r1)
nkeynes@991
   496
#define ORQ_r64_r64(r1,r2)           x86_encode_r64_rm64(0x09, r1, r2)
nkeynes@991
   497
nkeynes@991
   498
#define POP_r32(r1)                  x86_encode_opcode32(0x58, r1)
nkeynes@991
   499
nkeynes@991
   500
#define PUSH_imm32(imm)              OP(0x68); OP32(imm)
nkeynes@991
   501
#define PUSH_r32(r1)                 x86_encode_opcode32(0x50, r1)
nkeynes@991
   502
nkeynes@991
   503
#define RCLL_cl_r32(r1)              x86_encode_r32_rm32(0xD3,2,r1)
nkeynes@991
   504
#define RCLL_imm_r32(imm,r1)         if( imm == 1 ) { x86_encode_r32_rm32(0xD1,2,r1); } else { x86_encode_r32_rm32(0xC1,2,r1); OP(imm); }
nkeynes@991
   505
#define RCLQ_cl_r64(r1)              x86_encode_r64_rm64(0xD3,2,r1)
nkeynes@991
   506
#define RCLQ_imm_r64(imm,r1)         if( imm == 1 ) { x86_encode_r64_rm64(0xD1,2,r1); } else { x86_encode_r64_rm64(0xC1,2,r1); OP(imm); }
nkeynes@991
   507
#define RCRL_cl_r32(r1)              x86_encode_r32_rm32(0xD3,3,r1)
nkeynes@991
   508
#define RCRL_imm_r32(imm,r1)         if( imm == 1 ) { x86_encode_r32_rm32(0xD1,3,r1); } else { x86_encode_r32_rm32(0xC1,3,r1); OP(imm); }
nkeynes@991
   509
#define RCRQ_cl_r64(r1)              x86_encode_r64_rm64(0xD3,3,r1)
nkeynes@991
   510
#define RCRQ_imm_r64(imm,r1)         if( imm == 1 ) { x86_encode_r64_rm64(0xD1,3,r1); } else { x86_encode_r64_rm64(0xC1,3,r1); OP(imm); }
nkeynes@991
   511
#define ROLL_cl_r32(r1)              x86_encode_r32_rm32(0xD3,0,r1)
nkeynes@991
   512
#define ROLL_imm_r32(imm,r1)         if( imm == 1 ) { x86_encode_r32_rm32(0xD1,0,r1); } else { x86_encode_r32_rm32(0xC1,0,r1); OP(imm); }
nkeynes@991
   513
#define ROLQ_cl_r64(r1)              x86_encode_r64_rm64(0xD3,0,r1)
nkeynes@991
   514
#define ROLQ_imm_r64(imm,r1)         if( imm == 1 ) { x86_encode_r64_rm64(0xD1,0,r1); } else { x86_encode_r64_rm64(0xC1,0,r1); OP(imm); }
nkeynes@991
   515
#define RORL_cl_r32(r1)              x86_encode_r32_rm32(0xD3,1,r1)
nkeynes@991
   516
#define RORL_imm_r32(imm,r1)         if( imm == 1 ) { x86_encode_r32_rm32(0xD1,1,r1); } else { x86_encode_r32_rm32(0xC1,1,r1); OP(imm); }
nkeynes@991
   517
#define RORQ_cl_r64(r1)              x86_encode_r64_rm64(0xD3,1,r1)
nkeynes@991
   518
#define RORQ_imm_r64(imm,r1)         if( imm == 1 ) { x86_encode_r64_rm64(0xD1,1,r1); } else { x86_encode_r64_rm64(0xC1,1,r1); OP(imm); }
nkeynes@991
   519
nkeynes@991
   520
#define SARL_cl_r32(r1)              x86_encode_r32_rm32(0xD3,7,r1)
nkeynes@991
   521
#define SARL_imm_r32(imm,r1)         if( imm == 1 ) { x86_encode_r32_rm32(0xD1,7,r1); } else { x86_encode_r32_rm32(0xC1,7,r1); OP(imm); }
nkeynes@991
   522
#define SARQ_cl_r64(r1)              x86_encode_r64_rm64(0xD3,7,r1)
nkeynes@991
   523
#define SARQ_imm_r64(imm,r1)         if( imm == 1 ) { x86_encode_r64_rm64(0xD1,7,r1); } else { x86_encode_r64_rm64(0xC1,7,r1); OP(imm); }
nkeynes@991
   524
#define SHLL_cl_r32(r1)              x86_encode_r32_rm32(0xD3,4,r1)
nkeynes@991
   525
#define SHLL_imm_r32(imm,r1)         if( imm == 1 ) { x86_encode_r32_rm32(0xD1,4,r1); } else { x86_encode_r32_rm32(0xC1,4,r1); OP(imm); }
nkeynes@991
   526
#define SHLQ_cl_r64(r1)              x86_encode_r64_rm64(0xD3,4,r1)
nkeynes@991
   527
#define SHLQ_imm_r64(imm,r1)         if( imm == 1 ) { x86_encode_r64_rm64(0xD1,4,r1); } else { x86_encode_r64_rm64(0xC1,4,r1); OP(imm); }
nkeynes@991
   528
#define SHRL_cl_r32(r1)              x86_encode_r32_rm32(0xD3,5,r1)
nkeynes@991
   529
#define SHRL_imm_r32(imm,r1)         if( imm == 1 ) { x86_encode_r32_rm32(0xD1,5,r1); } else { x86_encode_r32_rm32(0xC1,5,r1); OP(imm); }
nkeynes@991
   530
#define SHRQ_cl_r64(r1)              x86_encode_r64_rm64(0xD3,5,r1)
nkeynes@991
   531
#define SHRQ_imm_r64(imm,r1)         if( imm == 1 ) { x86_encode_r64_rm64(0xD1,5,r1); } else { x86_encode_r64_rm64(0xC1,5,r1); OP(imm); }
nkeynes@991
   532
nkeynes@991
   533
#define SBBB_imms_r8(imm,r1)         x86_encode_r32_rm32(0x80, 3, r1); OP(imm)
nkeynes@991
   534
#define SBBB_r8_r8(r1,r2)            x86_encode_r32_rm32(0x18, r1, r2)
nkeynes@991
   535
#define SBBL_imms_r32(imm,r1)        x86_encode_imms_rm32(0x83, 0x81, 3, imm, r1)
nkeynes@991
   536
#define SBBL_imms_rbpdisp(imm,disp)  x86_encode_imms_rbpdisp32(0x83,0x81,3,imm,disp)
nkeynes@991
   537
#define SBBL_r32_r32(r1,r2)          x86_encode_r32_rm32(0x19, r1, r2)
nkeynes@991
   538
#define SBBL_r32_rbpdisp(r1,disp)    x86_encode_r32_rbpdisp32(0x19, r1, disp)
nkeynes@991
   539
#define SBBL_rbpdisp_r32(disp,r1)    x86_encode_r32_rbpdisp32(0x1B, r1, disp)
nkeynes@991
   540
#define SBBQ_imms_r64(imm,r1)        x86_encode_imms_rm64(0x83, 0x81, 3, imm, r1)
nkeynes@991
   541
#define SBBQ_r64_r64(r1,r2)          x86_encode_r64_rm64(0x19, r1, r2)
nkeynes@991
   542
nkeynes@991
   543
#define SETCCB_cc_r8(cc,r1)          x86_encode_r32_rm32(0x0F90+(cc), 0, r1)
nkeynes@991
   544
#define SETCCB_cc_rbpdisp(cc,disp)   x86_encode_r32_rbpdisp32(0x0F90+(cc), 0, disp)
nkeynes@991
   545
nkeynes@991
   546
#define STC()                        OP(0xF9)
nkeynes@991
   547
#define STD()                        OP(0xFD)
nkeynes@991
   548
nkeynes@991
   549
#define SUBB_imms_r8(imm,r1)         x86_encode_r32_rm32(0x80, 5, r1); OP(imm)
nkeynes@991
   550
#define SUBB_r8_r8(r1,r2)            x86_encode_r32_rm32(0x28, r1, r2)
nkeynes@991
   551
#define SUBL_imms_r32(imm,r1)        x86_encode_imms_rm32(0x83, 0x81, 5, imm, r1)
nkeynes@991
   552
#define SUBL_imms_rbpdisp(imm,disp)  x86_encode_imms_rbpdisp32(0x83,0x81,5,imm,disp)
nkeynes@991
   553
#define SUBL_r32_r32(r1,r2)          x86_encode_r32_rm32(0x29, r1, r2)
nkeynes@991
   554
#define SUBL_r32_rbpdisp(r1,disp)    x86_encode_r32_rbpdisp32(0x29, r1, disp)
nkeynes@991
   555
#define SUBL_rbpdisp_r32(disp,r1)    x86_encode_r32_rbpdisp32(0x2B, r1, disp)
nkeynes@991
   556
#define SUBQ_imms_r64(imm,r1)        x86_encode_imms_rm64(0x83, 0x81, 5, imm, r1)
nkeynes@991
   557
#define SUBQ_r64_r64(r1,r2)          x86_encode_r64_rm64(0x29, r1, r2)
nkeynes@991
   558
nkeynes@991
   559
#define TESTB_imms_r8(imm,r1)        x86_encode_r32_rm32(0xF6, 0, r1); OP(imm)
nkeynes@991
   560
#define TESTB_r8_r8(r1,r2)           x86_encode_r32_rm32(0x84, r1, r2)
nkeynes@991
   561
#define TESTL_imms_r32(imm,r1)       x86_encode_r32_rm32(0xF7, 0, r1); OP32(imm)
nkeynes@991
   562
#define TESTL_imms_rbpdisp(imm,dsp)  x86_encode_r32_rbpdisp32(0xF7, 0, dsp); OP32(imm)
nkeynes@991
   563
#define TESTL_r32_r32(r1,r2)         x86_encode_r32_rm32(0x85, r1, r2)
nkeynes@991
   564
#define TESTL_r32_rbpdisp(r1,disp)   x86_encode_r32_rbpdisp32(0x85, r1, disp)
nkeynes@991
   565
#define TESTL_rbpdisp_r32(disp,r1)   x86_encode_r32_rbpdisp32(0x85, r1, disp) /* Same OP */
nkeynes@991
   566
#define TESTQ_imms_r64(imm,r1)       x86_encode_r64_rm64(0xF7, 0, r1); OP32(imm)
nkeynes@991
   567
#define TESTQ_r64_r64(r1,r2)         x86_encode_r64_rm64(0x85, r1, r2)
nkeynes@1112
   568
#define TESTP_rptr_rptr(r1,r2)       x86_encode_rptr_rmptr(0x85, r1, r2)
nkeynes@991
   569
nkeynes@991
   570
#define XCHGB_r8_r8(r1,r2)           x86_encode_r32_rm32(0x86, r1, r2)
nkeynes@991
   571
#define XCHGL_r32_r32(r1,r2)         x86_encode_r32_rm32(0x87, r1, r2)
nkeynes@991
   572
#define XCHGQ_r64_r64(r1,r2)         x86_encode_r64_rm64(0x87, r1, r2)
nkeynes@991
   573
nkeynes@991
   574
#define XORB_imms_r8(imm,r1)         x86_encode_r32_rm32(0x80, 6, r1); OP(imm)
nkeynes@991
   575
#define XORB_r8_r8(r1,r2)            x86_encode_r32_rm32(0x30, r1, r2)
nkeynes@991
   576
#define XORL_imms_r32(imm,r1)        x86_encode_imms_rm32(0x83, 0x81, 6, imm, r1)
nkeynes@991
   577
#define XORL_imms_rbpdisp(imm,disp)  x86_encode_imms_rbpdisp32(0x83,0x81,6,imm,disp)
nkeynes@991
   578
#define XORL_r32_r32(r1,r2)          x86_encode_r32_rm32(0x31, r1, r2)
nkeynes@991
   579
#define XORL_r32_rbpdisp(r1,disp)    x86_encode_r32_rbpdisp32(0x31, r1, disp)
nkeynes@991
   580
#define XORL_rbpdisp_r32(disp,r1)    x86_encode_r32_rbpdisp32(0x33, r1, disp)
nkeynes@991
   581
#define XORQ_imms_r64(imm,r1)         x86_encode_imms_rm64(0x83, 0x81, 6, imm, r1)
nkeynes@991
   582
#define XORQ_r64_r64(r1,r2)           x86_encode_r64_rm64(0x31, r1, r2)
nkeynes@991
   583
nkeynes@991
   584
/* Control flow */
nkeynes@991
   585
#define CALL_rel(rel)                OP(0xE8); OP32(rel)
nkeynes@991
   586
#define CALL_imm32(ptr)              x86_encode_r32_mem32disp32(0xFF, 2, -1, ptr)
nkeynes@991
   587
#define CALL_r32(r1)                 x86_encode_r32_rm32(0xFF, 2, r1)
nkeynes@991
   588
#define CALL_r32disp(r1,disp)        x86_encode_r32_mem32disp32(0xFF, 2, r1, disp)
nkeynes@991
   589
nkeynes@991
   590
#define JCC_cc_rel8(cc,rel)          OP(0x70+(cc)); OP(rel)
nkeynes@991
   591
#define JCC_cc_rel32(cc,rel)         OP(0x0F); OP(0x80+(cc)); OP32(rel)
nkeynes@991
   592
#define JCC_cc_rel(cc,rel)           if( IS_INT8(rel) ) { JCC_cc_rel8(cc,(int8_t)rel); } else { JCC_cc_rel32(cc,rel); }
nkeynes@1112
   593
#define JCC_cc_prerel(cc,rel)        if( IS_INT8(rel) ) { JCC_cc_rel8(cc,(int8_t)((rel)-2)); } else { JCC_cc_rel32(cc,((rel)-6)); }
nkeynes@991
   594
nkeynes@991
   595
#define JMP_rel8(rel)                OP(0xEB); OP(rel)
nkeynes@991
   596
#define JMP_rel32(rel)               OP(0xE9); OP32(rel)
nkeynes@991
   597
#define JMP_rel(rel)                 if( IS_INT8(rel) ) { JMP_rel8((int8_t)rel); } else { JMP_rel32(rel); }
nkeynes@991
   598
#define JMP_prerel(rel)              if( IS_INT8(((int32_t)rel)-2) ) { JMP_rel8(((int8_t)rel)-2); } else { JMP_rel32(((int32_t)rel)-5); }
nkeynes@1112
   599
#define JMP_rptr(r1)                 x86_encode_r32_rm32(0xFF, 4, r1)
nkeynes@991
   600
#define JMP_r32disp(r1,disp)         x86_encode_r32_mem32disp32(0xFF, 4, r1, disp)
nkeynes@991
   601
#define RET()                        OP(0xC3)
nkeynes@991
   602
#define RET_imm(imm)                 OP(0xC2); OP16(imm)
nkeynes@991
   603
nkeynes@991
   604
nkeynes@991
   605
/* x87 Floating point instructions */
nkeynes@991
   606
#define FABS_st0()                   OP(0xD9); OP(0xE1)
nkeynes@991
   607
#define FADDP_st(st)                 OP(0xDE); OP(0xC0+(st))
nkeynes@991
   608
#define FCHS_st0()                   OP(0xD9); OP(0xE0)
nkeynes@991
   609
#define FCOMIP_st(st)                OP(0xDF); OP(0xF0+(st))
nkeynes@991
   610
#define FDIVP_st(st)                 OP(0xDE); OP(0xF8+(st))
nkeynes@991
   611
#define FILD_r32disp(r32, disp)      x86_encode_r32_mem32disp32(0xDB, 0, r32, disp)
nkeynes@991
   612
#define FLD0_st0()                   OP(0xD9); OP(0xEE);
nkeynes@991
   613
#define FLD1_st0()                   OP(0xD9); OP(0xE8);
nkeynes@991
   614
#define FLDCW_r32disp(r32, disp)     x86_encode_r32_mem32disp32(0xD9, 5, r32, disp)
nkeynes@991
   615
#define FMULP_st(st)                 OP(0xDE); OP(0xC8+(st))
nkeynes@991
   616
#define FNSTCW_r32disp(r32, disp)    x86_encode_r32_mem32disp32(0xD9, 7, r32, disp)
nkeynes@991
   617
#define FPOP_st()                    OP(0xDD); OP(0xC0); OP(0xD9); OP(0xF7)
nkeynes@991
   618
#define FSUBP_st(st)                 OP(0xDE); OP(0xE8+(st))
nkeynes@991
   619
#define FSQRT_st0()                  OP(0xD9); OP(0xFA)
nkeynes@991
   620
nkeynes@991
   621
#define FILD_rbpdisp(disp)           x86_encode_r32_rbpdisp32(0xDB, 0, disp)
nkeynes@991
   622
#define FLDF_rbpdisp(disp)           x86_encode_r32_rbpdisp32(0xD9, 0, disp)
nkeynes@991
   623
#define FLDD_rbpdisp(disp)           x86_encode_r32_rbpdisp32(0xDD, 0, disp)
nkeynes@991
   624
#define FISTP_rbpdisp(disp)          x86_encode_r32_rbpdisp32(0xDB, 3, disp)
nkeynes@991
   625
#define FSTPF_rbpdisp(disp)          x86_encode_r32_rbpdisp32(0xD9, 3, disp)
nkeynes@991
   626
#define FSTPD_rbpdisp(disp)          x86_encode_r32_rbpdisp32(0xDD, 3, disp)
nkeynes@991
   627
nkeynes@991
   628
nkeynes@991
   629
/* SSE Packed floating point instructions */
nkeynes@991
   630
#define ADDPS_rbpdisp_xmm(disp,r1)   x86_encode_r32_rbpdisp32(0x0F58, r1, disp)
nkeynes@991
   631
#define ADDPS_xmm_xmm(r1,r2)         x86_encode_r32_rm32(0x0F58, r2, r1)
nkeynes@991
   632
#define ANDPS_rbpdisp_xmm(disp,r1)   x86_encode_r32_rbpdisp32(0x0F54, r1, disp)
nkeynes@991
   633
#define ANDPS_xmm_xmm(r1,r2)         x86_encode_r32_rm32(0x0F54, r2, r1)
nkeynes@991
   634
#define ANDNPS_rbpdisp_xmm(disp,r1)  x86_encode_r32_rbpdisp32(0x0F55, r1, disp)
nkeynes@991
   635
#define ANDNPS_xmm_xmm(r1,r2)        x86_encode_r32_rm32(0x0F55, r2, r1)
nkeynes@991
   636
#define CMPPS_cc_rbpdisp_xmm(cc,d,r) x86_encode_r32_rbpdisp32(0x0FC2, r, d); OP(cc)
nkeynes@991
   637
#define CMPPS_cc_xmm_xmm(cc,r1,r2)   x86_encode_r32_rm32(0x0FC2, r2, r1); OP(cc)
nkeynes@991
   638
#define DIVPS_rbpdisp_xmm(disp,r1)   x86_encode_r32_rbpdisp32(0x0F5E, r1, disp)
nkeynes@991
   639
#define DIVPS_xmm_xmm(r1,r2)         x86_encode_r32_rm32(0x0F5E, r2, r1)
nkeynes@991
   640
#define MAXPS_rbpdisp_xmm(disp,r1)   x86_encode_r32_rbpdisp32(0x0F5F, r1, disp)
nkeynes@991
   641
#define MAXPS_xmm_xmm(r1,r2)         x86_encode_r32_rm32(0x0F5F, r2, r1)
nkeynes@991
   642
#define MINPS_rbpdisp_xmm(disp,r1)   x86_encode_r32_rbpdisp32(0x0F5D, r1, disp)
nkeynes@991
   643
#define MINPS_xmm_xmm(r1,r2)         x86_encode_r32_rm32(0x0F5D, r2, r1)
nkeynes@991
   644
#define MOV_xmm_xmm(r1,r2)           x86_encode_r32_rm32(0x0F28, r2, r1)
nkeynes@991
   645
#define MOVAPS_rbpdisp_xmm(disp,r1)  x86_encode_r32_rbpdisp32(0x0F28, r1, disp)
nkeynes@991
   646
#define MOVAPS_xmm_rbpdisp(r1,disp)  x86_encode_r32_rbpdisp32(0x0F29, r1, disp)
nkeynes@991
   647
#define MOVHLPS_xmm_xmm(r1,r2)       x86_encode_r32_rm32(0x0F12, r2, r1)
nkeynes@991
   648
#define MOVHPS_rbpdisp_xmm(disp,r1)  x86_encode_r32_rbpdisp32(0x0F16, r1, disp)
nkeynes@991
   649
#define MOVHPS_xmm_rbpdisp(r1,disp)  x86_encode_r32_rbpdisp32(0x0F17, r1, disp)
nkeynes@991
   650
#define MOVLHPS_xmm_xmm(r1,r2)       x86_encode_r32_rm32(0x0F16, r2, r1)
nkeynes@991
   651
#define MOVLPS_rbpdisp_xmm(disp,r1)  x86_encode_r32_rbpdisp32(0x0F12, r1, disp)
nkeynes@991
   652
#define MOVLPS_xmm_rbpdisp(r1,disp)  x86_encode_r32_rbpdisp32(0x0F13, r1, disp)
nkeynes@991
   653
#define MOVUPS_rbpdisp_xmm(disp,r1)  x86_encode_r32_rbpdisp32(0x0F10, r1, disp)
nkeynes@991
   654
#define MOVUPS_xmm_rbpdisp(disp,r1)  x86_encode_r32_rbpdisp32(0x0F11, r1, disp)
nkeynes@991
   655
#define MULPS_xmm_xmm(r1,r2)         x86_encode_r32_rm32(0x0F59, r2, r1)
nkeynes@991
   656
#define MULPS_rbpdisp_xmm(disp,r1)   x86_encode_r32_rbpdisp32(0xF59, r1, disp)
nkeynes@991
   657
#define ORPS_rbpdisp_xmm(disp,r1)    x86_encode_r32_rbpdisp32(0x0F56, r1, disp)
nkeynes@991
   658
#define ORPS_xmm_xmm(r1,r2)          x86_encode_r32_rm32(0x0F56, r2, r1)
nkeynes@991
   659
#define RCPPS_rbpdisp_xmm(disp,r1)   x86_encode_r32_rbpdisp32(0xF53, r1, disp)
nkeynes@991
   660
#define RCPPS_xmm_xmm(r1,r2)         x86_encode_r32_rm32(0x0F53, r2, r1)
nkeynes@991
   661
#define RSQRTPS_rbpdisp_xmm(disp,r1) x86_encode_r32_rbpdisp32(0x0F52, r1, disp)
nkeynes@991
   662
#define RSQRTPS_xmm_xmm(r1,r2)       x86_encode_r32_rm32(0x0F52, r2, r1)
nkeynes@991
   663
#define SHUFPS_rbpdisp_xmm(disp,r1)  x86_encode_r32_rbpdisp32(0x0FC6, r1, disp)
nkeynes@991
   664
#define SHUFPS_xmm_xmm(r1,r2)        x86_encode_r32_rm32(0x0FC6, r2, r1)
nkeynes@991
   665
#define SQRTPS_rbpdisp_xmm(disp,r1)  x86_encode_r32_rbpdisp32(0x0F51, r1, disp)
nkeynes@991
   666
#define SQRTPS_xmm_xmm(r1,r2)        x86_encode_r32_rm32(0x0F51, r2, r1)
nkeynes@991
   667
#define SUBPS_rbpdisp_xmm(disp,r1)   x86_encode_r32_rbpdisp32(0x0F5C, r1, disp)
nkeynes@991
   668
#define SUBPS_xmm_xmm(r1,r2)         x86_encode_r32_rm32(0x0F5C, r2, r1)
nkeynes@991
   669
#define UNPCKHPS_rbpdisp_xmm(dsp,r1) x86_encode_r32_rbpdisp32(0x0F15, r1, disp)
nkeynes@991
   670
#define UNPCKHPS_xmm_xmm(r1,r2)      x86_encode_r32_rm32(0x0F15, r2, r1)
nkeynes@991
   671
#define UNPCKLPS_rbpdisp_xmm(dsp,r1) x86_encode_r32_rbpdisp32(0x0F14, r1, disp)
nkeynes@991
   672
#define UNPCKLPS_xmm_xmm(r1,r2)      x86_encode_r32_rm32(0x0F14, r2, r1)
nkeynes@991
   673
#define XORPS_rbpdisp_xmm(disp,r1)   x86_encode_r32_rbpdisp32(0x0F57, r1, disp)
nkeynes@991
   674
#define XORPS_xmm_xmm(r1,r2)         x86_encode_r32_rm32(0x0F57, r2, r1)
nkeynes@991
   675
nkeynes@991
   676
/* SSE Scalar floating point instructions */
nkeynes@991
   677
#define ADDSS_rbpdisp_xmm(disp,r1)   OP(0xF3); x86_encode_r32_rbpdisp32(0x0F58, r1, disp)
nkeynes@991
   678
#define ADDSS_xmm_xmm(r1,r2)         OP(0xF3); x86_encode_r32_rm32(0x0F58, r2, r1)
nkeynes@991
   679
#define CMPSS_cc_rbpdisp_xmm(cc,d,r) OP(0xF3); x86_encode_r32_rbpdisp32(0x0FC2, r, d); OP(cc)
nkeynes@991
   680
#define CMPSS_cc_xmm_xmm(cc,r1,r2)   OP(0xF3); x86_encode_r32_rm32(0x0FC2, r2, r1); OP(cc)
nkeynes@991
   681
#define COMISS_rbpdisp_xmm(disp,r1)  x86_encode_r32_rbpdisp32(0x0F2F, r1, disp)
nkeynes@991
   682
#define COMISS_xmm_xmm(r1,r2)        x86_encode_r32_rm32(0x0F2F, r2, r1)
nkeynes@991
   683
#define DIVSS_rbpdisp_xmm(disp,r1)   OP(0xF3); x86_encode_r32_rbpdisp32(0x0F5E, r1, disp)
nkeynes@991
   684
#define DIVSS_xmm_xmm(r1,r2)         OP(0xF3); x86_encode_r32_rm32(0x0F5E, r2, r1)
nkeynes@991
   685
#define MAXSS_rbpdisp_xmm(disp,r1)   OP(0xF3); x86_encode_r32_rbpdisp32(0x0F5F, r1, disp)
nkeynes@991
   686
#define MAXSS_xmm_xmm(r1,r2)         OP(0xF3); x86_encode_r32_rm32(0x0F5F, r2, r1)
nkeynes@991
   687
#define MINSS_rbpdisp_xmm(disp,r1)   OP(0xF3); x86_encode_r32_rbpdisp32(0x0F5D, r1, disp)
nkeynes@991
   688
#define MINSS_xmm_xmm(r1,r2)         OP(0xF3); x86_encode_r32_rm32(0x0F5D, r2, r1)
nkeynes@991
   689
#define MOVSS_rbpdisp_xmm(disp,r1)   OP(0xF3); x86_encode_r32_rbpdisp32(0x0F10, r1, disp)
nkeynes@991
   690
#define MOVSS_xmm_rbpdisp(r1,disp)   OP(0xF3); x86_encode_r32_rbpdisp32(0x0F11, r1, disp)
nkeynes@991
   691
#define MOVSS_xmm_xmm(r1,r2)         OP(0xF3); x86_encode_r32_rm32(0x0F10, r2, r1)
nkeynes@991
   692
#define MULSS_rbpdisp_xmm(disp,r1)   OP(0xF3); x86_encode_r32_rbpdisp32(0xF59, r1, disp)
nkeynes@991
   693
#define MULSS_xmm_xmm(r1,r2)         OP(0xF3); x86_encode_r32_rm32(0x0F59, r2, r1)
nkeynes@991
   694
#define RCPSS_rbpdisp_xmm(disp,r1)   OP(0xF3); x86_encode_r32_rbpdisp32(0xF53, r1, disp)
nkeynes@991
   695
#define RCPSS_xmm_xmm(r1,r2)         OP(0xF3); x86_encode_r32_rm32(0x0F53, r2, r1)
nkeynes@991
   696
#define RSQRTSS_rbpdisp_xmm(disp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F52, r1, disp)
nkeynes@991
   697
#define RSQRTSS_xmm_xmm(r1,r2)       OP(0xF3); x86_encode_r32_rm32(0x0F52, r2, r1)
nkeynes@991
   698
#define SQRTSS_rbpdisp_xmm(disp,r1)  OP(0xF3); x86_encode_r32_rbpdisp32(0x0F51, r1, disp)
nkeynes@991
   699
#define SQRTSS_xmm_xmm(r1,r2)        OP(0xF3); x86_encode_r32_rm32(0x0F51, r2, r1)
nkeynes@991
   700
#define SUBSS_rbpdisp_xmm(disp,r1)   OP(0xF3); x86_encode_r32_rbpdisp32(0x0F5C, r1, disp)
nkeynes@991
   701
#define SUBSS_xmm_xmm(r1,r2)         OP(0xF3); x86_encode_r32_rm32(0x0F5C, r2, r1)
nkeynes@991
   702
#define UCOMISS_rbpdisp_xmm(dsp,r1)  x86_encode_r32_rbpdisp32(0x0F2E, r1, dsp)
nkeynes@991
   703
#define UCOMISS_xmm_xmm(r1,r2)       x86_encode_r32_rm32(0x0F2E, r2, r1)
nkeynes@991
   704
nkeynes@991
   705
/* SSE2 Packed floating point instructions */
nkeynes@991
   706
#define ADDPD_rbpdisp_xmm(disp,r1)   OP(0x66); x86_encode_r32_rbpdisp32(0x0F58, r1, disp)
nkeynes@991
   707
#define ADDPD_xmm_xmm(r1,r2)         OP(0x66); x86_encode_r32_rm32(0x0F58, r2, r1)
nkeynes@991
   708
#define ANDPD_rbpdisp_xmm(disp,r1)   OP(0x66); x86_encode_r32_rbpdisp32(0x0F54, r1, disp)
nkeynes@991
   709
#define ANDPD_xmm_xmm(r1,r2)         OP(0x66); x86_encode_r32_rm32(0x0F54, r2, r1)
nkeynes@991
   710
#define ANDNPD_rbpdisp_xmm(disp,r1)  OP(0x66); x86_encode_r32_rbpdisp32(0x0F55, r1, disp)
nkeynes@991
   711
#define ANDNPD_xmm_xmm(r1,r2)        OP(0x66); x86_encode_r32_rm32(0x0F55, r2, r1)
nkeynes@991
   712
#define CMPPD_cc_rbpdisp_xmm(cc,d,r) OP(0x66); x86_encode_r32_rbpdisp32(0x0FC2, r, d); OP(cc)
nkeynes@991
   713
#define CMPPD_cc_xmm_xmm(cc,r1,r2)   OP(0x66); x86_encode_r32_rm32(0x0FC2, r2, r1); OP(cc)
nkeynes@991
   714
#define CVTPD2PS_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F5A, r1, disp)
nkeynes@991
   715
#define CVTPD2PS_xmm_xmm(r1,r2)      OP(0x66); x86_encode_r32_rm32(0x0F5A, r2, r1)
nkeynes@991
   716
#define CVTPS2PD_rbpdisp_xmm(dsp,r1) x86_encode_r32_rbpdisp32(0x0F5A, r1, disp)
nkeynes@991
   717
#define CVTPS2PD_xmm_xmm(r1,r2)      x86_encode_r32_rm32(0x0F5A, r2, r1)
nkeynes@991
   718
#define DIVPD_rbpdisp_xmm(disp,r1)   OP(0x66); x86_encode_r32_rbpdisp32(0x0F5E, r1, disp)
nkeynes@991
   719
#define DIVPD_xmm_xmm(r1,r2)         OP(0x66); x86_encode_r32_rm32(0x0F5E, r2, r1)
nkeynes@991
   720
#define MAXPD_rbpdisp_xmm(disp,r1)   OP(0x66); x86_encode_r32_rbpdisp32(0x0F5F, r1, disp)
nkeynes@991
   721
#define MAXPD_xmm_xmm(r1,r2)         OP(0x66); x86_encode_r32_rm32(0x0F5F, r2, r1)
nkeynes@991
   722
#define MINPD_rbpdisp_xmm(disp,r1)   OP(0x66); x86_encode_r32_rbpdisp32(0x0F5D, r1, disp)
nkeynes@991
   723
#define MINPD_xmm_xmm(r1,r2)         OP(0x66); x86_encode_r32_rm32(0x0F5D, r2, r1)
nkeynes@991
   724
#define MOVHPD_rbpdisp_xmm(disp,r1)  OP(0x66); x86_encode_r32_rbpdisp32(0x0F16, r1, disp)
nkeynes@991
   725
#define MOVHPD_xmm_rbpdisp(r1,disp)  OP(0x66); x86_encode_r32_rbpdisp32(0x0F17, r1, disp)
nkeynes@991
   726
#define MOVLPD_rbpdisp_xmm(disp,r1)  OP(0x66); x86_encode_r32_rbpdisp32(0x0F12, r1, disp)
nkeynes@991
   727
#define MOVLPD_xmm_rbpdisp(r1,disp)  OP(0x66); x86_encode_r32_rbpdisp32(0x0F13, r1, disp)
nkeynes@991
   728
#define MULPD_rbpdisp_xmm(disp,r1)   OP(0x66); x86_encode_r32_rbpdisp32(0xF59, r1, disp)
nkeynes@991
   729
#define MULPD_xmm_xmm(r1,r2)         OP(0x66); x86_encode_r32_rm32(0x0F59, r2, r1)
nkeynes@991
   730
#define ORPD_rbpdisp_xmm(disp,r1)    OP(0x66); x86_encode_r32_rbpdisp32(0x0F56, r1, disp)
nkeynes@991
   731
#define ORPD_xmm_xmm(r1,r2)          OP(0x66); x86_encode_r32_rm32(0x0F56, r2, r1)
nkeynes@991
   732
#define SHUFPD_rbpdisp_xmm(disp,r1)  OP(0x66); x86_encode_r32_rbpdisp32(0x0FC6, r1, disp)
nkeynes@991
   733
#define SHUFPD_xmm_xmm(r1,r2)        OP(0x66); x86_encode_r32_rm32(0x0FC6, r2, r1)
nkeynes@991
   734
#define SUBPD_rbpdisp_xmm(disp,r1)   OP(0x66); x86_encode_r32_rbpdisp32(0x0F5C, r1, disp)
nkeynes@991
   735
#define SUBPD_xmm_xmm(r1,r2)         OP(0x66); x86_encode_r32_rm32(0x0F5C, r2, r1)
nkeynes@991
   736
#define UNPCKHPD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F15, r1, disp)
nkeynes@991
   737
#define UNPCKHPD_xmm_xmm(r1,r2)      OP(0x66); x86_encode_r32_rm32(0x0F15, r2, r1)
nkeynes@991
   738
#define UNPCKLPD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0F14, r1, disp)
nkeynes@991
   739
#define UNPCKLPD_xmm_xmm(r1,r2)      OP(0x66); x86_encode_r32_rm32(0x0F14, r2, r1)
nkeynes@991
   740
#define XORPD_rbpdisp_xmm(disp,r1)   OP(0x66); x86_encode_r32_rbpdisp32(0x0F57, r1, disp)
nkeynes@991
   741
#define XORPD_xmm_xmm(r1,r2)         OP(0x66); x86_encode_r32_rm32(0x0F57, r2, r1)
nkeynes@991
   742
nkeynes@991
   743
nkeynes@991
   744
/* SSE2 Scalar floating point instructions */
nkeynes@991
   745
#define ADDSD_rbpdisp_xmm(disp,r1)   OP(0xF2); x86_encode_r32_rbpdisp32(0x0F58, r1, disp)
nkeynes@991
   746
#define ADDSD_xmm_xmm(r1,r2)         OP(0xF2); x86_encode_r32_rm32(0x0F58, r2, r1)
nkeynes@991
   747
#define CMPSD_cc_rbpdisp_xmm(cc,d,r) OP(0xF2); x86_encode_r32_rbpdisp32(0x0FC2, r, d); OP(cc)
nkeynes@991
   748
#define CMPSD_cc_xmm_xmm(cc,r1,r2)   OP(0xF2); x86_encode_r32_rm32(0x0FC2, r2, r1); OP(cc)
nkeynes@991
   749
#define COMISD_rbpdisp_xmm(disp,r1)  OP(0x66); x86_encode_r32_rbpdisp32(0x0F2F, r1, disp)
nkeynes@991
   750
#define COMISD_xmm_xmm(r1,r2)        OP(0x66); x86_encode_r32_rm32(0x0F2F, r2, r1)
nkeynes@991
   751
#define DIVSD_rbpdisp_xmm(disp,r1)   OP(0xF2); x86_encode_r32_rbpdisp32(0x0F5E, r1, disp)
nkeynes@991
   752
#define DIVSD_xmm_xmm(r1,r2)         OP(0xF2); x86_encode_r32_rm32(0x0F5E, r2, r1)
nkeynes@991
   753
#define MAXSD_rbpdisp_xmm(disp,r1)   OP(0xF2); x86_encode_r32_rbpdisp32(0x0F5F, r1, disp)
nkeynes@991
   754
#define MAXSD_xmm_xmm(r1,r2)         OP(0xF2); x86_encode_r32_rm32(0x0F5F, r2, r1)
nkeynes@991
   755
#define MINSD_rbpdisp_xmm(disp,r1)   OP(0xF2); x86_encode_r32_rbpdisp32(0x0F5D, r1, disp)
nkeynes@991
   756
#define MINSD_xmm_xmm(r1,r2)         OP(0xF2); x86_encode_r32_rm32(0x0F5D, r2, r1)
nkeynes@991
   757
#define MOVSD_rbpdisp_xmm(disp,r1)   OP(0xF2); x86_encode_r32_rbpdisp32(0x0F10, r1, disp)
nkeynes@991
   758
#define MOVSD_xmm_rbpdisp(r1,disp)   OP(0xF2); x86_encode_r32_rbpdisp32(0x0F11, r1, disp)
nkeynes@991
   759
#define MOVSD_xmm_xmm(r1,r2)         OP(0xF2); x86_encode_r32_rm32(0x0F10, r2, r1)
nkeynes@991
   760
#define MULSD_rbpdisp_xmm(disp,r1)   OP(0xF2); x86_encode_r32_rbpdisp32(0xF59, r1, disp)
nkeynes@991
   761
#define MULSD_xmm_xmm(r1,r2)         OP(0xF2); x86_encode_r32_rm32(0x0F59, r2, r1)
nkeynes@991
   762
#define SQRTSD_rbpdisp_xmm(disp,r1)  OP(0xF2); x86_encode_r32_rbpdisp32(0x0F51, r1, disp)
nkeynes@991
   763
#define SQRTSD_xmm_xmm(r1,r2)        OP(0xF2); x86_encode_r32_rm32(0x0F51, r2, r1)
nkeynes@991
   764
#define SUBSD_rbpdisp_xmm(disp,r1)   OP(0xF2); x86_encode_r32_rbpdisp32(0x0F5C, r1, disp)
nkeynes@991
   765
#define SUBSD_xmm_xmm(r1,r2)         OP(0xF2); x86_encode_r32_rm32(0x0F5C, r2, r1)
nkeynes@991
   766
#define UCOMISD_rbpdisp_xmm(dsp,r1)  OP(0x66); x86_encode_r32_rbpdisp32(0x0F2E, r1, dsp)
nkeynes@991
   767
#define UCOMISD_xmm_xmm(r1,r2)       OP(0x66); x86_encode_r32_rm32(0x0F2E, r2, r1)
nkeynes@991
   768
nkeynes@991
   769
/* SSE3 floating point instructions */
nkeynes@991
   770
#define ADDSUBPD_rbpdisp_xmm(dsp,r1) OP(0x66); x86_encode_r32_rbpdisp32(0x0FD0, r1, dsp)
nkeynes@991
   771
#define ADDSUBPD_xmm_xmm(r1,r2)      OP(0x66); x86_encode_r32_rm32(0x0FD0, r2, r1)
nkeynes@991
   772
#define ADDSUBPS_rbpdisp_xmm(dsp,r1) OP(0xF2); x86_encode_r32_rbpdisp32(0x0FD0, r1, dsp)
nkeynes@991
   773
#define ADDSUBPS_xmm_xmm(r1,r2)      OP(0xF2); x86_encode_r32_rm32(0x0FD0, r2, r1)
nkeynes@991
   774
#define HADDPD_rbpdisp_xmm(dsp,r1)   OP(0x66); x86_encode_r32_rbpdisp32(0x0F7C, r1, dsp)
nkeynes@991
   775
#define HADDPD_xmm_xmm(r1,r2)        OP(0x66); x86_encode_r32_rm32(0x0F7C, r2, r1)
nkeynes@991
   776
#define HADDPS_rbpdisp_xmm(dsp,r1)   OP(0xF2); x86_encode_r32_rbpdisp32(0x0F7C, r1, dsp)
nkeynes@991
   777
#define HADDPS_xmm_xmm(r1,r2)        OP(0xF2); x86_encode_r32_rm32(0x0F7C, r2, r1)
nkeynes@991
   778
#define HSUBPD_rbpdisp_xmm(dsp,r1)   OP(0x66); x86_encode_r32_rbpdisp32(0x0F7D, r1, dsp)
nkeynes@991
   779
#define HSUBPD_xmm_xmm(r1,r2)        OP(0x66); x86_encode_r32_rm32(0x0F7D, r2, r1)
nkeynes@991
   780
#define HSUBPS_rbpdisp_xmm(dsp,r1)   OP(0xF2); x86_encode_r32_rbpdisp32(0x0F7D, r1, dsp)
nkeynes@991
   781
#define HSUBPS_xmm_xmm(r1,r2)        OP(0xF2); x86_encode_r32_rm32(0x0F7D, r2, r1)
nkeynes@991
   782
#define MOVSHDUP_rbpdisp_xmm(dsp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F16, r1, dsp)
nkeynes@991
   783
#define MOVSHDUP_xmm_xmm(r1,r2)      OP(0xF3); x86_encode_r32_rm32(0x0F16, r2, r1)
nkeynes@991
   784
#define MOVSLDUP_rbpdisp_xmm(dsp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F12, r1, dsp)
nkeynes@991
   785
#define MOVSLDUP_xmm_xmm(r1,r2)      OP(0xF3); x86_encode_r32_rm32(0x0F12, r2, r1)
nkeynes@995
   786
nkeynes@995
   787
/************************ Import calling conventions *************************/
nkeynes@995
   788
#if SIZEOF_VOID_P == 8
nkeynes@995
   789
#include "xlat/x86/amd64abi.h"
nkeynes@995
   790
#else /* 32-bit system */
nkeynes@995
   791
#include "xlat/x86/ia32abi.h"
nkeynes@995
   792
#endif
nkeynes@995
   793
nkeynes@995
   794
#endif /* !lxdream_x86op_H */
.