Skip to content

Commit

Permalink
x86: more simplification for better performance
Browse files Browse the repository at this point in the history
  • Loading branch information
aquynh committed Jun 5, 2014
1 parent 937e483 commit e70a043
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 109 deletions.
13 changes: 0 additions & 13 deletions arch/X86/X86Disassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,17 +687,6 @@ static int reader(const void* arg, uint8_t* byte, uint64_t address)
// copy x86 detail information from internal structure to public structure
static void update_pub_insn(cs_insn_flat *pub, InternalInstruction *inter, uint8_t *prefixes)
{
int i, c;

c = 0;
for(i = 0; i < 0x100; i++) {
if (inter->prefixPresent[i] > 0) {
pub->x86.prefix[c] = i;
prefixes[c] = i;
c++;
}
}

prefixes[0] = inter->prefix0;
prefixes[1] = inter->prefix1;
prefixes[2] = inter->prefix2;
Expand Down Expand Up @@ -777,8 +766,6 @@ bool X86_getInstruction(csh ud, const uint8_t *code, size_t code_len,
instr->x86_prefix[3] = insn.prefix3;
}

instr->x86_lock_rep = insn.x86_lock_rep;

// save immediate size to print immediate properly
instr->x86_imm_size = insn.immediateSize;
}
Expand Down
17 changes: 0 additions & 17 deletions arch/X86/X86DisassemblerDecoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,6 @@ static BOOL isPrefixAtLocation(struct InternalInstruction* insn,
static int readPrefixes(struct InternalInstruction* insn)
{
BOOL isPrefix = TRUE;
BOOL prefixGroups[4] = { FALSE };
uint64_t prefixLocation;
uint8_t byte = 0, nextByte;

Expand Down Expand Up @@ -456,9 +455,6 @@ static int readPrefixes(struct InternalInstruction* insn)
insn->prefixPresent[0xf2] = 0;
insn->prefixPresent[0xf3] = 0;
case 0xf0: /* LOCK */
if (prefixGroups[0])
dbgprintf(insn, "Redundant Group 1 prefix");
prefixGroups[0] = TRUE;
setPrefixPresent(insn, byte, prefixLocation);
insn->prefix0 = byte;
break;
Expand Down Expand Up @@ -491,9 +487,6 @@ static int readPrefixes(struct InternalInstruction* insn)
//debug("Unhandled override");
return -1;
}
if (prefixGroups[1])
dbgprintf(insn, "Redundant Group 2 prefix");
prefixGroups[1] = TRUE;
// only accept the last prefix
insn->prefixPresent[0x2e] = 0;
insn->prefixPresent[0x36] = 0;
Expand All @@ -505,17 +498,11 @@ static int readPrefixes(struct InternalInstruction* insn)
insn->prefix1 = byte;
break;
case 0x66: /* Operand-size override */
if (prefixGroups[2])
dbgprintf(insn, "Redundant Group 3 prefix");
prefixGroups[2] = TRUE;
hasOpSize = TRUE;
setPrefixPresent(insn, byte, prefixLocation);
insn->prefix2 = byte;
break;
case 0x67: /* Address-size override */
if (prefixGroups[3])
dbgprintf(insn, "Redundant Group 4 prefix");
prefixGroups[3] = TRUE;
hasAdSize = TRUE;
setPrefixPresent(insn, byte, prefixLocation);
insn->prefix3 = byte;
Expand All @@ -529,8 +516,6 @@ static int readPrefixes(struct InternalInstruction* insn)
dbgprintf(insn, "Found prefix 0x%hhx", byte);
}

insn->x86_lock_rep = prefixGroups[0];

insn->vectorExtensionType = TYPE_NO_VEX_XOP;

if (byte == 0x62) {
Expand Down Expand Up @@ -1961,8 +1946,6 @@ int decodeInstruction(struct InternalInstruction* insn,
uint64_t startLoc,
DisassemblerMode mode)
{
memset(insn, 0, sizeof(*insn));

insn->reader = reader;
insn->readerArg = readerArg;
insn->startLocation = startLoc;
Expand Down
3 changes: 0 additions & 3 deletions arch/X86/X86DisassemblerDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -636,9 +636,6 @@ typedef struct InternalInstruction {
uint8_t firstByte; // save the first byte in stream
uint8_t orgModRM; // save original modRM because we will modify modRM

// does this instruction contain LOC/REP/REPNE prefix?
bool x86_lock_rep;

/* The SIB byte, used for more complex 32- or 64-bit memory operands */
BOOL consumedSIB;
uint8_t sib;
Expand Down
130 changes: 54 additions & 76 deletions arch/X86/X86Mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -41908,105 +41908,83 @@ static bool valid_rep(cs_struct *h, unsigned int opcode)
// return true if we patch the mnemonic
bool X86_lockrep(MCInst *MI, SStream *O)
{
int i;
unsigned int opcode;
uint8_t prefix[8] = { 0 };
unsigned int c = 0;

if (MI->x86_lock_rep) {
for(i = 0; i < ARR_SIZE(MI->x86_prefix); i++) {
switch(MI->x86_prefix[i]) {
default:
// non-zero prefix, so copy it
prefix[c] = MI->x86_prefix[i];
c++;
break;
case 0:
// ignore
break;
case 0xf0:
switch(MI->x86_prefix[0]) {
default:
break;
case 0xf0:
#ifndef CAPSTONE_DIET
SStream_concat(O, "lock|");
SStream_concat(O, "lock|");
#endif
break;
case 0xf2: // repne
opcode = MCInst_getOpcode(MI);
break;
case 0xf2: // repne
opcode = MCInst_getOpcode(MI);
#ifndef CAPSTONE_DIET // only care about memonic in standard (non-diet) mode
if (valid_rep(MI->csh, opcode)) {
prefix[c] = MI->x86_prefix[i];
c++;
SStream_concat(O, "repne|");
} else {
// invalid prefix
MI->x86_prefix[i] = 0;
if (valid_rep(MI->csh, opcode)) {
SStream_concat(O, "repne|");
} else {
// invalid prefix
MI->x86_prefix[0] = 0;

// handle special cases
// handle special cases
#ifndef CAPSTONE_X86_REDUCE
if (opcode == X86_MULPDrr) {
MCInst_setOpcode(MI, X86_MULSDrr);
SStream_concat(O, "mulsd\t");
return true;
}
if (opcode == X86_MULPDrr) {
MCInst_setOpcode(MI, X86_MULSDrr);
SStream_concat(O, "mulsd\t");
return true;
}
#endif
}
}
#else // diet mode -> only patch opcode in special cases
if (!valid_rep(MI->csh, opcode)) {
MI->x86_prefix[i] = 0;
} else {
prefix[c] = MI->x86_prefix[i];
c++;
}
if (!valid_rep(MI->csh, opcode)) {
MI->x86_prefix[0] = 0;
}
#ifndef CAPSTONE_X86_REDUCE
// handle special cases
if (opcode == X86_MULPDrr) {
MCInst_setOpcode(MI, X86_MULSDrr);
}
// handle special cases
if (opcode == X86_MULPDrr) {
MCInst_setOpcode(MI, X86_MULSDrr);
}
#endif
#endif
break;
break;

case 0xf3:
case 0xf3:
#ifndef CAPSTONE_DIET // only care about memonic in standard (non-diet) mode
opcode = MCInst_getOpcode(MI);
if (valid_rep(MI->csh, opcode)) {
prefix[c] = MI->x86_prefix[i];
c++;
SStream_concat(O, "rep|");
} else {
// invalid prefix
MI->x86_prefix[i] = 0;
opcode = MCInst_getOpcode(MI);
if (valid_rep(MI->csh, opcode)) {
SStream_concat(O, "rep|");
} else {
// invalid prefix
MI->x86_prefix[0] = 0;

// handle special cases
// handle special cases
#ifndef CAPSTONE_X86_REDUCE
if (opcode == X86_MULPDrr) {
MCInst_setOpcode(MI, X86_MULSSrr);
SStream_concat(O, "mulss\t");
return true;
}
if (opcode == X86_MULPDrr) {
MCInst_setOpcode(MI, X86_MULSSrr);
SStream_concat(O, "mulss\t");
return true;
}
#endif
}
}
#else // diet mode -> only patch opcode in special cases
if (!valid_rep(MI->csh, opcode)) {
MI->x86_prefix[i] = 0;
} else {
prefix[c] = MI->x86_prefix[i];
c++;
}
if (!valid_rep(MI->csh, opcode)) {
MI->x86_prefix[0] = 0;
}
#ifndef CAPSTONE_X86_REDUCE
// handle special cases
if (opcode == X86_MULPDrr) {
MCInst_setOpcode(MI, X86_MULSSrr);
}
// handle special cases
if (opcode == X86_MULPDrr) {
MCInst_setOpcode(MI, X86_MULSSrr);
}
#endif
#endif
break;
}
}

// copy normalized prefix[] back to x86.prefix[]
memcpy(MI->flat_insn.x86.prefix, prefix, ARR_SIZE(MI->flat_insn.x86.prefix));
break;
}

// copy normalized prefix[] back to x86.prefix[]
if (MI->csh->detail)
memcpy(MI->flat_insn.x86.prefix, MI->x86_prefix, ARR_SIZE(MI->x86_prefix));

return false;
}

Expand Down

0 comments on commit e70a043

Please sign in to comment.