diff options
| author | iximeow <me@iximeow.net> | 2020-01-15 02:23:13 -0800 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2020-01-15 02:23:13 -0800 | 
| commit | a38fe698c2e00a798231ad0ccd984912b593f15a (patch) | |
| tree | 4316dab52d0989789accc0717fd595879acbbad8 | |
| parent | 53a6a79595e100b16b85d75676bcfee56cbd40f0 (diff) | |
add more sse2 instructions (packed shift by immediate, mostly)
really need to adjust OperandCode, almost out of one-off options...
| -rw-r--r-- | src/display.rs | 4 | ||||
| -rw-r--r-- | src/lib.rs | 117 | ||||
| -rw-r--r-- | 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 <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color              Opcode::PSHUFW |              Opcode::PSHUFB |              Opcode::PSLLD | +            Opcode::PSLLDQ |              Opcode::PSLLQ |              Opcode::PSLLW |              Opcode::PSRAD |              Opcode::PSRAW |              Opcode::PSRLD | +            Opcode::PSRLDQ |              Opcode::PSRLQ |              Opcode::PSRLW |              Opcode::PSUBB | @@ -747,11 +747,13 @@ pub enum Opcode {      PSHUFW,      PSHUFD,      PSLLD, +    PSLLDQ,      PSLLQ,      PSLLW,      PSRAD,      PSRAW,      PSRLD, +    PSRLDQ,      PSRLQ,      PSRLW,      PSUBB, @@ -2753,10 +2755,6 @@ pub enum OperandCode {      AX_Xv,      DX_AX,      E_G_xmm, -    E_G_ymm, -    E_G_zmm, -    G_E_ymm, -    G_E_zmm,      Ev_Ivs,      Ew_Sw,      Fw, @@ -2786,6 +2784,9 @@ pub enum OperandCode {      ModRM_0x0f71,      ModRM_0x0f72,      ModRM_0x0f73, +    ModRM_0x660f71, +    ModRM_0x660f72, +    ModRM_0x660f73,      ModRM_0x0fc7,      Nothing,      Implied, @@ -3031,12 +3032,12 @@ const OPCODE_660F_MAP: [OpcodeRecord; 256] = [      OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQA), OperandCode::G_E_xmm),  // 0x70      OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFD), OperandCode::G_E_xmm_Ib), -    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::Invalid), OperandCode::Nothing), -    OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -    OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +    OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f71), +    OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f72), +    OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f73), +    OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQB), OperandCode::G_E_xmm), +    OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQW), OperandCode::G_E_xmm), +    OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQD), OperandCode::G_E_xmm),      OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),      OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),      OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -5327,7 +5328,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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");  | 
