Add cmov* support to x86.nz (#6544)

This commit is contained in:
Sven Steinbauer 2017-01-20 16:14:08 +00:00 committed by radare
parent 3e4a2f87e1
commit 7c49535f07

View File

@ -517,6 +517,135 @@ static int opcall(RAsm *a, ut8 *data, const Opcode op) {
return l;
}
static int opcmov(RAsm *a, ut8 *data, const Opcode op) {
int l = 0;
int mod_byte = 0;
int offset = 0;
if (op.operands[0].type & OT_MEMORY ||
op.operands[1].type & OT_CONSTANT) {
return -1;
}
data[l++] = 0x0f;
char *cmov = op.mnemonic + 4;
if (!strcmp (cmov, "o")) {
data[l++] = 0x40;
} else if (!strcmp (cmov, "no")) {
data [l++] = 0x41;
} else if (!strcmp (cmov, "b") ||
!strcmp (cmov, "c") ||
!strcmp (cmov, "nae")) {
data [l++] = 0x42;
} else if (!strcmp (cmov, "ae") ||
!strcmp (cmov, "nb") ||
!strcmp (cmov, "nc")) {
data [l++] = 0x43;
} else if (!strcmp (cmov, "e") ||
!strcmp (cmov, "z")) {
data [l++] = 0x44;
} else if (!strcmp (cmov, "ne") ||
!strcmp (cmov, "nz")) {
data [l++] = 0x45;
} else if (!strcmp (cmov, "be") ||
!strcmp (cmov, "na")) {
data [l++] = 0x46;
} else if (!strcmp (cmov, "a") ||
!strcmp (cmov, "nbe")) {
data [l++] = 0x47;
} else if (!strcmp (cmov, "s")) {
data [l++] = 0x48;
} else if (!strcmp (cmov, "ns")) {
data [l++] = 0x49;
} else if (!strcmp (cmov, "p") ||
!strcmp (cmov, "pe")) {
data [l++] = 0x4a;
} else if (!strcmp (cmov, "np") ||
!strcmp (cmov, "po")) {
data [l++] = 0x4b;
} else if (!strcmp (cmov, "l") ||
!strcmp (cmov, "nge")) {
data [l++] = 0x4c;
} else if (!strcmp (cmov, "ge") ||
!strcmp (cmov, "nl")) {
data [l++] = 0x4d;
} else if (!strcmp (cmov, "le") ||
!strcmp (cmov, "ng")) {
data [l++] = 0x4e;
} else if (!strcmp (cmov, "g") ||
!strcmp (cmov, "nle")) {
data [l++] = 0x4f;
}
if (op.operands[0].type & OT_REGALL) {
if (op.operands[1].type & OT_MEMORY) {
if (op.operands[1].scale[0] > 1) {
if (op.operands[1].regs[1] != X86R_UNDEFINED) {
data[l++] = op.operands[0].reg << 3 | 4;
data[l++] = getsib (op.operands[1].scale[0]) << 6 |
op.operands[1].regs[0] << 3 |
op.operands[1].regs[1];
return l;
}
offset = op.operands[1].offset * op.operands[1].offset_sign;
if (op.operands[1].scale[0] == 2 && offset) {
data[l++] = 0x40 | op.operands[0].reg << 3 | 4; // 4 = SIB
} else {
data[l++] = op.operands[0].reg << 3 | 4; // 4 = SIB
}
if (op.operands[1].scale[0] == 2) {
data[l++] = op.operands[1].regs[0] << 3 | op.operands[1].regs[0];
} else {
data[l++] = getsib (op.operands[1].scale[0]) << 6 |
op.operands[1].regs[0] << 3 | 5;
}
if (offset) {
data[l++] = offset;
if (offset < ST8_MIN || offset > ST8_MAX) {
data[l++] = offset >> 8;
data[l++] = offset >> 16;
data[l++] = offset >> 24;
}
}
return l;
}
if (op.operands[1].regs[1] != X86R_UNDEFINED) {
data[l++] = op.operands[0].reg << 3 | 4;
data[l++] = op.operands[1].regs[1] << 3 | op.operands[1].regs[0];
return l;
}
offset = op.operands[1].offset * op.operands[1].offset_sign;
if (op.operands[1].offset || op.operands[1].regs[0] == X86R_EBP) {
mod_byte = 1;
}
if (offset < ST8_MIN || offset > ST8_MAX) {
mod_byte = 2;
}
data[l++] = mod_byte << 6 | op.operands[0].reg << 3 | op.operands[1].regs[0];
if (mod_byte) {
data[l++] = offset;
if (mod_byte == 2) {
data[l++] = offset >> 8;
data[l++] = offset >> 16;
data[l++] = offset >> 24;
}
}
} else {
data[l++] = 0xc0 | op.operands[0].reg << 3 | op.operands[1].reg;
}
}
return l;
}
static int opaam(RAsm *a, ut8 *data, const Opcode op) {
int l = 0;
int immediate = op.operands[0].immediate * op.operands[0].sign;
@ -848,51 +977,51 @@ static int opjc(RAsm *a, ut8 *data, const Opcode op) {
if (!op.is_short) {data[l++] = 0x0f;}
if (!strcmp (op.mnemonic, "ja") ||
!strcmp (op.mnemonic, "jnbe")) {
!strcmp (op.mnemonic, "jnbe")) {
data[l++] = 0x87;
} else if (!strcmp (op.mnemonic, "jae") ||
!strcmp (op.mnemonic, "jnb") ||
!strcmp (op.mnemonic, "jnc")) {
!strcmp (op.mnemonic, "jnb") ||
!strcmp (op.mnemonic, "jnc")) {
data[l++] = 0x83;
} else if (!strcmp (op.mnemonic, "jz") ||
!strcmp (op.mnemonic, "je")) {
!strcmp (op.mnemonic, "je")) {
data[l++] = 0x84;
} else if (!strcmp (op.mnemonic, "jb") ||
!strcmp (op.mnemonic, "jnae") ||
!strcmp (op.mnemonic, "jc")) {
!strcmp (op.mnemonic, "jnae") ||
!strcmp (op.mnemonic, "jc")) {
data[l++] = 0x82;
} else if (!strcmp (op.mnemonic, "jbe") ||
!strcmp (op.mnemonic, "jna")) {
!strcmp (op.mnemonic, "jna")) {
data[l++] = 0x86;
} else if (!strcmp (op.mnemonic, "jg") ||
!strcmp (op.mnemonic, "jnle")) {
!strcmp (op.mnemonic, "jnle")) {
data[l++] = 0x8f;
} else if (!strcmp (op.mnemonic, "jge") ||
!strcmp (op.mnemonic, "jnl")) {
!strcmp (op.mnemonic, "jnl")) {
data[l++] = 0x8d;
} else if (!strcmp (op.mnemonic, "jl") ||
!strcmp (op.mnemonic, "jnge")) {
!strcmp (op.mnemonic, "jnge")) {
data[l++] = 0x8c;
} else if (!strcmp (op.mnemonic, "jle") ||
!strcmp (op.mnemonic, "jng")) {
!strcmp (op.mnemonic, "jng")) {
data[l++] = 0x8e;
} else if (!strcmp (op.mnemonic, "jne") ||
!strcmp (op.mnemonic, "jnz")) {
!strcmp (op.mnemonic, "jnz")) {
data[l++] = 0x85;
} else if (!strcmp (op.mnemonic, "jno")) {
data[l++] = 0x81;
} else if (!strcmp (op.mnemonic, "jnp") ||
!strcmp (op.mnemonic, "jpo")) {
!strcmp (op.mnemonic, "jpo")) {
data[l++] = 0x8b;
} else if (!strcmp (op.mnemonic, "jns")) {
data[l++] = 0x89;
} else if (!strcmp (op.mnemonic, "jo")) {
data[l++] = 0x80;
} else if (!strcmp (op.mnemonic, "jp") ||
!strcmp(op.mnemonic, "jpe")) {
!strcmp(op.mnemonic, "jpe")) {
data[l++] = 0x8a;
} else if (!strcmp (op.mnemonic, "js") ||
!strcmp (op.mnemonic, "jz")) {
!strcmp (op.mnemonic, "jz")) {
data[l++] = 0x88;
}
if (op.is_short) {
@ -1663,6 +1792,38 @@ LookupTable oplookup[] = {
{"cli", NULL, 0xfa, 1},
{"clts", NULL, 0x0f06, 2},
{"cmc", NULL, 0xf5, 1},
{"cmovo", &opcmov, 0},
{"cmovno", &opcmov, 0},
{"cmovb", &opcmov, 0},
{"cmovc", &opcmov, 0},
{"cmovnae", &opcmov, 0},
{"cmovae", &opcmov, 0},
{"cmovnb", &opcmov, 0},
{"cmovnc", &opcmov, 0},
{"cmove", &opcmov, 0},
{"cmovz", &opcmov, 0},
{"cmovne", &opcmov, 0},
{"cmovnz", &opcmov, 0},
{"cmovbe", &opcmov, 0},
{"cmovna", &opcmov, 0},
{"cmova", &opcmov, 0},
{"cmovnbe", &opcmov, 0},
{"cmovne", &opcmov, 0},
{"cmovnz", &opcmov, 0},
{"cmovs", &opcmov, 0},
{"cmovns", &opcmov, 0},
{"cmovp", &opcmov, 0},
{"cmovpe", &opcmov, 0},
{"cmovnp", &opcmov, 0},
{"cmovpo", &opcmov, 0},
{"cmovl", &opcmov, 0},
{"cmovnge", &opcmov, 0},
{"cmovge", &opcmov, 0},
{"cmovnl", &opcmov, 0},
{"cmovle", &opcmov, 0},
{"cmovng", &opcmov, 0},
{"cmovg", &opcmov, 0},
{"cmovnle", &opcmov, 0},
{"cmp", &opcmp, 0},
{"cmpsb", NULL, 0xa6, 1},
{"cmpsd", NULL, 0xa7, 1},