mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-27 00:05:10 +00:00
Add cmov* support to x86.nz (#6544)
This commit is contained in:
parent
3e4a2f87e1
commit
7c49535f07
@ -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},
|
||||
|
Loading…
x
Reference in New Issue
Block a user