aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2019-10-20 04:13:13 -0700
committeriximeow <me@iximeow.net>2020-01-12 16:10:13 -0800
commitcd10937143a4fbcf1569f7572dcacb0c113cb34b (patch)
treeedebc60f4d3bc1801c23ca59f72751a4aaa151f4
parent14a7d58bce7b2e94ff362ed24b296a941b1a674e (diff)
shrink read_operands down from 53kb to ~35kb
-rw-r--r--src/lib.rs238
1 files changed, 91 insertions, 147 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 2bb29f5..f2184bb 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2451,26 +2451,20 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?;
},
- OperandCode::AL_Ob => {
- let _addr_width = if instruction.prefixes.address_size() { 4 } else { 8 };
- // stupid RCT thing:
- let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 };
- let opwidth = 1;
- let imm = read_num(&mut bytes_iter, addr_width, &mut instruction.length)?;
- instruction.operands = [
- Operand::Register(RegSpec::gp_from_parts(0, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())),
- if instruction.prefixes.address_size() {
- Operand::DisplacementU32(imm as u32)
- } else {
- Operand::DisplacementU64(imm)
+ op @ OperandCode::AL_Ob |
+ op @ OperandCode::AX_Ov => {
+ let opwidth = match op {
+ OperandCode::AL_Ob => 1,
+ OperandCode::AX_Ov => {
+ imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes)
}
- ];
- }
- OperandCode::AX_Ov => {
+ _ => {
+ unsafe { unreachable_unchecked() }
+ }
+ };
let _addr_width = if instruction.prefixes.address_size() { 4 } else { 8 };
// stupid RCT thing:
let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 };
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let imm = read_num(&mut bytes_iter, addr_width, &mut instruction.length)?;
instruction.operands = [
Operand::Register(RegSpec::gp_from_parts(0, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present())),
@@ -2481,26 +2475,20 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
}
];
}
- OperandCode::Ob_AL => {
- let _addr_width = if instruction.prefixes.address_size() { 4 } else { 8 };
- // stupid RCT thing:
- let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 };
- let opwidth = 1;
- let imm = read_num(&mut bytes_iter, addr_width, &mut instruction.length)?;
- instruction.operands = [
- if instruction.prefixes.address_size() {
- Operand::DisplacementU32(imm as u32)
- } else {
- Operand::DisplacementU64(imm)
- },
- Operand::Register(RegSpec::gp_from_parts(0, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()))
- ];
- }
- OperandCode::Ov_AX => {
+ op @ OperandCode::Ob_AL |
+ op @ OperandCode::Ov_AX => {
+ let opwidth = match op {
+ OperandCode::Ob_AL => 1,
+ OperandCode::Ov_AX => {
+ imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes)
+ }
+ _ => {
+ unsafe { unreachable_unchecked() }
+ }
+ };
let _addr_width = if instruction.prefixes.address_size() { 4 } else { 8 };
// stupid RCT thing:
let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 };
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
let imm = read_num(&mut bytes_iter, addr_width, &mut instruction.length)?;
instruction.operands = [
if instruction.prefixes.address_size() {
@@ -2511,17 +2499,17 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
Operand::Register(RegSpec::gp_from_parts(0, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present()))
];
}
- OperandCode::ModRM_0x80_Eb_Ib => {
- let opwidth = 1;
- let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
-
- read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?;
- 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);
- },
- OperandCode::ModRM_0x81_Ev_Ivs => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
+ op @ OperandCode::ModRM_0x80_Eb_Ib |
+ op @ OperandCode::ModRM_0x81_Ev_Ivs => {
+ let opwidth = match op {
+ OperandCode::ModRM_0x80_Eb_Ib => 1,
+ OperandCode::ModRM_0x81_Ev_Ivs => {
+ imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes)
+ }
+ _ => {
+ unsafe { unreachable_unchecked() }
+ }
+ };
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?;
@@ -2529,17 +2517,17 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
instruction.opcode = base_opcode_map((modrm >> 3) & 7);
instruction.operands[1] = imm;
},
- OperandCode::ModRM_0xc0_Eb_Ib => {
- let opwidth = 1;
- let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
-
- read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?;
- 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);
- },
- OperandCode::ModRM_0xc1_Ev_Ib => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
+ op @ OperandCode::ModRM_0xc0_Eb_Ib |
+ op @ OperandCode::ModRM_0xc1_Ev_Ib => {
+ let opwidth = match op {
+ OperandCode::ModRM_0xc0_Eb_Ib => 1,
+ OperandCode::ModRM_0xc1_Ev_Ib => {
+ imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes)
+ }
+ _ => {
+ unsafe { unreachable_unchecked() }
+ }
+ };
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?;
@@ -2547,21 +2535,17 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
instruction.opcode = BITWISE_OPCODE_MAP[((modrm >> 3) & 7) as usize].clone();
instruction.operands[1] = Operand::ImmediateI8(num);
},
- OperandCode::ModRM_0xc6_Eb_Ib => {
- let opwidth = 1;
- let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
-
- read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?;
- let num = read_num(&mut bytes_iter, 1, &mut instruction.length)? as i8;
- if (modrm & 0b00111000) != 0 {
- instruction.opcode = Opcode::Invalid;
- return Err(()); // 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);
+ op @ OperandCode::ModRM_0xc6_Eb_Ib |
+ op @ OperandCode::ModRM_0xc7_Ev_Iv => {
+ let opwidth = match op {
+ OperandCode::ModRM_0xc6_Eb_Ib => 1,
+ OperandCode::ModRM_0xc7_Ev_Iv => {
+ imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes)
+ }
+ _ => {
+ unsafe { unreachable_unchecked() }
+ }
+ };
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
if (modrm & 0b00111000) != 0 {
@@ -2571,18 +2555,19 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?;
instruction.opcode = Opcode::MOV;
- instruction.operands[1] = read_imm_unsigned(&mut bytes_iter, opwidth, &mut instruction.length)?;
+ instruction.operands[1] = read_imm_signed(&mut bytes_iter, if opwidth == 8 { 4 } else { opwidth }, opwidth, &mut instruction.length)?;
},
- OperandCode::ModRM_0xd0_Eb_1 => {
- let opwidth = 1;
- let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
-
- read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?;
- instruction.opcode = BITWISE_OPCODE_MAP[((modrm >> 3) & 7) as usize].clone();
- instruction.operands[1] = Operand::ImmediateI8(1);
- },
- OperandCode::ModRM_0xd1_Ev_1 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
+ op @ OperandCode::ModRM_0xd0_Eb_1 |
+ op @ OperandCode::ModRM_0xd1_Ev_1 => {
+ let opwidth = match op {
+ OperandCode::ModRM_0xd0_Eb_1 => 1,
+ OperandCode::ModRM_0xd1_Ev_1 => {
+ imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes)
+ }
+ _ => {
+ unsafe { unreachable_unchecked() }
+ }
+ };
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?;
@@ -2599,40 +2584,17 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
instruction.opcode = opcode;
instruction.operands[1] = Operand::Register(RegSpec::cl());
}
- OperandCode::ModRM_0xf6 => {
- let opwidth = 1;
- let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
- read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?;
- match (modrm >> 3) & 7 {
- 0 | 1 => {
- instruction.opcode = Opcode::TEST;
- instruction.operands[1] = read_imm_signed(&mut bytes_iter, 1, opwidth, &mut instruction.length)?;
- },
- 2 => {
- instruction.opcode = Opcode::NOT;
- },
- 3 => {
- instruction.opcode = Opcode::NEG;
- },
- 4 => {
- instruction.opcode = Opcode::MUL;
- },
- 5 => {
- instruction.opcode = Opcode::IMUL;
- },
- 6 => {
- instruction.opcode = Opcode::DIV;
- },
- 7 => {
- instruction.opcode = Opcode::IDIV;
- },
+ op @ OperandCode::ModRM_0xf6 |
+ op @ OperandCode::ModRM_0xf7 => {
+ let opwidth = match op {
+ OperandCode::ModRM_0xf6 => 1,
+ OperandCode::ModRM_0xf7 => {
+ imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes)
+ }
_ => {
- unsafe { unreachable_unchecked(); }
+ unsafe { unreachable_unchecked() }
}
- }
- },
- OperandCode::ModRM_0xf7 => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
+ };
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
read_E(&mut bytes_iter, instruction, modrm, 0, opwidth)?;
match ((modrm >> 3) & 7) {
@@ -3152,22 +3114,13 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
instruction.operands[1] = read_imm_signed(&mut bytes_iter, 1, 1, &mut instruction.length)?;
}
- OperandCode::Rq_Cq_0 => {
- let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
- let mut m = modrm & 7;
- let mut r = (modrm >> 3) & 7;
- if instruction.prefixes.rex().r() {
- r += 0b1000;
- }
- if instruction.prefixes.rex().b() {
- m += 0b1000;
- }
- instruction.operands = [
- Operand::Register(RegSpec { bank: RegisterBank::Q, num: m }),
- Operand::Register(RegSpec { bank: RegisterBank::CR, num: r })
- ];
- }
- OperandCode::Rq_Dq_0 => {
+ op @ OperandCode::Rq_Cq_0 |
+ op @ OperandCode::Rq_Dq_0 => {
+ let bank = match op {
+ OperandCode::Rq_Cq_0 => RegisterBank::CR,
+ OperandCode::Rq_Dq_0 => RegisterBank::DR,
+ _ => unsafe { unreachable_unchecked() }
+ };
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
let mut m = modrm & 7;
let mut r = (modrm >> 3) & 7;
@@ -3179,25 +3132,16 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
}
instruction.operands = [
Operand::Register(RegSpec { bank: RegisterBank::Q, num: m }),
- Operand::Register(RegSpec { bank: RegisterBank::DR, num: r })
- ];
- }
- OperandCode::Cq_Rq_0 => {
- let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
- let mut m = modrm & 7;
- let mut r = (modrm >> 3) & 7;
- if instruction.prefixes.rex().r() {
- r += 0b1000;
- }
- if instruction.prefixes.rex().b() {
- m += 0b1000;
- }
- instruction.operands = [
- Operand::Register(RegSpec { bank: RegisterBank::CR, num: r }),
- Operand::Register(RegSpec { bank: RegisterBank::Q, num: m })
+ Operand::Register(RegSpec { bank: bank, num: r })
];
}
- OperandCode::Dq_Rq_0 => {
+ op @ OperandCode::Cq_Rq_0 |
+ op @ OperandCode::Dq_Rq_0 => {
+ let bank = match op {
+ OperandCode::Cq_Rq_0 => RegisterBank::CR,
+ OperandCode::Dq_Rq_0 => RegisterBank::DR,
+ _ => unsafe { unreachable_unchecked() }
+ };
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length)?;
let mut m = modrm & 7;
let mut r = (modrm >> 3) & 7;
@@ -3208,7 +3152,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
m += 0b1000;
}
instruction.operands = [
- Operand::Register(RegSpec { bank: RegisterBank::DR, num: r }),
+ Operand::Register(RegSpec { bank: bank, num: r }),
Operand::Register(RegSpec { bank: RegisterBank::Q, num: m })
];
}