mirror of
https://github.com/capstone-engine/capstone.git
synced 2025-02-08 07:08:13 +00:00
add X86_COMPACT option. also add CS_SUPPORT_X86_COMPACT. made Python support this change
This commit is contained in:
parent
e2bdcf064c
commit
9518148e6f
15
Makefile
15
Makefile
@ -156,11 +156,18 @@ ifneq (,$(findstring systemz,$(CAPSTONE_ARCHS)))
|
||||
endif
|
||||
|
||||
|
||||
# by default, we compile full X86 instruction sets
|
||||
X86_COMPACT =
|
||||
ifneq (,$(findstring yes,$(CAPSTONE_X86_COMPACT)))
|
||||
X86_COMPACT = _compact
|
||||
CFLAGS += -DCAPSTONE_X86_COMPACT
|
||||
endif
|
||||
|
||||
DEP_X86 =
|
||||
DEP_X86 += arch/X86/X86GenAsmWriter.inc
|
||||
DEP_X86 += arch/X86/X86GenAsmWriter1.inc
|
||||
DEP_X86 += arch/X86/X86GenDisassemblerTables.inc
|
||||
DEP_X86 += arch/X86/X86GenInstrInfo.inc
|
||||
DEP_X86 += arch/X86/X86GenAsmWriter$(X86_COMPACT).inc
|
||||
DEP_X86 += arch/X86/X86GenAsmWriter1$(X86_COMPACT).inc
|
||||
DEP_X86 += arch/X86/X86GenDisassemblerTables$(X86_COMPACT).inc
|
||||
DEP_X86 += arch/X86/X86GenInstrInfo$(X86_COMPACT).inc
|
||||
DEP_X86 += arch/X86/X86GenRegisterInfo.inc
|
||||
|
||||
LIBOBJ_X86 =
|
||||
|
@ -69,6 +69,7 @@ static void printi128mem(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
printMemReference(MI, OpNo, O);
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_X86_COMPACT
|
||||
static void printi256mem(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
{
|
||||
SStream_concat(O, "ymmword ptr ");
|
||||
@ -115,6 +116,84 @@ static void printf512mem(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
printMemReference(MI, OpNo, O);
|
||||
}
|
||||
|
||||
static void printSSECC(MCInst *MI, unsigned Op, SStream *OS)
|
||||
{
|
||||
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0xf;
|
||||
switch (Imm) {
|
||||
default: break; // never reach
|
||||
case 0: SStream_concat(OS, "eq"); break;
|
||||
case 1: SStream_concat(OS, "lt"); break;
|
||||
case 2: SStream_concat(OS, "le"); break;
|
||||
case 3: SStream_concat(OS, "unord"); break;
|
||||
case 4: SStream_concat(OS, "neq"); break;
|
||||
case 5: SStream_concat(OS, "nlt"); break;
|
||||
case 6: SStream_concat(OS, "nle"); break;
|
||||
case 7: SStream_concat(OS, "ord"); break;
|
||||
case 8: SStream_concat(OS, "eq_uq"); break;
|
||||
case 9: SStream_concat(OS, "nge"); break;
|
||||
case 0xa: SStream_concat(OS, "ngt"); break;
|
||||
case 0xb: SStream_concat(OS, "false"); break;
|
||||
case 0xc: SStream_concat(OS, "neq_oq"); break;
|
||||
case 0xd: SStream_concat(OS, "ge"); break;
|
||||
case 0xe: SStream_concat(OS, "gt"); break;
|
||||
case 0xf: SStream_concat(OS, "true"); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void printAVXCC(MCInst *MI, unsigned Op, SStream *O)
|
||||
{
|
||||
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x1f;
|
||||
switch (Imm) {
|
||||
default: break;//printf("Invalid avxcc argument!\n"); break;
|
||||
case 0: SStream_concat(O, "eq"); break;
|
||||
case 1: SStream_concat(O, "lt"); break;
|
||||
case 2: SStream_concat(O, "le"); break;
|
||||
case 3: SStream_concat(O, "unord"); break;
|
||||
case 4: SStream_concat(O, "neq"); break;
|
||||
case 5: SStream_concat(O, "nlt"); break;
|
||||
case 6: SStream_concat(O, "nle"); break;
|
||||
case 7: SStream_concat(O, "ord"); break;
|
||||
case 8: SStream_concat(O, "eq_uq"); break;
|
||||
case 9: SStream_concat(O, "nge"); break;
|
||||
case 0xa: SStream_concat(O, "ngt"); break;
|
||||
case 0xb: SStream_concat(O, "false"); break;
|
||||
case 0xc: SStream_concat(O, "neq_oq"); break;
|
||||
case 0xd: SStream_concat(O, "ge"); break;
|
||||
case 0xe: SStream_concat(O, "gt"); break;
|
||||
case 0xf: SStream_concat(O, "true"); break;
|
||||
case 0x10: SStream_concat(O, "eq_os"); break;
|
||||
case 0x11: SStream_concat(O, "lt_oq"); break;
|
||||
case 0x12: SStream_concat(O, "le_oq"); break;
|
||||
case 0x13: SStream_concat(O, "unord_s"); break;
|
||||
case 0x14: SStream_concat(O, "neq_us"); break;
|
||||
case 0x15: SStream_concat(O, "nlt_uq"); break;
|
||||
case 0x16: SStream_concat(O, "nle_uq"); break;
|
||||
case 0x17: SStream_concat(O, "ord_s"); break;
|
||||
case 0x18: SStream_concat(O, "eq_us"); break;
|
||||
case 0x19: SStream_concat(O, "nge_uq"); break;
|
||||
case 0x1a: SStream_concat(O, "ngt_uq"); break;
|
||||
case 0x1b: SStream_concat(O, "false_os"); break;
|
||||
case 0x1c: SStream_concat(O, "neq_os"); break;
|
||||
case 0x1d: SStream_concat(O, "ge_oq"); break;
|
||||
case 0x1e: SStream_concat(O, "gt_oq"); break;
|
||||
case 0x1f: SStream_concat(O, "true_us"); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void printRoundingControl(MCInst *MI, unsigned Op, SStream *O)
|
||||
{
|
||||
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;
|
||||
switch (Imm) {
|
||||
case 0: SStream_concat(O, "{rn-sae}"); break;
|
||||
case 1: SStream_concat(O, "{rd-sae}"); break;
|
||||
case 2: SStream_concat(O, "{ru-sae}"); break;
|
||||
case 3: SStream_concat(O, "{rz-sae}"); break;
|
||||
default: break; // never reach
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)
|
||||
{
|
||||
MCOperand *SegReg;
|
||||
@ -250,82 +329,6 @@ static void printMemOffs64(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
|
||||
static void printRegName(SStream *OS, unsigned RegNo);
|
||||
|
||||
static void printSSECC(MCInst *MI, unsigned Op, SStream *OS)
|
||||
{
|
||||
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0xf;
|
||||
switch (Imm) {
|
||||
default: break; // never reach
|
||||
case 0: SStream_concat(OS, "eq"); break;
|
||||
case 1: SStream_concat(OS, "lt"); break;
|
||||
case 2: SStream_concat(OS, "le"); break;
|
||||
case 3: SStream_concat(OS, "unord"); break;
|
||||
case 4: SStream_concat(OS, "neq"); break;
|
||||
case 5: SStream_concat(OS, "nlt"); break;
|
||||
case 6: SStream_concat(OS, "nle"); break;
|
||||
case 7: SStream_concat(OS, "ord"); break;
|
||||
case 8: SStream_concat(OS, "eq_uq"); break;
|
||||
case 9: SStream_concat(OS, "nge"); break;
|
||||
case 0xa: SStream_concat(OS, "ngt"); break;
|
||||
case 0xb: SStream_concat(OS, "false"); break;
|
||||
case 0xc: SStream_concat(OS, "neq_oq"); break;
|
||||
case 0xd: SStream_concat(OS, "ge"); break;
|
||||
case 0xe: SStream_concat(OS, "gt"); break;
|
||||
case 0xf: SStream_concat(OS, "true"); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void printAVXCC(MCInst *MI, unsigned Op, SStream *O)
|
||||
{
|
||||
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x1f;
|
||||
switch (Imm) {
|
||||
default: break;//printf("Invalid avxcc argument!\n"); break;
|
||||
case 0: SStream_concat(O, "eq"); break;
|
||||
case 1: SStream_concat(O, "lt"); break;
|
||||
case 2: SStream_concat(O, "le"); break;
|
||||
case 3: SStream_concat(O, "unord"); break;
|
||||
case 4: SStream_concat(O, "neq"); break;
|
||||
case 5: SStream_concat(O, "nlt"); break;
|
||||
case 6: SStream_concat(O, "nle"); break;
|
||||
case 7: SStream_concat(O, "ord"); break;
|
||||
case 8: SStream_concat(O, "eq_uq"); break;
|
||||
case 9: SStream_concat(O, "nge"); break;
|
||||
case 0xa: SStream_concat(O, "ngt"); break;
|
||||
case 0xb: SStream_concat(O, "false"); break;
|
||||
case 0xc: SStream_concat(O, "neq_oq"); break;
|
||||
case 0xd: SStream_concat(O, "ge"); break;
|
||||
case 0xe: SStream_concat(O, "gt"); break;
|
||||
case 0xf: SStream_concat(O, "true"); break;
|
||||
case 0x10: SStream_concat(O, "eq_os"); break;
|
||||
case 0x11: SStream_concat(O, "lt_oq"); break;
|
||||
case 0x12: SStream_concat(O, "le_oq"); break;
|
||||
case 0x13: SStream_concat(O, "unord_s"); break;
|
||||
case 0x14: SStream_concat(O, "neq_us"); break;
|
||||
case 0x15: SStream_concat(O, "nlt_uq"); break;
|
||||
case 0x16: SStream_concat(O, "nle_uq"); break;
|
||||
case 0x17: SStream_concat(O, "ord_s"); break;
|
||||
case 0x18: SStream_concat(O, "eq_us"); break;
|
||||
case 0x19: SStream_concat(O, "nge_uq"); break;
|
||||
case 0x1a: SStream_concat(O, "ngt_uq"); break;
|
||||
case 0x1b: SStream_concat(O, "false_os"); break;
|
||||
case 0x1c: SStream_concat(O, "neq_os"); break;
|
||||
case 0x1d: SStream_concat(O, "ge_oq"); break;
|
||||
case 0x1e: SStream_concat(O, "gt_oq"); break;
|
||||
case 0x1f: SStream_concat(O, "true_us"); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void printRoundingControl(MCInst *MI, unsigned Op, SStream *O)
|
||||
{
|
||||
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;
|
||||
switch (Imm) {
|
||||
case 0: SStream_concat(O, "{rn-sae}"); break;
|
||||
case 1: SStream_concat(O, "{rd-sae}"); break;
|
||||
case 2: SStream_concat(O, "{ru-sae}"); break;
|
||||
case 3: SStream_concat(O, "{rz-sae}"); break;
|
||||
default: break; // never reach
|
||||
}
|
||||
}
|
||||
|
||||
/// printPCRelImm - This is used to print an immediate value that ends up
|
||||
/// being encoded as a pc-relative value (e.g. for jumps and calls). These
|
||||
/// print slightly differently than normal immediates. For example, a $ is not
|
||||
@ -479,14 +482,22 @@ static void printMemReference(MCInst *MI, unsigned Op, SStream *O)
|
||||
#include "X86InstPrinter.h"
|
||||
|
||||
#define GET_INSTRINFO_ENUM
|
||||
#ifdef CAPSTONE_X86_COMPACT
|
||||
#include "X86GenInstrInfo_compact.inc"
|
||||
#else
|
||||
#include "X86GenInstrInfo.inc"
|
||||
#endif
|
||||
|
||||
#define GET_REGINFO_ENUM
|
||||
#include "X86GenRegisterInfo.inc"
|
||||
|
||||
// Include the auto-generated portion of the assembly writer.
|
||||
#define PRINT_ALIAS_INSTR
|
||||
#ifdef CAPSTONE_X86_COMPACT
|
||||
#include "X86GenAsmWriter_compact.inc"
|
||||
#else
|
||||
#include "X86GenAsmWriter.inc"
|
||||
#endif
|
||||
|
||||
static void printRegName(SStream *OS, unsigned RegNo)
|
||||
{
|
||||
|
@ -32,7 +32,11 @@
|
||||
#include "X86GenRegisterInfo.inc"
|
||||
|
||||
#define GET_INSTRINFO_ENUM
|
||||
#ifdef CAPSTONE_X86_COMPACT
|
||||
#include "X86GenInstrInfo_compact.inc"
|
||||
#else
|
||||
#include "X86GenInstrInfo.inc"
|
||||
#endif
|
||||
|
||||
struct reader_info {
|
||||
const uint8_t *code;
|
||||
@ -181,15 +185,27 @@ static void translateImmediate(MCInst *mcInst, uint64_t immediate,
|
||||
case ENCODING_IB:
|
||||
// Special case those X86 instructions that use the imm8 as a set of
|
||||
// bits, bit count, etc. and are not sign-extend.
|
||||
if (Opcode != X86_BLENDPSrri && Opcode != X86_BLENDPDrri &&
|
||||
Opcode != X86_PBLENDWrri && Opcode != X86_MPSADBWrri &&
|
||||
Opcode != X86_DPPSrri && Opcode != X86_DPPDrri &&
|
||||
Opcode != X86_INSERTPSrr && Opcode != X86_VBLENDPSYrri &&
|
||||
Opcode != X86_VBLENDPSYrmi && Opcode != X86_VBLENDPDYrri &&
|
||||
Opcode != X86_VBLENDPDYrmi && Opcode != X86_VPBLENDWrri &&
|
||||
Opcode != X86_VMPSADBWrri && Opcode != X86_VDPPSYrri &&
|
||||
Opcode != X86_VDPPSYrmi && Opcode != X86_VDPPDrri &&
|
||||
Opcode != X86_VINSERTPSrr && Opcode != X86_INT)
|
||||
if (
|
||||
#ifndef CAPSTONE_X86_COMPACT
|
||||
Opcode != X86_BLENDPSrri &&
|
||||
Opcode != X86_BLENDPDrri &&
|
||||
Opcode != X86_PBLENDWrri &&
|
||||
Opcode != X86_MPSADBWrri &&
|
||||
Opcode != X86_DPPSrri &&
|
||||
Opcode != X86_DPPDrri &&
|
||||
Opcode != X86_INSERTPSrr &&
|
||||
Opcode != X86_VBLENDPSYrri &&
|
||||
Opcode != X86_VBLENDPSYrmi &&
|
||||
Opcode != X86_VBLENDPDYrri &&
|
||||
Opcode != X86_VBLENDPDYrmi &&
|
||||
Opcode != X86_VPBLENDWrri &&
|
||||
Opcode != X86_VMPSADBWrri &&
|
||||
Opcode != X86_VDPPSYrri &&
|
||||
Opcode != X86_VDPPSYrmi &&
|
||||
Opcode != X86_VDPPDrri &&
|
||||
Opcode != X86_VINSERTPSrr &&
|
||||
#endif
|
||||
Opcode != X86_INT)
|
||||
if(immediate & 0x80)
|
||||
immediate |= ~(0xffull);
|
||||
break;
|
||||
@ -305,6 +321,9 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
|
||||
MCOperand *displacement;
|
||||
MCOperand *segmentReg;
|
||||
bool IndexIs512;
|
||||
#ifndef CAPSTONE_X86_COMPACT
|
||||
uint32_t Opcode;
|
||||
#endif
|
||||
|
||||
if (insn->eaBase == EA_BASE_sib || insn->eaBase == EA_BASE_sib64) {
|
||||
if (insn->sibBase != SIB_BASE_NONE) {
|
||||
@ -328,8 +347,12 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
|
||||
// I don't see a way to get the correct IndexReg in readSIB:
|
||||
// We can tell whether it is VSIB or SIB after instruction ID is decoded,
|
||||
// but instruction ID may not be decoded yet when calling readSIB.
|
||||
uint32_t Opcode = MCInst_getOpcode(mcInst);
|
||||
bool IndexIs128 = (Opcode == X86_VGATHERDPDrm ||
|
||||
#ifndef CAPSTONE_X86_COMPACT
|
||||
Opcode = MCInst_getOpcode(mcInst);
|
||||
#endif
|
||||
bool IndexIs128 = (
|
||||
#ifndef CAPSTONE_X86_COMPACT
|
||||
Opcode == X86_VGATHERDPDrm ||
|
||||
Opcode == X86_VGATHERDPDYrm ||
|
||||
Opcode == X86_VGATHERQPDrm ||
|
||||
Opcode == X86_VGATHERDPSrm ||
|
||||
@ -338,21 +361,34 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
|
||||
Opcode == X86_VPGATHERDQYrm ||
|
||||
Opcode == X86_VPGATHERQQrm ||
|
||||
Opcode == X86_VPGATHERDDrm ||
|
||||
Opcode == X86_VPGATHERQDrm);
|
||||
bool IndexIs256 = (Opcode == X86_VGATHERQPDYrm ||
|
||||
Opcode == X86_VPGATHERQDrm ||
|
||||
#endif
|
||||
false
|
||||
);
|
||||
bool IndexIs256 = (
|
||||
#ifndef CAPSTONE_X86_COMPACT
|
||||
Opcode == X86_VGATHERQPDYrm ||
|
||||
Opcode == X86_VGATHERDPSYrm ||
|
||||
Opcode == X86_VGATHERQPSYrm ||
|
||||
Opcode == X86_VGATHERDPDZrm ||
|
||||
Opcode == X86_VPGATHERDQZrm ||
|
||||
Opcode == X86_VPGATHERQQYrm ||
|
||||
Opcode == X86_VPGATHERDDYrm ||
|
||||
Opcode == X86_VPGATHERQDYrm);
|
||||
IndexIs512 = (Opcode == X86_VGATHERQPDZrm ||
|
||||
Opcode == X86_VPGATHERQDYrm ||
|
||||
#endif
|
||||
false
|
||||
);
|
||||
IndexIs512 = (
|
||||
#ifndef CAPSTONE_X86_COMPACT
|
||||
Opcode == X86_VGATHERQPDZrm ||
|
||||
Opcode == X86_VGATHERDPSZrm ||
|
||||
Opcode == X86_VGATHERQPSZrm ||
|
||||
Opcode == X86_VPGATHERQQZrm ||
|
||||
Opcode == X86_VPGATHERDDZrm ||
|
||||
Opcode == X86_VPGATHERQDZrm);
|
||||
Opcode == X86_VPGATHERQDZrm ||
|
||||
#endif
|
||||
false
|
||||
);
|
||||
|
||||
if (IndexIs128 || IndexIs256 || IndexIs512) {
|
||||
unsigned IndexOffset = insn->sibIndex -
|
||||
@ -612,12 +648,14 @@ static bool translateInstruction(MCInst *mcInst, InternalInstruction *insn)
|
||||
// If when reading the prefix bytes we determined the overlapping 0xf2 or 0xf3
|
||||
// prefix bytes should be disassembled as xrelease and xacquire then set the
|
||||
// opcode to those instead of the rep and repne opcodes.
|
||||
#ifndef CAPSTONE_X86_COMPACT
|
||||
if (insn->xAcquireRelease) {
|
||||
if (MCInst_getOpcode(mcInst) == X86_REP_PREFIX)
|
||||
MCInst_setOpcode(mcInst, X86_XRELEASE_PREFIX);
|
||||
else if (MCInst_getOpcode(mcInst) == X86_REPNE_PREFIX)
|
||||
MCInst_setOpcode(mcInst, X86_XACQUIRE_PREFIX);
|
||||
}
|
||||
#endif
|
||||
|
||||
insn->numImmediatesTranslated = 0;
|
||||
|
||||
|
@ -24,11 +24,19 @@
|
||||
|
||||
#include "X86DisassemblerDecoder.h"
|
||||
|
||||
#ifdef CAPSTONE_X86_COMPACT
|
||||
#include "X86GenDisassemblerTables_compact.inc"
|
||||
#else
|
||||
#include "X86GenDisassemblerTables.inc"
|
||||
#endif
|
||||
|
||||
//#define GET_INSTRINFO_ENUM
|
||||
#define GET_INSTRINFO_MC_DESC
|
||||
#ifdef CAPSTONE_X86_COMPACT
|
||||
#include "X86GenInstrInfo_compact.inc"
|
||||
#else
|
||||
#include "X86GenInstrInfo.inc"
|
||||
#endif
|
||||
|
||||
static const char *x86DisassemblerGetInstrName(unsigned Opcode)
|
||||
{
|
||||
@ -79,6 +87,7 @@ static int modRMRequired(OpcodeType type,
|
||||
uint8_t index;
|
||||
|
||||
switch (type) {
|
||||
default:
|
||||
case ONEBYTE:
|
||||
decision = ONEBYTE_SYM;
|
||||
indextable = index_x86DisassemblerOneByteOpcodes;
|
||||
@ -95,6 +104,7 @@ static int modRMRequired(OpcodeType type,
|
||||
decision = THREEBYTE3A_SYM;
|
||||
indextable = index_x86DisassemblerThreeByte3AOpcodes;
|
||||
break;
|
||||
#ifndef CAPSTONE_X86_COMPACT
|
||||
case XOP8_MAP:
|
||||
decision = XOP8_MAP_SYM;
|
||||
indextable = index_x86DisassemblerXOP8Opcodes;
|
||||
@ -107,6 +117,7 @@ static int modRMRequired(OpcodeType type,
|
||||
decision = XOPA_MAP_SYM;
|
||||
indextable = index_x86DisassemblerXOPAOpcodes;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
index = indextable[insnContext];
|
||||
@ -137,6 +148,7 @@ static InstrUID decode(OpcodeType type,
|
||||
uint8_t index;
|
||||
|
||||
switch (type) {
|
||||
default:
|
||||
case ONEBYTE:
|
||||
indextable = index_x86DisassemblerOneByteOpcodes;
|
||||
index = indextable[insnContext];
|
||||
@ -169,6 +181,7 @@ static InstrUID decode(OpcodeType type,
|
||||
else
|
||||
dec = &emptyTable.modRMDecisions[opcode];
|
||||
break;
|
||||
#ifndef CAPSTONE_X86_COMPACT
|
||||
case XOP8_MAP:
|
||||
indextable = index_x86DisassemblerXOP8Opcodes;
|
||||
index = indextable[insnContext];
|
||||
@ -193,6 +206,7 @@ static InstrUID decode(OpcodeType type,
|
||||
else
|
||||
dec = &emptyTable.modRMDecisions[opcode];
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (dec->modrm_type) {
|
||||
|
2775
arch/X86/X86GenAsmWriter1_compact.inc
Normal file
2775
arch/X86/X86GenAsmWriter1_compact.inc
Normal file
File diff suppressed because it is too large
Load Diff
3021
arch/X86/X86GenAsmWriter_compact.inc
Normal file
3021
arch/X86/X86GenAsmWriter_compact.inc
Normal file
File diff suppressed because it is too large
Load Diff
102781
arch/X86/X86GenDisassemblerTables_compact.inc
Normal file
102781
arch/X86/X86GenDisassemblerTables_compact.inc
Normal file
File diff suppressed because it is too large
Load Diff
3310
arch/X86/X86GenInstrInfo_compact.inc
Normal file
3310
arch/X86/X86GenInstrInfo_compact.inc
Normal file
File diff suppressed because it is too large
Load Diff
@ -67,6 +67,7 @@ static void printi128mem(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
printMemReference(MI, OpNo, O);
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_X86_COMPACT
|
||||
static void printi256mem(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
{
|
||||
SStream_concat(O, "ymmword ptr ");
|
||||
@ -115,6 +116,84 @@ static void printf512mem(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
printMemReference(MI, OpNo, O);
|
||||
}
|
||||
|
||||
static void printSSECC(MCInst *MI, unsigned Op, SStream *OS)
|
||||
{
|
||||
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0xf;
|
||||
switch (Imm) {
|
||||
default: break; // never reach
|
||||
case 0: SStream_concat(OS, "eq"); break;
|
||||
case 1: SStream_concat(OS, "lt"); break;
|
||||
case 2: SStream_concat(OS, "le"); break;
|
||||
case 3: SStream_concat(OS, "unord"); break;
|
||||
case 4: SStream_concat(OS, "neq"); break;
|
||||
case 5: SStream_concat(OS, "nlt"); break;
|
||||
case 6: SStream_concat(OS, "nle"); break;
|
||||
case 7: SStream_concat(OS, "ord"); break;
|
||||
case 8: SStream_concat(OS, "eq_uq"); break;
|
||||
case 9: SStream_concat(OS, "nge"); break;
|
||||
case 0xa: SStream_concat(OS, "ngt"); break;
|
||||
case 0xb: SStream_concat(OS, "false"); break;
|
||||
case 0xc: SStream_concat(OS, "neq_oq"); break;
|
||||
case 0xd: SStream_concat(OS, "ge"); break;
|
||||
case 0xe: SStream_concat(OS, "gt"); break;
|
||||
case 0xf: SStream_concat(OS, "true"); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void printAVXCC(MCInst *MI, unsigned Op, SStream *O)
|
||||
{
|
||||
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x1f;
|
||||
switch (Imm) {
|
||||
default: break;//printf("Invalid avxcc argument!\n"); break;
|
||||
case 0: SStream_concat(O, "eq"); break;
|
||||
case 1: SStream_concat(O, "lt"); break;
|
||||
case 2: SStream_concat(O, "le"); break;
|
||||
case 3: SStream_concat(O, "unord"); break;
|
||||
case 4: SStream_concat(O, "neq"); break;
|
||||
case 5: SStream_concat(O, "nlt"); break;
|
||||
case 6: SStream_concat(O, "nle"); break;
|
||||
case 7: SStream_concat(O, "ord"); break;
|
||||
case 8: SStream_concat(O, "eq_uq"); break;
|
||||
case 9: SStream_concat(O, "nge"); break;
|
||||
case 0xa: SStream_concat(O, "ngt"); break;
|
||||
case 0xb: SStream_concat(O, "false"); break;
|
||||
case 0xc: SStream_concat(O, "neq_oq"); break;
|
||||
case 0xd: SStream_concat(O, "ge"); break;
|
||||
case 0xe: SStream_concat(O, "gt"); break;
|
||||
case 0xf: SStream_concat(O, "true"); break;
|
||||
case 0x10: SStream_concat(O, "eq_os"); break;
|
||||
case 0x11: SStream_concat(O, "lt_oq"); break;
|
||||
case 0x12: SStream_concat(O, "le_oq"); break;
|
||||
case 0x13: SStream_concat(O, "unord_s"); break;
|
||||
case 0x14: SStream_concat(O, "neq_us"); break;
|
||||
case 0x15: SStream_concat(O, "nlt_uq"); break;
|
||||
case 0x16: SStream_concat(O, "nle_uq"); break;
|
||||
case 0x17: SStream_concat(O, "ord_s"); break;
|
||||
case 0x18: SStream_concat(O, "eq_us"); break;
|
||||
case 0x19: SStream_concat(O, "nge_uq"); break;
|
||||
case 0x1a: SStream_concat(O, "ngt_uq"); break;
|
||||
case 0x1b: SStream_concat(O, "false_os"); break;
|
||||
case 0x1c: SStream_concat(O, "neq_os"); break;
|
||||
case 0x1d: SStream_concat(O, "ge_oq"); break;
|
||||
case 0x1e: SStream_concat(O, "gt_oq"); break;
|
||||
case 0x1f: SStream_concat(O, "true_us"); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void printRoundingControl(MCInst *MI, unsigned Op, SStream *O)
|
||||
{
|
||||
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;
|
||||
switch (Imm) {
|
||||
case 0: SStream_concat(O, "{rn-sae}"); break;
|
||||
case 1: SStream_concat(O, "{rd-sae}"); break;
|
||||
case 2: SStream_concat(O, "{ru-sae}"); break;
|
||||
case 3: SStream_concat(O, "{rz-sae}"); break;
|
||||
default: break; // never reach
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)
|
||||
{
|
||||
MCOperand *SegReg;
|
||||
@ -290,82 +369,6 @@ void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info)
|
||||
}
|
||||
}
|
||||
|
||||
static void printSSECC(MCInst *MI, unsigned Op, SStream *OS)
|
||||
{
|
||||
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0xf;
|
||||
switch (Imm) {
|
||||
default: break; // never reach
|
||||
case 0: SStream_concat(OS, "eq"); break;
|
||||
case 1: SStream_concat(OS, "lt"); break;
|
||||
case 2: SStream_concat(OS, "le"); break;
|
||||
case 3: SStream_concat(OS, "unord"); break;
|
||||
case 4: SStream_concat(OS, "neq"); break;
|
||||
case 5: SStream_concat(OS, "nlt"); break;
|
||||
case 6: SStream_concat(OS, "nle"); break;
|
||||
case 7: SStream_concat(OS, "ord"); break;
|
||||
case 8: SStream_concat(OS, "eq_uq"); break;
|
||||
case 9: SStream_concat(OS, "nge"); break;
|
||||
case 0xa: SStream_concat(OS, "ngt"); break;
|
||||
case 0xb: SStream_concat(OS, "false"); break;
|
||||
case 0xc: SStream_concat(OS, "neq_oq"); break;
|
||||
case 0xd: SStream_concat(OS, "ge"); break;
|
||||
case 0xe: SStream_concat(OS, "gt"); break;
|
||||
case 0xf: SStream_concat(OS, "true"); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void printAVXCC(MCInst *MI, unsigned Op, SStream *O)
|
||||
{
|
||||
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x1f;
|
||||
switch (Imm) {
|
||||
default: break;//printf("Invalid avxcc argument!\n"); break;
|
||||
case 0: SStream_concat(O, "eq"); break;
|
||||
case 1: SStream_concat(O, "lt"); break;
|
||||
case 2: SStream_concat(O, "le"); break;
|
||||
case 3: SStream_concat(O, "unord"); break;
|
||||
case 4: SStream_concat(O, "neq"); break;
|
||||
case 5: SStream_concat(O, "nlt"); break;
|
||||
case 6: SStream_concat(O, "nle"); break;
|
||||
case 7: SStream_concat(O, "ord"); break;
|
||||
case 8: SStream_concat(O, "eq_uq"); break;
|
||||
case 9: SStream_concat(O, "nge"); break;
|
||||
case 0xa: SStream_concat(O, "ngt"); break;
|
||||
case 0xb: SStream_concat(O, "false"); break;
|
||||
case 0xc: SStream_concat(O, "neq_oq"); break;
|
||||
case 0xd: SStream_concat(O, "ge"); break;
|
||||
case 0xe: SStream_concat(O, "gt"); break;
|
||||
case 0xf: SStream_concat(O, "true"); break;
|
||||
case 0x10: SStream_concat(O, "eq_os"); break;
|
||||
case 0x11: SStream_concat(O, "lt_oq"); break;
|
||||
case 0x12: SStream_concat(O, "le_oq"); break;
|
||||
case 0x13: SStream_concat(O, "unord_s"); break;
|
||||
case 0x14: SStream_concat(O, "neq_us"); break;
|
||||
case 0x15: SStream_concat(O, "nlt_uq"); break;
|
||||
case 0x16: SStream_concat(O, "nle_uq"); break;
|
||||
case 0x17: SStream_concat(O, "ord_s"); break;
|
||||
case 0x18: SStream_concat(O, "eq_us"); break;
|
||||
case 0x19: SStream_concat(O, "nge_uq"); break;
|
||||
case 0x1a: SStream_concat(O, "ngt_uq"); break;
|
||||
case 0x1b: SStream_concat(O, "false_os"); break;
|
||||
case 0x1c: SStream_concat(O, "neq_os"); break;
|
||||
case 0x1d: SStream_concat(O, "ge_oq"); break;
|
||||
case 0x1e: SStream_concat(O, "gt_oq"); break;
|
||||
case 0x1f: SStream_concat(O, "true_us"); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void printRoundingControl(MCInst *MI, unsigned Op, SStream *O)
|
||||
{
|
||||
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;
|
||||
switch (Imm) {
|
||||
case 0: SStream_concat(O, "{rn-sae}"); break;
|
||||
case 1: SStream_concat(O, "{rd-sae}"); break;
|
||||
case 2: SStream_concat(O, "{ru-sae}"); break;
|
||||
case 3: SStream_concat(O, "{rz-sae}"); break;
|
||||
default: break; // never reach
|
||||
}
|
||||
}
|
||||
|
||||
/// printPCRelImm - This is used to print an immediate value that ends up
|
||||
/// being encoded as a pc-relative value.
|
||||
static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
@ -527,8 +530,16 @@ static void printMemReference(MCInst *MI, unsigned Op, SStream *O) // qqq
|
||||
}
|
||||
|
||||
#define GET_INSTRINFO_ENUM
|
||||
#ifdef CAPSTONE_X86_COMPACT
|
||||
#include "X86GenInstrInfo_compact.inc"
|
||||
#else
|
||||
#include "X86GenInstrInfo.inc"
|
||||
#endif
|
||||
|
||||
#define PRINT_ALIAS_INSTR
|
||||
#ifdef CAPSTONE_X86_COMPACT
|
||||
#include "X86GenAsmWriter1_compact.inc"
|
||||
#else
|
||||
#include "X86GenAsmWriter1.inc"
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -58,6 +58,7 @@ __all__ = [
|
||||
'CS_ERR_DIET',
|
||||
|
||||
'CS_SUPPORT_DIET',
|
||||
'CS_SUPPORT_X86_COMPACT',
|
||||
]
|
||||
|
||||
# Capstone C interface
|
||||
@ -119,6 +120,7 @@ CS_ERR_DIET = 10 # Information irrelevant in diet engine
|
||||
|
||||
# query id for cs_support()
|
||||
CS_SUPPORT_DIET = CS_ARCH_ALL+1
|
||||
CS_SUPPORT_X86_COMPACT = CS_ARCH_ALL+2
|
||||
|
||||
import ctypes, ctypes.util, sys
|
||||
from os.path import split, join, dirname
|
||||
@ -545,6 +547,7 @@ class Cs(object):
|
||||
|
||||
self._detail = False # by default, do not produce instruction details
|
||||
self._diet = cs_support(CS_SUPPORT_DIET)
|
||||
self._x86_compact = cs_support(CS_SUPPORT_X86_COMPACT)
|
||||
|
||||
|
||||
# destructor to be called automatically when object is destroyed.
|
||||
@ -565,6 +568,12 @@ class Cs(object):
|
||||
return self._diet
|
||||
|
||||
|
||||
# is this engine compiled with X86 compact option?
|
||||
@property
|
||||
def x86_compact(self):
|
||||
return self._x86_compact
|
||||
|
||||
|
||||
# return assembly syntax.
|
||||
@property
|
||||
def syntax(self):
|
||||
@ -678,7 +687,7 @@ def debug():
|
||||
|
||||
archs = { "arm": CS_ARCH_ARM, "arm64": CS_ARCH_ARM64, \
|
||||
"mips": CS_ARCH_MIPS, "ppc": CS_ARCH_PPC, "sparc": CS_ARCH_SPARC, \
|
||||
"sysz": CS_ARCH_SYSZ, "x86": CS_ARCH_X86 }
|
||||
"sysz": CS_ARCH_SYSZ }
|
||||
|
||||
all_archs = ""
|
||||
keys = archs.keys()
|
||||
@ -687,6 +696,11 @@ def debug():
|
||||
if cs_support(archs[k]):
|
||||
all_archs += "-%s" %k
|
||||
|
||||
if cs_support(CS_ARCH_X86):
|
||||
all_archs += "-x86"
|
||||
if cs_support(CS_SUPPORT_X86_COMPACT):
|
||||
all_archs += "_compact"
|
||||
|
||||
(major, minor, _combined) = cs_version()
|
||||
|
||||
return "python-%s%s-c%u.%u-b%u.%u" %(diet, all_archs, major, minor, CS_API_MAJOR, CS_API_MINOR)
|
||||
|
@ -275,8 +275,7 @@ def debug():
|
||||
|
||||
archs = { "arm": capstone.CS_ARCH_ARM, "arm64": capstone.CS_ARCH_ARM64, \
|
||||
"mips": capstone.CS_ARCH_MIPS, "ppc": capstone.CS_ARCH_PPC, \
|
||||
"sparc": capstone.CS_ARCH_SPARC, "sysz": capstone.CS_ARCH_SYSZ, \
|
||||
"x86": capstone.CS_ARCH_X86 }
|
||||
"sparc": capstone.CS_ARCH_SPARC, "sysz": capstone.CS_ARCH_SYSZ)
|
||||
|
||||
all_archs = ""
|
||||
keys = archs.keys()
|
||||
@ -285,6 +284,11 @@ def debug():
|
||||
if cc.cs_support(archs[k]):
|
||||
all_archs += "-%s" %k
|
||||
|
||||
if cs_support(CS_ARCH_X86):
|
||||
all_archs += "-x86"
|
||||
if cs_support(CS_SUPPORT_X86_COMPACT):
|
||||
all_archs += "_compact"
|
||||
|
||||
(major, minor, _combined) = capstone.cs_version()
|
||||
|
||||
return "Cython-%s%s-c%u.%u-b%u.%u" %(diet, all_archs, major, minor, capstone.CS_API_MAJOR, capstone.CS_API_MINOR)
|
||||
|
19
config.mk
19
config.mk
@ -51,3 +51,22 @@ USE_SYS_DYN_MEM = yes
|
||||
# will not be updated (i.e empty), thus become irrelevant.
|
||||
|
||||
CAPSTONE_DIET = no
|
||||
|
||||
|
||||
################################################################################
|
||||
# Change 'CAPSTONE_X86_COMPACT = no' to 'CAPSTONE_X86_COMPACT = yes' to remove
|
||||
# non-critical instruction sets of X86, making the binary size smaller by ~50%.
|
||||
# This is desired in special cases, such as OS kernel, where these kind of
|
||||
# instructions are not used.
|
||||
#
|
||||
# The list of instruction sets to be removed includes:
|
||||
# - FPU
|
||||
# - MMX, SSE, SIMD, 3DNow, AVX, FMA, XOP
|
||||
# - VMX, SVM
|
||||
# - TSX
|
||||
#
|
||||
# Due to this removal, the related instructions are nolonger supported.
|
||||
#
|
||||
# By default, Capstone is compiled with 'CAPSTONE_X86_COMPACT = no'
|
||||
|
||||
CAPSTONE_X86_COMPACT = no
|
||||
|
8
cs.c
8
cs.c
@ -110,6 +110,14 @@ bool cs_support(int query)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (query == CS_SUPPORT_X86_COMPACT) {
|
||||
#if defined(CAPSTONE_HAS_X86) && defined(CAPSTONE_X86_COMPACT)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// unsupported query
|
||||
return false;
|
||||
}
|
||||
|
@ -45,8 +45,16 @@ typedef enum cs_arch {
|
||||
CS_ARCH_ALL = 0xFFFF,
|
||||
} cs_arch;
|
||||
|
||||
// Support value to verify diet mode of the engine.
|
||||
// If cs_support(CS_SUPPORT_DIET) return True, the engine was compiled
|
||||
// in diet mode.
|
||||
#define CS_SUPPORT_DIET (CS_ARCH_ALL + 1)
|
||||
|
||||
// Support value to verify X86 compact mode of the engine.
|
||||
// If cs_support(CS_SUPPORT_X86_COMPACT) return True, the engine was compiled
|
||||
// in X86 compact mode.
|
||||
#define CS_SUPPORT_X86_COMPACT (CS_ARCH_ALL + 2)
|
||||
|
||||
// Mode type
|
||||
typedef enum cs_mode {
|
||||
CS_MODE_LITTLE_ENDIAN = 0, // little endian mode (default mode)
|
||||
|
Loading…
x
Reference in New Issue
Block a user