loading registers from unicorn

def get_regs(self):
        ''' loading registers from unicorn '''

        # first, get the ignore list (in case of symbolic registers)
        if options.UNICORN_SYM_REGS_SUPPORT in self.state.options:
            highest_reg_offset, reg_size = max(self.state.arch.registers.values())
            symbolic_list = (ctypes.c_uint64*(highest_reg_offset + reg_size))()
            num_regs = _UC_NATIVE.get_symbolic_registers(self._uc_state, symbolic_list)

            # we take the approach of saving off the symbolic regs and then writing them back
            saved_registers = [ ]
            cur_group = None
            last = None
            for i in sorted(symbolic_list[:num_regs]):
                if cur_group is None:
                    cur_group = i
                elif i != last + 1 or cur_group//self.state.arch.bytes != i//self.state.arch.bytes:
                    saved_registers.append((
                        cur_group, self.state.registers.load(cur_group, last-cur_group+1)
                    ))
                    cur_group = i
                last = i
            if cur_group is not None:
                saved_registers.append((
                    cur_group, self.state.registers.load(cur_group, last-cur_group+1)
                ))

        # now we sync registers out of unicorn
        for r, c in self._uc_regs.items():
            if r in self.reg_blacklist:
                continue
            v = self.uc.reg_read(c)
            # l.debug('getting $%s = %#x', r, v)
            setattr(self.state.regs, r, v)

        # some architecture-specific register fixups
        if self.state.arch.name in ('X86', 'AMD64'):
            if self.jumpkind.startswith('Ijk_Sys'):
                self.state.registers.store('ip_at_syscall', self.state.regs.ip - 2)

            # update the eflags
            self.state.regs.eflags = self.state.solver.BVV(self.uc.reg_read(self._uc_const.UC_X86_REG_EFLAGS), self.state.arch.bits)

            # sync the fp clerical data
            status = self.uc.reg_read(unicorn.x86_const.UC_X86_REG_FPSW)
            c3210 = status & 0x4700
            top = (status & 0x3800) >> 11
            control = self.uc.reg_read(unicorn.x86_const.UC_X86_REG_FPCW)
            rm = (control & 0x0C00) >> 10
            self.state.regs.fpround = rm
            self.state.regs.fc3210 = c3210
            self.state.regs.ftop = top

            # sync the stx registers
            # we gotta round the 80-bit extended precision values to 64-bit doubles!
            uc_offset = unicorn.x86_const.UC_X86_REG_FP0
            vex_offset = self.state.arch.registers['fpu_regs'][0]
            vex_tag_offset = self.state.arch.registers['fpu_tags'][0] + 7
            tag_word = self.uc.reg_read(unicorn.x86_const.UC_X86_REG_FPTAG)

            for _ in range(8):
                if tag_word & 3 == 3:
                    self.state.registers.store(vex_tag_offset, 0, size=1)
                else:
                    self.state.registers.store(vex_tag_offset, 1, size=1)

                    mantissa, exponent = self.uc.reg_read(uc_offset)
                    sign = bool(exponent & 0x8000)
                    exponent = (exponent & 0x7FFF)
                    if exponent not in (0, 0x7FFF): # normal value
                        exponent = exponent - 16383 + 1023
                        if exponent <= 0:   # underflow to zero
                            exponent = 0
                            mantissa = 0
                        elif exponent >= 0x7FF: # overflow to infinity
                            exponent = 0x7FF
                            mantissa = 0
                    elif exponent == 0:     # zero or subnormal value
                        mantissa = 0
                    elif exponent == 0x7FFF:    # nan or infinity
                        exponent = 0x7FF
                        if mantissa != 0:
                            mantissa = 0xFFFF

                    val = 0x8000000000000000 if sign else 0
                    val |= exponent << 52
                    val |= (mantissa >> 11) & 0xFFFFFFFFFFFFF
                    # the mantissa calculation is to convert from the 64-bit mantissa to 52-bit
                    # additionally, extended precision keeps around an high bit that we don't care about
                    # so 11-shift, not 12

                    self.state.registers.store(vex_offset, val, size=8)

                uc_offset += 1
                vex_offset += 8
                tag_word >>= 2
                vex_tag_offset -= 1

        # now, we restore the symbolic registers
        if options.UNICORN_SYM_REGS_SUPPORT in self.state.options:
            for o,r in saved_registers:
                self.state.registers.store(o, r)