From 0a3811ec18d2154f050aaf6e611a3d65f467c0cc Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 21 Mar 2021 01:42:24 -0700 Subject: add waitpkg, clean up unused values, old comments --- src/long_mode/display.rs | 8 +++ src/long_mode/mod.rs | 174 +++++++++++++++++++++++++++-------------------- 2 files changed, 107 insertions(+), 75 deletions(-) (limited to 'src') diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index 9986194..8f7bd9b 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -1291,6 +1291,11 @@ const MNEMONICS: &[&'static str] = &[ "seamret", "seamops", "seamcall", + + // WAITPKG + "tpause", + "umonitor", + "umwait", ]; impl Opcode { @@ -2233,6 +2238,9 @@ impl > Colorize OpcodeRecord { if prefixes.repnz() { match opcode { 0x00 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f00), - 0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f01), 0x02 => OpcodeRecord(Interpretation::Instruction(Opcode::LAR), OperandCode::Gv_Ew), 0x03 => OpcodeRecord(Interpretation::Instruction(Opcode::LSL), OperandCode::Gv_Ew_LSL), 0x04 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -5150,7 +5150,7 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { } else if prefixes.rep() { match opcode { 0x00 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f00), - 0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f01), 0x02 => OpcodeRecord(Interpretation::Instruction(Opcode::LAR), OperandCode::Gv_Ew), 0x03 => OpcodeRecord(Interpretation::Instruction(Opcode::LSL), OperandCode::Gv_Ew_LSL), 0x04 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -5427,7 +5427,7 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { } else if prefixes.operand_size() { match opcode { 0x00 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f00), - 0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f01), + 0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f01), 0x02 => OpcodeRecord(Interpretation::Instruction(Opcode::LAR), OperandCode::Gv_Ew), 0x03 => OpcodeRecord(Interpretation::Instruction(Opcode::LSL), OperandCode::Gv_Ew_LSL), 0x04 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -6088,9 +6088,6 @@ fn read_0f38_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { }; } else { return match opcode { - // TODO: straggler? 0x0f => Opcode::PALIGNR, - // PALIGNR - // OperandCode::G_E_mm_Ib 0x00 => OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFB), OperandCode::G_E_mm), 0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::PHADDW), OperandCode::G_E_mm), 0x02 => OpcodeRecord(Interpretation::Instruction(Opcode::PHADDD), OperandCode::G_E_mm), @@ -6115,7 +6112,6 @@ fn read_0f38_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0xf0 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVBE), OperandCode::Gv_M), 0xf1 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVBE), OperandCode::M_Gv), 0xf6 => OpcodeRecord(Interpretation::Instruction(Opcode::WRSS), OperandCode::Mdq_Gdq), - // TODO: always 32-bit mov, be careful about memory size 0xf9 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVDIRI), OperandCode::Md_Gd), _ => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), }; @@ -6915,6 +6911,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = mem_oper; instruction.operand_count = 2; } + /* OperandCode::Edq_Gdq => { let bank = if instruction.prefixes.rex().w() { RegisterBank::Q @@ -6930,6 +6927,7 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = mem_oper; instruction.operand_count = 2; } + */ OperandCode::G_U_xmm => { instruction.modrm_rrr.bank = RegisterBank::X; if mem_oper != OperandSpec::RegMMM { @@ -8103,41 +8101,6 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter } instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?; } - OperandCode::ModRM_0x660f01 => { - let modrm = read_modrm(&mut bytes_iter, length)?; - let r = (modrm >> 3) & 7; - if r == 1 { - let mod_bits = modrm >> 6; - let m = modrm & 7; - if mod_bits == 0b11 { - instruction.operands[0] = OperandSpec::Nothing; - instruction.operand_count = 0; - match m { - 0b100 => { - instruction.opcode = Opcode::TDCALL; - } - 0b101 => { - instruction.opcode = Opcode::SEAMRET; - } - 0b110 => { - instruction.opcode = Opcode::SEAMOPS; - } - 0b111 => { - instruction.opcode = Opcode::SEAMCALL; - } - _ => { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } - } - return Ok(()); - } else { - return Err(DecodeError::InvalidOpcode); - } - } else { - return Err(DecodeError::InvalidOpcode); - } - } OperandCode::ModRM_0x0f01 => { let opwidth = imm_width_from_prefixes_64(SizeCode::vq, instruction.prefixes); let modrm = read_modrm(&mut bytes_iter, length)?; @@ -8180,26 +8143,50 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter if mod_bits == 0b11 { instruction.operands[0] = OperandSpec::Nothing; instruction.operand_count = 0; - match m { - 0b000 => { - instruction.opcode = Opcode::MONITOR; - } - 0b001 => { - instruction.opcode = Opcode::MWAIT; - }, - 0b010 => { - instruction.opcode = Opcode::CLAC; - } - 0b011 => { - instruction.opcode = Opcode::STAC; - } - 0b111 => { - instruction.opcode = Opcode::ENCLS; + if instruction.prefixes.operand_size() { + match m { + 0b100 => { + instruction.opcode = Opcode::TDCALL; + } + 0b101 => { + instruction.opcode = Opcode::SEAMRET; + } + 0b110 => { + instruction.opcode = Opcode::SEAMOPS; + } + 0b111 => { + instruction.opcode = Opcode::SEAMCALL; + } + _ => { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } } - _ => { - instruction.opcode = Opcode::Invalid; + } else { + if instruction.prefixes.rep() || instruction.prefixes.repnz() { return Err(DecodeError::InvalidOpcode); } + match m { + 0b000 => { + instruction.opcode = Opcode::MONITOR; + } + 0b001 => { + instruction.opcode = Opcode::MWAIT; + }, + 0b010 => { + instruction.opcode = Opcode::CLAC; + } + 0b011 => { + instruction.opcode = Opcode::STAC; + } + 0b111 => { + instruction.opcode = Opcode::ENCLS; + } + _ => { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } + } } } else { instruction.opcode = Opcode::SIDT; @@ -8398,8 +8385,12 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter } } OperandCode::ModRM_0x0fae => { + let modrm = read_modrm(&mut bytes_iter, length)?; + let r = (modrm >> 3) & 7; + let m = modrm & 7; + if instruction.prefixes.operand_size() && !(instruction.prefixes.rep() || instruction.prefixes.repnz()) { - let modrm = read_modrm(&mut bytes_iter, length)?; + instruction.prefixes.unset_operand_size(); if modrm < 0xc0 { instruction.opcode = match (modrm >> 3) & 7 { 6 => { @@ -8416,17 +8407,45 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 1 /* opwidth */, length)?; instruction.operand_count = 1; } else { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); + instruction.opcode = match (modrm >> 3) & 7 { + 6 => { + Opcode::TPAUSE + } + _ => { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } + }; + let opwidth = if instruction.prefixes.rex().w() { 8 } else { 4 }; + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; + instruction.operand_count = 1; } return Ok(()); } - if instruction.prefixes.rep() { - let modrm = read_modrm(&mut bytes_iter, length)?; - let r = (modrm >> 3) & 7; + if instruction.prefixes.repnz() { + if (modrm & 0xc0) == 0xc0 { + match r { + 6 => { + instruction.opcode = Opcode::UMWAIT; + instruction.modrm_rrr = RegSpec { + bank: if instruction.prefixes.rex().w() { RegisterBank::Q } else { RegisterBank::D }, + num: m + if instruction.prefixes.rex().x() { 0b1000 } else { 0 }, + }; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operand_count = 1; + } + _ => { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } + } + return Ok(()); + } + } + if instruction.prefixes.rep() { if r == 4 { if instruction.prefixes.operand_size() { // xed specifically rejects this. seeems out of line since rep takes @@ -8444,7 +8463,6 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter return Ok(()); } if (modrm & 0xc0) == 0xc0 { - let m = modrm & 7; match r { 0 => { instruction.opcode = Opcode::RDFSBASE; @@ -8491,6 +8509,15 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = OperandSpec::RegMMM; instruction.operand_count = 1; } + 6 => { + instruction.opcode = Opcode::UMONITOR; + instruction.modrm_rrr = RegSpec { + bank: RegisterBank::Q, + num: m + if instruction.prefixes.rex().x() { 0b1000 } else { 0 }, + }; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operand_count = 1; + } _ => { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); @@ -8502,15 +8529,12 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter } } - let modrm = read_modrm(&mut bytes_iter, length)?; - let r = (modrm >> 3) & 7; let mod_bits = modrm >> 6; // all the 0b11 instructions are err or no-operands if mod_bits == 0b11 { instruction.operands[0] = OperandSpec::Nothing; instruction.operand_count = 0; - let m = modrm & 7; match r { // invalid rrr for 0x0fae, mod: 11 0 | 1 | 2 | 3 | 4 => { -- cgit v1.1