diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 130 | 
1 files changed, 37 insertions, 93 deletions
| @@ -1277,26 +1277,16 @@ fn read_opcode(bytes_iter: &mut Iterator<Item=&u8>, instruction: &mut Instructio  fn read_E(bytes_iter: &mut Iterator<Item=&u8>, prefixes: &Prefixes, m: u8, modbits: u8, width: u8, result: &mut Operand) -> Result<(), String> {      let addr_width = if prefixes.address_size() { 4 } else { 8 };      if modbits == 0b11 { -        if prefixes.rex().b() { -            *result = Operand::Register(RegSpec { -                num: m + 0b1000, -                bank: width_to_gp_reg_bank(width) -            }); -            return Ok(()); -        } else { -            *result = Operand::Register(RegSpec { -                num: m, -                bank: width_to_gp_reg_bank(width) -            }); -            return Ok(()); -        } +        *result = Operand::Register(RegSpec { +            num: m + if prefixes.rex().b() { 0b1000 } else { 0 }, +            bank: width_to_gp_reg_bank(width) +        });      } else if m == 5 && modbits == 0b00 {          let disp = read_num(bytes_iter, 4);          *result = Operand::RegDisp(RegSpec {              num: 0,              bank: if addr_width == 8 { RegisterBank::RIP } else { RegisterBank::EIP }          }, disp as i32); -        Ok(())      } else if m == 4 {          let sibbyte = *bytes_iter.next().unwrap();          let (ss, index, base) = octets_of(sibbyte); @@ -1315,99 +1305,60 @@ fn read_E(bytes_iter: &mut Iterator<Item=&u8>, prefixes: &Prefixes, m: u8, modbi              if index == 0b100 {                  if modbits == 0b00 && !prefixes.rex().x() {                      *result = Operand::DisplacementU32(disp as i32); -                    Ok(())                  } else { -                    let indexnum = if prefixes.rex().x() { -                        0b1000 + 0b100 -                    } else { -                        0b100 +                    let reg = RegSpec { +                        num: 0b100 + if prefixes.rex().x() { 0b1000 } else { 0 }, +                        bank: width_to_gp_reg_bank(addr_width)                      };                      if disp == 0 { -                        *result = Operand::RegDeref(RegSpec { -                            num: indexnum, -                            bank: width_to_gp_reg_bank(addr_width) -                        }); -                        Ok(()) +                        *result = Operand::RegDeref(reg);                      } else { -                        *result = Operand::RegDisp(RegSpec { -                            num: indexnum, -                            bank: width_to_gp_reg_bank(addr_width) -                        }, disp as i32); -                        Ok(()) +                        *result = Operand::RegDisp(reg, disp as i32);                      }                  }              } else { -                let base_reg = if prefixes.rex().b() { -                    RegSpec { -                        num: 5 + 0b1000, -                        bank: width_to_gp_reg_bank(addr_width) -                    } -                } else { -                    RegSpec { -                        num: 5, -                        bank: width_to_gp_reg_bank(addr_width) -                    } +                let base_reg = RegSpec { +                    num: 5 + if prefixes.rex().b() { 0b1000 } else { 0 }, +                    bank: width_to_gp_reg_bank(addr_width)                  }; -                let index_reg = if prefixes.rex().x() { -                    RegSpec { -                        num: index + 0b1000, -                        bank: width_to_gp_reg_bank(addr_width) -                    } -                } else { -                    RegSpec { -                        num: index, -                        bank: width_to_gp_reg_bank(addr_width) -                    } +                let index_reg = RegSpec { +                    num: index + if prefixes.rex().x() { 0b1000 } else { 0 }, +                    bank: width_to_gp_reg_bank(addr_width)                  }; -                match (ss, modbits, disp) { +                *result = match (ss, modbits, disp) {                      (0, 0b00, 0) => { -                        *result = Operand::RegDeref(index_reg); -                        Ok(()) +                        Operand::RegDeref(index_reg)                      },                      (0, 0b00, _) => { -                        *result = Operand::RegDisp(index_reg, disp as i32); -                        Ok(()) +                        Operand::RegDisp(index_reg, disp as i32)                      },                      (0, _, 0) => { -                        *result = Operand::RegIndexBase(base_reg, index_reg); -                        Ok(()) +                        Operand::RegIndexBase(base_reg, index_reg)                      },                      (0, _, _) => { -                        *result = Operand::RegIndexBaseDisp(base_reg, index_reg, disp as i32); -                        Ok(()) +                        Operand::RegIndexBaseDisp(base_reg, index_reg, disp as i32)                      },                      (_, 0b00, 0) => { -                        *result = Operand::RegScale(index_reg, 1u8 << ss); -                        Ok(()) +                        Operand::RegScale(index_reg, 1u8 << ss)                      },                      (_, 0b00, _) => { -                        *result = Operand::RegScaleDisp(index_reg, 1u8 << ss, disp as i32); -                        Ok(()) +                        Operand::RegScaleDisp(index_reg, 1u8 << ss, disp as i32)                      },                      (_, _, 0) => { -                        *result = Operand::RegIndexBaseScale(base_reg, index_reg, 1u8 << ss); -                        Ok(()) +                        Operand::RegIndexBaseScale(base_reg, index_reg, 1u8 << ss)                      },                      (_, _, _) => { -                        *result = Operand::RegIndexBaseScaleDisp(base_reg, index_reg, 1u8 << ss, disp as i32); -                        Ok(()) +                        Operand::RegIndexBaseScaleDisp(base_reg, index_reg, 1u8 << ss, disp as i32)                      } -                } +                };              }          } else { -            let base_reg = if prefixes.rex().b() { -                RegSpec { -                    num: base + 0b1000, -                    bank: width_to_gp_reg_bank(addr_width) -                } -            } else { -                RegSpec { -                    num: base, -                    bank: width_to_gp_reg_bank(addr_width) -                } +            let base_reg = RegSpec { +                num: base + if prefixes.rex().b() { 0b1000 } else { 0 }, +                bank: width_to_gp_reg_bank(addr_width)              };              let disp = if modbits == 0b00 { @@ -1421,43 +1372,36 @@ fn read_E(bytes_iter: &mut Iterator<Item=&u8>, prefixes: &Prefixes, m: u8, modbi              if index == 0b100 {                  if disp == 0 {                      *result = Operand::RegDeref(base_reg); -                    Ok(())                  } else {                      *result = Operand::RegDisp(base_reg, disp as i32); -                    Ok(())                  }              } else {                  let index_reg = RegSpec { -                    num: index, +                    num: index + if prefixes.rex().x() { 0b1000 } else { 0 },                      bank: width_to_gp_reg_bank(addr_width)                  };                  if disp == 0 {                      *result = Operand::RegIndexBaseScale(base_reg, index_reg, 1u8 << ss); -                    Ok(())                  } else {                      *result = Operand::RegIndexBaseScaleDisp(base_reg, index_reg, 1u8 << ss, disp as i32); -                    Ok(())                  }              }          }      } else { -        let regidx = m + if prefixes.rex().b() { 0b1000 } else { 0 }; +        let reg = RegSpec { +            num: m + if prefixes.rex().b() { 0b1000 } else { 0 }, +            bank: width_to_gp_reg_bank(addr_width) +        }; +          if modbits == 0b00 { -            *result = Operand::RegDeref(RegSpec { -                num: regidx, -                bank: width_to_gp_reg_bank(addr_width) -            }); -            Ok(()) +            *result = Operand::RegDeref(reg);          } else {              let disp_width = if modbits == 0b01 { 1 } else { 4 };              let disp = read_num(bytes_iter, disp_width) as i32; -            *result = Operand::RegDisp(RegSpec { -                num: regidx, -                bank: width_to_gp_reg_bank(addr_width) -            }, disp); -            Ok(()) +            *result = Operand::RegDisp(reg, disp);          }      } +    Ok(())  }  fn read_operands( | 
