diff options
| author | iximeow <me@iximeow.net> | 2020-07-27 03:17:48 -0700 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2020-08-09 01:38:57 -0700 | 
| commit | 84c064bb7a3b0558e80fdc9c293cd4020d8d0c6b (patch) | |
| tree | d57127a20b920fcb24b5081e373a28d9463984dd /src/long_mode | |
| parent | 27da859a6361bf584d2a76e9bc0b6a5a26e788f4 (diff) | |
probably not
Diffstat (limited to 'src/long_mode')
| -rw-r--r-- | src/long_mode/mod.rs | 34 | ||||
| -rw-r--r-- | src/long_mode/vex.rs | 28 | 
2 files changed, 44 insertions, 18 deletions
| diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index a23b470..5ec89dc 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -5517,6 +5517,8 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,          instruction.operand_count = 0;          return Ok(());      } +    instruction.operand_count = 2; +    instruction.operands[0] = OperandSpec::RegRRR;      let operand_code = OperandCodeBuilder::from_bits(operand_code as u16);      if operand_code.has_embedded_instructions() {          match operand_code.get_embedded_instructions() { @@ -5533,7 +5535,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,                          } else {                              RegisterBank::Q                          }; -                        instruction.operands[0] = OperandSpec::RegRRR;                          instruction.modrm_rrr =                              RegSpec::from_parts(reg, instruction.prefixes.rex().b(), bank);                          instruction.operand_count = 1; @@ -5543,7 +5544,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,                      }                      2 => {                          // these are Zb_Ib_R -                        instruction.operands[0] = OperandSpec::RegRRR;                          instruction.modrm_rrr =                              RegSpec::gp_from_parts(reg, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present());                          instruction.imm = @@ -5561,7 +5561,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,                          } else {                              RegisterBank::Q                          }; -                        instruction.operands[0] = OperandSpec::RegRRR;                          instruction.modrm_rrr =                              RegSpec::from_parts(reg, instruction.prefixes.rex().b(), bank);                          instruction.imm = @@ -5583,7 +5582,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,              },              Err(embedded_operand_instructions) => {                  if operand_code.op0_is_rrr() { -                    instruction.operands[0] = OperandSpec::RegRRR;                  }              }          } @@ -5626,7 +5624,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,          };          instruction.operands[mmm] = mem_oper;          instruction.operands[rrr] = OperandSpec::RegRRR; -        instruction.operand_count = 2;      } else if operand_code.bits() == OperandCode::Ibs as u16 {          instruction.imm =              read_imm_signed(&mut bytes_iter, 1, length)? as u64; @@ -5997,7 +5994,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,              instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;              instruction.modrm_rrr =                  RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); -            instruction.operands[0] = OperandSpec::RegRRR;              instruction.imm =                  read_num(&mut bytes_iter, 1)? as u8 as u64;              *length += 1; @@ -6007,7 +6003,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,          OperandCode::G_E_mm_Ib => {              instruction.operands[1] = mem_oper;              instruction.modrm_rrr = RegSpec { bank: RegisterBank::MM, num: (modrm >> 3) & 7 }; -            instruction.operands[0] = OperandSpec::RegRRR;              instruction.imm =                  read_num(&mut bytes_iter, 1)? as u8 as u64;              *length += 1; @@ -6024,7 +6019,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,              instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;              instruction.modrm_rrr =                  RegSpec::from_parts((modrm >> 3) & 7, false, RegisterBank::MM); -            instruction.operands[0] = OperandSpec::RegRRR;              if instruction.operands[1] == OperandSpec::RegMMM {                  instruction.modrm_mmm.bank = RegisterBank::D;              } @@ -6084,7 +6078,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,              instruction.operands[0] = OperandSpec::ImmI32;          }          OperandCode::Gb_Eb_Ib => { -            instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = mem_oper;              instruction.imm =                  read_imm_signed(&mut bytes_iter, 1, length)? as u64; @@ -6094,7 +6087,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,          OperandCode::Gv_Ev_Iv => {              let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);              let numwidth = if opwidth == 8 { 4 } else { opwidth }; -            instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = mem_oper;              instruction.imm =                  read_imm_signed(&mut bytes_iter, numwidth, length)? as u64; @@ -6150,7 +6142,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              let modrm = read_modrm(&mut bytes_iter, 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)?;              if instruction.prefixes.rex().w() {                  let op = instruction.operands[0]; @@ -6427,7 +6418,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              }              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;          } @@ -6442,7 +6432,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              }              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;          } @@ -6510,7 +6499,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                  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;          } @@ -6540,7 +6528,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                          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, length)?; @@ -6556,7 +6543,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                          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, length)?; @@ -6887,6 +6873,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter          OperandCode::G_xmm_Ed_Ib => {              instruction.operands[1] = mem_oper;              instruction.operands[2] = OperandSpec::ImmU8; +            instruction.operand_count = 3;              instruction.imm =                  read_num(&mut bytes_iter, 1)? as u64;              *length += 1; @@ -6926,6 +6913,7 @@ 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.operand_count = 3;              instruction.imm =                  read_num(&mut bytes_iter, 1)? as u64;              *length += 1; @@ -6970,7 +6958,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                  _ => { unreachable!(); }              };              instruction.modrm_mmm = RegSpec::rsi(); -            instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = OperandSpec::Deref;          }          OperandCode::Yv_AX => { @@ -7016,6 +7003,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              }              let rrr = instruction.modrm_rrr.num & 0b111;              instruction.operands[0] = mem_oper; +            instruction.operand_count = 1;              instruction.opcode = match rrr {                  0 => Opcode::PREFETCHNTA,                  1 => Opcode::PREFETCH0, @@ -7097,6 +7085,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter          },          OperandCode::CVT_AA => {              let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); +            instruction.operands[0] = OperandSpec::Nothing; +            instruction.operand_count = 0;              instruction.opcode = match opwidth {                  2 => { Opcode::CBW },                  4 => { Opcode::CWDE }, @@ -7106,6 +7096,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter          }          OperandCode::CVT_DA => {              let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); +            instruction.operands[0] = OperandSpec::Nothing; +            instruction.operand_count = 0;              instruction.opcode = match opwidth {                  2 => { Opcode::CWD },                  4 => { Opcode::CDQ }, @@ -7624,9 +7616,15 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              instruction.operand_count = 2;          }          _ => { +            // TODO: this should be unreachable - safe to panic now? +            // can't simply delete this arm because the non-unlikely operands are handled outside +            // here, and some operands are entirely decoded before reaching match in the first +            // place. +            // perhaps fully-decoded operands could be a return here? they would be jump table +            // entries anyway, so no extra space for the dead arms. +            instruction.operands[0] = OperandSpec::Nothing;              instruction.operand_count = 0;              instruction.opcode = Opcode::Invalid; -//            return Err(()); // Err(format!("unsupported operand code: {:?}", operand_code));              return Err(DecodeError::InvalidOperand);          }      }; diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs index cf30622..c944532 100644 --- a/src/long_mode/vex.rs +++ b/src/long_mode/vex.rs @@ -352,9 +352,11 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst                  OperandSpec::RegMMM => {                      instruction.operands[1] = OperandSpec::RegVex;                      instruction.operands[2] = OperandSpec::RegMMM; +                    instruction.operand_count = 3;                  },                  other => {                      instruction.operands[1] = other; +                    instruction.operand_count = 2;                  }              }              Ok(()) @@ -370,9 +372,11 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst                  OperandSpec::RegMMM => {                      instruction.operands[0] = OperandSpec::RegVex;                      instruction.operands[2] = OperandSpec::RegMMM; +                    instruction.operand_count = 3;                  },                  other => {                      instruction.operands[0] = other; +                    instruction.operand_count = 2;                  }              }              Ok(()) @@ -392,6 +396,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.operands[0] = mem_oper;              instruction.operands[1] = OperandSpec::RegRRR;              instruction.operands[2] = OperandSpec::ImmU8; +            instruction.operand_count = 3;              instruction.imm = read_imm_unsigned(bytes, 1, length)?;              Ok(())          }, @@ -406,6 +411,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              let mem_oper = read_E(bytes, instruction, modrm, 8, length)?;              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = mem_oper; +            instruction.operand_count = 2;              Ok(())          }          VEXOperandCode::G_xmm_Ed => { @@ -419,6 +425,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = mem_oper; +            instruction.operand_count = 2;              Ok(())          }          VEXOperandCode::Eq_G_xmm => { @@ -432,6 +439,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              let mem_oper = read_E(bytes, instruction, modrm, 8, length)?;              instruction.operands[0] = mem_oper;              instruction.operands[1] = OperandSpec::RegRRR; +            instruction.operand_count = 2;              Ok(())          }          VEXOperandCode::Ed_G_xmm => { @@ -445,6 +453,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;              instruction.operands[0] = mem_oper;              instruction.operands[1] = OperandSpec::RegRRR; +            instruction.operand_count = 2;              Ok(())          }          _op @ VEXOperandCode::E_G_xmm | @@ -462,6 +471,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;              instruction.operands[0] = mem_oper;              instruction.operands[1] = OperandSpec::RegRRR; +            instruction.operand_count = 2;              Ok(())          }          _op @ VEXOperandCode::E_xmm_G_ymm_imm8 => { @@ -475,6 +485,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;              instruction.operands[0] = mem_oper;              instruction.operands[1] = OperandSpec::RegRRR; +            instruction.operand_count = 2;              Ok(())          } @@ -492,6 +503,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = mem_oper; +            instruction.operand_count = 2;              Ok(())          }          _op @ VEXOperandCode::G_xmm_E_xmm => { @@ -505,6 +517,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = mem_oper; +            instruction.operand_count = 2;              Ok(())          }          _op @ VEXOperandCode::G_xmm_E_ymm => { @@ -518,6 +531,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = mem_oper; +            instruction.operand_count = 2;              Ok(())          }          _op @ VEXOperandCode::G_ymm_E_xmm => { @@ -531,6 +545,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = mem_oper; +            instruction.operand_count = 2;              Ok(())          }          _op @ VEXOperandCode::G_ymm_E_ymm => { @@ -544,6 +559,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = mem_oper; +            instruction.operand_count = 2;              Ok(())          } @@ -560,6 +576,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;              instruction.operands[0] = mem_oper;              instruction.operands[1] = OperandSpec::RegRRR; +            instruction.operand_count = 2;              Ok(())          } @@ -576,6 +593,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = mem_oper; +            instruction.operand_count = 2;              Ok(())          }          _op @ VEXOperandCode::G_V_E_ymm | @@ -588,6 +606,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = OperandSpec::RegVex;              instruction.operands[2] = mem_oper; +            instruction.operand_count = 3;              Ok(())          }          _op @ VEXOperandCode::G_V_E_ymm_imm8 => { @@ -601,6 +620,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.operands[2] = mem_oper;              instruction.imm = read_imm_unsigned(bytes, 1, length)?;              instruction.operands[3] = OperandSpec::ImmU8; +            instruction.operand_count = 4;              Ok(())          }          _op @ VEXOperandCode::E_V_G_ymm | @@ -613,6 +633,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.operands[0] = mem_oper;              instruction.operands[1] = OperandSpec::RegVex;              instruction.operands[2] = OperandSpec::RegRRR; +            instruction.operand_count = 3;              Ok(())          }          _op @ VEXOperandCode::G_V_M_xmm | @@ -624,6 +645,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = OperandSpec::RegVex;              instruction.operands[2] = mem_oper; +            instruction.operand_count = 3;              Ok(())          }          _op @ VEXOperandCode::G_V_E_xmm_imm8 => { @@ -636,6 +658,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.operands[2] = mem_oper;              instruction.imm = read_imm_unsigned(bytes, 1, length)?;              instruction.operands[3] = OperandSpec::ImmU8; +            instruction.operand_count = 4;              Ok(())          }          _op @ VEXOperandCode::V_ymm_G_ymm_E_xmm_imm8 => { @@ -649,6 +672,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.operands[2] = mem_oper;              instruction.imm = read_imm_unsigned(bytes, 1, length)?;              instruction.operands[3] = OperandSpec::ImmU8; +            instruction.operand_count = 4;              Ok(())          }          _op @ VEXOperandCode::V_xmm_G_ymm_E_ymm_imm8 => { @@ -661,6 +685,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.operands[2] = mem_oper;              instruction.imm = read_imm_unsigned(bytes, 1, length)?;              instruction.operands[3] = OperandSpec::ImmU8; +            instruction.operand_count = 4;              Ok(())          }          _op @ VEXOperandCode::E_V_G_xmm | @@ -672,6 +697,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.operands[0] = mem_oper;              instruction.operands[1] = OperandSpec::RegVex;              instruction.operands[2] = OperandSpec::RegRRR; +            instruction.operand_count = 3;              Ok(())          } @@ -684,6 +710,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = mem_oper;              instruction.operands[2] = OperandSpec::RegVex; +            instruction.operand_count = 3;              Ok(())          }          VEXOperandCode::G_Ey_V_ymm => { @@ -696,6 +723,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = mem_oper;              instruction.operands[2] = OperandSpec::RegVex; +            instruction.operand_count = 3;              Ok(())          }          VEXOperandCode::G_V_E => { | 
