setting unicorn registers

def set_regs(self):
        ''' setting unicorn registers '''
        uc = self.uc

        if self.state.arch.qemu_name == 'x86_64':
            fs = self.state.solver.eval(self.state.regs.fs)
            gs = self.state.solver.eval(self.state.regs.gs)
            self.write_msr(fs, 0xC0000100)
            self.write_msr(gs, 0xC0000101)
            flags = self._process_value(self.state.regs.eflags, 'reg')
            if flags is None:
                raise SimValueError('symbolic eflags')
            uc.reg_write(self._uc_const.UC_X86_REG_EFLAGS, self.state.solver.eval(flags))
        elif self.state.arch.qemu_name == 'i386':
            flags = self._process_value(self.state.regs.eflags, 'reg')
            if flags is None:
                raise SimValueError('symbolic eflags')

            uc.reg_write(self._uc_const.UC_X86_REG_EFLAGS, self.state.solver.eval(flags))
            fs = self.state.solver.eval(self.state.regs.fs) << 16
            gs = self.state.solver.eval(self.state.regs.gs) << 16
            self.setup_gdt(fs, gs)


        for r, c in self._uc_regs.items():
            if r in self.reg_blacklist:
                continue
            v = self._process_value(getattr(self.state.regs, r), 'reg')
            if v is None:
                    raise SimValueError('setting a symbolic register')
            # l.debug('setting $%s = %#x', r, self.state.solver.eval(v))
            uc.reg_write(c, self.state.solver.eval(v))

        if self.state.arch.name in ('X86', 'AMD64'):
            # sync the fp clerical data
            c3210 = self.state.solver.eval(self.state.regs.fc3210)
            top = self.state.solver.eval(self.state.regs.ftop[2:0])
            rm = self.state.solver.eval(self.state.regs.fpround[1:0])
            control = 0x037F | (rm << 10)
            status = (top << 11) | c3210
            uc.reg_write(unicorn.x86_const.UC_X86_REG_FPCW, control)
            uc.reg_write(unicorn.x86_const.UC_X86_REG_FPSW, status)

            # we gotta convert the 64-bit doubles values to 80-bit extended precision!
            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]
            tag_word = 0
            for _ in range(8):
                tag = self.state.solver.eval(self.state.registers.load(vex_tag_offset, size=1))
                tag_word <<= 2
                if tag == 0:
                    tag_word |= 3       # unicorn doesn't care about any value other than 3 for setting
                else:
                    val = self._process_value(self.state.registers.load(vex_offset, size=8), 'reg')
                    if val is None:
                        raise SimValueError('setting a symbolic fp register')
                    val = self.state.solver.eval(val)

                    sign = bool(val & 0x8000000000000000)
                    exponent = (val & 0x7FF0000000000000) >> 52
                    mantissa =  val & 0x000FFFFFFFFFFFFF
                    if exponent not in (0, 0x7FF): # normal value
                        exponent = exponent - 1023 + 16383
                        mantissa <<= 11
                        mantissa |= 0x8000000000000000  # set integer part bit, implicit to double
                    elif exponent == 0:     # zero or subnormal value
                        mantissa = 0
                    elif exponent == 0x7FF:    # nan or infinity
                        exponent = 0x7FFF
                        if mantissa != 0:
                            mantissa = 0x8000000000000000
                        else:
                            mantissa = 0xFFFFFFFFFFFFFFFF

                    if sign:
                        exponent |= 0x8000

                    uc.reg_write(uc_offset, (exponent, mantissa))

                uc_offset += 1
                vex_offset += 8
                vex_tag_offset += 1

            uc.reg_write(unicorn.x86_const.UC_X86_REG_FPTAG, tag_word)