Handles the following case:
            ((A << a) | (A >> (_N - a))) & mask, where
                A being a BVS,
                a being a integer that is less than _N,
                _N is either 32 or 64, and
                mask can be evaluated to 0xffffffff (64-bit) or 0xffff (32-bit) after reversing the rotate-shift
                operation.

        It will be simplified to:
            (A & (mask >>> a)) <<< a

def rotate_shift_mask_simplifier(a, b):
        """
        Handles the following case:
            ((A << a) | (A >> (_N - a))) & mask, where
                A being a BVS,
                a being a integer that is less than _N,
                _N is either 32 or 64, and
                mask can be evaluated to 0xffffffff (64-bit) or 0xffff (32-bit) after reversing the rotate-shift
                operation.

        It will be simplified to:
            (A & (mask >>> a)) <<< a
        """

        # is the second argument a BVV?
        if b.op != 'BVV':
            return None

        # is it a rotate-shift?
        if a.op != '__or__' or len(a.args) != 2:
            return None
        a_0, a_1 = a.args

        if a_0.op != '__lshift__':
            return None
        if a_1.op != 'LShR':
            return None
        a_00, a_01 = a_0.args
        a_10, a_11 = a_1.args
        if not a_00 is a_10:
            return None
        if a_01.op != 'BVV' or a_11.op != 'BVV':
            return None
        lshift_ = a_01.args[0]
        rshift_ = a_11.args[0]
        bitwidth = lshift_ + rshift_
        if bitwidth not in (32, 64):
            return None

        # is the second argument a mask?
        # Note: the following check can be further loosen if we want to support more masks.
        if bitwidth == 32:
            m = ((b.args[0] << rshift_) & 0xffffffff) | (b.args[0] >> lshift_)
            if m != 0xffff:
                return None
        else: # bitwidth == 64
            m = ((b.args[0] << rshift_) & 0xffffffffffffffff) | (b.args[0] >> lshift_)
            if m != 0xffffffff:
                return None

        # Show our power!
        masked_a = (a_00 & m)
        expr = (masked_a << lshift_) | (masked_a >> rshift_)
        return expr