diff options
Diffstat (limited to 'src/long_mode/mod.rs')
-rw-r--r-- | src/long_mode/mod.rs | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 3b2b68d..1d7148c 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -4534,6 +4534,7 @@ pub struct Prefixes { rex: PrefixRex, segment: Segment, evex_data: EvexData, + vqp_size: RegisterBank, } /// the `avx512`-related data from an [`evex`](https://en.wikipedia.org/wiki/EVEX_prefix) prefix. @@ -4610,6 +4611,7 @@ impl Prefixes { rex: PrefixRex { bits: 0 }, segment: Segment::DS, evex_data: EvexData { bits: 0 }, + vqp_size: RegisterBank::D, } } #[inline] @@ -4625,9 +4627,19 @@ impl Prefixes { #[inline] fn operand_size(&self) -> bool { self.bits & 0x1 == 1 } #[inline] - fn set_operand_size(&mut self) { self.bits = self.bits | 0x1 } + fn set_operand_size(&mut self) { + self.bits = self.bits | 0x1; + self.vqp_size = RegisterBank::W; + } #[inline] - fn unset_operand_size(&mut self) { self.bits = self.bits & !0x1 } + fn unset_operand_size(&mut self) { + self.bits = self.bits & !0x1; + if self.rex.w() { + self.vqp_size = RegisterBank::Q; + } else { + self.vqp_size = RegisterBank::D; + } + } #[inline] fn address_size(&self) -> bool { self.bits & 0x2 == 2 } #[inline] @@ -4703,6 +4715,15 @@ impl Prefixes { self.rex.bits = bits; } + #[inline(always)] + fn vqp_size(&self) -> RegisterBank { + if self.rex.w() { + RegisterBank::Q + } else { + self.vqp_size + } + } + #[inline] fn vex_from_c5(&mut self, bits: u8) { // collect rex bits @@ -6844,7 +6865,7 @@ fn read_operands< // cool! we can precompute width and know we need to read_E. if !operand_code.has_byte_operands() { // further, this is an vdq E - bank = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); + bank = instruction.prefixes.vqp_size(); instruction.regs[0].bank = bank; instruction.mem_size = bank as u8; r = if instruction.prefixes.rex_unchecked().r() { 0b1000 } else { 0 }; @@ -6909,7 +6930,7 @@ fn read_operands< // cool! we can precompute width and know we need to read_E. if !operand_code.has_byte_operands() { // further, this is an vdq E - bank = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); + bank = instruction.prefixes.vqp_size(); instruction.mem_size = bank as u8; opwidth = bank as u8; } else { @@ -7023,7 +7044,7 @@ fn read_operands< instruction.operand_count = 0; return Ok(()); } - let bank = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); + let bank = instruction.prefixes.vqp_size(); // always *ax, but size is determined by prefixes (or lack thereof) instruction.regs[0] = RegSpec::from_parts(0, false, bank); @@ -7095,7 +7116,7 @@ fn read_operands< } 3 => { // category == 3, Zv_Ivq_R - let bank = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); + let bank = instruction.prefixes.vqp_size(); instruction.regs[0] = RegSpec::from_parts(reg, instruction.prefixes.rex_unchecked().b(), bank); sink.record( @@ -7436,7 +7457,7 @@ fn read_operands< instruction.mem_size = 2; RegisterBank::W }; - let bank = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); + let bank = instruction.prefixes.vqp_size(); let modrm = read_modrm(words)?; instruction.operands[1] = read_E(words, instruction, modrm, w, sink)?; @@ -7558,7 +7579,7 @@ fn read_operands< instruction.operands[1] = OperandSpec::ImmI8; } 24 => { - let bank = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); + let bank = instruction.prefixes.vqp_size(); let numwidth = if bank as u8 == 8 { 4 } else { bank as u8 }; instruction.regs[0] = RegSpec::gp_from_parts_non_byte(0, false, bank); |