diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 230 | 
1 files changed, 21 insertions, 209 deletions
| @@ -763,41 +763,35 @@ const BITWISE_OPCODE_MAP: [Opcode; 8] = [      Opcode::SAL,      Opcode::SAR  ]; -fn read_opcode_660f_map<T: Iterator<Item=u8>>(_bytes_iter: &mut T, _instruction: &mut Instruction, _prefixes: Prefixes, _length: &mut u8) -> Result<OperandCode, String> { +fn read_opcode_660f_map<T: Iterator<Item=u8>>(_bytes_iter: &mut T, _instruction: &mut Instruction, _length: &mut u8) -> Result<OperandCode, String> {      Err("660f opcode map unsupported".to_string())  } -fn read_opcode_f20f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instruction, prefixes: Prefixes, length: &mut u8) -> Result<OperandCode, String> { +fn read_opcode_f20f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instruction, length: &mut u8) -> Result<OperandCode, String> {      match bytes_iter.next() {          Some(b) => {              *length += 1;              match b {                  0x10 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOVSD;                      Ok(OperandCode::G_E_xmm)                  },                  0x11 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOVSD;                      Ok(OperandCode::E_G_xmm)                  },                  0x12 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOVDDUP;                      Ok(OperandCode::G_E_xmm)                  },                  0x2a => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CVTSI2SD;                      Ok(OperandCode::G_E_xmm)                  },                  0x2c => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CVTTSD2SI;                      Ok(OperandCode::G_E_xmm)                  },                  0x2d => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CVTSD2SI;                      Ok(OperandCode::G_E_xmm)                  }, @@ -809,62 +803,50 @@ fn read_opcode_f20f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &                      Err("x86_64 CRC32 not currently supported".to_string())                  }                  0x51 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::SQRTSD;                      Ok(OperandCode::G_E_xmm)                  },                  0x58 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::ADDSD;                      Ok(OperandCode::G_E_xmm)                  },                  0x59 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MULSD;                      Ok(OperandCode::G_E_xmm)                  },                  0x5a => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CVTSD2SS;                      Ok(OperandCode::G_E_xmm)                  },                  0x5c => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::SUBSD;                      Ok(OperandCode::G_E_xmm)                  },                  0x5d => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MINSD;                      Ok(OperandCode::G_E_xmm)                  },                  0x5e => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::DIVSD;                      Ok(OperandCode::G_E_xmm)                  },                  0x5f => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MAXSD;                      Ok(OperandCode::G_E_xmm)                  },                  0x7c => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::HADDPS;                      Ok(OperandCode::G_E_xmm)                  },                  0x7d => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::HSUBPS;                      Ok(OperandCode::G_E_xmm)                  },                  0xD0 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::ADDSUBPS;                      Ok(OperandCode::G_E_xmm)                  },                  0xf0 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::LDDQU;                      Ok(OperandCode::G_E_xmm)                  }, @@ -875,7 +857,6 @@ fn read_opcode_f20f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &                  0xe6 CVTPD2DQ                  */                  _ => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::Invalid;                      Err("Invalid opcode".to_string())                  } @@ -886,83 +867,68 @@ fn read_opcode_f20f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &          }      }  } -fn read_opcode_f30f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instruction, prefixes: Prefixes, length: &mut u8) -> Result<OperandCode, String> { +fn read_opcode_f30f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instruction, length: &mut u8) -> Result<OperandCode, String> {      match bytes_iter.next() {          Some(b) => {              *length += 1;              match b {                  0x10 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOVSS;                      Ok(OperandCode::G_E_xmm)                  },                  0x11 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOVSS;                      Ok(OperandCode::E_G_xmm)                  },                  0x12 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOVSLDUP;                      Ok(OperandCode::G_E_xmm)                  },                  0x2a => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CVTSI2SS;                      Ok(OperandCode::G_E_xmm)                  },                  0x2c => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CVTTSS2SI;                      Ok(OperandCode::G_E_xmm)                  },                  0x2d => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CVTSS2SI;                      Ok(OperandCode::G_E_xmm)                  },                  0x51 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::SQRTSS;                      Ok(OperandCode::G_E_xmm)                  },                  0x58 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::ADDSS;                      Ok(OperandCode::G_E_xmm)                  },                  0x59 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MULSS;                      Ok(OperandCode::G_E_xmm)                  },                  0x5a => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CVTSS2SD;                      Ok(OperandCode::G_E_xmm)                  },                  0x5c => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::SUBSS;                      Ok(OperandCode::G_E_xmm)                  },                  0x5d => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MINSS;                      Ok(OperandCode::G_E_xmm)                  },                  0x5e => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::DIVSS;                      Ok(OperandCode::G_E_xmm)                  },                  0x5f => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MAXSS;                      Ok(OperandCode::G_E_xmm)                  },                  _ => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::Invalid;                      Err("Invalid opcode".to_string())                  } @@ -973,271 +939,218 @@ fn read_opcode_f30f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &          }      }  } -fn read_opcode_0f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instruction, prefixes: Prefixes, length: &mut u8) -> Result<OperandCode, String> { +fn read_opcode_0f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instruction, length: &mut u8) -> Result<OperandCode, String> {      match bytes_iter.next() {          Some(b) => {              *length += 1;              match b {                  0x00 => { -                    instruction.prefixes = prefixes;                      Ok(OperandCode::ModRM_0x0f00)                  }                  0x01 => { -                    instruction.prefixes = prefixes;                      Ok(OperandCode::ModRM_0x0f01)                  }                  0x02 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::LAR;                      Ok(OperandCode::Gv_M)                  }                  0x03 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::LSL;                      Ok(OperandCode::Gv_M)                  }                  0x05 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::SYSCALL;                      Ok(OperandCode::Nothing)                  }                  0x06 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CLTS;                      Ok(OperandCode::Nothing)                  }                  0x07 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::SYSRET;                      Ok(OperandCode::Nothing)                  }                  0x08 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::INVD;                      Ok(OperandCode::Nothing)                  }                  0x09 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::WBINVD;                      Ok(OperandCode::Nothing)                  }                  0x0b => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::UD2;                      Ok(OperandCode::Nothing)                  }                  0x0d => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::NOP;                      Ok(OperandCode::Ev)                  }                  0x1f => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::NOP;                      Ok(OperandCode::Ev)                  },                  0x20 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOV;                      Ok(OperandCode::Rq_Cq_0)                  },                  0x21 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOV;                      Ok(OperandCode::Rq_Dq_0)                  },                  0x22 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOV;                      Ok(OperandCode::Cq_Rq_0)                  },                  0x23 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOV;                      Ok(OperandCode::Dq_Rq_0)                  },                  0x30 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::WRMSR;                      Ok(OperandCode::Nothing)                  },                  0x31 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::RDTSC;                      Ok(OperandCode::Nothing)                  },                  0x32 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::RDMSR;                      Ok(OperandCode::Nothing)                  },                  0x33 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::RDPMC;                      Ok(OperandCode::Nothing)                  },                  0x40 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVO;                      Ok(OperandCode::Gv_Ev)                  },                  0x41 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVNO;                      Ok(OperandCode::Gv_Ev)                  },                  0x42 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVB;                      Ok(OperandCode::Gv_Ev)                  },                  0x43 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVNB;                      Ok(OperandCode::Gv_Ev)                  },                  0x44 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVZ;                      Ok(OperandCode::Gv_Ev)                  },                  0x45 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVNZ;                      Ok(OperandCode::Gv_Ev)                  },                  0x46 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVNA;                      Ok(OperandCode::Gv_Ev)                  },                  0x47 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVA;                      Ok(OperandCode::Gv_Ev)                  },                  0x48 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVS;                      Ok(OperandCode::Gv_Ev)                  },                  0x49 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVNS;                     Ok(OperandCode::Gv_Ev)                  },                  0x4a => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVP;                      Ok(OperandCode::Gv_Ev)                  },                  0x4b => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVNP;                      Ok(OperandCode::Gv_Ev)                  },                  0x4c => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVL;                      Ok(OperandCode::Gv_Ev)                  },                  0x4d => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVGE;                      Ok(OperandCode::Gv_Ev)                  },                  0x4e => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVLE;                      Ok(OperandCode::Gv_Ev)                  },                  0x4f => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMOVG;                      Ok(OperandCode::Gv_Ev)                  },                  0x80 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JO;                      Ok(OperandCode::Jvds)                  },                  0x81 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JNO;                      Ok(OperandCode::Jvds)                  },                  0x82 => { -                    instruction.prefixes = prefixes;                     instruction.opcode = Opcode::JB;                      Ok(OperandCode::Jvds)                  },                  0x83 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JNB;                      Ok(OperandCode::Jvds)                  },                  0x84 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JZ;                      Ok(OperandCode::Jvds)                  },                  0x85 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JNZ;                      Ok(OperandCode::Jvds)                  },                  0x86 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JNA;                      Ok(OperandCode::Jvds)                  },                  0x87 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JA;                      Ok(OperandCode::Jvds)                  },                  0x88 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JS;                      Ok(OperandCode::Jvds)                  },                  0x89 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JNS;                      Ok(OperandCode::Jvds)                  },                  0x8a => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JP;                      Ok(OperandCode::Jvds)                  },                  0x8b => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JNP;                      Ok(OperandCode::Jvds)                  },                  0x8c => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JL;                      Ok(OperandCode::Jvds)                  },                  0x8d => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JGE;                      Ok(OperandCode::Jvds)                  },                  0x8e => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JLE;                      Ok(OperandCode::Jvds)                  },                  0x8f => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::JG;                      Ok(OperandCode::Jvds)                  },                  x if x < 0xa0 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = [                          Opcode::SETO,                          Opcode::SETNO, @@ -1259,100 +1172,80 @@ fn read_opcode_0f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mu                      Ok(OperandCode::Eb_R0)                  }                  0xa0 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::PUSH;                      Ok(OperandCode::FS)                  }                  0xa1 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::POP;                      Ok(OperandCode::GS)                  }                  0xa2 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CPUID;                      Ok(OperandCode::Nothing)                  }                  0xa3 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::BT;                      Ok(OperandCode::Gv_Ev)                  }                  0xa8 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::PUSH;                      Ok(OperandCode::Nothing)                  }                  0xa9 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::PUSH;                      Ok(OperandCode::GS)                  }                  0xae => { -                    instruction.prefixes = prefixes;                      Ok(OperandCode::ModRM_0x0fae)                  }                  0xaf => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::IMUL;                      Ok(OperandCode::Gv_Ev)                  }                  0xb0 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMPXCHG;                      Ok(OperandCode::Eb_Gb)                  },                  0xb1 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::CMPXCHG;                      Ok(OperandCode::Ev_Gv)                  }                  0xb6 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOVZX_b;                      Ok(OperandCode::Gv_Eb)                  },                  0xb7 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOVZX_w;                      Ok(OperandCode::Gv_Ew)                  }                  0xba => { -                    instruction.prefixes = prefixes;                      Ok(OperandCode::ModRM_0x0fba)                  }                  0xbb => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::BTC;                      Ok(OperandCode::Gv_Ev)                  }                  0xbc => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::BSF;                      Ok(OperandCode::Gv_Ev)                  }                  0xbd => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::BSR;                      Ok(OperandCode::Gv_Ev)                  }                  0xbe => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOVSX_b;                      Ok(OperandCode::Gv_Eb)                  }                  0xbf => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::MOVSX_w;                      Ok(OperandCode::Gv_Ew)                  }                  0xc0 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::XADD;                      Ok(OperandCode::Eb_Gb)                  }                  0xc1 => { -                    instruction.prefixes = prefixes;                      instruction.opcode = Opcode::XADD;                      Ok(OperandCode::Ev_Gv)                  } @@ -1371,7 +1264,7 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr      let mut alternate_opcode_map: Option<OpcodeMap> = None;      use std::hint::unreachable_unchecked;  //    use std::intrinsics::unlikely; -    let mut prefixes = Prefixes::new(0); +    instruction.prefixes = Prefixes::new(0);      loop {          match bytes_iter.next() {              Some(b) => { @@ -1385,33 +1278,33 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr                                  0x0f => {                                      return match alternate_opcode_map {                                          Some(OpcodeMap::Map66) => { -                                            read_opcode_660f_map(bytes_iter, instruction, prefixes, length) +                                            read_opcode_660f_map(bytes_iter, instruction, length)                                          },                                          Some(OpcodeMap::MapF2) => { -                                            read_opcode_f20f_map(bytes_iter, instruction, prefixes, length) +                                            read_opcode_f20f_map(bytes_iter, instruction, length)                                          },                                          Some(OpcodeMap::MapF3) => { -                                            read_opcode_f30f_map(bytes_iter, instruction, prefixes, length) +                                            read_opcode_f30f_map(bytes_iter, instruction, length)                                          },                                          None => { -                                            read_opcode_0f_map(bytes_iter, instruction, prefixes, length) +                                            read_opcode_0f_map(bytes_iter, instruction, length)                                          }                                      };                                  },                                  0x26 => { -                                    prefixes.set_es(); +                                    instruction.prefixes.set_es();                                      alternate_opcode_map = None;                                  },                                  0x2e => { -                                    prefixes.set_cs(); +                                    instruction.prefixes.set_cs();                                      alternate_opcode_map = None;                                  },                                  0x36 => { -                                    prefixes.set_ss(); +                                    instruction.prefixes.set_ss();                                      alternate_opcode_map = None;                                  },                                  0x3e => { -                                    prefixes.set_ds(); +                                    instruction.prefixes.set_ds();                                      alternate_opcode_map = None;                                  },                                  0x06 @@ -1425,7 +1318,6 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr                                  | 0x2f                                  | 0x37                                  | 0x3f => { -                                    instruction.prefixes = prefixes;                                      instruction.opcode = Opcode::Invalid;                                      return Ok(OperandCode::Nothing);                                  }, @@ -1443,79 +1335,68 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr                              OperandCode::AX_Ivd                          ][(x % 8) as usize].clone(); -                        instruction.prefixes = prefixes;                          instruction.opcode = op;                          return Ok(operand_code);                      },                      x if x < 0x50 => {                          // x86_32 inc/dec                          // x86_64 rex -                        prefixes.rex_mut().from(x); +                        instruction.prefixes.rex_mut().from(x);                      },                      x if x < 0x60 => {                          let op = if x < 0x58 { Opcode::PUSH } else { Opcode::POP }; -                        instruction.prefixes = prefixes;                          instruction.opcode = op;                          return Ok(OperandCode::Zv(x));                      },                      0x63 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOVSXD;                          return Ok(OperandCode::Gv_Ed);                      },                      0x64 => { -                        prefixes.set_fs(); +                        instruction.prefixes.set_fs();                          alternate_opcode_map = None;                      },                      0x65 => { -                        prefixes.set_gs(); +                        instruction.prefixes.set_gs();                          alternate_opcode_map = None;                      },                      0x66 => { -                        prefixes.set_operand_size(); +                        instruction.prefixes.set_operand_size();                          alternate_opcode_map = Some(OpcodeMap::Map66);                      },                      0x67 => { -                        prefixes.set_address_size(); +                        instruction.prefixes.set_address_size();                          alternate_opcode_map = None;                      },                      0x68 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::PUSH;                          return Ok(OperandCode::Ivs);                      },                      0x69 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::IMUL;                          return Ok(OperandCode::Gv_Ev_Iv);                      },                      0x6a => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::PUSH;                          return Ok(OperandCode::Ibs);                      },                      0x6b => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::IMUL;                          return Ok(OperandCode::Gb_Eb_Ib);                      },                      0x6c => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::INS;                          return Ok(OperandCode::Yb_DX);                      },                      0x6d => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::INS;                          return Ok(OperandCode::Yv_DX);                      },                      0x6e => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::OUTS;                          return Ok(OperandCode::DX_Xb);                      },                      0x6f => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::OUTS;                          return Ok(OperandCode::DX_Xv);                      }, @@ -1538,7 +1419,6 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr                              Opcode::JLE,                              Opcode::JG                          ][(x & 0xf) as usize].clone(); -                        instruction.prefixes = prefixes;                          instruction.opcode = op;                          return Ok(OperandCode::Jbs);                      } @@ -1555,194 +1435,156 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr                              } else {                                  OperandCode::ModRM_0x83_Ev_Ibs                              }; -                            instruction.prefixes = prefixes;                              instruction.opcode = op;                              return Ok(operand);                          }                      },                      0x84 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::TEST;                          return Ok(OperandCode::Eb_Gb);                      },                      0x85 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::TEST;                          return Ok(OperandCode::Ev_Gv);                      },                      0x86 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::XCHG;                          return Ok(OperandCode::Gb_Eb);                      },                      0x87 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::XCHG;                          return Ok(OperandCode::Gv_Ev);                      },                      0x88 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOV;                          return Ok(OperandCode::Eb_Gb);                      }                      0x89 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOV;                          return Ok(OperandCode::Ev_Gv);                      }                      0x8a => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOV;                          return Ok(OperandCode::Gb_Eb);                      }                      0x8b => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOV;                          return Ok(OperandCode::Gv_Ev);                      }                      0x8c => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOV;                          return Ok(OperandCode::Ew_Sw);                      }                      0x8d => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::LEA;                          return Ok(OperandCode::Gv_M);                      }                      0x8e => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOV;                          return Ok(OperandCode::Sw_Ew);                      },                      0x8f => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::Invalid;                          return Ok(OperandCode::ModRM_0x8f_Ev);                      },                      0x90 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::NOP;                          return Ok(OperandCode::Nothing);                      },                      x if x < 0x98 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::XCHG;                          return Ok(OperandCode::Zv_AX(x));                      },                      0x98 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::CBW;                          return Ok(OperandCode::AX_AL);                      },                      0x99 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::CBW;                          return Ok(OperandCode::DX_AX);                      },                      0x9a => { return Err("invalid opcode".to_owned()); },                      0x9b => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::WAIT;                          return Ok(OperandCode::Nothing);                      }                      0x9c => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::PUSHF;                          return Ok(OperandCode::Nothing);                      },                      0x9d => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::POPF;                          return Ok(OperandCode::Nothing);                      },                      0x9e => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::SAHF;                          return Ok(OperandCode::AH);                      },                      0x9f => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::LAHF;                          return Ok(OperandCode::AH);                      },                      0xa0 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOV;                          return Ok(OperandCode::AL_Ob);                      },                      0xa1 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOV;                          return Ok(OperandCode::AX_Ov);                      },                      0xa2 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOV;                          return Ok(OperandCode::Ob_AL);                      },                      0xa3 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOV;                          return Ok(OperandCode::Ov_AX);                      },                      0xa4 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOVS;                          return Ok(OperandCode::Yb_Xb);                      },                      0xa5 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOVS;                          return Ok(OperandCode::Yv_Xv);                      },                      0xa6 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::CMPS;                          return Ok(OperandCode::Yb_Xb);                      },                      0xa7 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::CMPS;                          return Ok(OperandCode::Yv_Xv);                      },                      0xa8 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::TEST;                          return Ok(OperandCode::AL_Ib);                      },                      0xa9 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::TEST;                          return Ok(OperandCode::AX_Ivd);                      },                      0xaa => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::STOS;                          return Ok(OperandCode::Yb_AL);                      },                      0xab => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::STOS;                          return Ok(OperandCode::Yv_AX);                      },                      0xac => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::LODS;                          return Ok(OperandCode::AL_Xb);                      },                      0xad => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::LODS;                          return Ok(OperandCode::AX_Xv);                      },                      0xae => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::SCAS;                          return Ok(OperandCode::Yb_AL);                      },                      0xaf => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::SCAS;                          return Ok(OperandCode::Yv_AX);                      }, @@ -1752,27 +1594,22 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr                          } else {                              OperandCode::Zv_Ivq(x)                          }; -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOV;                          return Ok(operand);                      },                      0xc0 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::Invalid;                          return Ok(OperandCode::ModRM_0xc0_Eb_Ib);                      },                      0xc1 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::Invalid;                          return Ok(OperandCode::ModRM_0xc1_Ev_Ib);                      },                      0xc2 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::RETURN;                          return Ok(OperandCode::Iw);                      },                      0xc3 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::RETURN;                          return Ok(OperandCode::Nothing);                      }, @@ -1780,52 +1617,42 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr                          return Err("invalid opcode".to_owned());                      },                      0xc6 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOV;                          return Ok(OperandCode::ModRM_0xc6_Eb_Ib);                      },                      0xc7 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::MOV;                          return Ok(OperandCode::ModRM_0xc7_Ev_Iv);                      },                      0xc8 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::ENTER;                          return Ok(OperandCode::Iw_Ib);                      },                      0xc9 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::LEAVE;                          return Ok(OperandCode::Nothing);                      },                      0xca => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::RETF;                          return Ok(OperandCode::Iw);                      }                      0xcb => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::RETF;                          return Ok(OperandCode::Nothing);                      }                      0xcc => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::INT;                          return Ok(OperandCode::I_3);                      },                      0xcd => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::INT;                          return Ok(OperandCode::Ib);                      },                      0xce => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::INTO;                          return Ok(OperandCode::Fw);                      },                      0xcf => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::IRET;                          return Ok(OperandCode::Fw);                      }, @@ -1836,7 +1663,6 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr                              OperandCode::ModRM_0xd2_Eb_CL,                              OperandCode::ModRM_0xd3_Ev_CL                          ][(x & 0x3) as usize].clone(); -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::Invalid;                          return Ok(operand);                      }, @@ -1856,84 +1682,70 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr                      }                      // TODO: GAP                      0xe8 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::CALL;                          return Ok(OperandCode::Jvds);                      },                      0xe9 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::JMP;                          return Ok(OperandCode::Jvds);                      },                      0xeb => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::JMP;                          return Ok(OperandCode::Jbs);                      },                      0xf0 => { -                        prefixes.set_lock(); +                        instruction.prefixes.set_lock();                      },                      0xf2 => { -                        prefixes.set_repnz(); +                        instruction.prefixes.set_repnz();                          alternate_opcode_map = Some(OpcodeMap::MapF2);                      },                      0xf3 => { -                        prefixes.set_rep(); +                        instruction.prefixes.set_rep();                          alternate_opcode_map = Some(OpcodeMap::MapF3);                      },                      0xf4 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::HLT;                          return Ok(OperandCode::Nothing);                      },                      0xf6 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::Invalid;                          return Ok(OperandCode::ModRM_0xf6);                      },                      0xf7 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::Invalid;                          return Ok(OperandCode::ModRM_0xf7);                      },                      0xf8 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::CLC;                          return Ok(OperandCode::Nothing);                      }                      0xf9 => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::STC;                          return Ok(OperandCode::Nothing);                      }                      0xfa => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::CLI;                          return Ok(OperandCode::Nothing);                      }                      0xfb => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::STI;                          return Ok(OperandCode::Nothing);                      }                      0xfc => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::CLD;                          return Ok(OperandCode::Nothing);                      }                      0xfd => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::STD;                          return Ok(OperandCode::Nothing);                      }                      0xfe => { -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::Invalid;                          return Ok(OperandCode::ModRM_0xfe_Eb);                      },                      0xff => {                          // TODO: test 0xff /3 -                        instruction.prefixes = prefixes;                          instruction.opcode = Opcode::Invalid;                          return Ok(OperandCode::ModRM_0xff_Ev);                      }, | 
