aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2019-07-20 12:28:01 -0700
committeriximeow <me@iximeow.net>2020-01-12 16:10:13 -0800
commitf4a96b7b9981ae38679bac707184377d5d994bba (patch)
tree91ee03427afd9ff4ce0afd91a56f086d7715cfc6
parent8a15ee38aa0ac8f3ba474fc99fb3722eed582aeb (diff)
more smallerizing, but this seems to have a perf impact
-rw-r--r--src/lib.rs537
1 files changed, 161 insertions, 376 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 6b571a2..64ecf6c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1024,7 +1024,7 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr
}
continue;
}
- let op = BASE_OPCODE_MAP[(x / 8) as usize].clone();
+ let op = BASE_OPCODE_MAP[(x / 8) as usize];
let operand_code = [
OperandCode::Eb_Gb,
OperandCode::Ev_Gv,
@@ -1436,7 +1436,7 @@ fn read_operands<T: Iterator<Item=u8>>(
return Err("Invalid modr/m for opcode 0xc6".to_owned());
}
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
},
OperandCode::AL_Ob => {
let _addr_width = if instruction.prefixes.address_size() { 4 } else { 8 };
@@ -1452,7 +1452,6 @@ fn read_operands<T: Iterator<Item=u8>>(
Operand::DisplacementU64(imm)
}
];
- Ok(())
}
OperandCode::AX_Ov => {
let _addr_width = if instruction.prefixes.address_size() { 4 } else { 8 };
@@ -1468,7 +1467,6 @@ fn read_operands<T: Iterator<Item=u8>>(
Operand::DisplacementU64(imm)
}
];
- Ok(())
}
OperandCode::Ob_AL => {
let _addr_width = if instruction.prefixes.address_size() { 4 } else { 8 };
@@ -1484,7 +1482,6 @@ fn read_operands<T: Iterator<Item=u8>>(
},
Operand::Register(RegSpec::gp_from_parts(0, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()))
];
- Ok(())
}
OperandCode::Ov_AX => {
let _addr_width = if instruction.prefixes.address_size() { 4 } else { 8 };
@@ -1500,93 +1497,55 @@ fn read_operands<T: Iterator<Item=u8>>(
},
Operand::Register(RegSpec::gp_from_parts(0, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()))
];
- Ok(())
}
OperandCode::ModRM_0x80_Eb_Ib => {
let opwidth = 1;
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- let num = read_num(bytes_iter, 1, length) as i8;
- let opcode = BASE_OPCODE_MAP[r as usize].clone();
- instruction.opcode = opcode;
- instruction.operands[1] = Operand::ImmediateI8(num);
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ let num = read_num(bytes_iter, 1, length) as i8;
+ instruction.opcode = BASE_OPCODE_MAP[r as usize];
+ instruction.operands[1] = Operand::ImmediateI8(num);
},
OperandCode::ModRM_0x81_Ev_Ivs => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- match read_imm_signed(bytes_iter, if opwidth == 8 { 4 } else { opwidth }, opwidth, length) {
- Ok(imm) => {
- let opcode = BASE_OPCODE_MAP[r as usize].clone();
- instruction.opcode = opcode;
- instruction.operands[1] = imm;
- Ok(())
- },
- Err(reason) => {
- instruction.opcode = Opcode::Invalid;
- Err(reason)
- }
-
- }
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ let imm = read_imm_signed(bytes_iter, if opwidth == 8 { 4 } else { opwidth }, opwidth, length)?;
+ instruction.opcode = BASE_OPCODE_MAP[r as usize];
+ instruction.operands[1] = imm;
},
OperandCode::ModRM_0xc0_Eb_Ib => {
let opwidth = 1;
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- let num = read_num(bytes_iter, 1, length) as i8;
- let opcode = BITWISE_OPCODE_MAP[r as usize].clone();
- instruction.opcode = opcode;
- instruction.operands[1] = Operand::ImmediateI8(num);
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ let num = read_num(bytes_iter, 1, length) as i8;
+ instruction.opcode = BITWISE_OPCODE_MAP[r as usize].clone();
+ instruction.operands[1] = Operand::ImmediateI8(num);
},
OperandCode::ModRM_0xc1_Ev_Ib => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- let num = read_num(bytes_iter, 1, length) as i8;
- let opcode = BITWISE_OPCODE_MAP[r as usize].clone();
- instruction.opcode = opcode;
- instruction.operands[1] = Operand::ImmediateI8(num);
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ let num = read_num(bytes_iter, 1, length) as i8;
+ instruction.opcode = BITWISE_OPCODE_MAP[r as usize].clone();
+ instruction.operands[1] = Operand::ImmediateI8(num);
},
OperandCode::ModRM_0xc6_Eb_Ib => {
let opwidth = 1;
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- let num = read_num(bytes_iter, 1, length) as i8;
- if r != 0 {
- instruction.opcode = Opcode::Invalid;
- return Err("Invalid modr/m for opcode 0xc6".to_owned());
- }
- instruction.opcode = Opcode::MOV;
- instruction.operands[1] = Operand::ImmediateI8(num);
- Ok(())
- },
- Err(reason) => Err(reason)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ let num = read_num(bytes_iter, 1, length) as i8;
+ if r != 0 {
+ instruction.opcode = Opcode::Invalid;
+ return Err("Invalid modr/m for opcode 0xc6".to_owned());
}
+ instruction.opcode = Opcode::MOV;
+ instruction.operands[1] = Operand::ImmediateI8(num);
},
OperandCode::ModRM_0xc7_Ev_Iv => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
@@ -1597,64 +1556,34 @@ fn read_operands<T: Iterator<Item=u8>>(
return Err("Invalid modr/m for opcode 0xc7".to_string());
}
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- match read_imm_unsigned(bytes_iter, opwidth, length) {
- Ok(imm) => {
- instruction.opcode = Opcode::MOV;
- instruction.operands[1] = imm;
- Ok(())
- },
- Err(reason) => Err(reason)
- }
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ instruction.opcode = Opcode::MOV;
+ instruction.operands[1] = read_imm_unsigned(bytes_iter, opwidth, length)?;
},
OperandCode::ModRM_0xd0_Eb_1 => {
let opwidth = 1;
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- let opcode = BITWISE_OPCODE_MAP[r as usize].clone();
- instruction.opcode = opcode;
- instruction.operands[1] = Operand::ImmediateI8(1);
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ instruction.opcode = BITWISE_OPCODE_MAP[r as usize];
+ instruction.operands[1] = Operand::ImmediateI8(1);
},
OperandCode::ModRM_0xd1_Ev_1 => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- let opcode = BITWISE_OPCODE_MAP[r as usize].clone();
- instruction.opcode = opcode;
- instruction.operands[1] = Operand::ImmediateI8(1);
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ instruction.opcode = BITWISE_OPCODE_MAP[r as usize];
+ instruction.operands[1] = Operand::ImmediateI8(1);
},
OperandCode::ModRM_0xf6 => {
let opwidth = 1;
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => { },
- Err(reason) => { return Err(reason); }
- };
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
match r {
0 | 1 => {
instruction.opcode = Opcode::TEST;
- match read_imm_signed(bytes_iter, 1, opwidth, length) {
- Ok(imm) => {
- instruction.operands[1] = imm;
- },
- Err(reason) => { return Err(reason); }
- }
+ instruction.operands[1] = read_imm_signed(bytes_iter, 1, opwidth, length)?;
},
2 => {
instruction.opcode = Opcode::NOT;
@@ -1678,25 +1607,16 @@ fn read_operands<T: Iterator<Item=u8>>(
unsafe { unreachable_unchecked(); }
}
}
- Ok(())
},
OperandCode::ModRM_0xf7 => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => { },
- Err(reason) => { return Err(reason); }
- };
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
match r {
0 | 1 => {
instruction.opcode = Opcode::TEST;
let numwidth = if opwidth == 8 { 4 } else { opwidth };
- match read_imm_signed(bytes_iter, numwidth, opwidth, length) {
- Ok(imm) => {
- instruction.operands[1] = imm;
- },
- Err(reason) => { return Err(reason); }
- }
+ instruction.operands[1] = read_imm_signed(bytes_iter, numwidth, opwidth, length)?;
},
2 => {
instruction.opcode = Opcode::NOT;
@@ -1720,130 +1640,88 @@ fn read_operands<T: Iterator<Item=u8>>(
unsafe { unreachable_unchecked(); }
}
}
- Ok(())
},
OperandCode::ModRM_0xfe_Eb => {
let opwidth = 1;
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- let opcode = [
- Opcode::INC,
- Opcode::DEC,
- Opcode::Invalid,
- Opcode::Invalid,
- Opcode::Invalid,
- Opcode::Invalid,
- Opcode::Invalid,
- Opcode::Invalid
- ][r as usize].clone();
- instruction.opcode = opcode;
- instruction.operands[1] = Operand::Nothing;
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ instruction.opcode = [
+ Opcode::INC,
+ Opcode::DEC,
+ Opcode::Invalid,
+ Opcode::Invalid,
+ Opcode::Invalid,
+ Opcode::Invalid,
+ Opcode::Invalid,
+ Opcode::Invalid
+ ][r as usize];
+ instruction.operands[1] = Operand::Nothing;
}
OperandCode::ModRM_0xff_Ev => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- let opcode = [
- Opcode::INC,
- Opcode::DEC,
- Opcode::CALL,
- Opcode::CALLF,
- Opcode::JMP,
- Opcode::JMPF,
- Opcode::PUSH,
- Opcode::Invalid
- ][r as usize].clone();
- instruction.opcode = opcode;
- instruction.operands[1] = Operand::Nothing;
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ let opcode = [
+ Opcode::INC,
+ Opcode::DEC,
+ Opcode::CALL,
+ Opcode::CALLF,
+ Opcode::JMP,
+ Opcode::JMPF,
+ Opcode::PUSH,
+ Opcode::Invalid
+ ][r as usize];
+ instruction.opcode = opcode;
+ instruction.operands[1] = Operand::Nothing;
}
OperandCode::Ev => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let (mod_bits, _, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- instruction.operands[1] = Operand::Nothing;
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ instruction.operands[1] = Operand::Nothing;
},
OperandCode::Eb_Gb => {
let opwidth = 1;
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- instruction.operands[1] =
- Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ instruction.operands[1] =
+ Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
},
OperandCode::Ev_Gv => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- instruction.operands[1] =
- Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ instruction.operands[1] =
+ Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
},
OperandCode::Gb_Eb => {
let opwidth = 1;
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length) {
- Ok(()) => {
- instruction.operands[0] =
- Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length)?;
+ instruction.operands[0] =
+ Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
},
OperandCode::Gv_Eb => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length) {
- Ok(()) => {
- instruction.operands[0] =
- Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length)?;
+ instruction.operands[0] =
+ Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
},
OperandCode::Gv_Ew => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[1], length) {
- Ok(()) => {
- instruction.operands[0] =
- Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[1], length)?;
+ instruction.operands[0] =
+ Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
},
OperandCode::Ew_Sw => {
let opwidth = 2;
@@ -1859,9 +1737,8 @@ fn read_operands<T: Iterator<Item=u8>>(
if mod_bits == 0b11 {
instruction.operands[0] =
Operand::Register(RegSpec { bank: RegisterBank::W, num: m });
- Ok(())
} else {
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
}
},
OperandCode::Sw_Ew => {
@@ -1878,9 +1755,8 @@ fn read_operands<T: Iterator<Item=u8>>(
if mod_bits == 0b11 {
instruction.operands[1] =
Operand::Register(RegSpec { bank: RegisterBank::W, num: m });
- Ok(())
} else {
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length)?;
}
},
// TODO: verify M
@@ -1889,168 +1765,101 @@ fn read_operands<T: Iterator<Item=u8>>(
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length) {
- Ok(()) => {
- instruction.operands[0] =
- Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length)?;
+ instruction.operands[0] =
+ Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
},
OperandCode::Gv_Ev | OperandCode::Gv_M => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length) {
- Ok(()) => {
- instruction.operands[0] =
- Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length)?;
+ instruction.operands[0] =
+ Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
},
OperandCode::E_G_xmm => {
let opwidth = 8;
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
- match read_E_xmm(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- instruction.operands[1] =
- Operand::Register(RegSpec::from_parts(r, instruction.prefixes.rex().r(), RegisterBank::X));
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E_xmm(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ instruction.operands[1] =
+ Operand::Register(RegSpec::from_parts(r, instruction.prefixes.rex().r(), RegisterBank::X));
},
OperandCode::G_E_xmm => {
let opwidth = 8;
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
- match read_E_xmm(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length) {
- Ok(()) => {
- instruction.operands[0] =
- Operand::Register(RegSpec::from_parts(r, instruction.prefixes.rex().r(), RegisterBank::X));
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ read_E_xmm(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[1], length)?;
+ instruction.operands[0] =
+ Operand::Register(RegSpec::from_parts(r, instruction.prefixes.rex().r(), RegisterBank::X));
},
OperandCode::Zv_Ivq(opcode_byte) => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let reg_idx = opcode_byte & 0x7;
- match read_imm_ivq(bytes_iter, opwidth, length) {
- Ok(imm) => {
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(reg_idx, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())),
- imm
- ];
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ instruction.operands = [
+ Operand::Register(RegSpec::gp_from_parts(reg_idx, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())),
+ read_imm_ivq(bytes_iter, opwidth, length)?
+ ];
},
OperandCode::AL_Ib => {
let opwidth = 1;
let numwidth = 1;
- match read_imm_signed(bytes_iter, numwidth, opwidth, length) {
- Ok(imm) => {
- instruction.operands = [
- Operand::Register(RegSpec::al()),
- imm
- ];
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ instruction.operands = [
+ Operand::Register(RegSpec::al()),
+ read_imm_signed(bytes_iter, numwidth, opwidth, length)?
+ ];
}
OperandCode::AX_Ivd => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let numwidth = if opwidth == 8 { 4 } else { opwidth };
- match read_imm_signed(bytes_iter, numwidth, opwidth, length) {
- Ok(imm) => {
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(0, false, opwidth, false)),
- imm
- ];
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ instruction.operands = [
+ Operand::Register(RegSpec::gp_from_parts(0, false, opwidth, false)),
+ read_imm_signed(bytes_iter, numwidth, opwidth, length)?
+ ];
}
OperandCode::Zb_Ib(opcode_byte) => {
let reg_idx = opcode_byte & 0x7;
- match read_imm_unsigned(bytes_iter, 1, length) {
- Ok(imm) => {
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(reg_idx, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present())),
- imm];
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ instruction.operands = [
+ Operand::Register(RegSpec::gp_from_parts(reg_idx, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present())),
+ read_imm_unsigned(bytes_iter, 1, length)?
+ ];
},
OperandCode::Iw => {
- match read_imm_unsigned(bytes_iter, 2, length) {
- Ok(imm) => {
- instruction.operands = [imm, Operand::Nothing];
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ instruction.operands = [
+ read_imm_unsigned(bytes_iter, 2, length)?,
+ Operand::Nothing
+ ];
}
OperandCode::Jbs => {
// TODO: arch width (8 in 64, 4 in 32, 2 in 16)
- match read_imm_signed(bytes_iter, 1, 8, length) {
- Ok(imm) => {
- instruction.operands = [imm, Operand::Nothing];
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ instruction.operands = [
+ read_imm_signed(bytes_iter, 1, 8, length)?,
+ Operand::Nothing
+ ];
},
OperandCode::Ibs => {
- match read_imm_signed(bytes_iter, 1, 8, length) {
- Ok(imm) => {
- instruction.operands = [imm, Operand::Nothing];
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ instruction.operands = [
+ read_imm_signed(bytes_iter, 1, 8, length)?,
+ Operand::Nothing
+ ];
},
OperandCode::Ivs => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vd, &instruction.prefixes);
- match read_imm_unsigned(bytes_iter, opwidth, length) {
- Ok(imm) => {
- instruction.operands = [imm, Operand::Nothing];
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ instruction.operands = [
+ read_imm_unsigned(bytes_iter, opwidth, length)?,
+ Operand::Nothing
+ ];
},
OperandCode::ModRM_0x83_Ev_Ibs => {
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
- match read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length) {
- Ok(()) => {
- let opcode = BASE_OPCODE_MAP[r as usize].clone();
-
- instruction.opcode = opcode;
- match read_imm_signed(bytes_iter, 1, opwidth, length) {
- Ok(op) => {
- instruction.operands[1] = op;
- Ok(())
- },
- Err(reason) => Err(reason)
- }
- },
- Err(reason) => Err(reason)
- }
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
+ instruction.opcode = BASE_OPCODE_MAP[r as usize];
+ instruction.operands[1] = read_imm_signed(bytes_iter, 1, opwidth, length)?;
},
OperandCode::Zv(opcode_byte) => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vq, &instruction.prefixes);
@@ -2059,45 +1868,42 @@ fn read_operands<T: Iterator<Item=u8>>(
opcode_byte & 0b111, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()
)
), Operand::Nothing];
- Ok(())
},
OperandCode::Jvds => {
let offset = read_num(bytes_iter, 4, length);
instruction.operands = [Operand::ImmediateI32(offset as i32), Operand::Nothing];
- Ok(())
}
OperandCode::ModRM_0x0f00 => {
let (mod_bits, r, m) = read_modrm(bytes_iter, length)?;
if r == 0 {
instruction.opcode = Opcode::SLDT;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)?;
} else if r == 1 {
instruction.opcode = Opcode::STR;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)?;
} else if r == 2 {
instruction.opcode = Opcode::LLDT;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)?;
} else if r == 3 {
instruction.opcode = Opcode::LTR;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)?;
} else if r == 4 {
instruction.opcode = Opcode::VERR;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)?;
} else if r == 5 {
instruction.opcode = Opcode::VERW;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)?;
} else if r == 6 {
instruction.opcode = Opcode::JMPE;
instruction.operands = [Operand::Nothing, Operand::Nothing];
- Ok(())
} else if r == 7 {
- Err("Invalid modr/m bits".to_owned())
+ return Err("Invalid modr/m bits".to_owned());
} else {
unreachable!("r <= 8");
}
@@ -2111,71 +1917,66 @@ fn read_operands<T: Iterator<Item=u8>>(
} else {
instruction.opcode = Opcode::SGDT;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
}
} else if r == 1 {
if mod_bits == 0b11 {
// TOOD: MONITOR
instruction.opcode = Opcode::NOP;
instruction.operands[0] = Operand::Nothing;
- Ok(())
} else {
instruction.opcode = Opcode::SIDT;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
}
} else if r == 2 {
if mod_bits == 0b11 {
// TOOD: XGETBV
instruction.opcode = Opcode::NOP;
instruction.operands[0] = Operand::Nothing;
- Ok(())
} else {
instruction.opcode = Opcode::LGDT;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
}
} else if r == 3 {
if mod_bits == 0b11 {
// TOOD: VMRUN
instruction.opcode = Opcode::NOP;
instruction.operands[0] = Operand::Nothing;
- Ok(())
} else {
instruction.opcode = Opcode::LIDT;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
}
} else if r == 4 {
// TODO: this permits storing only to word-size registers
// spec suggets this might do something different for f.ex rdi?
instruction.opcode = Opcode::SMSW;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)?;
} 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(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 2, &mut instruction.operands[0], length)?;
} else if r == 7 {
if mod_bits == 0b11 {
if m == 1 {
instruction.opcode = Opcode::SWAPGS;
instruction.operands = [Operand::Nothing, Operand::Nothing];
- Ok(())
} else if m == 2 {
instruction.opcode = Opcode::RDTSCP;
instruction.operands = [Operand::Nothing, Operand::Nothing];
- Ok(())
} else {
// panic!("Unsupported instruction: 0x0f01 with modrm: 11 110 r >= 2");
- Err("unsupported 0x0f01 variant".to_string())
+ return Err("unsupported 0x0f01 variant".to_string())
}
} else {
instruction.opcode = Opcode::INVLPG;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
}
} else {
unreachable!("r <= 8");
@@ -2186,82 +1987,79 @@ fn read_operands<T: Iterator<Item=u8>>(
match r {
0 => {
if mod_bits == 0b11 {
- Err("Invalid mod bits".to_owned())
+ return Err("Invalid mod bits".to_owned())
} else {
instruction.opcode = Opcode::FXSAVE;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)?;
}
}
1 => {
if mod_bits == 0b11 {
- Err("Invalid mod bits".to_owned())
+ return Err("Invalid mod bits".to_owned());
} else {
instruction.opcode = Opcode::FXRSTOR;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)?;
}
}
2 => {
if mod_bits == 0b11 {
- Err("Invalid mod bits".to_owned())
+ return Err("Invalid mod bits".to_owned());
} else {
instruction.opcode = Opcode::LDMXCSR;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)?;
}
}
3 => {
if mod_bits == 0b11 {
- Err("Invalid mod bits".to_owned())
+ return Err("Invalid mod bits".to_owned());
} else {
instruction.opcode = Opcode::STMXCSR;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)?;
}
}
4 => {
if mod_bits == 0b11 {
- Err("Invalid mod bits".to_owned())
+ return Err("Invalid mod bits".to_owned());
} else {
instruction.opcode = Opcode::XSAVE;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)?;
}
}
5 => {
if mod_bits == 0b11 {
instruction.opcode = Opcode::LFENCE;
instruction.operands = [Operand::Nothing, Operand::Nothing];
- Ok(())
} else {
instruction.opcode = Opcode::XSTOR;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)?;
}
}
6 => {
if mod_bits == 0b11 {
instruction.opcode = Opcode::MFENCE;
instruction.operands = [Operand::Nothing, Operand::Nothing];
- Ok(())
} else {
// TODO: radare reports this, but i'm not sure?
instruction.opcode = Opcode::XSAVEOPT;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)?;
}
}
7 => {
if mod_bits == 0b11 {
instruction.opcode = Opcode::SFENCE;
instruction.operands = [Operand::Nothing, Operand::Nothing];
- Ok(())
} else {
// TODO: radare reports this, but i'm not sure?
instruction.opcode = Opcode::CLFLUSH;
instruction.operands[1] = Operand::Nothing;
- read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)
+ read_E(bytes_iter, &instruction.prefixes, m, mod_bits, 8, &mut instruction.operands[0], length)?;
}
}
_ => { unreachable!("r < 6"); }
@@ -2294,13 +2092,7 @@ fn read_operands<T: Iterator<Item=u8>>(
read_E(bytes_iter, &instruction.prefixes, m, mod_bits, opwidth, &mut instruction.operands[0], length)?;
- match read_imm_signed(bytes_iter, 1, 1, length) {
- Ok(op) => {
- instruction.operands[1] = op;
- Ok(())
- },
- Err(reason) => Err(reason)
- }
+ instruction.operands[1] = read_imm_signed(bytes_iter, 1, 1, length)?;
}
OperandCode::Rq_Cq_0 => {
@@ -2315,7 +2107,6 @@ fn read_operands<T: Iterator<Item=u8>>(
Operand::Register(RegSpec { bank: RegisterBank::Q, num: m }),
Operand::Register(RegSpec { bank: RegisterBank::CR, num: r })
];
- Ok(())
}
OperandCode::Rq_Dq_0 => {
let (_, mut r, mut m) = read_modrm(bytes_iter, length)?;
@@ -2329,7 +2120,6 @@ fn read_operands<T: Iterator<Item=u8>>(
Operand::Register(RegSpec { bank: RegisterBank::Q, num: m }),
Operand::Register(RegSpec { bank: RegisterBank::DR, num: r })
];
- Ok(())
}
OperandCode::Cq_Rq_0 => {
let (_, mut r, mut m) = read_modrm(bytes_iter, length)?;
@@ -2343,7 +2133,6 @@ fn read_operands<T: Iterator<Item=u8>>(
Operand::Register(RegSpec { bank: RegisterBank::CR, num: r }),
Operand::Register(RegSpec { bank: RegisterBank::Q, num: m })
];
- Ok(())
}
OperandCode::Dq_Rq_0 => {
let (_, mut r, mut m) = read_modrm(bytes_iter, length)?;
@@ -2357,32 +2146,28 @@ fn read_operands<T: Iterator<Item=u8>>(
Operand::Register(RegSpec { bank: RegisterBank::DR, num: r }),
Operand::Register(RegSpec { bank: RegisterBank::Q, num: m })
];
- Ok(())
}
OperandCode::FS => {
instruction.operands = [Operand::Register(RegSpec::fs()), Operand::Nothing];
- Ok(())
}
OperandCode::GS => {
instruction.operands = [Operand::Register(RegSpec::fs()), Operand::Nothing];
- Ok(())
}
OperandCode::I_3 => {
instruction.operands = [Operand::ImmediateU8(3), Operand::Nothing];
- Ok(())
}
OperandCode::Nothing => {
instruction.operands = [Operand::Nothing, Operand::Nothing];
- Ok(())
}
_ => {
instruction.operands = [Operand::Nothing, Operand::Nothing];
instruction.opcode = Opcode::Invalid;
// use std::hint::unreachable_unchecked;
- Err(format!("unsupported operand code: {:?}", operand_code))
+ return Err(format!("unsupported operand code: {:?}", operand_code));
// unsafe { unreachable_unchecked(); }
}
- }
+ };
+ Ok(())
}
#[inline]