From 56bdb9925b17cd60192c6f7ca86db801b20c2d3b Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 1 Dec 2019 04:32:05 -0800 Subject: improved cvts again, movd/movq --- src/lib.rs | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- test/test.rs | 7 +++++ 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>(mut bytes_iter: T, instruction: &mut fn unlikely_operands>(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] -- cgit v1.1