From a38fe698c2e00a798231ad0ccd984912b593f15a Mon Sep 17 00:00:00 2001 From: iximeow Date: Wed, 15 Jan 2020 02:23:13 -0800 Subject: add more sse2 instructions (packed shift by immediate, mostly) really need to adjust OperandCode, almost out of one-off options... --- src/display.rs | 4 ++ src/lib.rs | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++------- test/test.rs | 21 ++++++++++- 3 files changed, 128 insertions(+), 14 deletions(-) diff --git a/src/display.rs b/src/display.rs index f3400f6..29e718e 100644 --- a/src/display.rs +++ b/src/display.rs @@ -567,11 +567,13 @@ impl fmt::Display for Opcode { &Opcode::PSHUFW => write!(f, "pshufw"), &Opcode::PSHUFD => write!(f, "pshufd"), &Opcode::PSLLD => write!(f, "pslld"), + &Opcode::PSLLDQ => write!(f, "pslldq"), &Opcode::PSLLQ => write!(f, "psllq"), &Opcode::PSLLW => write!(f, "psllw"), &Opcode::PSRAD => write!(f, "psrad"), &Opcode::PSRAW => write!(f, "psraw"), &Opcode::PSRLD => write!(f, "psrld"), + &Opcode::PSRLDQ => write!(f, "psrldq"), &Opcode::PSRLQ => write!(f, "psrlq"), &Opcode::PSRLW => write!(f, "psrlw"), &Opcode::PSUBB => write!(f, "psubb"), @@ -1314,11 +1316,13 @@ impl > Colorize>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 }; instruction.operands[0] = OperandSpec::RegMMM; instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; - instruction.operands[1] = OperandSpec::ImmI8; + instruction.operands[1] = OperandSpec::ImmU8; }, OperandCode::ModRM_0x0f72 => { instruction.operand_count = 2; @@ -5356,7 +5357,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 }; instruction.operands[0] = OperandSpec::RegMMM; instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; - instruction.operands[1] = OperandSpec::ImmI8; + instruction.operands[1] = OperandSpec::ImmU8; }, OperandCode::ModRM_0x0f73 => { instruction.operand_count = 2; @@ -5382,7 +5383,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 }; instruction.operands[0] = OperandSpec::RegMMM; instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; - instruction.operands[1] = OperandSpec::ImmI8; + instruction.operands[1] = OperandSpec::ImmU8; }, OperandCode::ModRM_0x660f38 => { let op = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?; @@ -5432,6 +5433,96 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter } }; } + OperandCode::ModRM_0x660f71 => { + instruction.operand_count = 2; + + let modrm = read_modrm(&mut bytes_iter, length)?; + if modrm & 0xc0 != 0xc0 { + return Err(DecodeError::InvalidOperand); + } + + let r = (modrm >> 3) & 7; + match r { + 2 => { + instruction.opcode = Opcode::PSRLW; + } + 4 => { + instruction.opcode = Opcode::PSRAW; + } + 6 => { + instruction.opcode = Opcode::PSLLW; + } + _ => { + return Err(DecodeError::InvalidOpcode); + } + } + + instruction.modrm_mmm = RegSpec { bank: RegisterBank::X, num: modrm & 7 }; + instruction.operands[0] = OperandSpec::RegMMM; + instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; + instruction.operands[1] = OperandSpec::ImmU8; + }, + OperandCode::ModRM_0x660f72 => { + instruction.operand_count = 2; + + let modrm = read_modrm(&mut bytes_iter, length)?; + if modrm & 0xc0 != 0xc0 { + return Err(DecodeError::InvalidOperand); + } + + let r = (modrm >> 3) & 7; + match r { + 2 => { + instruction.opcode = Opcode::PSRLD; + } + 4 => { + instruction.opcode = Opcode::PSRAD; + } + 6 => { + instruction.opcode = Opcode::PSLLD; + } + _ => { + return Err(DecodeError::InvalidOpcode); + } + } + + instruction.modrm_mmm = RegSpec { bank: RegisterBank::X, num: modrm & 7 }; + instruction.operands[0] = OperandSpec::RegMMM; + instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; + instruction.operands[1] = OperandSpec::ImmU8; + }, + OperandCode::ModRM_0x660f73 => { + instruction.operand_count = 2; + + let modrm = read_modrm(&mut bytes_iter, length)?; + if modrm & 0xc0 != 0xc0 { + return Err(DecodeError::InvalidOperand); + } + + let r = (modrm >> 3) & 7; + match r { + 2 => { + instruction.opcode = Opcode::PSRLQ; + } + 3 => { + instruction.opcode = Opcode::PSRLDQ; + } + 6 => { + instruction.opcode = Opcode::PSLLQ; + } + 7 => { + instruction.opcode = Opcode::PSLLDQ; + } + _ => { + return Err(DecodeError::InvalidOpcode); + } + } + + instruction.modrm_mmm = RegSpec { bank: RegisterBank::X, num: modrm & 7 }; + instruction.operands[0] = OperandSpec::RegMMM; + instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; + instruction.operands[1] = OperandSpec::ImmU8; + }, OperandCode::G_mm_Edq => { instruction.operands[1] = mem_oper; instruction.modrm_rrr.bank = RegisterBank::MM; diff --git a/test/test.rs b/test/test.rs index 5187df8..7248117 100644 --- a/test/test.rs +++ b/test/test.rs @@ -127,7 +127,6 @@ fn test_sse3() { test_invalid_under(&InstDecoder::minimal().with_sse3(), bytes); test_invalid_under(&InstDecoder::default(), bytes); } - test_instr(&[0xf2, 0x0f, 0xf0, 0x0f], "lddqu xmm1, [rdi]"); test_instr_invalid(&[0xf2, 0x0f, 0xf0, 0xcf]); test_instr(&[0xf2, 0x0f, 0xd0, 0x0f], "addsubps xmm1, [rdi]"); @@ -365,6 +364,26 @@ fn test_sse() { test_display(&[0x66, 0x48, 0x0f, 0x6e, 0xc0], "movq xmm0, rax"); test_display(&[0x66, 0x0f, 0x70, 0xc0, 0x4e], "pshufd xmm0, xmm0, 0x4e"); + test_invalid(&[0x66, 0x4f, 0x0f, 0x71, 0x10, 0x8f]); + test_display(&[0x66, 0x4f, 0x0f, 0x71, 0xd0, 0x8f], "psrlw xmm0, 0x8f"); + test_invalid(&[0x66, 0x4f, 0x0f, 0x71, 0x20, 0x8f]); + test_display(&[0x66, 0x4f, 0x0f, 0x71, 0xe0, 0x8f], "psraw xmm0, 0x8f"); + test_invalid(&[0x66, 0x4f, 0x0f, 0x71, 0x30, 0x8f]); + test_display(&[0x66, 0x4f, 0x0f, 0x71, 0xf0, 0x8f], "psllw xmm0, 0x8f"); + test_invalid(&[0x66, 0x4f, 0x0f, 0x72, 0x10, 0x8f]); + test_display(&[0x66, 0x4f, 0x0f, 0x72, 0xd0, 0x8f], "psrld xmm0, 0x8f"); + test_invalid(&[0x66, 0x4f, 0x0f, 0x72, 0x20, 0x8f]); + test_display(&[0x66, 0x4f, 0x0f, 0x72, 0xe0, 0x8f], "psrad xmm0, 0x8f"); + test_invalid(&[0x66, 0x4f, 0x0f, 0x72, 0x30, 0x8f]); + test_display(&[0x66, 0x4f, 0x0f, 0x72, 0xf0, 0x8f], "pslld xmm0, 0x8f"); + test_invalid(&[0x66, 0x4f, 0x0f, 0x73, 0x10, 0x8f]); + test_invalid(&[0x66, 0x4f, 0x0f, 0x73, 0x18, 0x8f]); + test_display(&[0x66, 0x4f, 0x0f, 0x73, 0xd0, 0x8f], "psrlq xmm0, 0x8f"); + test_display(&[0x66, 0x4f, 0x0f, 0x73, 0xd8, 0x8f], "psrldq xmm0, 0x8f"); + test_invalid(&[0x66, 0x4f, 0x0f, 0x73, 0x30, 0x8f]); + test_invalid(&[0x66, 0x4f, 0x0f, 0x73, 0x38, 0x8f]); + test_display(&[0x66, 0x4f, 0x0f, 0x73, 0xf0, 0x8f], "psllq xmm0, 0x8f"); + test_display(&[0x66, 0x4f, 0x0f, 0x73, 0xf8, 0x8f], "pslldq xmm0, 0x8f"); test_display(&[0x4f, 0x0f, 0x28, 0x00], "movaps xmm8, [r8]"); test_display(&[0x4f, 0x0f, 0x29, 0x00], "movaps [r8], xmm8"); test_display(&[0x4f, 0x0f, 0x2b, 0x00], "movntps [r8], xmm8"); -- cgit v1.1