aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2019-10-20 03:31:40 -0700
committeriximeow <me@iximeow.net>2020-01-12 16:10:13 -0800
commit11c18a030b3d1be03463025e389e07dc6b063217 (patch)
tree50f7c21e0f01317a216bf5b1ac9183c0b6261187
parent579299dbc3dbd5a16fc777e2be3aeb6a47b705e7 (diff)
try to get a handle on read_operands size
explicitly number some OperandCode so their variants can be reused, factor out other code which turns out to be helpful for code size and performance reasons. reorder some arguments for read_E/read_M because it seems to have made a small improvement.
-rw-r--r--src/lib.rs613
1 files changed, 261 insertions, 352 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 010b0ea..bcd5378 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -797,38 +797,38 @@ pub enum OperandCode {
Yb_Xb,
Yv_AX,
Yv_Xv,
- Zb_Ib_R0,
- Zb_Ib_R1,
- Zb_Ib_R2,
- Zb_Ib_R3,
- Zb_Ib_R4,
- Zb_Ib_R5,
- Zb_Ib_R6,
- Zb_Ib_R7,
- Zv_R0,
- Zv_R1,
- Zv_R2,
- Zv_R3,
- Zv_R4,
- Zv_R5,
- Zv_R6,
- Zv_R7,
- Zv_AX_R0,
- Zv_AX_R1,
- Zv_AX_R2,
- Zv_AX_R3,
- Zv_AX_R4,
- Zv_AX_R5,
- Zv_AX_R6,
- Zv_AX_R7,
- Zv_Ivq_R0,
- Zv_Ivq_R1,
- Zv_Ivq_R2,
- Zv_Ivq_R3,
- Zv_Ivq_R4,
- Zv_Ivq_R5,
- Zv_Ivq_R6,
- Zv_Ivq_R7,
+ Zb_Ib_R0 = 200,
+ Zb_Ib_R1 = 201,
+ Zb_Ib_R2 = 202,
+ Zb_Ib_R3 = 203,
+ Zb_Ib_R4 = 204,
+ Zb_Ib_R5 = 205,
+ Zb_Ib_R6 = 206,
+ Zb_Ib_R7 = 207,
+ Zv_R0 = 208,
+ Zv_R1 = 209,
+ Zv_R2 = 210,
+ Zv_R3 = 211,
+ Zv_R4 = 212,
+ Zv_R5 = 213,
+ Zv_R6 = 214,
+ Zv_R7 = 215,
+ Zv_AX_R0 = 216,
+ Zv_AX_R1 = 217,
+ Zv_AX_R2 = 218,
+ Zv_AX_R3 = 219,
+ Zv_AX_R4 = 220,
+ Zv_AX_R5 = 221,
+ Zv_AX_R6 = 222,
+ Zv_AX_R7 = 223,
+ Zv_Ivq_R0 = 224,
+ Zv_Ivq_R1 = 225,
+ Zv_Ivq_R2 = 226,
+ Zv_Ivq_R3 = 227,
+ Zv_Ivq_R4 = 228,
+ Zv_Ivq_R5 = 229,
+ Zv_Ivq_R6 = 230,
+ Zv_Ivq_R7 = 231,
Nothing,
Implied,
Unsupported,
@@ -1788,6 +1788,11 @@ enum Interpretation {
// this should be a 32-byte struct..
struct OpcodeRecord(Interpretation, OperandCode);
+#[test]
+fn opcode_record_size() {
+ assert_eq!(std::mem::size_of::<OpcodeRecord>(), 2);
+}
+
const OPCODES: [OpcodeRecord; 256] = [
OpcodeRecord(Interpretation::Instruction(Opcode::ADD), OperandCode::Eb_Gb),
OpcodeRecord(Interpretation::Instruction(Opcode::ADD), OperandCode::Ev_Gv),
@@ -2084,141 +2089,164 @@ const OPCODES: [OpcodeRecord; 256] = [
];
#[allow(non_snake_case)]
-fn read_E<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, width: u8, result: usize) -> Option<()> {
+fn read_E<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize, width: u8) -> Option<()> {
let bank = width_to_gp_reg_bank(width, instr.prefixes.rex().present());
- read_E_anybank(bytes_iter, instr, modrm, width, result, bank)
+ if modrm >= 0b11000000 {
+ read_modrm_reg(bytes_iter, instr, modrm, result, bank)
+ } else {
+ read_M(bytes_iter, instr, modrm, result)
+ }
+}
+#[allow(non_snake_case)]
+fn read_E_xmm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize) -> Option<()> {
+ if modrm >= 0b11000000 {
+ read_modrm_reg(bytes_iter, instr, modrm, result, RegisterBank::X)
+ } else {
+ read_M(bytes_iter, instr, modrm, result)
+ }
}
+
#[allow(non_snake_case)]
-fn read_E_xmm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, width: u8, result: usize) -> Option<()> {
- read_E_anybank(bytes_iter, instr, modrm, width, result, RegisterBank::X)
+fn read_modrm_reg<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize, reg_bank: RegisterBank) -> Option<()> {
+ instr.operands[result] = Operand::Register(RegSpec::from_parts(modrm & 7, instr.prefixes.rex().b(), reg_bank));
+ Some(())
}
#[allow(non_snake_case)]
-fn read_E_anybank<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, _width: u8, result: usize, reg_bank: RegisterBank) -> Option<()> {
+fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize) -> Option<()> {
let modbits = (modrm >> 6);
let addr_width = if instr.prefixes.address_size() { 4 } else { 8 };
- if modbits == 0b11 {
- instr.operands[result] = Operand::Register(RegSpec::from_parts(modrm & 7, instr.prefixes.rex().b(), reg_bank))
- } else if (modrm & 7) == 5 && modbits == 0b00 {
- let disp = read_num(bytes_iter, 4, &mut instr.length);
- instr.operands[result] = Operand::RegDisp(
- if addr_width == 8 { RegSpec::rip() } else { RegSpec::eip() },
- disp as i32
- );
- } else if (modrm & 7) == 4 {
- let sibbyte = match bytes_iter.next() {
- Some(b) => b,
- None => { return None; } //Err("Out of bytes".to_string())
- };
- instr.length += 1;
-// let (ss, index, base) = octets_of(sibbyte);
+ let sibbyte = match bytes_iter.next() {
+ Some(b) => b,
+ None => { return None; } //Err("Out of bytes".to_string())
+ };
+ instr.length += 1;
-// println!("scale: {:b}, index: {:b}, base: {:b}", ss, index, base);
+ instr.operands[result] = if (sibbyte & 7) == 0b101 {
+ let disp = if modbits == 0b00 {
+ read_num(bytes_iter, 4, &mut instr.length) as i32
+ } else if modbits == 0b01 {
+ read_num(bytes_iter, 1, &mut instr.length) as i8 as i32
+ } else {
+ read_num(bytes_iter, 4, &mut instr.length) as i32
+ };
- if (sibbyte & 7) == 0b101 {
- let disp = if modbits == 0b00 {
- read_num(bytes_iter, 4, &mut instr.length) as i32
- } else if modbits == 0b01 {
- read_num(bytes_iter, 1, &mut instr.length) as i8 as i32
+ if ((sibbyte >> 3) & 7) == 0b100 {
+ if modbits == 0b00 && !instr.prefixes.rex().x() {
+ Operand::DisplacementU32(disp as u32)
} else {
- read_num(bytes_iter, 4, &mut instr.length) as i32
- };
+ let reg = RegSpec::gp_from_parts(0b100, instr.prefixes.rex().x(), addr_width, instr.prefixes.rex().present());
- if ((sibbyte >> 3) & 7) == 0b100 {
- if modbits == 0b00 && !instr.prefixes.rex().x() {
- instr.operands[result] = Operand::DisplacementU32(disp as u32);
+ if disp == 0 {
+ Operand::RegDeref(reg)
} else {
- let reg = RegSpec::gp_from_parts(0b100, instr.prefixes.rex().x(), addr_width, instr.prefixes.rex().present());
+ Operand::RegDisp(reg, disp as i32)
+ }
+ }
+ } else {
+ let base_reg = RegSpec::gp_from_parts(5, instr.prefixes.rex().b(), addr_width, instr.prefixes.rex().present());
- if disp == 0 {
- instr.operands[result] = Operand::RegDeref(reg);
- } else {
- instr.operands[result] = Operand::RegDisp(reg, disp as i32);
- }
+ let index_reg = RegSpec::gp_from_parts((sibbyte >> 3) & 7, instr.prefixes.rex().x(), addr_width, instr.prefixes.rex().present());
+ let scale = 1u8 << (sibbyte >> 6);
+
+ match (scale, modbits, disp) {
+ (0, 0b00, 0) => {
+ Operand::RegDeref(index_reg)
+ },
+ (0, 0b00, _) => {
+ Operand::RegDisp(index_reg, disp as i32)
+ },
+ (0, _, 0) => {
+ Operand::RegIndexBase(base_reg, index_reg)
+ },
+ (0, _, _) => {
+ Operand::RegIndexBaseDisp(base_reg, index_reg, disp as i32)
+ },
+ (_, 0b00, 0) => {
+ Operand::RegScale(index_reg, scale)
+ },
+ (_, 0b00, _) => {
+ Operand::RegScaleDisp(index_reg, scale, disp as i32)
+ },
+ (_, _, 0) => {
+ Operand::RegIndexBaseScale(base_reg, index_reg, scale)
+ },
+ (_, _, _) => {
+ Operand::RegIndexBaseScaleDisp(base_reg, index_reg, scale, disp as i32)
}
- } else {
- let base_reg = RegSpec::gp_from_parts(5, instr.prefixes.rex().b(), addr_width, instr.prefixes.rex().present());
-
- let index_reg = RegSpec::gp_from_parts((sibbyte >> 3) & 7, instr.prefixes.rex().x(), addr_width, instr.prefixes.rex().present());
- let scale = 1u8 << (sibbyte >> 6);
-
- instr.operands[result] = match (scale, modbits, disp) {
- (0, 0b00, 0) => {
- Operand::RegDeref(index_reg)
- },
- (0, 0b00, _) => {
- Operand::RegDisp(index_reg, disp as i32)
- },
- (0, _, 0) => {
- Operand::RegIndexBase(base_reg, index_reg)
- },
- (0, _, _) => {
- Operand::RegIndexBaseDisp(base_reg, index_reg, disp as i32)
- },
- (_, 0b00, 0) => {
- Operand::RegScale(index_reg, scale)
- },
- (_, 0b00, _) => {
- Operand::RegScaleDisp(index_reg, scale, disp as i32)
- },
- (_, _, 0) => {
- Operand::RegIndexBaseScale(base_reg, index_reg, scale)
- },
- (_, _, _) => {
- Operand::RegIndexBaseScaleDisp(base_reg, index_reg, scale, disp as i32)
- }
- };
}
+ }
+ } else {
+ let base_reg = RegSpec::gp_from_parts((sibbyte & 7), instr.prefixes.rex().b(), addr_width, instr.prefixes.rex().present());
+
+ let disp = if modbits == 0b00 {
+ 0
+ } else if modbits == 0b01 {
+ read_num(bytes_iter, 1, &mut instr.length) as i8 as i32
} else {
- let base_reg = RegSpec::gp_from_parts((sibbyte & 7), instr.prefixes.rex().b(), addr_width, instr.prefixes.rex().present());
+ read_num(bytes_iter, 4, &mut instr.length) as i32
+ };
- let disp = if modbits == 0b00 {
- 0
- } else if modbits == 0b01 {
- read_num(bytes_iter, 1, &mut instr.length) as i8 as i32
+ if ((sibbyte >> 3) & 7) == 0b100 {
+ if disp == 0 {
+ Operand::RegDeref(base_reg)
} else {
- read_num(bytes_iter, 4, &mut instr.length) as i32
- };
-
- if ((sibbyte >> 3) & 7) == 0b100 {
- if disp == 0 {
- instr.operands[result] = Operand::RegDeref(base_reg);
+ Operand::RegDisp(base_reg, disp as i32)
+ }
+ } else {
+ let index_reg = RegSpec::gp_from_parts((sibbyte >> 3) & 7, instr.prefixes.rex().x(), addr_width, instr.prefixes.rex().present());
+ let scale = 1u8 << (sibbyte >> 6);
+ if disp == 0 {
+ if scale == 0 {
+ Operand::RegIndexBase(base_reg, index_reg)
} else {
- instr.operands[result] = Operand::RegDisp(base_reg, disp as i32);
+ Operand::RegIndexBaseScale(base_reg, index_reg, scale)
}
} else {
- let index_reg = RegSpec::gp_from_parts((sibbyte >> 3) & 7, instr.prefixes.rex().x(), addr_width, instr.prefixes.rex().present());
- let scale = 1u8 << (sibbyte >> 6);
- if disp == 0 {
- if scale == 0 {
- instr.operands[result] = Operand::RegIndexBase(base_reg, index_reg)
- } else {
- instr.operands[result] = Operand::RegIndexBaseScale(base_reg, index_reg, scale);
- }
- } else {
- if scale == 0 {
+ if scale == 0 {
- instr.operands[result] = Operand::RegIndexBaseDisp(base_reg, index_reg, disp as i32);
- } else {
- instr.operands[result] = Operand::RegIndexBaseScaleDisp(base_reg, index_reg, scale, disp as i32);
- }
+ Operand::RegIndexBaseDisp(base_reg, index_reg, disp as i32)
+ } else {
+ Operand::RegIndexBaseScaleDisp(base_reg, index_reg, scale, disp as i32)
}
}
}
+ };
+ Some(())
+}
+
+#[allow(non_snake_case)]
+fn read_M<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, result: usize) -> Option<()> {
+ let modbits = (modrm >> 6);
+ let addr_width = if instr.prefixes.address_size() { 4 } else { 8 };
+ let mmm = modrm & 7;
+ instr.operands[result] = if modbits == 0b11 {
+ unsafe { unreachable_unchecked() }
+ } else if mmm == 4 {
+ return read_sib(bytes_iter, instr, modrm, result);
+// let (ss, index, base) = octets_of(sibbyte);
+
+// println!("scale: {:b}, index: {:b}, base: {:b}", ss, index, base);
+ } else if mmm == 5 && modbits == 0b00 {
+ let disp = read_num(bytes_iter, 4, &mut instr.length);
+ Operand::RegDisp(
+ if addr_width == 8 { RegSpec::rip() } else { RegSpec::eip() },
+ disp as i32
+ )
} else {
- let reg = RegSpec::gp_from_parts(modrm & 7, instr.prefixes.rex().b(), addr_width, instr.prefixes.rex().present());
+ let reg = RegSpec::gp_from_parts(mmm, instr.prefixes.rex().b(), addr_width, instr.prefixes.rex().present());
if modbits == 0b00 {
- instr.operands[result] = Operand::RegDeref(reg);
+ Operand::RegDeref(reg)
} else {
let disp = if modbits == 0b01 {
read_num(bytes_iter, 1, &mut instr.length) as i8 as i32
} else {
read_num(bytes_iter, 4, &mut instr.length) as i32
};
- instr.operands[result] = Operand::RegDisp(reg, disp);
+ Operand::RegDisp(reg, disp)
}
- }
+ };
Some(())
}
@@ -2329,6 +2357,42 @@ pub fn read_instr<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut Ins
read_operands(bytes_iter, instruction, record.1)
}
pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode) -> Option<()> {
+ if operand_code == OperandCode::Gv_Ev {
+ let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
+ let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
+
+// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
+ read_E(&mut bytes_iter, instruction, modrm, 1, opwidth).unwrap();
+ instruction.operands[0] =
+ Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
+ } else if operand_code == OperandCode::Ev_Gv {
+ let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
+ let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
+
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
+ instruction.operands[1] =
+ Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
+ } else if operand_code == OperandCode::Gb_Eb {
+ let opwidth = 1;
+ let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
+
+ read_E(&mut bytes_iter, instruction, modrm, 1, opwidth).unwrap();
+ instruction.operands[0] =
+ Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
+ } else if operand_code == OperandCode::Eb_Gb {
+ let opwidth = 1;
+ let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
+
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
+ instruction.operands[1] =
+ Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
+ } else if operand_code == OperandCode::Jbs {
+ // TODO: arch width (8 in 64, 4 in 32, 2 in 16)
+ instruction.operands = [
+ read_imm_signed(&mut bytes_iter, 1, 8, &mut instruction.length).unwrap(),
+ Operand::Nothing
+ ];
+ } else {
match operand_code {
/*
Gv_Ev_Iv,
@@ -2385,7 +2449,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
return None; // Err("Invalid modr/m for opcode 0xc6".to_owned());
}
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
},
OperandCode::AL_Ob => {
let _addr_width = if instruction.prefixes.address_size() { 4 } else { 8 };
@@ -2451,7 +2515,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let opwidth = 1;
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
let num = read_num(&mut bytes_iter, 1, &mut instruction.length) as i8;
instruction.opcode = base_opcode_map((modrm >> 3) & 7);
instruction.operands[1] = Operand::ImmediateI8(num);
@@ -2460,7 +2524,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
let imm = read_imm_signed(&mut bytes_iter, if opwidth == 8 { 4 } else { opwidth }, opwidth, &mut instruction.length).unwrap();
instruction.opcode = base_opcode_map((modrm >> 3) & 7);
instruction.operands[1] = imm;
@@ -2469,7 +2533,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let opwidth = 1;
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
let num = read_num(&mut bytes_iter, 1, &mut instruction.length) as i8;
instruction.opcode = BITWISE_OPCODE_MAP[((modrm >> 3) & 7) as usize].clone();
instruction.operands[1] = Operand::ImmediateI8(num);
@@ -2478,7 +2542,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
let num = read_num(&mut bytes_iter, 1, &mut instruction.length) as i8;
instruction.opcode = BITWISE_OPCODE_MAP[((modrm >> 3) & 7) as usize].clone();
instruction.operands[1] = Operand::ImmediateI8(num);
@@ -2487,7 +2551,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let opwidth = 1;
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
let num = read_num(&mut bytes_iter, 1, &mut instruction.length) as i8;
if (modrm & 0b00111000) != 0 {
instruction.opcode = Opcode::Invalid;
@@ -2505,7 +2569,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
return None; // Err("Invalid modr/m for opcode 0xc7".to_string());
}
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
instruction.opcode = Opcode::MOV;
instruction.operands[1] = read_imm_unsigned(&mut bytes_iter, opwidth, &mut instruction.length).unwrap();
},
@@ -2513,7 +2577,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let opwidth = 1;
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
instruction.opcode = BITWISE_OPCODE_MAP[((modrm >> 3) & 7) as usize].clone();
instruction.operands[1] = Operand::ImmediateI8(1);
},
@@ -2521,7 +2585,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
instruction.opcode = BITWISE_OPCODE_MAP[((modrm >> 3) & 7) as usize].clone();
instruction.operands[1] = Operand::ImmediateI8(1);
},
@@ -2530,7 +2594,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
let (mod_bits, r, m) = octets_of(modrm);
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
let opcode = BITWISE_OPCODE_MAP[r as usize].clone();
instruction.opcode = opcode;
instruction.operands[1] = Operand::Register(RegSpec::cl());
@@ -2538,7 +2602,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
OperandCode::ModRM_0xf6 => {
let opwidth = 1;
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
match (modrm >> 3) & 7 {
0 | 1 => {
instruction.opcode = Opcode::TEST;
@@ -2570,7 +2634,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
OperandCode::ModRM_0xf7 => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
match ((modrm >> 3) & 7) {
0 | 1 => {
instruction.opcode = Opcode::TEST;
@@ -2604,7 +2668,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let opwidth = 1;
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
instruction.opcode = [
Opcode::INC,
Opcode::DEC,
@@ -2621,7 +2685,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
let opcode = [
Opcode::INC,
Opcode::DEC,
@@ -2639,33 +2703,9 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
instruction.operands[1] = Operand::Nothing;
},
- OperandCode::Eb_Gb => {
- let opwidth = 1;
- let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
-
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
- instruction.operands[1] =
- Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
- },
- OperandCode::Ev_Gv => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
- let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
-
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
- instruction.operands[1] =
- Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
- },
- OperandCode::Gb_Eb => {
- let opwidth = 1;
- let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
-
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 1).unwrap();
- instruction.operands[0] =
- Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
- },
OperandCode::Gb_Eb_Ib => {
let opwidth = 1;
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
@@ -2687,7 +2727,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 1).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 1, opwidth).unwrap();
instruction.operands[0] =
Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
},
@@ -2695,7 +2735,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
- read_E(&mut bytes_iter, instruction, modrm, 2, 1).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 1, 2).unwrap();
instruction.operands[0] =
Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
},
@@ -2716,7 +2756,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
instruction.operands[0] =
Operand::Register(RegSpec { bank: RegisterBank::W, num: modrm & 7});
} else {
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
}
},
OperandCode::Sw_Ew => {
@@ -2736,7 +2776,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
instruction.operands[1] =
Operand::Register(RegSpec { bank: RegisterBank::W, num: modrm & 7});
} else {
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 1).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 1, opwidth).unwrap();
}
},
OperandCode::Gdq_Ed => {
@@ -2744,16 +2784,16 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
- read_E(&mut bytes_iter, instruction, modrm, 4 /* opwidth */, 1).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 1, 4 /* opwidth */).unwrap();
instruction.operands[0] =
Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
},
- OperandCode::Gv_Ev | OperandCode::Gv_M => {
+ OperandCode::Gv_M => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 1).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 1, opwidth).unwrap();
instruction.operands[0] =
Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
},
@@ -2775,76 +2815,33 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
}).unwrap()
}
OperandCode::E_G_xmm => {
- let opwidth = 8;
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
- read_E_xmm(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E_xmm(&mut bytes_iter, instruction, modrm, 0).unwrap();
instruction.operands[1] =
Operand::Register(RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X));
},
OperandCode::G_E_xmm => {
- let opwidth = 8;
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
- read_E_xmm(&mut bytes_iter, instruction, modrm, opwidth, 1).unwrap();
+ read_E_xmm(&mut bytes_iter, instruction, modrm, 1).unwrap();
instruction.operands[0] =
Operand::Register(RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X));
},
- OperandCode::Zv_Ivq_R0 => {
+ op @ OperandCode::Zv_Ivq_R0 |
+ op @ OperandCode::Zv_Ivq_R1 |
+ op @ OperandCode::Zv_Ivq_R2 |
+ op @ OperandCode::Zv_Ivq_R3 |
+ op @ OperandCode::Zv_Ivq_R4 |
+ op @ OperandCode::Zv_Ivq_R5 |
+ op @ OperandCode::Zv_Ivq_R6 |
+ op @ OperandCode::Zv_Ivq_R7 => {
+ let reg = (op as u8) - (OperandCode::Zv_Ivq_R0 as u8);
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(0, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())),
- read_imm_ivq(&mut bytes_iter, opwidth, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zv_Ivq_R1 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(1, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())),
- read_imm_ivq(&mut bytes_iter, opwidth, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zv_Ivq_R2 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(2, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())),
- read_imm_ivq(&mut bytes_iter, opwidth, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zv_Ivq_R3 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(3, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())),
- read_imm_ivq(&mut bytes_iter, opwidth, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zv_Ivq_R4 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(4, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())),
- read_imm_ivq(&mut bytes_iter, opwidth, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zv_Ivq_R5 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(5, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())),
- read_imm_ivq(&mut bytes_iter, opwidth, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zv_Ivq_R6 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(6, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())),
- read_imm_ivq(&mut bytes_iter, opwidth, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zv_Ivq_R7 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(7, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())),
+ Operand::Register(RegSpec::gp_from_parts(reg, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())),
read_imm_ivq(&mut bytes_iter, opwidth, &mut instruction.length).unwrap()
];
},
@@ -2864,51 +2861,17 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
read_imm_signed(&mut bytes_iter, numwidth, opwidth, &mut instruction.length).unwrap()
];
}
- OperandCode::Zb_Ib_R0 => {
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(0, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present())),
- read_imm_unsigned(&mut bytes_iter, 1, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zb_Ib_R1 => {
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(1, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present())),
- read_imm_unsigned(&mut bytes_iter, 1, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zb_Ib_R2 => {
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(2, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present())),
- read_imm_unsigned(&mut bytes_iter, 1, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zb_Ib_R3 => {
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(3, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present())),
- read_imm_unsigned(&mut bytes_iter, 1, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zb_Ib_R4 => {
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(4, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present())),
- read_imm_unsigned(&mut bytes_iter, 1, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zb_Ib_R5 => {
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(5, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present())),
- read_imm_unsigned(&mut bytes_iter, 1, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zb_Ib_R6 => {
+ op @ OperandCode::Zb_Ib_R0 |
+ op @ OperandCode::Zb_Ib_R1 |
+ op @ OperandCode::Zb_Ib_R2 |
+ op @ OperandCode::Zb_Ib_R3 |
+ op @ OperandCode::Zb_Ib_R4 |
+ op @ OperandCode::Zb_Ib_R5 |
+ op @ OperandCode::Zb_Ib_R6 |
+ op @ OperandCode::Zb_Ib_R7 => {
+ let reg = (op as u8) - (OperandCode::Zb_Ib_R0 as u8);
instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(6, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present())),
- read_imm_unsigned(&mut bytes_iter, 1, &mut instruction.length).unwrap()
- ];
- },
- OperandCode::Zb_Ib_R7 => {
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(7, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present())),
+ Operand::Register(RegSpec::gp_from_parts(reg, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present())),
read_imm_unsigned(&mut bytes_iter, 1, &mut instruction.length).unwrap()
];
},
@@ -2918,13 +2881,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
Operand::Nothing
];
}
- OperandCode::Jbs => {
- // TODO: arch width (8 in 64, 4 in 32, 2 in 16)
- instruction.operands = [
- read_imm_signed(&mut bytes_iter, 1, 8, &mut instruction.length).unwrap(),
- Operand::Nothing
- ];
- },
OperandCode::Ibs => {
instruction.operands = [
read_imm_signed(&mut bytes_iter, 1, 8, &mut instruction.length).unwrap(),
@@ -2942,71 +2898,23 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
instruction.opcode = base_opcode_map((modrm >> 3) & 7);
instruction.operands[1] = read_imm_signed(&mut bytes_iter, 1, opwidth, &mut instruction.length).unwrap();
},
- OperandCode::Zv_R0 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes);
- instruction.operands = [Operand::Register(
- RegSpec::gp_from_parts(
- 0, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()
- )
- ), Operand::Nothing];
- },
- OperandCode::Zv_R1 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes);
- instruction.operands = [Operand::Register(
- RegSpec::gp_from_parts(
- 1, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()
- )
- ), Operand::Nothing];
- },
- OperandCode::Zv_R2 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes);
- instruction.operands = [Operand::Register(
- RegSpec::gp_from_parts(
- 2, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()
- )
- ), Operand::Nothing];
- },
- OperandCode::Zv_R3 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes);
- instruction.operands = [Operand::Register(
- RegSpec::gp_from_parts(
- 3, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()
- )
- ), Operand::Nothing];
- },
- OperandCode::Zv_R4 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes);
- instruction.operands = [Operand::Register(
- RegSpec::gp_from_parts(
- 4, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()
- )
- ), Operand::Nothing];
- },
- OperandCode::Zv_R5 => {
+ op @ OperandCode::Zv_R0 |
+ op @ OperandCode::Zv_R1 |
+ op @ OperandCode::Zv_R2 |
+ op @ OperandCode::Zv_R3 |
+ op @ OperandCode::Zv_R4 |
+ op @ OperandCode::Zv_R5 |
+ op @ OperandCode::Zv_R6 |
+ op @ OperandCode::Zv_R7 => {
+ let reg = (op as u8) - (OperandCode::Zv_R0 as u8);
let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes);
instruction.operands = [Operand::Register(
RegSpec::gp_from_parts(
- 5, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()
- )
- ), Operand::Nothing];
- },
- OperandCode::Zv_R6 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes);
- instruction.operands = [Operand::Register(
- RegSpec::gp_from_parts(
- 6, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()
- )
- ), Operand::Nothing];
- },
- OperandCode::Zv_R7 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes);
- instruction.operands = [Operand::Register(
- RegSpec::gp_from_parts(
- 7, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()
+ reg, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()
)
), Operand::Nothing];
},
@@ -3046,7 +2954,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
} else {
unreachable!("r <= 8");
}
- read_E(&mut bytes_iter, instruction, modrm, 2, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, 2).unwrap();
}
OperandCode::ModRM_0x0f01 => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes);
@@ -3060,7 +2968,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
} else {
instruction.opcode = Opcode::SGDT;
instruction.operands[1] = Operand::Nothing;
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
}
} else if r == 1 {
let mod_bits = modrm >> 6;
@@ -3072,7 +2980,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
} else {
instruction.opcode = Opcode::SIDT;
instruction.operands[1] = Operand::Nothing;
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
}
} else if r == 2 {
let mod_bits = modrm >> 6;
@@ -3084,7 +2992,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
} else {
instruction.opcode = Opcode::LGDT;
instruction.operands[1] = Operand::Nothing;
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
}
} else if r == 3 {
let mod_bits = modrm >> 6;
@@ -3096,20 +3004,20 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
} else {
instruction.opcode = Opcode::LIDT;
instruction.operands[1] = Operand::Nothing;
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
}
} else if r == 4 {
// TODO: this permits storing only to word-size registers
// spec suggets this might do something different for f.ex rdi.unwrap()
instruction.opcode = Opcode::SMSW;
instruction.operands[1] = Operand::Nothing;
- read_E(&mut bytes_iter, instruction, modrm, 2, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, 2).unwrap();
} else if r == 5 {
panic!("Unsupported instruction: 0x0f01 with modrm: __ 101 ___");
} else if r == 6 {
instruction.opcode = Opcode::LMSW;
instruction.operands[1] = Operand::Nothing;
- read_E(&mut bytes_iter, instruction, modrm, 2, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, 2).unwrap();
} else if r == 7 {
let mod_bits = modrm >> 6;
let m = modrm & 7;
@@ -3127,7 +3035,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
} else {
instruction.opcode = Opcode::INVLPG;
instruction.operands[1] = Operand::Nothing;
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
}
} else {
unreachable!("r <= 8");
@@ -3211,7 +3119,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
}
_ => { unreachable!("r < 6"); }
}
- read_E(&mut bytes_iter, instruction, modrm, 8, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, 8).unwrap();
}
OperandCode::ModRM_0x0fba => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes);
@@ -3239,7 +3147,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
}
}
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 0, opwidth).unwrap();
instruction.operands[1] = read_imm_signed(&mut bytes_iter, 1, 1, &mut instruction.length).unwrap();
}
@@ -3323,6 +3231,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
// unsafe { unreachable_unchecked(); }
}
};
+ }
Some(())
}