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

        // create our head block
        let (head_index, rhs, counter) = {
            let (head_index, rhs) = {
                let head_block = control_flow_graph.new_block()?;

                // get started
                let rhs = self.operand_load(head_block, &detail.operands[1])?;

                (head_block.index(), rhs)
            };

            let counter = { control_flow_graph.temp(rhs.bits()) };

            let head_block = control_flow_graph.block_mut(head_index)?;

            // This is the loop preamble, and we'll always execute it
            head_block.assign(scalar("ZF", 1), expr_const(0, 1));
            head_block.assign(counter.clone(), expr_const(0, rhs.bits()));

            (head_index, rhs, counter)
        };

        // if rhs == 0 then ZF = 1 and we are done.
        let zero_index = {
            let zero_block = control_flow_graph.new_block()?;
            zero_block.assign(scalar("ZF", 1), expr_const(1, 1));

            zero_block.index()
        };

        // The loop body checks if the bits for our counter is set.
        let (bitfield, loop_index) = {
            let bitfield = control_flow_graph.temp(rhs.bits());

            let loop_block = control_flow_graph.new_block()?;
            loop_block.assign(
                bitfield.clone(),
                Expr::and(
                    Expr::shr(rhs.clone(), counter.clone().into())?,
                    expr_const(1, rhs.bits()),
                )?,
            );

            (bitfield, loop_block.index())
        };

        // While our bitfield == 0, we increment counter and keep looping
        let iterate_index = {
            let iterate_block = control_flow_graph.new_block()?;

            iterate_block.assign(
                counter.clone(),
                Expr::add(counter.clone().into(), expr_const(1, counter.bits()))?,
            );

            iterate_block.index()
        };

        // In our terminating block, we set the result to counter
        let terminating_index = {
            let terminating_block = control_flow_graph.new_block()?;

            self.operand_store(terminating_block, &detail.operands[0], counter.into())?;

            terminating_block.index()
        };

        control_flow_graph.conditional_edge(
            head_index,
            zero_index,
            Expr::cmpeq(rhs.clone(), expr_const(0, rhs.bits()))?,
        )?;
        control_flow_graph.conditional_edge(
            head_index,
            loop_index,
            Expr::cmpneq(rhs.clone(), expr_const(0, rhs.bits()))?,
        )?;

        control_flow_graph.unconditional_edge(zero_index, terminating_index)?;

        control_flow_graph.conditional_edge(
            loop_index,
            iterate_index,
            Expr::cmpeq(bitfield.clone().into(), expr_const(0, bitfield.bits()))?,
        )?;
        control_flow_graph.conditional_edge(
            loop_index,
            terminating_index,
            Expr::cmpneq(bitfield.clone().into(), expr_const(0, bitfield.bits()))?,
        )?;
        control_flow_graph.unconditional_edge(iterate_index, loop_index)?;

        control_flow_graph.set_entry(head_index)?;
        control_flow_graph.set_exit(terminating_index)?;

        Ok(())
    }
/*
        BSF scans the bits in the second word or doubleword operand starting with
        bit 0. The ZF flag is cleared if the bits are all 0; otherwise, the ZF flag
        is set and the destination register is loaded with the bit index of the
        first set bit.
    */
BSF scans the bits in the second word or doubleword operand starting with
bit 0. The ZF flag is cleared if the bits are all 0; otherwise, the ZF flag
is set and the destination register is loaded with the bit index of the
first set bit.
BSF scans the bits in the second word or doubleword operand starting with bit 0 . The ZF flag is cleared if the bits are all 0 ; otherwise the ZF flag is set and the destination register is loaded with the bit index of the first set bit .
pub fn bsf(&self, control_flow_graph: &mut ControlFlowGraph) -> Result<()> {
        let detail = self.details()?;
        // create our head block
        let (head_index, rhs, counter) = {
            let (head_index, rhs) = {
                let head_block = control_flow_graph.new_block()?;
                // get started
                let rhs = self.operand_load(head_block, &detail.operands[1])?;
                (head_block.index(), rhs)
            };
            let counter = { control_flow_graph.temp(rhs.bits()) };
            let head_block = control_flow_graph.block_mut(head_index)?;
            // This is the loop preamble, and we'll always execute it
            head_block.assign(scalar("ZF", 1), expr_const(0, 1));
            head_block.assign(counter.clone(), expr_const(0, rhs.bits()));
            (head_index, rhs, counter)
        };
        // if rhs == 0 then ZF = 1 and we are done.
        let zero_index = {
            let zero_block = control_flow_graph.new_block()?;
            zero_block.assign(scalar("ZF", 1), expr_const(1, 1));
            zero_block.index()
        };
        // The loop body checks if the bits for our counter is set.
        let (bitfield, loop_index) = {
            let bitfield = control_flow_graph.temp(rhs.bits());
            let loop_block = control_flow_graph.new_block()?;
            loop_block.assign(
                bitfield.clone(),
                Expr::and(
                    Expr::shr(rhs.clone(), counter.clone().into())?,
                    expr_const(1, rhs.bits()),
                )?,
            );
            (bitfield, loop_block.index())
        };
        // While our bitfield == 0, we increment counter and keep looping
        let iterate_index = {
            let iterate_block = control_flow_graph.new_block()?;
            iterate_block.assign(
                counter.clone(),
                Expr::add(counter.clone().into(), expr_const(1, counter.bits()))?,
            );
            iterate_block.index()
        };
        // In our terminating block, we set the result to counter
        let terminating_index = {
            let terminating_block = control_flow_graph.new_block()?;
            self.operand_store(terminating_block, &detail.operands[0], counter.into())?;
            terminating_block.index()
        };
        control_flow_graph.conditional_edge(
            head_index,
            zero_index,
            Expr::cmpeq(rhs.clone(), expr_const(0, rhs.bits()))?,
        )?;
        control_flow_graph.conditional_edge(
            head_index,
            loop_index,
            Expr::cmpneq(rhs.clone(), expr_const(0, rhs.bits()))?,
        )?;
        control_flow_graph.unconditional_edge(zero_index, terminating_index)?;
        control_flow_graph.conditional_edge(
            loop_index,
            iterate_index,
            Expr::cmpeq(bitfield.clone().into(), expr_const(0, bitfield.bits()))?,
        )?;
        control_flow_graph.conditional_edge(
            loop_index,
            terminating_index,
            Expr::cmpneq(bitfield.clone().into(), expr_const(0, bitfield.bits()))?,
        )?;
        control_flow_graph.unconditional_edge(iterate_index, loop_index)?;
        control_flow_graph.set_entry(head_index)?;
        control_flow_graph.set_exit(terminating_index)?;
        Ok(())
    }
pub fn bsf ( & self , control_flow_graph : & mut ControlFlowGraph ) -> Result < ( ) > { let detail = self . details ( ) ? ; // create our head block let ( head_index , rhs , counter ) = { let ( head_index , rhs ) = { let head_block = control_flow_graph . new_block ( ) ? ; // get started let rhs = self . operand_load ( head_block , & detail . operands [ 1 ] ) ? ; ( head_block . index ( ) , rhs ) } ; let counter = { control_flow_graph . temp ( rhs . bits ( ) ) } ; let head_block = control_flow_graph . block_mut ( head_index ) ? ; // This is the loop preamble, and we'll always execute it head_block . assign ( scalar ( " " , 1 ) , expr_const ( 0 , 1 ) ) ; head_block . assign ( counter . clone ( ) , expr_const ( 0 , rhs . bits ( ) ) ) ; ( head_index , rhs , counter ) } ; // if rhs == 0 then ZF = 1 and we are done. let zero_index = { let zero_block = control_flow_graph . new_block ( ) ? ; zero_block . assign ( scalar ( " " , 1 ) , expr_const ( 1 , 1 ) ) ; zero_block . index ( ) } ; // The loop body checks if the bits for our counter is set. let ( bitfield , loop_index ) = { let bitfield = control_flow_graph . temp ( rhs . bits ( ) ) ; let loop_block = control_flow_graph . new_block ( ) ? ; loop_block . assign ( bitfield . clone ( ) , Expr :: and ( Expr :: shr ( rhs . clone ( ) , counter . clone ( ) . into ( ) ) ? , expr_const ( 1 , rhs . bits ( ) ) , ) ? , ) ; ( bitfield , loop_block . index ( ) ) } ; // While our bitfield == 0, we increment counter and keep looping let iterate_index = { let iterate_block = control_flow_graph . new_block ( ) ? ; iterate_block . assign ( counter . clone ( ) , Expr :: add ( counter . clone ( ) . into ( ) , expr_const ( 1 , counter . bits ( ) ) ) ? , ) ; iterate_block . index ( ) } ; // In our terminating block, we set the result to counter let terminating_index = { let terminating_block = control_flow_graph . new_block ( ) ? ; self . operand_store ( terminating_block , & detail . operands [ 0 ] , counter . into ( ) ) ? ; terminating_block . index ( ) } ; control_flow_graph . conditional_edge ( head_index , zero_index , Expr :: cmpeq ( rhs . clone ( ) , expr_const ( 0 , rhs . bits ( ) ) ) ? , ) ? ; control_flow_graph . conditional_edge ( head_index , loop_index , Expr :: cmpneq ( rhs . clone ( ) , expr_const ( 0 , rhs . bits ( ) ) ) ? , ) ? ; control_flow_graph . unconditional_edge ( zero_index , terminating_index ) ? ; control_flow_graph . conditional_edge ( loop_index , iterate_index , Expr :: cmpeq ( bitfield . clone ( ) . into ( ) , expr_const ( 0 , bitfield . bits ( ) ) ) ? , ) ? ; control_flow_graph . conditional_edge ( loop_index , terminating_index , Expr :: cmpneq ( bitfield . clone ( ) . into ( ) , expr_const ( 0 , bitfield . bits ( ) ) ) ? , ) ? ; control_flow_graph . unconditional_edge ( iterate_index , loop_index ) ? ; control_flow_graph . set_entry ( head_index ) ? ; control_flow_graph . set_exit ( terminating_index ) ? ; Ok ( ( ) ) }
BSF scans the bits in the second word or doubleword operand starting with
bit 0.
BSF scans the bits in the second word or doubleword operand starting with bit 0 .
&self
control_flow_graph
&mut ControlFlowGraph
&self
control_flow_graph
&mut ControlFlowGraph