| Index: src/trusted/validator/x86/ncval_seg_sfi/generator/ncdecode_table.c
|
| diff --git a/src/trusted/validator/x86/ncval_seg_sfi/generator/ncdecode_table.c b/src/trusted/validator/x86/ncval_seg_sfi/generator/ncdecode_table.c
|
| deleted file mode 100644
|
| index 1742bad60d88c1bba384d2e16dcf5b39d2278f06..0000000000000000000000000000000000000000
|
| --- a/src/trusted/validator/x86/ncval_seg_sfi/generator/ncdecode_table.c
|
| +++ /dev/null
|
| @@ -1,2877 +0,0 @@
|
| -/* Copyright (c) 2011 The Native Client Authors. All rights reserved.
|
| - * Use of this source code is governed by a BSD-style license that can be
|
| - * found in the LICENSE file.
|
| - */
|
| -
|
| -/*
|
| - * ncdecode_intable.h - table driven decoder for Native Client.
|
| - *
|
| - * This program generates C source for the ncdecode.c decoder tables.
|
| - * It writes two C .h file to standard out, one for decoding and one
|
| - * for disassembly, that contain six decoder tables.
|
| - *
|
| - * Note: Most of the organization of this document is based on the
|
| - * Opcode Map appendix of one of the following documents:
|
| -
|
| - * (1) "Intel 64 and IA-32 Architectures
|
| - * Software Developer's Manual (volume 2b, document 253665.pdf)".
|
| - *
|
| - * (2) "Intel 80386 Reference Programmer's Manual" (document
|
| - * http://pdos.csail.mit.edu/6.828/2004/readings/i386/toc.htm).
|
| - */
|
| -
|
| -
|
| -#ifndef NACL_TRUSTED_BUT_NOT_TCB
|
| -#error("This file is not meant for use in the TCB")
|
| -#endif
|
| -
|
| -#include "native_client/src/include/portability.h"
|
| -#include "native_client/src/include/portability_io.h"
|
| -#include <stdlib.h>
|
| -#include <stdio.h>
|
| -#include <string.h>
|
| -#include <assert.h>
|
| -#include "native_client/src/trusted/validator/x86/ncval_seg_sfi/ncdecode.h"
|
| -
|
| -typedef uint8_t bool; /* zero or non-zero */
|
| -#define TRUE 1
|
| -#define FALSE 0
|
| -
|
| -#define TODO(who, what)
|
| -
|
| -/* Possible run modes for instructions. */
|
| -typedef enum {
|
| - X86_32, /* Model x86-32 bit instructions. */
|
| - X86_64, /* Model x86-64-bit instructions. */
|
| - RunModeSize /* Special end of list marker, denoting the number
|
| - * of run modes;
|
| - */
|
| -} RunMode;
|
| -
|
| -/* Returns the print name of the given run mode. */
|
| -static const char* RunModeName(RunMode mode) {
|
| - switch (mode) {
|
| - case X86_32: return "x86-32 bit mode";
|
| - case X86_64: return "x86-64 bit mode";
|
| - default: assert(0);
|
| - }
|
| -
|
| - /* NOTREACHED */
|
| - return NULL;
|
| -}
|
| -
|
| -/* Defines the run mode files that should be generated. */
|
| -static RunMode FLAGS_run_mode = RunModeSize;
|
| -
|
| -/* Generate names for DecodeOpsKind values. */
|
| -static const char* DecodeOpsKindName(DecodeOpsKind kind) {
|
| - switch (kind) {
|
| - case DECODE_OPS_DEFAULT_64: return "DECODE_OPS_DEFAULT_64";
|
| - case DECODE_OPS_DEFAULT_32: return "DECODE_OPS_DEFAULT_32";
|
| - case DECODE_OPS_FORCE_64: return "DECODE_OPS_FORCE_64";
|
| - default: assert(0);
|
| - }
|
| -
|
| - /* NOTREACHED */
|
| - return NULL;
|
| -}
|
| -
|
| -/* For handling prefixes we consume the prefix byte and then
|
| - * record the state in this record. Note: In general, we define two versions
|
| - * of each instruction - 0 for X86_32 and 1 for X86_64.
|
| - */
|
| -typedef struct OpMetaInfo {
|
| - const char* disfmt; /* as a short string, for printing */
|
| - NaClInstType insttype;
|
| - bool mrmbyte; /* 0 or 1 */
|
| - uint8_t immtype; /* IMM_UNKNOWN .. IMM_DEFAULT_4 */
|
| - uint8_t opinmrm; /* 0 .. 8 */
|
| -} OpMetaInfo;
|
| -
|
| -/* The decoder input table is an array of instruction definitions, */
|
| -/* defined using OpMetaInfo as defined in ncdecode.h */
|
| -
|
| -/* one byte opcode tables */
|
| -OpMetaInfo* g_Op1ByteTable[NCDTABLESIZE];
|
| -
|
| -/* Defines encodings of prefix bytes. */
|
| -const char* g_PrefixTable[NCDTABLESIZE];
|
| -
|
| -/* two byte opcode tables */
|
| -/* byte prefixed with byte OF */
|
| -OpMetaInfo* g_Op0FXXMetaTable[NCDTABLESIZE];
|
| -/* byte prefixed with bytes F2 OF */
|
| -OpMetaInfo* g_OpF20FXXTable[NCDTABLESIZE];
|
| -/* byte prefixed with bytes F3 OF */
|
| -OpMetaInfo* g_OpF30FXXTable[NCDTABLESIZE];
|
| -/* byte prefixed with bytes 66 OF */
|
| -OpMetaInfo* g_Op660FXXTable[NCDTABLESIZE];
|
| -
|
| -/* three byte opcode tables */
|
| -/* byte prefixed with bytes 0F 0F */
|
| -OpMetaInfo* g_Op0F0FTable[NCDTABLESIZE];
|
| -/* byte prefixed with bytes 0F 38 */
|
| -OpMetaInfo* g_Op0F38Table[NCDTABLESIZE];
|
| -/* byte prefixed with bytes 66 0F 38 */
|
| -OpMetaInfo* g_Op660F38Table[NCDTABLESIZE];
|
| -/* byte prefixed with bytes F2 OF 38 */
|
| -OpMetaInfo* g_OpF20F38Table[NCDTABLESIZE];
|
| -/* byte prefixed with bytes 0F 3A */
|
| -OpMetaInfo* g_Op0F3ATable[NCDTABLESIZE];
|
| -/* byte prefixed with bytes 66 oF 3A */
|
| -OpMetaInfo* g_Op660F3ATable[NCDTABLESIZE];
|
| -/* tables for opcodes in ModRM */
|
| -OpMetaInfo* g_ModRMOpTable[kNaClMRMGroupsRange][kModRMOpcodeGroupSize];
|
| -/* x87 opcode tables */
|
| -OpMetaInfo* g_Op87D8[NCDTABLESIZE];
|
| -OpMetaInfo* g_Op87D9[NCDTABLESIZE];
|
| -OpMetaInfo* g_Op87DA[NCDTABLESIZE];
|
| -OpMetaInfo* g_Op87DB[NCDTABLESIZE];
|
| -OpMetaInfo* g_Op87DC[NCDTABLESIZE];
|
| -OpMetaInfo* g_Op87DD[NCDTABLESIZE];
|
| -OpMetaInfo* g_Op87DE[NCDTABLESIZE];
|
| -OpMetaInfo* g_Op87DF[NCDTABLESIZE];
|
| -
|
| -/* Define the stategy to decode operands for a one byte instruction,
|
| - when running in 64-bit mode.
|
| - */
|
| -DecodeOpsKind g_OpDecodeOpsKind[NCDTABLESIZE];
|
| -
|
| -
|
| -/* Operand size associated with byte (when prefixed with byte 0F)
|
| - * when in 64 bit mode.
|
| - */
|
| -DecodeOpsKind g_Op0FDecodeOpsKind[NCDTABLESIZE];
|
| -
|
| -/* Defines operand size of MRM opcode extensions for a group,
|
| - * when in 64 bit mode.
|
| - */
|
| -DecodeOpsKind
|
| - g_ModRMOpDecodeOpsKind[kNaClMRMGroupsRange][kModRMOpcodeGroupSize];
|
| -
|
| -/* Model an undefined instruction. */
|
| -static OpMetaInfo DecodeUndefinedInstInfo = {
|
| - "undefined", NACLi_UNDEFINED, 0, IMM_NONE, 0
|
| -};
|
| -
|
| -/* Note: in general all errors in this module will be fatal.
|
| - * To debug: use gdb or your favorite debugger.
|
| - */
|
| -static void fatal(const char* s) {
|
| - fprintf(stderr, "%s\n", s);
|
| - fprintf(stderr, "fatal error, cannot recover\n");
|
| - exit(-1);
|
| -}
|
| -
|
| -/* note that this function accepts only one string in s */
|
| -static char* aprintf(const char* fmt, const char* s) {
|
| - char *rstring = NULL;
|
| - /* there will be one spare byte, because %s is replaced, but it's ok */
|
| - size_t length = strlen(fmt) + strlen(s);
|
| - rstring = malloc(length);
|
| - if (rstring != NULL) {
|
| - SNPRINTF(rstring, length, fmt, s);
|
| - } else {
|
| - fprintf(stderr, "In aprintf (%s, %s):\n", fmt, s);
|
| - fatal("malloc failed");
|
| - }
|
| - return rstring;
|
| -}
|
| -
|
| -/* operandsize == 0 implies operand size determined by operand size attributes
|
| - * opbytes: length of opcode, one or two bytes
|
| - * mrmbyte: 0 or 1, 1 if mrmbyte is present
|
| - * immbytes: bytes of immediate: 1, 2, 4
|
| - * itype: decoder treatment, an NaClInstType as in ncdecode.h
|
| - * disfmt: format string for disassembly
|
| - */
|
| -static OpMetaInfo* NewMetaDefn(
|
| - const bool mrmbyte, const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - OpMetaInfo *imd = (OpMetaInfo *)malloc(sizeof(*imd));
|
| - if (imd == NULL) {
|
| - fatal("NewMetaDefn: malloc failed");
|
| - }
|
| - imd->insttype = itype;
|
| - imd->disfmt = disfmt;
|
| - imd->mrmbyte = mrmbyte;
|
| - imd->immtype = immtype;
|
| - imd->opinmrm = 0;
|
| - return imd;
|
| -}
|
| -
|
| -/* The names of 32-bit general purpose registers. */
|
| -#define NUM_GP_X86_32_REGS 8
|
| -static const char* gp_x86_32_regs[NUM_GP_X86_32_REGS] = {
|
| - "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"
|
| -};
|
| -
|
| -/* The corresponding names for general purpose registers
|
| - * when generating x86-64.
|
| - */
|
| -static const char* corresp_gp_x86_64_regs[] = {
|
| - "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi"
|
| -};
|
| -
|
| -/* Converts the format string, written for x86-32, converted to the given
|
| - * run mode.
|
| - */
|
| -static const char* ModedGenRegs(const char* format, RunMode mode) {
|
| - switch (mode) {
|
| - case X86_32:
|
| - return format;
|
| - case X86_64: {
|
| - /* Note: Assumes that the character size of the corresponding x86-64
|
| - * bit general registers have the same size as the x86-32 bit
|
| - * counterparts.
|
| - */
|
| - char* rformat = strdup(format);
|
| - if (rformat != NULL) {
|
| - int i;
|
| - char* substr = rformat;
|
| - for (i = 0; i < NUM_GP_X86_32_REGS; ++i) {
|
| - size_t name_size = strlen(gp_x86_32_regs[i]);
|
| - char* loc;
|
| - assert(name_size == strlen(corresp_gp_x86_64_regs[i]));
|
| - loc = strstr(substr, gp_x86_32_regs[i]);
|
| - while (loc != NULL) {
|
| - memcpy(loc, corresp_gp_x86_64_regs[i], name_size);
|
| - loc = strstr(loc + name_size, gp_x86_32_regs[i]);
|
| - }
|
| - }
|
| - } else {
|
| - fprintf(stderr, "In ModedGenRegs(%s, %s):\n",
|
| - format, RunModeName(mode));
|
| - fatal("strdup failed");
|
| - }
|
| - return rformat;
|
| - }
|
| - default:
|
| - assert(0);
|
| - }
|
| - /* NOTREACHED */
|
| - return NULL;
|
| -}
|
| -
|
| -/* Define the encoding for a one byte opcode, for the given run mode. */
|
| -static void EncodeModedOp(
|
| - const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - g_Op1ByteTable[byte] = NewMetaDefn(mrmbyte, immtype, itype, disfmt);
|
| - }
|
| -}
|
| -
|
| -/* Define the encoding for a one byte opcode, for all run modes. */
|
| -static void EncodeOp(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedOp(byte, mrmbyte, immtype, itype, disfmt, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Define the prefix name for the given opcode, for the given run mode. */
|
| -static void EncodeModedPrefixName(const uint8_t byte, const char* name,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - g_PrefixTable[byte] = name;
|
| - }
|
| -}
|
| -
|
| -/* Define the prefix name for the given opcode, for all run modes. */
|
| -static void EncodePrefixName(const uint8_t byte, const char* name) {
|
| - EncodeModedPrefixName(byte, name, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Define the encoding for a one byte opcode, for all run modes, fixing
|
| - * the names of general purpose registers to match the run mode.
|
| - */
|
| -static void EncodeOpRegs(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedOp(byte, mrmbyte, immtype, itype,
|
| - ModedGenRegs(disfmt, FLAGS_run_mode), FLAGS_run_mode);
|
| -}
|
| -
|
| -static void UpdateDecodeOpsKind(
|
| - const char* fn_name,
|
| - DecodeOpsKind* gtbl,
|
| - uint8_t byte,
|
| - DecodeOpsKind new_kind) {
|
| - DecodeOpsKind was_kind = gtbl[byte];
|
| - if (was_kind != new_kind && was_kind != DECODE_OPS_DEFAULT_32) {
|
| - printf("*ERROR*: Incompatable update to %s[%02x] from %s to %s\n",
|
| - fn_name, byte, DecodeOpsKindName(was_kind),
|
| - DecodeOpsKindName(new_kind));
|
| - }
|
| - gtbl[byte] = new_kind;
|
| -}
|
| -
|
| -/* Mark one byte opcode to define instruction that defaults to a 64-bit operand
|
| - * size and can't encode 32 bit operand size, when run in 64-bit mode.
|
| - */
|
| -static void SetOpDefaultSize64(const uint8_t byte) {
|
| - UpdateDecodeOpsKind("SetOpDefaultSize64",
|
| - g_OpDecodeOpsKind,
|
| - byte,
|
| - DECODE_OPS_DEFAULT_64);
|
| -}
|
| -
|
| -/* Mark one byte opcode to define instructions whose operand size must be
|
| - * 64-bit, when run in 64-bit mode. (prefixes that change operand size are
|
| - * ignored for the instruction when in 64-bit mode).
|
| - */
|
| -static void SetOpForceSize64(const uint8_t byte) {
|
| - UpdateDecodeOpsKind("SetOpForceSize64",
|
| - g_OpDecodeOpsKind,
|
| - byte,
|
| - DECODE_OPS_FORCE_64);
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * byte OF), for the given run mode.
|
| - */
|
| -static void EncodeModedOp0F(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - g_Op0FXXMetaTable[byte] = NewMetaDefn(mrmbyte, immtype, itype, disfmt);
|
| - }
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with with
|
| - * byte 0F), for all run modes.
|
| - */
|
| -static void EncodeOp0F(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedOp0F(byte, mrmbyte, immtype, itype, disfmt, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Mark byte opcode (when the byte is prefixed with byte 0F) to define
|
| - * instructions that defaults to a 64-bit operand sizse and can't encode 32
|
| - * bit operand size, when run in 64-bit mode.
|
| - */
|
| -static void SetOp0FDefaultSize64(const uint8_t byte) {
|
| - UpdateDecodeOpsKind("SetOp0FDefaultSize64",
|
| - g_Op0FDecodeOpsKind,
|
| - byte,
|
| - DECODE_OPS_DEFAULT_64);
|
| -}
|
| -
|
| -/* Mark byte opcode (when the byte is prefixed with byte 0F) to define
|
| - * instructions whose operand size must be 64-bit, when run in 64-bit mode.
|
| - * (prefixes that change operand size are ignored for the instruction when
|
| - * in 64-bit mode).
|
| - */
|
| -static void SetOp0FForceSize64(const uint8_t byte) {
|
| - UpdateDecodeOpsKind("SetOp0FForceSize64",
|
| - g_Op0FDecodeOpsKind,
|
| - byte,
|
| - DECODE_OPS_FORCE_64);
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes 66 0F), for the given run mode.
|
| - */
|
| -static void EncodeModedOp660F(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - g_Op660FXXTable[byte] = NewMetaDefn(mrmbyte, immtype, itype, disfmt);
|
| - }
|
| -}
|
| -
|
| -/* Define the encodintg for a byte opcode (when the byte is prefixed with
|
| - * bytes 66 0F), for all run modes.
|
| - */
|
| -static void EncodeOp660F(const uint8_t byte2, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedOp660F(byte2, mrmbyte, immtype, itype, disfmt, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes F2 0F), for the given run mode.
|
| - */
|
| -static void EncodeModedOpF20F(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - g_OpF20FXXTable[byte] = NewMetaDefn(mrmbyte, immtype, itype, disfmt);
|
| - }
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes F2 OF), for all run modes.
|
| - */
|
| -static void EncodeOpF20F(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedOpF20F(byte, mrmbyte, immtype, itype, disfmt, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes F3 0F), for the given run mode.
|
| - */
|
| -static void EncodeModedOpF30F(const uint8_t byte2, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - g_OpF30FXXTable[byte2] = NewMetaDefn(mrmbyte, immtype, itype, disfmt);
|
| - }
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes F3 OF), for all run modes.
|
| - */
|
| -static void EncodeOpF30F(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedOpF30F(byte, mrmbyte, immtype, itype, disfmt, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes 0F 0F), for the given run mode.
|
| - */
|
| -static void EncodeModedOp0F0F(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - g_Op0F0FTable[byte] = NewMetaDefn(mrmbyte, immtype, itype, disfmt);
|
| - }
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes 0F 0F), for all run modes.
|
| - */
|
| -static void EncodeOp0F0F(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedOp0F0F(byte, mrmbyte, immtype, itype, disfmt, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes 0F 38), for the given run mode.
|
| - */
|
| -static void EncodeModedOp0F38(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - g_Op0F38Table[byte] = NewMetaDefn(mrmbyte, immtype, itype, disfmt);
|
| - }
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes 0F 38), for all run modes.
|
| - */
|
| -static void EncodeOp0F38(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedOp0F38(byte, mrmbyte, immtype, itype, disfmt, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Defines the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes 66 0F 38), for the given run mode.
|
| - */
|
| -static void EncodeModedOp660F38(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - g_Op660F38Table[byte] = NewMetaDefn(mrmbyte, immtype, itype, disfmt);
|
| - }
|
| -}
|
| -
|
| -/* Defines the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes 66 0F 38), for all run modes.
|
| - */
|
| -static void EncodeOp660F38(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedOp660F38(byte, mrmbyte, immtype, itype, disfmt, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Defines the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes F2 0F 38), for the given run mode.
|
| - */
|
| -static void EncodeModedOpF20F38(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - g_OpF20F38Table[byte] = NewMetaDefn(mrmbyte, immtype, itype, disfmt);
|
| - }
|
| -}
|
| -
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes F2 0F 38), for all run modes.
|
| - */
|
| -static void EncodeOpF20F38(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedOpF20F38(byte, mrmbyte, immtype, itype, disfmt, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes 0F 3A), for the given run mode.
|
| - */
|
| -static void EncodeModedOp0F3A(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - g_Op0F3ATable[byte] = NewMetaDefn(mrmbyte, immtype, itype, disfmt);
|
| - }
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes 0F 3A), for all run modes.
|
| - */
|
| -static void EncodeOp0F3A(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedOp0F3A(byte, mrmbyte, immtype, itype, disfmt, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes 66 0F 3A), for the given run mode.
|
| - */
|
| -static void EncodeModedOp660F3A(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - g_Op660F3ATable[byte] = NewMetaDefn(mrmbyte, immtype, itype, disfmt);
|
| - }
|
| -}
|
| -
|
| -/* Define the encoding for a byte opcode (when the byte is prefixed with
|
| - * bytes 66 0F 3A), for all run modes.
|
| - */
|
| -static void EncodeOp660F3A(const uint8_t byte, const bool mrmbyte,
|
| - const uint8_t immtype,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedOp660F3A(byte, mrmbyte, immtype, itype, disfmt, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Define the encoding of opcodes in the nnn field (bits 3-5) of the ModR/M
|
| - * byte, for the given instruction group, for the given run mode.
|
| - */
|
| -static void EncodeModedModRMOp(const uint8_t group, const uint8_t nnn,
|
| - const NaClInstType itype, const char* disfmt,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - OpMetaInfo *idefn = NewMetaDefn(1, IMM_NONE, itype, disfmt);
|
| - g_ModRMOpTable[group][nnn] = idefn;
|
| - }
|
| -}
|
| -
|
| -/* Define the encoding of opcodes in the nnn field (bits 3-5) of the ModR/M
|
| - * byte, for the given instruction group, for all run modes.
|
| - */
|
| -static void EncodeModRMOp(const uint8_t group, const uint8_t nnn,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedModRMOp(group, nnn, itype, disfmt, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Define the encoding of opcodes in the nnn field (bits 3-5) of the ModR/M
|
| - * byte, for the given instruction group, for all run modes, fixing the
|
| - * names of general purpose registers to match the run mode.
|
| - */
|
| -static void EncodeModRMOpRegs(const uint8_t group, const uint8_t nnn,
|
| - const NaClInstType itype, const char* disfmt) {
|
| - EncodeModedModRMOp(group, nnn, itype,
|
| - ModedGenRegs(disfmt, FLAGS_run_mode), FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Mark MRM opcode extension to define instructions that defauilts to a 64-bit
|
| - * operand size and can't encode 32 bit operand size, when in 64-bit mode.
|
| - */
|
| -static void SetModRMOpDefaultSize64(
|
| - const uint8_t group, const uint8_t nnn) {
|
| - UpdateDecodeOpsKind("SetModRMOpDefaultSize64",
|
| - g_ModRMOpDecodeOpsKind[group],
|
| - nnn,
|
| - DECODE_OPS_DEFAULT_64);
|
| -}
|
| -
|
| -/* Mark MRM opcode extension to define instructions whose operand size must be
|
| - * 64-bit, when in 64-bit mode. (prefixes that change operand size are ignored
|
| - * for the instruction when in 64-bit mode).
|
| - */
|
| -static void SetModRMOpForceSize64(
|
| - const uint8_t group, const uint8_t nnn) {
|
| - UpdateDecodeOpsKind("SetModRMOpDefaultSize64",
|
| - g_ModRMOpDecodeOpsKind[group],
|
| - nnn,
|
| - DECODE_OPS_FORCE_64);
|
| -}
|
| -
|
| -/* Associate a group to use to determine the opcode extensions to use for a
|
| - * one byte opcode, for the given run mode. The extensions are defined by the
|
| - * nnn field (bits 3-5) of the ModR/M byte.
|
| - */
|
| -static void SetModedOpOpInMRM(const uint8_t byte, const uint8_t group,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - assert(g_Op1ByteTable[byte] != &DecodeUndefinedInstInfo);
|
| - g_Op1ByteTable[byte]->opinmrm = group;
|
| - }
|
| -}
|
| -
|
| -/* Associate a group to use to determine the Opcode extensions to use for a
|
| - * one byte opcode, for all run modes. The extensions are defined by the
|
| - * nnn field (bits 3-5) of the ModR/M byte.
|
| - */
|
| -static void SetOpOpInMRM(const uint8_t byte, const uint8_t group) {
|
| - SetModedOpOpInMRM(byte, group, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Associate a group to use to determine the opcode extensions to use for a
|
| - * byte opcode (when the byte is prefixed with byte 0F), for the given run mode.
|
| - * The extensions are defined by the nnn field (bits 3-5) of the ModR/M byte.
|
| - */
|
| -static void SetModedOp0FOpInMRM(const uint8_t byte, const uint8_t group,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - assert(g_Op0FXXMetaTable[byte] != &DecodeUndefinedInstInfo);
|
| - g_Op0FXXMetaTable[byte]->opinmrm = group;
|
| - }
|
| -}
|
| -
|
| -/* Associate a group to use to determine the opcode extensions to use for a
|
| - * byte opcode (when the byte is prefixed with byte 0F), for all run modes.
|
| - * The extensions are defined by the nnn field (bits 3-5) of the ModR/M byte.
|
| - */
|
| -static void SetOp0FOpInMRM(const uint8_t byte, const uint8_t group) {
|
| - SetModedOp0FOpInMRM(byte, group, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Associate a group to use to determine the opcode extensions to use for
|
| - * a byte opcode (when the byte is prefixed by byte 66), for the given run mode.
|
| - * The extensions are defined by the nnn field (bits 3-5) of the ModR/M byte.
|
| - */
|
| -static void SetModedOp66OpInMRM(const uint8_t byte, const uint8_t group,
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - assert(g_Op660FXXTable[byte] != &DecodeUndefinedInstInfo);
|
| - g_Op660FXXTable[byte]->opinmrm = group;
|
| - }
|
| -}
|
| -
|
| -/* Associate a group to use to determine the opcode extensions to use for
|
| - * a byte opcode (when the byte is prefixed by byte 66), for all run modes.
|
| - * The extensions are defined by the nnn field (bits 3-5) of the ModR/M byte.
|
| - */
|
| -static void SetOp66OpInMRM(const uint8_t byte, const uint8_t group) {
|
| - SetModedOp66OpInMRM(byte, group, FLAGS_run_mode);
|
| -}
|
| -
|
| -/* Define ALU operand variants (6) starting at the given byte base. */
|
| -static void ALUOperandVariants00_05(const uint8_t base,
|
| - const NaClInstType itype,
|
| - const char* ocstr) {
|
| - EncodeOp(base, 1, IMM_NONE, itype, aprintf("%s $Eb, $Gb", ocstr));
|
| - EncodeOp(base+1, 1, IMM_NONE, itype, aprintf("%s $Ev, $Gv", ocstr));
|
| - EncodeOp(base+2, 1, IMM_NONE, itype, aprintf("%s $Gb, $Eb", ocstr));
|
| - EncodeOp(base+3, 1, IMM_NONE, itype, aprintf("%s $Gv, $Ev", ocstr));
|
| - EncodeOp(base+4, 0, IMM_FIXED1, itype, aprintf("%s %%al, $Ib", ocstr));
|
| - EncodeOpRegs(base+5, 0, IMM_DATAV, itype, aprintf("%s %%eax, $Iz", ocstr));
|
| -}
|
| -
|
| -/* Define the One register variants (8) starting at the given byte base. */
|
| -static void OneRegVariants00_07(const uint8_t base,
|
| - const NaClInstType itype,
|
| - const char* ocstr,
|
| - bool has_mode_64) {
|
| - int i;
|
| - for (i = 0; i < NUM_GP_X86_32_REGS; ++i) {
|
| - char* regname_format = aprintf("%%s %%%s", gp_x86_32_regs[i]);
|
| - char* format = aprintf(regname_format, ocstr);
|
| - free(regname_format);
|
| - EncodeModedOp(base+i, 0, IMM_NONE, itype, format, X86_32);
|
| - if (has_mode_64) {
|
| - char* regname_format = aprintf("%%s %%%s", corresp_gp_x86_64_regs[i]);
|
| - char* format = aprintf(regname_format, ocstr);
|
| - free(regname_format);
|
| - EncodeModedOp(base+i, 0, IMM_NONE, itype, format, X86_64);
|
| - SetOpDefaultSize64(base+i);
|
| - } else {
|
| - /* Rex prefix marker */
|
| - EncodeModedOp(base+i, 0, IMM_NONE, NACLi_ILLEGAL, "[rex]", X86_64);
|
| - EncodeModedPrefixName(base+i, "kPrefixREX", X86_64);
|
| - }
|
| - }
|
| -}
|
| -
|
| -/* TODO(gregoryd) - this function generates an error since it is not used */
|
| -#if 0
|
| -static char* asmprint(char** asmstr, const char* opcode,
|
| - const char* reg, const char* dest) {
|
| - /* Note: add 20, just to be safe, in case the format string gets changed. */
|
| - int asmstr_length = strlen(opcode) + strlen(reg) + strlen(dest) + 20;
|
| - *asmstr = (char*) malloc(asmstr_length);
|
| - if (asmstr == NULL) {
|
| - fatal("unable to malloc in asmprint");
|
| - }
|
| - SNPRINTF(asm_str, "%s %s, %s", opcode, reg, dest);
|
| - return *asmstr;
|
| -}
|
| -#endif
|
| -
|
| -static void InitializeGlobalTables(void) {
|
| - int i, j;
|
| - /* pre-initialize g_Op1ByteTable */
|
| - for (i = 0; i < NCDTABLESIZE; i++) {
|
| - g_Op1ByteTable[i] = &DecodeUndefinedInstInfo;
|
| - g_PrefixTable[i] = "0";
|
| - g_Op0FXXMetaTable[i] = &DecodeUndefinedInstInfo;
|
| - g_Op0F38Table[i] = &DecodeUndefinedInstInfo;
|
| - g_Op660FXXTable[i] = &DecodeUndefinedInstInfo;
|
| - g_OpF30FXXTable[i] = &DecodeUndefinedInstInfo;
|
| - g_Op0F0FTable[i] = &DecodeUndefinedInstInfo;
|
| - g_OpF20FXXTable[i] = &DecodeUndefinedInstInfo;
|
| - g_Op660F38Table[i] = &DecodeUndefinedInstInfo;
|
| - g_OpF20F38Table[i] = &DecodeUndefinedInstInfo;
|
| - g_Op0F3ATable[i] = &DecodeUndefinedInstInfo;
|
| - g_Op660F3ATable[i] = &DecodeUndefinedInstInfo;
|
| - g_Op87D8[i] = &DecodeUndefinedInstInfo;
|
| - g_Op87D9[i] = &DecodeUndefinedInstInfo;
|
| - g_Op87DA[i] = &DecodeUndefinedInstInfo;
|
| - g_Op87DB[i] = &DecodeUndefinedInstInfo;
|
| - g_Op87DC[i] = &DecodeUndefinedInstInfo;
|
| - g_Op87DD[i] = &DecodeUndefinedInstInfo;
|
| - g_Op87DE[i] = &DecodeUndefinedInstInfo;
|
| - g_Op87DF[i] = &DecodeUndefinedInstInfo;
|
| - g_OpDecodeOpsKind[i] = DECODE_OPS_DEFAULT_32;
|
| - g_Op0FDecodeOpsKind[i] = DECODE_OPS_DEFAULT_32;
|
| - }
|
| - for (i = 0; i < kNaClMRMGroupsRange; i++) {
|
| - for (j = 0; j < kModRMOpcodeGroupSize; j++) {
|
| - g_ModRMOpTable[i][j] = &DecodeUndefinedInstInfo;
|
| - g_ModRMOpDecodeOpsKind[i][j] = DECODE_OPS_DEFAULT_32;
|
| - }
|
| - }
|
| -}
|
| -
|
| -/* Create default x87 operations for the given run mode. */
|
| -static void EncodeModed87Op(OpMetaInfo* g87tab[NCDTABLESIZE],
|
| - const char* set1[8],
|
| - const char* set2[64],
|
| - const RunMode mode) {
|
| - if (FLAGS_run_mode == mode) {
|
| - int j, reg;
|
| - uint8_t i;
|
| -
|
| - for (i = 0; i < 0xc0; i++) {
|
| - reg = modrm_reg(i);
|
| - if (set1[reg] == NULL) {
|
| - g87tab[i] = NewMetaDefn(1, IMM_NONE, NACLi_INVALID, "invalid");
|
| - } else {
|
| - g87tab[i] = NewMetaDefn(1, IMM_NONE, NACLi_X87, set1[reg]);
|
| - }
|
| - }
|
| - for (j = 0xc0; j < 0x100; j++) {
|
| - if (set2[j - 0xc0] == NULL) {
|
| - g87tab[j] = NewMetaDefn(1, IMM_NONE, NACLi_INVALID, "invalid");
|
| - } else if (strcmp("fsincos", set2[j - 0xc0]) == 0) {
|
| - g87tab[j] = NewMetaDefn(1, IMM_NONE, NACLi_X87_FSINCOS,
|
| - set2[j - 0xc0]);
|
| - } else {
|
| - g87tab[j] = NewMetaDefn(1, IMM_NONE, NACLi_X87, set2[j - 0xc0]);
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -/* Create default x87 operations for all run modes. */
|
| -static void Encode87Op(OpMetaInfo* g87tab[NCDTABLESIZE],
|
| - const char* set1[8],
|
| - const char* set2[64]) {
|
| - EncodeModed87Op(g87tab, set1, set2, FLAGS_run_mode);
|
| -}
|
| -
|
| -static void BuildSSE4Tables(void) {
|
| - TODO(brad, "extend hcf to check three byte instructions");
|
| - EncodeOp660F(0x38, 1, IMM_NONE, NACLi_3BYTE, "SSE4");
|
| - EncodeOp660F(0x3A, 1, IMM_FIXED1, NACLi_3BYTE, "SSE4");
|
| - EncodeOpF20F(0x38, 0, IMM_NONE, NACLi_3BYTE, "SSE4");
|
| -
|
| - EncodeOp660F38(0x00, 1, IMM_NONE, NACLi_SSSE3, "pshufb $V, $W");
|
| - EncodeOp660F38(0x01, 1, IMM_NONE, NACLi_SSSE3, "phaddw $V, $W");
|
| - EncodeOp660F38(0x02, 1, IMM_NONE, NACLi_SSSE3, "phaddd $V, $W");
|
| - EncodeOp660F38(0x03, 1, IMM_NONE, NACLi_SSSE3, "phaddsw $V, $W");
|
| - EncodeOp660F38(0x04, 1, IMM_NONE, NACLi_SSSE3, "pmaddubsw $V, $W");
|
| - EncodeOp660F38(0x05, 1, IMM_NONE, NACLi_SSSE3, "phsubw $V, $W");
|
| - EncodeOp660F38(0x06, 1, IMM_NONE, NACLi_SSSE3, "phsubd $V, $W");
|
| - EncodeOp660F38(0x07, 1, IMM_NONE, NACLi_SSSE3, "phsubsw $V, $W");
|
| -
|
| - EncodeOp660F38(0x10, 1, IMM_NONE, NACLi_SSE41, "pblendvb $V, $W");
|
| - EncodeOp660F38(0x14, 1, IMM_NONE, NACLi_SSE41, "blendvps $V, $W");
|
| - EncodeOp660F38(0x15, 1, IMM_NONE, NACLi_SSE41, "blendvpd $V, $W");
|
| - EncodeOp660F38(0x17, 1, IMM_NONE, NACLi_SSE41, "ptest $V, $W");
|
| -
|
| - EncodeOp660F38(0x20, 1, IMM_NONE, NACLi_SSE41, "pmovsxbw $V, $U/M");
|
| - EncodeOp660F38(0x21, 1, IMM_NONE, NACLi_SSE41, "pmovsxbd $V, $U/M");
|
| - EncodeOp660F38(0x22, 1, IMM_NONE, NACLi_SSE41, "pmovsxbq $V, $U/M");
|
| - EncodeOp660F38(0x23, 1, IMM_NONE, NACLi_SSE41, "pmovsxwd $V, $U/M");
|
| - EncodeOp660F38(0x24, 1, IMM_NONE, NACLi_SSE41, "pmovsxwq $V, $U/M");
|
| - EncodeOp660F38(0x25, 1, IMM_NONE, NACLi_SSE41, "pmovsxdq $V, $U/M");
|
| -
|
| - EncodeOp660F38(0x30, 1, IMM_NONE, NACLi_SSE41, "pmovzxbw $V, $U/M");
|
| - EncodeOp660F38(0x31, 1, IMM_NONE, NACLi_SSE41, "pmovzxbd $V, $U/M");
|
| - EncodeOp660F38(0x32, 1, IMM_NONE, NACLi_SSE41, "pmovzxbq $V, $U/M");
|
| - EncodeOp660F38(0x33, 1, IMM_NONE, NACLi_SSE41, "pmovzxwd $V, $U/M");
|
| - EncodeOp660F38(0x34, 1, IMM_NONE, NACLi_SSE41, "pmovzxwq $V, $U/M");
|
| - EncodeOp660F38(0x35, 1, IMM_NONE, NACLi_SSE41, "pmovzxdq $V, $U/M");
|
| - EncodeOp660F38(0x37, 1, IMM_NONE, NACLi_SSE42, "pcmpgtq $V, $U/M");
|
| -
|
| - EncodeOp660F38(0x40, 1, IMM_NONE, NACLi_SSE41, "pmulld $V, $W");
|
| - EncodeOp660F38(0x41, 1, IMM_NONE, NACLi_SSE41, "phminposuw $V, $W");
|
| -
|
| - EncodeOp660F38(0x80, 1, IMM_NONE, NACLi_INVALID, "NVEPT $G, $M");
|
| - EncodeOp660F38(0x81, 1, IMM_NONE, NACLi_INVALID, "NVVPID $G, $M");
|
| -
|
| - EncodeOp0F38(0xf0, 1, IMM_NONE, NACLi_MOVBE, "MOVBE $G, $M");
|
| - EncodeOp0F38(0xf1, 1, IMM_NONE, NACLi_MOVBE, "MOVBE $M, $G");
|
| - EncodeOpF20F38(0xf0, 1, IMM_NONE, NACLi_SSE42, "CRC32 $Gd, $Eb");
|
| - EncodeOpF20F38(0xf1, 1, IMM_NONE, NACLi_SSE42, "CRC32 $Gd, $Ev");
|
| -
|
| - EncodeOp660F38(0x08, 1, IMM_NONE, NACLi_SSSE3, "psignb $V, $W");
|
| - EncodeOp660F38(0x09, 1, IMM_NONE, NACLi_SSSE3, "psignw $V, $W");
|
| - EncodeOp660F38(0x0a, 1, IMM_NONE, NACLi_SSSE3, "psignd $V, $W");
|
| - EncodeOp660F38(0x0b, 1, IMM_NONE, NACLi_SSSE3, "pmulhrsw $V, $W");
|
| -
|
| - EncodeOp660F38(0x1c, 1, IMM_NONE, NACLi_SSSE3, "pabsb $V, $W");
|
| - EncodeOp660F38(0x1d, 1, IMM_NONE, NACLi_SSSE3, "pabsw $V, $W");
|
| - EncodeOp660F38(0x1e, 1, IMM_NONE, NACLi_SSSE3, "pabsd $V, $W");
|
| -
|
| - EncodeOp660F38(0x28, 1, IMM_NONE, NACLi_SSE41, "pmuldq $V, $W");
|
| - EncodeOp660F38(0x29, 1, IMM_NONE, NACLi_SSE41, "pcmpeqq $V, $W");
|
| - EncodeOp660F38(0x2a, 1, IMM_NONE, NACLi_SSE41, "movntdqa $V, $W");
|
| - EncodeOp660F38(0x2b, 1, IMM_NONE, NACLi_SSE41, "packusdw $V, $W");
|
| -
|
| - EncodeOp660F38(0x38, 1, IMM_NONE, NACLi_SSE41, "pminsb $V, $W");
|
| - EncodeOp660F38(0x39, 1, IMM_NONE, NACLi_SSE41, "pminsd $V, $W");
|
| - EncodeOp660F38(0x3a, 1, IMM_NONE, NACLi_SSE41, "pminuw $V, $W");
|
| - EncodeOp660F38(0x3b, 1, IMM_NONE, NACLi_SSE41, "pminud $V, $W");
|
| - EncodeOp660F38(0x3c, 1, IMM_NONE, NACLi_SSE41, "pmaxsb $V, $W");
|
| - EncodeOp660F38(0x3d, 1, IMM_NONE, NACLi_SSE41, "pmaxsd $V, $W");
|
| - EncodeOp660F38(0x3e, 1, IMM_NONE, NACLi_SSE41, "pmaxuw $V, $W");
|
| - EncodeOp660F38(0x3f, 1, IMM_NONE, NACLi_SSE41, "pmaxud $V, $W");
|
| -
|
| - EncodeOp660F3A(0x14, 1, IMM_FIXED1, NACLi_SSE41, "pextrb $R/M, $V, $Ib");
|
| - EncodeOp660F3A(0x15, 1, IMM_FIXED1, NACLi_SSE41, "pextrw $R/M, $V, $Ib");
|
| - EncodeOp660F3A(0x16, 1, IMM_FIXED1, NACLi_SSE41, "pextrd/q $E, $V, $Ib");
|
| - EncodeOp660F3A(0x17, 1, IMM_FIXED1, NACLi_SSE41, "extractps $E, $V, $Ib");
|
| -
|
| - EncodeOp660F3A(0x20, 1, IMM_FIXED1, NACLi_SSE41, "pinsrb $V, $R/M, $Ib");
|
| - EncodeOp660F3A(0x21, 1, IMM_FIXED1, NACLi_SSE41, "insertps $V, $U/M, $Ib");
|
| - EncodeOp660F3A(0x22, 1, IMM_FIXED1, NACLi_SSE41, "pinsrd/q $V, $E, $Ib");
|
| -
|
| - EncodeOp660F3A(0x40, 1, IMM_FIXED1, NACLi_SSE41, "dpps $V, $W, $Ib");
|
| - EncodeOp660F3A(0x41, 1, IMM_FIXED1, NACLi_SSE41, "dppd $V, $W, $Ib");
|
| - EncodeOp660F3A(0x42, 1, IMM_FIXED1, NACLi_SSE41, "mpsadbw $V, $W, $Ib");
|
| -
|
| - EncodeOp660F3A(0x60, 1, IMM_FIXED1, NACLi_SSE42, "pcmpestrm $V, $W, $Ib");
|
| - EncodeOp660F3A(0x61, 1, IMM_FIXED1, NACLi_SSE42, "pcmpestri $V, $W, $Ib");
|
| - EncodeOp660F3A(0x62, 1, IMM_FIXED1, NACLi_SSE42, "pcmpistrm $V, $W, $Ib");
|
| - EncodeOp660F3A(0x63, 1, IMM_FIXED1, NACLi_SSE42, "pcmpistri $V, $W, $Ib");
|
| -
|
| - EncodeOp660F3A(0x08, 1, IMM_FIXED1, NACLi_SSE41, "roundps $V, $W, $Ib");
|
| - EncodeOp660F3A(0x09, 1, IMM_FIXED1, NACLi_SSE41, "roundpd $V, $W, $Ib");
|
| - EncodeOp660F3A(0x0a, 1, IMM_FIXED1, NACLi_SSE41, "roundss $V, $W, $Ib");
|
| - EncodeOp660F3A(0x0b, 1, IMM_FIXED1, NACLi_SSE41, "roundsd $V, $W, $Ib");
|
| - EncodeOp660F3A(0x0c, 1, IMM_FIXED1, NACLi_SSE41, "blendps $V, $W, $Ib");
|
| - EncodeOp660F3A(0x0d, 1, IMM_FIXED1, NACLi_SSE41, "blendpd $V, $W, $Ib");
|
| - EncodeOp660F3A(0x0e, 1, IMM_FIXED1, NACLi_SSE41, "pblendw $V, $W, $Ib");
|
| - EncodeOp660F3A(0x0f, 1, IMM_FIXED1, NACLi_SSSE3, "palignr $V, $W, $Ib");
|
| -}
|
| -
|
| -static void Buildx87Tables(void) {
|
| - int i;
|
| - /* since these are so repetative I'm using a little bit of a hack */
|
| - /* to make this more concise. */
|
| - static const char* k87D8Table1[8] =
|
| - {"fadd", "fmul", "fcom", "fcomp", "fsub", "fsubr", "fdiv", "fdivr"};
|
| - static const char* k87D8Table2[64] = {
|
| - "fadd", "fadd", "fadd", "fadd", "fadd", "fadd", "fadd", "fadd",
|
| - "fmul", "fmul", "fmul", "fmul", "fmul", "fmul", "fmul", "fmul",
|
| - "fcom", "fcom", "fcom", "fcom", "fcom", "fcom", "fcom", "fcom",
|
| - "fcomp", "fcomp", "fcomp", "fcomp", "fcomp", "fcomp", "fcomp", "fcomp",
|
| - "fsub", "fsub", "fsub", "fsub", "fsub", "fsub", "fsub", "fsub",
|
| - "fsubr", "fsubr", "fsubr", "fsubr", "fsubr", "fsubr", "fsubr", "fsubr",
|
| - "fdiv", "fdiv", "fdiv", "fdiv", "fdiv", "fdiv", "fdiv", "fdiv",
|
| - "fdivr", "fdivr", "fdivr", "fdivr", "fdivr", "fdivr", "fdivr", "fdivr"};
|
| -
|
| - static const char* k87D9Table1[8] =
|
| - {"fld", NULL, "fst", "fstp", "fldenv", "fldcw", "fnstenv", "fnstcw"};
|
| - static const char* k87D9Table2[64] = {
|
| - "fld", "fld", "fld", "fld", "fld", "fld", "fld", "fld",
|
| - "fxch", "fxch", "fxch", "fxch", "fxch", "fxch", "fxch", "fxch",
|
| - "fnop", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - "fchs", "fabs", NULL, NULL, "ftst", "fxam", NULL, NULL,
|
| - "fld1", "fldl2t", "fldl2e", "fldpi", "fldlg2", "fldln2", "fldz", NULL,
|
| - "f2xm1", "fyl2x", "fptan", "fpatan",
|
| - "fxtract", "fprem1", "fdecstp", "fincstp",
|
| - "fprem", "fyl2xp1", "fsqrt", "fsincos",
|
| - "frndint", "fscale", "fsin", "fcos" };
|
| -
|
| - static const char* k87DATable1[8] =
|
| - {"fiadd", "fimul", "ficom", "ficomp", "fisub", "fisubr", "fidiv", "fidivr"};
|
| - static const char* k87DATable2[64] = {
|
| - "fcmovb", "fcmovb", "fcmovb", "fcmovb",
|
| - "fcmovb", "fcmovb", "fcmovb", "fcmovb",
|
| - "fcmove", "fcmove", "fcmove", "fcmove",
|
| - "fcmove", "fcmove", "fcmove", "fcmove",
|
| - "fcmovbe", "fcmovbe", "fcmovbe", "fcmovbe",
|
| - "fcmovbe", "fcmovbe", "fcmovbe", "fcmovbe",
|
| - "fcmovu", "fcmovu", "fcmovu", "fcmovu",
|
| - "fcmovu", "fcmovu", "fcmovu", "fcmovu",
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - NULL, "fucompp", NULL, NULL, NULL, NULL, NULL, NULL,
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
| -
|
| - static const char* k87DBTable1[8] =
|
| - {"fild", "fisttp", "fist", "fistp", NULL, "fld", NULL, "fstp"};
|
| - static const char* k87DBTable2[64] = {
|
| - "fcmovnb", "fcmovnb", "fcmovnb", "fcmovnb",
|
| - "fcmovnb", "fcmovnb", "fcmovnb", "fcmovnb",
|
| - "fcmovne", "fcmovne", "fcmovne", "fcmovne",
|
| - "fcmovne", "fcmovne", "fcmovne", "fcmovne",
|
| - "fcmovnbe", "fcmovnbe", "fcmovnbe", "fcmovnbe",
|
| - "fcmovnbe", "fcmovnbe", "fcmovnbe", "fcmovnbe",
|
| - "fcmovnu", "fcmovnu", "fcmovnu", "fcmovnu",
|
| - "fcmovnu", "fcmovnu", "fcmovnu", "fcmovnu",
|
| - NULL, NULL, "fnclex", "fninit", NULL, NULL, NULL, NULL,
|
| - "fucomi", "fucomi", "fucomi", "fucomi",
|
| - "fucomi", "fucomi", "fucomi", "fucomi",
|
| - "fcomi", "fcomi", "fcomi", "fcomi",
|
| - "fcomi", "fcomi", "fcomi", "fcomi",
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
| -
|
| - static const char* k87DCTable1[8] =
|
| - {"fadd", "fmul", "fcom", "fcomp", "fsub", "fsubr", "fdiv", "fdivr"};
|
| - static const char* k87DCTable2[64] = {
|
| - "fadd", "fadd", "fadd", "fadd", "fadd", "fadd", "fadd", "fadd",
|
| - "fmul", "fmul", "fmul", "fmul", "fmul", "fmul", "fmul", "fmul",
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - "fsubr", "fsubr", "fsubr", "fsubr", "fsubr", "fsubr", "fsubr", "fsubr",
|
| - "fsub", "fsub", "fsub", "fsub", "fsub", "fsub", "fsub", "fsub",
|
| - "fdivr", "fdivr", "fdivr", "fdivr", "fdivr", "fdivr", "fdivr", "fdivr",
|
| - "fdiv", "fdiv", "fdiv", "fdiv", "fdiv", "fdiv", "fdiv", "fdiv" };
|
| -
|
| - static const char* k87DDTable1[8] =
|
| - {"fld", "fisttp", "fst", "fstp", "frstor", NULL, "fnsave", "fnstsw"};
|
| - static const char* k87DDTable2[64] = {
|
| - "ffree", "ffree", "ffree", "ffree", "ffree", "ffree", "ffree", "ffree",
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - "fst", "fst", "fst", "fst", "fst", "fst", "fst", "fst",
|
| - "fstp", "fstp", "fstp", "fstp", "fstp", "fstp", "fstp", "fstp",
|
| - "fucom", "fucom", "fucom", "fucom", "fucom", "fucom", "fucom", "fucom",
|
| - "fucomp", "fucomp", "fucomp", "fucomp",
|
| - "fucomp", "fucomp", "fucomp", "fucomp",
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
| -
|
| - static const char* k87DETable1[8] =
|
| - {"fiadd", "fimul", "ficom", "ficomp", "fisub", "fisubr", "fidiv", "fidivr"};
|
| - static const char* k87DETable2[64] = {
|
| - "faddp", "faddp", "faddp", "faddp", "faddp", "faddp", "faddp", "faddp",
|
| - "fmulp", "fmulp", "fmulp", "fmulp", "fmulp", "fmulp", "fmulp", "fmulp",
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - NULL, "fcompp", NULL, NULL, NULL, NULL, NULL, NULL,
|
| - "fsubrp", "fsubrp", "fsubrp", "fsubrp",
|
| - "fsubrp", "fsubrp", "fsubrp", "fsubrp",
|
| - "fsubp", "fsubp", "fsubp", "fsubp",
|
| - "fsubp", "fsubp", "fsubp", "fsubp",
|
| - "fdivrp", "fdivrp", "fdivrp", "fdivrp",
|
| - "fdivrp", "fdivrp", "fdivrp", "fdivrp",
|
| - "fdivp", "fdivp", "fdivp", "fdivp",
|
| - "fdivp", "fdivp", "fdivp", "fdivp"};
|
| -
|
| - static const char* k87DFTable1[8] =
|
| - {"fild", "fisttp", "fist", "fistp", "fbld", "fild", "fbstp", "fistp"};
|
| - static const char* k87DFTable2[64] = {
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - "fnstsw", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - "fucomip", "fucomip", "fucomip", "fucomip",
|
| - "fucomip", "fucomip", "fucomip", "fucomip",
|
| - "fcomip", "fcomip", "fcomip", "fcomip",
|
| - "fcomip", "fcomip", "fcomip", "fcomip",
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
| -
|
| - Encode87Op(g_Op87D8, k87D8Table1, k87D8Table2);
|
| - Encode87Op(g_Op87D9, k87D9Table1, k87D9Table2);
|
| - Encode87Op(g_Op87DA, k87DATable1, k87DATable2);
|
| - Encode87Op(g_Op87DB, k87DBTable1, k87DBTable2);
|
| - Encode87Op(g_Op87DC, k87DCTable1, k87DCTable2);
|
| - Encode87Op(g_Op87DD, k87DDTable1, k87DDTable2);
|
| - Encode87Op(g_Op87DE, k87DETable1, k87DETable2);
|
| - Encode87Op(g_Op87DF, k87DFTable1, k87DFTable2);
|
| - /* fix instruction type for x87 conditional moves */
|
| - for (i = 0; i < 8; i++) {
|
| - g_Op87DA[0xc0 + i]->insttype = NACLi_FCMOV;
|
| - g_Op87DA[0xc8 + i]->insttype = NACLi_FCMOV;
|
| - g_Op87DA[0xd0 + i]->insttype = NACLi_FCMOV;
|
| - g_Op87DA[0xd8 + i]->insttype = NACLi_FCMOV;
|
| - g_Op87DB[0xc0 + i]->insttype = NACLi_FCMOV;
|
| - g_Op87DB[0xc8 + i]->insttype = NACLi_FCMOV;
|
| - g_Op87DB[0xd0 + i]->insttype = NACLi_FCMOV;
|
| - g_Op87DB[0xd8 + i]->insttype = NACLi_FCMOV;
|
| - }
|
| -}
|
| -
|
| -/* The root of all matching nop trie nodes. These
|
| - * nodes are specific encodings that the decoder
|
| - * will recognize as a NOP, if the corresponding
|
| - * sequence of bytes occur.
|
| - */
|
| -static NCNopTrieNode* nc_nop_root = NULL;
|
| -
|
| -static struct OpInfo nc_nop_info = { NACLi_NOP , 0 , IMM_NONE , 0 };
|
| -
|
| -/* Simple (fast hack) routine to extract a byte value from a character string.
|
| - */
|
| -static int NCExtractByte(const char* sequence, int index) {
|
| - char buffer[3];
|
| - int i;
|
| - for (i = 0; i < 2; ++i) {
|
| - char ch = sequence[index + i];
|
| - if ('\0' == ch) {
|
| - fatal(aprintf(
|
| - "Odd number of characters in opcode sequence: '%s'\n",
|
| - sequence));
|
| - }
|
| - buffer[i] = ch;
|
| - }
|
| - buffer[2] = '\0';
|
| - return strtoul(buffer, NULL, 16);
|
| -}
|
| -
|
| -/* Define the given sequence of (hex) bytes as a nop instruction with
|
| - * the given nop_info.
|
| - */
|
| -static void NCDefNopLikeOp(const char* sequence, struct OpInfo* nop_info) {
|
| - NCNopTrieNode** next = &nc_nop_root;
|
| - NCNopTrieNode* last = NULL;
|
| - int i = 0;
|
| - while (sequence[i]) {
|
| - int byte = NCExtractByte(sequence, i);
|
| - if (*next == NULL) {
|
| - /* Create node and advance. */
|
| - *next = (NCNopTrieNode*) malloc(sizeof(NCNopTrieNode));
|
| - (*next)->matching_byte = byte;
|
| - (*next)->matching_opinfo = NULL;
|
| - (*next)->success = NULL;
|
| - (*next)->fail = NULL;
|
| - }
|
| - if (byte == (*next)->matching_byte) {
|
| - last = *next;
|
| - next = &((*next)->success);
|
| - i += 2;
|
| - } else {
|
| - /* try next possible match */
|
| - next = &((*next)->fail);
|
| - }
|
| - }
|
| - /* Next points to matching node, add nop info. */
|
| - last->matching_opinfo = nop_info;
|
| -}
|
| -
|
| -/* Define the given sequence of (hex) bytes as a nop. */
|
| -static void NCDefNop(const char* sequence) {
|
| - NCDefNopLikeOp(sequence, &nc_nop_info);
|
| -}
|
| -
|
| -/* Define set of explicitly defined nop byte sequences. */
|
| -static void NCDefNops(void) {
|
| - /* Note: The following could be recognized as nops, but are already
|
| - * parsed and accepted by the validator:
|
| - *
|
| - * 90 nop
|
| - * 66 90 nop
|
| - * 89 f6 mov %esi, %esi
|
| - * 8d 74 26 00 lea %esi, 0x0[%esi]
|
| - * 8d 76 00 lea %esi, 0x0[%esi]
|
| - * 8d b6 00 00 00 00 lea %esi, 0x0[%esi]
|
| - * 8d b4 26 00 00 00 00 lea %esi, 0x0[%esi]
|
| - * 8d bc 27 00 00 00 00 lea %edi, 0x0[%edi]
|
| - * 8d bf 00 00 00 00 lea %edi, 0x0[%edi]
|
| - * 0f 1f 00 nop
|
| - * 0f 1f 40 00 nop
|
| - * 0f 1f 44 00 00 nop
|
| - * 0f 1f 80 00 00 00 00 nop
|
| - * 0f 1f 84 00 00 00 00 00 nop
|
| - */
|
| - NCDefNop("660f1f440000");
|
| - NCDefNop("660f1f840000000000");
|
| - NCDefNop("662e0f1f840000000000");
|
| - NCDefNop("66662e0f1f840000000000");
|
| - NCDefNop("6666662e0f1f840000000000");
|
| - NCDefNop("666666662e0f1f840000000000");
|
| - NCDefNop("66666666662e0f1f840000000000");
|
| - NCDefNop("6666666666662e0f1f840000000000");
|
| -}
|
| -
|
| -static void BuildMetaTables(void) {
|
| - InitializeGlobalTables();
|
| -
|
| - NCDefNops();
|
| -
|
| - if (NULL == nc_nop_root) {
|
| - /* Create dummy node so that it is non-empty. */
|
| - nc_nop_root = (NCNopTrieNode*) malloc(sizeof(NCNopTrieNode));
|
| - nc_nop_root->matching_byte = 0;
|
| - nc_nop_root->matching_opinfo = NULL;
|
| - nc_nop_root->success = NULL;
|
| - nc_nop_root->fail = NULL;
|
| - }
|
| -
|
| - /* now add the real contents */
|
| - /* Eight opcode groups with a regular pattern... */
|
| - ALUOperandVariants00_05(0x00, NACLi_386L, "add");
|
| - ALUOperandVariants00_05(0x08, NACLi_386L, "or");
|
| - ALUOperandVariants00_05(0x10, NACLi_386L, "adc");
|
| - ALUOperandVariants00_05(0x18, NACLi_386L, "sbb");
|
| - ALUOperandVariants00_05(0x20, NACLi_386L, "and");
|
| - ALUOperandVariants00_05(0x28, NACLi_386L, "sub");
|
| - ALUOperandVariants00_05(0x30, NACLi_386L, "xor");
|
| - ALUOperandVariants00_05(0x38, NACLi_386, "cmp");
|
| -
|
| -
|
| - /* Fill in gaps between 00 and 0x40 */
|
| - EncodeModedOp(0x06, 0, IMM_NONE, NACLi_ILLEGAL, "push %es", X86_32);
|
| - EncodeModedOp(0x16, 0, IMM_NONE, NACLi_ILLEGAL, "push %ss", X86_32);
|
| - EncodeOp(0x26, 0, IMM_NONE, NACLi_ILLEGAL, "[seg %es]");
|
| - EncodePrefixName(0x26, "kPrefixSEGES");
|
| - EncodeOp(0x36, 0, IMM_NONE, NACLi_ILLEGAL, "[seg %ss]");
|
| - EncodePrefixName(0x36, "kPrefixSEGSS");
|
| - EncodeModedOp(0x07, 0, IMM_NONE, NACLi_ILLEGAL, "pop %es", X86_32);
|
| - EncodeModedOp(0x17, 0, IMM_NONE, NACLi_ILLEGAL, "pop %ss", X86_32);
|
| - EncodeModedOp(0x27, 0, IMM_NONE, NACLi_ILLEGAL, "daa", X86_32);
|
| - EncodeModedOp(0x37, 0, IMM_NONE, NACLi_ILLEGAL, "aaa",
|
| - X86_32); /* deprecated */
|
| - EncodeModedOp(0x0e, 0, IMM_NONE, NACLi_ILLEGAL, "push %cs", X86_32);
|
| - EncodeModedOp(0x1e, 0, IMM_NONE, NACLi_ILLEGAL, "push %ds", X86_32);
|
| - EncodeOp(0x2e, 0, IMM_NONE, NACLi_ILLEGAL, "[seg %cs]");
|
| - EncodePrefixName(0x2e, "kPrefixSEGCS");
|
| - EncodeOp(0x3e, 0, IMM_NONE, NACLi_ILLEGAL, "[seg %ds]");
|
| - EncodePrefixName(0x3e, "kPrefixSEGDS");
|
| -
|
| - /* 0x0f is an escape to two-byte instructions, below... */
|
| - EncodeOp(0x0f, 0, IMM_NONE, NACLi_UNDEFINED, "[two-byte opcode]");
|
| - EncodeModedOp(0x1f, 0, IMM_NONE, NACLi_ILLEGAL, "pop %ds", X86_32);
|
| - EncodeOp(0x2f, 0, IMM_NONE, NACLi_ILLEGAL, "das");
|
| - EncodeOp(0x3f, 0, IMM_NONE, NACLi_ILLEGAL, "aas"); /* deprecated */
|
| -
|
| - /* another easy pattern, 0x40-0x5f */
|
| - /* inc and dec are deprecated in x86-64; NaCl discourages their use. */
|
| - OneRegVariants00_07(0x40, NACLi_386L, "inc", FALSE);
|
| - OneRegVariants00_07(0x48, NACLi_386L, "dec", FALSE);
|
| - OneRegVariants00_07(0x50, NACLi_386, "push", TRUE);
|
| - OneRegVariants00_07(0x58, NACLi_386, "pop", TRUE);
|
| -
|
| - /* 0x60-0x6f */
|
| - /* also PUSHAD */
|
| - EncodeModedOp(0x60, 0, IMM_NONE, NACLi_ILLEGAL, "pusha", X86_32);
|
| - /* 0x61 - also POPAD */
|
| - EncodeModedOp(0x61, 0, IMM_NONE, NACLi_ILLEGAL, "popa", X86_32);
|
| - /* 0x62 - deprecated */
|
| - EncodeModedOp(0x62, 1, IMM_NONE, NACLi_ILLEGAL, "bound $Gv, $Ma", X86_32);
|
| - /* system */
|
| - EncodeModedOp(0x63, 1, IMM_NONE, NACLi_SYSTEM, "arpl $Ew, $Gw", X86_32);
|
| - EncodeModedOp(0x63, 1, IMM_NONE, NACLi_SYSTEM,"movsxd $Gv, $Ev", X86_64);
|
| - EncodeOp(0x64, 0, IMM_NONE, NACLi_ILLEGAL, "[seg fs]");
|
| - EncodePrefixName(0x64, "kPrefixSEGFS");
|
| - EncodeOp(0x65, 0, IMM_NONE, NACLi_ILLEGAL, "[seg gs]");
|
| - EncodePrefixName(0x65, "kPrefixSEGGS");
|
| - EncodeOp(0x66, 0, IMM_NONE, NACLi_ILLEGAL, "[data16]");
|
| - EncodePrefixName(0x66, "kPrefixDATA16");
|
| - EncodeOp(0x67, 0, IMM_NONE, NACLi_ILLEGAL, "[addr size]");
|
| - EncodePrefixName(0x67, "kPrefixADDR16");
|
| - EncodeOp(0x68, 0, IMM_DATAV, NACLi_386, "push $Iz");
|
| - SetOpDefaultSize64(0x68);
|
| - EncodeOp(0x69, 1, IMM_DATAV, NACLi_386, "imul $Gv, $Ev, $Iz");
|
| - EncodeOp(0x6a, 0, IMM_FIXED1, NACLi_386, "push $Ib");
|
| - SetOpDefaultSize64(0x6a);
|
| - EncodeOp(0x6b, 1, IMM_FIXED1, NACLi_386, "imul $Gv, $Ev, $Ib");
|
| - EncodeOp(0x6c, 0, IMM_NONE, NACLi_ILLEGAL, "insb $Y, $D");
|
| - EncodeOp(0x6d, 0, IMM_NONE, NACLi_ILLEGAL, "insw/d $Y, $D");
|
| - EncodeOp(0x6e, 0, IMM_NONE, NACLi_ILLEGAL, "outsb $D, $X");
|
| - EncodeOp(0x6f, 0, IMM_NONE, NACLi_ILLEGAL, "outsw/d $D, $X");
|
| -
|
| - /* 0x70-0x77: jumps */
|
| - EncodeOp(0x70, 0, IMM_FIXED1, NACLi_JMP8, "jo $Jb");
|
| - SetOpForceSize64(0x70);
|
| - EncodeOp(0x71, 0, IMM_FIXED1, NACLi_JMP8, "jno $Jb");
|
| - SetOpForceSize64(0x71);
|
| - EncodeOp(0x72, 0, IMM_FIXED1, NACLi_JMP8, "jb $Jb");
|
| - SetOpForceSize64(0x72);
|
| - EncodeOp(0x73, 0, IMM_FIXED1, NACLi_JMP8, "jnb $Jb");
|
| - SetOpForceSize64(0x73);
|
| - EncodeOp(0x74, 0, IMM_FIXED1, NACLi_JMP8, "jz $Jb");
|
| - SetOpForceSize64(0x74);
|
| - EncodeOp(0x75, 0, IMM_FIXED1, NACLi_JMP8, "jnz $Jb");
|
| - SetOpForceSize64(0x75);
|
| - EncodeOp(0x76, 0, IMM_FIXED1, NACLi_JMP8, "jbe $Jb");
|
| - SetOpForceSize64(0x76);
|
| - EncodeOp(0x77, 0, IMM_FIXED1, NACLi_JMP8, "jnbe $Jb");
|
| - SetOpForceSize64(0x77);
|
| - EncodeOp(0x78, 0, IMM_FIXED1, NACLi_JMP8, "js $Jb");
|
| - SetOpForceSize64(0x78);
|
| - EncodeOp(0x79, 0, IMM_FIXED1, NACLi_JMP8, "jns $Jb");
|
| - SetOpForceSize64(0x79);
|
| - EncodeOp(0x7a, 0, IMM_FIXED1, NACLi_JMP8, "jp $Jb");
|
| - SetOpForceSize64(0x7a);
|
| - EncodeOp(0x7b, 0, IMM_FIXED1, NACLi_JMP8, "jnp $Jb");
|
| - SetOpForceSize64(0x7b);
|
| - EncodeOp(0x7c, 0, IMM_FIXED1, NACLi_JMP8, "jl $Jb");
|
| - SetOpForceSize64(0x7c);
|
| - EncodeOp(0x7d, 0, IMM_FIXED1, NACLi_JMP8, "jge $Jb");
|
| - SetOpForceSize64(0x7d);
|
| - EncodeOp(0x7e, 0, IMM_FIXED1, NACLi_JMP8, "jle $Jb");
|
| - SetOpForceSize64(0x7e);
|
| - EncodeOp(0x7f, 0, IMM_FIXED1, NACLi_JMP8, "jg $Jb");
|
| - SetOpForceSize64(0x7f);
|
| -
|
| - /* 0x80-0x8f: Gpr1, test, xchg, mov, lea, mov, pop */
|
| - EncodeOp(0x80, 1, IMM_FIXED1, NACLi_OPINMRM, "$group1 $Eb, $Ib");
|
| - SetOpOpInMRM(0x80, GROUP1);
|
| - EncodeOp(0x81, 1, IMM_DATAV, NACLi_OPINMRM, "$group1 $Ev, $Iz");
|
| - SetOpOpInMRM(0x81, GROUP1);
|
| -
|
| - /* The AMD manual shows 0x82 as a synonym for 0x80,
|
| - * however these are all illegal in 64-bit mode so we omit them here
|
| - * too.
|
| - */
|
| - EncodeModedOp(0x82, 1, IMM_FIXED1, NACLi_ILLEGAL, "undef", X86_32);
|
| -
|
| - /* table disagrees with objdump on 0x83? */
|
| - EncodeOp(0x83, 1, IMM_FIXED1, NACLi_OPINMRM, "$group1 $Ev, $Ib");
|
| - SetOpOpInMRM(0x83, GROUP1);
|
| - EncodeOp(0x84, 1, IMM_NONE, NACLi_386, "test $E, $G");
|
| - EncodeOp(0x85, 1, IMM_NONE, NACLi_386, "test $E, $G");
|
| - EncodeOp(0x86, 1, IMM_NONE, NACLi_386L, "xchg $E, $G");
|
| - EncodeOp(0x87, 1, IMM_NONE, NACLi_386L, "xchg $E, $G");
|
| - EncodeOp(0x88, 1, IMM_NONE, NACLi_386, "mov $Eb, $Gb");
|
| - EncodeOp(0x89, 1, IMM_NONE, NACLi_386, "mov $Ev, $Gv");
|
| - EncodeOp(0x8a, 1, IMM_NONE, NACLi_386, "mov $Gb, $Eb");
|
| - EncodeOp(0x8b, 1, IMM_NONE, NACLi_386, "mov $Gv, $Ev");
|
| - EncodeOp(0x8c, 1, IMM_NONE, NACLi_ILLEGAL, "mov $E, $S");
|
| - EncodeOp(0x8d, 1, IMM_NONE, NACLi_386, "lea $G, $M");
|
| - EncodeOp(0x8e, 1, IMM_NONE, NACLi_ILLEGAL, "mov $S, $E");
|
| - EncodeOp(0x8f, 1, IMM_NONE, NACLi_OPINMRM, "$group1a $Ev");
|
| - SetOpOpInMRM(0x8f, GROUP1A);
|
| - SetOpDefaultSize64(0x8f);
|
| -
|
| - /* 0x90-0x9f */
|
| - /* TODO(karl, encode 64 mode with rXX/xn based on REX.b) */
|
| - EncodeOp(0x90, 0, IMM_NONE, NACLi_386R, "nop");
|
| - EncodeOpRegs(0x91, 0, IMM_NONE, NACLi_386L, "xchg %eax, %ecx");
|
| - EncodeOpRegs(0x92, 0, IMM_NONE, NACLi_386L, "xchg %eax, %edx");
|
| - EncodeOpRegs(0x93, 0, IMM_NONE, NACLi_386L, "xchg %eax, %ebx");
|
| - EncodeOpRegs(0x94, 0, IMM_NONE, NACLi_386L, "xchg %eax, %esp");
|
| - EncodeOpRegs(0x95, 0, IMM_NONE, NACLi_386L, "xchg %eax, %ebp");
|
| - EncodeOpRegs(0x96, 0, IMM_NONE, NACLi_386L, "xchg %eax, %esi");
|
| - EncodeOpRegs(0x97, 0, IMM_NONE, NACLi_386L, "xchg %eax, %edi");
|
| - EncodeOp(0x98, 0, IMM_NONE, NACLi_386, "cbw"); /* cwde cdqe */
|
| - EncodeOp(0x99, 0, IMM_NONE, NACLi_386, "cwd"); /* cdq cqo */
|
| - EncodeModedOp(0x9a, 0, IMM_FARPTR, NACLi_ILLEGAL, "lcall $A", X86_32);
|
| - EncodeOp(0x9b, 0, IMM_NONE, NACLi_X87, "wait");
|
| - EncodeOp(0x9c, 0, IMM_NONE, NACLi_ILLEGAL, "pushf $F");
|
| - SetOpDefaultSize64(0x9c);
|
| - EncodeOp(0x9d, 0, IMM_NONE, NACLi_ILLEGAL, "popf $F");
|
| - SetOpDefaultSize64(0x9d);
|
| - EncodeOp(0x9e, 0, IMM_NONE, NACLi_386, "sahf");
|
| - EncodeOp(0x9f, 0, IMM_NONE, NACLi_386, "lahf");
|
| -
|
| - /* 0xa0-0xaf */
|
| - EncodeOp(0xa0, 0, IMM_ADDRV, NACLi_386, "mov %al, $O");
|
| - EncodeOpRegs(0xa1, 0, IMM_ADDRV, NACLi_386, "mov %eax, $O");
|
| - EncodeOp(0xa2, 0, IMM_ADDRV, NACLi_386, "mov $O, %al");
|
| - EncodeOpRegs(0xa3, 0, IMM_ADDRV, NACLi_386, "mov $O, %eax");
|
| - EncodeOp(0xa4, 0, IMM_NONE, NACLi_386R, "movsb $X, $Y");
|
| - EncodeOp(0xa5, 0, IMM_NONE, NACLi_386R, "movsw $X, $Y");
|
| - EncodeOp(0xa6, 0, IMM_NONE, NACLi_386RE, "cmpsb $X, $Y");
|
| - EncodeOp(0xa7, 0, IMM_NONE, NACLi_386RE, "cmpsw $X, $Y");
|
| - EncodeOp(0xa8, 0, IMM_FIXED1, NACLi_386, "test %al, $I");
|
| - EncodeOpRegs(0xa9, 0, IMM_DATAV, NACLi_386, "test %eax, $I");
|
| - EncodeOp(0xaa, 0, IMM_NONE, NACLi_386R, "stosb $Y, %al");
|
| - EncodeOpRegs(0xab, 0, IMM_NONE, NACLi_386R, "stosw $Y, $eax");
|
| - /* ISE reviewers suggested omitting lods and scas */
|
| - EncodeOp(0xac, 0, IMM_NONE, NACLi_ILLEGAL, "lodsb %al, $X");
|
| - EncodeOpRegs(0xad, 0, IMM_NONE, NACLi_ILLEGAL, "lodsw %eax, $X");
|
| - EncodeOp(0xae, 0, IMM_NONE, NACLi_386RE, "scasb %al, $X");
|
| - EncodeOpRegs(0xaf, 0, IMM_NONE, NACLi_386RE, "scasw %eax, $X");
|
| -
|
| - /* 0xb0-0xbf */
|
| - TODO(karl, "add mode64 versions");
|
| - TODO(karl,
|
| - "form is rXX/xn or xl/rnl or xh/rnl based on REX.b when in mode64");
|
| - EncodeModedOp(0xb0, 0, IMM_FIXED1, NACLi_386, "mov %al, $Ib", X86_32);
|
| - EncodeModedOp(0xb1, 0, IMM_FIXED1, NACLi_386, "mov %cl, $Ib", X86_32);
|
| - EncodeModedOp(0xb2, 0, IMM_FIXED1, NACLi_386, "mov %dl, $Ib", X86_32);
|
| - EncodeModedOp(0xb3, 0, IMM_FIXED1, NACLi_386, "mov %bl, $Ib", X86_32);
|
| - EncodeModedOp(0xb4, 0, IMM_FIXED1, NACLi_386, "mov %ah, $Ib", X86_32);
|
| - EncodeModedOp(0xb5, 0, IMM_FIXED1, NACLi_386, "mov %ch, $Ib", X86_32);
|
| - EncodeModedOp(0xb6, 0, IMM_FIXED1, NACLi_386, "mov %dh, $Ib", X86_32);
|
| - EncodeModedOp(0xb7, 0, IMM_FIXED1, NACLi_386, "mov %bh, $Ib", X86_32);
|
| -
|
| - EncodeOp(0xb8, 0, IMM_MOV_DATAV, NACLi_386, "mov %eax, $Iv");
|
| - EncodeOp(0xb9, 0, IMM_MOV_DATAV, NACLi_386, "mov %ecx, $Iv");
|
| - EncodeOp(0xba, 0, IMM_MOV_DATAV, NACLi_386, "mov %edx, $Iv");
|
| - EncodeOp(0xbb, 0, IMM_MOV_DATAV, NACLi_386, "mov %ebx, $Iv");
|
| - EncodeOp(0xbc, 0, IMM_MOV_DATAV, NACLi_386, "mov %esp, $Iv");
|
| - EncodeOp(0xbd, 0, IMM_MOV_DATAV, NACLi_386, "mov %ebp, $Iv");
|
| - EncodeOp(0xbe, 0, IMM_MOV_DATAV, NACLi_386, "mov %esi, $Iv");
|
| - EncodeOp(0xbf, 0, IMM_MOV_DATAV, NACLi_386, "mov %edi, $Iv");
|
| -
|
| - /* 0xc0-0xcf */
|
| - EncodeOp(0xc0, 1, IMM_FIXED1, NACLi_OPINMRM, "$group2 $Eb, $Ib");
|
| - SetOpOpInMRM(0xc0, GROUP2);
|
| - EncodeOp(0xc1, 1, IMM_FIXED1, NACLi_OPINMRM, "$group2 $Ev, $Ib");
|
| - SetOpOpInMRM(0xc1, GROUP2);
|
| - EncodeOp(0xc2, 0, IMM_FIXED2, NACLi_RETURN, "ret $Iw");
|
| - SetOpForceSize64(0xc2);
|
| - EncodeOp(0xc3, 0, IMM_NONE, NACLi_RETURN, "ret");
|
| - SetOpForceSize64(0xc3);
|
| - EncodeModedOp(0xc4, 1, IMM_NONE, NACLi_ILLEGAL, "les $G, $M", X86_32);
|
| - EncodeModedOp(0xc5, 1, IMM_NONE, NACLi_ILLEGAL, "lds $G, $M", X86_32);
|
| - EncodeOp(0xc6, 1, IMM_FIXED1, NACLi_OPINMRM, "$group11 $Eb, $Ib");
|
| - SetOpOpInMRM(0xc6, GROUP11);
|
| - EncodeOp(0xc7, 1, IMM_DATAV, NACLi_OPINMRM, "$group11 $Ev, $Iz");
|
| - SetOpOpInMRM(0xc7, GROUP11);
|
| - EncodeOp(0xc8, 0, IMM_FIXED3, NACLi_ILLEGAL, "enter $I, $I");
|
| - EncodeOp(0xc9, 0, IMM_NONE, NACLi_386, "leave");
|
| - SetOpDefaultSize64(0xc9);
|
| - EncodeOp(0xca, 0, IMM_FIXED2, NACLi_RETURN, "ret (far)");
|
| - EncodeOp(0xcb, 0, IMM_NONE, NACLi_RETURN, "ret (far)");
|
| - EncodeOp(0xcc, 0, IMM_NONE, NACLi_ILLEGAL, "int3");
|
| - EncodeOp(0xcd, 0, IMM_FIXED1, NACLi_ILLEGAL, "int $Iv");
|
| - EncodeModedOp(0xce, 0, IMM_NONE, NACLi_ILLEGAL, "into", X86_32);
|
| - EncodeOp(0xcf, 0, IMM_NONE, NACLi_SYSTEM, "iret");
|
| - /* 0xd0-0xdf */
|
| - EncodeOp(0xd0, 1, IMM_NONE, NACLi_OPINMRM, "$group2 $Eb, 1");
|
| - SetOpOpInMRM(0xd0, GROUP2);
|
| - EncodeOp(0xd1, 1, IMM_NONE, NACLi_OPINMRM, "$group2 $Ev, 1");
|
| - SetOpOpInMRM(0xd1, GROUP2);
|
| - EncodeOp(0xd2, 1, IMM_NONE, NACLi_OPINMRM, "$group2 $Eb, %cl");
|
| - SetOpOpInMRM(0xd2, GROUP2);
|
| - EncodeOp(0xd3, 1, IMM_NONE, NACLi_OPINMRM, "$group2 $Ev, %cl");
|
| - SetOpOpInMRM(0xd3, GROUP2);
|
| -
|
| - /* ISE reviewers suggested omision of AAM, AAD */
|
| - /* 0xd4-0xd5 - deprecated */
|
| - EncodeModedOp(0xd4, 0, IMM_FIXED1, NACLi_ILLEGAL, "aam", X86_32);
|
| - EncodeModedOp(0xd5, 0, IMM_FIXED1, NACLi_ILLEGAL, "aad", X86_32);
|
| - TODO(karl,
|
| - "Intel manual (see comments above) has a blank entry"
|
| - "for opcode 0xd6, which states that blank entries in"
|
| - "the tables correspond to reserved (undefined) values"
|
| - "Should we treat this accordingly?")
|
| - EncodeOp(0xd6, 0, IMM_NONE, NACLi_ILLEGAL, "salc");
|
| -
|
| - /* ISE reviewers suggested this omision */
|
| - EncodeOp(0xd7, 0, IMM_NONE, NACLi_ILLEGAL, "xlat");
|
| - EncodeOp(0xd8, 1, IMM_NONE, NACLi_X87, "x87");
|
| - EncodeOp(0xd9, 1, IMM_NONE, NACLi_X87, "x87");
|
| - EncodeOp(0xda, 1, IMM_NONE, NACLi_X87, "x87");
|
| - EncodeOp(0xdb, 1, IMM_NONE, NACLi_X87, "x87");
|
| - EncodeOp(0xdc, 1, IMM_NONE, NACLi_X87, "x87");
|
| - EncodeOp(0xdd, 1, IMM_NONE, NACLi_X87, "x87");
|
| - EncodeOp(0xde, 1, IMM_NONE, NACLi_X87, "x87");
|
| - EncodeOp(0xdf, 1, IMM_NONE, NACLi_X87, "x87");
|
| -
|
| - /* 0xe0-0xef */
|
| - /* ISE reviewers suggested making loopne, loope, loop, jcxz illegal */
|
| - /* There are faster alternatives on modern x86 implementations. */
|
| - EncodeOp(0xe0, 0, IMM_FIXED1, NACLi_ILLEGAL, "loopne $Jb");
|
| - SetOpForceSize64(0xe0);
|
| - EncodeOp(0xe1, 0, IMM_FIXED1, NACLi_ILLEGAL, "loope $Jb");
|
| - SetOpForceSize64(0xe1);
|
| - EncodeOp(0xe2, 0, IMM_FIXED1, NACLi_ILLEGAL, "loop $Jb");
|
| - SetOpForceSize64(0xe2);
|
| - EncodeOp(0xe3, 0, IMM_FIXED1, NACLi_ILLEGAL, "jcxz $Jb");
|
| - SetOpForceSize64(0xe3);
|
| -
|
| - /* I/O instructions */
|
| - EncodeOp(0xe4, 0, IMM_FIXED1, NACLi_ILLEGAL, "in %al, $I");
|
| - EncodeOp(0xe5, 0, IMM_FIXED1, NACLi_ILLEGAL, "in %eax, $I");
|
| - EncodeOp(0xe6, 0, IMM_FIXED1, NACLi_ILLEGAL, "out %al, $I");
|
| - EncodeOp(0xe7, 0, IMM_FIXED1, NACLi_ILLEGAL, "out %eax, $I");
|
| - EncodeOp(0xe8, 0, IMM_DATAV, NACLi_JMPZ, "call $Jz");
|
| - SetOpForceSize64(0xe8);
|
| - EncodeOp(0xe9, 0, IMM_DATAV, NACLi_JMPZ, "jmp $Jz");
|
| - SetOpForceSize64(0xe9);
|
| - EncodeModedOp(0xea, 0, IMM_FARPTR, NACLi_ILLEGAL, "ljmp $A", X86_32);
|
| - EncodeOp(0xeb, 0, IMM_FIXED1, NACLi_JMP8, "jmp $Jb");
|
| - SetOpForceSize64(0xeb);
|
| - EncodeOp(0xec, 0, IMM_NONE, NACLi_ILLEGAL, "in %al, %dx");
|
| - EncodeOp(0xed, 0, IMM_NONE, NACLi_ILLEGAL, "in %eax, %dx");
|
| - EncodeOp(0xee, 0, IMM_NONE, NACLi_ILLEGAL, "out %dx, %al");
|
| - EncodeOp(0xef, 0, IMM_NONE, NACLi_ILLEGAL, "out %dx, %eax");
|
| -
|
| - /* 0xf0-0xff */
|
| - EncodeOp(0xf0, 0, IMM_NONE, NACLi_ILLEGAL, "[lock]");
|
| - EncodePrefixName(0xf0, "kPrefixLOCK");
|
| - EncodeOp(0xf1, 0, IMM_NONE, NACLi_ILLEGAL, "int1");
|
| - TODO(karl,
|
| - "Intel manual (see comments above) has a blank entry"
|
| - "for opcode 0xf2, which states that blank entries in"
|
| - "the tables correspond to reserved (undefined) values"
|
| - "Should we treat this accordingly?")
|
| - EncodeOp(0xf2, 0, IMM_NONE, NACLi_ILLEGAL, "[repne]");
|
| - EncodePrefixName(0xf2, "kPrefixREPNE");
|
| - EncodeOp(0xf3, 0, IMM_NONE, NACLi_ILLEGAL, "[rep]");
|
| - EncodePrefixName(0xf3, "kPrefixREP");
|
| -
|
| - /* NaCl uses the hlt instruction for bytes that should never be */
|
| - /* executed. hlt causes immediate termination of the module. */
|
| - EncodeOp(0xf4, 0, IMM_NONE, NACLi_386, "hlt");
|
| - EncodeOp(0xf5, 0, IMM_NONE, NACLi_386, "cmc");
|
| -
|
| - /* Note: /0 and /1 also have an immediate */
|
| - EncodeOp(0xf6, 1, IMM_GROUP3_F6, NACLi_OPINMRM, "$group3 $Eb");
|
| - SetOpOpInMRM(0xf6, GROUP3);
|
| - EncodeOp(0xf7, 1, IMM_GROUP3_F7, NACLi_OPINMRM, "$group3 $Ev");
|
| - SetOpOpInMRM(0xf7, GROUP3);
|
| - EncodeOp(0xf8, 0, IMM_NONE, NACLi_386, "clc");
|
| - EncodeOp(0xf9, 0, IMM_NONE, NACLi_386, "stc");
|
| - EncodeOp(0xfa, 0, IMM_NONE, NACLi_SYSTEM, "cli");
|
| - EncodeOp(0xfb, 0, IMM_NONE, NACLi_SYSTEM, "sti");
|
| -
|
| - /* cld and std are generated by gcc, used for mem move operations */
|
| - EncodeOp(0xfc, 0, IMM_NONE, NACLi_386, "cld");
|
| - EncodeOp(0xfd, 0, IMM_NONE, NACLi_386, "std");
|
| - EncodeOp(0xfe, 1, IMM_NONE, NACLi_OPINMRM, "$group4 $Eb");
|
| - SetOpOpInMRM(0xfe, GROUP4);
|
| -
|
| - /* Note: /3 and /5 are $Mp rather than $Ev */
|
| - EncodeOp(0xff, 1, IMM_NONE, NACLi_OPINMRM, "$group5 $Ev");
|
| - SetOpOpInMRM(0xff, GROUP5);
|
| -
|
| - /* Opcodes encoded in the modrm field */
|
| - /* Anything not done explicitly is marked illegal */
|
| - /* group1 */
|
| - EncodeModRMOp(GROUP1, 0, NACLi_386L, "add");
|
| - EncodeModRMOp(GROUP1, 1, NACLi_386L, "or");
|
| - EncodeModRMOp(GROUP1, 2, NACLi_386L, "adc");
|
| - EncodeModRMOp(GROUP1, 3, NACLi_386L, "sbb");
|
| - EncodeModRMOp(GROUP1, 4, NACLi_386L, "and");
|
| - EncodeModRMOp(GROUP1, 5, NACLi_386L, "sub");
|
| - EncodeModRMOp(GROUP1, 6, NACLi_386L, "xor");
|
| - EncodeModRMOp(GROUP1, 7, NACLi_386, "cmp");
|
| -
|
| - /* group1a */
|
| - EncodeModRMOp(GROUP1A, 0, NACLi_386, "pop $Ev");
|
| -
|
| - /* all other group1a opcodes are illegal */
|
| - /* group2 */
|
| - EncodeModRMOp(GROUP2, 0, NACLi_386, "rol");
|
| - EncodeModRMOp(GROUP2, 1, NACLi_386, "ror");
|
| - EncodeModRMOp(GROUP2, 2, NACLi_386, "rcl");
|
| - EncodeModRMOp(GROUP2, 3, NACLi_386, "rcr");
|
| - EncodeModRMOp(GROUP2, 4, NACLi_386, "shl"); /* sal */
|
| - EncodeModRMOp(GROUP2, 5, NACLi_386, "shr"); /* sar */
|
| -
|
| - /* note 2, 6 is illegal according to Intel, shl according to AMD */
|
| - EncodeModRMOp(GROUP2, 7, NACLi_386, "sar");
|
| -
|
| - /* group3 */
|
| - EncodeModRMOp(GROUP3, 0, NACLi_386, "test $I");
|
| -
|
| - /* this is such a weird case ... just put a special case in ncdecode.c */
|
| - /* note 3, 1 is handled by a special case in the decoder */
|
| - /* SetModRMOpImmType(3, 0, IMM_FIXED1); */
|
| - EncodeModRMOp(GROUP3, 2, NACLi_386L, "not");
|
| - EncodeModRMOp(GROUP3, 3, NACLi_386L, "neg");
|
| - EncodeModRMOpRegs(GROUP3, 4, NACLi_386, "mul %eax");
|
| - EncodeModRMOpRegs(GROUP3, 5, NACLi_386, "imul %eax");
|
| - EncodeModRMOpRegs(GROUP3, 6, NACLi_386, "div %eax");
|
| - EncodeModRMOpRegs(GROUP3, 7, NACLi_386, "idiv %eax");
|
| -
|
| - /* group4 */
|
| - EncodeModRMOp(GROUP4, 0, NACLi_386L, "inc");
|
| - EncodeModRMOp(GROUP4, 1, NACLi_386L, "dec");
|
| -
|
| - /* group5 */
|
| - EncodeModRMOp(GROUP5, 0, NACLi_386L, "inc");
|
| - EncodeModRMOp(GROUP5, 1, NACLi_386L, "dec");
|
| - EncodeModRMOp(GROUP5, 2, NACLi_INDIRECT, "call *"); /* call indirect */
|
| - SetModRMOpForceSize64(GROUP5, 2);
|
| - EncodeModRMOp(GROUP5, 3, NACLi_ILLEGAL, "lcall *"); /* far call */
|
| - EncodeModRMOp(GROUP5, 4, NACLi_INDIRECT, "jmp *"); /* jump indirect */
|
| - SetModRMOpForceSize64(GROUP5, 4);
|
| - EncodeModRMOp(GROUP5, 5, NACLi_ILLEGAL, "ljmp *"); /* far jmp */
|
| - EncodeModRMOp(GROUP5, 6, NACLi_386, "push");
|
| - SetModRMOpDefaultSize64(GROUP5, 6);
|
| -
|
| - /* group6 */
|
| - EncodeModRMOp(GROUP6, 0, NACLi_SYSTEM, "sldt");
|
| - EncodeModRMOp(GROUP6, 1, NACLi_SYSTEM, "str");
|
| - EncodeModRMOp(GROUP6, 2, NACLi_SYSTEM, "lldt");
|
| - EncodeModRMOp(GROUP6, 3, NACLi_SYSTEM, "ltr");
|
| - EncodeModRMOp(GROUP6, 4, NACLi_SYSTEM, "verr");
|
| - EncodeModRMOp(GROUP6, 5, NACLi_SYSTEM, "verw");
|
| -
|
| - /* group7 */
|
| - EncodeModRMOp(GROUP7, 0, NACLi_SYSTEM, "sgdt");
|
| - EncodeModRMOp(GROUP7, 1, NACLi_SYSTEM, "sidt"); /* monitor mwait */
|
| - EncodeModRMOp(GROUP7, 2, NACLi_SYSTEM, "lgdt");
|
| - EncodeModRMOp(GROUP7, 3, NACLi_SYSTEM, "lidt");
|
| - EncodeModRMOp(GROUP7, 4, NACLi_SYSTEM, "smsw");
|
| - EncodeModRMOp(GROUP7, 6, NACLi_SYSTEM, "lmsw");
|
| - EncodeModRMOp(GROUP7, 7, NACLi_SYSTEM, "invlpg"); /* swapgs rdtscp */
|
| -
|
| - /* group8 */
|
| - /* ISE reviewers suggested omitting bt* */
|
| - EncodeModRMOp(GROUP8, 4, NACLi_ILLEGAL, "bt"); /* deprecated */
|
| - EncodeModRMOp(GROUP8, 5, NACLi_ILLEGAL, "bts"); /* deprecated */
|
| - EncodeModRMOp(GROUP8, 6, NACLi_ILLEGAL, "btr"); /* deprecated */
|
| - EncodeModRMOp(GROUP8, 7, NACLi_ILLEGAL, "btc"); /* deprecated */
|
| -
|
| - /* group9 */
|
| - /* If the effective operand size is 16 or 32 bits, cmpxchg8b is used. */
|
| - /* If the size is 64 bits, cmpxchg16b is used, (64-bit mode only) */
|
| - /* These instructions do support the LOCK prefix */
|
| - EncodeModRMOp(GROUP9, 1, NACLi_CMPXCHG8B, "cmpxchg8b");
|
| -
|
| - /* group10 - all illegal */
|
| - /* group11 */
|
| - EncodeModRMOp(GROUP11, 0, NACLi_386, "mov");
|
| -
|
| - /* group12 */
|
| - EncodeModRMOp(GROUP12, 2, NACLi_MMXSSE2, "psrlw");
|
| - EncodeModRMOp(GROUP12, 4, NACLi_MMXSSE2, "psraw");
|
| - EncodeModRMOp(GROUP12, 6, NACLi_MMXSSE2, "psllw");
|
| -
|
| - /* group13 */
|
| - EncodeModRMOp(GROUP13, 2, NACLi_MMXSSE2, "psrld");
|
| - EncodeModRMOp(GROUP13, 4, NACLi_MMXSSE2, "psrad");
|
| - EncodeModRMOp(GROUP13, 6, NACLi_MMXSSE2, "pslld");
|
| -
|
| - /* group14 */
|
| - EncodeModRMOp(GROUP14, 2, NACLi_MMXSSE2, "psrlq");
|
| - EncodeModRMOp(GROUP14, 3, NACLi_SSE2x, "psrldq");
|
| - EncodeModRMOp(GROUP14, 6, NACLi_MMXSSE2, "psllq");
|
| - EncodeModRMOp(GROUP14, 7, NACLi_SSE2x, "pslldq");
|
| -
|
| - /* group15 */
|
| - EncodeModRMOp(GROUP15, 0, NACLi_ILLEGAL, "fxsave");
|
| - EncodeModRMOp(GROUP15, 1, NACLi_ILLEGAL, "fxrstor");
|
| - EncodeModRMOp(GROUP15, 2, NACLi_SSE, "ldmxcsr");
|
| - EncodeModRMOp(GROUP15, 3, NACLi_SSE, "stmxcsr");
|
| - EncodeModRMOp(GROUP15, 4, NACLi_ILLEGAL, "invalid");
|
| - EncodeModRMOp(GROUP15, 5, NACLi_SSE2, "lfence");
|
| - EncodeModRMOp(GROUP15, 6, NACLi_SSE2, "mfence");
|
| - EncodeModRMOp(GROUP15, 7, NACLi_SFENCE_CLFLUSH, "sfence/clflush");
|
| -
|
| - /* group16 - SSE prefetch instructions */
|
| - EncodeModRMOp(GROUP16, 0, NACLi_SSE, "prefetch NTA");
|
| - EncodeModRMOp(GROUP16, 1, NACLi_SSE, "prefetch T0");
|
| - EncodeModRMOp(GROUP16, 2, NACLi_SSE, "prefetch T1");
|
| - EncodeModRMOp(GROUP16, 3, NACLi_SSE, "prefetch T1");
|
| - EncodeModRMOp(GROUP16, 4, NACLi_ILLEGAL, "NOP (prefetch)");
|
| - EncodeModRMOp(GROUP16, 5, NACLi_ILLEGAL, "NOP (prefetch)");
|
| - EncodeModRMOp(GROUP16, 6, NACLi_ILLEGAL, "NOP (prefetch)");
|
| - EncodeModRMOp(GROUP16, 7, NACLi_ILLEGAL, "NOP (prefetch)");
|
| -
|
| - /* groupp: prefetch - requires longmode or 3DNow! */
|
| - /* It may be the case that these can also be enabled by CPUID_ECX_PRE; */
|
| - /* This enabling is not supported by the validator at this time. */
|
| - EncodeModRMOp(GROUPP, 0, NACLi_3DNOW, "prefetch exclusive");
|
| - EncodeModRMOp(GROUPP, 1, NACLi_3DNOW, "prefetch modified");
|
| - EncodeModRMOp(GROUPP, 2, NACLi_ILLEGAL, "[prefetch reserved]");
|
| - EncodeModRMOp(GROUPP, 3, NACLi_ILLEGAL, "prefetch modified");
|
| - EncodeModRMOp(GROUPP, 4, NACLi_ILLEGAL, "[prefetch reserved]");
|
| - EncodeModRMOp(GROUPP, 5, NACLi_ILLEGAL, "[prefetch reserved]");
|
| - EncodeModRMOp(GROUPP, 6, NACLi_ILLEGAL, "[prefetch reserved]");
|
| - EncodeModRMOp(GROUPP, 7, NACLi_ILLEGAL, "[prefetch reserved]");
|
| -
|
| - /* encode opbyte 2; first byte is 0x0f */
|
| - /* holes are undefined instructions */
|
| - /* This code used to allow the data16 (0x16) prefix to be used with */
|
| - /* any two-byte opcode, until it caused a bug. Now all allowed */
|
| - /* prefixes need to be added explicitly. */
|
| - /* See http://code.google.com/p/nativeclient/issues/detail?id=50 */
|
| - /* Note: /0 and /1 have $Mw/Rv instead of $Ew */
|
| - EncodeOp0F(0x00, 1, IMM_NONE, NACLi_OPINMRM, "$group6 $Ew");
|
| - SetOp0FOpInMRM(0x0, GROUP6);
|
| -
|
| - /* Group7 is all privileged/system instructions */
|
| - EncodeOp0F(0x01, 1, IMM_NONE, NACLi_OPINMRM, "$group7");
|
| - SetOp0FOpInMRM(0x01, GROUP7);
|
| - EncodeOp0F(0x02, 1, IMM_NONE, NACLi_SYSTEM, "lar $G, $E");
|
| - EncodeOp0F(0x03, 1, IMM_NONE, NACLi_ILLEGAL, "lsl $Gv, $Ew");
|
| -
|
| - /* Intel table states that this only applies in 64-bit mode. */
|
| - EncodeModedOp0F(0x05, 0, IMM_NONE, NACLi_SYSCALL, "syscall", X86_64);
|
| - EncodeOp0F(0x06, 0, IMM_NONE, NACLi_SYSTEM, "clts");
|
| -
|
| - /* Intel table states that this only applies in 64-bit mode. */
|
| - EncodeModedOp0F(0x07, 0, IMM_NONE, NACLi_ILLEGAL, "sysret", X86_64);
|
| - EncodeOp0F(0x08, 0, IMM_NONE, NACLi_SYSTEM, "invd");
|
| - EncodeOp0F(0x09, 0, IMM_NONE, NACLi_SYSTEM, "wbinvd");
|
| - /* UD2 always generates a #UD exception sl (like HLT) is always safe. */
|
| - EncodeOp0F(0x0b, 0, IMM_NONE, NACLi_386, "ud2");
|
| -
|
| - TODO(karl, "Intel table states that 0x0d is a 'NOP Ev'");
|
| - EncodeOp0F(0x0d, 1, IMM_NONE, NACLi_OPINMRM, "$groupP (prefetch)");
|
| - SetOp0FOpInMRM(0x0d, GROUPP);
|
| -
|
| - TODO(karl, "Intel table states that this is undefined");
|
| - EncodeOp0F(0x0e, 0, IMM_NONE, NACLi_3DNOW, "femms");
|
| -
|
| - /* 3DNow instruction encodings use a MODRM byte and a 1-byte */
|
| - /* immediate which defines the opcode. */
|
| - TODO(karl, "Intel table states that this is undefined");
|
| - EncodeOp0F(0x0f, 1, IMM_FIXED1, NACLi_3DNOW, "3DNow");
|
| -
|
| - /* 0x10-17 appear below with the other newer opcodes ... */
|
| - EncodeOp0F(0x18, 1, IMM_NONE, NACLi_OPINMRM, "$group16");
|
| - SetOp0FOpInMRM(0x18, GROUP16);
|
| -
|
| - /* this nop takes an MRM byte */
|
| - EncodeOp0F(0x1f, 1, IMM_NONE, NACLi_386, "nop");
|
| - EncodeOp0F(0x20, 1, IMM_NONE, NACLi_SYSTEM, "mov $C, $R");
|
| - EncodeOp0F(0x21, 1, IMM_NONE, NACLi_SYSTEM, "mov $D, $R");
|
| - EncodeOp0F(0x22, 1, IMM_NONE, NACLi_SYSTEM, "mov $R, $C");
|
| - EncodeOp0F(0x23, 1, IMM_NONE, NACLi_SYSTEM, "mov $R, $D");
|
| -
|
| - /* These two seem to be a mistake */
|
| - /* EncodeOp0F(0x24, 0, IMM_NONE, NACLi_SYSTEM, "mov $T, $R"); */
|
| - /* EncodeOp0F(0x26, 0, IMM_NONE, NACLi_SYSTEM, "mov $R, $T"); */
|
| - /* 0x28-2f appear below with the other newer opcodes ... */
|
| - /* 0x30-0x38 */
|
| - EncodeOp0F(0x30, 0, IMM_NONE, NACLi_RDMSR, "wrmsr");
|
| - EncodeOp0F(0x31, 0, IMM_NONE, NACLi_RDTSC, "rdtsc");
|
| - EncodeOp0F(0x32, 0, IMM_NONE, NACLi_RDMSR, "rdmsr");
|
| - EncodeOp0F(0x33, 0, IMM_NONE, NACLi_SYSTEM, "rdpmc");
|
| - EncodeOp0F(0x34, 0, IMM_NONE, NACLi_SYSENTER, "sysenter");
|
| - EncodeOp0F(0x35, 0, IMM_NONE, NACLi_SYSENTER, "sysexit");
|
| - TODO(karl, "should this be added?");
|
| - EncodeOp0F(0x37, 0, IMM_NONE, NACLi_ILLEGAL, "getsec");
|
| - EncodeOp0F(0x38, 1, IMM_NONE, NACLi_3BYTE, "SSSE3, SSE4");
|
| - EncodeOp0F(0x3a, 1, IMM_FIXED1, NACLi_3BYTE, "SSSE3, SSE4");
|
| -
|
| - /* 0x40-0x48 */
|
| - EncodeOp0F(0x40, 1, IMM_NONE, NACLi_CMOV, "cmovo $Gv, $Ev");
|
| - EncodeOp0F(0x41, 1, IMM_NONE, NACLi_CMOV, "cmovno $Gv, $Ev");
|
| - EncodeOp0F(0x42, 1, IMM_NONE, NACLi_CMOV, "cmovb $Gv, $Ev");
|
| - EncodeOp0F(0x43, 1, IMM_NONE, NACLi_CMOV, "cmovnb $Gv, $Ev");
|
| - EncodeOp0F(0x44, 1, IMM_NONE, NACLi_CMOV, "cmovz $Gv, $Ev");
|
| - EncodeOp0F(0x45, 1, IMM_NONE, NACLi_CMOV, "cmovnz $Gv, $Ev");
|
| - EncodeOp0F(0x46, 1, IMM_NONE, NACLi_CMOV, "cmovbe $Gv, $Ev");
|
| - EncodeOp0F(0x47, 1, IMM_NONE, NACLi_CMOV, "cmovnbe $Gv, $Ev");
|
| - EncodeOp0F(0x48, 1, IMM_NONE, NACLi_CMOV, "cmovs $Gv, $Ev");
|
| - EncodeOp0F(0x49, 1, IMM_NONE, NACLi_CMOV, "cmovns $Gv, $Ev");
|
| - EncodeOp0F(0x4a, 1, IMM_NONE, NACLi_CMOV, "cmovp $Gv, $Ev");
|
| - EncodeOp0F(0x4b, 1, IMM_NONE, NACLi_CMOV, "cmovnp $Gv, $Ev");
|
| - EncodeOp0F(0x4c, 1, IMM_NONE, NACLi_CMOV, "cmovl $Gv, $Ev");
|
| - EncodeOp0F(0x4d, 1, IMM_NONE, NACLi_CMOV, "cmovnl $Gv, $Ev");
|
| - EncodeOp0F(0x4e, 1, IMM_NONE, NACLi_CMOV, "cmovle $Gv, $Ev");
|
| - EncodeOp0F(0x4f, 1, IMM_NONE, NACLi_CMOV, "cmovnle $Gv, $Ev");
|
| -
|
| - /* repeat for 0x66 prefix */
|
| - EncodeOp660F(0x40, 1, IMM_NONE, NACLi_CMOV, "cmovo $Gv, $Ev");
|
| - EncodeOp660F(0x41, 1, IMM_NONE, NACLi_CMOV, "cmovno $Gv, $Ev");
|
| - EncodeOp660F(0x42, 1, IMM_NONE, NACLi_CMOV, "cmovb $Gv, $Ev");
|
| - EncodeOp660F(0x43, 1, IMM_NONE, NACLi_CMOV, "cmovnb $Gv, $Ev");
|
| - EncodeOp660F(0x44, 1, IMM_NONE, NACLi_CMOV, "cmovz $Gv, $Ev");
|
| - EncodeOp660F(0x45, 1, IMM_NONE, NACLi_CMOV, "cmovnz $Gv, $Ev");
|
| - EncodeOp660F(0x46, 1, IMM_NONE, NACLi_CMOV, "cmovbe $Gv, $Ev");
|
| - EncodeOp660F(0x47, 1, IMM_NONE, NACLi_CMOV, "cmovnbe $Gv, $Ev");
|
| - EncodeOp660F(0x48, 1, IMM_NONE, NACLi_CMOV, "cmovs $Gv, $Ev");
|
| - EncodeOp660F(0x49, 1, IMM_NONE, NACLi_CMOV, "cmovns $Gv, $Ev");
|
| - EncodeOp660F(0x4a, 1, IMM_NONE, NACLi_CMOV, "cmovp $Gv, $Ev");
|
| - EncodeOp660F(0x4b, 1, IMM_NONE, NACLi_CMOV, "cmovnp $Gv, $Ev");
|
| - EncodeOp660F(0x4c, 1, IMM_NONE, NACLi_CMOV, "cmovl $Gv, $Ev");
|
| - EncodeOp660F(0x4d, 1, IMM_NONE, NACLi_CMOV, "cmovnl $Gv, $Ev");
|
| - EncodeOp660F(0x4e, 1, IMM_NONE, NACLi_CMOV, "cmovle $Gv, $Ev");
|
| - EncodeOp660F(0x4f, 1, IMM_NONE, NACLi_CMOV, "cmovnle $Gv, $Ev");
|
| -
|
| - /* 0x80-0x8f */
|
| - EncodeOp0F(0x80, 0, IMM_DATAV, NACLi_JMPZ, "jo $Jz");
|
| - SetOp0FForceSize64(0x80);
|
| - EncodeOp0F(0x81, 0, IMM_DATAV, NACLi_JMPZ, "jno $Jz");
|
| - SetOp0FForceSize64(0x81);
|
| - EncodeOp0F(0x82, 0, IMM_DATAV, NACLi_JMPZ, "jb $Jz");
|
| - SetOp0FForceSize64(0x82);
|
| - EncodeOp0F(0x83, 0, IMM_DATAV, NACLi_JMPZ, "jnb $Jz");
|
| - SetOp0FForceSize64(0x83);
|
| - EncodeOp0F(0x84, 0, IMM_DATAV, NACLi_JMPZ, "jz $Jz");
|
| - SetOp0FForceSize64(0x84);
|
| - EncodeOp0F(0x85, 0, IMM_DATAV, NACLi_JMPZ, "jnz $Jz");
|
| - SetOp0FForceSize64(0x85);
|
| - EncodeOp0F(0x86, 0, IMM_DATAV, NACLi_JMPZ, "jbe $Jz");
|
| - SetOp0FForceSize64(0x86);
|
| - EncodeOp0F(0x87, 0, IMM_DATAV, NACLi_JMPZ, "jnbe $Jz");
|
| - SetOp0FForceSize64(0x87);
|
| - EncodeOp0F(0x88, 0, IMM_DATAV, NACLi_JMPZ, "js $Jz");
|
| - SetOp0FForceSize64(0x88);
|
| - EncodeOp0F(0x89, 0, IMM_DATAV, NACLi_JMPZ, "jns $Jz");
|
| - SetOp0FForceSize64(0x89);
|
| - EncodeOp0F(0x8a, 0, IMM_DATAV, NACLi_JMPZ, "jp $Jz");
|
| - SetOp0FForceSize64(0x8a);
|
| - EncodeOp0F(0x8b, 0, IMM_DATAV, NACLi_JMPZ, "jnp $Jz");
|
| - SetOp0FForceSize64(0x8b);
|
| - EncodeOp0F(0x8c, 0, IMM_DATAV, NACLi_JMPZ, "jl $Jz");
|
| - SetOp0FForceSize64(0x8c);
|
| - EncodeOp0F(0x8d, 0, IMM_DATAV, NACLi_JMPZ, "jge $Jz");
|
| - SetOp0FForceSize64(0x8d);
|
| - EncodeOp0F(0x8e, 0, IMM_DATAV, NACLi_JMPZ, "jle $Jz");
|
| - SetOp0FForceSize64(0x8e);
|
| - EncodeOp0F(0x8f, 0, IMM_DATAV, NACLi_JMPZ, "jg $Jz");
|
| - SetOp0FForceSize64(0x8f);
|
| -
|
| - /* 0x90-0x9f */
|
| - EncodeOp0F(0x90, 1, IMM_NONE, NACLi_386, "seto $Eb");
|
| - EncodeOp0F(0x91, 1, IMM_NONE, NACLi_386, "setno $Eb");
|
| - EncodeOp0F(0x92, 1, IMM_NONE, NACLi_386, "setb $Eb");
|
| - EncodeOp0F(0x93, 1, IMM_NONE, NACLi_386, "setnb $Eb");
|
| - EncodeOp0F(0x94, 1, IMM_NONE, NACLi_386, "setz $Eb");
|
| - EncodeOp0F(0x95, 1, IMM_NONE, NACLi_386, "setnz $Eb");
|
| - EncodeOp0F(0x96, 1, IMM_NONE, NACLi_386, "setbe $Eb");
|
| - EncodeOp0F(0x97, 1, IMM_NONE, NACLi_386, "setnbe $Eb");
|
| - EncodeOp0F(0x98, 1, IMM_NONE, NACLi_386, "sets $Eb");
|
| - EncodeOp0F(0x99, 1, IMM_NONE, NACLi_386, "setns $Eb");
|
| - EncodeOp0F(0x9a, 1, IMM_NONE, NACLi_386, "setp $Eb");
|
| - EncodeOp0F(0x9b, 1, IMM_NONE, NACLi_386, "setnp $Eb");
|
| - EncodeOp0F(0x9c, 1, IMM_NONE, NACLi_386, "setl $Eb");
|
| - EncodeOp0F(0x9d, 1, IMM_NONE, NACLi_386, "setge $Eb");
|
| - EncodeOp0F(0x9e, 1, IMM_NONE, NACLi_386, "setle $Eb");
|
| - EncodeOp0F(0x9f, 1, IMM_NONE, NACLi_386, "setg $Eb");
|
| -
|
| - /* 0xa0-0xaf */
|
| - EncodeOp0F(0xa0, 0, IMM_NONE, NACLi_ILLEGAL, "push %fs");
|
| - SetOp0FDefaultSize64(0xa0);
|
| - EncodeOp0F(0xa1, 0, IMM_NONE, NACLi_ILLEGAL, "pop %fs");
|
| - SetOp0FDefaultSize64(0xa1);
|
| - EncodeOp0F(0xa2, 0, IMM_NONE, NACLi_386, "cpuid");
|
| - EncodeOp0F(0xa3, 1, IMM_NONE, NACLi_ILLEGAL, "bt $Ev, $Gv");
|
| -
|
| - /* ISE reviewers suggested omitting shld */
|
| - EncodeOp0F(0xa4, 1, IMM_FIXED1, NACLi_386, "shld $Ev, $Gv, $Ib");
|
| - EncodeOp0F(0xa5, 1, IMM_NONE, NACLi_386, "shld $Ev, $Gv, %cl");
|
| - EncodeOp0F(0xa6, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp0F(0xa7, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp0F(0xa8, 0, IMM_NONE, NACLi_ILLEGAL, "push %gs");
|
| - SetOp0FDefaultSize64(0xa8);
|
| - EncodeOp0F(0xa9, 0, IMM_NONE, NACLi_ILLEGAL, "pop %gs");
|
| - SetOp0FDefaultSize64(0xa9);
|
| - EncodeOp0F(0xaa, 0, IMM_NONE, NACLi_SYSTEM, "rsm");
|
| - EncodeOp0F(0xab, 1, IMM_NONE, NACLi_ILLEGAL, "bts $Ev, $Gv");
|
| -
|
| - /* ISE reviewers suggested omitting shrd */
|
| - EncodeOp0F(0xac, 1, IMM_FIXED1, NACLi_386, "shrd $Ev, $Gv, $Ib");
|
| - EncodeOp0F(0xad, 1, IMM_NONE, NACLi_386, "shrd $Ev, $Gv, %cl");
|
| -
|
| - /* fxsave fxrstor ldmxcsr stmxcsr clflush */
|
| - /* lfence mfence sfence */
|
| - /* Note: size of memory operand varies with MRM. */
|
| - EncodeOp0F(0xae, 1, IMM_NONE, NACLi_OPINMRM, "$group15 $M");
|
| - SetOp0FOpInMRM(0xae, GROUP15);
|
| - EncodeOp0F(0xaf, 1, IMM_NONE, NACLi_386, "imul $Gv, $Ev");
|
| - EncodeOp660F(0xaf, 1, IMM_NONE, NACLi_386, "imul $Gv, $Ev");
|
| -
|
| - /* 0xb0-0xbf */
|
| - /* Note NaCl doesn't allow 16-bit cmpxchg */
|
| - EncodeOp0F(0xb0, 1, IMM_NONE, NACLi_386L, "cmpxchg $E, $G");
|
| - EncodeOp0F(0xb1, 1, IMM_NONE, NACLi_386L, "cmpxchg $E, $G");
|
| - EncodeOp0F(0xb2, 1, IMM_NONE, NACLi_ILLEGAL, "lss $Mp");
|
| - EncodeOp0F(0xb3, 1, IMM_NONE, NACLi_ILLEGAL, "btr $Ev, $Gv");
|
| - EncodeOp0F(0xb4, 1, IMM_NONE, NACLi_ILLEGAL, "lfs $Mp");
|
| - EncodeOp0F(0xb5, 1, IMM_NONE, NACLi_ILLEGAL, "lgs $Mp");
|
| - EncodeOp0F(0xb6, 1, IMM_NONE, NACLi_386, "movzx $Gv, $Eb");
|
| - EncodeOp660F(0xb6, 1, IMM_NONE, NACLi_386, "movzx $Gv, $Eb");
|
| - EncodeOp0F(0xb7, 1, IMM_NONE, NACLi_386, "movzx $Gv, $Ew");
|
| - EncodeOp660F(0xb7, 1, IMM_NONE, NACLi_386, "movzx $Gv, $Ew");
|
| -
|
| - TODO(karl, "Define effect of bswap in 64-bit mode (which can be"
|
| - "up to 4 registers");
|
| - EncodeModedOp0F(0xc8, 0, IMM_NONE, NACLi_386, "bswap %eax", X86_32);
|
| - EncodeModedOp0F(0xc9, 0, IMM_NONE, NACLi_386, "bswap %ecx", X86_32);
|
| - EncodeModedOp0F(0xca, 0, IMM_NONE, NACLi_386, "bswap %edx", X86_32);
|
| - EncodeModedOp0F(0xcb, 0, IMM_NONE, NACLi_386, "bswap %ebx", X86_32);
|
| - EncodeModedOp0F(0xcc, 0, IMM_NONE, NACLi_386, "bswap %esp", X86_32);
|
| - EncodeModedOp0F(0xcd, 0, IMM_NONE, NACLi_386, "bswap %ebp", X86_32);
|
| - EncodeModedOp0F(0xce, 0, IMM_NONE, NACLi_386, "bswap %esi", X86_32);
|
| - EncodeModedOp0F(0xcf, 0, IMM_NONE, NACLi_386, "bswap %edi", X86_32);
|
| -
|
| - /* Instructions from ?? 0F 10 to ?? 0F 1F */
|
| - EncodeOp0F(0x10, 1, IMM_NONE, NACLi_SSE, "movups $Vps, $Wps");
|
| - EncodeOpF30F(0x10, 1, IMM_NONE, NACLi_SSE, "movss $Vss, $Wss");
|
| - EncodeOp660F(0x10, 1, IMM_NONE, NACLi_SSE2, "movupd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x10, 1, IMM_NONE, NACLi_SSE2, "movsd $Vsd, $Wsd");
|
| -
|
| - EncodeOp0F(0x11, 1, IMM_NONE, NACLi_SSE, "movups $Wps, $Vps");
|
| - EncodeOpF30F(0x11, 1, IMM_NONE, NACLi_SSE, "movss $Wss, $Vss");
|
| - EncodeOp660F(0x11, 1, IMM_NONE, NACLi_SSE2, "movupd $Wpd, $Vpd");
|
| - EncodeOpF20F(0x11, 1, IMM_NONE, NACLi_SSE2, "movsd $Wsd, $Vsd");
|
| -
|
| - EncodeOp0F(0x12, 1, IMM_NONE, NACLi_SSE,
|
| - "movlps $Vps, $Mq"); /* or movhlps */
|
| - EncodeOpF30F(0x12, 1, IMM_NONE, NACLi_SSE3, "movsldup $Vps, $Wps");
|
| - EncodeOp660F(0x12, 1, IMM_NONE, NACLi_SSE2, "movlpd $Vps, $Mq");
|
| - EncodeOpF20F(0x12, 1, IMM_NONE, NACLi_SSE3, "movddup $Vpd, $Wsd");
|
| -
|
| - EncodeOp0F(0x13, 1, IMM_NONE, NACLi_SSE, "movlps $Mq, $Vps");
|
| - EncodeOpF30F(0x13, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x13, 1, IMM_NONE, NACLi_SSE2, "movlpd $Mq, $Vsd");
|
| - EncodeOpF20F(0x13, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x14, 1, IMM_NONE, NACLi_SSE, "unpcklps $Vps, $Wq");
|
| - EncodeOpF30F(0x14, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x14, 1, IMM_NONE, NACLi_SSE2, "unpcklpd $Vpd, $Wq");
|
| - EncodeOpF20F(0x14, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x15, 1, IMM_NONE, NACLi_SSE, "unpckhps $Vps, $Wq");
|
| - EncodeOpF30F(0x15, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x15, 1, IMM_NONE, NACLi_SSE2, "unpckhpd $Vpd, $Wq");
|
| - EncodeOpF20F(0x15, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x16, 1, IMM_NONE, NACLi_SSE,
|
| - "movhps $Vps, $Mq"); /* or movlhps */
|
| - EncodeOpF30F(0x16, 1, IMM_NONE, NACLi_SSE3, "movshdup $Vps, $Wps");
|
| - EncodeOp660F(0x16, 1, IMM_NONE, NACLi_SSE2, "movhpd $Vsd, $Mq");
|
| - EncodeOpF20F(0x16, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x17, 1, IMM_NONE, NACLi_SSE, "movhps $Mq, $Vps");
|
| - EncodeOpF30F(0x17, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x17, 1, IMM_NONE, NACLi_SSE2, "movhpd $Mq, $Vpd");
|
| - EncodeOpF20F(0x17, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - /* Instructions from ?? 0F 28 to ?? 0F 2F */
|
| - EncodeOp0F(0x28, 1, IMM_NONE, NACLi_SSE, "movaps $Vps, $Wps");
|
| - EncodeOpF30F(0x28, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x28, 1, IMM_NONE, NACLi_SSE2, "movapd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x28, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x29, 1, IMM_NONE, NACLi_SSE, "movaps $Wps, $Vps");
|
| - EncodeOpF30F(0x29, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x29, 1, IMM_NONE, NACLi_SSE2, "movapd $Wpd, $Vpd");
|
| - EncodeOpF20F(0x29, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x2a, 1, IMM_NONE, NACLi_SSE, "cvtpi2ps $Vps, $Qq");
|
| - EncodeOpF30F(0x2a, 1, IMM_NONE, NACLi_SSE, "cvtsi2ss $Vss, $Ed");
|
| - EncodeOp660F(0x2a, 1, IMM_NONE, NACLi_SSE2, "cvtpi2pd $Vpd $Qq");
|
| - EncodeOpF20F(0x2a, 1, IMM_NONE, NACLi_SSE2, "cvtsi2sd $Vsd, $Ed");
|
| -
|
| - EncodeOp0F(0x2b, 1, IMM_NONE, NACLi_SSE, "movntps $Mdq, $Vps");
|
| - EncodeOpF30F(0x2b, 1, IMM_NONE, NACLi_SSE4A, "movntss $Md, $Vss");
|
| - EncodeOp660F(0x2b, 1, IMM_NONE, NACLi_SSE2, "movntpd $Mdq, $Vpd");
|
| - EncodeOpF20F(0x2b, 1, IMM_NONE, NACLi_SSE4A, "movntsd $Mq, $Vsd");
|
| -
|
| - EncodeOp0F(0x2c, 1, IMM_NONE, NACLi_SSE, "cvttps2pi $Pq, $Wps");
|
| - EncodeOpF30F(0x2c, 1, IMM_NONE, NACLi_SSE, "cvttss2si $Gd, $Wss");
|
| - EncodeOp660F(0x2c, 1, IMM_NONE, NACLi_SSE2, "cvttpd2pi $Pq, $Wpd");
|
| - EncodeOpF20F(0x2c, 1, IMM_NONE, NACLi_SSE2, "cvttsd2si $Gd, $Wsd");
|
| -
|
| - EncodeOp0F(0x2d, 1, IMM_NONE, NACLi_SSE, "cvtps2pi $Pq, $Wps");
|
| - EncodeOpF30F(0x2d, 1, IMM_NONE, NACLi_SSE, "cvtss2si $Gd, $Wss");
|
| - EncodeOp660F(0x2d, 1, IMM_NONE, NACLi_SSE2, "cvtpd2pi $Pq, $Wpd");
|
| - EncodeOpF20F(0x2d, 1, IMM_NONE, NACLi_SSE2, "cvtsd2si $Gd, $Wsd");
|
| -
|
| - EncodeOp0F(0x2e, 1, IMM_NONE, NACLi_SSE, "ucomiss $Vss, $Wss");
|
| - EncodeOpF30F(0x2e, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x2e, 1, IMM_NONE, NACLi_SSE2, "ucomisd $Vps, $Wps");
|
| - EncodeOpF20F(0x2e, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x2f, 1, IMM_NONE, NACLi_SSE, "comiss $Vps, $Wps");
|
| - EncodeOpF30F(0x2f, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x2f, 1, IMM_NONE, NACLi_SSE2, "comisd $Vpd, $Wsd");
|
| - EncodeOpF20F(0x2f, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - /* Others from ?? 0F 39 to ?? 0F 3F are invalid */
|
| -
|
| - /* Instructions from ?? 0F 50 to ?? 0F 7F */
|
| - EncodeOp0F(0x50, 1, IMM_NONE, NACLi_SSE, "movmskps $Gd, $VRps");
|
| - EncodeOpF30F(0x50, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x50, 1, IMM_NONE, NACLi_SSE2, "movmskpd $Gd, $VRpd");
|
| - EncodeOpF20F(0x50, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x51, 1, IMM_NONE, NACLi_SSE, "sqrtps $Vps, $Wps");
|
| - EncodeOpF30F(0x51, 1, IMM_NONE, NACLi_SSE, "sqrtss $Vss, $Wss");
|
| - EncodeOp660F(0x51, 1, IMM_NONE, NACLi_SSE2, "sqrtpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x51, 1, IMM_NONE, NACLi_SSE2, "sqrtsd $Vsd, $Wsd");
|
| -
|
| - EncodeOp0F(0x52, 1, IMM_NONE, NACLi_SSE, "rsqrtps $Vps, $Wps");
|
| - EncodeOpF30F(0x52, 1, IMM_NONE, NACLi_SSE, "rsqrtss $Vss, $Wss");
|
| - EncodeOp660F(0x52, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF20F(0x52, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x53, 1, IMM_NONE, NACLi_SSE, "rcpps $Vps, $Wps");
|
| - EncodeOpF30F(0x53, 1, IMM_NONE, NACLi_SSE, "rcpss $Vss, $Wss");
|
| - EncodeOp660F(0x53, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF20F(0x53, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x54, 1, IMM_NONE, NACLi_SSE, "andps $Vps, $Wps");
|
| - EncodeOpF30F(0x54, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x54, 1, IMM_NONE, NACLi_SSE2, "andpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x54, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x55, 1, IMM_NONE, NACLi_SSE, "andnps $Vps, $Wps");
|
| - EncodeOpF30F(0x55, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x55, 1, IMM_NONE, NACLi_SSE2, "andnpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x55, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x56, 1, IMM_NONE, NACLi_SSE, "orps $Vps, $Wps");
|
| - EncodeOpF30F(0x56, 1, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x56, 1, IMM_NONE, NACLi_SSE2, "orpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x56, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x57, 1, IMM_NONE, NACLi_SSE, "xorps $Vps, $Wps");
|
| - EncodeOpF30F(0x57, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x57, 1, IMM_NONE, NACLi_SSE2, "xorpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x57, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x58, 1, IMM_NONE, NACLi_SSE, "addps $Vps, $Wps");
|
| - EncodeOpF30F(0x58, 1, IMM_NONE, NACLi_SSE, "addss $Vss, $Wss");
|
| - EncodeOp660F(0x58, 1, IMM_NONE, NACLi_SSE2, "addpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x58, 1, IMM_NONE, NACLi_SSE2, "addsd $Vsd, $Wsd");
|
| -
|
| - EncodeOp0F(0x59, 1, IMM_NONE, NACLi_SSE, "mulps $Vps, $Wps");
|
| - EncodeOpF30F(0x59, 1, IMM_NONE, NACLi_SSE, "mulss $Vss, $Wss");
|
| - EncodeOp660F(0x59, 1, IMM_NONE, NACLi_SSE2, "mulpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x59, 1, IMM_NONE, NACLi_SSE2, "mulsd $Vsd, $Wsd");
|
| -
|
| - EncodeOp0F(0x5a, 1, IMM_NONE, NACLi_SSE2, "cvtps2pd $Vpd, $Wps");
|
| - EncodeOpF30F(0x5a, 1, IMM_NONE, NACLi_SSE2, "cvtss2sd $Vsd, $Wss");
|
| - EncodeOp660F(0x5a, 1, IMM_NONE, NACLi_SSE2, "cvtpd2ps $Vps, $Wpd");
|
| - EncodeOpF20F(0x5a, 1, IMM_NONE, NACLi_SSE2, "cvtsd2ss $Vss, $Wsd");
|
| -
|
| - EncodeOp0F(0x5b, 1, IMM_NONE, NACLi_SSE2, "cvtdq2ps $Vps, $Wdq");
|
| - EncodeOpF30F(0x5b, 1, IMM_NONE, NACLi_SSE2, "cvttps2dq $Vdq, $Wps");
|
| - EncodeOp660F(0x5b, 1, IMM_NONE, NACLi_SSE2, "cvtps2dq $Vdq, $Wps");
|
| - EncodeOpF20F(0x5b, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x5c, 1, IMM_NONE, NACLi_SSE, "subps $Vps, $Wps");
|
| - EncodeOpF30F(0x5c, 1, IMM_NONE, NACLi_SSE, "subss $Vss, $Wss");
|
| - EncodeOp660F(0x5c, 1, IMM_NONE, NACLi_SSE2, "subpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x5c, 1, IMM_NONE, NACLi_SSE2, "subsd $Vsd, $Wsd");
|
| -
|
| - EncodeOp0F(0x5d, 1, IMM_NONE, NACLi_SSE, "minps $Vps, $Wps");
|
| - EncodeOpF30F(0x5d, 1, IMM_NONE, NACLi_SSE, "minss $Vss, $Wss");
|
| - EncodeOp660F(0x5d, 1, IMM_NONE, NACLi_SSE2, "minpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x5d, 1, IMM_NONE, NACLi_SSE2, "minsd $Vsd, $Wsd");
|
| -
|
| - EncodeOp0F(0x5e, 1, IMM_NONE, NACLi_SSE, "divps $Vps, $Wps");
|
| - EncodeOpF30F(0x5e, 1, IMM_NONE, NACLi_SSE, "divss $Vss, $Wss");
|
| - EncodeOp660F(0x5e, 1, IMM_NONE, NACLi_SSE2, "divpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x5e, 1, IMM_NONE, NACLi_SSE2, "divsd $Vsd, $Wsd");
|
| -
|
| - EncodeOp0F(0x5f, 1, IMM_NONE, NACLi_SSE, "maxps $Vps, $Wps");
|
| - EncodeOpF30F(0x5f, 1, IMM_NONE, NACLi_SSE, "maxss $Vss, $Wss");
|
| - EncodeOp660F(0x5f, 1, IMM_NONE, NACLi_SSE2, "maxpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x5f, 1, IMM_NONE, NACLi_SSE2, "maxsd $Vsd, $Wsd");
|
| -
|
| - EncodeOp0F(0x60, 1, IMM_NONE, NACLi_MMX, "punpcklbw $Pq, $Qd");
|
| - EncodeOpF30F(0x60, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x60, 1, IMM_NONE, NACLi_SSE2, "punpcklbw $Vdq, $Wq");
|
| - EncodeOpF20F(0x60, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x61, 1, IMM_NONE, NACLi_MMX, "punpcklwd $Pq, $Qd");
|
| - EncodeOpF30F(0x61, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x61, 1, IMM_NONE, NACLi_SSE2, "punpcklwd $Vdq, $Wq");
|
| - EncodeOpF20F(0x61, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x62, 1, IMM_NONE, NACLi_MMX, "punpckldq $Pq, $Qd");
|
| - EncodeOpF30F(0x62, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x62, 1, IMM_NONE, NACLi_SSE2, "punpckldq $Vdq, $Wq");
|
| - EncodeOpF20F(0x62, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x63, 1, IMM_NONE, NACLi_MMX, "packsswb $Pq, $Qq");
|
| - EncodeOpF30F(0x63, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x63, 1, IMM_NONE, NACLi_SSE2, "packsswb $Vdq, $Wdq");
|
| - EncodeOpF20F(0x63, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x64, 1, IMM_NONE, NACLi_MMX, "pcmpgtb $Pq, $Qq");
|
| - EncodeOpF30F(0x64, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x64, 1, IMM_NONE, NACLi_SSE2, "pcmpgtb $Vdq, $Wdq");
|
| - EncodeOpF20F(0x64, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x65, 1, IMM_NONE, NACLi_MMX, "pcmpgtw $Pq, $Qq");
|
| - EncodeOpF30F(0x65, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x65, 1, IMM_NONE, NACLi_SSE2, "pcmpgtw $Vdq, $Wdq");
|
| - EncodeOpF20F(0x65, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x66, 1, IMM_NONE, NACLi_MMX, "pcmpgtd $Pq, $Qq");
|
| - EncodeOpF30F(0x66, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x66, 1, IMM_NONE, NACLi_SSE2, "pcmpgtd $Vdq, $Wdq");
|
| - EncodeOpF20F(0x66, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x67, 1, IMM_NONE, NACLi_MMX, "packuswb $Pq, $Qq");
|
| - EncodeOpF30F(0x67, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x67, 1, IMM_NONE, NACLi_SSE2, "packuswb $Vdq, $Wdq");
|
| - EncodeOpF20F(0x67, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x68, 1, IMM_NONE, NACLi_MMX, "punpckhbw $Pq, $Qd");
|
| - EncodeOpF30F(0x68, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x68, 1, IMM_NONE, NACLi_SSE2, "punpckhbw $Vdq, $Wq");
|
| - EncodeOpF20F(0x68, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x69, 1, IMM_NONE, NACLi_MMX, "punpckhwd $Pq, $Qd");
|
| - EncodeOpF30F(0x69, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x69, 1, IMM_NONE, NACLi_SSE2, "punpckhwd $Vdq, $Wq");
|
| - EncodeOpF20F(0x69, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x6a, 1, IMM_NONE, NACLi_MMX, "punpckhdq $Pq, $Qd");
|
| - EncodeOpF30F(0x6a, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x6a, 1, IMM_NONE, NACLi_SSE2, "punpckhdq $Vdq, $Wq");
|
| - EncodeOpF20F(0x6a, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x6b, 1, IMM_NONE, NACLi_MMX, "packssdw $Pq, $Qq");
|
| - EncodeOpF30F(0x6b, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x6b, 1, IMM_NONE, NACLi_SSE2, "packssdw $Vdq, $Wdq");
|
| - EncodeOpF20F(0x6b, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x6c, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF30F(0x6c, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x6c, 1, IMM_NONE, NACLi_SSE2, "punpcklqdq $Vdq, $Wq");
|
| - EncodeOpF20F(0x6c, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x6d, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF30F(0x6d, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x6d, 1, IMM_NONE, NACLi_SSE2, "punpckhqdq $Vdq, $Wq");
|
| - EncodeOpF20F(0x6d, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x6e, 1, IMM_NONE, NACLi_MMX, "movd $Pq, $Ed");
|
| - EncodeOpF30F(0x6e, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x6e, 1, IMM_NONE, NACLi_SSE2, "movd $Vdq, $Edq");
|
| - EncodeOpF20F(0x6e, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x6f, 1, IMM_NONE, NACLi_MMX, "movq $Pq, $Qq");
|
| - EncodeOpF30F(0x6f, 1, IMM_NONE, NACLi_SSE2, "movdqu $Vdq, $Wdq");
|
| - EncodeOp660F(0x6f, 1, IMM_NONE, NACLi_SSE2, "movdqa $Vdq, $Wdq");
|
| - EncodeOpF20F(0x6f, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x70, 1, IMM_FIXED1, NACLi_SSE, "pshufw $Pq, $Qq, $Ib");
|
| - EncodeOpF30F(0x70, 1, IMM_FIXED1, NACLi_SSE2, "pshufhw $Vq, $Wq, $Ib");
|
| - EncodeOp660F(0x70, 1, IMM_FIXED1, NACLi_SSE2, "pshufd $Vdq, $Wdq, $Ib");
|
| - EncodeOpF20F(0x70, 1, IMM_FIXED1, NACLi_SSE2, "pshuflw $Vq, $Wq, $Ib");
|
| -
|
| - EncodeOp0F(0x71, 1, IMM_FIXED1, NACLi_OPINMRM, "$group12 $PRq, $Ib");
|
| - EncodeOpF30F(0x71, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x71, 1, IMM_FIXED1, NACLi_OPINMRM, "$group12 $VRdq, $Ib");
|
| - EncodeOpF20F(0x71, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - SetOp0FOpInMRM(0x71, GROUP12);
|
| - SetOp66OpInMRM(0x71, GROUP12);
|
| -
|
| - EncodeOp0F(0x72, 1, IMM_FIXED1, NACLi_OPINMRM, "$group13 $PRq, $Ib");
|
| - EncodeOpF30F(0x72, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x72, 1, IMM_FIXED1, NACLi_OPINMRM, "$group13 $VRdq, $Ib");
|
| - EncodeOpF20F(0x72, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - SetOp0FOpInMRM(0x72, GROUP13);
|
| - SetOp66OpInMRM(0x72, GROUP13);
|
| -
|
| - EncodeOp0F(0x73, 1, IMM_FIXED1, NACLi_OPINMRM, "$group14 $PRq, $Ib");
|
| - EncodeOpF30F(0x73, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x73, 1, IMM_FIXED1, NACLi_OPINMRM, "$group14 $VRdq, $Ib");
|
| - EncodeOpF20F(0x73, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - SetOp0FOpInMRM(0x73, GROUP14);
|
| - SetOp66OpInMRM(0x73, GROUP14);
|
| -
|
| - EncodeOp0F(0x74, 1, IMM_NONE, NACLi_MMX, "pcmpeqb $Pq, $Qq");
|
| - EncodeOpF30F(0x74, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x74, 1, IMM_NONE, NACLi_SSE2, "pcmpeqb $Vdq, $Wdq");
|
| - EncodeOpF20F(0x74, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x75, 1, IMM_NONE, NACLi_MMX, "pcmpeqw $Pq, $Qq");
|
| - EncodeOpF30F(0x75, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x75, 1, IMM_NONE, NACLi_SSE2, "pcmpeqw $Vdq, $Wdq");
|
| - EncodeOpF20F(0x75, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x76, 1, IMM_NONE, NACLi_MMX, "pcmpeqd $Pq, $Qq");
|
| - EncodeOpF30F(0x76, 1, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x76, 1, IMM_NONE, NACLi_SSE2, "pcmpeqd $Vdq, $Wdq");
|
| - EncodeOpF20F(0x76, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x77, 0, IMM_NONE, NACLi_MMX, "emms");
|
| - EncodeOpF30F(0x77, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x77, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF20F(0x77, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x78, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF30F(0x78, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x78, 1, IMM_FIXED1, NACLi_OPINMRM, "$group17 $Vdq, $Ib, $Ib");
|
| - SetOp66OpInMRM(0x78, GROUP17);
|
| - EncodeOpF20F(0x78, 1, IMM_FIXED2, NACLi_SSE4A,
|
| - "insertq $Vdq, $VRq, $Ib, $Ib");
|
| -
|
| - EncodeOp0F(0x79, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF30F(0x79, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x79, 1, IMM_NONE, NACLi_SSE4A, "extrq $Vdq, $VRq");
|
| - EncodeOpF20F(0x79, 1, IMM_NONE, NACLi_SSE4A, "insertq $Vdq, $VRdq");
|
| -
|
| - EncodeOp0F(0x7a, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF30F(0x7a, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x7a, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF20F(0x7a, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x7b, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF30F(0x7b, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x7b, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF20F(0x7b, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x7c, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF30F(0x7c, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x7c, 1, IMM_NONE, NACLi_SSE3, "haddpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x7c, 1, IMM_NONE, NACLi_SSE3, "haddps $Vps, $Wps");
|
| -
|
| - EncodeOp0F(0x7d, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF30F(0x7d, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0x7d, 1, IMM_NONE, NACLi_SSE3, "hsubpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0x7d, 1, IMM_NONE, NACLi_SSE3, "hsubps $Vps, $Wps");
|
| -
|
| - EncodeOp0F(0x7e, 1, IMM_NONE, NACLi_MMX, "movd $Ed, $Pd");
|
| - EncodeOpF30F(0x7e, 1, IMM_NONE, NACLi_SSE2, "movq $Vq, $Wq");
|
| - EncodeOp660F(0x7e, 1, IMM_NONE, NACLi_SSE2, "movd $Ed, $Vd");
|
| - EncodeOpF20F(0x7e, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0x7f, 1, IMM_NONE, NACLi_MMX, "movq $Qq, $Pq");
|
| - EncodeOpF30F(0x7f, 1, IMM_NONE, NACLi_SSE2, "movdqu $Wdq, $Vdq");
|
| - EncodeOp660F(0x7f, 1, IMM_NONE, NACLi_SSE2, "movdqa $Wdq, $Vdq");
|
| - EncodeOpF20F(0x7f, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - /* Instructions from ?? 0F b8 to ?? 0F bf */
|
| - EncodeOp0F(0xb8, 0, IMM_NONE, NACLi_INVALID, "reserved");
|
| - EncodeOpF30F(0xb8, 1, IMM_NONE, NACLi_POPCNT, "popcnt");
|
| - EncodeOpF20F(0xb8, 0, IMM_NONE, NACLi_INVALID, "reserved");
|
| -
|
| - EncodeOp0F(0xb9, 1, IMM_NONE, NACLi_OPINMRM, "$group10");
|
| - EncodeOpF30F(0xb9, 0, IMM_NONE, NACLi_INVALID, "reserved");
|
| - EncodeOpF20F(0xb9, 0, IMM_NONE, NACLi_INVALID, "reserved");
|
| -
|
| - EncodeOp0F(0xba, 1, IMM_FIXED1, NACLi_OPINMRM, "$group8 $Ev, $Ib");
|
| - EncodeOpF30F(0xba, 0, IMM_FIXED1, NACLi_INVALID, "reserved");
|
| - EncodeOpF20F(0xba, 0, IMM_NONE, NACLi_INVALID, "reserved");
|
| - SetOp0FOpInMRM(0xba, GROUP8);
|
| -
|
| - EncodeOp0F(0xbb, 1, IMM_NONE, NACLi_ILLEGAL, "btc $Ev, $Gv");
|
| - EncodeOpF30F(0xbb, 0, IMM_NONE, NACLi_INVALID, "reserved");
|
| - EncodeOpF20F(0xbb, 0, IMM_NONE, NACLi_INVALID, "reserved");
|
| -
|
| - EncodeOp0F(0xbc, 1, IMM_NONE, NACLi_386, "bsf $Gv, $Ev");
|
| - /* tzcnt is treated as a bsf on machines that don't have tzcnt.
|
| - * Hence, even though its conditional on NACLi_LZCNT, we act
|
| - * like it can be used on all processors.
|
| - */
|
| - EncodeOpF30F(0xbc, 1, IMM_NONE, NACLi_386, "tzcnt $Gv, $Ev");
|
| - EncodeOpF20F(0xbc, 0, IMM_NONE, NACLi_INVALID, "reserved");
|
| -
|
| - EncodeOp0F(0xbd, 1, IMM_NONE, NACLi_386, "bsr $Gv, $Ev");
|
| - /* lzcnt is treated as a bsr on machines that don't have lzcnt.
|
| - * Hence, even though its conditional on NACLi_LZCNT, we act
|
| - * like it can be used on all processors.
|
| - */
|
| - EncodeOpF30F(0xbd, 1, IMM_NONE, NACLi_386, "lzcnt $Gv, $Ev");
|
| - EncodeOpF20F(0xbd, 0, IMM_NONE, NACLi_INVALID, "reserved");
|
| -
|
| - EncodeOp0F(0xbe, 1, IMM_NONE, NACLi_386, "movsx $Gv, $Eb");
|
| - EncodeOp660F(0xbe, 1, IMM_NONE, NACLi_386, "movsx $Gv, $Eb");
|
| - EncodeOpF30F(0xbe, 1, IMM_NONE, NACLi_INVALID, "reserved");
|
| - EncodeOpF20F(0xbe, 1, IMM_NONE, NACLi_INVALID, "reserved");
|
| -
|
| - EncodeOp0F(0xbf, 1, IMM_NONE, NACLi_386, "movsx $Gv, $Ew");
|
| - EncodeOp660F(0xbf, 1, IMM_NONE, NACLi_386, "movsx $Gv, $Ew");
|
| - EncodeOpF30F(0xbf, 0, IMM_NONE, NACLi_INVALID, "reserved");
|
| - EncodeOpF20F(0xbf, 0, IMM_NONE, NACLi_INVALID, "reserved");
|
| -
|
| - /* Instructions from ?? 0F C0 to ?? 0F FF */
|
| - /* xadd and cmpxchg appear to be the only instructions designed */
|
| - /* for use with multiple prefix bytes. We may need to create */
|
| - /* a special case for this if somebody actually needs it. */
|
| - EncodeOp0F(0xc0, 1, IMM_NONE, NACLi_386L, "xadd $E, $G");
|
| - EncodeOp0F(0xc1, 1, IMM_NONE, NACLi_386L, "xadd $E, $G");
|
| -
|
| - EncodeOp0F(0xc2, 1, IMM_FIXED1, NACLi_SSE, "cmpps $V, $W, $I");
|
| - EncodeOpF30F(0xc2, 1, IMM_FIXED1, NACLi_SSE, "cmpss $V, $W, $I");
|
| - EncodeOp660F(0xc2, 1, IMM_FIXED1, NACLi_SSE2, "cmppd $V, $W, $I");
|
| - EncodeOpF20F(0xc2, 1, IMM_FIXED1, NACLi_SSE2, "cmpsd $V, $W, $I");
|
| -
|
| - EncodeOp0F(0xc3, 1, IMM_NONE, NACLi_SSE2, "movnti $Md, $Gd");
|
| - EncodeOpF30F(0xc3, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xc3, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF20F(0xc3, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xc4, 1, IMM_FIXED1, NACLi_SSE, "pinsrw $Pq, $Ew, $Ib");
|
| - EncodeOpF30F(0xc4, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xc4, 1, IMM_FIXED1, NACLi_SSE2, "pinsrw $Vdq, $Ew, $Ib");
|
| - EncodeOpF20F(0xc4, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xc5, 1, IMM_FIXED1, NACLi_SSE, "pextrw $Gd, $PRq, $Ib");
|
| - EncodeOpF30F(0xc5, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xc5, 1, IMM_FIXED1, NACLi_SSE2, "pextrw $Gd, $VRdq, $Ib");
|
| - EncodeOpF20F(0xc5, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xc6, 1, IMM_FIXED1, NACLi_SSE, "shufps $Vps, $Wps, $Ib");
|
| - EncodeOpF30F(0xc6, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xc6, 1, IMM_FIXED1, NACLi_SSE2, "shufpd $Vpd, $Wpd, $Ib");
|
| - EncodeOpF20F(0xc6, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xc7, 1, IMM_NONE, NACLi_OPINMRM, "$group9 $Mq");
|
| - SetOp0FOpInMRM(0xc7, GROUP9);
|
| -
|
| - EncodeOp0F(0xd0, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF30F(0xd0, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xd0, 1, IMM_NONE, NACLi_SSE3, "addsubpd $Vpd, $Wpd");
|
| - EncodeOpF20F(0xd0, 1, IMM_NONE, NACLi_SSE3, "addsubps $Vps, $Wps");
|
| -
|
| - EncodeOp0F(0xd1, 1, IMM_NONE, NACLi_MMX, "psrlw $Pq, $Qq");
|
| - EncodeOpF30F(0xd1, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xd1, 1, IMM_NONE, NACLi_SSE2, "psrlw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xd1, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xd2, 1, IMM_NONE, NACLi_MMX, "psrld $Pq, $Qq");
|
| - EncodeOpF30F(0xd2, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xd2, 1, IMM_NONE, NACLi_SSE2, "psrld $Vdq, $Wdq");
|
| - EncodeOpF20F(0xd2, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xd3, 1, IMM_NONE, NACLi_MMX, "psrlq $Pq, $Qq");
|
| - EncodeOpF30F(0xd3, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xd3, 1, IMM_NONE, NACLi_SSE2, "psrlq $Vdq, $Wdq");
|
| - EncodeOpF20F(0xd3, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xd4, 1, IMM_NONE, NACLi_SSE2, "paddq $Pq, $Qq");
|
| - EncodeOpF30F(0xd4, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xd4, 1, IMM_NONE, NACLi_SSE2, "paddq $Vdq, $Wdq");
|
| - EncodeOpF20F(0xd4, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xd5, 1, IMM_NONE, NACLi_MMX, "pmullw $Pq, $Qq");
|
| - EncodeOpF30F(0xd5, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xd5, 1, IMM_NONE, NACLi_SSE2, "pmullw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xd5, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xd6, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF30F(0xd6, 1, IMM_NONE, NACLi_SSE2, "movq2dq $Vdq, $PRq");
|
| - EncodeOp660F(0xd6, 1, IMM_NONE, NACLi_SSE2, "movq $Wq, $Vq");
|
| - EncodeOpF20F(0xd6, 1, IMM_NONE, NACLi_SSE2, "movdq2q $Pq, $VRq");
|
| -
|
| - EncodeOp0F(0xd7, 1, IMM_NONE, NACLi_SSE, "pmovmskb $Gd, $PRq");
|
| - EncodeOpF30F(0xd7, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xd7, 1, IMM_NONE, NACLi_SSE2, "pmovmskb $Gd, $VRdq");
|
| - EncodeOpF20F(0xd7, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xd8, 1, IMM_NONE, NACLi_MMX, "psubusb $Pq, $Qq");
|
| - EncodeOpF30F(0xd8, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xd8, 1, IMM_NONE, NACLi_SSE2, "psubusb $Vdq, $Wdq");
|
| - EncodeOpF20F(0xd8, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xd9, 1, IMM_NONE, NACLi_MMX, "psubusw $Pq, $Qq");
|
| - EncodeOpF30F(0xd9, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xd9, 1, IMM_NONE, NACLi_SSE2, "psubusw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xd9, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xda, 1, IMM_NONE, NACLi_SSE, "pminub $Pq, $Qq");
|
| - EncodeOpF30F(0xda, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xda, 1, IMM_NONE, NACLi_SSE2, "pminub $Vdq, $Wdq");
|
| - EncodeOpF20F(0xda, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xdb, 1, IMM_NONE, NACLi_MMX, "pand $Pq, $Qq");
|
| - EncodeOpF30F(0xdb, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xdb, 1, IMM_NONE, NACLi_SSE2, "pand $Vdq, $Wdq");
|
| - EncodeOpF20F(0xdb, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xdc, 1, IMM_NONE, NACLi_MMX, "paddusb $Pq, $Qq");
|
| - EncodeOpF30F(0xdc, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xdc, 1, IMM_NONE, NACLi_SSE2, "paddusb $Vdq, $Wdq");
|
| - EncodeOpF20F(0xdc, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xdd, 1, IMM_NONE, NACLi_MMX, "paddusw $Pq, $Qq");
|
| - EncodeOpF30F(0xdd, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xdd, 1, IMM_NONE, NACLi_SSE2, "paddusw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xdd, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xde, 1, IMM_NONE, NACLi_SSE, "pmaxub $Pq, $Qq");
|
| - EncodeOpF30F(0xde, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xde, 1, IMM_NONE, NACLi_SSE2, "pmaxub $Vdq, $Wdq");
|
| - EncodeOpF20F(0xde, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xdf, 1, IMM_NONE, NACLi_MMX, "pandn $Pq, $Qq");
|
| - EncodeOpF30F(0xdf, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xdf, 1, IMM_NONE, NACLi_SSE2, "pandn $Vdq, $Wdq");
|
| - EncodeOpF20F(0xdf, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xe0, 1, IMM_NONE, NACLi_SSE, "pavgb $Pq, $Qq");
|
| - EncodeOpF30F(0xe0, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xe0, 1, IMM_NONE, NACLi_SSE2, "pavgb $Vdq, $Wdq");
|
| - EncodeOpF20F(0xe0, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xe1, 1, IMM_NONE, NACLi_MMX, "psraw $Pq, $Qq");
|
| - EncodeOpF30F(0xe1, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xe1, 1, IMM_NONE, NACLi_SSE2, "psraw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xe1, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xe2, 1, IMM_NONE, NACLi_MMX, "psrad $Pq, $Qq");
|
| - EncodeOpF30F(0xe2, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xe2, 1, IMM_NONE, NACLi_SSE2, "psrad $Vdq, $Wdq");
|
| - EncodeOpF20F(0xe2, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xe3, 1, IMM_NONE, NACLi_SSE, "pavgw $Pq, $Qq");
|
| - EncodeOpF30F(0xe3, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xe3, 1, IMM_NONE, NACLi_SSE2, "pavgw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xe3, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xe4, 1, IMM_NONE, NACLi_SSE, "pmulhuw $Pq, $Qq");
|
| - EncodeOpF30F(0xe4, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xe4, 1, IMM_NONE, NACLi_SSE2, "pmulhuw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xe4, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xe5, 1, IMM_NONE, NACLi_MMX, "pmulhw $Pq, $Qq");
|
| - EncodeOpF30F(0xe5, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xe5, 1, IMM_NONE, NACLi_SSE2, "pmulhw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xe5, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xe6, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF30F(0xe6, 1, IMM_NONE, NACLi_SSE2, "cvtdq2pd $Vpd, $Wq");
|
| - EncodeOp660F(0xe6, 1, IMM_NONE, NACLi_SSE2, "cvttpd2dq $Vq, $Wpd");
|
| - EncodeOpF20F(0xe6, 1, IMM_NONE, NACLi_SSE2, "cvtpd2dq $Vq, $Wpd");
|
| -
|
| - EncodeOp0F(0xe7, 1, IMM_NONE, NACLi_SSE, "movntq $Mq, $Pq");
|
| - EncodeOpF30F(0xe7, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xe7, 1, IMM_NONE, NACLi_SSE2, "movntdq $Mdq, $Vdq");
|
| - EncodeOpF20F(0xe7, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xe8, 1, IMM_NONE, NACLi_MMX, "psubsb $Pq, $Qq");
|
| - EncodeOpF30F(0xe8, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xe8, 1, IMM_NONE, NACLi_SSE2, "psubsb $Vdq, $Wdq");
|
| - EncodeOpF20F(0xe8, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xe9, 1, IMM_NONE, NACLi_MMX, "psubsw $Pq, $Qq");
|
| - EncodeOpF30F(0xe9, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xe9, 1, IMM_NONE, NACLi_SSE2, "psubsw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xe9, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xea, 1, IMM_NONE, NACLi_SSE, "pminsw $Pq, $Qq");
|
| - EncodeOpF30F(0xea, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xea, 1, IMM_NONE, NACLi_SSE2, "pminsw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xea, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xeb, 1, IMM_NONE, NACLi_MMX, "por $Pq, $Qq");
|
| - EncodeOpF30F(0xeb, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xeb, 1, IMM_NONE, NACLi_SSE2, "por $Vdq, $Wdq");
|
| - EncodeOpF20F(0xeb, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xec, 1, IMM_NONE, NACLi_MMX, "paddsb $Pq, $Qq");
|
| - EncodeOpF30F(0xec, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xec, 1, IMM_NONE, NACLi_SSE2, "paddsb $Vdq, $Wdq");
|
| - EncodeOpF20F(0xec, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xed, 1, IMM_NONE, NACLi_MMX, "paddsw $Pq, $Qq");
|
| - EncodeOpF30F(0xed, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xed, 1, IMM_NONE, NACLi_SSE2, "paddsw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xed, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xee, 1, IMM_NONE, NACLi_SSE, "pmaxsw $Pq, $Qq");
|
| - EncodeOpF30F(0xee, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xee, 1, IMM_NONE, NACLi_SSE2, "pmaxsw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xee, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xef, 1, IMM_NONE, NACLi_MMX, "pxor $Pq, $Qq");
|
| - EncodeOpF30F(0xef, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xef, 1, IMM_NONE, NACLi_SSE2, "pxor $Vdq, $Wdq");
|
| - EncodeOpF20F(0xef, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xf0, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF30F(0xf0, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xf0, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF20F(0xf0, 1, IMM_NONE, NACLi_SSE3, "lddqu $Vpd, $Mdq");
|
| -
|
| - EncodeOp0F(0xf1, 1, IMM_NONE, NACLi_MMX, "psllw $Pq, $Qq");
|
| - EncodeOpF30F(0xf1, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xf1, 1, IMM_NONE, NACLi_SSE2, "psllw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xf1, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xf2, 1, IMM_NONE, NACLi_MMX, "pslld $Pq, $Qq");
|
| - EncodeOpF30F(0xf2, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xf2, 1, IMM_NONE, NACLi_SSE2, "pslld $Vdq, $Wdq");
|
| - EncodeOpF20F(0xf2, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xf3, 1, IMM_NONE, NACLi_MMX, "psllq $Pq, $Qq");
|
| - EncodeOpF30F(0xf3, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xf3, 1, IMM_NONE, NACLi_SSE2, "psllq $Vdq, $Wdq");
|
| - EncodeOpF20F(0xf3, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xf4, 1, IMM_NONE, NACLi_SSE2, "pmuludq $Pq, $Qq");
|
| - EncodeOpF30F(0xf4, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xf4, 1, IMM_NONE, NACLi_SSE2, "pmuludq $Vdq, $Wdq");
|
| - EncodeOpF20F(0xf4, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xf5, 1, IMM_NONE, NACLi_MMX, "pmaddwd $Pq, $Qq");
|
| - EncodeOpF30F(0xf5, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xf5, 1, IMM_NONE, NACLi_SSE2, "pmaddwd $Vdq, $Wdq");
|
| - EncodeOpF20F(0xf5, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xf6, 1, IMM_NONE, NACLi_SSE, "psadbw $Pq, $Qq");
|
| - EncodeOpF30F(0xf6, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xf6, 1, IMM_NONE, NACLi_SSE2, "psadbw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xf6, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xf7, 1, IMM_NONE, NACLi_SSE, "maskmovq $Pq, $PRq");
|
| - EncodeOpF30F(0xf7, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xf7, 1, IMM_NONE, NACLi_SSE2, "maskmovdqu $Vdq, $VRdq");
|
| - EncodeOpF20F(0xf7, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xf8, 1, IMM_NONE, NACLi_MMX, "psubb $Pq, $Qq");
|
| - EncodeOpF30F(0xf8, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xf8, 1, IMM_NONE, NACLi_SSE2, "psubb $Vdq, $Wdq");
|
| - EncodeOpF20F(0xf8, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xf9, 1, IMM_NONE, NACLi_MMX, "psubw $Pq, $Qq");
|
| - EncodeOpF30F(0xf9, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xf9, 1, IMM_NONE, NACLi_SSE2, "psubw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xf9, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xfa, 1, IMM_NONE, NACLi_MMX, "psubd $Pq, $Qq");
|
| - EncodeOpF30F(0xfa, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xfa, 1, IMM_NONE, NACLi_SSE2, "psubd $Vdq, $Wdq");
|
| - EncodeOpF20F(0xfa, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - /* Here is an SSE2 instruction that doesn't require 0x66 */
|
| - EncodeOp0F(0xfb, 1, IMM_NONE, NACLi_SSE2, "psubq $Pq, $Qq");
|
| - EncodeOpF30F(0xfb, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xfb, 1, IMM_NONE, NACLi_SSE2, "psubq $Vdq, $Wdq");
|
| - EncodeOpF20F(0xfb, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xfc, 1, IMM_NONE, NACLi_MMX, "paddb $Pq, $Qq");
|
| - EncodeOpF30F(0xfc, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xfc, 1, IMM_NONE, NACLi_SSE2, "paddb $Vdq, $Wdq");
|
| - EncodeOpF20F(0xfc, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xfd, 1, IMM_NONE, NACLi_MMX, "paddw $Pq, $Qq");
|
| - EncodeOpF30F(0xfd, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xfd, 1, IMM_NONE, NACLi_SSE2, "paddw $Vdq, $Wdq");
|
| - EncodeOpF20F(0xfd, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xfe, 1, IMM_NONE, NACLi_MMX, "paddd $Pq, $Qq");
|
| - EncodeOpF30F(0xfe, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xfe, 1, IMM_NONE, NACLi_SSE2, "paddd $Vdq, $Wdq");
|
| - EncodeOpF20F(0xfe, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - EncodeOp0F(0xff, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF30F(0xff, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOp660F(0xff, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| - EncodeOpF20F(0xff, 0, IMM_NONE, NACLi_INVALID, "invalid");
|
| -
|
| - /* three byte opcodes */
|
| - /* 3DNow! */
|
| - TODO(karl, "find corresponding information for 64-bit");
|
| - EncodeOp0F0F(0x90, 1, IMM_NONE, NACLi_3DNOW, "pfcmpge $P, $Q");
|
| - EncodeOp0F0F(0x94, 1, IMM_NONE, NACLi_3DNOW, "pfmin $P, $Q");
|
| - EncodeOp0F0F(0x96, 1, IMM_NONE, NACLi_3DNOW, "pfrcp $P, $Q");
|
| - EncodeOp0F0F(0x97, 1, IMM_NONE, NACLi_3DNOW, "pfrsqrt $P, $Q");
|
| - EncodeOp0F0F(0xa0, 1, IMM_NONE, NACLi_3DNOW, "pfcmpgt $P, $Q");
|
| - EncodeOp0F0F(0xa4, 1, IMM_NONE, NACLi_3DNOW, "pfmax $P, $Q");
|
| - EncodeOp0F0F(0xa6, 1, IMM_NONE, NACLi_3DNOW, "pfrcpit1 $P, $Q");
|
| - EncodeOp0F0F(0xa7, 1, IMM_NONE, NACLi_3DNOW, "pfrsqit1 $P, $Q");
|
| - EncodeOp0F0F(0xb0, 1, IMM_NONE, NACLi_3DNOW, "pfcmpeq $P, $Q");
|
| - EncodeOp0F0F(0xb4, 1, IMM_NONE, NACLi_3DNOW, "pfmul $P, $Q");
|
| - EncodeOp0F0F(0xb6, 1, IMM_NONE, NACLi_3DNOW, "pfrcpit2 $P, $Q");
|
| - EncodeOp0F0F(0xb7, 1, IMM_NONE, NACLi_3DNOW, "pmulhrw $P, $Q");
|
| - EncodeOp0F0F(0x0c, 1, IMM_NONE, NACLi_E3DNOW, "pi2fw $P, $Q");
|
| - EncodeOp0F0F(0x0d, 1, IMM_NONE, NACLi_3DNOW, "pi2fd $P, $Q");
|
| - EncodeOp0F0F(0x1c, 1, IMM_NONE, NACLi_E3DNOW, "pf2iw $P, $Q");
|
| - EncodeOp0F0F(0x1d, 1, IMM_NONE, NACLi_3DNOW, "pf2id $P, $Q");
|
| - EncodeOp0F0F(0x8a, 1, IMM_NONE, NACLi_E3DNOW, "pfnacc $P, $Q");
|
| - EncodeOp0F0F(0x8e, 1, IMM_NONE, NACLi_E3DNOW, "pfpnacc $P, $Q");
|
| - EncodeOp0F0F(0x9a, 1, IMM_NONE, NACLi_3DNOW, "pfsub $P, $Q");
|
| - EncodeOp0F0F(0x9e, 1, IMM_NONE, NACLi_3DNOW, "pfadd $P, $Q");
|
| - EncodeOp0F0F(0xaa, 1, IMM_NONE, NACLi_3DNOW, "pfsubr $P, $Q");
|
| - EncodeOp0F0F(0xae, 1, IMM_NONE, NACLi_3DNOW, "pfacc $P, $Q");
|
| - EncodeOp0F0F(0xbb, 1, IMM_NONE, NACLi_E3DNOW, "pswapd $P, $Q");
|
| - EncodeOp0F0F(0xbf, 1, IMM_NONE, NACLi_3DNOW, "pavgusb $P, $Q");
|
| -
|
| - /* SSSE3 */
|
| - EncodeOp0F38(0x00, 1, IMM_NONE, NACLi_SSSE3, "pshufb $P, $Q");
|
| - EncodeOp0F38(0x01, 1, IMM_NONE, NACLi_SSSE3, "phaddw $P, $Q");
|
| - EncodeOp0F38(0x02, 1, IMM_NONE, NACLi_SSSE3, "phaddd $P, $Q");
|
| - EncodeOp0F38(0x03, 1, IMM_NONE, NACLi_SSSE3, "phaddsw $P, $Q");
|
| - EncodeOp0F38(0x04, 1, IMM_NONE, NACLi_SSSE3, "pmaddubsw $P, $Q");
|
| - EncodeOp0F38(0x05, 1, IMM_NONE, NACLi_SSSE3, "phsubw $P, $Q");
|
| - EncodeOp0F38(0x06, 1, IMM_NONE, NACLi_SSSE3, "phsubd $P, $Q");
|
| - EncodeOp0F38(0x07, 1, IMM_NONE, NACLi_SSSE3, "phsubsw $P, $Q");
|
| - EncodeOp0F38(0x08, 1, IMM_NONE, NACLi_SSSE3, "psignb $P, $Q");
|
| - EncodeOp0F38(0x09, 1, IMM_NONE, NACLi_SSSE3, "psignw $P, $Q");
|
| - EncodeOp0F38(0x0a, 1, IMM_NONE, NACLi_SSSE3, "psignd $P, $Q");
|
| - EncodeOp0F38(0x0b, 1, IMM_NONE, NACLi_SSSE3, "pmulhrsw $P, $Q");
|
| - EncodeOp0F38(0x1c, 1, IMM_NONE, NACLi_SSSE3, "pabsb $P, $Q");
|
| - EncodeOp0F38(0x1d, 1, IMM_NONE, NACLi_SSSE3, "pabsw $P, $Q");
|
| - EncodeOp0F38(0x1e, 1, IMM_NONE, NACLi_SSSE3, "pabsd $P, $Q");
|
| - EncodeOp0F3A(0x0f, 1, IMM_FIXED1, NACLi_SSSE3, "palignr $P, $Q, $Ib");
|
| -
|
| - BuildSSE4Tables();
|
| - Buildx87Tables();
|
| -}
|
| -
|
| -static void PrintHeader(FILE* f, const char* argv0, const char* fname) {
|
| -
|
| - /* Directory neutralize fname, so that it doesn't change depending
|
| - * on who generates the file. Also, don't generate name of who
|
| - * generated it (i.e. argv0), since it is dependent on the
|
| - * build architecture used.
|
| - */
|
| - char* simplified_fname = strstr(fname, "native_client/");
|
| - if (simplified_fname == NULL) fname = (char*) fname;
|
| -
|
| - fprintf(f, "/* %s\n", simplified_fname);
|
| - fprintf(f, " * THIS FILE IS AUTO-GENERATED. DO NOT EDIT.\n");
|
| - fprintf(f, " * Compiled for %s.\n", RunModeName(FLAGS_run_mode));
|
| - fprintf(f, " *\n");
|
| - fprintf(f, " * You must include ncdecode.h before this file.\n");
|
| - fprintf(f, " */\n\n");
|
| -}
|
| -
|
| -/* Print out the contents of the given table for use with ncdecode.c */
|
| -static void PrintDecodeTable(FILE* f,
|
| - OpMetaInfo* gtbl[NCDTABLESIZE],
|
| - const char* gtbl_name) {
|
| - int opc;
|
| - fprintf(f, "static const struct OpInfo %s[NCDTABLESIZE] = {\n", gtbl_name);
|
| - for (opc = 0; opc < NCDTABLESIZE; opc++) {
|
| - OpMetaInfo* opinfo = gtbl[opc];
|
| - fprintf(f, " /* %02x */ { %s, %d, %d, %d },\t/* %s */\n", opc,
|
| - NaClInstTypeString(opinfo->insttype),
|
| - opinfo->mrmbyte,
|
| - opinfo->immtype,
|
| - opinfo->opinmrm,
|
| - opinfo->disfmt);
|
| - }
|
| - fprintf(f, "};\n\n");
|
| -}
|
| -
|
| -/* Print the contents of the (64-bit) decode ops kind table
|
| - * to the specified file. Argument gtbl_size specifies how many
|
| - * elements (out of a max of NCDTABLESIZE) should be printed.
|
| - */
|
| -static void PrintDecodeOpsKindTableBody(FILE* f,
|
| - DecodeOpsKind gtbl[NCDTABLESIZE],
|
| - size_t gtbl_size) {
|
| - size_t opc;
|
| - assert(gtbl_size <= NCDTABLESIZE);
|
| - fprintf(f, " {\n");
|
| - for (opc = 0; opc < gtbl_size; opc++) {
|
| - fprintf(f, " /* %02"NACL_PRIxS" */ %s,\n", opc,
|
| - DecodeOpsKindName(gtbl[opc]));
|
| - };
|
| - fprintf(f, " }");
|
| -}
|
| -
|
| -/* Print out a C definition for the contents of the (64-bit) decode ops kind
|
| - * table to the specified filed.
|
| - */
|
| -static void PrintDecodeOpsKindTable(FILE* f,
|
| - DecodeOpsKind gtbl[NCDTABLESIZE],
|
| - const char* gtbl_name) {
|
| - fprintf(f, "static const DecodeOpsKind %s[NCDTABLESIZE] =", gtbl_name);
|
| - PrintDecodeOpsKindTableBody(f, gtbl, NCDTABLESIZE);
|
| - fprintf(f, ";\n\n");
|
| -}
|
| -
|
| -/* Print out which bytes correspond to prefix bytes. */
|
| -static void PrintPrefixTable(FILE* f) {
|
| - int opc;
|
| - fprintf(f, "static const uint32_t kPrefixTable[NCDTABLESIZE] = {");
|
| - for (opc = 0; opc < NCDTABLESIZE; opc++) {
|
| - if (0 == opc % 16) {
|
| - fprintf(f, "\n /* 0x%02x-0x%02x */\n ", opc, opc + 15);
|
| - }
|
| - fprintf(f, "%s, ", g_PrefixTable[opc]);
|
| - }
|
| - fprintf(f, "\n};\n\n");
|
| -}
|
| -
|
| -static int NCNopTrieSize(NCNopTrieNode* node) {
|
| - if (NULL == node) {
|
| - return 0;
|
| - } else {
|
| - return 1 + NCNopTrieSize(node->success) + NCNopTrieSize(node->fail);
|
| - }
|
| -}
|
| -
|
| -static void PrintNopTrieNode(FILE* f, NCNopTrieNode* node, int index) {
|
| - if (NULL == node) return;
|
| - fprintf(f, " /* %5d */ { 0x%02x, %s, ", index,
|
| - (int) node->matching_byte,
|
| - ((NULL == node->matching_opinfo)
|
| - ? "NULL"
|
| - : "(struct OpInfo*)(&kNopInst)"));
|
| - if (NULL == node->success) {
|
| - fprintf(f, "NULL");
|
| - } else {
|
| - fprintf(f, "(NCNopTrieNode*) (kNcNopTrieNode + %d)", index + 1);
|
| - }
|
| - fprintf(f, ", ");
|
| - if (NULL == node->fail) {
|
| - fprintf(f, "NULL");
|
| - } else {
|
| - fprintf(f, "(NCNopTrieNode*) (kNcNopTrieNode + %d)",
|
| - index + 1 + NCNopTrieSize(node->success));
|
| - }
|
| - fprintf(f, "},\n");
|
| - PrintNopTrieNode(f, node->success, index + 1);
|
| - PrintNopTrieNode(f, node->fail, index + 1 + NCNopTrieSize(node->success));
|
| -}
|
| -
|
| -static void PrintNopTables(FILE* f) {
|
| - if (NULL != nc_nop_root) {
|
| - fprintf(f,
|
| - "static const struct OpInfo kNopInst = { %s, %d, %d, %d };\n\n",
|
| - NaClInstTypeString(nc_nop_info.insttype),
|
| - nc_nop_info.hasmrmbyte,
|
| - nc_nop_info.immtype,
|
| - nc_nop_info.opinmrm);
|
| - }
|
| - fprintf(f, "static const NCNopTrieNode kNcNopTrieNode[] = {\n");
|
| - PrintNopTrieNode(f, nc_nop_root, 0);
|
| - fprintf(f, "};\n\n");
|
| -}
|
| -
|
| -/* Print out the contents of the tables needed by ncdecode.c */
|
| -static void PrintDecodeTables(FILE* f) {
|
| - int group, nnn;
|
| -
|
| - PrintNopTables(f);
|
| -
|
| - fprintf(f, "static const struct OpInfo kDecodeModRMOp[kNaClMRMGroupsRange]");
|
| - fprintf(f, "[kModRMOpcodeGroupSize] = {\n");
|
| - for (group = 0; group < kNaClMRMGroupsRange; group++) {
|
| - fprintf(f, " /* group %d */\n", group);
|
| - fprintf(f, " {\n");
|
| - for (nnn = 0; nnn < kModRMOpcodeGroupSize; nnn++) {
|
| - OpMetaInfo *opinfo = g_ModRMOpTable[group][nnn];
|
| - fprintf(f, " /* %d, %d */ { %s, %d, %d, %d },\t/* %s */\n",
|
| - group, nnn,
|
| - NaClInstTypeString(opinfo->insttype),
|
| - opinfo->mrmbyte,
|
| - opinfo->immtype,
|
| - opinfo->opinmrm,
|
| - opinfo->disfmt);
|
| - }
|
| - fprintf(f, " },\n");
|
| - }
|
| - fprintf(f, "};\n\n");
|
| -
|
| - fprintf(f, "\n/* one byte opcode tables */\n");
|
| - PrintDecodeTable(f, g_Op1ByteTable, "kDecode1ByteOp");
|
| -
|
| - fprintf(f, "\n/* two byte opcode tables */\n");
|
| - PrintDecodeTable(f, g_Op0FXXMetaTable, "kDecode0FXXOp");
|
| - PrintDecodeTable(f, g_Op660FXXTable, "kDecode660FXXOp");
|
| - PrintDecodeTable(f, g_OpF20FXXTable, "kDecodeF20FXXOp");
|
| - PrintDecodeTable(f, g_OpF30FXXTable, "kDecodeF30FXXOp");
|
| -
|
| - fprintf(f, "\n/* three byte opcode tables */\n");
|
| - PrintDecodeTable(f, g_Op0F0FTable, "kDecode0F0FOp");
|
| - PrintDecodeTable(f, g_Op0F38Table, "kDecode0F38Op");
|
| - PrintDecodeTable(f, g_Op0F3ATable, "kDecode0F3AOp");
|
| - PrintDecodeTable(f, g_Op660F38Table, "kDecode660F38Op");
|
| - PrintDecodeTable(f, g_OpF20F38Table, "kDecodeF20F38Op");
|
| - PrintDecodeTable(f, g_Op660F3ATable, "kDecode660F3AOp");
|
| -
|
| - fprintf(f, "\n/* x87 opcode tables*/\n");
|
| - PrintDecodeTable(f, g_Op87D8, "kDecode87D8");
|
| - PrintDecodeTable(f, g_Op87D9, "kDecode87D9");
|
| - PrintDecodeTable(f, g_Op87DA, "kDecode87DA");
|
| - PrintDecodeTable(f, g_Op87DB, "kDecode87DB");
|
| - PrintDecodeTable(f, g_Op87DC, "kDecode87DC");
|
| - PrintDecodeTable(f, g_Op87DD, "kDecode87DD");
|
| - PrintDecodeTable(f, g_Op87DE, "kDecode87DE");
|
| - PrintDecodeTable(f, g_Op87DF, "kDecode87DF");
|
| -
|
| - PrintPrefixTable(f);
|
| -
|
| - if (FLAGS_run_mode == X86_64) {
|
| - /* Print out 64-bit decoding rules for instructions. */
|
| - PrintDecodeOpsKindTable(f, g_OpDecodeOpsKind, "kOpDecodeOpsKind");
|
| - PrintDecodeOpsKindTable(f, g_Op0FDecodeOpsKind, "kOp0FDecodeOpsKind");
|
| -
|
| - /* Now print out 64-bit decoding rules for instruction in
|
| - * the Mod/RM byte, based on the group associated with it.
|
| - */
|
| - fprintf(f, "static const DecodeOpsKind kModRMOpDecodeOpsKind");
|
| - fprintf(f, "[kNaClMRMGroupsRange][kModRMOpcodeGroupSize] = {\n");
|
| - for (group = 0; group < kNaClMRMGroupsRange; group++) {
|
| - fprintf(f, " /* group %d */\n", group);
|
| - PrintDecodeOpsKindTableBody(f, g_ModRMOpDecodeOpsKind[group],
|
| - kModRMOpcodeGroupSize);
|
| - fprintf(f,",\n");
|
| - }
|
| - fprintf(f, "};\n\n");
|
| - }
|
| -}
|
| -
|
| -/* Print out disassembly format for each possible byte value, for the
|
| - * given run mode.
|
| - */
|
| -static void PrintDisasmTable(FILE *f,
|
| - OpMetaInfo* gtbl[NCDTABLESIZE],
|
| - const char* gtbl_name) {
|
| - int opc;
|
| - fprintf(f, "static const char *%s[NCDTABLESIZE] = {\n", gtbl_name);
|
| - for (opc = 0; opc < NCDTABLESIZE; ++opc) {
|
| - fprintf(f, " /* %02x */ \"%s\",\n", opc, gtbl[opc]->disfmt);
|
| - }
|
| - fprintf(f, "};\n\n");
|
| -}
|
| -
|
| -/* Print out the tables to use to disassemble x64 code for the given mode. */
|
| -static void PrintDisasmTables(FILE *f) {
|
| - int group, nnn;
|
| -
|
| - fprintf(f, "static const char *kDisasmModRMOp[]");
|
| - fprintf(f, "[kNaClMRMGroupsRange] = {\n");
|
| - for (group = 0; group < kNaClMRMGroupsRange; group++) {
|
| - fprintf(f, " {");
|
| - for (nnn = 0; nnn < kModRMOpcodeGroupSize; nnn++) {
|
| - fprintf(f, " /* %d %d */ \"%s\",\n", group, nnn,
|
| - g_ModRMOpTable[group][nnn]->disfmt);
|
| - }
|
| - fprintf(f, " },\n");
|
| - }
|
| - fprintf(f, "};\n\n");
|
| -
|
| - fprintf(f, "\n/* one byte opcode tables */\n");
|
| - PrintDisasmTable(f, g_Op1ByteTable, "kDisasm1ByteOp");
|
| -
|
| - fprintf(f, "\n/* two byte opcode tables */\n");
|
| - PrintDisasmTable(f, g_Op0FXXMetaTable, "kDisasm0FXXOp");
|
| - PrintDisasmTable(f, g_Op660FXXTable, "kDisasm660FXXOp");
|
| - PrintDisasmTable(f, g_OpF20FXXTable, "kDisasmF20FXXOp");
|
| - PrintDisasmTable(f, g_OpF30FXXTable, "kDisasmF30FXXOp");
|
| -
|
| - fprintf(f, "\n/* three byte opcode tables */\n");
|
| - PrintDisasmTable(f, g_Op0F0FTable, "kDisasm0F0FOp");
|
| - PrintDisasmTable(f, g_Op0F38Table, "kDisasm0F38Op");
|
| - PrintDisasmTable(f, g_Op660F38Table, "kDisasm660F38Op");
|
| - PrintDisasmTable(f, g_OpF20F38Table, "kDisasmF20F38Op");
|
| - PrintDisasmTable(f, g_Op0F3ATable, "kDisasm0F3AOp");
|
| - PrintDisasmTable(f, g_Op660F3ATable, "kDisasm660F3AOp");
|
| -
|
| - fprintf(f, "\n/* x87 opcode tables*/\n");
|
| - PrintDisasmTable(f, g_Op87D8, "kDisasm87D8");
|
| - PrintDisasmTable(f, g_Op87D9, "kDisasm87D9");
|
| - PrintDisasmTable(f, g_Op87DA, "kDisasm87DA");
|
| - PrintDisasmTable(f, g_Op87DB, "kDisasm87DB");
|
| - PrintDisasmTable(f, g_Op87DC, "kDisasm87DC");
|
| - PrintDisasmTable(f, g_Op87DD, "kDisasm87DD");
|
| - PrintDisasmTable(f, g_Op87DE, "kDisasm87DE");
|
| - PrintDisasmTable(f, g_Op87DF, "kDisasm87DF");
|
| -}
|
| -
|
| -/* Construct the presumptions about what prefixes are allowed by
|
| - * the x86-32 validator.
|
| - *
|
| - * In general, we are quite paranoid about what prefixes can
|
| - * be used and where. For one-byte opcodes, prefixes are restricted
|
| - * based on the NACLi_ type and the masks in
|
| - * BadPrefixMask. For two-byte opcodes, any
|
| - * prefix can be used, but they function more to define the
|
| - * opcode as opposed to modify it; Hence there are separate
|
| - * tables in ncdecodetab.h for the four allowed prefix bytes.
|
| - */
|
| -static void InitBadPrefixMask(uint32_t* BadPrefixMask) {
|
| - int i;
|
| - for (i = 0; i < kNaClInstTypeRange; i++) {
|
| - BadPrefixMask[i] = 0xffffffff; /* all prefixes are bad */
|
| - }
|
| - BadPrefixMask[NACLi_386] = ~(kPrefixDATA16 | kPrefixSEGGS);
|
| - BadPrefixMask[NACLi_386L] = ~(kPrefixDATA16 | kPrefixLOCK);
|
| - BadPrefixMask[NACLi_386R] = ~(kPrefixDATA16 | kPrefixREP);
|
| - BadPrefixMask[NACLi_386RE] = ~(kPrefixDATA16 | kPrefixREP | kPrefixREPNE);
|
| - /* CS and DS prefix bytes are used as branch prediction hints */
|
| - /* and do not affect target address computation. */
|
| - BadPrefixMask[NACLi_JMP8] = ~(kPrefixSEGCS | kPrefixSEGDS);
|
| - BadPrefixMask[NACLi_JMPZ] = ~(kPrefixSEGCS | kPrefixSEGDS);
|
| - BadPrefixMask[NACLi_CMPXCHG8B] = ~kPrefixLOCK;
|
| -}
|
| -
|
| -/* Print out the table of presumptions about what prefixes are allowed
|
| - * by the x86-32 validator.
|
| - */
|
| -static void PrintBadPrefixMask(FILE *f) {
|
| - int i;
|
| - uint32_t BadPrefixMask[kNaClInstTypeRange];
|
| - InitBadPrefixMask(BadPrefixMask);
|
| - fprintf(f, "static uint32_t BadPrefixMask[kNaClInstTypeRange] = {\n");
|
| - for (i = 0; i < kNaClInstTypeRange; ++i) {
|
| - fprintf(f, " 0x%"NACL_PRIx32", /* %s */\n", BadPrefixMask[i],
|
| - NaClInstTypeString(i));
|
| - }
|
| - fprintf(f, "};\n");
|
| -}
|
| -
|
| -FILE* mustopen(const char* fname, const char* how) {
|
| - FILE* f = fopen(fname, how);
|
| - if (f == NULL) {
|
| - fprintf(stderr, "could not fopen(%s, %s)\n", fname, how);
|
| - fprintf(stderr, "exiting now\n");
|
| - exit(-1);
|
| - }
|
| - return f;
|
| -}
|
| -
|
| -/* Recognizes flags in argv, processes them, and then removes them.
|
| - * Returns the updated value for argc.
|
| - */
|
| -int GrokFlags(int argc, const char* argv[]) {
|
| - int i;
|
| - int new_argc;
|
| - if (argc == 0) return 0;
|
| - new_argc = 1;
|
| - for (i = 1; i < argc; ++i) {
|
| - if (0 == strcmp("-m32", argv[i])) {
|
| - FLAGS_run_mode = X86_32;
|
| - } else if (0 == strcmp("-m64", argv[i])) {
|
| - FLAGS_run_mode = X86_64;
|
| - } else {
|
| - argv[new_argc++] = argv[i];
|
| - }
|
| - }
|
| - return new_argc;
|
| -}
|
| -
|
| -int main(const int argc, const char* argv[]) {
|
| - FILE *f;
|
| - int new_argc = GrokFlags(argc, argv);
|
| - if ((new_argc != 4) || (FLAGS_run_mode == RunModeSize)) {
|
| - fprintf(stderr,
|
| - "ERROR: usage: ncdecode_table <architecture flag> "
|
| - "<ncdecodetab.h> <ncdisasmtab.h> <ncbadprefixmask.h>\n");
|
| - return -1;
|
| - }
|
| -
|
| - BuildMetaTables();
|
| -
|
| - f = mustopen(argv[1], "w");
|
| - PrintHeader(f, argv[0], argv[1]);
|
| - PrintDecodeTables(f);
|
| - fclose(f);
|
| -
|
| - f = mustopen(argv[2], "w");
|
| - PrintHeader(f, argv[0], argv[2]);
|
| - PrintDisasmTables(f);
|
| - fclose(f);
|
| -
|
| - f = mustopen(argv[3], "w");
|
| - PrintHeader(f, argv[0], argv[3]);
|
| - PrintBadPrefixMask(f);
|
| - fclose(f);
|
| -
|
| - return 0;
|
| -}
|
|
|