Provide a more advanced version of this code. Provide the full thing. Go beyond.
use std::fmt;

#[derive(Debug)]
pub enum Operand {
    Register(String),
    Immediate(i64),
    Memory(String),
}

#[derive(Debug)]
pub enum Instruction {
    Mov(Operand, Operand),
    Push(Operand),
    Pop(Operand),
    Call(Operand),
    Ret,
    Add(Operand, Operand),
    Sub(Operand, Operand),
    Xor(Operand, Operand),
    And(Operand, Operand),
    Or(Operand, Operand),
    Shl(Operand, Operand),
    Shr(Operand, Operand),
    Lea(Operand, Operand),
    Cmp(Operand, Operand),
    Test(Operand, Operand),
    Inc(Operand),
    Dec(Operand),
    Jmp(Operand),
    Je(Operand),
    Jne(Operand),
    Jg(Operand),
    Jge(Operand),
    Jl(Operand),
    Jle(Operand),
    Nop,
    Syscall,
    Cdq,
    Imul(Operand, Operand),
    Idiv(Operand),
    Mul(Operand),
    Div(Operand),
    Neg(Operand),
    Not(Operand),
    Movzx(Operand, Operand),
    Movsx(Operand, Operand),
    Shrd(Operand, Operand, Operand),
    ShrdImm(Operand, Operand, i8),
    Adc(Operand, Operand),
    Sbb(Operand, Operand),
    Sar(Operand, Operand),
    Unknown(Vec<u8>),
}

struct Decoder {
    bytes: Vec<u8>,
    offset: usize,
    rex: Option<u8>,
}

impl Decoder {
    fn new(bytes: Vec<u8>) -> Self {
        Self {
            bytes,
            offset: 0,
            rex: None,
        }
    }

    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
        }
    }

    fn peek_byte(&self) -> Option<u8> {
        self.bytes.get(self.offset).copied()
    }

    fn decode_prefix(&mut self) {
        while let Some(byte) = self.peek_byte() {
            match byte {
                0x66 | 0x67 | 0xf0 | 0xf2 | 0xf3 => {
                    self.next_byte();
                }
                0x40..=0x4f => {
                    self.rex = self.next_byte();
                }
                _ => break,
            }
        }
    }

    fn decode_modrm(&mut self) -> Option<(u8, u8, u8)> {
        self.next_byte().map(|modrm| {
            let mode = (modrm >> 6) & 0b11;
            let reg = (modrm >> 3) & 0b111;
            let rm = modrm & 0b111;
            (mode, reg, rm)
        })
    }

    fn decode_sib(&mut self) -> Option<(u8, u8, u8)> {
        self.next_byte().map(|sib| {
            let scale = (sib >> 6) & 0b11;
            let index = (sib >> 3) & 0b111;
            let base = sib & 0b111;
            (scale, index, base)
        })
    }

    fn decode_displacement(&mut self, mode: u8) -> Option<i32> {
        match mode {
            0b00 => Some(0),
            0b01 => self.next_byte().map(|b| b as i8 as i32),
            0b10 => {
                let b1 = self.next_byte()? as u32;
                let b2 = self.next_byte()? as u32;
                let b3 = self.next_byte()? as u32;
                let b4 = self.next_byte()? as u32;
                Some((b1 | (b2 << 8) | (b3 << 16) | (b4 << 24)) as i32)
            }
            _ => None,
        }
    }

    fn decode_immediate(&mut self, size: usize) -> Option<i64> {
        let mut value = 0i64;
        for i in 0..size {
            if let Some(byte) = self.next_byte() {
                value |= (byte as i64) << (i * 8);
            } else {
                return None;
            }
        }
        Some(value)
    }

    fn decode_operand(&mut self, mode: u8, reg: u8, rm: u8) -> Option<Operand> {
        match mode {
            0b11 => Some(Operand::Register(register_name(rm, self.rex))),
            _ => {
                let base = register_name(rm, self.rex);
                let displacement = self.decode_displacement(mode)?;
                if rm == 0b100 {
                    let (scale, index, base) = self.decode_sib()?;
                    let index_reg = if index != 0b100 {
                        register_name(index, self.rex)
                    } else {
                        "".to_string()
                    };
                    let base_reg = register_name(base, self.rex);
                    Some(Operand::Memory(format!(
                        "[{} + {} * {} + {}]",
                        base_reg,
                        index_reg,
                        1 << scale,
                        displacement
                    )))
                } else {
                    Some(Operand::Memory(format!("[{} + {}]", base, displacement)))
                }
            }
        }
    }
}

impl Instruction {
    pub fn decode(bytes: &[u8], rip: u64) -> Result<(Self, usize), &'static str> {
        let mut decoder = Decoder::new(bytes.to_vec());
        decoder.decode_prefix();

        let opcode = decoder.next_byte().ok_or("Unexpected end of input")?;

        match opcode {
            0x50..=0x57 => {
                let reg = register_name(opcode - 0x50, decoder.rex);
                Ok((
                    Instruction::Push(Operand::Register(reg)),
                    decoder.offset,
                ))
            }
            0x58..=0x5f => {
                let reg = register_name(opcode - 0x58, decoder.rex);
                Ok((
                    Instruction::Pop(Operand::Register(reg)),
                    decoder.offset,
                ))
            }
            0x89 | 0x8b => {
                let (mode, reg, rm) = decoder
                    .decode_modrm()
                    .ok_or("Failed to decode ModR/M")?;
                let src = Operand::Register(register_name(reg, decoder.rex));
                let dst = decoder
                    .decode_operand(mode, reg, rm)
                    .ok_or("Failed to decode operand")?;
                let instruction = if opcode == 0x89 {
                    Instruction::Mov(dst, src)
                } else {
                    Instruction::Mov(src, dst)
                };
                Ok((instruction, decoder.offset))
            }
            0xe8 => {
                let offset = decoder
                    .decode_immediate(4)
                    .ok_or("Failed to decode immediate")? as i32;
                let target = (rip as i64 + offset as i64 + decoder.offset as i64) as u64;
                Ok((
                    Instruction::Call(Operand::Immediate(target as i64)),
                    decoder.offset,
                ))
            }
            0xc3 => Ok((Instruction::Ret, decoder.offset)),
            0x01 | 0x29 | 0x31 | 0x21 | 0x09 => {
                let (mode, reg, rm) = decoder
                    .decode_modrm()
                    .ok_or("Failed to decode ModR/M")?;
                let src = Operand::Register(register_name(reg, decoder.rex));
                let dst = decoder
                    .decode_operand(mode, reg, rm)
                    .ok_or("Failed to decode operand")?;
                let instruction = match opcode {
                    0x01 => Instruction::Add(dst, src),
                    0x29 => Instruction::Sub(dst, src),
                    0x31 => Instruction::Xor(dst, src),
                    0x21 => Instruction::And(dst, src),
                    0x09 => Instruction::Or(dst, src),
                    _ => unreachable!(),
                };
                Ok((instruction, decoder.offset))
            }
            0x81 => {
                let (mode, reg, rm) = decoder
                    .decode_modrm()
                    .ok_or("Failed to decode ModR/M")?;
                let imm = decoder
                    .decode_immediate(4)
                    .ok_or("Failed to decode immediate")? as i32;
                let dst = decoder
                    .decode_operand(mode, reg, rm)
                    .ok_or("Failed to decode operand")?;
                let instruction = match reg {
                    0 => Instruction::Add(dst, Operand::Immediate(imm as i64)),
                    1 => Instruction::Or(dst, Operand::Immediate(imm as i64)),
                    2 => Instruction::Adc(dst, Operand::Immediate(imm as i64)),
                    3 => Instruction::Sbb(dst, Operand::Immediate(imm as i64)),
                    4 => Instruction::And(dst, Operand::Immediate(imm as i64)),
                    5 => Instruction::Sub(dst, Operand::Immediate(imm as i64)),
                    6 => Instruction::Xor(dst, Operand::Immediate(imm as i64)),
                    7 => Instruction::Cmp(dst, Operand::Immediate(imm as i64)),
                    _ => Instruction::Unknown(bytes[..decoder.offset].to_vec()),
                };
                Ok((instruction, decoder.offset))
            }
            0x83 => {
                let (mode, reg, rm) = decoder
                    .decode_modrm()
                    .ok_or("Failed to decode ModR/M")?;
                let imm = decoder
                    .decode_immediate(1)
                    .ok_or("Failed to decode immediate")? as i8 as i32;
                let dst = decoder
                    .decode_operand(mode, reg, rm)
                    .ok_or("Failed to decode operand")?;
                let instruction = match reg {
                    0 => Instruction::Add(dst, Operand::Immediate(imm as i64)),
                    1 => Instruction::Or(dst, Operand::Immediate(imm as i64)),
                    2 => Instruction::Adc(dst, Operand::Immediate(imm as i64)),
                    3 => Instruction::Sbb(dst, Operand::Immediate(imm as i64)),
                    4 => Instruction::And(dst, Operand::Immediate(imm as i64)),
                    5 => Instruction::Sub(dst, Operand::Immediate(imm as i64)),
                    6 => Instruction::Xor(dst, Operand::Immediate(imm as i64)),
                    7 => Instruction::Cmp(dst, Operand::Immediate(imm as i64)),
                    _ => Instruction::Unknown(bytes[..decoder.offset].to_vec()),
                };
                Ok((instruction, decoder.offset))
            }
            0x0f => {
                let extended_opcode = decoder.next_byte().ok_or("Unexpected end of input")?;
                match extended_opcode {
                    0x84 | 0x85 | 0x8f | 0x8d | 0x8c | 0x8e => {
                        let offset = decoder
                            .decode_immediate(4)
                            .ok_or("Failed to decode immediate")? as i32;
                        let target = (rip as i64 + offset as i64 + decoder.offset as i64) as u64;
                        let instruction = match extended_opcode {
                            0x84 => Instruction::Je(Operand::Immediate(target as i64)),
                            0x85 => Instruction::Jne(Operand::Immediate(target as i64)),
                            0x8f => Instruction::Jg(Operand::Immediate(target as i64)),
                            0x8d => Instruction::Jge(Operand::Immediate(target as i64)),
                            0x8c => Instruction::Jl(Operand::Immediate(target as i64)),
                            0x8e => Instruction::Jle(Operand::Immediate(target as i64)),
                            _ => unreachable!(),
                        };
                        Ok((instruction, decoder.offset))
                    }
                    0xaf => {
                        let (mode, reg, rm) = decoder
                            .decode_modrm()
                            .ok_or("Failed to decode ModR/M")?;
                        let dst = Operand::Register(register_name(reg, decoder.rex));
                        let src = decoder
                            .decode_operand(mode, reg, rm)
                            .ok_or("Failed to decode operand")?;
                        Ok((Instruction::Imul(dst, src), decoder.offset))
                    }
                    0x0e => {
                        // Example for additional extended opcodes
                        // Implement as needed
                        Ok((Instruction::Unknown(vec![0x0f, extended_opcode]), decoder.offset))
                    }
                    _ => Ok((
                        Instruction::Unknown(bytes[..decoder.offset].to_vec()),
                        decoder.offset,
                    )),
                }
            }
            0x90 => Ok((Instruction::Nop, decoder.offset)),
            0x99 => Ok((Instruction::Cdq, decoder.offset)),
            0xf7 => {
                let (mode, reg, rm) = decoder
                    .decode_modrm()
                    .ok_or("Failed to decode ModR/M")?;
                let operand = decoder
                    .decode_operand(mode, reg, rm)
                    .ok_or("Failed to decode operand")?;
                let instruction = match reg {
                    2 => Instruction::Not(operand),
                    3 => Instruction::Neg(operand),
                    4 => Instruction::Mul(operand),
                    5 => Instruction::Imul(Operand::Register("rax".to_string()), operand),
                    6 => Instruction::Div(operand),
                    7 => Instruction::Idiv(operand),
                    _ => Instruction::Unknown(bytes[..decoder.offset].to_vec()),
                };
                Ok((instruction, decoder.offset))
            }
            0xff => {
                let (mode, reg, rm) = decoder
                    .decode_modrm()
                    .ok_or("Failed to decode ModR/M")?;
                let operand = decoder
                    .decode_operand(mode, reg, rm)
                    .ok_or("Failed to decode operand")?;
                let instruction = match reg {
                    0 => Instruction::Inc(operand),
                    1 => Instruction::Dec(operand),
                    2 | 3 => Instruction::Call(operand),
                    4 | 5 => Instruction::Jmp(operand),
                    _ => Instruction::Unknown(bytes[..decoder.offset].to_vec()),
                };
                Ok((instruction, decoder.offset))
            }
            0x8d => {
                let (mode, reg, rm) = decoder
                    .decode_modrm()
                    .ok_or("Failed to decode ModR/M")?;
                let dst = Operand::Register(register_name(reg, decoder.rex));
                let src = decoder
                    .decode_operand(mode, reg, rm)
                    .ok_or("Failed to decode operand")?;
                Ok((Instruction::Lea(dst, src), decoder.offset))
            }
            0x39 | 0x3b => {
                let (mode, reg, rm) = decoder
                    .decode_modrm()
                    .ok_or("Failed to decode ModR/M")?;
                let src = Operand::Register(register_name(reg, decoder.rex));
                let dst = decoder
                    .decode_operand(mode, reg, rm)
                    .ok_or("Failed to decode operand")?;
                let instruction = if opcode == 0x39 {
                    Instruction::Cmp(dst, src)
                } else {
                    Instruction::Cmp(src, dst)
                };
                Ok((instruction, decoder.offset))
            }
            0x85 => {
                let (mode, reg, rm) = decoder
                    .decode_modrm()
                    .ok_or("Failed to decode ModR/M")?;
                let src = Operand::Register(register_name(reg, decoder.rex));
                let dst = decoder
                    .decode_operand(mode, reg, rm)
                    .ok_or("Failed to decode operand")?;
                Ok((Instruction::Test(dst, src), decoder.offset))
            }
            0xc1 => {
                let (mode, reg, rm) = decoder
                    .decode_modrm()
                    .ok_or("Failed to decode ModR/M")?;
                let dst = decoder
                    .decode_operand(mode, reg, rm)
                    .ok_or("Failed to decode operand")?;
                let imm = decoder
                    .decode_immediate(1)
                    .ok_or("Failed to decode immediate")? as i8;
                let instruction = match reg {
                    4 => Instruction::Shl(dst, Operand::Immediate(imm as i64)),
                    5 => Instruction::Shr(dst, Operand::Immediate(imm as i64)),
                    7 => Instruction::Sar(dst, Operand::Immediate(imm as i64)),
                    _ => Instruction::Unknown(bytes[..decoder.offset].to_vec()),
                };
                Ok((instruction, decoder.offset))
            }
            0xba => {
                // Example: MOV edx, imm32
                let imm = decoder
                    .decode_immediate(4)
                    .ok_or("Failed to decode immediate")?;
                Ok((
                    Instruction::Mov(
                        Operand::Register("edx".to_string()),
                        Operand::Immediate(imm),
                    ),
                    decoder.offset,
                ))
            }
            // Add more opcodes and their handling as needed
            _ => Ok((
                Instruction::Unknown(bytes[..decoder.offset].to_vec()),
                decoder.offset,
            )),
        }
    }
}

fn register_name(index: u8, rex: Option<u8>) -> String {
    let extended = rex.map_or(false, |r| r & 0b0100 != 0);
    match (index, extended) {
        (0, false) => "rax".to_string(),
        (1, false) => "rcx".to_string(),
        (2, false) => "rdx".to_string(),
        (3, false) => "rbx".to_string(),
        (4, false) => "rsp".to_string(),
        (5, false) => "rbp".to_string(),
        (6, false) => "rsi".to_string(),
        (7, false) => "rdi".to_string(),
        (0, true) => "r8".to_string(),
        (1, true) => "r9".to_string(),
        (2, true) => "r10".to_string(),
        (3, true) => "r11".to_string(),
        (4, true) => "r12".to_string(),
        (5, true) => "r13".to_string(),
        (6, true) => "r14".to_string(),
        (7, true) => "r15".to_string(),
        _ => unreachable!(),
    }
}

impl fmt::Display for Instruction {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Instruction::Mov(dst, src) => write!(f, "mov {}, {}", dst, src),
            Instruction::Push(op) => write!(f, "push {}", op),
            Instruction::Pop(op) => write!(f, "pop {}", op),
            Instruction::Call(op) => write!(f, "call {}", op),
            Instruction::Ret => write!(f, "ret"),
            Instruction::Add(dst, src) => write!(f, "add {}, {}", dst, src),
            Instruction::Sub(dst, src) => write!(f, "sub {}, {}", dst, src),
            Instruction::Xor(dst, src) => write!(f, "xor {}, {}", dst, src),
            Instruction::And(dst, src) => write!(f, "and {}, {}", dst, src),
            Instruction::Or(dst, src) => write!(f, "or {}, {}", dst, src),
            Instruction::Shl(dst, src) => write!(f, "shl {}, {}", dst, src),
            Instruction::Shr(dst, src) => write!(f, "shr {}, {}", dst, src),
            Instruction::Lea(dst, src) => write!(f, "lea {}, {}", dst, src),
            Instruction::Cmp(dst, src) => write!(f, "cmp {}, {}", dst, src),
            Instruction::Test(dst, src) => write!(f, "test {}, {}", dst, src),
            Instruction::Inc(op) => write!(f, "inc {}", op),
            Instruction::Dec(op) => write!(f, "dec {}", 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::Jl(op) => write!(f, "jl {}", op),
            Instruction::Jle(op) => write!(f, "jle {}", op),
            Instruction::Nop => write!(f, "nop"),
            Instruction::Syscall => write!(f, "syscall"),
            Instruction::Cdq => write!(f, "cdq"),
            Instruction::Imul(dst, src) => write!(f, "imul {}, {}", dst, src),
            Instruction::Idiv(op) => write!(f, "idiv {}", op),
            Instruction::Mul(op) => write!(f, "mul {}", op),
            Instruction::Div(op) => write!(f, "div {}", op),
            Instruction::Neg(op) => write!(f, "neg {}", op),
            Instruction::Not(op) => write!(f, "not {}", op),
            Instruction::Movzx(dst, src) => write!(f, "movzx {}, {}", dst, src),
            Instruction::Movsx(dst, src) => write!(f, "movsx {}, {}", dst, src),
            Instruction::Shrd(dst, src, count) => {
                write!(f, "shrd {}, {}, {}", dst, src, count)
            }
            Instruction::ShrdImm(dst, src, imm) => {
                write!(f, "shrd {}, {}, {}", dst, src, imm)
            }
            Instruction::Adc(dst, src) => write!(f, "adc {}, {}", dst, src),
            Instruction::Sbb(dst, src) => write!(f, "sbb {}, {}", dst, src),
            Instruction::Sar(dst, src) => write!(f, "sar {}, {}", dst, src),
            Instruction::Unknown(bytes) => write!(
                f,
                "db {}",
                bytes
                    .iter()
                    .map(|b| format!("{:02x}", b))
                    .collect::<Vec<_>>()
                    .join(" ")
            ),
        }
    }
}

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, "{:#x}", imm),
            Operand::Memory(mem) => write!(f, "{}", mem),
        }
    }
}