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 | |
| parent | 81c6cdd1b508402edc16ab2ae88379d951c8cfa6 (diff) | |
first brush of Many operand use, for 3-arg imul
| -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(); | 
