From 9b965525afced37e99543e3a412218207a41e793 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 23 May 2020 19:37:58 -0700 Subject: add SHA, BMI1, and BMI2, complete XSAVE extension support additionally: cmpcxchg{8,16}b, rdrand, rdseed, rdpid, {rd,wr}{fs,gs}base --- src/protected_mode/vex.rs | 166 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 163 insertions(+), 3 deletions(-) (limited to 'src/protected_mode/vex.rs') diff --git a/src/protected_mode/vex.rs b/src/protected_mode/vex.rs index b4716d7..b2a845e 100644 --- a/src/protected_mode/vex.rs +++ b/src/protected_mode/vex.rs @@ -83,6 +83,10 @@ enum VEXOperandCode { Ed_G_xmm, G_xmm_Ed, G_xmm_Eq, + G_E_V, + G_V_E, + G_E_Ib, + BMI1_F3, } #[inline(never)] @@ -691,6 +695,72 @@ fn read_vex_operands>(bytes: &mut T, instruction: &mut Inst instruction.operands[2] = OperandSpec::RegVex; Ok(()) } + VEXOperandCode::G_V_E => { + let modrm = read_modrm(bytes, length)?; + let (opwidth, bank) = (4, RegisterBank::D); + instruction.modrm_rrr = + RegSpec::from_parts((modrm >> 3) & 7, bank); + instruction.vex_reg.bank = bank; + let mem_oper = read_E(bytes, instruction, modrm, opwidth, length)?; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = OperandSpec::RegVex; + instruction.operands[2] = mem_oper; + instruction.operand_count = 3; + Ok(()) + } + VEXOperandCode::G_E_V => { + let modrm = read_modrm(bytes, length)?; + let (opwidth, bank) = (4, RegisterBank::D); + instruction.modrm_rrr = + RegSpec::from_parts((modrm >> 3) & 7, bank); + instruction.vex_reg.bank = bank; + let mem_oper = read_E(bytes, instruction, modrm, opwidth, length)?; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = mem_oper; + instruction.operands[2] = OperandSpec::RegVex; + instruction.operand_count = 3; + Ok(()) + } + VEXOperandCode::G_E_Ib => { + let modrm = read_modrm(bytes, length)?; + let (opwidth, bank) = (4, RegisterBank::D); + instruction.modrm_rrr = + RegSpec::from_parts((modrm >> 3) & 7, bank); + let mem_oper = read_E(bytes, instruction, modrm, opwidth, length)?; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = mem_oper; + instruction.imm = read_imm_unsigned(bytes, 1, length)?; + instruction.operands[2] = OperandSpec::ImmI8; + instruction.operand_count = 3; + Ok(()) + } + VEXOperandCode::BMI1_F3 => { + let modrm = read_modrm(bytes, length)?; + instruction.opcode = match (modrm >> 3) & 7 { + 1 => { + Opcode::BLSR + } + 2 => { + Opcode::BLSMSK + } + 3 => { + Opcode::BLSI + } + _ => { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } + }; + let (opwidth, bank) = (4, RegisterBank::D); + instruction.modrm_rrr = + RegSpec::from_parts((modrm >> 3) & 7, bank); + let mem_oper = read_E(bytes, instruction, modrm, opwidth, length)?; + instruction.operands[0] = OperandSpec::RegVex; + instruction.operands[1] = mem_oper; + instruction.operand_count = 2; + instruction.vex_reg.bank = bank; + Ok(()) + } VEXOperandCode::G_E_ymm_imm8 | VEXOperandCode::G_V_E_xmm_xmm4 | @@ -2267,15 +2337,92 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & } else { VEXOperandCode::G_V_E_xmm }), + 0xF7 => (Opcode::SHLX, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::G_E_V + }), + _ => { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } + } + } else if let VEXOpcodePrefix::PrefixF2 = p { + match opc { + 0xF5 => (Opcode::PDEP, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::G_V_E + }), + 0xF6 => (Opcode::MULX, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::G_V_E + }), + 0xF7 => (Opcode::SHRX, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::G_E_V + }), + _ => { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } + } + } else if let VEXOpcodePrefix::PrefixF3 = p { + match opc { + 0xF5 => (Opcode::PEXT, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::G_V_E + }), + 0xF7 => (Opcode::SARX, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::G_E_V + }), _ => { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } } else { - // the only VEX* 0f38 instructions have an implied 66 prefix. - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); + match opc { + 0xF2 => (Opcode::ANDN, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::G_V_E + }), + 0xF3 => (Opcode::Invalid, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::BMI1_F3 + }), + 0xF5 => (Opcode::BZHI, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::G_E_V + }), + 0xF7 => (Opcode::BEXTR, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::G_E_V + }), + _ => { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } + } } } VEXOpcodeMap::Map0F3A => { @@ -2501,6 +2648,19 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & return Err(DecodeError::InvalidOpcode); } } + } else if let VEXOpcodePrefix::PrefixF2 = p { + match opc { + 0xF0 => (Opcode::RORX, if L { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } else { + VEXOperandCode::G_E_Ib + }), + _ => { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } + } } else { // the only VEX* 0f3a instructions have an implied 66 prefix. instruction.opcode = Opcode::Invalid; -- cgit v1.1