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

        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((rhs.bits() - 1) as u64, 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 decrement counter and keep looping
        let iterate_index = {
            let iterate_block = control_flow_graph.new_block()?;

            iterate_block.assign(
                counter.clone(),
                Expr::sub(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(())
    }
/*
        BSR scans the bits in the second word or doubleword operand from the most
        significant bit to the least significant bit. The ZF flag is cleared if the
        bits are all 0; otherwise, ZF is set and the destination register is loaded
        with the bit index of the first set bit found when scanning in the reverse
        direction.
    */
BSR scans the bits in the second word or doubleword operand from the most
significant bit to the least significant bit. The ZF flag is cleared if the
bits are all 0; otherwise, ZF is set and the destination register is loaded
with the bit index of the first set bit found when scanning in the reverse
direction.
BSR scans the bits in the second word or doubleword operand from the most significant bit to the least significant bit . The ZF flag is cleared if the bits are all 0 ; otherwise ZF is set and the destination register is loaded with the bit index of the first set bit found when scanning in the reverse direction .
pub fn bsr(&self, control_flow_graph: &mut ControlFlowGraph) -> Result<()> {
        let detail = self.details()?;
        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((rhs.bits() - 1) as u64, 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 decrement counter and keep looping
        let iterate_index = {
            let iterate_block = control_flow_graph.new_block()?;
            iterate_block.assign(
                counter.clone(),
                Expr::sub(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 bsr ( & self , control_flow_graph : & mut ControlFlowGraph ) -> Result < ( ) > { let detail = self . details ( ) ? ; 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 ( ( rhs . bits ( ) - 1 ) as u64 , 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 decrement counter and keep looping let iterate_index = { let iterate_block = control_flow_graph . new_block ( ) ? ; iterate_block . assign ( counter . clone ( ) , Expr :: sub ( 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 ( ( ) ) }
BSR scans the bits in the second word or doubleword operand from the most
significant bit to the least significant bit.
BSR scans the bits in the second word or doubleword operand from the most significant bit to the least significant bit .
&self
control_flow_graph
&mut ControlFlowGraph
&self
control_flow_graph
&mut ControlFlowGraph