aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2019-12-01 04:32:05 -0800
committeriximeow <me@iximeow.net>2020-01-12 16:10:13 -0800
commit56bdb9925b17cd60192c6f7ca86db801b20c2d3b (patch)
tree95d51d30855e498a279c02f9f49d3bd8b9197090
parent767c604e2ee47cde4edf72b63d17998ce1767bde (diff)
improved cvts again, movd/movq
-rw-r--r--src/lib.rs87
-rw-r--r--test/test.rs7
2 files changed, 87 insertions, 7 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 6d4ed86..6ecc5da 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1192,7 +1192,6 @@ pub enum OperandCode {
AL_Xb = 0x68,
AX_AL = 0x69,
AX_Ov = 0x6a,
- G_E_mm = 0x6b,
Eb_Gb = 0x80,
Ev_Gv = 0x81,
@@ -1228,6 +1227,14 @@ pub enum OperandCode {
ModRM_0x0f18 = 0x9b,
// gap, 0x9a
Gv_M = 0xdb,
+ G_mm_Edq = 0xdd,
+ G_mm_E = 0xdf,
+ G_xmm_Ed = 0xe1,
+ G_xmm_Eq = 0xe3,
+ G_mm_E_xmm = 0xe5,
+ G_E_mm = 0xe7,
+ Edq_G_mm = 0xe9,
+ E_G_mm = 0xeb,
}
fn base_opcode_map(v: u8) -> Opcode {
@@ -2174,8 +2181,8 @@ const OPCODE_0F_MAP: [OpcodeRecord; 256] = [
OpcodeRecord(Interpretation::Instruction(Opcode::MOVAPS), OperandCode::E_G_xmm),
OpcodeRecord(Interpretation::Instruction(Opcode::CVTPI2PS), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTPS), OperandCode::M_G_xmm),
- OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPS2PI), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::CVTPS2PI), OperandCode::Nothing),
+ OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPS2PI), OperandCode::G_mm_E_xmm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::CVTPS2PI), OperandCode::G_mm_E_xmm),
OpcodeRecord(Interpretation::Instruction(Opcode::UCOMISS), OperandCode::G_E_xmm),
OpcodeRecord(Interpretation::Instruction(Opcode::COMISS), OperandCode::G_E_xmm),
@@ -2248,8 +2255,8 @@ const OPCODE_0F_MAP: [OpcodeRecord; 256] = [
OpcodeRecord(Interpretation::Instruction(Opcode::PACKSSDW), OperandCode::Unsupported),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::MOVD), OperandCode::Unsupported),
- OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::Unsupported),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVD), OperandCode::G_mm_Edq),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::G_mm_E),
// 0x70
OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFW), OperandCode::Unsupported),
@@ -2266,8 +2273,8 @@ const OPCODE_0F_MAP: [OpcodeRecord; 256] = [
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::MOVD), OperandCode::Unsupported),
- OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::Unsupported),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVD), OperandCode::Edq_G_mm),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::E_G_mm),
// 0x80
OpcodeRecord(Interpretation::Instruction(Opcode::JO), OperandCode::Jvds),
@@ -3545,6 +3552,72 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
fn unlikely_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, mem_oper: OperandSpec, length: &mut u8) -> Result<(), ()> {
let mut bytes_read = 0;
match operand_code {
+ OperandCode::G_mm_Edq => {
+ instruction.operands[1] = mem_oper;
+ instruction.modrm_rrr.bank = RegisterBank::MM;
+ instruction.modrm_rrr.num &= 0b111;
+ if mem_oper == OperandSpec::RegMMM {
+ if instruction.prefixes.rex().w() {
+ instruction.modrm_mmm.bank = RegisterBank::Q;
+ } else {
+ instruction.modrm_mmm.bank = RegisterBank::D;
+ }
+ }
+ }
+ OperandCode::G_mm_E => {
+ instruction.operands[1] = mem_oper;
+ instruction.modrm_rrr.bank = RegisterBank::MM;
+ instruction.modrm_rrr.num &= 0b111;
+ if mem_oper == OperandSpec::RegMMM {
+ instruction.modrm_mmm.bank = RegisterBank::MM;
+ instruction.modrm_mmm.num &= 0b111;
+ }
+ }
+ OperandCode::Edq_G_mm => {
+ instruction.operands[1] = instruction.operands[0];
+ instruction.operands[0] = mem_oper;
+ instruction.modrm_rrr.bank = RegisterBank::MM;
+ instruction.modrm_rrr.num &= 0b111;
+ if mem_oper == OperandSpec::RegMMM {
+ if instruction.prefixes.rex().w() {
+ instruction.modrm_mmm.bank = RegisterBank::Q;
+ } else {
+ instruction.modrm_mmm.bank = RegisterBank::D;
+ }
+ }
+ }
+ OperandCode::E_G_mm => {
+ instruction.operands[1] = instruction.operands[0];
+ instruction.operands[0] = mem_oper;
+ instruction.modrm_rrr.bank = RegisterBank::MM;
+ instruction.modrm_rrr.num &= 0b111;
+ if mem_oper == OperandSpec::RegMMM {
+ instruction.modrm_mmm.bank = RegisterBank::MM;
+ instruction.modrm_mmm.num &= 0b111;
+ }
+ }
+ OperandCode::G_xmm_Ed => {
+ instruction.operands[1] = mem_oper;
+ instruction.modrm_rrr.bank = RegisterBank::X;
+ if mem_oper == OperandSpec::RegMMM {
+ instruction.modrm_mmm.bank = RegisterBank::D;
+ }
+ },
+ OperandCode::G_xmm_Eq => {
+ instruction.operands[1] = mem_oper;
+ instruction.modrm_rrr.bank = RegisterBank::X;
+ if mem_oper == OperandSpec::RegMMM {
+ instruction.modrm_mmm.bank = RegisterBank::Q;
+ }
+ },
+ OperandCode::G_mm_E_xmm => {
+ instruction.operands[1] = mem_oper;
+ instruction.modrm_rrr.bank = RegisterBank::MM;
+ instruction.modrm_rrr.num &= 0b111;
+ if mem_oper == OperandSpec::RegMMM {
+ instruction.modrm_mmm.bank = RegisterBank::X;
+ }
+ },
// sure hope these aren't backwards huh
OperandCode::AL_Xb => {
instruction.modrm_rrr = RegSpec::al();
diff --git a/test/test.rs b/test/test.rs
index a08dbec..ec014ac 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -48,6 +48,7 @@ fn test_display(data: &[u8], expected: &'static str) {
#[test]
fn test_mmx() {
test_display(&[0x4f, 0x0f, 0x7e, 0xcf], "movd r15, mm1");
+ test_display(&[0x41, 0x0f, 0x7e, 0xcf], "movd r15d, mm1");
test_display(&[0x4f, 0x0f, 0x7f, 0xcf], "movq mm7, mm1");
test_display(&[0x0f, 0xc4, 0xc0, 0x14], "pinsrw mm0, eax, 0x14");
test_display(&[0x4f, 0x0f, 0xc4, 0xc0, 0x14], "pinsrw mm0, r8d, 0x14");
@@ -65,11 +66,17 @@ fn test_cvt() {
test_display(&[0x4f, 0x0f, 0x2c, 0xcf], "cvttps2pi mm1, xmm15");
test_display(&[0x4f, 0x0f, 0x2a, 0xcf], "cvtpi2ps xmm9, mm7");
test_display(&[0x4f, 0x66, 0x0f, 0x2a, 0xcf], "cvtpi2pd xmm1, mm7");
+ test_display(&[0x66, 0x4f, 0x0f, 0x2a, 0xcf], "cvtpi2pd xmm9, mm7");
test_display(&[0x4f, 0xf3, 0x0f, 0x2a, 0xcf], "cvtsi2ss xmm1, edi");
+ test_display(&[0xf3, 0x4f, 0x0f, 0x2a, 0xcf], "cvtsi2ss xmm9, r15");
test_display(&[0x4f, 0xf2, 0x0f, 0x2a, 0xcf], "cvtsi2sd xmm1, edi");
+ test_display(&[0xf2, 0x4f, 0x0f, 0x2a, 0xcf], "cvtsi2sd xmm9, r15");
test_display(&[0x4f, 0xf2, 0x0f, 0x2a, 0x00], "cvtsi2sd xmm0, [rax]");
+ test_display(&[0xf2, 0x4f, 0x0f, 0x2a, 0x00], "cvtsi2sd xmm8, [r8]");
test_display(&[0x4f, 0xf3, 0x0f, 0x2a, 0x00], "cvtsi2ss xmm0, [rax]");
+ test_display(&[0xf3, 0x4f, 0x0f, 0x2a, 0x00], "cvtsi2ss xmm8, [r8]");
test_display(&[0x4f, 0x66, 0x0f, 0x2a, 0x00], "cvtpi2pd xmm0, qword [rax]");
+ test_display(&[0x66, 0x4f, 0x0f, 0x2a, 0x00], "cvtpi2pd xmm8, qword [r8]");
}
#[test]