static void lm32_uclinux_init(MachineState *machine)

{

    const char *cpu_model = machine->cpu_model;

    const char *kernel_filename = machine->kernel_filename;

    const char *kernel_cmdline = machine->kernel_cmdline;

    const char *initrd_filename = machine->initrd_filename;

    LM32CPU *cpu;

    CPULM32State *env;

    DriveInfo *dinfo;

    MemoryRegion *address_space_mem =  get_system_memory();

    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);

    qemu_irq irq[32];

    HWSetup *hw;

    ResetInfo *reset_info;

    int i;

    /* memory map */

    hwaddr flash_base   = 0x04000000;

    size_t flash_sector_size        = 256 * 1024;

    size_t flash_size               = 32 * 1024 * 1024;

    hwaddr ram_base     = 0x08000000;

    size_t ram_size                 = 64 * 1024 * 1024;

    hwaddr uart0_base   = 0x80000000;

    hwaddr timer0_base  = 0x80002000;

    hwaddr timer1_base  = 0x80010000;

    hwaddr timer2_base  = 0x80012000;

    int uart0_irq                   = 0;

    int timer0_irq                  = 1;

    int timer1_irq                  = 20;

    int timer2_irq                  = 21;

    hwaddr hwsetup_base = 0x0bffe000;

    hwaddr cmdline_base = 0x0bfff000;

    hwaddr initrd_base  = 0x08400000;

    size_t initrd_max               = 0x01000000;

    reset_info = g_malloc0(sizeof(ResetInfo));

    if (cpu_model == NULL) {

        cpu_model = "lm32-full";

    }

    cpu = LM32_CPU(cpu_generic_init(TYPE_LM32_CPU, cpu_model));

    if (cpu == NULL) {

        fprintf(stderr, "qemu: unable to find CPU '%s'\n", cpu_model);

        exit(1);

    }

    env = &cpu->env;

    reset_info->cpu = cpu;

    reset_info->flash_base = flash_base;

    memory_region_allocate_system_memory(phys_ram, NULL,

                                         "lm32_uclinux.sdram", ram_size);

    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);

    dinfo = drive_get(IF_PFLASH, 0, 0);

    /* Spansion S29NS128P */

    pflash_cfi02_register(flash_base, NULL, "lm32_uclinux.flash", flash_size,

                          dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,

                          flash_sector_size, flash_size / flash_sector_size,

                          1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);

    /* create irq lines */

    env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, env, 0));

    for (i = 0; i < 32; i++) {

        irq[i] = qdev_get_gpio_in(env->pic_state, i);

    }

    lm32_uart_create(uart0_base, irq[uart0_irq], serial_hds[0]);

    sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]);

    sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]);

    sysbus_create_simple("lm32-timer", timer2_base, irq[timer2_irq]);

    /* make sure juart isn't the first chardev */

    env->juart_state = lm32_juart_init(serial_hds[1]);

    reset_info->bootstrap_pc = flash_base;

    if (kernel_filename) {

        uint64_t entry;

        int kernel_size;

        kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL,

                               1, EM_LATTICEMICO32, 0, 0);

        reset_info->bootstrap_pc = entry;

        if (kernel_size < 0) {

            kernel_size = load_image_targphys(kernel_filename, ram_base,

                                              ram_size);

            reset_info->bootstrap_pc = ram_base;

        }

        if (kernel_size < 0) {

            fprintf(stderr, "qemu: could not load kernel '%s'\n",

                    kernel_filename);

            exit(1);

        }

    }

    /* generate a rom with the hardware description */

    hw = hwsetup_init();

    hwsetup_add_cpu(hw, "LM32", 75000000);

    hwsetup_add_flash(hw, "flash", flash_base, flash_size);

    hwsetup_add_ddr_sdram(hw, "ddr_sdram", ram_base, ram_size);

    hwsetup_add_timer(hw, "timer0", timer0_base, timer0_irq);

    hwsetup_add_timer(hw, "timer1_dev_only", timer1_base, timer1_irq);

    hwsetup_add_timer(hw, "timer2_dev_only", timer2_base, timer2_irq);

    hwsetup_add_uart(hw, "uart", uart0_base, uart0_irq);

    hwsetup_add_trailer(hw);

    hwsetup_create_rom(hw, hwsetup_base);

    hwsetup_free(hw);

    reset_info->hwsetup_base = hwsetup_base;

    if (kernel_cmdline && strlen(kernel_cmdline)) {

        pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE,

                kernel_cmdline);

        reset_info->cmdline_base = cmdline_base;

    }

    if (initrd_filename) {

        size_t initrd_size;

        initrd_size = load_image_targphys(initrd_filename, initrd_base,

                initrd_max);

        reset_info->initrd_base = initrd_base;

        reset_info->initrd_size = initrd_size;

    }

    qemu_register_reset(main_cpu_reset, reset_info);

}


static int vnc_update_client(VncState *vs, int has_dirty)

{

    if (vs->need_update && vs->csock != -1) {

        VncDisplay *vd = vs->vd;

        VncJob *job;

        int y;

        int width, height;

        int n = 0;

        if (vs->output.offset && !vs->audio_cap && !vs->force_update)

            /* kernel send buffers are full -> drop frames to throttle */

            return 0;

        if (!has_dirty && !vs->audio_cap && !vs->force_update)

            return 0;

        /*

         * Send screen updates to the vnc client using the server

         * surface and server dirty map.  guest surface updates

         * happening in parallel don't disturb us, the next pass will

         * send them to the client.

         */

        job = vnc_job_new(vs);

        width = MIN(pixman_image_get_width(vd->server), vs->client_width);

        height = MIN(pixman_image_get_height(vd->server), vs->client_height);

        for (y = 0; y < height; y++) {

            int x;

            int last_x = -1;

            for (x = 0; x < width / 16; x++) {

                if (test_and_clear_bit(x, vs->dirty[y])) {

                    if (last_x == -1) {

                        last_x = x;

                    }

                } else {

                    if (last_x != -1) {

                        int h = find_and_clear_dirty_height(vs, y, last_x, x,

                                                            height);

                        n += vnc_job_add_rect(job, last_x * 16, y,

                                              (x - last_x) * 16, h);

                    }

                    last_x = -1;

                }

            }

            if (last_x != -1) {

                int h = find_and_clear_dirty_height(vs, y, last_x, x, height);

                n += vnc_job_add_rect(job, last_x * 16, y,

                                      (x - last_x) * 16, h);

            }

        }

        vnc_job_push(job);

        vs->force_update = 0;

        return n;

    }

    if (vs->csock == -1)

        vnc_disconnect_finish(vs);

    return 0;

}


static void test_qemu_strtol_empty(void)

{

    const char *str = "";

    char f = 'X';

    const char *endptr = &f;

    long res = 999;

    int err;

    err = qemu_strtol(str, &endptr, 0, &res);

    g_assert_cmpint(err, ==, 0);

    g_assert_cmpint(res, ==, 0);

    g_assert(endptr == str);

}


static void test_endianness(gconstpointer data)

{

    const TestCase *test = data;

    char *args;

    args = g_strdup_printf("-display none -M %s%s%s -device pc-testdev",

                           test->machine,

                           test->superio ? " -device " : "",

                           test->superio ?: "");

    qtest_start(args);

    isa_outl(test, 0xe0, 0x87654321);

    g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);

    g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);

    g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);

    g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);

    g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);

    g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);

    g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21);

    isa_outw(test, 0xe2, 0x8866);

    g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664321);

    g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);

    g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);

    g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x88);

    g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66);

    g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);

    g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21);

    isa_outw(test, 0xe0, 0x4422);

    g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664422);

    g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);

    g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);

    g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x88);

    g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66);

    g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44);

    g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);

    isa_outb(test, 0xe3, 0x87);

    g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87664422);

    g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8766);

    g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);

    g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66);

    g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44);

    g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);

    isa_outb(test, 0xe2, 0x65);

    g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654422);

    g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);

    g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);

    g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);

    g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);

    g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44);

    g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);

    isa_outb(test, 0xe1, 0x43);

    g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654322);

    g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);

    g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4322);

    g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);

    g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);

    g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);

    g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);

    isa_outb(test, 0xe0, 0x21);

    g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);

    g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);

    g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);

    g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);

    g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);

    g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);

    g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21);

    qtest_quit(global_qtest);

    g_free(args);

}


float32 HELPER(ucf64_negs)(float32 a)

{

    return float32_chs(a);

}


static void *rcu_read_perf_test(void *arg)

{

    int i;

    long long n_reads_local = 0;

    rcu_register_thread();

    *(struct rcu_reader_data **)arg = &rcu_reader;

    atomic_inc(&nthreadsrunning);

    while (goflag == GOFLAG_INIT) {

        g_usleep(1000);

    }

    while (goflag == GOFLAG_RUN) {

        for (i = 0; i < RCU_READ_RUN; i++) {

            rcu_read_lock();

            rcu_read_unlock();

        }

        n_reads_local += RCU_READ_RUN;

    }

    atomic_add(&n_reads, n_reads_local);

    rcu_unregister_thread();

    return NULL;

}


static inline int coeff_unpack_golomb(GetBitContext *gb, int qfactor, int qoffset)

{

    int sign, coeff;

    uint32_t buf;

    OPEN_READER(re, gb);

    UPDATE_CACHE(re, gb);

    buf = GET_CACHE(re, gb);

    if (buf & 0xAA800000) {

        buf >>= 32 - 8;

        SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]);

        coeff = ff_interleaved_ue_golomb_vlc_code[buf];

    } else {

        unsigned ret = 1;

        do {

            buf >>= 32 - 8;

            SKIP_BITS(re, gb,

                           FFMIN(ff_interleaved_golomb_vlc_len[buf], 8));

            if (ff_interleaved_golomb_vlc_len[buf] != 9) {

                ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1;

                ret  |= ff_interleaved_dirac_golomb_vlc_code[buf];

                break;

            }

            ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf];

            UPDATE_CACHE(re, gb);

            buf = GET_CACHE(re, gb);

        } while (ret<0x8000000U && BITS_AVAILABLE(re, gb));

        coeff = ret - 1;

    }

    if (coeff) {

        coeff = (coeff * qfactor + qoffset + 2) >> 2;

        sign  = SHOW_SBITS(re, gb, 1);

        LAST_SKIP_BITS(re, gb, 1);

        coeff = (coeff ^ sign) - sign;

    }

    CLOSE_READER(re, gb);

    return coeff;

}


static CharDriverState *qemu_chr_open_tcp(const char *host_str,

                                          int is_telnet,

					  int is_unix)

{

    CharDriverState *chr = NULL;

    TCPCharDriver *s = NULL;

    int fd = -1, ret, err, val;

    int is_listen = 0;

    int is_waitconnect = 1;

    int do_nodelay = 0;

    const char *ptr;

    struct sockaddr_in saddr;

#ifndef _WIN32

    struct sockaddr_un uaddr;

#endif

    struct sockaddr *addr;

    socklen_t addrlen;

#ifndef _WIN32

    if (is_unix) {

	addr = (struct sockaddr *)&uaddr;

	addrlen = sizeof(uaddr);

	if (parse_unix_path(&uaddr, host_str) < 0)

	    goto fail;

    } else

#endif

    {

	addr = (struct sockaddr *)&saddr;

	addrlen = sizeof(saddr);

	if (parse_host_port(&saddr, host_str) < 0)

	    goto fail;

    }

    ptr = host_str;

    while((ptr = strchr(ptr,','))) {

        ptr++;

        if (!strncmp(ptr,"server",6)) {

            is_listen = 1;

        } else if (!strncmp(ptr,"nowait",6)) {

            is_waitconnect = 0;

        } else if (!strncmp(ptr,"nodelay",6)) {

            do_nodelay = 1;

        } else {

            printf("Unknown option: %s\n", ptr);

            goto fail;

        }

    }

    if (!is_listen)

        is_waitconnect = 0;

    chr = qemu_mallocz(sizeof(CharDriverState));

    if (!chr)

        goto fail;

    s = qemu_mallocz(sizeof(TCPCharDriver));

    if (!s)

        goto fail;

#ifndef _WIN32

    if (is_unix)

	fd = socket(PF_UNIX, SOCK_STREAM, 0);

    else

#endif

	fd = socket(PF_INET, SOCK_STREAM, 0);

    if (fd < 0)

        goto fail;

    if (!is_waitconnect)

        socket_set_nonblock(fd);

    s->connected = 0;

    s->fd = -1;

    s->listen_fd = -1;

    s->is_unix = is_unix;

    s->do_nodelay = do_nodelay && !is_unix;

    chr->opaque = s;

    chr->chr_write = tcp_chr_write;

    chr->chr_close = tcp_chr_close;

    if (is_listen) {

        /* allow fast reuse */

#ifndef _WIN32

	if (is_unix) {

	    char path[109];

	    pstrcpy(path, sizeof(path), uaddr.sun_path);

	    unlink(path);

	} else

#endif

	{

	    val = 1;

	    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));

	}

        ret = bind(fd, addr, addrlen);

        if (ret < 0)

            goto fail;

        ret = listen(fd, 0);

        if (ret < 0)

            goto fail;

        s->listen_fd = fd;

        qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);

        if (is_telnet)

            s->do_telnetopt = 1;

    } else {

        for(;;) {

            ret = connect(fd, addr, addrlen);

            if (ret < 0) {

                err = socket_error();

                if (err == EINTR || err == EWOULDBLOCK) {

                } else if (err == EINPROGRESS) {

                    break;

#ifdef _WIN32

                } else if (err == WSAEALREADY) {

                    break;

#endif

                } else {

                    goto fail;

                }

            } else {

                s->connected = 1;

                break;

            }

        }

        s->fd = fd;

        socket_set_nodelay(fd);

        if (s->connected)

            tcp_chr_connect(chr);

        else

            qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);

    }

    if (is_listen && is_waitconnect) {

        printf("QEMU waiting for connection on: %s\n", host_str);

        tcp_chr_accept(chr);

        socket_set_nonblock(s->listen_fd);

    }

    return chr;

 fail:

    if (fd >= 0)

        closesocket(fd);

    qemu_free(s);

    qemu_free(chr);

    return NULL;

}


void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,

                                       const ARMCPRegInfo *r, void *opaque)

{

    /* Define implementations of coprocessor registers.

     * We store these in a hashtable because typically

     * there are less than 150 registers in a space which

     * is 16*16*16*8*8 = 262144 in size.

     * Wildcarding is supported for the crm, opc1 and opc2 fields.

     * If a register is defined twice then the second definition is

     * used, so this can be used to define some generic registers and

     * then override them with implementation specific variations.

     * At least one of the original and the second definition should

     * include ARM_CP_OVERRIDE in its type bits -- this is just a guard

     * against accidental use.

     */

    int crm, opc1, opc2;

    int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;

    int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;

    int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;

    int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;

    int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;

    int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;

    /* 64 bit registers have only CRm and Opc1 fields */

    assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));

    /* Check that the register definition has enough info to handle

     * reads and writes if they are permitted.

     */

    if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {

        if (r->access & PL3_R) {

            assert(r->fieldoffset || r->readfn);

        }

        if (r->access & PL3_W) {

            assert(r->fieldoffset || r->writefn);

        }

    }

    /* Bad type field probably means missing sentinel at end of reg list */

    assert(cptype_valid(r->type));

    for (crm = crmmin; crm <= crmmax; crm++) {

        for (opc1 = opc1min; opc1 <= opc1max; opc1++) {

            for (opc2 = opc2min; opc2 <= opc2max; opc2++) {

                uint32_t *key = g_new(uint32_t, 1);

                ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));

                int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;

                *key = ENCODE_CP_REG(r->cp, is64, r->crn, crm, opc1, opc2);

                if (opaque) {

                    r2->opaque = opaque;

                }

                /* Make sure reginfo passed to helpers for wildcarded regs

                 * has the correct crm/opc1/opc2 for this reg, not CP_ANY:

                 */

                r2->crm = crm;

                r2->opc1 = opc1;

                r2->opc2 = opc2;

                /* By convention, for wildcarded registers only the first

                 * entry is used for migration; the others are marked as

                 * NO_MIGRATE so we don't try to transfer the register

                 * multiple times. Special registers (ie NOP/WFI) are

                 * never migratable.

                 */

                if ((r->type & ARM_CP_SPECIAL) ||

                    ((r->crm == CP_ANY) && crm != 0) ||

                    ((r->opc1 == CP_ANY) && opc1 != 0) ||

                    ((r->opc2 == CP_ANY) && opc2 != 0)) {

                    r2->type |= ARM_CP_NO_MIGRATE;

                }

                /* Overriding of an existing definition must be explicitly

                 * requested.

                 */

                if (!(r->type & ARM_CP_OVERRIDE)) {

                    ARMCPRegInfo *oldreg;

                    oldreg = g_hash_table_lookup(cpu->cp_regs, key);

                    if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {

                        fprintf(stderr, "Register redefined: cp=%d %d bit "

                                "crn=%d crm=%d opc1=%d opc2=%d, "

                                "was %s, now %s\n", r2->cp, 32 + 32 * is64,

                                r2->crn, r2->crm, r2->opc1, r2->opc2,

                                oldreg->name, r2->name);

                        g_assert_not_reached();

                    }

                }

                g_hash_table_insert(cpu->cp_regs, key, r2);

            }

        }

    }

}


static void sdhci_sdma_transfer_single_block(SDHCIState *s)

{

    int n;

    uint32_t datacnt = s->blksize & 0x0fff;

    if (s->trnmod & SDHC_TRNS_READ) {

        for (n = 0; n < datacnt; n++) {

            s->fifo_buffer[n] = sdbus_read_data(&s->sdbus);

        }

        dma_memory_write(&address_space_memory, s->sdmasysad, s->fifo_buffer,

                         datacnt);

    } else {

        dma_memory_read(&address_space_memory, s->sdmasysad, s->fifo_buffer,

                        datacnt);

        for (n = 0; n < datacnt; n++) {

            sdbus_write_data(&s->sdbus, s->fifo_buffer[n]);

        }

    }

    if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {

        s->blkcnt--;

    }

    sdhci_end_transfer(s);

}


static int tight_compress_data(VncState *vs, int stream_id, size_t bytes,

                               int level, int strategy)

{

    z_streamp zstream = &vs->tight_stream[stream_id];

    int previous_out;

    if (bytes < VNC_TIGHT_MIN_TO_COMPRESS) {

        vnc_write(vs, vs->tight.buffer, vs->tight.offset);

        return bytes;

    }

    if (tight_init_stream(vs, stream_id, level, strategy)) {

        return -1;

    }

    /* reserve memory in output buffer */

    buffer_reserve(&vs->tight_zlib, bytes + 64);

    /* set pointers */

    zstream->next_in = vs->tight.buffer;

    zstream->avail_in = vs->tight.offset;

    zstream->next_out = vs->tight_zlib.buffer + vs->tight_zlib.offset;

    zstream->avail_out = vs->tight_zlib.capacity - vs->tight_zlib.offset;

    zstream->data_type = Z_BINARY;

    previous_out = zstream->total_out;

    /* start encoding */

    if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {

        fprintf(stderr, "VNC: error during tight compression\n");

        return -1;

    }

    vs->tight_zlib.offset = vs->tight_zlib.capacity - zstream->avail_out;

    bytes = zstream->total_out - previous_out;

    tight_send_compact_size(vs, bytes);

    vnc_write(vs, vs->tight_zlib.buffer, bytes);

    buffer_reset(&vs->tight_zlib);

    return bytes;

}


static void gen_compute_eflags_p(DisasContext *s, TCGv reg)

{

    gen_compute_eflags(s);

    tcg_gen_shri_tl(reg, cpu_cc_src, 2);

    tcg_gen_andi_tl(reg, reg, 1);

}


int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)

{

    int ret;

    av_frame_unref(frame);

    if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec))

        return AVERROR(EINVAL);

    if (avctx->codec->receive_frame) {

        if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY))

            return AVERROR_EOF;

        return avctx->codec->receive_frame(avctx, frame);

    }

    // Emulation via old API.

    if (!avctx->internal->buffer_frame->buf[0]) {

        if (!avctx->internal->buffer_pkt->size && !avctx->internal->draining)

            return AVERROR(EAGAIN);

        while (1) {

            if ((ret = do_decode(avctx, avctx->internal->buffer_pkt)) < 0) {

                av_packet_unref(avctx->internal->buffer_pkt);

                return ret;

            }

            // Some audio decoders may consume partial data without returning

            // a frame (fate-wmapro-2ch). There is no way to make the caller

            // call avcodec_receive_frame() again without returning a frame,

            // so try to decode more in these cases.

            if (avctx->internal->buffer_frame->buf[0] ||

                !avctx->internal->buffer_pkt->size)

                break;

        }

    }

    if (!avctx->internal->buffer_frame->buf[0])

        return avctx->internal->draining ? AVERROR_EOF : AVERROR(EAGAIN);

    av_frame_move_ref(frame, avctx->internal->buffer_frame);

    return 0;

}


static void test_visitor_out_no_string(TestOutputVisitorData *data,

                                       const void *unused)

{

    char *string = NULL;

    QObject *obj;

    /* A null string should return "" */

    visit_type_str(data->ov, NULL, &string, &error_abort);

    obj = visitor_get(data);

    g_assert(qobject_type(obj) == QTYPE_QSTRING);

    g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==, "");

}


static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)

{

    int ret = 0, offset, cpus_offset;

    CPUState *cs;

    char cpu_model[32];

    int smt = kvmppc_smt_threads();

    uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};

    CPU_FOREACH(cs) {

        PowerPCCPU *cpu = POWERPC_CPU(cs);

        DeviceClass *dc = DEVICE_GET_CLASS(cs);

        int index = ppc_get_vcpu_dt_id(cpu);

        uint32_t associativity[] = {cpu_to_be32(0x5),

                                    cpu_to_be32(0x0),

                                    cpu_to_be32(0x0),

                                    cpu_to_be32(0x0),

                                    cpu_to_be32(cs->numa_node),

                                    cpu_to_be32(index)};

        if ((index % smt) != 0) {

            continue;

        }

        snprintf(cpu_model, 32, "%s@%x", dc->fw_name, index);

        cpus_offset = fdt_path_offset(fdt, "/cpus");

        if (cpus_offset < 0) {

            cpus_offset = fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"),

                                          "cpus");

            if (cpus_offset < 0) {

                return cpus_offset;

            }

        }

        offset = fdt_subnode_offset(fdt, cpus_offset, cpu_model);

        if (offset < 0) {

            offset = fdt_add_subnode(fdt, cpus_offset, cpu_model);

            if (offset < 0) {

                return offset;

            }

        }

        if (nb_numa_nodes > 1) {

            ret = fdt_setprop(fdt, offset, "ibm,associativity", associativity,

                              sizeof(associativity));

            if (ret < 0) {

                return ret;

            }

        }

        ret = fdt_setprop(fdt, offset, "ibm,pft-size",

                          pft_size_prop, sizeof(pft_size_prop));

        if (ret < 0) {

            return ret;

        }

        ret = spapr_fixup_cpu_smt_dt(fdt, offset, cpu,

                                     smp_threads);

        if (ret < 0) {

            return ret;

        }

    }

    return ret;

}


static always_inline void gen_excp (DisasContext *ctx,

                                    int exception, int error_code)

{

    TCGv tmp1, tmp2;

    tcg_gen_movi_i64(cpu_pc, ctx->pc);

    tmp1 = tcg_const_i32(exception);

    tmp2 = tcg_const_i32(error_code);

    tcg_gen_helper_0_2(helper_excp, tmp1, tmp2);

    tcg_temp_free(tmp2);

    tcg_temp_free(tmp1);

}


static bool gen_check_loop_end(DisasContext *dc, int slot)

{

    if (option_enabled(dc, XTENSA_OPTION_LOOP) &&

            !(dc->tb->flags & XTENSA_TBFLAG_EXCM) &&

            dc->next_pc == dc->lend) {

        int label = gen_new_label();

        gen_advance_ccount(dc);

        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);

        tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);

        gen_jumpi(dc, dc->lbeg, slot);

        gen_set_label(label);

        gen_jumpi(dc, dc->next_pc, -1);

        return true;

    }

    return false;

}


int i2c_send(I2CBus *bus, uint8_t data)

{

    I2CSlaveClass *sc;

    I2CNode *node;

    int ret = 0;

    QLIST_FOREACH(node, &bus->current_devs, next) {

        sc = I2C_SLAVE_GET_CLASS(node->elt);

        if (sc->send) {

            ret = ret || sc->send(node->elt, data);

        } else {

            ret = -1;

        }

    }

    return ret ? -1 : 0;

}


static int find_image_range(int *pfirst_index, int *plast_index,

                            const char *path, int start_index, int start_index_range)

{

    char buf[1024];

    int range, last_index, range1, first_index;

    /* find the first image */

    for (first_index = start_index; first_index < start_index + start_index_range; first_index++) {

        if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0) {

            *pfirst_index =

            *plast_index  = 1;

            if (avio_check(buf, AVIO_FLAG_READ) > 0)

                return 0;

            return -1;

        }

        if (avio_check(buf, AVIO_FLAG_READ) > 0)

            break;

    }

    if (first_index == start_index + start_index_range)

        goto fail;

    /* find the last image */

    last_index = first_index;

    for (;;) {

        range = 0;

        for (;;) {

            if (!range)

                range1 = 1;

            else

                range1 = 2 * range;

            if (av_get_frame_filename(buf, sizeof(buf), path,

                                      last_index + range1) < 0)

                goto fail;

            if (avio_check(buf, AVIO_FLAG_READ) <= 0)

                break;

            range = range1;

            /* just in case... */

            if (range >= (1 << 30))

                goto fail;

        }

        /* we are sure than image last_index + range exists */

        if (!range)

            break;

        last_index += range;

    }

    *pfirst_index = first_index;

    *plast_index  = last_index;

    return 0;

fail:

    return -1;

}


start_list(Visitor *v, const char *name, GenericList **list, size_t size,

           Error **errp)

{

    StringInputVisitor *siv = to_siv(v);

    /* We don't support visits without a list */

    assert(list);

    if (parse_str(siv, name, errp) < 0) {

        *list = NULL;

        return;

    }

    siv->cur_range = g_list_first(siv->ranges);

    if (siv->cur_range) {

        Range *r = siv->cur_range->data;

        if (r) {

            siv->cur = r->begin;

        }

        *list = g_malloc0(size);

    } else {

        *list = NULL;

    }

}


static int xio3130_downstream_initfn(PCIDevice *d)

{

    PCIBridge* br = DO_UPCAST(PCIBridge, dev, d);

    PCIEPort *p = DO_UPCAST(PCIEPort, br, br);

    PCIESlot *s = DO_UPCAST(PCIESlot, port, p);

    int rc;

    int tmp;

    rc = pci_bridge_initfn(d);

    if (rc < 0) {

        return rc;

    }

    pcie_port_init_reg(d);

    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_TI);

    pci_config_set_device_id(d->config, PCI_DEVICE_ID_TI_XIO3130D);

    d->config[PCI_REVISION_ID] = XIO3130_REVISION;

    rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,

                  XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,

                  XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT);

    if (rc < 0) {

        goto err_bridge;

    }

    rc = pci_bridge_ssvid_init(d, XIO3130_SSVID_OFFSET,

                               XIO3130_SSVID_SVID, XIO3130_SSVID_SSID);

    if (rc < 0) {

        goto err_bridge;

    }

    rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, PCI_EXP_TYPE_DOWNSTREAM,

                       p->port);

    if (rc < 0) {

        goto err_msi;

    }

    pcie_cap_flr_init(d);

    pcie_cap_deverr_init(d);

    pcie_cap_slot_init(d, s->slot);

    pcie_chassis_create(s->chassis);

    rc = pcie_chassis_add_slot(s);

    if (rc < 0) {

        goto err_pcie_cap;

    }

    pcie_cap_ari_init(d);

    rc = pcie_aer_init(d, XIO3130_AER_OFFSET);

    if (rc < 0) {

        goto err;

    }

    return 0;

err:

    pcie_chassis_del_slot(s);

err_pcie_cap:

    pcie_cap_exit(d);

err_msi:

    msi_uninit(d);

err_bridge:

    tmp = pci_bridge_exitfn(d);

    assert(!tmp);

    return rc;

}


void imx_timerg_create(const target_phys_addr_t addr,

                              qemu_irq irq,

                              DeviceState *ccm)

{

    IMXTimerGState *pp;

    DeviceState *dev;

    dev = sysbus_create_simple("imx_timerg", addr, irq);

    pp = container_of(dev, IMXTimerGState, busdev.qdev);

    pp->ccm = ccm;

}


static int mig_save_device_bulk(Monitor *mon, QEMUFile *f,

                                BlkMigDevState *bmds)

{

    int64_t total_sectors = bmds->total_sectors;

    int64_t cur_sector = bmds->cur_sector;

    BlockDriverState *bs = bmds->bs;

    BlkMigBlock *blk;

    int nr_sectors;

    if (bmds->shared_base) {

        while (cur_sector < total_sectors &&

               !bdrv_is_allocated(bs, cur_sector, MAX_IS_ALLOCATED_SEARCH,

                                  &nr_sectors)) {

            cur_sector += nr_sectors;

        }

    }

    if (cur_sector >= total_sectors) {

        bmds->cur_sector = bmds->completed_sectors = total_sectors;

        return 1;

    }

    bmds->completed_sectors = cur_sector;

    cur_sector &= ~((int64_t)BDRV_SECTORS_PER_DIRTY_CHUNK - 1);

    /* we are going to transfer a full block even if it is not allocated */

    nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK;

    if (total_sectors - cur_sector < BDRV_SECTORS_PER_DIRTY_CHUNK) {

        nr_sectors = total_sectors - cur_sector;

    }

    blk = g_malloc(sizeof(BlkMigBlock));

    blk->buf = g_malloc(BLOCK_SIZE);

    blk->bmds = bmds;

    blk->sector = cur_sector;

    blk->nr_sectors = nr_sectors;

    blk->iov.iov_base = blk->buf;

    blk->iov.iov_len = nr_sectors * BDRV_SECTOR_SIZE;

    qemu_iovec_init_external(&blk->qiov, &blk->iov, 1);

    if (block_mig_state.submitted == 0) {

        block_mig_state.prev_time_offset = qemu_get_clock_ns(rt_clock);

    }

    blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov,

                                nr_sectors, blk_mig_read_cb, blk);

    block_mig_state.submitted++;

    bdrv_reset_dirty(bs, cur_sector, nr_sectors);

    bmds->cur_sector = cur_sector + nr_sectors;

    return (bmds->cur_sector >= total_sectors);

}


int64_t qemu_clock_get_ns(QEMUClockType type)

{

    int64_t now, last;

    QEMUClock *clock = qemu_clock_ptr(type);

    switch (type) {

    case QEMU_CLOCK_REALTIME:

        return get_clock();

    default:

    case QEMU_CLOCK_VIRTUAL:

        if (use_icount) {

            return cpu_get_icount();

        } else {

            return cpu_get_clock();

        }

    case QEMU_CLOCK_HOST:

        now = get_clock_realtime();

        last = clock->last;

        clock->last = now;

        if (now < last) {

            notifier_list_notify(&clock->reset_notifiers, &now);

        }

        return now;

    case QEMU_CLOCK_VIRTUAL_RT:

        return cpu_get_clock();

    }

}


static void test_acpi_q35_tcg_cphp(void)

{

    test_data data;

    memset(&data, 0, sizeof(data));

    data.machine = MACHINE_Q35;

    data.variant = ".cphp";

    test_acpi_one(" -smp 2,cores=3,sockets=2,maxcpus=6"

                  " -numa node -numa node",

                  &data);

    free_test_data(&data);

}


int block_job_set_speed(BlockJob *job, int64_t value)

{

    int rc;

    if (!job->job_type->set_speed) {

        return -ENOTSUP;

    }

    rc = job->job_type->set_speed(job, value);

    if (rc == 0) {

        job->speed = value;

    }

    return rc;

}


static void test_acpi_q35_tcg_memhp(void)

{

    test_data data;

    memset(&data, 0, sizeof(data));

    data.machine = MACHINE_Q35;

    data.variant = ".memhp";

    test_acpi_one(" -m 128,slots=3,maxmem=1G -numa node", &data);

    free_test_data(&data);

}


void pci_bus_reset(PCIBus *bus)

{

    int i;

    for (i = 0; i < bus->nirq; i++) {

        bus->irq_count[i] = 0;

    }

    for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {

        if (bus->devices[i]) {

            pci_device_reset(bus->devices[i]);

        }

    }

}


static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)

{

    bool is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;

    if (is_cap && qmp_cmd_mode(mon)) {

        qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,

                      "Capabilities negotiation is already complete, command "

                      "'%s' ignored", cmd->name);

        return true;

    }

    if (!is_cap && !qmp_cmd_mode(mon)) {

        qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,

                      "Expecting capabilities negotiation with "

                      "'qmp_capabilities' before command '%s'", cmd->name);

        return true;

    }

    return false;

}


static int encode_ext_header(Wmv2Context *w){

    MpegEncContext * const s= &w->s;

    PutBitContext pb;

    int code;

    init_put_bits(&pb, s->avctx->extradata, s->avctx->extradata_size);

    put_bits(&pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); //yes 29.97 -> 29

    put_bits(&pb, 11, FFMIN(s->bit_rate/1024, 2047));

    put_bits(&pb, 1, w->mspel_bit=1);

    put_bits(&pb, 1, w->flag3=1);

    put_bits(&pb, 1, w->abt_flag=1);

    put_bits(&pb, 1, w->j_type_bit=1);

    put_bits(&pb, 1, w->top_left_mv_flag=0);

    put_bits(&pb, 1, w->per_mb_rl_bit=1);

    put_bits(&pb, 3, code=1);

    flush_put_bits(&pb);

    s->slice_height = s->mb_height / code;

    return 0;

}


static int sd_schedule_bh(QEMUBHFunc *cb, SheepdogAIOCB *acb)

{

    if (acb->bh) {

        error_report("bug: %d %d\n", acb->aiocb_type, acb->aiocb_type);

        return -EIO;

    }

    acb->bh = qemu_bh_new(cb, acb);

    if (!acb->bh) {

        error_report("oom: %d %d\n", acb->aiocb_type, acb->aiocb_type);

        return -EIO;

    }

    qemu_bh_schedule(acb->bh);

    return 0;

}


static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,

                          UHCI_TD *td, uint32_t td_addr, uint32_t *int_mask)

{

    int len = 0, max_len;

    bool spd;

    bool queuing = (q != NULL);

    uint8_t pid = td->token & 0xff;

    UHCIAsync *async = uhci_async_find_td(s, td_addr);

    if (async) {

        if (uhci_queue_verify(async->queue, qh_addr, td, td_addr, queuing)) {

            assert(q == NULL || q == async->queue);

            q = async->queue;

        } else {

            uhci_queue_free(async->queue, "guest re-used pending td");

            async = NULL;

        }

    }

    if (q == NULL) {

        q = uhci_queue_find(s, td);

        if (q && !uhci_queue_verify(q, qh_addr, td, td_addr, queuing)) {

            uhci_queue_free(q, "guest re-used qh");

            q = NULL;

        }

    }

    if (q) {

        q->valid = 32;

    }

    /* Is active ? */

    if (!(td->ctrl & TD_CTRL_ACTIVE)) {

        if (async) {

            /* Guest marked a pending td non-active, cancel the queue */

            uhci_queue_free(async->queue, "pending td non-active");

        }

        /*

         * ehci11d spec page 22: "Even if the Active bit in the TD is already

         * cleared when the TD is fetched ... an IOC interrupt is generated"

         */

        if (td->ctrl & TD_CTRL_IOC) {

                *int_mask |= 0x01;

        }

        return TD_RESULT_NEXT_QH;

    }

    if (async) {

        if (!async->done)

            return TD_RESULT_ASYNC_CONT;

        if (queuing) {

            /* we are busy filling the queue, we are not prepared

               to consume completed packages then, just leave them

               in async state */

            return TD_RESULT_ASYNC_CONT;

        }

        uhci_async_unlink(async);

        goto done;

    }

    /* Allocate new packet */

    if (q == NULL) {

        USBDevice *dev = uhci_find_device(s, (td->token >> 8) & 0x7f);

        USBEndpoint *ep = usb_ep_get(dev, pid, (td->token >> 15) & 0xf);

        q = uhci_queue_new(s, qh_addr, td, ep);

    }

    async = uhci_async_alloc(q, td_addr);

    max_len = ((td->token >> 21) + 1) & 0x7ff;

    spd = (pid == USB_TOKEN_IN && (td->ctrl & TD_CTRL_SPD) != 0);

    usb_packet_setup(&async->packet, pid, q->ep, td_addr, spd,

                     (td->ctrl & TD_CTRL_IOC) != 0);

    qemu_sglist_add(&async->sgl, td->buffer, max_len);

    usb_packet_map(&async->packet, &async->sgl);

    switch(pid) {

    case USB_TOKEN_OUT:

    case USB_TOKEN_SETUP:

        len = usb_handle_packet(q->ep->dev, &async->packet);

        if (len >= 0)

            len = max_len;

        break;

    case USB_TOKEN_IN:

        len = usb_handle_packet(q->ep->dev, &async->packet);

        break;

    default:

        /* invalid pid : frame interrupted */

        usb_packet_unmap(&async->packet, &async->sgl);

        uhci_async_free(async);

        s->status |= UHCI_STS_HCPERR;

        uhci_update_irq(s);

        return TD_RESULT_STOP_FRAME;

    }

    if (len == USB_RET_ASYNC) {

        uhci_async_link(async);

        if (!queuing) {

            uhci_queue_fill(q, td);

        }

        return TD_RESULT_ASYNC_START;

    }

    async->packet.result = len;

done:

    len = uhci_complete_td(s, td, async, int_mask);

    usb_packet_unmap(&async->packet, &async->sgl);

    uhci_async_free(async);

    return len;

}


static int ccid_handle_data(USBDevice *dev, USBPacket *p)

{

    USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev);

    int ret = 0;

    uint8_t buf[2];

    switch (p->pid) {

    case USB_TOKEN_OUT:

        ret = ccid_handle_bulk_out(s, p);

        break;

    case USB_TOKEN_IN:

        switch (p->devep & 0xf) {

        case CCID_BULK_IN_EP:

            if (!p->iov.size) {

                ret = USB_RET_NAK;

            } else {

                ret = ccid_bulk_in_copy_to_guest(s, p);

            }

            break;

        case CCID_INT_IN_EP:

            if (s->notify_slot_change) {

                /* page 56, RDR_to_PC_NotifySlotChange */

                buf[0] = CCID_MESSAGE_TYPE_RDR_to_PC_NotifySlotChange;

                buf[1] = s->bmSlotICCState;

                usb_packet_copy(p, buf, 2);

                ret = 2;

                s->notify_slot_change = false;

                s->bmSlotICCState &= ~SLOT_0_CHANGED_MASK;

                DPRINTF(s, D_INFO,

                        "handle_data: int_in: notify_slot_change %X, "

                        "requested len %zd\n",

                        s->bmSlotICCState, p->iov.size);

            }

            break;

        default:

            DPRINTF(s, 1, "Bad endpoint\n");

            ret = USB_RET_STALL;

            break;

        }

        break;

    default:

        DPRINTF(s, 1, "Bad token\n");

        ret = USB_RET_STALL;

        break;

    }

    return ret;

}


char *g_strconcat(const char *s, ...)

{

    char *s;

    /*

     * Can't model: last argument must be null, the others

     * null-terminated strings

     */

    s = __coverity_alloc_nosize__();

    __coverity_writeall__(s);

    __coverity_mark_as_afm_allocated__(s, AFM_free);

    return s;

}


static void test_qemu_strtoul_max(void)

{

    char *str = g_strdup_printf("%lu", ULONG_MAX);

    char f = 'X';

    const char *endptr = &f;

    unsigned long res = 999;

    int err;

    err = qemu_strtoul(str, &endptr, 0, &res);

    g_assert_cmpint(err, ==, 0);

    g_assert_cmpint(res, ==, ULONG_MAX);

    g_assert(endptr == str + strlen(str));

    g_free(str);

}


static int coroutine_enter_func(void *arg)

{

    Coroutine *co = arg;

    qemu_coroutine_enter(co, NULL);

    return 0;

}


START_TEST(qdict_new_test)

{

    QDict *qdict;

    qdict = qdict_new();

    fail_unless(qdict != NULL);

    fail_unless(qdict_size(qdict) == 0);

    fail_unless(qdict->base.refcnt == 1);

    fail_unless(qobject_type(QOBJECT(qdict)) == QTYPE_QDICT);

    // destroy doesn't exit yet

    free(qdict);

}


int print_insn_xtensa(bfd_vma memaddr, struct disassemble_info *info)

{

    xtensa_isa isa = info->private_data;

    xtensa_insnbuf insnbuf = xtensa_insnbuf_alloc(isa);

    xtensa_insnbuf slotbuf = xtensa_insnbuf_alloc(isa);

    bfd_byte *buffer = g_malloc(1);

    int status = info->read_memory_func(memaddr, buffer, 1, info);

    xtensa_format fmt;

    unsigned slot, slots;

    unsigned len;

    if (status) {

        info->memory_error_func(status, memaddr, info);

        len = -1;

        goto out;

    }

    len = xtensa_isa_length_from_chars(isa, buffer);

    if (len == XTENSA_UNDEFINED) {

        info->fprintf_func(info->stream, ".byte 0x%02x", buffer[0]);

        len = 1;

        goto out;

    }

    buffer = g_realloc(buffer, len);

    status = info->read_memory_func(memaddr + 1, buffer + 1, len - 1, info);

    if (status) {

        info->fprintf_func(info->stream, ".byte 0x%02x", buffer[0]);

        info->memory_error_func(status, memaddr + 1, info);

        len = 1;

        goto out;

    }

    xtensa_insnbuf_from_chars(isa, insnbuf, buffer, len);

    fmt = xtensa_format_decode(isa, insnbuf);

    if (fmt == XTENSA_UNDEFINED) {

        unsigned i;

        for (i = 0; i < len; ++i) {

            info->fprintf_func(info->stream, "%s 0x%02x",

                               i ? ", " : ".byte ", buffer[i]);

        }

        goto out;

    }

    slots = xtensa_format_num_slots(isa, fmt);

    if (slots > 1) {

        info->fprintf_func(info->stream, "{ ");

    }

    for (slot = 0; slot < slots; ++slot) {

        xtensa_opcode opc;

        unsigned opnd, vopnd, opnds;

        if (slot) {

            info->fprintf_func(info->stream, "; ");

        }

        xtensa_format_get_slot(isa, fmt, slot, insnbuf, slotbuf);

        opc = xtensa_opcode_decode(isa, fmt, slot, slotbuf);

        if (opc == XTENSA_UNDEFINED) {

            info->fprintf_func(info->stream, "???");

            continue;

        }

        opnds = xtensa_opcode_num_operands(isa, opc);

        info->fprintf_func(info->stream, "%s", xtensa_opcode_name(isa, opc));

        for (opnd = vopnd = 0; opnd < opnds; ++opnd) {

            if (xtensa_operand_is_visible(isa, opc, opnd)) {

                uint32_t v = 0xbadc0de;

                int rc;

                info->fprintf_func(info->stream, vopnd ? ", " : "\t");

                xtensa_operand_get_field(isa, opc, opnd, fmt, slot,

                                         slotbuf, &v);

                rc = xtensa_operand_decode(isa, opc, opnd, &v);

                if (rc == XTENSA_UNDEFINED) {

                    info->fprintf_func(info->stream, "???");

                } else if (xtensa_operand_is_register(isa, opc, opnd)) {

                    xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd);

                    info->fprintf_func(info->stream, "%s%d",

                                       xtensa_regfile_shortname(isa, rf), v);

                } else if (xtensa_operand_is_PCrelative(isa, opc, opnd)) {

                    xtensa_operand_undo_reloc(isa, opc, opnd, &v, memaddr);

                    info->fprintf_func(info->stream, "0x%x", v);

                } else {

                    info->fprintf_func(info->stream, "%d", v);

                }

                ++vopnd;

            }

        }

    }

    if (slots > 1) {

        info->fprintf_func(info->stream, " }");

    }

out:

    g_free(buffer);

    xtensa_insnbuf_free(isa, insnbuf);

    xtensa_insnbuf_free(isa, slotbuf);

    return len;

}


char *qemu_strdup(const char *str)

{

    char *ptr;

    size_t len = strlen(str);

    ptr = qemu_malloc(len + 1);

    if (!ptr)

        return NULL;

    pstrcpy(ptr, len + 1, str);

    return ptr;

}


static inline void flash_sync_area(Flash *s, int64_t off, int64_t len)

{

    int64_t start, end, nb_sectors;

    QEMUIOVector iov;

    if (!s->bdrv || bdrv_is_read_only(s->bdrv)) {

        return;

    }

    assert(!(len % BDRV_SECTOR_SIZE));

    start = off / BDRV_SECTOR_SIZE;

    end = (off + len) / BDRV_SECTOR_SIZE;

    nb_sectors = end - start;

    qemu_iovec_init(&iov, 1);

    qemu_iovec_add(&iov, s->storage + (start * BDRV_SECTOR_SIZE),

                                        nb_sectors * BDRV_SECTOR_SIZE);

    bdrv_aio_writev(s->bdrv, start, &iov, nb_sectors, bdrv_sync_complete, NULL);

}


static ssize_t test_block_read_func(QCryptoBlock *block,

                                    size_t offset,

                                    uint8_t *buf,

                                    size_t buflen,

                                    Error **errp,

                                    void *opaque)

{

    Buffer *header = opaque;

    g_assert_cmpint(offset + buflen, <=, header->capacity);

    memcpy(buf, header->buffer + offset, buflen);

    return buflen;

}


static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,

                                    uint16_t insn_hw1)

{

    int32_t offset;

    uint16_t insn;

    int rt, rs, rd, rr;

    int16_t imm;

    uint32_t op, minor, mips32_op;

    uint32_t cond, fmt, cc;

    insn = cpu_lduw_code(env, ctx->pc + 2);

    ctx->opcode = (ctx->opcode << 16) | insn;

    rt = (ctx->opcode >> 21) & 0x1f;

    rs = (ctx->opcode >> 16) & 0x1f;

    rd = (ctx->opcode >> 11) & 0x1f;

    rr = (ctx->opcode >> 6) & 0x1f;

    imm = (int16_t) ctx->opcode;

    op = (ctx->opcode >> 26) & 0x3f;

    switch (op) {

    case POOL32A:

        minor = ctx->opcode & 0x3f;

        switch (minor) {

        case 0x00:

            minor = (ctx->opcode >> 6) & 0xf;

            switch (minor) {

            case SLL32:

                mips32_op = OPC_SLL;

                goto do_shifti;

            case SRA:

                mips32_op = OPC_SRA;

                goto do_shifti;

            case SRL32:

                mips32_op = OPC_SRL;

                goto do_shifti;

            case ROTR:

                mips32_op = OPC_ROTR;

            do_shifti:

                gen_shift_imm(ctx, mips32_op, rt, rs, rd);

                break;

            default:

                goto pool32a_invalid;

            }

            break;

        case 0x10:

            minor = (ctx->opcode >> 6) & 0xf;

            switch (minor) {

                /* Arithmetic */

            case ADD:

                mips32_op = OPC_ADD;

                goto do_arith;

            case ADDU32:

                mips32_op = OPC_ADDU;

                goto do_arith;

            case SUB:

                mips32_op = OPC_SUB;

                goto do_arith;

            case SUBU32:

                mips32_op = OPC_SUBU;

                goto do_arith;

            case MUL:

                mips32_op = OPC_MUL;

            do_arith:

                gen_arith(ctx, mips32_op, rd, rs, rt);

                break;

                /* Shifts */

            case SLLV:

                mips32_op = OPC_SLLV;

                goto do_shift;

            case SRLV:

                mips32_op = OPC_SRLV;

                goto do_shift;

            case SRAV:

                mips32_op = OPC_SRAV;

                goto do_shift;

            case ROTRV:

                mips32_op = OPC_ROTRV;

            do_shift:

                gen_shift(ctx, mips32_op, rd, rs, rt);

                break;

                /* Logical operations */

            case AND:

                mips32_op = OPC_AND;

                goto do_logic;

            case OR32:

                mips32_op = OPC_OR;

                goto do_logic;

            case NOR:

                mips32_op = OPC_NOR;

                goto do_logic;

            case XOR32:

                mips32_op = OPC_XOR;

            do_logic:

                gen_logic(ctx, mips32_op, rd, rs, rt);

                break;

                /* Set less than */

            case SLT:

                mips32_op = OPC_SLT;

                goto do_slt;

            case SLTU:

                mips32_op = OPC_SLTU;

            do_slt:

                gen_slt(ctx, mips32_op, rd, rs, rt);

                break;

            default:

                goto pool32a_invalid;

            }

            break;

        case 0x18:

            minor = (ctx->opcode >> 6) & 0xf;

            switch (minor) {

                /* Conditional moves */

            case MOVN:

                mips32_op = OPC_MOVN;

                goto do_cmov;

            case MOVZ:

                mips32_op = OPC_MOVZ;

            do_cmov:

                gen_cond_move(ctx, mips32_op, rd, rs, rt);

                break;

            case LWXS:

                gen_ldxs(ctx, rs, rt, rd);

                break;

            default:

                goto pool32a_invalid;

            }

            break;

        case INS:

            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);

            return;

        case EXT:

            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);

            return;

        case POOL32AXF:

            gen_pool32axf(env, ctx, rt, rs);

            break;

        case 0x07:

            generate_exception(ctx, EXCP_BREAK);

            break;

        default:

        pool32a_invalid:

                MIPS_INVAL("pool32a");

                generate_exception(ctx, EXCP_RI);

                break;

        }

        break;

    case POOL32B:

        minor = (ctx->opcode >> 12) & 0xf;

        switch (minor) {

        case CACHE:

            check_cp0_enabled(ctx);

            /* Treat as no-op. */

            break;

        case LWC2:

        case SWC2:

            /* COP2: Not implemented. */

            generate_exception_err(ctx, EXCP_CpU, 2);

            break;

        case LWP:

        case SWP:

#ifdef TARGET_MIPS64

        case LDP:

        case SDP:

#endif

            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));

            break;

        case LWM32:

        case SWM32:

#ifdef TARGET_MIPS64

        case LDM:

        case SDM:

#endif

            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));

            break;

        default:

            MIPS_INVAL("pool32b");

            generate_exception(ctx, EXCP_RI);

            break;

        }

        break;

    case POOL32F:

        if (env->CP0_Config1 & (1 << CP0C1_FP)) {

            minor = ctx->opcode & 0x3f;

            check_cp1_enabled(ctx);

            switch (minor) {

            case ALNV_PS:

                mips32_op = OPC_ALNV_PS;

                goto do_madd;

            case MADD_S:

                mips32_op = OPC_MADD_S;

                goto do_madd;

            case MADD_D:

                mips32_op = OPC_MADD_D;

                goto do_madd;

            case MADD_PS:

                mips32_op = OPC_MADD_PS;

                goto do_madd;

            case MSUB_S:

                mips32_op = OPC_MSUB_S;

                goto do_madd;

            case MSUB_D:

                mips32_op = OPC_MSUB_D;

                goto do_madd;

            case MSUB_PS:

                mips32_op = OPC_MSUB_PS;

                goto do_madd;

            case NMADD_S:

                mips32_op = OPC_NMADD_S;

                goto do_madd;

            case NMADD_D:

                mips32_op = OPC_NMADD_D;

                goto do_madd;

            case NMADD_PS:

                mips32_op = OPC_NMADD_PS;

                goto do_madd;

            case NMSUB_S:

                mips32_op = OPC_NMSUB_S;

                goto do_madd;

            case NMSUB_D:

                mips32_op = OPC_NMSUB_D;

                goto do_madd;

            case NMSUB_PS:

                mips32_op = OPC_NMSUB_PS;

            do_madd:

                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);

                break;

            case CABS_COND_FMT:

                cond = (ctx->opcode >> 6) & 0xf;

                cc = (ctx->opcode >> 13) & 0x7;

                fmt = (ctx->opcode >> 10) & 0x3;

                switch (fmt) {

                case 0x0:

                    gen_cmpabs_s(ctx, cond, rt, rs, cc);

                    break;

                case 0x1:

                    gen_cmpabs_d(ctx, cond, rt, rs, cc);

                    break;

                case 0x2:

                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

            case C_COND_FMT:

                cond = (ctx->opcode >> 6) & 0xf;

                cc = (ctx->opcode >> 13) & 0x7;

                fmt = (ctx->opcode >> 10) & 0x3;

                switch (fmt) {

                case 0x0:

                    gen_cmp_s(ctx, cond, rt, rs, cc);

                    break;

                case 0x1:

                    gen_cmp_d(ctx, cond, rt, rs, cc);

                    break;

                case 0x2:

                    gen_cmp_ps(ctx, cond, rt, rs, cc);

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

            case POOL32FXF:

                gen_pool32fxf(ctx, rt, rs);

                break;

            case 0x00:

                /* PLL foo */

                switch ((ctx->opcode >> 6) & 0x7) {

                case PLL_PS:

                    mips32_op = OPC_PLL_PS;

                    goto do_ps;

                case PLU_PS:

                    mips32_op = OPC_PLU_PS;

                    goto do_ps;

                case PUL_PS:

                    mips32_op = OPC_PUL_PS;

                    goto do_ps;

                case PUU_PS:

                    mips32_op = OPC_PUU_PS;

                    goto do_ps;

                case CVT_PS_S:

                    mips32_op = OPC_CVT_PS_S;

                do_ps:

                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

            case 0x08:

                /* [LS][WDU]XC1 */

                switch ((ctx->opcode >> 6) & 0x7) {

                case LWXC1:

                    mips32_op = OPC_LWXC1;

                    goto do_ldst_cp1;

                case SWXC1:

                    mips32_op = OPC_SWXC1;

                    goto do_ldst_cp1;

                case LDXC1:

                    mips32_op = OPC_LDXC1;

                    goto do_ldst_cp1;

                case SDXC1:

                    mips32_op = OPC_SDXC1;

                    goto do_ldst_cp1;

                case LUXC1:

                    mips32_op = OPC_LUXC1;

                    goto do_ldst_cp1;

                case SUXC1:

                    mips32_op = OPC_SUXC1;

                do_ldst_cp1:

                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

            case 0x18:

                /* 3D insns */

                fmt = (ctx->opcode >> 9) & 0x3;

                switch ((ctx->opcode >> 6) & 0x7) {

                case RSQRT2_FMT:

                    switch (fmt) {

                    case FMT_SDPS_S:

                        mips32_op = OPC_RSQRT2_S;

                        goto do_3d;

                    case FMT_SDPS_D:

                        mips32_op = OPC_RSQRT2_D;

                        goto do_3d;

                    case FMT_SDPS_PS:

                        mips32_op = OPC_RSQRT2_PS;

                        goto do_3d;

                    default:

                        goto pool32f_invalid;

                    }

                    break;

                case RECIP2_FMT:

                    switch (fmt) {

                    case FMT_SDPS_S:

                        mips32_op = OPC_RECIP2_S;

                        goto do_3d;

                    case FMT_SDPS_D:

                        mips32_op = OPC_RECIP2_D;

                        goto do_3d;

                    case FMT_SDPS_PS:

                        mips32_op = OPC_RECIP2_PS;

                        goto do_3d;

                    default:

                        goto pool32f_invalid;

                    }

                    break;

                case ADDR_PS:

                    mips32_op = OPC_ADDR_PS;

                    goto do_3d;

                case MULR_PS:

                    mips32_op = OPC_MULR_PS;

                do_3d:

                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

            case 0x20:

                /* MOV[FT].fmt and PREFX */

                cc = (ctx->opcode >> 13) & 0x7;

                fmt = (ctx->opcode >> 9) & 0x3;

                switch ((ctx->opcode >> 6) & 0x7) {

                case MOVF_FMT:

                    switch (fmt) {

                    case FMT_SDPS_S:

                        gen_movcf_s(rs, rt, cc, 0);

                        break;

                    case FMT_SDPS_D:

                        gen_movcf_d(ctx, rs, rt, cc, 0);

                        break;

                    case FMT_SDPS_PS:

                        gen_movcf_ps(rs, rt, cc, 0);

                        break;

                    default:

                        goto pool32f_invalid;

                    }

                    break;

                case MOVT_FMT:

                    switch (fmt) {

                    case FMT_SDPS_S:

                        gen_movcf_s(rs, rt, cc, 1);

                        break;

                    case FMT_SDPS_D:

                        gen_movcf_d(ctx, rs, rt, cc, 1);

                        break;

                    case FMT_SDPS_PS:

                        gen_movcf_ps(rs, rt, cc, 1);

                        break;

                    default:

                        goto pool32f_invalid;

                    }

                    break;

                case PREFX:

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

#define FINSN_3ARG_SDPS(prfx)                           \

                switch ((ctx->opcode >> 8) & 0x3) {     \

                case FMT_SDPS_S:                        \

                    mips32_op = OPC_##prfx##_S;         \

                    goto do_fpop;                       \

                case FMT_SDPS_D:                        \

                    mips32_op = OPC_##prfx##_D;         \

                    goto do_fpop;                       \

                case FMT_SDPS_PS:                       \

                    mips32_op = OPC_##prfx##_PS;        \

                    goto do_fpop;                       \

                default:                                \

                    goto pool32f_invalid;               \

                }

            case 0x30:

                /* regular FP ops */

                switch ((ctx->opcode >> 6) & 0x3) {

                case ADD_FMT:

                    FINSN_3ARG_SDPS(ADD);

                    break;

                case SUB_FMT:

                    FINSN_3ARG_SDPS(SUB);

                    break;

                case MUL_FMT:

                    FINSN_3ARG_SDPS(MUL);

                    break;

                case DIV_FMT:

                    fmt = (ctx->opcode >> 8) & 0x3;

                    if (fmt == 1) {

                        mips32_op = OPC_DIV_D;

                    } else if (fmt == 0) {

                        mips32_op = OPC_DIV_S;

                    } else {

                        goto pool32f_invalid;

                    }

                    goto do_fpop;

                default:

                    goto pool32f_invalid;

                }

                break;

            case 0x38:

                /* cmovs */

                switch ((ctx->opcode >> 6) & 0x3) {

                case MOVN_FMT:

                    FINSN_3ARG_SDPS(MOVN);

                    break;

                case MOVZ_FMT:

                    FINSN_3ARG_SDPS(MOVZ);

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

            do_fpop:

                gen_farith(ctx, mips32_op, rt, rs, rd, 0);

                break;

            default:

            pool32f_invalid:

                MIPS_INVAL("pool32f");

                generate_exception(ctx, EXCP_RI);

                break;

            }

        } else {

            generate_exception_err(ctx, EXCP_CpU, 1);

        }

        break;

    case POOL32I:

        minor = (ctx->opcode >> 21) & 0x1f;

        switch (minor) {

        case BLTZ:

            mips32_op = OPC_BLTZ;

            goto do_branch;

        case BLTZAL:

            mips32_op = OPC_BLTZAL;

            goto do_branch;

        case BLTZALS:

            mips32_op = OPC_BLTZALS;

            goto do_branch;

        case BGEZ:

            mips32_op = OPC_BGEZ;

            goto do_branch;

        case BGEZAL:

            mips32_op = OPC_BGEZAL;

            goto do_branch;

        case BGEZALS:

            mips32_op = OPC_BGEZALS;

            goto do_branch;

        case BLEZ:

            mips32_op = OPC_BLEZ;

            goto do_branch;

        case BGTZ:

            mips32_op = OPC_BGTZ;

        do_branch:

            gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);

            break;

            /* Traps */

        case TLTI:

            mips32_op = OPC_TLTI;

            goto do_trapi;

        case TGEI:

            mips32_op = OPC_TGEI;

            goto do_trapi;

        case TLTIU:

            mips32_op = OPC_TLTIU;

            goto do_trapi;

        case TGEIU:

            mips32_op = OPC_TGEIU;

            goto do_trapi;

        case TNEI:

            mips32_op = OPC_TNEI;

            goto do_trapi;

        case TEQI:

            mips32_op = OPC_TEQI;

        do_trapi:

            gen_trap(ctx, mips32_op, rs, -1, imm);

            break;

        case BNEZC:

        case BEQZC:

            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,

                               4, rs, 0, imm << 1);

            /* Compact branches don't have a delay slot, so just let

               the normal delay slot handling take us to the branch

               target. */

            break;

        case LUI:

            gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);

            break;

        case SYNCI:

            break;

        case BC2F:

        case BC2T:

            /* COP2: Not implemented. */

            generate_exception_err(ctx, EXCP_CpU, 2);

            break;

        case BC1F:

            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;

            goto do_cp1branch;

        case BC1T:

            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;

            goto do_cp1branch;

        case BC1ANY4F:

            mips32_op = OPC_BC1FANY4;

            goto do_cp1mips3d;

        case BC1ANY4T:

            mips32_op = OPC_BC1TANY4;

        do_cp1mips3d:

            check_cop1x(ctx);

            check_insn(ctx, ASE_MIPS3D);

            /* Fall through */

        do_cp1branch:

            gen_compute_branch1(ctx, mips32_op,

                                (ctx->opcode >> 18) & 0x7, imm << 1);

            break;

        case BPOSGE64:

        case BPOSGE32:

            /* MIPS DSP: not implemented */

            /* Fall through */

        default:

            MIPS_INVAL("pool32i");

            generate_exception(ctx, EXCP_RI);

            break;

        }

        break;

    case POOL32C:

        minor = (ctx->opcode >> 12) & 0xf;

        switch (minor) {

        case LWL:

            mips32_op = OPC_LWL;

            goto do_ld_lr;

        case SWL:

            mips32_op = OPC_SWL;

            goto do_st_lr;

        case LWR:

            mips32_op = OPC_LWR;

            goto do_ld_lr;

        case SWR:

            mips32_op = OPC_SWR;

            goto do_st_lr;

#if defined(TARGET_MIPS64)

        case LDL:

            mips32_op = OPC_LDL;

            goto do_ld_lr;

        case SDL:

            mips32_op = OPC_SDL;

            goto do_st_lr;

        case LDR:

            mips32_op = OPC_LDR;

            goto do_ld_lr;

        case SDR:

            mips32_op = OPC_SDR;

            goto do_st_lr;

        case LWU:

            mips32_op = OPC_LWU;

            goto do_ld_lr;

        case LLD:

            mips32_op = OPC_LLD;

            goto do_ld_lr;

#endif

        case LL:

            mips32_op = OPC_LL;

            goto do_ld_lr;

        do_ld_lr:

            gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));

            break;

        do_st_lr:

            gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));

            break;

        case SC:

            gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));

            break;

#if defined(TARGET_MIPS64)

        case SCD:

            gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));

            break;

#endif

        case PREF:

            /* Treat as no-op */

            break;

        default:

            MIPS_INVAL("pool32c");

            generate_exception(ctx, EXCP_RI);

            break;

        }

        break;

    case ADDI32:

        mips32_op = OPC_ADDI;

        goto do_addi;

    case ADDIU32:

        mips32_op = OPC_ADDIU;

    do_addi:

        gen_arith_imm(ctx, mips32_op, rt, rs, imm);

        break;

        /* Logical operations */

    case ORI32:

        mips32_op = OPC_ORI;

        goto do_logici;

    case XORI32:

        mips32_op = OPC_XORI;

        goto do_logici;

    case ANDI32:

        mips32_op = OPC_ANDI;

    do_logici:

        gen_logic_imm(ctx, mips32_op, rt, rs, imm);

        break;

        /* Set less than immediate */

    case SLTI32:

        mips32_op = OPC_SLTI;

        goto do_slti;

    case SLTIU32:

        mips32_op = OPC_SLTIU;

    do_slti:

        gen_slt_imm(ctx, mips32_op, rt, rs, imm);

        break;

    case JALX32:

        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;

        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);

        break;

    case JALS32:

        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;

        gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);

        break;

    case BEQ32:

        gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);

        break;

    case BNE32:

        gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);

        break;

    case J32:

        gen_compute_branch(ctx, OPC_J, 4, rt, rs,

                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);

        break;

    case JAL32:

        gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,

                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);

        break;

        /* Floating point (COP1) */

    case LWC132:

        mips32_op = OPC_LWC1;

        goto do_cop1;

    case LDC132:

        mips32_op = OPC_LDC1;

        goto do_cop1;

    case SWC132:

        mips32_op = OPC_SWC1;

        goto do_cop1;

    case SDC132:

        mips32_op = OPC_SDC1;

    do_cop1:

        gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);

        break;

    case ADDIUPC:

        {

            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));

            int offset = SIMM(ctx->opcode, 0, 23) << 2;

            gen_addiupc(ctx, reg, offset, 0, 0);

        }

        break;

        /* Loads and stores */

    case LB32:

        mips32_op = OPC_LB;

        goto do_ld;

    case LBU32:

        mips32_op = OPC_LBU;

        goto do_ld;

    case LH32:

        mips32_op = OPC_LH;

        goto do_ld;

    case LHU32:

        mips32_op = OPC_LHU;

        goto do_ld;

    case LW32:

        mips32_op = OPC_LW;

        goto do_ld;

#ifdef TARGET_MIPS64

    case LD32:

        mips32_op = OPC_LD;

        goto do_ld;

    case SD32:

        mips32_op = OPC_SD;

        goto do_st;

#endif

    case SB32:

        mips32_op = OPC_SB;

        goto do_st;

    case SH32:

        mips32_op = OPC_SH;

        goto do_st;

    case SW32:

        mips32_op = OPC_SW;

        goto do_st;

    do_ld:

        gen_ld(ctx, mips32_op, rt, rs, imm);

        break;

    do_st:

        gen_st(ctx, mips32_op, rt, rs, imm);

        break;

    default:

        generate_exception(ctx, EXCP_RI);

        break;

    }

}


static void test_qga_guest_exec(gconstpointer fix)

{

    const TestFixture *fixture = fix;

    QDict *ret, *val;

    const gchar *out;

    guchar *decoded;

    int64_t pid, now, exitcode;

    gsize len;

    bool exited;

    /* exec 'echo foo bar' */

    ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"

                 " 'path': '/bin/echo', 'arg': [ '-n', '\" test_str \"' ],"

                 " 'capture-output': true } }");

    g_assert_nonnull(ret);

    qmp_assert_no_error(ret);

    val = qdict_get_qdict(ret, "return");

    pid = qdict_get_int(val, "pid");

    g_assert_cmpint(pid, >, 0);

    QDECREF(ret);

    /* wait for completion */

    now = g_get_monotonic_time();

    do {

        ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec-status',"

                     " 'arguments': { 'pid': %" PRId64 "  } }", pid);

        g_assert_nonnull(ret);

        val = qdict_get_qdict(ret, "return");

        exited = qdict_get_bool(val, "exited");

        if (!exited) {

            QDECREF(ret);

        }

    } while (!exited &&

             g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND);

    g_assert(exited);

    /* check stdout */

    exitcode = qdict_get_int(val, "exitcode");

    g_assert_cmpint(exitcode, ==, 0);

    out = qdict_get_str(val, "out-data");

    decoded = g_base64_decode(out, &len);

    g_assert_cmpint(len, ==, 12);

    g_assert_cmpstr((char *)decoded, ==, "\" test_str \"");

    g_free(decoded);

    QDECREF(ret);

}


static void vtd_do_iommu_translate(VTDAddressSpace *vtd_as, uint8_t bus_num,

                                   uint8_t devfn, hwaddr addr, bool is_write,

                                   IOMMUTLBEntry *entry)

{

    IntelIOMMUState *s = vtd_as->iommu_state;

    VTDContextEntry ce;

    VTDContextCacheEntry *cc_entry = &vtd_as->context_cache_entry;

    uint64_t slpte;

    uint32_t level;

    uint16_t source_id = vtd_make_source_id(bus_num, devfn);

    int ret_fr;

    bool is_fpd_set = false;

    bool reads = true;

    bool writes = true;

    VTDIOTLBEntry *iotlb_entry;

    /* Check if the request is in interrupt address range */

    if (vtd_is_interrupt_addr(addr)) {

        if (is_write) {

            /* FIXME: since we don't know the length of the access here, we

             * treat Non-DWORD length write requests without PASID as

             * interrupt requests, too. Withoud interrupt remapping support,

             * we just use 1:1 mapping.

             */

            VTD_DPRINTF(MMU, "write request to interrupt address "

                        "gpa 0x%"PRIx64, addr);

            entry->iova = addr & VTD_PAGE_MASK_4K;

            entry->translated_addr = addr & VTD_PAGE_MASK_4K;

            entry->addr_mask = ~VTD_PAGE_MASK_4K;

            entry->perm = IOMMU_WO;

            return;

        } else {

            VTD_DPRINTF(GENERAL, "error: read request from interrupt address "

                        "gpa 0x%"PRIx64, addr);

            vtd_report_dmar_fault(s, source_id, addr, VTD_FR_READ, is_write);

            return;

        }

    }

    /* Try to fetch slpte form IOTLB */

    iotlb_entry = vtd_lookup_iotlb(s, source_id, addr);

    if (iotlb_entry) {

        VTD_DPRINTF(CACHE, "hit iotlb sid 0x%"PRIx16 " gpa 0x%"PRIx64

                    " slpte 0x%"PRIx64 " did 0x%"PRIx16, source_id, addr,

                    iotlb_entry->slpte, iotlb_entry->domain_id);

        slpte = iotlb_entry->slpte;

        reads = iotlb_entry->read_flags;

        writes = iotlb_entry->write_flags;

        goto out;

    }

    /* Try to fetch context-entry from cache first */

    if (cc_entry->context_cache_gen == s->context_cache_gen) {

        VTD_DPRINTF(CACHE, "hit context-cache bus %d devfn %d "

                    "(hi %"PRIx64 " lo %"PRIx64 " gen %"PRIu32 ")",

                    bus_num, devfn, cc_entry->context_entry.hi,

                    cc_entry->context_entry.lo, cc_entry->context_cache_gen);

        ce = cc_entry->context_entry;

        is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD;

    } else {

        ret_fr = vtd_dev_to_context_entry(s, bus_num, devfn, &ce);

        is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD;

        if (ret_fr) {

            ret_fr = -ret_fr;

            if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) {

                VTD_DPRINTF(FLOG, "fault processing is disabled for DMA "

                            "requests through this context-entry "

                            "(with FPD Set)");

            } else {

                vtd_report_dmar_fault(s, source_id, addr, ret_fr, is_write);

            }

            return;

        }

        /* Update context-cache */

        VTD_DPRINTF(CACHE, "update context-cache bus %d devfn %d "

                    "(hi %"PRIx64 " lo %"PRIx64 " gen %"PRIu32 "->%"PRIu32 ")",

                    bus_num, devfn, ce.hi, ce.lo,

                    cc_entry->context_cache_gen, s->context_cache_gen);

        cc_entry->context_entry = ce;

        cc_entry->context_cache_gen = s->context_cache_gen;

    }

    ret_fr = vtd_gpa_to_slpte(&ce, addr, is_write, &slpte, &level,

                              &reads, &writes);

    if (ret_fr) {

        ret_fr = -ret_fr;

        if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) {

            VTD_DPRINTF(FLOG, "fault processing is disabled for DMA requests "

                        "through this context-entry (with FPD Set)");

        } else {

            vtd_report_dmar_fault(s, source_id, addr, ret_fr, is_write);

        }

        return;

    }

    vtd_update_iotlb(s, source_id, VTD_CONTEXT_ENTRY_DID(ce.hi), addr, slpte,

                     reads, writes);

out:

    entry->iova = addr & VTD_PAGE_MASK_4K;

    entry->translated_addr = vtd_get_slpte_addr(slpte) & VTD_PAGE_MASK_4K;

    entry->addr_mask = ~VTD_PAGE_MASK_4K;

    entry->perm = (writes ? 2 : 0) + (reads ? 1 : 0);

}


static void single_quote_string(void)

{

    int i;

    struct {

        const char *encoded;

        const char *decoded;

    } test_cases[] = {

        { "'hello world'", "hello world" },

        { "'the quick brown fox \\' jumped over the fence'",

          "the quick brown fox ' jumped over the fence" },

        {}

    };

    for (i = 0; test_cases[i].encoded; i++) {

        QObject *obj;

        QString *str;

        obj = qobject_from_json(test_cases[i].encoded);

        g_assert(obj != NULL);

        g_assert(qobject_type(obj) == QTYPE_QSTRING);

        str = qobject_to_qstring(obj);

        g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);

        QDECREF(str);

    }

}


static int alloc_refcount_block(BlockDriverState *bs,

    int64_t cluster_index, uint16_t **refcount_block)

{

    BDRVQcowState *s = bs->opaque;

    unsigned int refcount_table_index;

    int ret;

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC);

    /* Find the refcount block for the given cluster */

    refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);

    if (refcount_table_index < s->refcount_table_size) {

        uint64_t refcount_block_offset =

            s->refcount_table[refcount_table_index];

        /* If it's already there, we're done */

        if (refcount_block_offset) {

             return load_refcount_block(bs, refcount_block_offset,

                 (void**) refcount_block);

        }

    }

    /*

     * If we came here, we need to allocate something. Something is at least

     * a cluster for the new refcount block. It may also include a new refcount

     * table if the old refcount table is too small.

     *

     * Note that allocating clusters here needs some special care:

     *

     * - We can't use the normal qcow2_alloc_clusters(), it would try to

     *   increase the refcount and very likely we would end up with an endless

     *   recursion. Instead we must place the refcount blocks in a way that

     *   they can describe them themselves.

     *

     * - We need to consider that at this point we are inside update_refcounts

     *   and doing the initial refcount increase. This means that some clusters

     *   have already been allocated by the caller, but their refcount isn't

     *   accurate yet. free_cluster_index tells us where this allocation ends

     *   as long as we don't overwrite it by freeing clusters.

     *

     * - alloc_clusters_noref and qcow2_free_clusters may load a different

     *   refcount block into the cache

     */

    *refcount_block = NULL;

    /* We write to the refcount table, so we might depend on L2 tables */

    qcow2_cache_flush(bs, s->l2_table_cache);

    /* Allocate the refcount block itself and mark it as used */

    int64_t new_block = alloc_clusters_noref(bs, s->cluster_size);

    if (new_block < 0) {

        return new_block;

    }

#ifdef DEBUG_ALLOC2

    fprintf(stderr, "qcow2: Allocate refcount block %d for %" PRIx64

        " at %" PRIx64 "\n",

        refcount_table_index, cluster_index << s->cluster_bits, new_block);

#endif

    if (in_same_refcount_block(s, new_block, cluster_index << s->cluster_bits)) {

        /* Zero the new refcount block before updating it */

        ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block,

            (void**) refcount_block);

        if (ret < 0) {

            goto fail_block;

        }

        memset(*refcount_block, 0, s->cluster_size);

        /* The block describes itself, need to update the cache */

        int block_index = (new_block >> s->cluster_bits) &

            ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);

        (*refcount_block)[block_index] = cpu_to_be16(1);

    } else {

        /* Described somewhere else. This can recurse at most twice before we

         * arrive at a block that describes itself. */

        ret = update_refcount(bs, new_block, s->cluster_size, 1);

        if (ret < 0) {

            goto fail_block;

        }

        bdrv_flush(bs->file);

        /* Initialize the new refcount block only after updating its refcount,

         * update_refcount uses the refcount cache itself */

        ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block,

            (void**) refcount_block);

        if (ret < 0) {

            goto fail_block;

        }

        memset(*refcount_block, 0, s->cluster_size);

    }

    /* Now the new refcount block needs to be written to disk */

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE);

    qcow2_cache_entry_mark_dirty(s->refcount_block_cache, *refcount_block);

    ret = qcow2_cache_flush(bs, s->refcount_block_cache);

    if (ret < 0) {

        goto fail_block;

    }

    /* If the refcount table is big enough, just hook the block up there */

    if (refcount_table_index < s->refcount_table_size) {

        uint64_t data64 = cpu_to_be64(new_block);

        BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP);

        ret = bdrv_pwrite_sync(bs->file,

            s->refcount_table_offset + refcount_table_index * sizeof(uint64_t),

            &data64, sizeof(data64));

        if (ret < 0) {

            goto fail_block;

        }

        s->refcount_table[refcount_table_index] = new_block;

        return 0;

    }

    ret = qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block);

    if (ret < 0) {

        goto fail_block;

    }

    /*

     * If we come here, we need to grow the refcount table. Again, a new

     * refcount table needs some space and we can't simply allocate to avoid

     * endless recursion.

     *

     * Therefore let's grab new refcount blocks at the end of the image, which

     * will describe themselves and the new refcount table. This way we can

     * reference them only in the new table and do the switch to the new

     * refcount table at once without producing an inconsistent state in

     * between.

     */

    BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_GROW);

    /* Calculate the number of refcount blocks needed so far */

    uint64_t refcount_block_clusters = 1 << (s->cluster_bits - REFCOUNT_SHIFT);

    uint64_t blocks_used = (s->free_cluster_index +

        refcount_block_clusters - 1) / refcount_block_clusters;

    /* And now we need at least one block more for the new metadata */

    uint64_t table_size = next_refcount_table_size(s, blocks_used + 1);

    uint64_t last_table_size;

    uint64_t blocks_clusters;

    do {

        uint64_t table_clusters = size_to_clusters(s, table_size);

        blocks_clusters = 1 +

            ((table_clusters + refcount_block_clusters - 1)

            / refcount_block_clusters);

        uint64_t meta_clusters = table_clusters + blocks_clusters;

        last_table_size = table_size;

        table_size = next_refcount_table_size(s, blocks_used +

            ((meta_clusters + refcount_block_clusters - 1)

            / refcount_block_clusters));

    } while (last_table_size != table_size);

#ifdef DEBUG_ALLOC2

    fprintf(stderr, "qcow2: Grow refcount table %" PRId32 " => %" PRId64 "\n",

        s->refcount_table_size, table_size);

#endif

    /* Create the new refcount table and blocks */

    uint64_t meta_offset = (blocks_used * refcount_block_clusters) *

        s->cluster_size;

    uint64_t table_offset = meta_offset + blocks_clusters * s->cluster_size;

    uint16_t *new_blocks = g_malloc0(blocks_clusters * s->cluster_size);

    uint64_t *new_table = g_malloc0(table_size * sizeof(uint64_t));

    assert(meta_offset >= (s->free_cluster_index * s->cluster_size));

    /* Fill the new refcount table */

    memcpy(new_table, s->refcount_table,

        s->refcount_table_size * sizeof(uint64_t));

    new_table[refcount_table_index] = new_block;

    int i;

    for (i = 0; i < blocks_clusters; i++) {

        new_table[blocks_used + i] = meta_offset + (i * s->cluster_size);

    }

    /* Fill the refcount blocks */

    uint64_t table_clusters = size_to_clusters(s, table_size * sizeof(uint64_t));

    int block = 0;

    for (i = 0; i < table_clusters + blocks_clusters; i++) {

        new_blocks[block++] = cpu_to_be16(1);

    }

    /* Write refcount blocks to disk */

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS);

    ret = bdrv_pwrite_sync(bs->file, meta_offset, new_blocks,

        blocks_clusters * s->cluster_size);

    g_free(new_blocks);

    if (ret < 0) {

        goto fail_table;

    }

    /* Write refcount table to disk */

    for(i = 0; i < table_size; i++) {

        cpu_to_be64s(&new_table[i]);

    }

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE);

    ret = bdrv_pwrite_sync(bs->file, table_offset, new_table,

        table_size * sizeof(uint64_t));

    if (ret < 0) {

        goto fail_table;

    }

    for(i = 0; i < table_size; i++) {

        cpu_to_be64s(&new_table[i]);

    }

    /* Hook up the new refcount table in the qcow2 header */

    uint8_t data[12];

    cpu_to_be64w((uint64_t*)data, table_offset);

    cpu_to_be32w((uint32_t*)(data + 8), table_clusters);

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE);

    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, refcount_table_offset),

        data, sizeof(data));

    if (ret < 0) {

        goto fail_table;

    }

    /* And switch it in memory */

    uint64_t old_table_offset = s->refcount_table_offset;

    uint64_t old_table_size = s->refcount_table_size;

    g_free(s->refcount_table);

    s->refcount_table = new_table;

    s->refcount_table_size = table_size;

    s->refcount_table_offset = table_offset;

    /* Free old table. Remember, we must not change free_cluster_index */

    uint64_t old_free_cluster_index = s->free_cluster_index;

    qcow2_free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t));

    s->free_cluster_index = old_free_cluster_index;

    ret = load_refcount_block(bs, new_block, (void**) refcount_block);

    if (ret < 0) {

        return ret;

    }

    return new_block;

fail_table:

    g_free(new_table);

fail_block:

    if (*refcount_block != NULL) {

        qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block);

    }

    return ret;

}


static always_inline void gen_qemu_stg (TCGv t0, TCGv t1, int flags)

{

    TCGv tmp = tcg_temp_new(TCG_TYPE_I64);

    tcg_gen_helper_1_1(helper_g_to_memory, tmp, t0);

    tcg_gen_qemu_st64(tmp, t1, flags);

    tcg_temp_free(tmp);

}


static void test_qemu_strtosz_erange(void)

{

    const char *str = "10E";

    char *endptr = NULL;

    int64_t res;

    res = qemu_strtosz(str, &endptr);

    g_assert_cmpint(res, ==, -ERANGE);

    g_assert(endptr == str + 3);

}


static uint32_t scsi_init_iovec(SCSIDiskReq *r)

{

    r->iov.iov_len = MIN(r->sector_count * 512, SCSI_DMA_BUF_SIZE);

    qemu_iovec_init_external(&r->qiov, &r->iov, 1);

    return r->qiov.size / 512;

}


static int read_dct_coeffs(BitstreamContext *bc, int32_t block[64],

                           const uint8_t *scan,

                           const int32_t quant_matrices[16][64], int q)

{

    int coef_list[128];

    int mode_list[128];

    int i, t, bits, ccoef, mode;

    int list_start = 64, list_end = 64, list_pos;

    int coef_count = 0;

    int coef_idx[64];

    int quant_idx;

    const int32_t *quant;

    coef_list[list_end] = 4;  mode_list[list_end++] = 0;

    coef_list[list_end] = 24; mode_list[list_end++] = 0;

    coef_list[list_end] = 44; mode_list[list_end++] = 0;

    coef_list[list_end] = 1;  mode_list[list_end++] = 3;

    coef_list[list_end] = 2;  mode_list[list_end++] = 3;

    coef_list[list_end] = 3;  mode_list[list_end++] = 3;

    for (bits = bitstream_read(bc, 4) - 1; bits >= 0; bits--) {

        list_pos = list_start;

        while (list_pos < list_end) {

            if (!(mode_list[list_pos] | coef_list[list_pos]) || !bitstream_read_bit(bc)) {

                list_pos++;

                continue;

            }

            ccoef = coef_list[list_pos];

            mode  = mode_list[list_pos];

            switch (mode) {

            case 0:

                coef_list[list_pos] = ccoef + 4;

                mode_list[list_pos] = 1;

            case 2:

                if (mode == 2) {

                    coef_list[list_pos]   = 0;

                    mode_list[list_pos++] = 0;

                }

                for (i = 0; i < 4; i++, ccoef++) {

                    if (bitstream_read_bit(bc)) {

                        coef_list[--list_start] = ccoef;

                        mode_list[  list_start] = 3;

                    } else {

                        if (!bits) {

                            t = 1 - (bitstream_read_bit(bc) << 1);

                        } else {

                            t = bitstream_read(bc, bits) | 1 << bits;

                            t = bitstream_apply_sign(bc, t);

                        }

                        block[scan[ccoef]] = t;

                        coef_idx[coef_count++] = ccoef;

                    }

                }

                break;

            case 1:

                mode_list[list_pos] = 2;

                for (i = 0; i < 3; i++) {

                    ccoef += 4;

                    coef_list[list_end]   = ccoef;

                    mode_list[list_end++] = 2;

                }

                break;

            case 3:

                if (!bits) {

                    t = 1 - (bitstream_read_bit(bc) << 1);

                } else {

                    t = bitstream_read(bc, bits) | 1 << bits;

                    t = bitstream_apply_sign(bc, t);

                }

                block[scan[ccoef]] = t;

                coef_idx[coef_count++] = ccoef;

                coef_list[list_pos]   = 0;

                mode_list[list_pos++] = 0;

                break;

            }

        }

    }

    if (q == -1) {

        quant_idx = bitstream_read(bc, 4);

    } else {

        quant_idx = q;

    }

    if (quant_idx >= 16)

        return AVERROR_INVALIDDATA;

    quant = quant_matrices[quant_idx];

    block[0] = (block[0] * quant[0]) >> 11;

    for (i = 0; i < coef_count; i++) {

        int idx = coef_idx[i];

        block[scan[idx]] = (block[scan[idx]] * quant[idx]) >> 11;

    }

    return 0;

}


bool qemu_co_queue_next(CoQueue *queue)

{

    Coroutine *next;

    next = QTAILQ_FIRST(&queue->entries);

    if (next) {

        QTAILQ_REMOVE(&queue->entries, next, co_queue_next);

        QTAILQ_INSERT_TAIL(&unlock_bh_queue, next, co_queue_next);

        trace_qemu_co_queue_next(next);

        qemu_bh_schedule(unlock_bh);

    }

    return (next != NULL);

}


static int nut_write_packet(AVFormatContext *s, int stream_index,

			    const uint8_t *buf, int size, int64_t pts)

{

    NUTContext *nut = s->priv_data;

    StreamContext *stream= &nut->stream[stream_index];

    ByteIOContext *bc = &s->pb;

    int key_frame = 0, full_pts=0;

    AVCodecContext *enc;

    int64_t lsb_pts, delta_pts;

    int frame_type, best_length, frame_code, flags, i, size_mul, size_lsb;

    const int64_t frame_start= url_ftell(bc);

    if (stream_index > s->nb_streams)

	return 1;

    pts= (av_rescale(pts, stream->rate_num, stream->rate_den) + AV_TIME_BASE/2) / AV_TIME_BASE;

    enc = &s->streams[stream_index]->codec;

    key_frame = enc->coded_frame->key_frame;

    delta_pts= pts - stream->last_pts;

    frame_type=0;

    if(frame_start + size + 20 - FFMAX(nut->last_frame_start[1], nut->last_frame_start[2]) > MAX_TYPE1_DISTANCE)

        frame_type=1;

    if(key_frame){

        if(frame_type==1 && frame_start + size - nut->last_frame_start[2] > MAX_TYPE2_DISTANCE)

            frame_type=2;

        if(!stream->last_key_frame)

            frame_type=2;

    }

    if(frame_type>0){

        update_packetheader(nut, bc, 0);

        reset(s);

        full_pts=1;

    }

    //FIXME ensure that the timestamp can be represented by either delta or lsb or full_pts=1

    lsb_pts = pts & ((1 << stream->msb_timestamp_shift)-1);

    best_length=INT_MAX;

    frame_code= -1;

    for(i=0; i<256; i++){

        int stream_id_plus1= nut->frame_code[i].stream_id_plus1;

        int fc_key_frame= stream->last_key_frame;

        int length=0;

        size_mul= nut->frame_code[i].size_mul;

        size_lsb= nut->frame_code[i].size_lsb;

        flags= nut->frame_code[i].flags;

        if(stream_id_plus1 == 0) length+= get_length(stream_index);

        else if(stream_id_plus1 - 1 != stream_index)

            continue;

        if(flags & FLAG_PRED_KEY_FRAME){

            if(flags & FLAG_KEY_FRAME)

                fc_key_frame= !fc_key_frame;

        }else{

            fc_key_frame= !!(flags & FLAG_KEY_FRAME);

        }

        assert(key_frame==0 || key_frame==1);

        if(fc_key_frame != key_frame)

            continue;

        if((!!(flags & FLAG_FRAME_TYPE)) != (frame_type > 0))

            continue;

        if(size_mul <= size_lsb){

            int p= stream->lru_size[size_lsb - size_mul];

            if(p != size)

                continue;

        }else{

            if(size % size_mul != size_lsb)

                continue;

            if(flags & FLAG_DATA_SIZE)

                length += get_length(size / size_mul);

            else if(size/size_mul)

                continue;

        }

        if(full_pts != ((flags & FLAG_PTS) && (flags & FLAG_FULL_PTS)))

            continue;

        if(flags&FLAG_PTS){

            if(flags&FLAG_FULL_PTS){

                length += get_length(pts);

            }else{

                length += get_length(lsb_pts);

            }

        }else{

            int delta= stream->lru_pts_delta[(flags & 12)>>2];

            if(delta != pts - stream->last_pts)

                continue;

            assert(frame_type == 0);

        }

        if(length < best_length){

            best_length= length;

            frame_code=i;

        }

//    av_log(s, AV_LOG_DEBUG, "%d %d %d %d %d %d %d %d %d %d\n", key_frame, frame_type, full_pts, size, stream_index, flags, size_mul, size_lsb, stream_id_plus1, length);

    }

    assert(frame_code != -1);

    flags= nut->frame_code[frame_code].flags;

    size_mul= nut->frame_code[frame_code].size_mul;

    size_lsb= nut->frame_code[frame_code].size_lsb;

#if 0

    best_length /= 7;

    best_length ++; //frame_code

    if(frame_type>0){

        best_length += 4; //packet header

        if(frame_type>1)

            best_length += 8; // startcode

    }

    av_log(s, AV_LOG_DEBUG, "kf:%d ft:%d pt:%d fc:%2X len:%2d size:%d stream:%d flag:%d mul:%d lsb:%d s+1:%d pts_delta:%d\n", key_frame, frame_type, full_pts ? 2 : ((flags & FLAG_PTS) ? 1 : 0), frame_code, best_length, size, stream_index, flags, size_mul, size_lsb, nut->frame_code[frame_code].stream_id_plus1,(int)(pts - stream->last_pts));

#endif

    if (frame_type==2)

	put_be64(bc, KEYFRAME_STARTCODE);

    put_byte(bc, frame_code);

    if(frame_type>0)

        put_packetheader(nut, bc, FFMAX(size+20, MAX_TYPE1_DISTANCE));

    if(nut->frame_code[frame_code].stream_id_plus1 == 0)

        put_v(bc, stream_index);

    if (flags & FLAG_PTS){

        if (flags & FLAG_FULL_PTS)

            put_v(bc, pts);

        else

            put_v(bc, lsb_pts);

    }

    if(flags & FLAG_DATA_SIZE)

        put_v(bc, size / size_mul);

    if(size > MAX_TYPE1_DISTANCE){

        assert(frame_type > 0);

        update_packetheader(nut, bc, size);

    }

    put_buffer(bc, buf, size);

    update(nut, stream_index, frame_start, frame_type, frame_code, key_frame, size, pts);

    return 0;

}