aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/long_mode/mod.rs34
-rw-r--r--src/long_mode/vex.rs28
2 files changed, 44 insertions, 18 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index a23b470..5ec89dc 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -5517,6 +5517,8 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.operand_count = 0;
return Ok(());
}
+ instruction.operand_count = 2;
+ instruction.operands[0] = OperandSpec::RegRRR;
let operand_code = OperandCodeBuilder::from_bits(operand_code as u16);
if operand_code.has_embedded_instructions() {
match operand_code.get_embedded_instructions() {
@@ -5533,7 +5535,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
} else {
RegisterBank::Q
};
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr =
RegSpec::from_parts(reg, instruction.prefixes.rex().b(), bank);
instruction.operand_count = 1;
@@ -5543,7 +5544,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
}
2 => {
// these are Zb_Ib_R
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr =
RegSpec::gp_from_parts(reg, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present());
instruction.imm =
@@ -5561,7 +5561,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
} else {
RegisterBank::Q
};
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr =
RegSpec::from_parts(reg, instruction.prefixes.rex().b(), bank);
instruction.imm =
@@ -5583,7 +5582,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
},
Err(embedded_operand_instructions) => {
if operand_code.op0_is_rrr() {
- instruction.operands[0] = OperandSpec::RegRRR;
}
}
}
@@ -5626,7 +5624,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
};
instruction.operands[mmm] = mem_oper;
instruction.operands[rrr] = OperandSpec::RegRRR;
- instruction.operand_count = 2;
} else if operand_code.bits() == OperandCode::Ibs as u16 {
instruction.imm =
read_imm_signed(&mut bytes_iter, 1, length)? as u64;
@@ -5997,7 +5994,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.imm =
read_num(&mut bytes_iter, 1)? as u8 as u64;
*length += 1;
@@ -6007,7 +6003,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
OperandCode::G_E_mm_Ib => {
instruction.operands[1] = mem_oper;
instruction.modrm_rrr = RegSpec { bank: RegisterBank::MM, num: (modrm >> 3) & 7 };
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.imm =
read_num(&mut bytes_iter, 1)? as u8 as u64;
*length += 1;
@@ -6024,7 +6019,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, false, RegisterBank::MM);
- instruction.operands[0] = OperandSpec::RegRRR;
if instruction.operands[1] == OperandSpec::RegMMM {
instruction.modrm_mmm.bank = RegisterBank::D;
}
@@ -6084,7 +6078,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.operands[0] = OperandSpec::ImmI32;
}
OperandCode::Gb_Eb_Ib => {
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
instruction.imm =
read_imm_signed(&mut bytes_iter, 1, length)? as u64;
@@ -6094,7 +6087,6 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
OperandCode::Gv_Ev_Iv => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
let numwidth = if opwidth == 8 { 4 } else { opwidth };
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
instruction.imm =
read_imm_signed(&mut bytes_iter, numwidth, length)? as u64;
@@ -6150,7 +6142,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
let modrm = read_modrm(&mut bytes_iter, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
if instruction.prefixes.rex().w() {
let op = instruction.operands[0];
@@ -6427,7 +6418,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
instruction.operand_count = 2;
}
@@ -6442,7 +6432,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
instruction.operand_count = 2;
}
@@ -6510,7 +6499,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
instruction.operand_count = 2;
}
@@ -6540,7 +6528,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
instruction.imm =
read_imm_unsigned(&mut bytes_iter, 1, length)?;
@@ -6556,7 +6543,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
instruction.imm =
read_imm_unsigned(&mut bytes_iter, 1, length)?;
@@ -6887,6 +6873,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
OperandCode::G_xmm_Ed_Ib => {
instruction.operands[1] = mem_oper;
instruction.operands[2] = OperandSpec::ImmU8;
+ instruction.operand_count = 3;
instruction.imm =
read_num(&mut bytes_iter, 1)? as u64;
*length += 1;
@@ -6926,6 +6913,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
OperandCode::Rv_Gmm_Ib => {
instruction.operands[1] = mem_oper;
instruction.operands[2] = OperandSpec::ImmU8;
+ instruction.operand_count = 3;
instruction.imm =
read_num(&mut bytes_iter, 1)? as u64;
*length += 1;
@@ -6970,7 +6958,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
_ => { unreachable!(); }
};
instruction.modrm_mmm = RegSpec::rsi();
- instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::Deref;
}
OperandCode::Yv_AX => {
@@ -7016,6 +7003,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
let rrr = instruction.modrm_rrr.num & 0b111;
instruction.operands[0] = mem_oper;
+ instruction.operand_count = 1;
instruction.opcode = match rrr {
0 => Opcode::PREFETCHNTA,
1 => Opcode::PREFETCH0,
@@ -7097,6 +7085,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
},
OperandCode::CVT_AA => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
+ instruction.operands[0] = OperandSpec::Nothing;
+ instruction.operand_count = 0;
instruction.opcode = match opwidth {
2 => { Opcode::CBW },
4 => { Opcode::CWDE },
@@ -7106,6 +7096,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::CVT_DA => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
+ instruction.operands[0] = OperandSpec::Nothing;
+ instruction.operand_count = 0;
instruction.opcode = match opwidth {
2 => { Opcode::CWD },
4 => { Opcode::CDQ },
@@ -7624,9 +7616,15 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 2;
}
_ => {
+ // TODO: this should be unreachable - safe to panic now?
+ // can't simply delete this arm because the non-unlikely operands are handled outside
+ // here, and some operands are entirely decoded before reaching match in the first
+ // place.
+ // perhaps fully-decoded operands could be a return here? they would be jump table
+ // entries anyway, so no extra space for the dead arms.
+ instruction.operands[0] = OperandSpec::Nothing;
instruction.operand_count = 0;
instruction.opcode = Opcode::Invalid;
-// return Err(()); // Err(format!("unsupported operand code: {:?}", operand_code));
return Err(DecodeError::InvalidOperand);
}
};
diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs
index cf30622..c944532 100644
--- a/src/long_mode/vex.rs
+++ b/src/long_mode/vex.rs
@@ -352,9 +352,11 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
OperandSpec::RegMMM => {
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = OperandSpec::RegMMM;
+ instruction.operand_count = 3;
},
other => {
instruction.operands[1] = other;
+ instruction.operand_count = 2;
}
}
Ok(())
@@ -370,9 +372,11 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
OperandSpec::RegMMM => {
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[2] = OperandSpec::RegMMM;
+ instruction.operand_count = 3;
},
other => {
instruction.operands[0] = other;
+ instruction.operand_count = 2;
}
}
Ok(())
@@ -392,6 +396,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.operands[2] = OperandSpec::ImmU8;
+ instruction.operand_count = 3;
instruction.imm = read_imm_unsigned(bytes, 1, length)?;
Ok(())
},
@@ -406,6 +411,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let mem_oper = read_E(bytes, instruction, modrm, 8, length)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
+ instruction.operand_count = 2;
Ok(())
}
VEXOperandCode::G_xmm_Ed => {
@@ -419,6 +425,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
+ instruction.operand_count = 2;
Ok(())
}
VEXOperandCode::Eq_G_xmm => {
@@ -432,6 +439,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let mem_oper = read_E(bytes, instruction, modrm, 8, length)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
+ instruction.operand_count = 2;
Ok(())
}
VEXOperandCode::Ed_G_xmm => {
@@ -445,6 +453,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
+ instruction.operand_count = 2;
Ok(())
}
_op @ VEXOperandCode::E_G_xmm |
@@ -462,6 +471,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
+ instruction.operand_count = 2;
Ok(())
}
_op @ VEXOperandCode::E_xmm_G_ymm_imm8 => {
@@ -475,6 +485,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
+ instruction.operand_count = 2;
Ok(())
}
@@ -492,6 +503,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
+ instruction.operand_count = 2;
Ok(())
}
_op @ VEXOperandCode::G_xmm_E_xmm => {
@@ -505,6 +517,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
+ instruction.operand_count = 2;
Ok(())
}
_op @ VEXOperandCode::G_xmm_E_ymm => {
@@ -518,6 +531,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
+ instruction.operand_count = 2;
Ok(())
}
_op @ VEXOperandCode::G_ymm_E_xmm => {
@@ -531,6 +545,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
+ instruction.operand_count = 2;
Ok(())
}
_op @ VEXOperandCode::G_ymm_E_ymm => {
@@ -544,6 +559,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
+ instruction.operand_count = 2;
Ok(())
}
@@ -560,6 +576,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
+ instruction.operand_count = 2;
Ok(())
}
@@ -576,6 +593,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
+ instruction.operand_count = 2;
Ok(())
}
_op @ VEXOperandCode::G_V_E_ymm |
@@ -588,6 +606,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
+ instruction.operand_count = 3;
Ok(())
}
_op @ VEXOperandCode::G_V_E_ymm_imm8 => {
@@ -601,6 +620,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[2] = mem_oper;
instruction.imm = read_imm_unsigned(bytes, 1, length)?;
instruction.operands[3] = OperandSpec::ImmU8;
+ instruction.operand_count = 4;
Ok(())
}
_op @ VEXOperandCode::E_V_G_ymm |
@@ -613,6 +633,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = OperandSpec::RegRRR;
+ instruction.operand_count = 3;
Ok(())
}
_op @ VEXOperandCode::G_V_M_xmm |
@@ -624,6 +645,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
+ instruction.operand_count = 3;
Ok(())
}
_op @ VEXOperandCode::G_V_E_xmm_imm8 => {
@@ -636,6 +658,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[2] = mem_oper;
instruction.imm = read_imm_unsigned(bytes, 1, length)?;
instruction.operands[3] = OperandSpec::ImmU8;
+ instruction.operand_count = 4;
Ok(())
}
_op @ VEXOperandCode::V_ymm_G_ymm_E_xmm_imm8 => {
@@ -649,6 +672,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[2] = mem_oper;
instruction.imm = read_imm_unsigned(bytes, 1, length)?;
instruction.operands[3] = OperandSpec::ImmU8;
+ instruction.operand_count = 4;
Ok(())
}
_op @ VEXOperandCode::V_xmm_G_ymm_E_ymm_imm8 => {
@@ -661,6 +685,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[2] = mem_oper;
instruction.imm = read_imm_unsigned(bytes, 1, length)?;
instruction.operands[3] = OperandSpec::ImmU8;
+ instruction.operand_count = 4;
Ok(())
}
_op @ VEXOperandCode::E_V_G_xmm |
@@ -672,6 +697,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = OperandSpec::RegRRR;
+ instruction.operand_count = 3;
Ok(())
}
@@ -684,6 +710,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
instruction.operands[2] = OperandSpec::RegVex;
+ instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::G_Ey_V_ymm => {
@@ -696,6 +723,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
instruction.operands[2] = OperandSpec::RegVex;
+ instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::G_V_E => {