'Lift an IRSB.
There are many possible valid sets of parameters. You at the very least must pass some
source of data, some source of an architecture, and some source of an address.
Sources of data in order of priority: insn_bytes, clemory, state
Sources of an address, in order of priority: addr, state
Sources of an architecture, in order of priority: arch, clemory, state
:param state:           A state to use as a data source.
:param clemory:         A cle.memory.Clemory object to use as a data source.
:param addr:            The address at which to start the block.
:param thumb:           Whether the block should be lifted in ARM\'s THUMB mode.
:param opt_level:       The VEX optimization level to use. The final IR optimization level is determined by
(ordered by priority):
- Argument opt_level
- opt_level is set to 1 if OPTIMIZE_IR exists in state options
- self._default_opt_level
:param insn_bytes:      A string of bytes to use as a data source.
:param size:            The maximum size of the block, in bytes.
:param num_inst:        The maximum number of instructions.
:param traceflags:      traceflags to be passed to VEX. (default: 0)'

def lift(self, state=None, clemory=None, insn_bytes=None, arch=None, addr=None, size=None, num_inst=None, traceflags=0, thumb=False, opt_level=None):

    if ((not state) and (not clemory) and (not insn_bytes)):
        raise ValueError('Must    provide    state    or    clemory    or    insn_bytes!')
    if ((not state) and (not clemory) and (not arch)):
        raise ValueError('Must    provide    state    or    clemory    or    arch!')
    if ((addr is None) and (not state)):
        raise ValueError('Must    provide    state    or    addr!')
    if (arch is None):
        arch = (clemory._arch if clemory else state.arch)
    if (arch.name.startswith('MIPS') and self._single_step):
        l.error('Cannot    specify    single-stepping    on    MIPS.')
        self._single_step = False
    if (addr is None):
        addr = state.se.any_int(state._ip)
    if (size is not None):
        size = min(size, VEX_IRSB_MAX_SIZE)
    if (size is None):
        size = VEX_IRSB_MAX_SIZE
    if (num_inst is not None):
        num_inst = min(num_inst, VEX_IRSB_MAX_INST)
    if ((num_inst is None) and self._single_step):
        num_inst = 1
    if (opt_level is None):
        if (state and (o.OPTIMIZE_IR in state.options)):
            opt_level = 1
        else:
            opt_level = self._default_opt_level
    if self._support_selfmodifying_code:
        if (opt_level > 0):
            l.warning('Self-modifying    code    is    not    always    correctly    optimized    by    PyVEX.    To    guarantee    correctness,    VEX    optimizations    have    been    disabled.')
            opt_level = 0
            if (state and (o.OPTIMIZE_IR in state.options)):
                state.options.remove(o.OPTIMIZE_IR)
    thumb = int(thumb)
    if isinstance(arch, ArchARM):
        if ((addr % 2) == 1):
            thumb = 1
        if thumb:
            addr &= (~ 1)
    elif thumb:
        l.error('thumb=True    passed    on    non-arm    architecture!')
        thumb = 0
    cache_key = (addr, insn_bytes, size, num_inst, thumb, opt_level)
    if (self._use_cache and (cache_key in self._block_cache)):
        self._cache_hit_count += 1
        irsb = self._block_cache[cache_key]
        stop_point = self._first_stoppoint(irsb)
        if (stop_point is None):
            return irsb
        else:
            size = (stop_point - addr)
            cache_key = (addr, insn_bytes, size, num_inst, thumb, opt_level)
            if (cache_key in self._block_cache):
                self._cache_hit_count += 1
                return self._block_cache[cache_key]
            else:
                self._cache_miss_count += 1
    else:
        self._cache_miss_count += 1
    if (insn_bytes is not None):
        (buff, size) = (insn_bytes, len(insn_bytes))
    else:
        (buff, size) = self._load_bytes(addr, size, state, clemory)
    if ((not buff) or (size == 0)):
        raise SimEngineError(('No    bytes    in    memory    for    block    starting    at    %#x.' % addr))
    l.debug('Creating    pyvex.IRSB    of    arch    %s    at    %#x', arch.name, addr)
    try:
        for subphase in xrange(2):
            irsb = pyvex.IRSB(buff, (addr + thumb), arch, num_bytes=size, num_inst=num_inst, bytes_offset=thumb, traceflags=traceflags, opt_level=opt_level)
            if (subphase == 0):
                stop_point = self._first_stoppoint(irsb)
                if (stop_point is not None):
                    size = (stop_point - addr)
                    continue
            if self._use_cache:
                self._block_cache[cache_key] = irsb
            return irsb
    except pyvex.PyVEXError:
        l.debug('VEX    translation    error    at    %#x', addr)
        if isinstance(buff, str):
            l.debug(('Using    bytes:    ' + buff))
        else:
            l.debug(('Using    bytes:    ' + str(pyvex.ffi.buffer(buff, size)).encode('hex')))
        (e_type, value, traceback) = sys.exc_info()
        raise SimTranslationError, ('Translation    error', e_type, value), traceback
