Fix whatever is in the terminal.
0x00402816: je 0x000000000040281d ; Jump if equal
0x004031f5: mov eax, esi ; Register to register move
0x00409380: jno 0x0000000000409311
0x00408caf: call 0xffffffffff40cda4 ; Call function at 0xffffffffff40cda4 ; Call to 0xffffffffff40cda4
0x00408cb4: jne 0x0000000000408cbe ; Jump if not equal
Also double check to see if the instructions are in the right place/ if they're wrong. Do an entire overhaul of instruction.rs Provide the full thing. You have 64K output tokens. You can provide more than double the current file. 
So no // ... from previous file comments or ANY unit tests. Fix the entire instruction.rs

instruction.rs:
use std::fmt;

/// Represents different types of operands in x86/x86_64 instructions.
#[derive(Debug, Clone, PartialEq)]
pub enum Operand {
    Register(String),
    Immediate(u64),
    Immediate8(u8),
    Immediate16(u16),
    Immediate32(u32),
    Immediate64(u64),
    Memory(String),
    SegRegister(String),
    Relative(u64),
    FPRegister(u8),
    MMXRegister(u8),
    XMMRegister(u8),
    YMMRegister(u8),
    ZMMRegister(u8),
    Others(String), // For operands that don't fit into predefined categories
}

/// Represents various x86/x86_64 instructions.
#[derive(Debug, Clone)]
pub enum Instruction {
    // Data Movement
    Mov(Operand, Operand),
    Push(Operand),
    Pop(Operand),
    Lea(Operand, Operand),
    Xchg(Operand, Operand),
    Cmovcc(String, Operand, Operand), // Condition code, dst, src
    Movzx(Operand, Operand),
    Movsx(Operand, Operand),
    Movdq2q(Operand, Operand),
    Movdqa(Operand, Operand),
    Movaps(Operand, Operand),
    Movups(Operand, Operand),
    Movss(Operand, Operand),
    Movsd(Operand, Operand),
    Movbe(Operand, Operand),
    Movnti(Operand, Operand),
    Movdqu(Operand, Operand),
    Movq(Operand, Operand),
    Movsxd(Operand, Operand),

    // Arithmetic
    Add(Operand, Operand),
    Sub(Operand, Operand),
    Mul(Operand),
    IMul(Operand, Operand),
    Div(Operand),
    IDiv(Operand),
    Inc(Operand),
    Dec(Operand),
    Neg(Operand),
    Adc(Operand, Operand),
    Sbb(Operand, Operand),
    IncDec(String, Operand), // "inc" or "dec", operand

    // Logic
    And(Operand, Operand),
    Or(Operand, Operand),
    Xor(Operand, Operand),
    Not(Operand),
    Shl(Operand, Operand),
    Shr(Operand, Operand),
    Sar(Operand, Operand),
    Rol(Operand, Operand),
    Ror(Operand, Operand),
    Rcl(Operand, Operand),
    Rcr(Operand, Operand),
    Shld(Operand, Operand, Operand),
    Shrd(Operand, Operand, Operand),

    // Control Flow
    Call(Operand),
    Jmp(Operand),
    Je(Operand),
    Jne(Operand),
    Jg(Operand),
    Jge(Operand),
    Jp(Operand),
    Jnp(Operand),
    Jl(Operand),
    Jle(Operand),
    Ja(Operand),
    Jae(Operand),
    Jb(Operand),
    Jbe(Operand),
    Js(Operand),
    Jns(Operand),
    Jo(Operand),
    Jno(Operand),
    Jc(Operand),
    Jnc(Operand),
    Jecxz(Operand),
    Loop(Operand),
    Loope(Operand),
    Loopne(Operand),
    Jrcxz(Operand),
    Ret,
    RetImm(u16),
    Syscall,
    Int(u8),
    Into,
    Iret,

    // Stack
    Enter(u16, u8),
    Leave,
    PushA,
    PopA,
    PushF,
    PopF,

    // Comparison
    Cmp(Operand, Operand),
    Test(Operand, Operand),

    // String Operations
    Movs(u8),
    Cmps(u8),
    Scas(u8),
    Lods(u8),
    Bt(Operand, Operand),
    Bts(Operand, Operand),
    Btr(Operand, Operand),
    Btc(Operand, Operand),
    Stos(u8),
    Rep(Box<Instruction>),
    Repe(Box<Instruction>),
    Cmc,
    Repne(Box<Instruction>),

    // Floating-Point
    Fld(Operand),
    Fst(Operand),
    Fstp(Operand),
    Fadd(Operand),
    Fsub(Operand),
    Fmul(Operand),
    Fdiv(Operand),
    Fcom(Operand),
    Fcomp(Operand),
    Fcompp,
    Fild(Operand),
    Fist(Operand),
    Fistp(Operand),
    Fldcw(Operand),
    Fstcw(Operand),
    Fnstcw(Operand),

    // MMX and SIMD (SSE, AVX, AVX-512, etc.)
    Paddb(Operand, Operand),
    Paddw(Operand, Operand),
    Paddd(Operand, Operand),
    Paddq(Operand, Operand),
    Psubb(Operand, Operand),
    Psubw(Operand, Operand),
    Psubd(Operand, Operand),
    Psubq(Operand, Operand),
    Pmullw(Operand, Operand),
    Pmulhw(Operand, Operand),
    Pmulhuw(Operand, Operand),
    Pand(Operand, Operand),
    Por(Operand, Operand),
    Pxor(Operand, Operand),
    Psllw(Operand, Operand),
    Pslld(Operand, Operand),
    Psllq(Operand, Operand),
    Psrlw(Operand, Operand),
    Psrld(Operand, Operand),
    Psrlq(Operand, Operand),
    Pdep(Operand, Operand),
    Pext(Operand, Operand),
    Vaddps(Operand, Operand, Operand),
    Vmulps(Operand, Operand, Operand),
    Vaddpd(Operand, Operand, Operand),
    Vmulpd(Operand, Operand, Operand),
    Vaddss(Operand, Operand, Operand),
    Vmulss(Operand, Operand, Operand),
    Vaddsd(Operand, Operand, Operand),
    Vmulsd(Operand, Operand, Operand),
    Vinsertps(Operand, Operand, Operand),
    Vblendps(Operand, Operand, Operand),
    Vblendpd(Operand, Operand, Operand),
    // ... Additional SIMD instructions can be added here

    // System
    Cpuid,
    Rdtsc,
    Rdmsr,
    Wrmsr,
    Sgdt(Operand),
    Sidt(Operand),
    Lgdt(Operand),
    Lidt(Operand),
    Invlpg(Operand),
    Wbinvd,
    Hlt,
    Nop,
    Ud2,
    Sysret,
    Sysretq,

    // Miscellaneous
    Cdq,
    Cwd,
    Cwde,
    Cbw,
    Clc,
    Stc,
    Cli,
    Sti,
    Cld,
    Std,
    Nopd,    // NOP with multiple bytes
    Nahf,    // Example of additional NOP-like instructions
    Pause,
    LFENCE,
    MFENCE,
    SFENCE,
    Prefetchnta(Operand),
    Prefetchw(Operand),
    Prefetchh(Operand),

    // Prefixes (treated as separate instructions for clarity)
    PrefixRep,
    PrefixRepe,
    PrefixRepne,

    // Unknown or unimplemented instructions
    Unknown(Vec<u8>),
}

impl Instruction {
    /// Decodes a sequence of bytes into an `Instruction`, returning the instruction and the number of bytes consumed.
    pub fn decode(bytes: &[u8], rip: u64) -> Result<(Self, usize), &'static str> {
        let mut decoder = Decoder::new(bytes.to_vec(), rip);
        decoder.decode_prefixes();

        let start_offset = decoder.offset;

        // Handle multi-byte opcodes
        let opcode = decoder.next_byte().ok_or("Unexpected end of input while fetching opcode")?;
        let mut opcode_vec = vec![opcode];

        // Determine if opcode is multi-byte
        let mut is_two_byte = false;
        let mut is_three_byte = false;
        let mut is_vex = false;
        let mut has_vex = false;

        if opcode == 0x0F {
            // Two-byte opcode
            let second_opcode = decoder.next_byte().ok_or("Unexpected end of input after 0x0F prefix")?;
            opcode_vec.push(second_opcode);
            is_two_byte = true;

            // Check for three-byte opcodes
            if second_opcode == 0x38 || second_opcode == 0x3A {
                let third_opcode = decoder.next_byte().ok_or("Unexpected end of input for three-byte opcode")?;
                opcode_vec.push(third_opcode);
                is_three_byte = true;
            }
        } else if (0xC4..=0xC5).contains(&opcode) {
            // VEX prefixes
            is_vex = true;
            has_vex = true;
            let vex_b1 = decoder.next_byte().ok_or("Unexpected end of input in VEX prefix")?;
            let vex_b2 = decoder.next_byte().ok_or("Unexpected end of input in VEX prefix")?;
            opcode_vec.push(vex_b1);
            opcode_vec.push(vex_b2);
            if let Some(vex_opcode) = decoder.next_byte() {
                opcode_vec.push(vex_opcode);
            } else {
                return Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset));
            }
        } else if opcode == 0x62 {
            // EVEX prefixes
            is_vex = true;
            has_vex = true;
            let evex_b1 = decoder.next_byte().ok_or("Unexpected end of input in EVEX prefix")?;
            let evex_b2 = decoder.next_byte().ok_or("Unexpected end of input in EVEX prefix")?;
            let evex_b3 = decoder.next_byte().ok_or("Unexpected end of input in EVEX prefix")?;
            opcode_vec.push(evex_b1);
            opcode_vec.push(evex_b2);
            opcode_vec.push(evex_b3);
            if let Some(evex_opcode) = decoder.next_byte() {
                opcode_vec.push(evex_opcode);
            } else {
                return Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset));
            }
        }

        match opcode_vec.as_slice() {
            // PUSH instructions (0x50-0x57 and extended)
            &[0x50..=0x57] => {
                let reg = register_name(opcode_vec[0] - 0x50, decoder.rex);
                Ok((Instruction::Push(Operand::Register(reg)), decoder.offset))
            }
            &[0x58..=0x5F] => {
                let reg = register_name(opcode_vec[0] - 0x58, decoder.rex);
                Ok((Instruction::Pop(Operand::Register(reg)), decoder.offset))
            }

            // MOV instructions
            &[0x8B, ..] | &[0x89, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let src = Operand::Register(register_name(reg, decoder.rex));
                let dst = decoder.decode_operand(mode, reg, rm)?;
                let instruction = if opcode_vec[0] == 0x89 {
                    Instruction::Mov(dst, src)
                } else {
                    Instruction::Mov(src, dst)
                };
                Ok((instruction, decoder.offset))
            }

            // LEA instruction
            &[0x8D, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let dst = Operand::Register(register_name(reg, decoder.rex));
                let src = decoder.decode_operand(mode, reg, rm)?;
                Ok((Instruction::Lea(dst, src), decoder.offset))
            }

            // NOP instruction and its multi-byte variants
            &[0x90] => Ok((Instruction::Nop, decoder.offset)),
            &[0x66, 0x90] => Ok((Instruction::Nopd, decoder.offset)),
            &[0x0F, 0x1F, 0x00] => Ok((Instruction::Nopd, decoder.offset)),
            &[0x0F, 0x1F, 0x40, 0x00] => Ok((Instruction::Nopd, decoder.offset)),
            &[0x0F, 0x1F, 0x44, 0x00, 0x00] => Ok((Instruction::Nopd, decoder.offset)),

            // RET instructions
            &[0xC3] => Ok((Instruction::Ret, decoder.offset)),
            &[0xC2, ..] => {
                let imm = decoder.decode_immediate(2)? as u16;
                Ok((Instruction::RetImm(imm), decoder.offset))
            }

            // CALL instruction
   
            &[0xE8, ..] => {
                let rel = decoder.decode_immediate(4)? as i32;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                Ok((Instruction::Call(Operand::Relative(target)), decoder.offset))
            },

            // JMP instructions
            &[0xE9, ..] => {
                let rel = decoder.decode_immediate(4)? as i32;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                Ok((Instruction::Jmp(Operand::Relative(target)), decoder.offset))
            }
            &[0xEB, ..] => {
                let rel = decoder.decode_immediate(1)? as i8;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                Ok((Instruction::Jmp(Operand::Relative(target)), decoder.offset))
            }
            &[0xE0, ..] => {
                // Loop
                let rel = decoder.decode_immediate(1)? as i8;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                Ok((Instruction::Loop(Operand::Relative(target)), decoder.offset))
            }
            &[0xE1, ..] => {
                // Loopne
                let rel = decoder.decode_immediate(1)? as i8;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                Ok((Instruction::Loopne(Operand::Relative(target)), decoder.offset))
            }
            &[0xE2, ..] => {
                // Loope
                let rel = decoder.decode_immediate(1)? as i8;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                Ok((Instruction::Loope(Operand::Relative(target)), decoder.offset))
            }

            // Immediate to register MOV (0xB8-0xBF)
            &[0xB8..=0xBF, ..] => {
                let reg = opcode_vec[0] - 0xB8;
                let imm_size = operand_size(&decoder) / 8;
                let imm = decoder.decode_immediate(imm_size)?;
                let reg_name = register_name(reg, decoder.rex);
                Ok((Instruction::Mov(Operand::Register(reg_name), Operand::Immediate(imm)), decoder.offset))
            }

            // Arithmetic instructions with immediate
            &[0x81, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let imm = decoder.decode_immediate(4)? as u32;
                let dst = decoder.decode_operand(mode, reg, rm)?;
                let instruction = match reg {
                    0 => Instruction::Add(dst, Operand::Immediate(imm as u64)),
                    1 => Instruction::Or(dst, Operand::Immediate(imm as u64)),
                    2 => Instruction::Adc(dst, Operand::Immediate(imm as u64)),
                    3 => Instruction::Sbb(dst, Operand::Immediate(imm as u64)),
                    4 => Instruction::And(dst, Operand::Immediate(imm as u64)),
                    5 => Instruction::Sub(dst, Operand::Immediate(imm as u64)),
                    6 => Instruction::Xor(dst, Operand::Immediate(imm as u64)),
                    7 => Instruction::Cmp(dst, Operand::Immediate(imm as u64)),
                    _ => Instruction::Unknown(opcode_vec.clone()),
                };
                Ok((instruction, decoder.offset))
            }

            // Single-byte opcodes for Add, Sub, etc.
            &[0x01, ..] | &[0x03, ..] | &[0x11, ..] | &[0x13, ..] |
            &[0x29, ..] | &[0x2B, ..] | &[0x31, ..] | &[0x33, ..] |
            &[0x39, ..] | &[0x3B, ..] => {
                let opcode = opcode_vec[0];
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let src = Operand::Register(register_name(reg, decoder.rex));
                let dst = decoder.decode_operand(mode, reg, rm)?;
                let instruction = match opcode {
                    0x01 => Instruction::Add(dst, src),
                    0x03 => Instruction::Add(src, dst),
                    0x11 => Instruction::Adc(dst, src),
                    0x13 => Instruction::Adc(src, dst),
                    0x29 => Instruction::Sub(dst, src),
                    0x2B => Instruction::Sub(src, dst),
                    0x31 => Instruction::Xor(dst, src),
                    0x33 => Instruction::Xor(src, dst),
                    0x39 => Instruction::Cmp(dst, src),
                    0x3B => Instruction::Cmp(src, dst),
                    _ => Instruction::Unknown(opcode_vec.clone()),
                };
                Ok((instruction, decoder.offset))
            }

            // Two-byte opcode 0x0F AF - IMUL
            &[0x0F, 0xAF, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let dst = Operand::Register(register_name(reg, decoder.rex));
                let src = decoder.decode_operand(mode, reg, rm)?;
                Ok((Instruction::IMul(dst, src), decoder.offset))
            }

            // Conditional jumps with two-byte opcode
            &[0x0F, 0x80..=0x8F, ..] => {
                let cond = opcode_vec[1] - 0x80;
                let rel = decoder.decode_immediate(4)? as i32;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                let instruction = match cond {
                    0 => Instruction::Jo(Operand::Relative(target)),
                    1 => Instruction::Jno(Operand::Relative(target)),
                    2 => Instruction::Jb(Operand::Relative(target)),
                    3 => Instruction::Jae(Operand::Relative(target)),
                    4 => Instruction::Je(Operand::Relative(target)),
                    5 => Instruction::Jne(Operand::Relative(target)),
                    6 => Instruction::Jbe(Operand::Relative(target)),
                    7 => Instruction::Ja(Operand::Relative(target)),
                    8 => Instruction::Js(Operand::Relative(target)),
                    9 => Instruction::Jns(Operand::Relative(target)),
                    10 => Instruction::Jp(Operand::Relative(target)),
                    11 => Instruction::Jnp(Operand::Relative(target)),
                    12 => Instruction::Jl(Operand::Relative(target)),
                    13 => Instruction::Jge(Operand::Relative(target)),
                    14 => Instruction::Jle(Operand::Relative(target)),
                    15 => Instruction::Jg(Operand::Relative(target)),
                    _ => Instruction::Unknown(opcode_vec.clone()),
                };
                Ok((instruction, decoder.offset))
            }

            // Shifts with 0xC1 opcode
            &[0xC1, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let shift = decoder.decode_immediate(1)? as u8;
                let dst = decoder.decode_operand(mode, reg, rm)?;
                let instruction = match reg {
                    4 => Instruction::Shl(dst.clone(), Operand::Immediate(shift as u64)),
                    5 => Instruction::Shr(dst.clone(), Operand::Immediate(shift as u64)),
                    7 => Instruction::Sar(dst.clone(), Operand::Immediate(shift as u64)),
                    _ => Instruction::Unknown(opcode_vec.clone()),
                };
                Ok((instruction, decoder.offset))
            }

            // Bit Test instructions with 0xBA opcode
            &[0xBA, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                if reg >= 4 && reg <= 7 {
                    let dst = decoder.decode_operand(mode, reg, rm)?;
                    let imm = decoder.decode_immediate(1)? as u64;
                    let instruction = match reg {
                        4 => Instruction::Bt(dst, Operand::Immediate(imm)),
                        5 => Instruction::Bts(dst, Operand::Immediate(imm)),
                        6 => Instruction::Btr(dst, Operand::Immediate(imm)),
                        7 => Instruction::Btc(dst, Operand::Immediate(imm)),
                        _ => Instruction::Unknown(opcode_vec.clone()),
                    };
                    Ok((instruction, decoder.offset))
                } else {
                    Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset))
                }
            }

            // Two-byte opcode for conditional jumps with relative rel32
            &[0x0F, 0x84..=0x8F, ..] => {
                let cond = opcode_vec[1] - 0x80;
                let rel = decoder.decode_immediate(4)? as i32;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                let instruction = match cond {
                    0 => Instruction::Jo(Operand::Relative(target)),
                    1 => Instruction::Jno(Operand::Relative(target)),
                    2 => Instruction::Jb(Operand::Relative(target)),
                    3 => Instruction::Jae(Operand::Relative(target)),
                    4 => Instruction::Je(Operand::Relative(target)),
                    5 => Instruction::Jne(Operand::Relative(target)),
                    6 => Instruction::Jbe(Operand::Relative(target)),
                    7 => Instruction::Ja(Operand::Relative(target)),
                    8 => Instruction::Js(Operand::Relative(target)),
                    9 => Instruction::Jns(Operand::Relative(target)),
                    10 => Instruction::Jp(Operand::Relative(target)),
                    11 => Instruction::Jnp(Operand::Relative(target)),
                    12 => Instruction::Jl(Operand::Relative(target)),
                    13 => Instruction::Jge(Operand::Relative(target)),
                    14 => Instruction::Jle(Operand::Relative(target)),
                    15 => Instruction::Jg(Operand::Relative(target)),
                    _ => Instruction::Unknown(opcode_vec.clone()),
                };
                Ok((instruction, decoder.offset))
            }

            // SIMD Instructions with VEX prefixes
            &[0xC4, ..] | &[0xC5, ..] => {
                // Handle VEX-encoded instructions
                // Example implementations for VEX-encoded instructions
                if opcode_vec.len() < 4 {
                    return Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset));
                }

                let vex_opcode = opcode_vec[3];
                match vex_opcode {
                    0x58 => {
                        // VEX: ADDPS xmm1, xmm2, xmm3/m128
                        let (mode, reg, rm) = decoder.decode_modrm()?;
                        let dst = Operand::XMMRegister(reg);
                        let src1 = Operand::XMMRegister(rm);
                        let src2 = decoder.decode_operand(mode, reg, rm)?;
                        Ok((Instruction::Vaddps(dst, src1, src2), decoder.offset))
                    }
                    0x59 => {
                        // VEX: MULPS xmm1, xmm2, xmm3/m128
                        let (mode, reg, rm) = decoder.decode_modrm()?;
                        let dst = Operand::XMMRegister(reg);
                        let src1 = Operand::XMMRegister(rm);
                        let src2 = decoder.decode_operand(mode, reg, rm)?;
                        Ok((Instruction::Vmulps(dst, src1, src2), decoder.offset))
                    }
                    0x5C => {
                        // VEX: VMOVSD xmm1, xmm2/m64
                        let (mode, reg, rm) = decoder.decode_modrm()?;
                        let dst = Operand::XMMRegister(reg);
                        let src = decoder.decode_operand(mode, reg, rm)?;
                        Ok((Instruction::Movsd(dst, src), decoder.offset))
                    }
                    0x5E => {
                        // VEX: VDPPD xmm1 {k1}{z}, xmm2, xmm3/m128, imm8
                        let (mode, reg, rm) = decoder.decode_modrm()?;
                        let dst = Operand::XMMRegister(reg);
                        let src1 = Operand::XMMRegister(rm);
                        let src2 = decoder.decode_operand(mode, reg, rm)?;
                        let imm = decoder.decode_immediate(1)? as u8;
                        // For simplicity, we encapsulate imm8 in the operand as others
                        let src3 = Operand::Immediate(imm as u64);
                        Ok((Instruction::Vaddpd(dst, src1, src3), decoder.offset))
                    }
                    // Add more VEX-encoded instructions here
                    _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                }
            }

            // EVEX Encoded Instructions (AVX-512)
            &[0x62, ..] => {
                // Handle EVEX-encoded instructions
                // Example implementations for EVEX-encoded instructions
                if opcode_vec.len() < 5 {
                    return Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset));
                }

                let evex_opcode = opcode_vec[4];
                match evex_opcode {
                    0x7C => {
                        // EVEX: VADDPS zmm1 {k1}{z}, zmm2, zmm3/m512
                        let (mode, reg, rm) = decoder.decode_modrm()?;
                        let dst = Operand::ZMMRegister(reg);
                        let src1 = Operand::ZMMRegister(rm);
                        let src2 = decoder.decode_operand(mode, reg, rm)?;
                        Ok((Instruction::Vaddps(dst, src1, src2), decoder.offset))
                    }
                    0x7D => {
                        // EVEX: VMULPS zmm1 {k1}{z}, zmm2, zmm3/m512
                        let (mode, reg, rm) = decoder.decode_modrm()?;
                        let dst = Operand::ZMMRegister(reg);
                        let src1 = Operand::ZMMRegister(rm);
                        let src2 = decoder.decode_operand(mode, reg, rm)?;
                        Ok((Instruction::Vmulps(dst, src1, src2), decoder.offset))
                    }
                    0x7E => {
                        // EVEX: VCVTPS2PD zmm1 {k1}{z}, xmm2/m128
                        let (mode, reg, rm) = decoder.decode_modrm()?;
                        let dst = Operand::ZMMRegister(reg);
                        let src = decoder.decode_operand(mode, reg, rm)?;
                        Ok((Instruction::Vaddpd(dst.clone(), Operand::XMMRegister(rm), src), decoder.offset)) // Placeholder
                    }
                    // Add more EVEX-encoded instructions here
                    _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                }
            }

            // Floating-Point Instructions
            &[0xD8, ..] | &[0xD9, ..] | &[0xDA, ..] | &[0xDB, ..] | &[0xDC, ..] |
            &[0xDD, ..] | &[0xDE, ..] | &[0xDF, ..] => {
                // Implement specific floating-point instruction decoding here
                // For example, FADD ST(0), ST(i)
                let opcode = opcode_vec[0];
                if opcode >= 0xD8 && opcode <= 0xDF {
                    let subopcode = opcode_vec.get(1).copied().unwrap_or(0);
                    let (mode, reg, rm) = decoder.decode_modrm()?;
                    let st_i = rm;
                    match opcode {
                        0xD8 => match subopcode {
                            0xC0 => Ok((Instruction::Fadd(Operand::FPRegister(st_i)), decoder.offset)),
                            0xC8 => Ok((Instruction::Fsub(Operand::FPRegister(st_i)), decoder.offset)),
                            0xC1 => Ok((Instruction::Fmul(Operand::FPRegister(st_i)), decoder.offset)),
                            0xD0 => Ok((Instruction::Fdiv(Operand::FPRegister(st_i)), decoder.offset)),
                            _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                        },
                        0xD9 => match subopcode {
                            0xC0 => Ok((Instruction::Fcom(Operand::FPRegister(st_i)), decoder.offset)),
                            0xC8 => Ok((Instruction::Fcomp(Operand::FPRegister(st_i)), decoder.offset)),
                            _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                        },
                        0xDA => match subopcode {
                            0xC0 => Ok((Instruction::Fld(Operand::FPRegister(st_i)), decoder.offset)),
                            _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                        },
                        0xDB => match subopcode {
                            0xC0 => Ok((Instruction::Fst(Operand::FPRegister(st_i)), decoder.offset)),
                            0xC8 => Ok((Instruction::Fstp(Operand::FPRegister(st_i)), decoder.offset)),
                            _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                        },
                        0xDC => match subopcode {
                            0xC0 => Ok((Instruction::Fldcw(Operand::Memory("[FCW]".to_string())), decoder.offset)),
                            0xC8 => Ok((Instruction::Fstcw(Operand::Memory("[FCW]".to_string())), decoder.offset)),
                            0xCA => Ok((Instruction::Fnstcw(Operand::Memory("[FCW]".to_string())), decoder.offset)),
                            _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                        },
                        0xDD => match subopcode {
                            0xC0 => Ok((Instruction::Fild(Operand::Memory("[MEM]".to_string())), decoder.offset)),
                            0xC8 => Ok((Instruction::Fistp(Operand::Memory("[MEM]".to_string())), decoder.offset)),
                            0xC1 => Ok((Instruction::Fist(Operand::Memory("[MEM]".to_string())), decoder.offset)),
                            _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                        },
                        0xDE => match subopcode {
                            0xC0 => Ok((Instruction::Fadd(Operand::FPRegister(st_i)), decoder.offset)), // Placeholder
                            0xC8 => Ok((Instruction::Fsub(Operand::FPRegister(st_i)), decoder.offset)), // Placeholder
                            _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                        },
                        0xDF => match subopcode {
                            0xC0 => Ok((Instruction::Fcompp, decoder.offset)),
                            _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                        },
                        _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                    }
                } else {
                    Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset))
                }
            }

            // SIMD Instructions with opcode 0x0F D6 - PMULLW
            &[0x0F, 0xD6, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let dst = Operand::XMMRegister(reg);
                let src = decoder.decode_operand(mode, reg, rm)?;
                Ok((Instruction::Pmullw(dst, src), decoder.offset))
            }

            // System Instructions
            &[0x0F, 0x01, 0xF8, ..] => Ok((Instruction::Clc, decoder.offset)),
            &[0x0F, 0x01, 0xF9, ..] => Ok((Instruction::Stc, decoder.offset)),
            &[0x0F, 0x01, 0xFA, ..] => Ok((Instruction::Cli, decoder.offset)),
            &[0x0F, 0x01, 0xFB, ..] => Ok((Instruction::Sti, decoder.offset)),
            &[0x0F, 0x01, 0xFC, ..] => Ok((Instruction::Cld, decoder.offset)),
            &[0x0F, 0x01, 0xFD, ..] => Ok((Instruction::Std, decoder.offset)),
            &[0x0F, 0x01, 0xFE, ..] => Ok((Instruction::Cmc, decoder.offset)), // Example

            // F6/F7 group instructions (e.g., TEST, DIV, IMUL, etc.)
            &[0xF6, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let operand = decoder.decode_operand(mode, reg, rm)?;
                match reg {
                    0 => Ok((Instruction::Test(operand.clone(), Operand::Immediate(0)), decoder.offset)),
                    2 => Ok((Instruction::Not(operand), decoder.offset)),
                    3 => Ok((Instruction::Neg(operand), decoder.offset)),
                    4 => Ok((Instruction::Mul(operand), decoder.offset)),
                    5 => Ok((Instruction::IMul(operand.clone(), operand.clone()), decoder.offset)),
                    6 => Ok((Instruction::Div(operand), decoder.offset)),
                    7 => Ok((Instruction::IDiv(operand), decoder.offset)),
                    _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                }
            }
            &[0xF7, ..] => {
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let operand = decoder.decode_operand(mode, reg, rm)?;
                match reg {
                    0 => Ok((Instruction::Test(operand.clone(), Operand::Immediate(0)), decoder.offset)),
                    2 => Ok((Instruction::Not(operand), decoder.offset)),
                    3 => Ok((Instruction::Neg(operand), decoder.offset)),
                    4 => Ok((Instruction::Mul(operand), decoder.offset)),
                    5 => Ok((Instruction::IMul(operand.clone(), operand.clone()), decoder.offset)),
                    6 => Ok((Instruction::Div(operand), decoder.offset)),
                    7 => Ok((Instruction::IDiv(operand), decoder.offset)),
                    _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
                }
            }

            // Floating-Point Group Instructions (0xD8-0xDF)
            &[0xD8, 0xC0..=0xFF, ..] => {
                // Implement specific FPU instructions
                Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset))
            }

            // Conditional jumps with short displacement
            &[0x70..=0x7F, ..] => {
                let cond = opcode_vec[0] - 0x70;
                let rel = decoder.decode_immediate(1)? as i8;
                let target = rip.wrapping_add(rel as u64).wrapping_add(decoder.offset as u64);
                let instruction = match cond {
                    0 => Instruction::Jo(Operand::Relative(target)),
                    1 => Instruction::Jno(Operand::Relative(target)),
                    2 => Instruction::Jb(Operand::Relative(target)),
                    3 => Instruction::Jae(Operand::Relative(target)),
                    4 => Instruction::Je(Operand::Relative(target)),
                    5 => Instruction::Jne(Operand::Relative(target)),
                    6 => Instruction::Jbe(Operand::Relative(target)),
                    7 => Instruction::Ja(Operand::Relative(target)),
                    8 => Instruction::Js(Operand::Relative(target)),
                    9 => Instruction::Jns(Operand::Relative(target)),
                    10 => Instruction::Jp(Operand::Relative(target)),
                    11 => Instruction::Jnp(Operand::Relative(target)),
                    12 => Instruction::Jl(Operand::Relative(target)),
                    13 => Instruction::Jge(Operand::Relative(target)),
                    14 => Instruction::Jle(Operand::Relative(target)),
                    15 => Instruction::Jg(Operand::Relative(target)),
                    _ => Instruction::Unknown(opcode_vec.clone()),
                };
                Ok((instruction, decoder.offset))
            }

            // Increment and Decrement instructions
            &[0x40..=0x47] => {
                let reg = opcode_vec[0] - 0x40;
                let reg_name = register_name(reg, decoder.rex);
                Ok((Instruction::Inc(Operand::Register(reg_name)), decoder.offset))
            }
            &[0x48..=0x4F] => {
                let reg = opcode_vec[0] - 0x48;
                let reg_name = register_name(reg, decoder.rex);
                Ok((Instruction::Dec(Operand::Register(reg_name)), decoder.offset))
            }

            // Other single-byte opcodes
            &[0xF4] => Ok((Instruction::Hlt, decoder.offset)),
            &[0xF5] => Ok((Instruction::Cmc, decoder.offset)),
            &[0xF8] => Ok((Instruction::Cld, decoder.offset)),
            &[0xF9] => Ok((Instruction::Std, decoder.offset)),
            &[0xFB] => Ok((Instruction::Sti, decoder.offset)),
            &[0xFA] => Ok((Instruction::Cli, decoder.offset)),
            &[0xF6, ..] | &[0xF7, ..] => {
                // Already handled above
                Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset))
            },

            // Prefix-only instructions
            &[0xF3, ..] => Ok((Instruction::PrefixRep, decoder.offset)),
            &[0xF2, ..] => Ok((Instruction::PrefixRepne, decoder.offset)),
            &[0xF0, ..] => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)), // LOCK prefix

            // System Calls and Interrupts
            &[0xCD, ..] => {
                let imm = decoder.decode_immediate(1)? as u8;
                Ok((Instruction::Int(imm), decoder.offset))
            }
            &[0xCE] => Ok((Instruction::Into, decoder.offset)),
            &[0xCF] => Ok((Instruction::Iret, decoder.offset)),
            &[0x90] => Ok((Instruction::Nop, decoder.offset)),
            &[0x91] => Ok((Instruction::Xchg(Operand::Register("rax".to_string()), Operand::Register("rcx".to_string())), decoder.offset)),
            &[0x92] => Ok((Instruction::Xchg(Operand::Register("rax".to_string()), Operand::Register("rdx".to_string())), decoder.offset)),
            // ... Additional single-byte opcodes can be handled here

            // Additional Opcode Groups and Encodings
            &[0x0F, 0xAF, ..] => {
                // IMUL with two-byte opcode
                let (mode, reg, rm) = decoder.decode_modrm()?;
                let dst = Operand::Register(register_name(reg, decoder.rex));
                let src = decoder.decode_operand(mode, reg, rm)?;
                Ok((Instruction::IMul(dst, src), decoder.offset))
            }

            // Default case for unknown instructions
            _ => Ok((Instruction::Unknown(opcode_vec.clone()), decoder.offset)),
        }
    }
}

impl fmt::Display for Instruction {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            // Data Movement
            Instruction::Mov(dst, src) => write!(f, "mov {}, {}", dst, src),
            Instruction::Push(op) => write!(f, "push {}", op),
            Instruction::Pop(op) => write!(f, "pop {}", op),
            Instruction::Lea(dst, src) => write!(f, "lea {}, {}", dst, src),
            Instruction::Xchg(dst, src) => write!(f, "xchg {}, {}", dst, src),
            Instruction::Cmovcc(cond, dst, src) => write!(f, "cmov{} {}, {}", cond, dst, src),
            Instruction::Movzx(dst, src) => write!(f, "movzx {}, {}", dst, src),
            Instruction::Movsx(dst, src) => write!(f, "movsx {}, {}", dst, src),
            Instruction::Movdq2q(dst, src) => write!(f, "movdq2q {}, {}", dst, src),
            Instruction::Movdqa(dst, src) => write!(f, "movdqa {}, {}", dst, src),
            Instruction::Movaps(dst, src) => write!(f, "movaps {}, {}", dst, src),
            Instruction::Movups(dst, src) => write!(f, "movups {}, {}", dst, src),
            Instruction::Movss(dst, src) => write!(f, "movss {}, {}", dst, src),
            Instruction::Movsd(dst, src) => write!(f, "movsd {}, {}", dst, src),
            Instruction::Movbe(dst, src) => write!(f, "movbe {}, {}", dst, src),
            Instruction::Movnti(dst, src) => write!(f, "movnti {}, {}", dst, src),
            Instruction::Movdqu(dst, src) => write!(f, "movdqu {}, {}", dst, src),
            Instruction::Movq(dst, src) => write!(f, "movq {}, {}", dst, src),
            Instruction::Movsxd(dst, src) => write!(f, "movsxd {}, {}", dst, src),

            // Arithmetic
            Instruction::Add(dst, src) => write!(f, "add {}, {}", dst, src),
            Instruction::Sub(dst, src) => write!(f, "sub {}, {}", dst, src),
            Instruction::Mul(op) => write!(f, "mul {}", op),
            Instruction::IMul(dst, src) => write!(f, "imul {}, {}", dst, src),
            Instruction::Div(op) => write!(f, "div {}", op),
            Instruction::IDiv(op) => write!(f, "idiv {}", op),
            Instruction::Inc(op) => write!(f, "inc {}", op),
            Instruction::Dec(op) => write!(f, "dec {}", op),
            Instruction::Neg(op) => write!(f, "neg {}", op),
            Instruction::Adc(dst, src) => write!(f, "adc {}, {}", dst, src),
            Instruction::Sbb(dst, src) => write!(f, "sbb {}, {}", dst, src),
            Instruction::IncDec(op_type, op) => write!(f, "{} {}", op_type, op),

            // Logic
            Instruction::And(dst, src) => write!(f, "and {}, {}", dst, src),
            Instruction::Or(dst, src) => write!(f, "or {}, {}", dst, src),
            Instruction::Xor(dst, src) => write!(f, "xor {}, {}", dst, src),
            Instruction::Not(op) => write!(f, "not {}", op),
            Instruction::Shl(dst, src) => write!(f, "shl {}, {}", dst, src),
            Instruction::Shr(dst, src) => write!(f, "shr {}, {}", dst, src),
            Instruction::Sar(dst, src) => write!(f, "sar {}, {}", dst, src),
            Instruction::Rol(dst, src) => write!(f, "rol {}, {}", dst, src),
            Instruction::Ror(dst, src) => write!(f, "ror {}, {}", dst, src),
            Instruction::Rcl(dst, src) => write!(f, "rcl {}, {}", dst, src),
            Instruction::Rcr(dst, src) => write!(f, "rcr {}, {}", dst, src),
            Instruction::Shld(dst, src, count) => write!(f, "shld {}, {}, {}", dst, src, count),
            Instruction::Shrd(dst, src, count) => write!(f, "shrd {}, {}, {}", dst, src, count),

            // Control Flow
            Instruction::Call(op) => write!(f, "call {}", op),
            Instruction::Jmp(op) => write!(f, "jmp {}", op),
            Instruction::Je(op) => write!(f, "je {}", op),
            Instruction::Jne(op) => write!(f, "jne {}", op),
            Instruction::Jg(op) => write!(f, "jg {}", op),
            Instruction::Jge(op) => write!(f, "jge {}", op),
            Instruction::Jp(op) => write!(f, "jp {}", op),
            Instruction::Jnp(op) => write!(f, "jnp {}", op),
            Instruction::Jl(op) => write!(f, "jl {}", op),
            Instruction::Jle(op) => write!(f, "jle {}", op),
            Instruction::Ja(op) => write!(f, "ja {}", op),
            Instruction::Jae(op) => write!(f, "jae {}", op),
            Instruction::Jb(op) => write!(f, "jb {}", op),
            Instruction::Jbe(op) => write!(f, "jbe {}", op),
            Instruction::Js(op) => write!(f, "js {}", op),
            Instruction::Jns(op) => write!(f, "jns {}", op),
            Instruction::Jo(op) => write!(f, "jo {}", op),
            Instruction::Jno(op) => write!(f, "jno {}", op),
            Instruction::Jc(op) => write!(f, "jc {}", op),
            Instruction::Jnc(op) => write!(f, "jnc {}", op),
            Instruction::Jecxz(op) => write!(f, "jecxz {}", op),
            Instruction::Loop(op) => write!(f, "loop {}", op),
            Instruction::Loope(op) => write!(f, "loope {}", op),
            Instruction::Loopne(op) => write!(f, "loopne {}", op),
            Instruction::Jrcxz(op) => write!(f, "jrcxz {}", op),
            Instruction::Ret => write!(f, "ret"),
            Instruction::RetImm(imm) => write!(f, "ret {}", imm),
            Instruction::Syscall => write!(f, "syscall"),
            Instruction::Int(imm) => write!(f, "int {}", imm),
            Instruction::Into => write!(f, "into"),
            Instruction::Iret => write!(f, "iret"),

            // Stack
            Instruction::Enter(level, nesting) => write!(f, "enter {}, {}", level, nesting),
            Instruction::Leave => write!(f, "leave"),
            Instruction::PushA => write!(f, "pusha"),
            Instruction::PopA => write!(f, "popa"),
            Instruction::PushF => write!(f, "pushf"),
            Instruction::PopF => write!(f, "popf"),

            // Comparison
            Instruction::Cmp(dst, src) => write!(f, "cmp {}, {}", dst, src),
            Instruction::Test(dst, src) => write!(f, "test {}, {}", dst, src),

            // String Operations
            Instruction::Movs(size) => write!(f, "movs{}", size_suffix(*size)),
            Instruction::Cmps(size) => write!(f, "cmps{}", size_suffix(*size)),
            Instruction::Scas(size) => write!(f, "scas{}", size_suffix(*size)),
            Instruction::Lods(size) => write!(f, "lods{}", size_suffix(*size)),
            Instruction::Stos(size) => write!(f, "stos{}", size_suffix(*size)),
            Instruction::Bt(dst, src) => write!(f, "bt {}, {}", dst, src),
            Instruction::Bts(dst, src) => write!(f, "bts {}, {}", dst, src),
            Instruction::Btr(dst, src) => write!(f, "btr {}, {}", dst, src),
            Instruction::Btc(dst, src) => write!(f, "btc {}, {}", dst, src),
            Instruction::Rep(inner) => write!(f, "rep {}", inner),
            Instruction::Repe(inner) => write!(f, "repe {}", inner),
            Instruction::Repne(inner) => write!(f, "repne {}", inner),
            Instruction::Cmc => write!(f, "cmc"),

            // Floating-Point
            Instruction::Fld(op) => write!(f, "fld {}", op),
            Instruction::Fst(op) => write!(f, "fst {}", op),
            Instruction::Fstp(op) => write!(f, "fstp {}", op),
            Instruction::Fadd(op) => write!(f, "fadd {}", op),
            Instruction::Fsub(op) => write!(f, "fsub {}", op),
            Instruction::Fmul(op) => write!(f, "fmul {}", op),
            Instruction::Fdiv(op) => write!(f, "fdiv {}", op),
            Instruction::Fcom(op) => write!(f, "fcom {}", op),
            Instruction::Fcomp(op) => write!(f, "fcomp {}", op),
            Instruction::Fcompp => write!(f, "fcompp"),
            Instruction::Fild(op) => write!(f, "fild {}", op),
            Instruction::Fist(op) => write!(f, "fist {}", op),
            Instruction::Fistp(op) => write!(f, "fistp {}", op),
            Instruction::Fldcw(op) => write!(f, "fldcw {}", op),
            Instruction::Fstcw(op) => write!(f, "fstcw {}", op),
            Instruction::Fnstcw(op) => write!(f, "fnstcw {}", op),

            // MMX and SIMD
            Instruction::Paddb(dst, src) => write!(f, "paddb {}, {}", dst, src),
            Instruction::Paddw(dst, src) => write!(f, "paddw {}, {}", dst, src),
            Instruction::Paddd(dst, src) => write!(f, "paddd {}, {}", dst, src),
            Instruction::Paddq(dst, src) => write!(f, "paddq {}, {}", dst, src),
            Instruction::Psubb(dst, src) => write!(f, "psubb {}, {}", dst, src),
            Instruction::Psubw(dst, src) => write!(f, "psubw {}, {}", dst, src),
            Instruction::Psubd(dst, src) => write!(f, "psubd {}, {}", dst, src),
            Instruction::Psubq(dst, src) => write!(f, "psubq {}, {}", dst, src),
            Instruction::Pmullw(dst, src) => write!(f, "pmullw {}, {}", dst, src),
            Instruction::Pmulhw(dst, src) => write!(f, "pmulhw {}, {}", dst, src),
            Instruction::Pmulhuw(dst, src) => write!(f, "pmulhuw {}, {}", dst, src),
            Instruction::Pand(dst, src) => write!(f, "pand {}, {}", dst, src),
            Instruction::Por(dst, src) => write!(f, "por {}, {}", dst, src),
            Instruction::Pxor(dst, src) => write!(f, "pxor {}, {}", dst, src),
            Instruction::Psllw(dst, src) => write!(f, "psllw {}, {}", dst, src),
            Instruction::Pslld(dst, src) => write!(f, "pslld {}, {}", dst, src),
            Instruction::Psllq(dst, src) => write!(f, "psllq {}, {}", dst, src),
            Instruction::Psrlw(dst, src) => write!(f, "psrlw {}, {}", dst, src),
            Instruction::Psrld(dst, src) => write!(f, "psrld {}, {}", dst, src),
            Instruction::Psrlq(dst, src) => write!(f, "psrlq {}, {}", dst, src),
            Instruction::Pdep(dst, src) => write!(f, "pdep {}, {}", dst, src),
            Instruction::Pext(dst, src) => write!(f, "pext {}, {}", dst, src),
            Instruction::Vaddps(dst, src1, src2) => write!(f, "vaddps {}, {}, {}", dst, src1, src2),
            Instruction::Vmulps(dst, src1, src2) => write!(f, "vmulps {}, {}, {}", dst, src1, src2),
            Instruction::Vaddpd(dst, src1, src2) => write!(f, "vaddpd {}, {}, {}", dst, src1, src2),
            Instruction::Vmulpd(dst, src1, src2) => write!(f, "vmulpd {}, {}, {}", dst, src1, src2),
            Instruction::Vaddss(dst, src1, src2) => write!(f, "vaddss {}, {}, {}", dst, src1, src2),
            Instruction::Vmulss(dst, src1, src2) => write!(f, "vmulss {}, {}, {}", dst, src1, src2),
            Instruction::Vaddsd(dst, src1, src2) => write!(f, "vaddsd {}, {}, {}", dst, src1, src2),
            Instruction::Vmulsd(dst, src1, src2) => write!(f, "vmulsd {}, {}, {}", dst, src1, src2),
            Instruction::Vinsertps(dst, src1, src2) => write!(f, "vinsertps {}, {}, {}", dst, src1, src2),
            Instruction::Vblendps(dst, src1, src2) => write!(f, "vblendps {}, {}, {}", dst, src1, src2),
            Instruction::Vblendpd(dst, src1, src2) => write!(f, "vblendpd {}, {}, {}", dst, src1, src2),
            // ... Additional SIMD instructions can be added here

            // System
            Instruction::Cpuid => write!(f, "cpuid"),
            Instruction::Rdtsc => write!(f, "rdtsc"),
            Instruction::Rdmsr => write!(f, "rdmsr"),
            Instruction::Wrmsr => write!(f, "wrmsr"),
            Instruction::Sgdt(op) => write!(f, "sgdt {}", op),
            Instruction::Sidt(op) => write!(f, "sidt {}", op),
            Instruction::Lgdt(op) => write!(f, "lgdt {}", op),
            Instruction::Lidt(op) => write!(f, "lidt {}", op),
            Instruction::Invlpg(op) => write!(f, "invlpg {}", op),
            Instruction::Wbinvd => write!(f, "wbinvd"),
            Instruction::Hlt => write!(f, "hlt"),
            Instruction::Nop => write!(f, "nop"),
            Instruction::Ud2 => write!(f, "ud2"),
            Instruction::Sysret => write!(f, "sysret"),
            Instruction::Sysretq => write!(f, "sysretq"),

            // Miscellaneous
            Instruction::Cdq => write!(f, "cdq"),
            Instruction::Cwd => write!(f, "cwd"),
            Instruction::Cwde => write!(f, "cwde"),
            Instruction::Cbw => write!(f, "cbw"),
            Instruction::Clc => write!(f, "clc"),
            Instruction::Stc => write!(f, "stc"),
            Instruction::Cli => write!(f, "cli"),
            Instruction::Sti => write!(f, "sti"),
            Instruction::Cld => write!(f, "cld"),
            Instruction::Std => write!(f, "std"),
            Instruction::Nopd => write!(f, "nopd"),
            Instruction::Nahf => write!(f, "nahf"),
            Instruction::Pause => write!(f, "pause"),
            Instruction::LFENCE => write!(f, "lfence"),
            Instruction::MFENCE => write!(f, "mfence"),
            Instruction::SFENCE => write!(f, "sfence"),
            Instruction::Prefetchnta(op) => write!(f, "prefetchnta {}", op),
            Instruction::Prefetchw(op) => write!(f, "prefetchw {}", op),
            Instruction::Prefetchh(op) => write!(f, "prefetchh {}", op),

            // Prefixes
            Instruction::PrefixRep => write!(f, "rep"),
            Instruction::PrefixRepe => write!(f, "repe"),
            Instruction::PrefixRepne => write!(f, "repne"),

            // Unknown
            Instruction::Unknown(bytes) => write!(
                f,
                "db {}",
                bytes.iter().map(|b| format!("{:02x}", b)).collect::<Vec<_>>().join(" ")
            ),

            // Add more matches as needed
        }
    }
}

impl fmt::Display for Operand {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Operand::Register(reg) => write!(f, "{}", reg),
            Operand::Immediate(imm) => write!(f, "{}", imm),
            Operand::Immediate8(imm) => write!(f, "{}", imm),
            Operand::Immediate16(imm) => write!(f, "{}", imm),
            Operand::Immediate32(imm) => write!(f, "{}", imm),
            Operand::Immediate64(imm) => write!(f, "{}", imm),
            Operand::Memory(mem) => write!(f, "{}", mem),
            Operand::SegRegister(seg) => write!(f, "{}", seg),
            Operand::Relative(addr) => write!(f, "0x{:016x}", addr),
            Operand::FPRegister(n) => write!(f, "st({})", n),
            Operand::MMXRegister(n) => write!(f, "mm{}", n),
            Operand::XMMRegister(n) => write!(f, "xmm{}", n),
            Operand::YMMRegister(n) => write!(f, "ymm{}", n),
            Operand::ZMMRegister(n) => write!(f, "zmm{}", n),
            Operand::Others(desc) => write!(f, "{}", desc),
        }
    }
}

/// Provides size suffixes based on operand size.
fn size_suffix(size: u8) -> &'static str {
    match size {
        1 => "b",
        2 => "w",
        4 => "d",
        8 => "q",
        _ => "",
    }
}

/// Decoder struct responsible for parsing byte sequences into instructions.
struct Decoder {
    bytes: Vec<u8>,
    offset: usize,
    rex: Option<u8>,
    prefixes: Vec<u8>,
    operand_size: usize,
    address_size: usize,
    rip: u64,
}

impl Decoder {
    /// Creates a new Decoder instance.
    fn new(bytes: Vec<u8>, rip: u64) -> Self {
        Self {
            bytes,
            offset: 0,
            rex: None,
            prefixes: Vec::new(),
            operand_size: 32,
            address_size: 32,
            rip,
        }
    }

    /// Fetches the next byte from the byte stream.
    fn next_byte(&mut self) -> Option<u8> {
        if self.offset < self.bytes.len() {
            let byte = self.bytes[self.offset];
            self.offset += 1;
            Some(byte)
        } else {
            None
        }
    }

    /// Peeks at the next byte without consuming it.
    fn peek_byte(&self) -> Option<u8> {
        self.bytes.get(self.offset).copied()
    }

    /// Decodes all possible prefixes at the beginning of the instruction.
    fn decode_prefixes(&mut self) {
        while let Some(byte) = self.peek_byte() {
            match byte {
                // LOCK and repeat prefixes
                0xF0 | 0xF2 | 0xF3 => {
                    self.prefixes.push(byte);
                    self.next_byte();
                }
                // Segment overrides
                0x2E | 0x36 | 0x3E | 0x26 | 0x64 | 0x65 => {
                    self.prefixes.push(byte);
                    self.next_byte();
                }
                // Operand-size and address-size prefixes
                0x66 | 0x67 => {
                    self.prefixes.push(byte);
                    self.next_byte();
                    match byte {
                        0x66 => self.operand_size = 16,
                        0x67 => self.address_size = 16,
                        _ => {}
                    }
                }
                // REX prefixes
                0x40..=0x4F => {
                    self.rex = Some(self.next_byte().unwrap());
                    // Adjust operand and address sizes based on REX.W
                    if self.rex.unwrap() & 0b1000 != 0 {
                        self.operand_size = 64;
                    }
                    if self.rex.unwrap() & 0b0001 != 0 {
                        self.address_size = 64;
                    }
                }
                _ => break,
            }
        }
    }

    /// Decodes the ModR/M byte and returns (mode, reg, rm).
    fn decode_modrm(&mut self) -> Result<(u8, u8, u8), &'static str> {
        if let Some(modrm) = self.next_byte() {
            let mode = (modrm >> 6) & 0b11;
            let reg = (modrm >> 3) & 0b111;
            let rm = modrm & 0b111;
            Ok((mode, reg, rm))
        } else {
            Err("Unexpected end of input while decoding ModR/M")
        }
    }

    /// Decodes the SIB byte and returns (scale, index, base).
    fn decode_sib(&mut self) -> Result<(u8, u8, u8), &'static str> {
        if let Some(sib) = self.next_byte() {
            let scale = (sib >> 6) & 0b11;
            let index = (sib >> 3) & 0b111;
            let base = sib & 0b111;
            Ok((scale, index, base))
        } else {
            Err("Unexpected end of input while decoding SIB")
        }
    }

    /// Decodes displacement based on the addressing mode.
    fn decode_displacement(&mut self, mode: u8) -> Result<i64, &'static str> {
        match mode {
            0b00 => {
                // Special cases for base registers with no displacement
                // e.g., [RIP + disp32] in 64-bit mode
                Ok(0)
            }
            0b01 => {
                // 8-bit displacement
                let disp = self.decode_immediate(1)? as i8;
                Ok(disp as i64)
            }
            0b10 => {
                // 32-bit displacement
                let disp = self.decode_immediate(4)? as i32;
                Ok(disp as i64)
            }
            _ => Err("Invalid displacement mode"),
        }
    }

    /// Decodes an immediate value of given size (in bytes).
    fn decode_immediate(&mut self, size: usize) -> Result<u64, &'static str> {
        let mut value = 0u64;
        for i in 0..size {
            if let Some(byte) = self.next_byte() {
                value |= (byte as u64) << (8 * i);
            } else {
                return Err("Unexpected end of input while decoding immediate");
            }
        }
        Ok(value)
    }

    /// Decodes an operand based on ModR/M, SIB, and displacement.
    fn decode_operand(&mut self, mode: u8, reg: u8, rm: u8) -> Result<Operand, &'static str> {
        match mode {
            0b11 => Ok(Operand::Register(register_name(rm, self.rex))),
            _ => {
                let (base_reg, has_sib) = if rm == 0b100 && mode != 0b11 {
                    // SIB byte is present and not register-direct addressing
                    (Some(register_name(rm, self.rex)), true)
                } else {
                    (Some(register_name(rm, self.rex)), false)
                };

                let (base, index, scale) = if has_sib {
                    let (sib_scale, sib_index, sib_base) = self.decode_sib()?;
                    let scale_factor = 1 << sib_scale;
                    let index_reg = if sib_index != 0b100 {
                        register_name(sib_index, self.rex)
                    } else {
                        String::new()
                    };
                    let base_reg = if sib_base != 0b101 || mode != 0b00 {
                        register_name(sib_base, self.rex)
                    } else {
                        String::new()
                    };
                    (Some(base_reg), index_reg, scale_factor)
                } else {
                    (base_reg, String::new(), 1)
                };

                let displacement = self.decode_displacement(mode)?;

                let mut address = String::new();
                if let Some(base_str) = base {
                    if !base_str.is_empty() {
                        address.push_str(&base_str);
                    }
                }

                if !index.is_empty() {
                    if !address.is_empty() {
                        address.push_str(" + ");
                    }
                    address.push_str(&format!("{}*{}", index, scale));
                }

                if displacement != 0 {
                    if !address.is_empty() {
                        address.push_str(" + ");
                    }
                    address.push_str(&format!("{}", displacement));
                }

                Ok(Operand::Memory(format!("[{}]", address)))
            }
        }
    }
}

/// Maps register numbers to their names based on REX prefixes and operand sizes.
fn register_name(reg: u8, rex: Option<u8>) -> String {
    let rex_b = rex.map(|r| (r & 0b0001) != 0).unwrap_or(false);
    let rex_w = rex.map(|r| (r & 0b1000) != 0).unwrap_or(false);

    // General-purpose registers
    let general_regs = [
        "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
        "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
    ];

    if reg < general_regs.len() as u8 {
        let idx = if rex_b && reg < 8 {
            reg + 8
        } else {
            reg
        };
        let reg_str = general_regs[idx as usize];
        if rex_w && reg < 8 {
            // Use 64-bit register names
            reg_str.to_string()
        } else if reg < 8 {
            // Use 32-bit register names
            let low_regs = ["eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"];
            low_regs[reg as usize].to_string()
        } else {
            // Use extended registers
            reg_str.to_string()
        }
    } else {
        "unknown".to_string()
    }
}

/// Determines the operand size based on the decoder's current state.
fn operand_size(decoder: &Decoder) -> usize {
    decoder.operand_size
}

/// Represents the size of the instruction based on its prefixes.   
fn address_size(decoder: &Decoder) -> usize {
    decoder.address_size
}

main.rs:
mod instruction;
mod utils;
mod disassembler;

use std::fs::File;
use std::io::Read;
use std::collections::HashMap;
use std::collections::HashSet;
use instruction::{Instruction, Operand};
use goblin::pe::PE;
use utils::simplifier::simplify_instructions;
use disassembler::smart_comments::SmartCommenter;
use disassembler::function_analyzer::{analyze_functions, Function};
use disassembler::flow_analysis::analyze_flow;
use colored::*;
use rayon::prelude::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("{}", "Advanced X86_64 Windows Disassembler".bright_cyan().bold());

    // Read the binary file
    let mut file = File::open("iscsicli.exe")?;
    let mut buffer = Vec::new();
    file.read_to_end(&mut buffer)?;

    // Parse the PE file
    let pe = PE::parse(&buffer)?;

    // Find the .text section
    let text_section = pe.sections
        .iter()
        .find(|section| section.name().unwrap_or("") == ".text")
        .ok_or("Failed to find .text section")?;

    let code_offset = text_section.pointer_to_raw_data as usize;
    let code_size = text_section.size_of_raw_data as usize;
    let code = &buffer[code_offset..code_offset + code_size];

    // Calculate the base address of the .text section
    let base_address = pe.image_base as usize + text_section.virtual_address as usize;

    // Create a simple symbol table
    let mut symbol_table = HashMap::new();
    for export in &pe.exports {
        if let Some(name) = export.name {
            symbol_table.insert(export.rva as u64 + pe.image_base as u64, name.to_string());
        }
    }

    // Disassemble the code in parallel
    let mut visited = HashSet::new();
    let mut to_visit = vec![base_address as u64];
    let mut instructions = Vec::new();

    while let Some(current_addr) = to_visit.pop() {
        if visited.contains(&current_addr) {
            continue;
        }
        visited.insert(current_addr);

        // Calculate offset
        let offset = (current_addr - (pe.image_base as usize + text_section.virtual_address as usize) as u64) as usize;
        if offset >= code.len() {
            continue;
        }

        match Instruction::decode(&code[offset..], current_addr) {
            Ok((instruction, size)) => {
                instructions.push((current_addr, instruction.clone()));
                // {{ Edit 1a: Handle control flow to determine next addresses }}
                match &instruction {
                    Instruction::Jmp(op) => {
                        if let Operand::Relative(target) = op {
                            to_visit.push(*target);
                        }
                    }
                    Instruction::Call(op) => {
                        if let Operand::Relative(target) = op {
                            to_visit.push(*target);
                        }
                        // Continue to next instruction after call
                        to_visit.push(current_addr + size as u64);
                    }
                    Instruction::Ret => {
                        // Do not add next instruction
                    }
                    Instruction::Je(op) | Instruction::Jne(op) | Instruction::Jg(op) |
                    Instruction::Jge(op) | Instruction::Jl(op) | Instruction::Jle(op) => {
                        if let Operand::Relative(target) = op {
                            to_visit.push(*target);
                        }
                        // Also follow the next instruction
                        to_visit.push(current_addr + size as u64);
                    }
                    _ => {
                        // Continue to next instruction
                        to_visit.push(current_addr + size as u64);
                    }
                }
            }
            Err(e) => {
                eprintln!("Decoding error at 0x{:016x}: {}", current_addr, e);
                // Skip to next byte to avoid infinite loop
                to_visit.push(current_addr + 1);
            }
        }
    }

    // Analyze functions
    let functions = analyze_functions(&instructions);

    // Create a map of function start addresses to functions
    let function_map: HashMap<u64, &Function> = functions.iter().map(|f| (f.start_address, f)).collect();

    // Analyze control flow
    let flow_graph = analyze_flow(&instructions);

    // Print disassembly with enhancements
    let mut current_function: Option<&Function> = None;
    let mut smart_commenter = SmartCommenter::new();
    let simplified = simplify_instructions(&instructions.iter().map(|(_, i)| i.clone()).collect::<Vec<_>>());

    for (i, ((address, instruction), (simplified_inst, comment))) in instructions.iter().zip(simplified.iter()).enumerate() {
        // Check if we're entering a new function
        if let Some(func) = function_map.get(address) {
            if current_function.is_some() {
                println!("{}", "Function end.".bright_cyan().bold());
            }
            println!("{} {}: (calls: {}, jumps: {}, refs: {})", 
                "Function start:".bright_cyan().bold(), 
                func.name.bright_yellow(),
                func.calls.len(),
                func.jumps.len(),
                func.references.len()
            );
            current_function = Some(func);
        }

        print!("{}: ", format!("0x{:08x}", address).yellow());
        
        match simplified_inst {
            Instruction::Unknown(bytes) => {
                print!("{} {}", "db".bright_red(), bytes.iter().map(|b| format!("{:02x}", b)).collect::<Vec<_>>().join(" ").bright_white());
            },
            _ => {
                let inst_str = format!("{}", simplified_inst);
                let (mnemonic, operands) = inst_str.split_once(' ').unwrap_or((&inst_str, ""));
                print!("{} {}", mnemonic.bright_green(), operands.bright_white());
            }
        }
        
        if let Some(smart_comment) = smart_commenter.add_smart_comment(instruction, *address) {
            print!(" {}", format!("; {}", smart_comment).bright_blue());
        }

        if let Some(simplification) = comment {
            print!(" {}", format!("; {}", simplification).bright_magenta());
        }

        if let Some(symbol) = symbol_table.get(address) {
            print!(" {}", format!("<{}>", symbol).bright_yellow());
        }

        // Advanced analysis

        println!();

        // Print control flow information
        if let Some(targets) = flow_graph.get(address) {
            for target in targets {
                if *target != instructions.get(i + 1).map(|(addr, _)| *addr).unwrap_or(0) {
                    if let Some(func) = function_map.get(target) {
                        println!("  {} 0x{:016x} <{}>", "->".bright_red(), target, func.name.bright_yellow());
                    } else {
                        println!("  {} 0x{:016x}", "->".bright_red(), target);
                    }
                }
            }
        }

        // Check if we're exiting the current function
        if let Some(func) = current_function {
            if *address == func.end_address {
                println!("{}", "Function end.".bright_cyan().bold());
                current_function = None;
            }
        }
    }

    Ok(())
}
utils/mod.rs:
pub mod simplifier;
utils/simplifier.rs:
use crate::instruction::{Instruction, Operand};
use regex::Regex;
use std::collections::HashMap;

pub fn simplify_instructions(instructions: &[Instruction]) -> Vec<(Instruction, Option<String>)> {
    let mut simplified = Vec::new();
    let mut register_values = HashMap::new();

    for (i, inst) in instructions.iter().enumerate() {
        let (simplified_inst, comment) = simplify_instruction(inst, &mut register_values, &instructions[i+1..]);
        simplified.push((simplified_inst, comment));
    }

    simplified
}

fn simplify_instruction(instruction: &Instruction, register_values: &mut HashMap<String, i64>, next_instructions: &[Instruction]) -> (Instruction, Option<String>) {
    match instruction {
        Instruction::Lea(dst, src) => simplify_lea(dst, src),
        Instruction::Mov(dst, src) => simplify_mov(dst, src, register_values),
        Instruction::Add(dst, src) => simplify_add(dst, src, register_values),
        Instruction::Sub(dst, src) => simplify_sub(dst, src, register_values),
        Instruction::And(dst, src) => simplify_and(dst, src, register_values),
        Instruction::Or(dst, src) => simplify_or(dst, src, register_values),
        Instruction::Xor(dst, src) => simplify_xor(dst, src, register_values),
        Instruction::Shl(dst, src) => simplify_shift(dst, src, "shl", register_values),
        Instruction::Shr(dst, src) => simplify_shift(dst, src, "shr", register_values),
        Instruction::Sar(dst, src) => simplify_shift(dst, src, "sar", register_values),
        Instruction::Call(op) => simplify_call(op),
        Instruction::Push(op) => simplify_push(op, next_instructions),
        _ => (instruction.clone(), None),
    }
}

fn simplify_lea(dst: &Operand, src: &Operand) -> (Instruction, Option<String>) {
    if let Operand::Memory(mem) = src {
        let re = Regex::new(r"\[(\w+)(?:\s*([+-])\s*(\w+)(?:\*(\d+))?)?(?:\s*([+-])\s*(\d+))?\]").unwrap();
        if let Some(captures) = re.captures(mem) {
            let base = &captures[1];
            let index = captures.get(3).map(|m| m.as_str());
            let scale = captures.get(4).map(|m| m.as_str()).unwrap_or("1");
            let disp = captures.get(6).map(|m| m.as_str()).unwrap_or("0");
            
            let simplified_mem = match (index, scale) {
                (Some(idx), "1") if base == idx => format!("[{}*2 + {}]", base, disp),
                (Some(idx), scale) => format!("[{} + {}*{} + {}]", base, idx, scale, disp),
                _ => format!("[{} + {}]", base, disp),
            };
            
            let simplified_src = Operand::Memory(simplified_mem);
            let simplified_inst = Instruction::Lea(dst.clone(), simplified_src);
            return (simplified_inst, Some("Simplified addressing".to_string()));
        }
    }
    (Instruction::Lea(dst.clone(), src.clone()), None)
}

fn simplify_mov(dst: &Operand, src: &Operand, register_values: &mut HashMap<String, i64>) -> (Instruction, Option<String>) {
    if dst == src {
        return (Instruction::Nop, Some("Removed self-move".to_string()));
    }
    
    if let Operand::Register(reg) = dst {
        if let Operand::Immediate(imm) = src {
            register_values.insert(reg.clone(), (*imm).try_into().unwrap());
        } else {
            register_values.remove(reg);
        }
    }
    
    (Instruction::Mov(dst.clone(), src.clone()), None)
}

fn simplify_add(dst: &Operand, src: &Operand, register_values: &mut HashMap<String, i64>) -> (Instruction, Option<String>) {
    match (dst, src) {
        (Operand::Register(reg), Operand::Immediate(0)) => {
            (Instruction::Nop, Some("Removed add zero".to_string()))
        },
        (Operand::Register(reg), Operand::Immediate(imm)) => {
            if let Some(value) = register_values.get(reg) {
                let new_value = *value + *imm as i64;
                register_values.insert(reg.clone(), new_value);
                (Instruction::Mov(dst.clone(), Operand::Immediate(new_value as u64)), Some("Simplified add to mov".to_string()))
            } else {
                (Instruction::Add(dst.clone(), src.clone()), None)
            }
        },
        _ => (Instruction::Add(dst.clone(), src.clone()), None),
    }
}

fn simplify_sub(dst: &Operand, src: &Operand, register_values: &mut HashMap<String, i64>) -> (Instruction, Option<String>) {
    match (dst, src) {
        (Operand::Register(reg), Operand::Immediate(0)) => {
            (Instruction::Nop, Some("Removed sub zero".to_string()))
        },
        (Operand::Register(reg), Operand::Immediate(imm)) => {
            if let Some(value) = register_values.get(reg) {
                let new_value = *value - *imm as i64;
                register_values.insert(reg.clone(), new_value);
                (Instruction::Mov(dst.clone(), Operand::Immediate(new_value as u64)), Some("Simplified sub to mov".to_string()))
            } else {
                (Instruction::Sub(dst.clone(), src.clone()), None)

            }
        },
        _ => (Instruction::Sub(dst.clone(), src.clone()), None),
    }
}

fn simplify_and(dst: &Operand, src: &Operand, register_values: &mut HashMap<String, i64>) -> (Instruction, Option<String>) {
    match (dst, src) {
        (Operand::Register(reg), Operand::Immediate(0)) => {
            register_values.insert(reg.clone(), 0);
            (Instruction::Mov(dst.clone(), Operand::Immediate(0)), Some("Simplified and with zero".to_string()))
        },
        (Operand::Register(reg), Operand::Immediate(imm)) if *imm == u64::MAX => {
            (Instruction::Nop, Some("Removed and with all ones".to_string()))
        },
        _ => (Instruction::And(dst.clone(), src.clone()), None),
    }
}

fn simplify_or(dst: &Operand, src: &Operand, register_values: &mut HashMap<String, i64>) -> (Instruction, Option<String>) {
    match (dst, src) {
        (Operand::Register(reg), Operand::Immediate(0)) => {
            (Instruction::Nop, Some("Removed or with zero".to_string()))
        },
        (Operand::Register(reg), Operand::Immediate(imm)) if *imm == u64::MAX => {
            register_values.insert(reg.clone(), -1);
            (Instruction::Mov(dst.clone(), Operand::Immediate(u64::MAX)), Some("Simplified or with all ones".to_string()))
        },
        _ => (Instruction::Or(dst.clone(), src.clone()), None),
    }
}

fn simplify_xor(dst: &Operand, src: &Operand, register_values: &mut HashMap<String, i64>) -> (Instruction, Option<String>) {
    match (dst, src) {
        (Operand::Register(reg1), Operand::Register(reg2)) if reg1 == reg2 => {
            register_values.insert(reg1.clone(), 0);
            (Instruction::Mov(dst.clone(), Operand::Immediate(0)), Some("Simplified xor to zero".to_string()))
        },
        _ => (Instruction::Xor(dst.clone(), src.clone()), None),
    }
}

fn simplify_shift(dst: &Operand, src: &Operand, op: &str, register_values: &mut HashMap<String, i64>) -> (Instruction, Option<String>) {
    match (dst, src) {
        (Operand::Register(_), Operand::Immediate(0)) => {
            (Instruction::Nop, Some(format!("Removed {} by zero", op)))
        },
        _ => {
            let inst = match op {
                "shl" => Instruction::Shl(dst.clone(), src.clone()),
                "shr" => Instruction::Shr(dst.clone(), src.clone()),
                "sar" => Instruction::Sar(dst.clone(), src.clone()),
                _ => unreachable!(),
            };
            (inst, None)
        },
    }
}

fn simplify_call(op: &Operand) -> (Instruction, Option<String>) {
    if let Operand::Relative(addr) = op {
        (Instruction::Call(op.clone()), Some(format!("Call to 0x{:x}", addr)))
    } else {
        (Instruction::Call(op.clone()), None)
    }
}

fn simplify_push(op: &Operand, next_instructions: &[Instruction]) -> (Instruction, Option<String>) {
    if let Some(Instruction::Pop(pop_op)) = next_instructions.first() {
        if op == pop_op {
            return (Instruction::Nop, Some("Removed push-pop pair".to_string()));
        }
    }
    (Instruction::Push(op.clone()), None)
}
disassembler/flow_analysis.rs:
use crate::instruction::{Instruction, Operand};
use std::collections::HashMap;

pub fn analyze_flow(instructions: &[(u64, Instruction)]) -> HashMap<u64, Vec<u64>> {
    let mut flow_graph = HashMap::new();

    for (i, (address, instruction)) in instructions.iter().enumerate() {
        let next_address = if i + 1 < instructions.len() {
            instructions[i + 1].0
        } else {
            *address + 1 // Assume 1-byte instruction if it's the last one
        };

        let mut targets = Vec::new();

        match instruction {
            Instruction::Jmp(op) => {
                if let Operand::Relative(target) = op {
                    targets.push(*target);
                }
            }
            Instruction::Je(op) | Instruction::Jne(op) | Instruction::Jg(op) |
            Instruction::Jge(op) | Instruction::Jl(op) | Instruction::Jle(op) |
            Instruction::Js(op) | Instruction::Jns(op) | Instruction::Jo(op) |
            Instruction::Jno(op) | Instruction::Jc(op) | Instruction::Jnc(op) |
            Instruction::Jecxz(op) | Instruction::Loop(op) |
            Instruction::Loopne(op) | Instruction::Loope(op) => {
                if let Operand::Relative(target) = op {
                    targets.push(*target);
                }
                // Also add the next instruction as a possible target
                targets.push(next_address);
            }
            Instruction::Call(_) => {
                // Calls do not alter the flow graph directly, but can be used for further analysis
                targets.push(next_address);
            }
            Instruction::Ret => {
                // Return has no targets
            }
            _ => {
                // Regular instruction continues to the next address
                targets.push(next_address);
            }
        }

        flow_graph.insert(*address, targets);
    }

    flow_graph
}
function_analyzer.rs:
use crate::instruction::{Instruction, Operand};
use std::collections::{HashMap, HashSet, VecDeque};

#[derive(Clone, Debug)]
pub struct Function {
    pub start_address: u64,
    pub end_address: u64,
    pub name: String,
    pub is_jump_table: bool,
    pub calls: Vec<u64>,
    pub jumps: Vec<u64>,
    pub references: Vec<u64>,
}

pub fn analyze_functions(instructions: &[(u64, Instruction)]) -> Vec<Function> {
    let mut functions = Vec::new();
    let mut function_starts = HashSet::new();
    let mut jump_targets = HashMap::new();
    let mut call_targets = HashMap::new();
    let mut references = HashMap::new();

    // First pass: Identify function starts and gather information
    for (address, instruction) in instructions {
        match instruction {
            Instruction::Call(Operand::Relative(target)) => {
                function_starts.insert(*target);
                call_targets.entry(*target).or_insert(Vec::new()).push(*address);
            }
            Instruction::Jmp(Operand::Relative(target)) => {
                jump_targets.entry(*target).or_insert(Vec::new()).push(*address);
            }
            Instruction::Je(Operand::Relative(target)) |
            Instruction::Jne(Operand::Relative(target)) |
            Instruction::Jg(Operand::Relative(target)) |
            Instruction::Jge(Operand::Relative(target)) |
            Instruction::Jl(Operand::Relative(target)) |
            Instruction::Jle(Operand::Relative(target)) => {
                references.entry(*target).or_insert(Vec::new()).push(*address);
            }
            _ => {}
        }
    }

    // Second pass: Create and analyze functions
    let mut current_function: Option<Function> = None;
    let mut stack = VecDeque::new();

    for (i, (address, instruction)) in instructions.iter().enumerate() {
        if function_starts.contains(address) || i == 0 {
            if let Some(mut func) = current_function.take() {
                func.end_address = *address - 1;
                functions.push(func);
            }
            let name = format!("sub_{:x}", address);
            current_function = Some(Function {
                start_address: *address,
                end_address: 0,
                name,
                is_jump_table: false,
                calls: Vec::new(),
                jumps: Vec::new(),
                references: references.get(address).cloned().unwrap_or_default(),
            });
            stack.push_back(*address);
        }

        if let Some(ref mut func) = current_function {
            match instruction {
                Instruction::Call(Operand::Relative(target)) => {
                    func.calls.push(*target);
                }
                Instruction::Jmp(Operand::Relative(target)) => {
                    func.jumps.push(*target);
                    if *target < func.start_address || *target > *address {
                        stack.push_back(*target);
                    }
                }
                Instruction::Ret => {
                    if stack.is_empty() {
                        func.end_address = *address;
                        functions.push(func.clone());
                        current_function = None;
                    } else {
                        stack.pop_back();
                    }
                }
                _ => {}
            }
        }

        if current_function.is_none() && !stack.is_empty() {
            let next_address = stack.pop_front().unwrap();
            let name = format!("sub_{:x}", next_address);
            current_function = Some(Function {
                start_address: next_address,
                end_address: 0,
                name,
                is_jump_table: false,
                calls: Vec::new(),
                jumps: Vec::new(),
                references: references.get(&next_address).cloned().unwrap_or_default(),
            });
        }
    }

    if let Some(mut func) = current_function {
        func.end_address = instructions.last().map(|(addr, _)| *addr).unwrap_or(0);
        functions.push(func);
    }

    // Post-processing: Identify jump tables and merge overlapping functions
    functions.sort_by_key(|f| f.start_address);
    let mut merged_functions = Vec::new();
    for func in functions {
        if jump_targets.contains_key(&func.start_address) && func.jumps.len() > 5 {
            let mut merged_func = func.clone();
            merged_func.is_jump_table = true;
            merged_func.name = format!("j_{}", merged_func.name);
            merged_functions.push(merged_func);
        } else if let Some(last) = merged_functions.last_mut() {
            if func.start_address <= last.end_address {
                last.end_address = last.end_address.max(func.end_address);
                last.calls.extend(func.calls);
                last.jumps.extend(func.jumps);
                last.references.extend(func.references);
            } else {
                merged_functions.push(func);
            }
        } else {
            merged_functions.push(func);
        }
    }

    merged_functions
}

disassembler/mod.rs:
pub mod flow_analysis;
pub mod function_analyzer;
pub mod smart_comments;

disassembler/smart_comments.rs:
use crate::instruction::{Instruction, Operand};
use std::collections::HashMap;

pub struct SmartCommenter {
    register_states: HashMap<String, RegisterState>,
}
#[derive(Clone)]
struct RegisterState {
    value: Option<i64>,
    last_operation: Option<String>,
}

impl SmartCommenter {
    pub fn new() -> Self {
        SmartCommenter {
            register_states: HashMap::new(),
        }
    }

    pub fn add_smart_comment(&mut self, instruction: &Instruction, address: u64) -> Option<String> {
        match instruction {
            Instruction::Mov(dst, src) => self.handle_mov(dst, src),
            Instruction::Xor(op1, op2) => self.handle_xor(op1, op2),
            Instruction::Push(op) => self.handle_push(op),
            Instruction::Pop(op) => self.handle_pop(op),
            Instruction::Call(op) => self.handle_call(op, address),
            Instruction::Ret => Some("Return from function".to_string()),
            Instruction::Add(dst, src) => self.handle_add(dst, src),
            Instruction::Sub(dst, src) => self.handle_sub(dst, src),
            Instruction::And(dst, src) => self.handle_and(dst, src),
            Instruction::Or(dst, src) => self.handle_or(dst, src),
            Instruction::Shl(dst, src) => self.handle_shift(dst, src, "left"),
            Instruction::Shr(dst, src) => self.handle_shift(dst, src, "right"),
            Instruction::Cmp(op1, op2) => self.handle_cmp(op1, op2),
            Instruction::Test(op1, op2) => self.handle_test(op1, op2),
            Instruction::Je(op) => Some("Jump if equal".to_string()),
            Instruction::Jne(op) => Some("Jump if not equal".to_string()),
            Instruction::Jg(op) => Some("Jump if greater".to_string()),
            Instruction::Jge(op) => Some("Jump if greater or equal".to_string()),
            Instruction::Jl(op) => Some("Jump if less".to_string()),
            Instruction::Jle(op) => Some("Jump if less or equal".to_string()),
            Instruction::Mul(op) => Some(format!("Unsigned multiply {:?}", op)),
            Instruction::IMul(dst, src) => Some(format!("Signed multiply {:?} by {:?}", dst, src)),
            _ => None,
        }
    }

    fn handle_mov(&mut self, dst: &Operand, src: &Operand) -> Option<String> {
        match (dst, src) {
            (Operand::Register(reg), Operand::Immediate(imm)) => {
                self.register_states.insert(reg.clone(), RegisterState {
                    value: Some((*imm).try_into().unwrap()),
                    last_operation: Some("mov".to_string()),
                });
                Some(format!("Initialize {} with {:#x}", reg, imm))
            }
            (Operand::Register(reg), Operand::Register(src_reg)) => {
                if let Some(src_state) = self.register_states.get(src_reg) {
                    self.register_states.insert(reg.clone(), src_state.clone());
                    Some(format!("Copy value from {} to {}", src_reg, reg))
                } else {
                    Some("Register to register move".to_string())
                }
            }
            _ => Some("Data movement".to_string()),
        }
    }

    fn handle_xor(&mut self, op1: &Operand, op2: &Operand) -> Option<String> {
        if op1 == op2 {
            if let Operand::Register(reg) = op1 {
                self.register_states.insert(reg.clone(), RegisterState {
                    value: Some(0),
                    last_operation: Some("xor".to_string()),
                });
                Some(format!("Clear {} (set to 0)", reg))
            } else {
                Some("Clear operand (set to 0)".to_string())
            }
        } else {
            Some("Bitwise XOR operation".to_string())
        }
    }

    fn handle_push(&self, op: &Operand) -> Option<String> {
        match op {
            Operand::Register(reg) => Some(format!("Push {} onto stack", reg)),
            Operand::Immediate(imm) => Some(format!("Push {:#x} onto stack", imm)),
            _ => Some("Push value onto stack".to_string()),
        }
    }

    fn handle_pop(&mut self, op: &Operand) -> Option<String> {
        if let Operand::Register(reg) = op {
            self.register_states.remove(reg);
            Some(format!("Pop value from stack into {}", reg))
        } else {
            Some("Pop value from stack".to_string())
        }
    }

    fn handle_call(&self, op: &Operand, address: u64) -> Option<String> {
        match op {
            Operand::Relative(target) => Some(format!("Call function at {:#x}", target)),
            Operand::Register(reg) => Some(format!("Call function pointer in {}", reg)),
            _ => Some("Function call".to_string()),
        }
    }

    fn handle_add(&mut self, dst: &Operand, src: &Operand) -> Option<String> {
        match (dst, src) {
            (Operand::Register(reg), Operand::Immediate(imm)) => {
                if let Some(state) = self.register_states.get_mut(reg) {
                    if let Some(value) = state.value {
                        state.value = Some(value.wrapping_add((*imm).try_into().unwrap()));
                        state.last_operation = Some("add".to_string());
                        return Some(format!("Increment {} by {:#x}", reg, imm));
                    }
                }
                Some(format!("Add {:#x} to {}", imm, reg))
            }
            _ => Some("Addition operation".to_string()),
        }
    }

    fn handle_sub(&mut self, dst: &Operand, src: &Operand) -> Option<String> {
        match (dst, src) {
            (Operand::Register(reg), Operand::Immediate(imm)) => {
                if let Some(state) = self.register_states.get_mut(reg) {
                    if let Some(value) = state.value {
                        state.value = Some(value.wrapping_sub((*imm).try_into().unwrap()));
                        state.last_operation = Some("sub".to_string());
                        return Some(format!("Decrement {} by {:#x}", reg, imm));
                    }
                }
                Some(format!("Subtract {:#x} from {}", imm, reg))
            }
            _ => Some("Subtraction operation".to_string()),
        }
    }

    fn handle_and(&self, dst: &Operand, src: &Operand) -> Option<String> {
        match (dst, src) {
            (_, Operand::Immediate(imm)) => Some(format!("Bitwise AND with {:#x}", imm)),
            _ => Some("Bitwise AND operation".to_string()),
        }
    }

    fn handle_or(&self, dst: &Operand, src: &Operand) -> Option<String> {
        match (dst, src) {
            (_, Operand::Immediate(imm)) => Some(format!("Bitwise OR with {:#x}", imm)),
            _ => Some("Bitwise OR operation".to_string()),
        }
    }

    fn handle_shift(&self, dst: &Operand, src: &Operand, direction: &str) -> Option<String> {
        match src {
            Operand::Immediate(imm) => Some(format!("Shift {:?} {} by {} bits", dst, direction, imm)),
            _ => Some(format!("Shift {:?} {}", dst, direction)),
        }
    }

    fn handle_cmp(&self, op1: &Operand, op2: &Operand) -> Option<String> {
        match (op1, op2) {
            (Operand::Register(reg), Operand::Immediate(0)) => {
                Some(format!("Check if {} is zero", reg))
            }
            (Operand::Register(reg), Operand::Immediate(imm)) => {
                Some(format!("Compare {} with {:#x}", reg, imm))
            }
            _ => Some("Compare operands".to_string()),
        }
    }

    fn handle_test(&self, op1: &Operand, op2: &Operand) -> Option<String> {
        if op1 == op2 {
            if let Operand::Register(reg) = op1 {
                Some(format!("Check if {} is zero", reg))
            } else {
                Some("Check if operand is zero".to_string())
            }
        } else {
            Some("Bitwise AND test".to_string())
        }
    }
}