diff options
| author | iximeow <me@iximeow.net> | 2020-07-26 03:45:40 -0700 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2020-07-26 03:45:40 -0700 | 
| commit | 1f0cdea3e996ff2006c560c1f495ca49b03c23ee (patch) | |
| tree | 4e139b313587059b9e9e6f2b868403602d8530be | |
| parent | c5b4cd30efa6cc830f5effaf04df6ec86ad858dd (diff) | |
ssse3, some missing sse4.1, and pextrw operands
| -rw-r--r-- | src/long_mode/display.rs | 8 | ||||
| -rw-r--r-- | src/long_mode/mod.rs | 64 | ||||
| -rw-r--r-- | test/long_mode/mod.rs | 25 | 
3 files changed, 88 insertions, 9 deletions
| diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index 807565c..9614374 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -1074,7 +1074,7 @@ impl fmt::Display for Opcode {              &Opcode::PMINUD => write!(f, "pminud"),              &Opcode::PMINUW => write!(f, "pminuw"),              &Opcode::BLENDW => write!(f, "blendw"), -            &Opcode::BLENDDVB => write!(f, "blenddvb"), +            &Opcode::BLENDVB => write!(f, "blendvb"),              &Opcode::BLENDVPS => write!(f, "blendvps"),              &Opcode::BLENDVPD => write!(f, "blendvpd"),              &Opcode::BLENDPS => write!(f, "blendps"), @@ -1087,7 +1087,7 @@ impl fmt::Display for Opcode {              &Opcode::PSIGND => write!(f, "psignd"),              &Opcode::PSIGNB => write!(f, "psignb"),              &Opcode::PSHUFB => write!(f, "pshufb"), -            &Opcode::PMULHRSU => write!(f, "pmulhrsu"), +            &Opcode::PMULHRSW => write!(f, "pmulhrsw"),              &Opcode::PMADDUBSW => write!(f, "pmaddubsw"),              &Opcode::PABSD => write!(f, "pabsd"),              &Opcode::PABSW => write!(f, "pabsw"), @@ -1244,7 +1244,7 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color              Opcode::VPMULUDQ |              Opcode::PCLMULQDQ |              Opcode::PMULDQ | -            Opcode::PMULHRSU | +            Opcode::PMULHRSW |              Opcode::PMULLD |              Opcode::VPSUBB |              Opcode::VPSUBD | @@ -1515,7 +1515,7 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color              Opcode::VBLENDPS |              Opcode::VBLENDVPD |              Opcode::VBLENDVPS | -            Opcode::BLENDDVB | +            Opcode::BLENDVB |              Opcode::BLENDPD |              Opcode::BLENDPS |              Opcode::BLENDVPD | diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index ac9edf5..d709e53 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -1346,7 +1346,7 @@ pub enum Opcode {      PMINUD,      PMINUW,      BLENDW, -    BLENDDVB, +    BLENDVB,      BLENDVPS,      BLENDVPD,      BLENDPS, @@ -1359,7 +1359,7 @@ pub enum Opcode {      PSIGND,      PSIGNB,      PSHUFB, -    PMULHRSU, +    PMULHRSW,      PMADDUBSW,      PABSD,      PABSW, @@ -2255,7 +2255,7 @@ impl InstDecoder {              Opcode::PABSW |              Opcode::PABSD |              Opcode::PMADDUBSW | -            Opcode::PMULHRSU | +            Opcode::PMULHRSW |              Opcode::PSHUFB |              Opcode::PSIGNB |              Opcode::PSIGNW | @@ -2274,7 +2274,7 @@ impl InstDecoder {              Opcode::BLENDPS |              Opcode::BLENDVPD |              Opcode::BLENDVPS | -            Opcode::BLENDDVB | +            Opcode::BLENDVB |              Opcode::BLENDW |              Opcode::PMINUW |              Opcode::PMINUD | @@ -3229,7 +3229,6 @@ pub enum OperandCode {      Yv_Xv,      G_E_q,      E_G_q, -    Rv_Gmm_Ib,      G_mm_Ew_Ib,      Mq_Dq,      ModRM_0x0f38, @@ -3348,6 +3347,7 @@ pub enum OperandCode {      G_xmm_E_mm = 0xed,      G_xmm_U_mm = 0x1ed,      U_mm_G_xmm = 0x2ed, +    Rv_Gmm_Ib = 0x3ed,      G_xmm_Edq = 0xef,      G_U_mm = 0xf1,      Ev_Gv_Ib = 0xf3, @@ -5909,6 +5909,19 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                  }              };              instruction.opcode = match opcode { +                0x00 => Opcode::PSHUFB, +                0x01 => Opcode::PHADDW, +                0x02 => Opcode::PHADDD, +                0x03 => Opcode::PHADDSW, +                0x04 => Opcode::PMADDUBSW, +                0x05 => Opcode::PHSUBW, +                0x06 => Opcode::PHSUBD, +                0x07 => Opcode::PHSUBSW, +                0x08 => Opcode::PSIGNB, +                0x09 => Opcode::PSIGNW, +                0x0a => Opcode::PSIGND, +                0x0b => Opcode::PMULHRSW, +                  0xc8 => Opcode::SHA1NEXTE,                  0xc9 => Opcode::SHA1MSG1,                  0xca => Opcode::SHA1MSG2, @@ -6144,6 +6157,25 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter          OperandCode::ModRM_0x660f38 => {              let op = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?;              match op { +                0x00 => { instruction.opcode = Opcode::PSHUFB; } +                0x01 => { instruction.opcode = Opcode::PHADDW; } +                0x02 => { instruction.opcode = Opcode::PHADDD; } +                0x03 => { instruction.opcode = Opcode::PHADDSW; } +                0x04 => { instruction.opcode = Opcode::PMADDUBSW; } +                0x05 => { instruction.opcode = Opcode::PHSUBW; } +                0x06 => { instruction.opcode = Opcode::PHSUBD; } +                0x07 => { instruction.opcode = Opcode::PHSUBSW; } +                0x08 => { instruction.opcode = Opcode::PSIGNB; } +                0x09 => { instruction.opcode = Opcode::PSIGNW; } +                0x0a => { instruction.opcode = Opcode::PSIGND; } +                0x0b => { instruction.opcode = Opcode::PMULHRSW; } + +                0x1c => { instruction.opcode = Opcode::PABSB; } +                0x1d => { instruction.opcode = Opcode::PABSW; } +                0x1e => { instruction.opcode = Opcode::PABSD; } + +                0x40 => { instruction.opcode = Opcode::PMULLD; } +                  0xdb => { instruction.opcode = Opcode::AESIMC; }                  0xdc => { instruction.opcode = Opcode::AESENC; }                  0xdd => { instruction.opcode = Opcode::AESENCLAST; } @@ -6171,6 +6203,14 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter          OperandCode::ModRM_0x660f3a => {              let op = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?;              match op { +                0x0c => { instruction.opcode = Opcode::BLENDPS; } +                0x0d => { instruction.opcode = Opcode::BLENDPD; } +                0x0f => { instruction.opcode = Opcode::PALIGNR; } +                0x10 => { instruction.opcode = Opcode::BLENDVB; } + +                0x14 => { instruction.opcode = Opcode::BLENDVPS; } +                0x15 => { instruction.opcode = Opcode::BLENDVPD; } +                  0xcc => {                      instruction.opcode = Opcode::SHA1RNDS4; @@ -6562,6 +6602,20 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                  }              }          }, +        OperandCode::Rv_Gmm_Ib => { +            instruction.operands[1] = mem_oper; +            instruction.operands[2] = OperandSpec::ImmU8; +            instruction.imm = +                read_num(&mut bytes_iter, 1)? as u64; +            *length += 1; +            instruction.modrm_rrr.bank = RegisterBank::D; +            if mem_oper == OperandSpec::RegMMM { +                instruction.modrm_mmm.bank = RegisterBank::MM; +                instruction.modrm_mmm.num &= 0b111; +            } else { +                return Err(DecodeError::InvalidOperand); +            } +        }          OperandCode::U_mm_G_xmm => {              instruction.operands[1] = mem_oper;              instruction.modrm_mmm.bank = RegisterBank::X; diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs index 50774ff..545a2d5 100644 --- a/test/long_mode/mod.rs +++ b/test/long_mode/mod.rs @@ -130,10 +130,14 @@ fn test_mmx() {      test_display(&[0x0f, 0x6f, 0xe9], "movq mm5, mm1");      test_display(&[0x0f, 0xe5, 0x3d, 0xaa, 0xbb, 0xcc, 0x77], "pmulhw mm7, [rip + 0x77ccbbaa]"); +    test_display(&[0x0f, 0x38, 0x00, 0xda], "pshufb mm3, mm2"); +      test_display(&[0x0f, 0x74, 0xc2], "pcmpeqb mm0, mm2");      test_display(&[0x0f, 0x75, 0xc2], "pcmpeqw mm0, mm2");      test_display(&[0x0f, 0x76, 0xc2], "pcmpeqd mm0, mm2"); +    test_display(&[0x0f, 0xc5, 0xd1, 0x00], "pextrw edx, mm1, 0x0"); +      test_display(&[0x0f, 0xd8, 0xc2], "psubusb mm0, mm2");      test_display(&[0x0f, 0xd9, 0xc2], "psubusw mm0, mm2");      test_display(&[0x0f, 0xda, 0xc2], "pminub mm0, mm2"); @@ -582,6 +586,26 @@ fn test_sse3() {  }  #[test] +fn test_ssse3() { +    fn test_instr(bytes: &[u8], text: &'static str) { +        test_display_under(&InstDecoder::minimal().with_ssse3(), bytes, text); +        test_invalid_under(&InstDecoder::minimal(), bytes); +        // avx doesn't imply older instructions are necessarily valid +        test_invalid_under(&InstDecoder::minimal().with_avx(), bytes); +        // sse4 doesn't imply older instructions are necessarily valid +        test_invalid_under(&InstDecoder::minimal().with_sse4_1(), bytes); +        test_invalid_under(&InstDecoder::minimal().with_sse4_2(), bytes); +    } + +    #[allow(unused)] +    fn test_instr_invalid(bytes: &[u8]) { +        test_invalid_under(&InstDecoder::minimal().with_ssse3(), bytes); +        test_invalid_under(&InstDecoder::default(), bytes); +    } +    test_instr(&[0x66, 0x0f, 0x38, 0x00, 0xda], "pshufb xmm3, xmm2"); +} + +#[test]  fn test_0f01() {      // drawn heavily from "Table A-6.  Opcode Extensions for One- and Two-byte Opcodes by Group      // Number" @@ -1214,6 +1238,7 @@ fn prefixed_0f() {      test_display(&[0x0f, 0x6e, 0xc2], "movd mm0, edx");      test_display(&[0x0f, 0x6f, 0x00], "movq mm0, [rax]");      test_display(&[0x0f, 0x6f, 0xc2], "movq mm0, mm2"); +    test_display(&[0x0f, 0x6f, 0xfb], "movq mm7, mm3");      test_display(&[0x0f, 0x70, 0x00, 0x7f], "pshufw mm0, [rax], 0x7f");      test_display(&[0x4f, 0x0f, 0x70, 0x00, 0x7f], "pshufw mm0, [r8], 0x7f");      test_invalid(&[0x0f, 0x71, 0x00, 0x7f]); | 
