diff options
| -rw-r--r-- | src/lib.rs | 58 | ||||
| -rw-r--r-- | test/test.rs | 32 | 
2 files changed, 86 insertions, 4 deletions
@@ -2344,6 +2344,8 @@ pub enum OperandCode {      ModRM_0x0fba,      ModRM_0xf238,      ModRM_0xf30fc7, +    ModRM_0x660f38, +    ModRM_0x660f3a,      CVT_AA,      CVT_DA,      Rq_Cq_0, @@ -2578,9 +2580,9 @@ const OPCODE_660F_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::Invalid), OperandCode::ModRM_0x660f38),      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_0x660f3a),      OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),      OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),      OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -3689,7 +3691,7 @@ enum Interpretation {      Prefix,  } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq)]  // this should be a 32-byte struct..  struct OpcodeRecord(Interpretation, OperandCode); @@ -4222,7 +4224,7 @@ pub fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T                                      read_opcode_f30f_map(&mut bytes_iter, &mut length)?                                  },                              }; -                            if rec.0 == Interpretation::Instruction(Opcode::Invalid) { +                            if rec == OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing) {                                  escapes_are_prefixes_actually(&mut prefixes, &mut Some(opcode_map));                                  OPCODE_0F_MAP[opcode_byte as usize]                              } else { @@ -4997,6 +4999,54 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;              instruction.operands[1] = OperandSpec::ImmI8;          }, +        OperandCode::ModRM_0x660f38 => { +            let op = bytes_iter.next().map(|b| { *length += 1; b }).ok_or(())?; +            match op { +                0xdb => { instruction.opcode = Opcode::AESIMC; } +                0xdc => { instruction.opcode = Opcode::AESENC; } +                0xdd => { instruction.opcode = Opcode::AESENCLAST; } +                0xde => { instruction.opcode = Opcode::AESDEC; } +                0xdf => { instruction.opcode = Opcode::AESDECLAST; } +                _ => { +                    instruction.opcode = Opcode::Invalid; +                    return Err(()); +                } +            }; +            // all these SO FAR are G_E_xmm +            let modrm = read_modrm(&mut bytes_iter, instruction, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); + + +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; +            instruction.operand_count = 2; +        } +        OperandCode::ModRM_0x660f3a => { +            let op = bytes_iter.next().map(|b| { *length += 1; b }).ok_or(())?; +            match op { +                0xdf => { +                    instruction.opcode = Opcode::AESKEYGENASSIST; +                    // read operands right here right now + +                    let modrm = read_modrm(&mut bytes_iter, instruction, length)?; +                    instruction.modrm_rrr = +                        RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); + + +                    instruction.operands[0] = OperandSpec::RegRRR; +                    instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; +                    instruction.imm = +                        read_imm_unsigned(&mut bytes_iter, 1)?; +                    instruction.operands[2] = OperandSpec::ImmU8; +                    instruction.operand_count = 3; +                } +                _ => { +                    instruction.opcode = Opcode::Invalid; +                    return Err(()); +                } +            }; +        }          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 e2c52fe..cd2f6c0 100644 --- a/test/test.rs +++ b/test/test.rs @@ -98,6 +98,38 @@ fn test_cvt() {  }  #[test] +fn test_aesni() { +    fn test_instr(bytes: &[u8], text: &'static str) { +        test_display_under(&InstDecoder::minimal().with_aesni(), bytes, text); +        test_display_under(&InstDecoder::default(), bytes, text); +        test_invalid_under(&InstDecoder::minimal(), bytes); +    } + +    fn test_instr_invalid(bytes: &[u8]) { +        test_invalid_under(&InstDecoder::minimal().with_aesni(), bytes); +        test_invalid_under(&InstDecoder::default(), bytes); +    } + +    test_instr(&[0x66, 0x0f, 0x38, 0xdb, 0x0f], "aesimc xmm1, [rdi]"); +    test_instr(&[0x66, 0x4f, 0x0f, 0x38, 0xdb, 0xcf], "aesimc xmm9, xmm15"); + +    test_instr(&[0x66, 0x0f, 0x38, 0xdc, 0x0f], "aesenc xmm1, [rdi]"); +    test_instr(&[0x66, 0x4f, 0x0f, 0x38, 0xdc, 0xcf], "aesenc xmm9, xmm15"); + +    test_instr(&[0x66, 0x0f, 0x38, 0xdd, 0x0f], "aesenclast xmm1, [rdi]"); +    test_instr(&[0x66, 0x4f, 0x0f, 0x38, 0xdd, 0xcf], "aesenclast xmm9, xmm15"); + +    test_instr(&[0x66, 0x0f, 0x38, 0xde, 0x0f], "aesdec xmm1, [rdi]"); +    test_instr(&[0x66, 0x4f, 0x0f, 0x38, 0xde, 0xcf], "aesdec xmm9, xmm15"); + +    test_instr(&[0x66, 0x0f, 0x38, 0xdf, 0x0f], "aesdeclast xmm1, [rdi]"); +    test_instr(&[0x66, 0x4f, 0x0f, 0x38, 0xdf, 0xcf], "aesdeclast xmm9, xmm15"); + +    test_instr(&[0x66, 0x0f, 0x3a, 0xdf, 0x0f, 0xaa], "aeskeygenassist xmm1, [rdi], 0xaa"); +    test_instr(&[0x66, 0x4f, 0x0f, 0x3a, 0xdf, 0xcf, 0xaa], "aeskeygenassist xmm9, xmm15, 0xaa"); +} + +#[test]  fn test_sse3() {      fn test_instr(bytes: &[u8], text: &'static str) {          test_display_under(&InstDecoder::minimal().with_sse3(), bytes, text);  | 
