diff options
author | iximeow <me@iximeow.net> | 2019-10-19 22:48:33 -0700 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2020-01-12 16:10:13 -0800 |
commit | f1c94dadfa73c755566a491c7c2d15823101408b (patch) | |
tree | 4388b8c964bd9a73b1cbbc35bcca0bf1b719ce3e /src | |
parent | 81c6cdd1b508402edc16ab2ae88379d951c8cfa6 (diff) |
first brush of Many operand use, for 3-arg imul
Diffstat (limited to 'src')
-rw-r--r-- | src/display.rs | 6 | ||||
-rw-r--r-- | src/lib.rs | 50 |
2 files changed, 52 insertions, 4 deletions
diff --git a/src/display.rs b/src/display.rs index 7d8c1b5..2a1dcc2 100644 --- a/src/display.rs +++ b/src/display.rs @@ -176,6 +176,12 @@ impl <T: std::fmt::Write> Colorize<T> for Operand { }, &Operand::Nothing => { Ok(()) }, // &Operand::Many(_) => { panic!("many not covered"); } + &Operand::Many(ref ops) => { + for op in ops.iter() { + write!(f, ", {}", op)?; + } + Ok(()) + } } } } @@ -173,7 +173,7 @@ pub enum Operand { RegScaleDisp(RegSpec, u8, i32), RegIndexBaseScale(RegSpec, RegSpec, u8), RegIndexBaseScaleDisp(RegSpec, RegSpec, u8, i32), - // Many(Vec<Operand>), + Many(Vec<Operand>), Nothing, } @@ -201,10 +201,18 @@ impl Operand { Operand::ImmediateU64(_) | Operand::ImmediateI64(_) | Operand::Register(_) | - //Operand::Many(_) | Operand::Nothing => { false } + Operand::Many(els) => { + for el in els { + if el.is_memory() { + return true; + } + } + + false + } } } } @@ -683,7 +691,9 @@ pub enum OperandCode { Eb_Gb, Ev_Gv, Gb_Eb, + Gb_Eb_Ib, Gv_Ev, + Gv_Ev_Iv, AL_Ib, AX_Ivd, ModRM_0x0f00, @@ -703,8 +713,6 @@ pub enum OperandCode { Eb_R0, ModRM_0xf6, ModRM_0xf7, - Gv_Ev_Iv, - Gb_Eb_Ib, Yb_DX, Yv_DX, DX_Xb, @@ -2616,6 +2624,23 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut 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(); + let (mod_bits, r, m) = octets_of(modrm); + + let mut ext = vec![Operand::Nothing; 2]; + + // TODO + panic!("oh no, a mul!"); +// read_E(&mut bytes_iter, instruction, modrm, opwidth, &mut ext[0]).unwrap(); + instruction.operands[0] = + Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); + read_imm_signed(&mut bytes_iter, 1, 1, &mut instruction.length).map(|imm| { + ext[1] = imm; + instruction.operands[1] = Operand::Many(ext); + }).unwrap() + } OperandCode::Gv_Eb => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); @@ -2691,6 +2716,23 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut instruction.operands[0] = Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); }, + OperandCode::Gv_Ev_Iv => { + let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes); + let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); + let (mod_bits, r, m) = octets_of(modrm); + + let mut ext = vec![Operand::Nothing; 2]; + + // TODO + panic!("oh no, a mul!"); +// read_E(&mut bytes_iter, instruction, modrm, opwidth, &mut ext[0]).unwrap(); + instruction.operands[0] = + Operand::Register(RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present())); + read_imm_signed(&mut bytes_iter, if opwidth == 8 { 4 } else { opwidth }, opwidth, &mut instruction.length).map(|imm| { + ext[1] = imm; + instruction.operands[1] = Operand::Many(ext); + }).unwrap() + } OperandCode::E_G_xmm => { let opwidth = 8; let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap(); |