pub fn idiv(&self, control_flow_graph: &mut ControlFlowGraph) -> Result<()> {
        let detail = self.details()?;

        let block_index = {
            let block = control_flow_graph.new_block()?;

            let divisor = self.operand_load(block, &detail.operands[0])?;
            let divisor = Expr::zext(divisor.bits() * 2, divisor)?;

            let dividend: Expr = match divisor.bits() {
                16 => self.get_register(x86_reg::X86_REG_AX)?.get()?,
                32 => {
                    let expr_dx = Expr::zext(32, self.get_register(x86_reg::X86_REG_DX)?.get()?)?;
                    let expr_dx = Expr::shl(expr_dx, expr_const(16, 32))?;
                    Expr::or(
                        expr_dx,
                        Expr::zext(32, self.get_register(x86_reg::X86_REG_AX)?.get()?)?,
                    )?
                }
                64 => {
                    let expr_edx = Expr::zext(64, self.get_register(x86_reg::X86_REG_EDX)?.get()?)?;
                    let expr_edx = Expr::shl(expr_edx, expr_const(32, 64))?;
                    Expr::or(
                        expr_edx,
                        Expr::zext(64, self.get_register(x86_reg::X86_REG_EAX)?.get()?)?,
                    )?
                }
                128 => {
                    let expr_edx =
                        Expr::zext(128, self.get_register(x86_reg::X86_REG_RDX)?.get()?)?;
                    let expr_edx = Expr::shl(expr_edx, expr_const(64, 128))?;
                    Expr::or(
                        expr_edx,
                        Expr::zext(128, self.get_register(x86_reg::X86_REG_EAX)?.get()?)?,
                    )?
                }
                _ => return Err("invalid bit-width in x86 div".into()),
            };

            let quotient = self.temp(0, divisor.bits());
            let remainder = self.temp(1, divisor.bits());

            block.assign(
                quotient.clone(),
                Expr::divs(dividend.clone(), divisor.clone())?,
            );
            block.assign(remainder.clone(), Expr::mods(dividend, divisor.clone())?);

            match divisor.bits() {
                16 => {
                    let al = self.get_register(x86_reg::X86_REG_AL)?;
                    let ah = self.get_register(x86_reg::X86_REG_AH)?;
                    al.set(block, Expr::trun(8, quotient.into())?)?;
                    ah.set(block, Expr::trun(8, remainder.into())?)?;
                }
                32 => {
                    let ax = self.get_register(x86_reg::X86_REG_AX)?;
                    let dx = self.get_register(x86_reg::X86_REG_DX)?;
                    ax.set(block, Expr::trun(16, quotient.into())?)?;
                    dx.set(block, Expr::trun(16, remainder.into())?)?;
                }
                64 => {
                    let eax = self.get_register(x86_reg::X86_REG_EAX)?;
                    let edx = self.get_register(x86_reg::X86_REG_EDX)?;
                    eax.set(block, Expr::trun(32, quotient.into())?)?;
                    edx.set(block, Expr::trun(32, remainder.into())?)?;
                }
                128 => {
                    let rax = self.get_register(x86_reg::X86_REG_RAX)?;
                    let rdx = self.get_register(x86_reg::X86_REG_RDX)?;
                    rax.set(block, Expr::trun(32, quotient.into())?)?;
                    rdx.set(block, Expr::trun(32, remainder.into())?)?;
                }
                _ => return Err("invalid bit-width in x86 div".into()),
            }

            block.index()
        };

        control_flow_graph.set_entry(block_index)?;
        control_flow_graph.set_exit(block_index)?;

        Ok(())
    }
// This is essentially the exact same as div with the signs of the arith ops
// reversed.
This is essentially the exact same as div with the signs of the arith ops
reversed.
This is essentially the exact same as div with the signs of the arith ops reversed .
pub fn idiv(&self, control_flow_graph: &mut ControlFlowGraph) -> Result<()> {
        let detail = self.details()?;
        let block_index = {
            let block = control_flow_graph.new_block()?;
            let divisor = self.operand_load(block, &detail.operands[0])?;
            let divisor = Expr::zext(divisor.bits() * 2, divisor)?;
            let dividend: Expr = match divisor.bits() {
                16 => self.get_register(x86_reg::X86_REG_AX)?.get()?,
                32 => {
                    let expr_dx = Expr::zext(32, self.get_register(x86_reg::X86_REG_DX)?.get()?)?;
                    let expr_dx = Expr::shl(expr_dx, expr_const(16, 32))?;
                    Expr::or(
                        expr_dx,
                        Expr::zext(32, self.get_register(x86_reg::X86_REG_AX)?.get()?)?,
                    )?
                }
                64 => {
                    let expr_edx = Expr::zext(64, self.get_register(x86_reg::X86_REG_EDX)?.get()?)?;
                    let expr_edx = Expr::shl(expr_edx, expr_const(32, 64))?;
                    Expr::or(
                        expr_edx,
                        Expr::zext(64, self.get_register(x86_reg::X86_REG_EAX)?.get()?)?,
                    )?
                }
                128 => {
                    let expr_edx =
                        Expr::zext(128, self.get_register(x86_reg::X86_REG_RDX)?.get()?)?;
                    let expr_edx = Expr::shl(expr_edx, expr_const(64, 128))?;
                    Expr::or(
                        expr_edx,
                        Expr::zext(128, self.get_register(x86_reg::X86_REG_EAX)?.get()?)?,
                    )?
                }
                _ => return Err("invalid bit-width in x86 div".into()),
            };
            let quotient = self.temp(0, divisor.bits());
            let remainder = self.temp(1, divisor.bits());
            block.assign(
                quotient.clone(),
                Expr::divs(dividend.clone(), divisor.clone())?,
            );
            block.assign(remainder.clone(), Expr::mods(dividend, divisor.clone())?);
            match divisor.bits() {
                16 => {
                    let al = self.get_register(x86_reg::X86_REG_AL)?;
                    let ah = self.get_register(x86_reg::X86_REG_AH)?;
                    al.set(block, Expr::trun(8, quotient.into())?)?;
                    ah.set(block, Expr::trun(8, remainder.into())?)?;
                }
                32 => {
                    let ax = self.get_register(x86_reg::X86_REG_AX)?;
                    let dx = self.get_register(x86_reg::X86_REG_DX)?;
                    ax.set(block, Expr::trun(16, quotient.into())?)?;
                    dx.set(block, Expr::trun(16, remainder.into())?)?;
                }
                64 => {
                    let eax = self.get_register(x86_reg::X86_REG_EAX)?;
                    let edx = self.get_register(x86_reg::X86_REG_EDX)?;
                    eax.set(block, Expr::trun(32, quotient.into())?)?;
                    edx.set(block, Expr::trun(32, remainder.into())?)?;
                }
                128 => {
                    let rax = self.get_register(x86_reg::X86_REG_RAX)?;
                    let rdx = self.get_register(x86_reg::X86_REG_RDX)?;
                    rax.set(block, Expr::trun(32, quotient.into())?)?;
                    rdx.set(block, Expr::trun(32, remainder.into())?)?;
                }
                _ => return Err("invalid bit-width in x86 div".into()),
            }
            block.index()
        };
        control_flow_graph.set_entry(block_index)?;
        control_flow_graph.set_exit(block_index)?;
        Ok(())
    }
pub fn idiv ( & self , control_flow_graph : & mut ControlFlowGraph ) -> Result < ( ) > { let detail = self . details ( ) ? ; let block_index = { let block = control_flow_graph . new_block ( ) ? ; let divisor = self . operand_load ( block , & detail . operands [ 0 ] ) ? ; let divisor = Expr :: zext ( divisor . bits ( ) * 2 , divisor ) ? ; let dividend : Expr = match divisor . bits ( ) { 16 => self . get_register ( x86_reg :: X86_REG_AX ) ? . get ( ) ? , 32 => { let expr_dx = Expr :: zext ( 32 , self . get_register ( x86_reg :: X86_REG_DX ) ? . get ( ) ? ) ? ; let expr_dx = Expr :: shl ( expr_dx , expr_const ( 16 , 32 ) ) ? ; Expr :: or ( expr_dx , Expr :: zext ( 32 , self . get_register ( x86_reg :: X86_REG_AX ) ? . get ( ) ? ) ? , ) ? } 64 => { let expr_edx = Expr :: zext ( 64 , self . get_register ( x86_reg :: X86_REG_EDX ) ? . get ( ) ? ) ? ; let expr_edx = Expr :: shl ( expr_edx , expr_const ( 32 , 64 ) ) ? ; Expr :: or ( expr_edx , Expr :: zext ( 64 , self . get_register ( x86_reg :: X86_REG_EAX ) ? . get ( ) ? ) ? , ) ? } 128 => { let expr_edx = Expr :: zext ( 128 , self . get_register ( x86_reg :: X86_REG_RDX ) ? . get ( ) ? ) ? ; let expr_edx = Expr :: shl ( expr_edx , expr_const ( 64 , 128 ) ) ? ; Expr :: or ( expr_edx , Expr :: zext ( 128 , self . get_register ( x86_reg :: X86_REG_EAX ) ? . get ( ) ? ) ? , ) ? } _ => return Err ( " " . into ( ) ) , } ; let quotient = self . temp ( 0 , divisor . bits ( ) ) ; let remainder = self . temp ( 1 , divisor . bits ( ) ) ; block . assign ( quotient . clone ( ) , Expr :: divs ( dividend . clone ( ) , divisor . clone ( ) ) ? , ) ; block . assign ( remainder . clone ( ) , Expr :: mods ( dividend , divisor . clone ( ) ) ? ) ; match divisor . bits ( ) { 16 => { let al = self . get_register ( x86_reg :: X86_REG_AL ) ? ; let ah = self . get_register ( x86_reg :: X86_REG_AH ) ? ; al . set ( block , Expr :: trun ( 8 , quotient . into ( ) ) ? ) ? ; ah . set ( block , Expr :: trun ( 8 , remainder . into ( ) ) ? ) ? ; } 32 => { let ax = self . get_register ( x86_reg :: X86_REG_AX ) ? ; let dx = self . get_register ( x86_reg :: X86_REG_DX ) ? ; ax . set ( block , Expr :: trun ( 16 , quotient . into ( ) ) ? ) ? ; dx . set ( block , Expr :: trun ( 16 , remainder . into ( ) ) ? ) ? ; } 64 => { let eax = self . get_register ( x86_reg :: X86_REG_EAX ) ? ; let edx = self . get_register ( x86_reg :: X86_REG_EDX ) ? ; eax . set ( block , Expr :: trun ( 32 , quotient . into ( ) ) ? ) ? ; edx . set ( block , Expr :: trun ( 32 , remainder . into ( ) ) ? ) ? ; } 128 => { let rax = self . get_register ( x86_reg :: X86_REG_RAX ) ? ; let rdx = self . get_register ( x86_reg :: X86_REG_RDX ) ? ; rax . set ( block , Expr :: trun ( 32 , quotient . into ( ) ) ? ) ? ; rdx . set ( block , Expr :: trun ( 32 , remainder . into ( ) ) ? ) ? ; } _ => return Err ( " " . into ( ) ) , } block . index ( ) } ; control_flow_graph . set_entry ( block_index ) ? ; control_flow_graph . set_exit ( block_index ) ? ; Ok ( ( ) ) }
This is essentially the exact same as div with the signs of the arith ops
reversed.
This is essentially the exact same as div with the signs of the arith ops reversed .
&self
control_flow_graph
&mut ControlFlowGraph
&self
control_flow_graph
&mut ControlFlowGraph