int main(int argc, char **argv, char **envp)
    int i;
    int snapshot, linux_boot;
    const char *initrd_filename;
    const char *kernel_filename, *kernel_cmdline;
    const char *boot_order = NULL;
    const char *boot_once = NULL;
    DisplayState *ds;
    int cyls, heads, secs, translation;
    QemuOpts *opts, *machine_opts;
    QemuOpts *hda_opts = NULL, *icount_opts = NULL, *accel_opts = NULL;
    QemuOptsList *olist;
    int optind;
    const char *optarg;
    const char *loadvm = NULL;
    MachineClass *machine_class;
    const char *cpu_model;
    const char *vga_model = NULL;
    const char *qtest_chrdev = NULL;
    const char *qtest_log = NULL;
    const char *pid_file = NULL;
    const char *incoming = NULL;
    bool defconfig = true;
    bool userconfig = true;
    bool nographic = false;
    DisplayType display_type = DT_DEFAULT;
    int display_remote = 0;
    const char *log_mask = NULL;
    const char *log_file = NULL;
    char *trace_file = NULL;
    ram_addr_t maxram_size;
    uint64_t ram_slots = 0;
    FILE *vmstate_dump_file = NULL;
    Error *main_loop_err = NULL;
    Error *err = NULL;
    bool list_data_dirs = false;
    typedef struct BlockdevOptions_queue {
        BlockdevOptions *bdo;
        Location loc;
        QSIMPLEQ_ENTRY(BlockdevOptions_queue) entry;
    } BlockdevOptions_queue;
    QSIMPLEQ_HEAD(, BlockdevOptions_queue) bdo_queue
        = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
    module_call_init(MODULE_INIT_TRACE);
    qemu_init_cpu_list();
    qemu_init_cpu_loop();
    qemu_mutex_lock_iothread();
    atexit(qemu_run_exit_notifiers);
    error_set_progname(argv[0]);
    qemu_init_exec_dir(argv[0]);
    module_call_init(MODULE_INIT_QOM);
    monitor_init_qmp_commands();
    qemu_add_opts(&qemu_drive_opts);
    qemu_add_drive_opts(&qemu_legacy_drive_opts);
    qemu_add_drive_opts(&qemu_common_drive_opts);
    qemu_add_drive_opts(&qemu_drive_opts);
    qemu_add_drive_opts(&bdrv_runtime_opts);
    qemu_add_opts(&qemu_chardev_opts);
    qemu_add_opts(&qemu_device_opts);
    qemu_add_opts(&qemu_netdev_opts);
    qemu_add_opts(&qemu_net_opts);
    qemu_add_opts(&qemu_rtc_opts);
    qemu_add_opts(&qemu_global_opts);
    qemu_add_opts(&qemu_mon_opts);
    qemu_add_opts(&qemu_trace_opts);
    qemu_add_opts(&qemu_option_rom_opts);
    qemu_add_opts(&qemu_machine_opts);
    qemu_add_opts(&qemu_accel_opts);
    qemu_add_opts(&qemu_mem_opts);
    qemu_add_opts(&qemu_smp_opts);
    qemu_add_opts(&qemu_boot_opts);
    qemu_add_opts(&qemu_sandbox_opts);
    qemu_add_opts(&qemu_add_fd_opts);
    qemu_add_opts(&qemu_object_opts);
    qemu_add_opts(&qemu_tpmdev_opts);
    qemu_add_opts(&qemu_realtime_opts);
    qemu_add_opts(&qemu_msg_opts);
    qemu_add_opts(&qemu_name_opts);
    qemu_add_opts(&qemu_numa_opts);
    qemu_add_opts(&qemu_icount_opts);
    qemu_add_opts(&qemu_semihosting_config_opts);
    qemu_add_opts(&qemu_fw_cfg_opts);
    module_call_init(MODULE_INIT_OPTS);
    runstate_init();
    if (qcrypto_init(&err) < 0) {
        error_reportf_err(err, "cannot initialize crypto: ");
    rtc_clock = QEMU_CLOCK_HOST;
    QLIST_INIT (&vm_change_state_head);
    os_setup_early_signal_handling();
    cpu_model = NULL;
    snapshot = 0;
    cyls = heads = secs = 0;
    translation = BIOS_ATA_TRANSLATION_AUTO;
    nb_nics = 0;
    bdrv_init_with_whitelist();
    autostart = 1;
    /* first pass of option parsing */
    optind = 1;
    while (optind < argc) {
        if (argv[optind][0] != '-') {
            /* disk image */
            optind++;
        } else {
            const QEMUOption *popt;
            popt = lookup_opt(argc, argv, &optarg, &optind);
            switch (popt->index) {
            case QEMU_OPTION_nodefconfig:
                defconfig = false;
            case QEMU_OPTION_nouserconfig:
                userconfig = false;
    if (defconfig && userconfig) {
        if (qemu_read_default_config_file() < 0) {
    /* second pass of option parsing */
    optind = 1;
    for(;;) {
        if (optind >= argc)
        if (argv[optind][0] != '-') {
            hda_opts = drive_add(IF_DEFAULT, 0, argv[optind++], HD_OPTS);
        } else {
            const QEMUOption *popt;
            popt = lookup_opt(argc, argv, &optarg, &optind);
            if (!(popt->arch_mask & arch_type)) {
                error_report("Option not supported for this target");
            switch(popt->index) {
            case QEMU_OPTION_no_kvm_irqchip: {
                olist = qemu_find_opts("machine");
                qemu_opts_parse_noisily(olist, "kernel_irqchip=off", false);
            case QEMU_OPTION_cpu:
                /* hw initialization will check this */
                cpu_model = optarg;
            case QEMU_OPTION_hda:
                    char buf[256];
                    if (cyls == 0)
                        snprintf(buf, sizeof(buf), "%s", HD_OPTS);
                    else
                        snprintf(buf, sizeof(buf),
                                 "%s,cyls=%d,heads=%d,secs=%d%s",
                                 HD_OPTS , cyls, heads, secs,
                                 translation == BIOS_ATA_TRANSLATION_LBA ?
                                 ",trans=lba" :
                                 translation == BIOS_ATA_TRANSLATION_NONE ?
                                 ",trans=none" : "");
                    drive_add(IF_DEFAULT, 0, optarg, buf);
            case QEMU_OPTION_hdb:
            case QEMU_OPTION_hdc:
            case QEMU_OPTION_hdd:
                drive_add(IF_DEFAULT, popt->index - QEMU_OPTION_hda, optarg,
                          HD_OPTS);
            case QEMU_OPTION_drive:
                if (drive_def(optarg) == NULL) {
            case QEMU_OPTION_set:
                if (qemu_set_option(optarg) != 0)
            case QEMU_OPTION_global:
                if (qemu_global_option(optarg) != 0)
            case QEMU_OPTION_mtdblock:
                drive_add(IF_MTD, -1, optarg, MTD_OPTS);
            case QEMU_OPTION_sd:
                drive_add(IF_SD, -1, optarg, SD_OPTS);
            case QEMU_OPTION_pflash:
                drive_add(IF_PFLASH, -1, optarg, PFLASH_OPTS);
            case QEMU_OPTION_snapshot:
                snapshot = 1;
            case QEMU_OPTION_hdachs:
                    const char *p;
                    p = optarg;
                    cyls = strtol(p, (char **)&p, 0);
                    if (cyls < 1 || cyls > 16383)
                        goto chs_fail;
                    if (*p != ',')
                        goto chs_fail;
                    p++;
                    heads = strtol(p, (char **)&p, 0);
                    if (heads < 1 || heads > 16)
                        goto chs_fail;
                    if (*p != ',')
                        goto chs_fail;
                    p++;
                    secs = strtol(p, (char **)&p, 0);
                    if (secs < 1 || secs > 63)
                        goto chs_fail;
                    if (*p == ',') {
                        p++;
                        if (!strcmp(p, "large")) {
                            translation = BIOS_ATA_TRANSLATION_LARGE;
                        } else if (!strcmp(p, "rechs")) {
                            translation = BIOS_ATA_TRANSLATION_RECHS;
                        } else if (!strcmp(p, "none")) {
                            translation = BIOS_ATA_TRANSLATION_NONE;
                        } else if (!strcmp(p, "lba")) {
                            translation = BIOS_ATA_TRANSLATION_LBA;
                        } else if (!strcmp(p, "auto")) {
                            translation = BIOS_ATA_TRANSLATION_AUTO;
                        } else {
                            goto chs_fail;
                    } else if (*p != '\0') {
                    chs_fail:
                        error_report("invalid physical CHS format");
                    if (hda_opts != NULL) {
                        qemu_opt_set_number(hda_opts, "cyls", cyls,
                                            &error_abort);
                        qemu_opt_set_number(hda_opts, "heads", heads,
                                            &error_abort);
                        qemu_opt_set_number(hda_opts, "secs", secs,
                                            &error_abort);
                        if (translation == BIOS_ATA_TRANSLATION_LARGE) {
                            qemu_opt_set(hda_opts, "trans", "large",
                                         &error_abort);
                        } else if (translation == BIOS_ATA_TRANSLATION_RECHS) {
                            qemu_opt_set(hda_opts, "trans", "rechs",
                                         &error_abort);
                        } else if (translation == BIOS_ATA_TRANSLATION_LBA) {
                            qemu_opt_set(hda_opts, "trans", "lba",
                                         &error_abort);
                        } else if (translation == BIOS_ATA_TRANSLATION_NONE) {
                            qemu_opt_set(hda_opts, "trans", "none",
                                         &error_abort);
            case QEMU_OPTION_numa:
                opts = qemu_opts_parse_noisily(qemu_find_opts("numa"),
                                               optarg, true);
                if (!opts) {
            case QEMU_OPTION_display:
                display_type = select_display(optarg);
            case QEMU_OPTION_nographic:
                olist = qemu_find_opts("machine");
                qemu_opts_parse_noisily(olist, "graphics=off", false);
                nographic = true;
                display_type = DT_NONE;
            case QEMU_OPTION_curses:
#ifdef CONFIG_CURSES
                display_type = DT_CURSES;
#else
                error_report("curses support is disabled");
#endif
            case QEMU_OPTION_portrait:
                graphic_rotate = 90;
            case QEMU_OPTION_rotate:
                graphic_rotate = strtol(optarg, (char **) &optarg, 10);
                if (graphic_rotate != 0 && graphic_rotate != 90 &&
                    graphic_rotate != 180 && graphic_rotate != 270) {
                    error_report("only 90, 180, 270 deg rotation is available");
            case QEMU_OPTION_kernel:
                qemu_opts_set(qemu_find_opts("machine"), 0, "kernel", optarg,
                              &error_abort);
            case QEMU_OPTION_initrd:
                qemu_opts_set(qemu_find_opts("machine"), 0, "initrd", optarg,
                              &error_abort);
            case QEMU_OPTION_append:
                qemu_opts_set(qemu_find_opts("machine"), 0, "append", optarg,
                              &error_abort);
            case QEMU_OPTION_dtb:
                qemu_opts_set(qemu_find_opts("machine"), 0, "dtb", optarg,
                              &error_abort);
            case QEMU_OPTION_cdrom:
                drive_add(IF_DEFAULT, 2, optarg, CDROM_OPTS);
            case QEMU_OPTION_boot:
                opts = qemu_opts_parse_noisily(qemu_find_opts("boot-opts"),
                                               optarg, true);
                if (!opts) {
            case QEMU_OPTION_fda:
            case QEMU_OPTION_fdb:
                drive_add(IF_FLOPPY, popt->index - QEMU_OPTION_fda,
                          optarg, FD_OPTS);
            case QEMU_OPTION_no_fd_bootchk:
                fd_bootchk = 0;
            case QEMU_OPTION_netdev:
                default_net = 0;
                if (net_client_parse(qemu_find_opts("netdev"), optarg) == -1) {
            case QEMU_OPTION_net:
                default_net = 0;
                if (net_client_parse(qemu_find_opts("net"), optarg) == -1) {
#ifdef CONFIG_LIBISCSI
            case QEMU_OPTION_iscsi:
                opts = qemu_opts_parse_noisily(qemu_find_opts("iscsi"),
                                               optarg, false);
                if (!opts) {
#endif
#ifdef CONFIG_SLIRP
            case QEMU_OPTION_tftp:
                error_report("The -tftp option is deprecated. "
                             "Please use '-netdev user,tftp=...' instead.");
                legacy_tftp_prefix = optarg;
            case QEMU_OPTION_bootp:
                error_report("The -bootp option is deprecated. "
                             "Please use '-netdev user,bootfile=...' instead.");
                legacy_bootp_filename = optarg;
            case QEMU_OPTION_redir:
                error_report("The -redir option is deprecated. "
                             "Please use '-netdev user,hostfwd=...' instead.");
                if (net_slirp_redir(optarg) < 0)
#endif
            case QEMU_OPTION_bt:
                add_device_config(DEV_BT, optarg);
            case QEMU_OPTION_audio_help:
                AUD_help ();
                exit (0);
            case QEMU_OPTION_soundhw:
                select_soundhw (optarg);
            case QEMU_OPTION_h:
                help(0);
            case QEMU_OPTION_version:
                version();
                exit(0);
            case QEMU_OPTION_m:
                opts = qemu_opts_parse_noisily(qemu_find_opts("memory"),
                                               optarg, true);
                if (!opts) {
                    exit(EXIT_FAILURE);
#ifdef CONFIG_TPM
            case QEMU_OPTION_tpmdev:
                if (tpm_config_parse(qemu_find_opts("tpmdev"), optarg) < 0) {
#endif
            case QEMU_OPTION_mempath:
                mem_path = optarg;
            case QEMU_OPTION_mem_prealloc:
                mem_prealloc = 1;
            case QEMU_OPTION_d:
                log_mask = optarg;
            case QEMU_OPTION_D:
                log_file = optarg;
            case QEMU_OPTION_DFILTER:
                qemu_set_dfilter_ranges(optarg, &error_fatal);
            case QEMU_OPTION_s:
                add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT);
            case QEMU_OPTION_gdb:
                add_device_config(DEV_GDB, optarg);
            case QEMU_OPTION_L:
                if (is_help_option(optarg)) {
                    list_data_dirs = true;
                } else if (data_dir_idx < ARRAY_SIZE(data_dir)) {
                    data_dir[data_dir_idx++] = optarg;
            case QEMU_OPTION_bios:
                qemu_opts_set(qemu_find_opts("machine"), 0, "firmware", optarg,
                              &error_abort);
            case QEMU_OPTION_singlestep:
                singlestep = 1;
            case QEMU_OPTION_S:
                autostart = 0;
            case QEMU_OPTION_k:
                keyboard_layout = optarg;
            case QEMU_OPTION_localtime:
                rtc_utc = 0;
            case QEMU_OPTION_vga:
                vga_model = optarg;
                default_vga = 0;
            case QEMU_OPTION_g:
                    const char *p;
                    int w, h, depth;
                    p = optarg;
                    w = strtol(p, (char **)&p, 10);
                    if (w <= 0) {
                    graphic_error:
                        error_report("invalid resolution or depth");
                    if (*p != 'x')
                        goto graphic_error;
                    p++;
                    h = strtol(p, (char **)&p, 10);
                    if (h <= 0)
                        goto graphic_error;
                    if (*p == 'x') {
                        p++;
                        depth = strtol(p, (char **)&p, 10);
                        if (depth != 8 && depth != 15 && depth != 16 &&
                            depth != 24 && depth != 32)
                            goto graphic_error;
                    } else if (*p == '\0') {
                        depth = graphic_depth;
                    } else {
                        goto graphic_error;
                    graphic_width = w;
                    graphic_height = h;
                    graphic_depth = depth;
            case QEMU_OPTION_echr:
                    char *r;
                    term_escape_char = strtol(optarg, &r, 0);
                    if (r == optarg)
                        printf("Bad argument to echr\n");
            case QEMU_OPTION_monitor:
                default_monitor = 0;
                if (strncmp(optarg, "none", 4)) {
                    monitor_parse(optarg, "readline", false);
            case QEMU_OPTION_qmp:
                monitor_parse(optarg, "control", false);
                default_monitor = 0;
            case QEMU_OPTION_qmp_pretty:
                monitor_parse(optarg, "control", true);
                default_monitor = 0;
            case QEMU_OPTION_mon:
                opts = qemu_opts_parse_noisily(qemu_find_opts("mon"), optarg,
                                               true);
                if (!opts) {
                default_monitor = 0;
            case QEMU_OPTION_chardev:
                opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
                                               optarg, true);
                if (!opts) {
            case QEMU_OPTION_fsdev:
                olist = qemu_find_opts("fsdev");
                if (!olist) {
                    error_report("fsdev support is disabled");
                opts = qemu_opts_parse_noisily(olist, optarg, true);
                if (!opts) {
            case QEMU_OPTION_virtfs: {
                QemuOpts *fsdev;
                QemuOpts *device;
                const char *writeout, *sock_fd, *socket;
                olist = qemu_find_opts("virtfs");
                if (!olist) {
                    error_report("virtfs support is disabled");
                opts = qemu_opts_parse_noisily(olist, optarg, true);
                if (!opts) {
                if (qemu_opt_get(opts, "fsdriver") == NULL ||
                    qemu_opt_get(opts, "mount_tag") == NULL) {
                    error_report("Usage: -virtfs fsdriver,mount_tag=tag");
                fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
                                         qemu_opt_get(opts, "mount_tag"),
                                         1, NULL);
                if (!fsdev) {
                    error_report("duplicate fsdev id: %s",
                                 qemu_opt_get(opts, "mount_tag"));
                writeout = qemu_opt_get(opts, "writeout");
                if (writeout) {
#ifdef CONFIG_SYNC_FILE_RANGE
                    qemu_opt_set(fsdev, "writeout", writeout, &error_abort);
#else
                    error_report("writeout=immediate not supported "
                                 "on this platform");
#endif
                qemu_opt_set(fsdev, "fsdriver",
                             qemu_opt_get(opts, "fsdriver"), &error_abort);
                qemu_opt_set(fsdev, "path", qemu_opt_get(opts, "path"),
                             &error_abort);
                qemu_opt_set(fsdev, "security_model",
                             qemu_opt_get(opts, "security_model"),
                             &error_abort);
                socket = qemu_opt_get(opts, "socket");
                if (socket) {
                    qemu_opt_set(fsdev, "socket", socket, &error_abort);
                sock_fd = qemu_opt_get(opts, "sock_fd");
                if (sock_fd) {
                    qemu_opt_set(fsdev, "sock_fd", sock_fd, &error_abort);
                qemu_opt_set_bool(fsdev, "readonly",
                                  qemu_opt_get_bool(opts, "readonly", 0),
                                  &error_abort);
                device = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
                                          &error_abort);
                qemu_opt_set(device, "driver", "virtio-9p-pci", &error_abort);
                qemu_opt_set(device, "fsdev",
                             qemu_opt_get(opts, "mount_tag"), &error_abort);
                qemu_opt_set(device, "mount_tag",
                             qemu_opt_get(opts, "mount_tag"), &error_abort);
            case QEMU_OPTION_virtfs_synth: {
                QemuOpts *fsdev;
                QemuOpts *device;
                fsdev = qemu_opts_create(qemu_find_opts("fsdev"), "v_synth",
                                         1, NULL);
                if (!fsdev) {
                    error_report("duplicate option: %s", "virtfs_synth");
                qemu_opt_set(fsdev, "fsdriver", "synth", &error_abort);
                device = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
                                          &error_abort);
                qemu_opt_set(device, "driver", "virtio-9p-pci", &error_abort);
                qemu_opt_set(device, "fsdev", "v_synth", &error_abort);
                qemu_opt_set(device, "mount_tag", "v_synth", &error_abort);
            case QEMU_OPTION_serial:
                add_device_config(DEV_SERIAL, optarg);
                default_serial = 0;
                if (strncmp(optarg, "mon:", 4) == 0) {
                    default_monitor = 0;
            case QEMU_OPTION_watchdog:
                if (watchdog) {
                    error_report("only one watchdog option may be given");
                    return 1;
                watchdog = optarg;
            case QEMU_OPTION_watchdog_action:
                if (select_watchdog_action(optarg) == -1) {
                    error_report("unknown -watchdog-action parameter");
            case QEMU_OPTION_virtiocon:
                add_device_config(DEV_VIRTCON, optarg);
                default_virtcon = 0;
                if (strncmp(optarg, "mon:", 4) == 0) {
                    default_monitor = 0;
            case QEMU_OPTION_parallel:
                add_device_config(DEV_PARALLEL, optarg);
                default_parallel = 0;
                if (strncmp(optarg, "mon:", 4) == 0) {
                    default_monitor = 0;
            case QEMU_OPTION_debugcon:
                add_device_config(DEV_DEBUGCON, optarg);
            case QEMU_OPTION_loadvm:
                loadvm = optarg;
            case QEMU_OPTION_full_screen:
                full_screen = 1;
            case QEMU_OPTION_no_frame:
                no_frame = 1;
            case QEMU_OPTION_alt_grab:
                alt_grab = 1;
            case QEMU_OPTION_ctrl_grab:
                ctrl_grab = 1;
            case QEMU_OPTION_no_quit:
                no_quit = 1;
            case QEMU_OPTION_sdl:
#ifdef CONFIG_SDL
                display_type = DT_SDL;
#else
                error_report("SDL support is disabled");
#endif
            case QEMU_OPTION_pidfile:
                pid_file = optarg;
            case QEMU_OPTION_win2k_hack:
                win2k_install_hack = 1;
            case QEMU_OPTION_rtc_td_hack: {
                static GlobalProperty slew_lost_ticks = {
                    .driver   = "mc146818rtc",
                    .property = "lost_tick_policy",
                    .value    = "slew",
                };
                qdev_prop_register_global(&slew_lost_ticks);
            case QEMU_OPTION_acpitable:
                opts = qemu_opts_parse_noisily(qemu_find_opts("acpi"),
                                               optarg, true);
                if (!opts) {
                acpi_table_add(opts, &error_fatal);
            case QEMU_OPTION_smbios:
                opts = qemu_opts_parse_noisily(qemu_find_opts("smbios"),
                                               optarg, false);
                if (!opts) {
                smbios_entry_add(opts, &error_fatal);
            case QEMU_OPTION_fwcfg:
                opts = qemu_opts_parse_noisily(qemu_find_opts("fw_cfg"),
                                               optarg, true);
                if (opts == NULL) {
            case QEMU_OPTION_enable_kvm:
                olist = qemu_find_opts("machine");
                qemu_opts_parse_noisily(olist, "accel=kvm", false);
            case QEMU_OPTION_enable_hax:
                olist = qemu_find_opts("machine");
                qemu_opts_parse_noisily(olist, "accel=hax", false);
            case QEMU_OPTION_M:
            case QEMU_OPTION_machine:
                olist = qemu_find_opts("machine");
                opts = qemu_opts_parse_noisily(olist, optarg, true);
                if (!opts) {
             case QEMU_OPTION_no_kvm:
                olist = qemu_find_opts("machine");
                qemu_opts_parse_noisily(olist, "accel=tcg", false);
            case QEMU_OPTION_no_kvm_pit: {
                error_report("warning: ignoring deprecated option");
            case QEMU_OPTION_no_kvm_pit_reinjection: {
                static GlobalProperty kvm_pit_lost_tick_policy = {
                    .driver   = "kvm-pit",
                    .property = "lost_tick_policy",
                    .value    = "discard",
                };
                error_report("warning: deprecated, replaced by "
                             "-global kvm-pit.lost_tick_policy=discard");
                qdev_prop_register_global(&kvm_pit_lost_tick_policy);
            case QEMU_OPTION_accel:
                accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"),
                                                     optarg, true);
                optarg = qemu_opt_get(accel_opts, "accel");
                olist = qemu_find_opts("machine");
                if (strcmp("kvm", optarg) == 0) {
                    qemu_opts_parse_noisily(olist, "accel=kvm", false);
                } else if (strcmp("xen", optarg) == 0) {
                    qemu_opts_parse_noisily(olist, "accel=xen", false);
                } else if (strcmp("tcg", optarg) == 0) {
                    qemu_opts_parse_noisily(olist, "accel=tcg", false);
                } else {
                    if (!is_help_option(optarg)) {
                        error_printf("Unknown accelerator: %s", optarg);
                    error_printf("Supported accelerators: kvm, xen, tcg\n");
            case QEMU_OPTION_usb:
                olist = qemu_find_opts("machine");
                qemu_opts_parse_noisily(olist, "usb=on", false);
            case QEMU_OPTION_usbdevice:
                olist = qemu_find_opts("machine");
                qemu_opts_parse_noisily(olist, "usb=on", false);
                add_device_config(DEV_USB, optarg);
            case QEMU_OPTION_device:
                if (!qemu_opts_parse_noisily(qemu_find_opts("device"),
                                             optarg, true)) {
            case QEMU_OPTION_smp:
                if (!qemu_opts_parse_noisily(qemu_find_opts("smp-opts"),
                                             optarg, true)) {
            case QEMU_OPTION_vnc:
                vnc_parse(optarg, &error_fatal);
            case QEMU_OPTION_no_acpi:
                acpi_enabled = 0;
            case QEMU_OPTION_no_hpet:
                no_hpet = 1;
            case QEMU_OPTION_balloon:
                if (balloon_parse(optarg) < 0) {
                    error_report("unknown -balloon argument %s", optarg);
            case QEMU_OPTION_no_reboot:
                no_reboot = 1;
            case QEMU_OPTION_no_shutdown:
                no_shutdown = 1;
            case QEMU_OPTION_show_cursor:
                cursor_hide = 0;
            case QEMU_OPTION_uuid:
                if (qemu_uuid_parse(optarg, &qemu_uuid) < 0) {
                    error_report("failed to parse UUID string: wrong format");
                qemu_uuid_set = true;
            case QEMU_OPTION_option_rom:
                if (nb_option_roms >= MAX_OPTION_ROMS) {
                    error_report("too many option ROMs");
                opts = qemu_opts_parse_noisily(qemu_find_opts("option-rom"),
                                               optarg, true);
                if (!opts) {
                option_rom[nb_option_roms].name = qemu_opt_get(opts, "romfile");
                option_rom[nb_option_roms].bootindex =
                    qemu_opt_get_number(opts, "bootindex", -1);
                if (!option_rom[nb_option_roms].name) {
                    error_report("Option ROM file is not specified");
                nb_option_roms++;
            case QEMU_OPTION_semihosting:
                semihosting.enabled = true;
                semihosting.target = SEMIHOSTING_TARGET_AUTO;
            case QEMU_OPTION_semihosting_config:
                semihosting.enabled = true;
                opts = qemu_opts_parse_noisily(qemu_find_opts("semihosting-config"),
                                               optarg, false);
                if (opts != NULL) {
                    semihosting.enabled = qemu_opt_get_bool(opts, "enable",
                                                            true);
                    const char *target = qemu_opt_get(opts, "target");
                    if (target != NULL) {
                        if (strcmp("native", target) == 0) {
                            semihosting.target = SEMIHOSTING_TARGET_NATIVE;
                        } else if (strcmp("gdb", target) == 0) {
                            semihosting.target = SEMIHOSTING_TARGET_GDB;
                        } else  if (strcmp("auto", target) == 0) {
                            semihosting.target = SEMIHOSTING_TARGET_AUTO;
                        } else {
                            error_report("unsupported semihosting-config %s",
                                         optarg);
                    } else {
                        semihosting.target = SEMIHOSTING_TARGET_AUTO;
                    /* Set semihosting argument count and vector */
                    qemu_opt_foreach(opts, add_semihosting_arg,
                                     &semihosting, NULL);
                } else {
                    error_report("unsupported semihosting-config %s", optarg);
            case QEMU_OPTION_tdf:
                error_report("warning: ignoring deprecated option");
            case QEMU_OPTION_name:
                opts = qemu_opts_parse_noisily(qemu_find_opts("name"),
                                               optarg, true);
                if (!opts) {
            case QEMU_OPTION_prom_env:
                if (nb_prom_envs >= MAX_PROM_ENVS) {
                    error_report("too many prom variables");
                prom_envs[nb_prom_envs] = optarg;
                nb_prom_envs++;
            case QEMU_OPTION_old_param:
                old_param = 1;
            case QEMU_OPTION_clock:
                /* Clock options no longer exist.  Keep this option for
                 * backward compatibility.
                 */
            case QEMU_OPTION_startdate:
                configure_rtc_date_offset(optarg, 1);
            case QEMU_OPTION_rtc:
                opts = qemu_opts_parse_noisily(qemu_find_opts("rtc"), optarg,
                                               false);
                if (!opts) {
                configure_rtc(opts);
            case QEMU_OPTION_tb_size:
                tcg_tb_size = strtol(optarg, NULL, 0);
                if (tcg_tb_size < 0) {
                    tcg_tb_size = 0;
            case QEMU_OPTION_icount:
                icount_opts = qemu_opts_parse_noisily(qemu_find_opts("icount"),
                                                      optarg, true);
                if (!icount_opts) {
            case QEMU_OPTION_incoming:
                if (!incoming) {
                    runstate_set(RUN_STATE_INMIGRATE);
                incoming = optarg;
            case QEMU_OPTION_only_migratable:
                only_migratable = 1;
            case QEMU_OPTION_nodefaults:
                has_defaults = 0;
            case QEMU_OPTION_xen_domid:
                if (!(xen_available())) {
                    error_report("Option not supported for this target");
                xen_domid = atoi(optarg);
            case QEMU_OPTION_xen_create:
                if (!(xen_available())) {
                    error_report("Option not supported for this target");
                xen_mode = XEN_CREATE;
            case QEMU_OPTION_xen_attach:
                if (!(xen_available())) {
                    error_report("Option not supported for this target");
                xen_mode = XEN_ATTACH;
            case QEMU_OPTION_trace:
                g_free(trace_file);
                trace_file = trace_opt_parse(optarg);
            case QEMU_OPTION_readconfig:
                    int ret = qemu_read_config_file(optarg);
                    if (ret < 0) {
                        error_report("read config %s: %s", optarg,
                                     strerror(-ret));
            case QEMU_OPTION_spice:
                olist = qemu_find_opts("spice");
                if (!olist) {
                    error_report("spice support is disabled");
                opts = qemu_opts_parse_noisily(olist, optarg, false);
                if (!opts) {
                display_remote++;
            case QEMU_OPTION_writeconfig:
                    FILE *fp;
                    if (strcmp(optarg, "-") == 0) {
                        fp = stdout;
                    } else {
                        fp = fopen(optarg, "w");
                        if (fp == NULL) {
                            error_report("open %s: %s", optarg,
                                         strerror(errno));
                    qemu_config_write(fp);
                    if (fp != stdout) {
                        fclose(fp);
            case QEMU_OPTION_qtest:
                qtest_chrdev = optarg;
            case QEMU_OPTION_qtest_log:
                qtest_log = optarg;
            case QEMU_OPTION_sandbox:
                opts = qemu_opts_parse_noisily(qemu_find_opts("sandbox"),
                                               optarg, true);
                if (!opts) {
            case QEMU_OPTION_add_fd:
#ifndef _WIN32
                opts = qemu_opts_parse_noisily(qemu_find_opts("add-fd"),
                                               optarg, false);
                if (!opts) {
#else
                error_report("File descriptor passing is disabled on this "
                             "platform");
#endif
            case QEMU_OPTION_object:
                opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
                                               optarg, true);
                if (!opts) {
            case QEMU_OPTION_realtime:
                opts = qemu_opts_parse_noisily(qemu_find_opts("realtime"),
                                               optarg, false);
                if (!opts) {
                enable_mlock = qemu_opt_get_bool(opts, "mlock", true);
            case QEMU_OPTION_msg:
                opts = qemu_opts_parse_noisily(qemu_find_opts("msg"), optarg,
                                               false);
                if (!opts) {
                configure_msg(opts);
            case QEMU_OPTION_dump_vmstate:
                if (vmstate_dump_file) {
                    error_report("only one '-dump-vmstate' "
                                 "option may be given");
                vmstate_dump_file = fopen(optarg, "w");
                if (vmstate_dump_file == NULL) {
                    error_report("open %s: %s", optarg, strerror(errno));
            default:
                os_parse_cmd_args(popt->index, optarg);
    /*
     * Clear error location left behind by the loop.
     * Best done right after the loop.  Do not insert code here!
     */
    loc_set_none();
    replay_configure(icount_opts);
    qemu_tcg_configure(accel_opts, &error_fatal);
    machine_class = select_machine();
    set_memory_options(&ram_slots, &maxram_size, machine_class);
    os_daemonize();
    if (pid_file && qemu_create_pidfile(pid_file) != 0) {
        error_report("could not acquire pid file: %s", strerror(errno));
    if (qemu_init_main_loop(&main_loop_err)) {
        error_report_err(main_loop_err);
    if (qemu_opts_foreach(qemu_find_opts("sandbox"),
                          parse_sandbox, NULL, NULL)) {
    if (qemu_opts_foreach(qemu_find_opts("name"),
                          parse_name, NULL, NULL)) {
#ifndef _WIN32
    if (qemu_opts_foreach(qemu_find_opts("add-fd"),
                          parse_add_fd, NULL, NULL)) {
    if (qemu_opts_foreach(qemu_find_opts("add-fd"),
                          cleanup_add_fd, NULL, NULL)) {
#endif
    current_machine = MACHINE(object_new(object_class_get_name(
                          OBJECT_CLASS(machine_class))));
    if (machine_help_func(qemu_get_machine_opts(), current_machine)) {
        exit(0);
    object_property_add_child(object_get_root(), "machine",
                              OBJECT(current_machine), &error_abort);
    if (machine_class->minimum_page_bits) {
        if (!set_preferred_target_page_bits(machine_class->minimum_page_bits)) {
            /* This would be a board error: specifying a minimum smaller than
             * a target's compile-time fixed setting.
             */
            g_assert_not_reached();
    cpu_exec_init_all();
    if (machine_class->hw_version) {
        qemu_set_hw_version(machine_class->hw_version);
    if (cpu_model && is_help_option(cpu_model)) {
        list_cpus(stdout, &fprintf, cpu_model);
        exit(0);
    if (!trace_init_backends()) {
    trace_init_file(trace_file);
    /* Open the logfile at this point and set the log mask if necessary.
     */
    if (log_file) {
        qemu_set_log_filename(log_file, &error_fatal);
    if (log_mask) {
        int mask;
        mask = qemu_str_to_log_mask(log_mask);
        if (!mask) {
            qemu_print_log_usage(stdout);
        qemu_set_log(mask);
    } else {
        qemu_set_log(0);
    /* If no data_dir is specified then try to find it relative to the
       executable path.  */
    if (data_dir_idx < ARRAY_SIZE(data_dir)) {
        data_dir[data_dir_idx] = os_find_datadir();
        if (data_dir[data_dir_idx] != NULL) {
            data_dir_idx++;
    /* If all else fails use the install path specified when building. */
    if (data_dir_idx < ARRAY_SIZE(data_dir)) {
        data_dir[data_dir_idx++] = CONFIG_QEMU_DATADIR;
    /* -L help lists the data directories and exits. */
    if (list_data_dirs) {
        for (i = 0; i < data_dir_idx; i++) {
            printf("%s\n", data_dir[i]);
        exit(0);
    smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
    machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */
    if (max_cpus > machine_class->max_cpus) {
        error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
                     "supported by machine '%s' (%d)", max_cpus,
                     machine_class->name, machine_class->max_cpus);
    /*
     * Get the default machine options from the machine if it is not already
     * specified either by the configuration file or by the command line.
     */
    if (machine_class->default_machine_opts) {
        qemu_opts_set_defaults(qemu_find_opts("machine"),
                               machine_class->default_machine_opts, 0);
    qemu_opts_foreach(qemu_find_opts("device"),
                      default_driver_check, NULL, NULL);
    qemu_opts_foreach(qemu_find_opts("global"),
                      default_driver_check, NULL, NULL);
    if (!vga_model && !default_vga) {
        vga_interface_type = VGA_DEVICE;
    if (!has_defaults || machine_class->no_serial) {
        default_serial = 0;
    if (!has_defaults || machine_class->no_parallel) {
        default_parallel = 0;
    if (!has_defaults || !machine_class->use_virtcon) {
        default_virtcon = 0;
    if (!has_defaults || !machine_class->use_sclp) {
        default_sclp = 0;
    if (!has_defaults || machine_class->no_floppy) {
        default_floppy = 0;
    if (!has_defaults || machine_class->no_cdrom) {
        default_cdrom = 0;
    if (!has_defaults || machine_class->no_sdcard) {
        default_sdcard = 0;
    if (!has_defaults) {
        default_monitor = 0;
        default_net = 0;
        default_vga = 0;
    if (is_daemonized()) {
        /* According to documentation and historically, -nographic redirects
         * serial port, parallel port and monitor to stdio, which does not work
         * with -daemonize.  We can redirect these to null instead, but since
         * -nographic is legacy, let's just error out.
         * We disallow -nographic only if all other ports are not redirected
         * explicitly, to not break existing legacy setups which uses
         * -nographic _and_ redirects all ports explicitly - this is valid
         * usage, -nographic is just a no-op in this case.
         */
        if (nographic
            && (default_parallel || default_serial
                || default_monitor || default_virtcon)) {
            error_report("-nographic cannot be used with -daemonize");
#ifdef CONFIG_CURSES
        if (display_type == DT_CURSES) {
            error_report("curses display cannot be used with -daemonize");
#endif
    if (nographic) {
        if (default_parallel)
            add_device_config(DEV_PARALLEL, "null");
        if (default_serial && default_monitor) {
            add_device_config(DEV_SERIAL, "mon:stdio");
        } else if (default_virtcon && default_monitor) {
            add_device_config(DEV_VIRTCON, "mon:stdio");
        } else if (default_sclp && default_monitor) {
            add_device_config(DEV_SCLP, "mon:stdio");
        } else {
            if (default_serial)
                add_device_config(DEV_SERIAL, "stdio");
            if (default_virtcon)
                add_device_config(DEV_VIRTCON, "stdio");
            if (default_sclp) {
                add_device_config(DEV_SCLP, "stdio");
            if (default_monitor)
                monitor_parse("stdio", "readline", false);
    } else {
        if (default_serial)
            add_device_config(DEV_SERIAL, "vc:80Cx24C");
        if (default_parallel)
            add_device_config(DEV_PARALLEL, "vc:80Cx24C");
        if (default_monitor)
            monitor_parse("vc:80Cx24C", "readline", false);
        if (default_virtcon)
            add_device_config(DEV_VIRTCON, "vc:80Cx24C");
        if (default_sclp) {
            add_device_config(DEV_SCLP, "vc:80Cx24C");
#if defined(CONFIG_VNC)
    if (!QTAILQ_EMPTY(&(qemu_find_opts("vnc")->head))) {
        display_remote++;
#endif
    if (display_type == DT_DEFAULT && !display_remote) {
#if defined(CONFIG_GTK)
        display_type = DT_GTK;
#elif defined(CONFIG_SDL)
        display_type = DT_SDL;
#elif defined(CONFIG_COCOA)
        display_type = DT_COCOA;
#elif defined(CONFIG_VNC)
        vnc_parse("localhost:0,to=99,id=default", &error_abort);
#else
        display_type = DT_NONE;
#endif
    if ((no_frame || alt_grab || ctrl_grab) && display_type != DT_SDL) {
        error_report("-no-frame, -alt-grab and -ctrl-grab are only valid "
                     "for SDL, ignoring option");
    if (no_quit && (display_type != DT_GTK && display_type != DT_SDL)) {
        error_report("-no-quit is only valid for GTK and SDL, "
                     "ignoring option");
    if (display_type == DT_GTK) {
        early_gtk_display_init(request_opengl);
    if (display_type == DT_SDL) {
        sdl_display_early_init(request_opengl);
    qemu_console_early_init();
    if (request_opengl == 1 && display_opengl == 0) {
#if defined(CONFIG_OPENGL)
        error_report("OpenGL is not supported by the display");
#else
        error_report("OpenGL support is disabled");
#endif
    page_size_init();
    socket_init();
    if (qemu_opts_foreach(qemu_find_opts("object"),
                          user_creatable_add_opts_foreach,
                          object_create_initial, NULL)) {
    if (qemu_opts_foreach(qemu_find_opts("chardev"),
                          chardev_init_func, NULL, NULL)) {
#ifdef CONFIG_VIRTFS
    if (qemu_opts_foreach(qemu_find_opts("fsdev"),
                          fsdev_init_func, NULL, NULL)) {
#endif
    if (qemu_opts_foreach(qemu_find_opts("device"),
                          device_help_func, NULL, NULL)) {
        exit(0);
    machine_opts = qemu_get_machine_opts();
    if (qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
                         NULL)) {
        object_unref(OBJECT(current_machine));
    configure_accelerator(current_machine);
    if (qtest_chrdev) {
        qtest_init(qtest_chrdev, qtest_log, &error_fatal);
    machine_opts = qemu_get_machine_opts();
    kernel_filename = qemu_opt_get(machine_opts, "kernel");
    initrd_filename = qemu_opt_get(machine_opts, "initrd");
    kernel_cmdline = qemu_opt_get(machine_opts, "append");
    bios_name = qemu_opt_get(machine_opts, "firmware");
    opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL);
    if (opts) {
        boot_order = qemu_opt_get(opts, "order");
        if (boot_order) {
            validate_bootdevices(boot_order, &error_fatal);
        boot_once = qemu_opt_get(opts, "once");
        if (boot_once) {
            validate_bootdevices(boot_once, &error_fatal);
        boot_menu = qemu_opt_get_bool(opts, "menu", boot_menu);
        boot_strict = qemu_opt_get_bool(opts, "strict", false);
    if (!boot_order) {
        boot_order = machine_class->default_boot_order;
    if (!kernel_cmdline) {
        kernel_cmdline = "";
        current_machine->kernel_cmdline = (char *)kernel_cmdline;
    linux_boot = (kernel_filename != NULL);
    if (!linux_boot && *kernel_cmdline != '\0') {
        error_report("-append only allowed with -kernel option");
    if (!linux_boot && initrd_filename != NULL) {
        error_report("-initrd only allowed with -kernel option");
    if (semihosting_enabled() && !semihosting_get_argc() && kernel_filename) {
        /* fall back to the -kernel/-append */
        semihosting_arg_fallback(kernel_filename, kernel_cmdline);
    os_set_line_buffering();
    /* spice needs the timers to be initialized by this point */
    qemu_spice_init();
    cpu_ticks_init();
    if (icount_opts) {
        if (!tcg_enabled()) {
            error_report("-icount is not allowed with hardware virtualization");
        } else if (qemu_tcg_mttcg_enabled()) {
            error_report("-icount does not currently work with MTTCG");
        configure_icount(icount_opts, &error_abort);
        qemu_opts_del(icount_opts);
    if (default_net) {
        QemuOptsList *net = qemu_find_opts("net");
        qemu_opts_set(net, NULL, "type", "nic", &error_abort);
#ifdef CONFIG_SLIRP
        qemu_opts_set(net, NULL, "type", "user", &error_abort);
#endif
    colo_info_init();
    if (net_init_clients() < 0) {
    if (qemu_opts_foreach(qemu_find_opts("object"),
                          user_creatable_add_opts_foreach,
                          object_create_delayed, NULL)) {
#ifdef CONFIG_TPM
    if (tpm_init() < 0) {
#endif
    /* init the bluetooth world */
    if (foreach_device_config(DEV_BT, bt_parse))
    if (!xen_enabled()) {
        /* On 32-bit hosts, QEMU is limited by virtual address space */
        if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {
            error_report("at most 2047 MB RAM can be simulated");
    blk_mig_init();
    ram_mig_init();
    /* If the currently selected machine wishes to override the units-per-bus
     * property of its default HBA interface type, do so now. */
    if (machine_class->units_per_default_bus) {
        override_max_devs(machine_class->block_default_type,
                          machine_class->units_per_default_bus);
    /* open the virtual block devices */
    while (!QSIMPLEQ_EMPTY(&bdo_queue)) {
        BlockdevOptions_queue *bdo = QSIMPLEQ_FIRST(&bdo_queue);
        QSIMPLEQ_REMOVE_HEAD(&bdo_queue, entry);
        loc_push_restore(&bdo->loc);
        qmp_blockdev_add(bdo->bdo, &error_fatal);
        loc_pop(&bdo->loc);
        qapi_free_BlockdevOptions(bdo->bdo);
        g_free(bdo);
    if (snapshot || replay_mode != REPLAY_MODE_NONE) {
        qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot,
                          NULL, NULL);
    if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func,
                          &machine_class->block_default_type, NULL)) {
    default_drive(default_cdrom, snapshot, machine_class->block_default_type, 2,
                  CDROM_OPTS);
    default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS);
    default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS);
    parse_numa_opts(machine_class);
    if (qemu_opts_foreach(qemu_find_opts("mon"),
                          mon_init_func, NULL, NULL)) {
    if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
    if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)
    if (foreach_device_config(DEV_VIRTCON, virtcon_parse) < 0)
    if (foreach_device_config(DEV_SCLP, sclp_parse) < 0) {
    if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
    /* If no default VGA is requested, the default is "none".  */
    if (default_vga) {
        if (machine_class->default_display) {
            vga_model = machine_class->default_display;
        } else if (vga_interface_available(VGA_CIRRUS)) {
            vga_model = "cirrus";
        } else if (vga_interface_available(VGA_STD)) {
            vga_model = "std";
    if (vga_model) {
        select_vgahw(vga_model);
    if (watchdog) {
        i = select_watchdog(watchdog);
        if (i > 0)
            exit (i == 1 ? 1 : 0);
    machine_register_compat_props(current_machine);
    qemu_opts_foreach(qemu_find_opts("global"),
                      global_init_func, NULL, NULL);
    /* This checkpoint is required by replay to separate prior clock
       reading from the other reads, because timer polling functions query
       clock values from the log. */
    replay_checkpoint(CHECKPOINT_INIT);
    qdev_machine_init();
    current_machine->ram_size = ram_size;
    current_machine->maxram_size = maxram_size;
    current_machine->ram_slots = ram_slots;
    current_machine->boot_order = boot_order;
    current_machine->cpu_model = cpu_model;
    machine_class->init(current_machine);
    realtime_init();
    audio_init();
    if (hax_enabled()) {
        hax_sync_vcpus();
    if (qemu_opts_foreach(qemu_find_opts("fw_cfg"),
                          parse_fw_cfg, fw_cfg_find(), NULL) != 0) {
    /* init USB devices */
    if (machine_usb(current_machine)) {
        if (foreach_device_config(DEV_USB, usb_parse) < 0)
    /* Check if IGD GFX passthrough. */
    igd_gfx_passthru();
    /* init generic devices */
    rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE);
    if (qemu_opts_foreach(qemu_find_opts("device"),
                          device_init_func, NULL, NULL)) {
    cpu_synchronize_all_post_init();
    numa_post_machine_init();
    rom_reset_order_override();
    /*
     * Create frontends for -drive if=scsi leftovers.
     * Normally, frontends for -drive get created by machine
     * initialization for onboard SCSI HBAs.  However, we create a few
     * more ever since SCSI qdevification, but this is pretty much an
     * implementation accident, and deprecated.
     */
    scsi_legacy_handle_cmdline();
    /* Did we create any drives that we failed to create a device for? */
    drive_check_orphaned();
    /* Don't warn about the default network setup that you get if
     * no command line -net or -netdev options are specified. There
     * are two cases that we would otherwise complain about:
     * (1) board doesn't support a NIC but the implicit "-net nic"
     * requested one
     * (2) CONFIG_SLIRP not set, in which case the implicit "-net nic"
     * sets up a nic that isn't connected to anything.
     */
    if (!default_net) {
        net_check_clients();
    if (boot_once) {
        qemu_boot_set(boot_once, &error_fatal);
        qemu_register_reset(restore_boot_order, g_strdup(boot_order));
    ds = init_displaystate();
    /* init local displays */
    switch (display_type) {
    case DT_CURSES:
        curses_display_init(ds, full_screen);
    case DT_SDL:
        sdl_display_init(ds, full_screen, no_frame);
    case DT_COCOA:
        cocoa_display_init(ds, full_screen);
    case DT_GTK:
        gtk_display_init(ds, full_screen, grab_on_hover);
    default:
    /* must be after terminal init, SDL library changes signal handlers */
    os_setup_signal_handling();
    /* init remote displays */
#ifdef CONFIG_VNC
    qemu_opts_foreach(qemu_find_opts("vnc"),
                      vnc_init_func, NULL, NULL);
#endif
    if (using_spice) {
        qemu_spice_display_init();
    if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
    qdev_machine_creation_done();
    /* TODO: once all bus devices are qdevified, this should be done
     * when bus is created by qdev.c */
    qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
    qemu_run_machine_init_done_notifiers();
    if (rom_check_and_register_reset() != 0) {
        error_report("rom check and register reset failed");
    replay_start();
    /* This checkpoint is required by replay to separate prior clock
       reading from the other reads, because timer polling functions query
       clock values from the log. */
    replay_checkpoint(CHECKPOINT_RESET);
    qemu_system_reset(VMRESET_SILENT);
    register_global_state();
    if (replay_mode != REPLAY_MODE_NONE) {
        replay_vmstate_init();
    } else if (loadvm) {
        if (load_vmstate(loadvm) < 0) {
            autostart = 0;
    qdev_prop_check_globals();
    if (vmstate_dump_file) {
        /* dump and exit */
        dump_vmstate_json_to_file(vmstate_dump_file);
        return 0;
    if (incoming) {
        Error *local_err = NULL;
        qemu_start_incoming_migration(incoming, &local_err);
        if (local_err) {
            error_reportf_err(local_err, "-incoming %s: ", incoming);
    } else if (autostart) {
        vm_start();
    os_setup_post();
    main_loop();
    replay_disable_events();
    iothread_stop_all();
    bdrv_close_all();
    pause_all_vcpus();
    res_free();
    /* vhost-user must be cleaned up before chardevs.  */
    net_cleanup();
    audio_cleanup();
    monitor_cleanup();
    qemu_chr_cleanup();
    return 0;


static void qmp_command_info(QmpCommand *cmd, void *opaque)

{

    GuestAgentInfo *info = opaque;

    GuestAgentCommandInfo *cmd_info;

    GuestAgentCommandInfoList *cmd_info_list;

    cmd_info = g_malloc0(sizeof(GuestAgentCommandInfo));

    cmd_info->name = g_strdup(qmp_command_name(cmd));

    cmd_info->enabled = qmp_command_is_enabled(cmd);

    cmd_info->success_response = qmp_has_success_response(cmd);

    cmd_info_list = g_malloc0(sizeof(GuestAgentCommandInfoList));

    cmd_info_list->value = cmd_info;

    cmd_info_list->next = info->supported_commands;

    info->supported_commands = cmd_info_list;

}


av_cold void ff_mpeg1_encode_init(MpegEncContext *s)

{

    static int done = 0;

    ff_mpeg12_common_init(s);

    if (!done) {

        int f_code;

        int mv;

        int i;

        done = 1;

        ff_rl_init(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]);

        ff_rl_init(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]);

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

            mpeg1_max_level[0][i] = ff_rl_mpeg1.max_level[0][i];

            mpeg1_index_run[0][i] = ff_rl_mpeg1.index_run[0][i];

        }

        init_uni_ac_vlc(&ff_rl_mpeg1, uni_mpeg1_ac_vlc_len);

        if (s->intra_vlc_format)

            init_uni_ac_vlc(&ff_rl_mpeg2, uni_mpeg2_ac_vlc_len);

        /* build unified dc encoding tables */

        for (i = -255; i < 256; i++) {

            int adiff, index;

            int bits, code;

            int diff = i;

            adiff = FFABS(diff);

            if (diff < 0)

                diff--;

            index = av_log2(2 * adiff);

            bits = ff_mpeg12_vlc_dc_lum_bits[index] + index;

            code = (ff_mpeg12_vlc_dc_lum_code[index] << index) +

                    av_mod_uintp2(diff, index);

            mpeg1_lum_dc_uni[i + 255] = bits + (code << 8);

            bits = ff_mpeg12_vlc_dc_chroma_bits[index] + index;

            code = (ff_mpeg12_vlc_dc_chroma_code[index] << index) +

                    av_mod_uintp2(diff, index);

            mpeg1_chr_dc_uni[i + 255] = bits + (code << 8);

        }

        for (f_code = 1; f_code <= MAX_FCODE; f_code++)

            for (mv = -MAX_MV; mv <= MAX_MV; mv++) {

                int len;

                if (mv == 0) {

                    len = ff_mpeg12_mbMotionVectorTable[0][1];

                } else {

                    int val, bit_size, code;

                    bit_size = f_code - 1;

                    val = mv;

                    if (val < 0)

                        val = -val;

                    val--;

                    code = (val >> bit_size) + 1;

                    if (code < 17)

                        len = ff_mpeg12_mbMotionVectorTable[code][1] +

                              1 + bit_size;

                    else

                        len = ff_mpeg12_mbMotionVectorTable[16][1] +

                              2 + bit_size;

                }

                mv_penalty[f_code][mv + MAX_MV] = len;

            }

        for (f_code = MAX_FCODE; f_code > 0; f_code--)

            for (mv = -(8 << f_code); mv < (8 << f_code); mv++)

                fcode_tab[mv + MAX_MV] = f_code;

    }

    s->me.mv_penalty = mv_penalty;

    s->fcode_tab     = fcode_tab;

    if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO) {

        s->min_qcoeff = -255;

        s->max_qcoeff = 255;

    } else {

        s->min_qcoeff = -2047;

        s->max_qcoeff = 2047;

    }

    if (s->intra_vlc_format) {

        s->intra_ac_vlc_length      =

        s->intra_ac_vlc_last_length = uni_mpeg2_ac_vlc_len;

    } else {

        s->intra_ac_vlc_length      =

        s->intra_ac_vlc_last_length = uni_mpeg1_ac_vlc_len;

    }

    s->inter_ac_vlc_length      =

    s->inter_ac_vlc_last_length = uni_mpeg1_ac_vlc_len;

}


void av_opt_set_defaults(void *s)

{

    av_opt_set_defaults2(s, 0, 0);

}


static inline void RENAME(yv12toyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst,

	long width, long height,

	long lumStride, long chromStride, long dstStride)

{

	//FIXME interpolate chroma

	RENAME(yuvPlanartoyuy2)(ysrc, usrc, vsrc, dst, width, height, lumStride, chromStride, dstStride, 2);

}


PPC_OP(check_reservation)

{

    if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003))

        env->reserve = -1;

    RETURN();

}


int ff_mjpeg_decode_sos(MJpegDecodeContext *s)

{

    int len, nb_components, i, h, v, predictor, point_transform;

    int index, id;

    const int block_size= s->lossless ? 1 : 8;

    int ilv, prev_shift;

    /* XXX: verify len field validity */

    len = get_bits(&s->gb, 16);

    nb_components = get_bits(&s->gb, 8);

    if (len != 6+2*nb_components)

    {

        av_log(s->avctx, AV_LOG_ERROR, "decode_sos: invalid len (%d)\n", len);

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

        id = get_bits(&s->gb, 8) - 1;

        av_log(s->avctx, AV_LOG_DEBUG, "component: %d\n", id);

        /* find component index */

        for(index=0;index<s->nb_components;index++)

            if (id == s->component_id[index])

                break;

        if (index == s->nb_components)

        {

            av_log(s->avctx, AV_LOG_ERROR, "decode_sos: index(%d) out of components\n", index);

        s->comp_index[i] = index;

        s->nb_blocks[i] = s->h_count[index] * s->v_count[index];

        s->h_scount[i] = s->h_count[index];

        s->v_scount[i] = s->v_count[index];

        s->dc_index[i] = get_bits(&s->gb, 4);

        s->ac_index[i] = get_bits(&s->gb, 4);

        if (s->dc_index[i] <  0 || s->ac_index[i] < 0 ||

            s->dc_index[i] >= 4 || s->ac_index[i] >= 4)

            goto out_of_range;

        if (!s->vlcs[0][s->dc_index[i]].table || !s->vlcs[1][s->ac_index[i]].table)

            goto out_of_range;

    predictor= get_bits(&s->gb, 8); /* JPEG Ss / lossless JPEG predictor /JPEG-LS NEAR */

    ilv= get_bits(&s->gb, 8);    /* JPEG Se / JPEG-LS ILV */

    prev_shift = get_bits(&s->gb, 4); /* Ah */

    point_transform= get_bits(&s->gb, 4); /* Al */

    for(i=0;i<nb_components;i++)

        s->last_dc[i] = 1024;

    if (nb_components > 1) {

        /* interleaved stream */

        s->mb_width  = (s->width  + s->h_max * block_size - 1) / (s->h_max * block_size);

        s->mb_height = (s->height + s->v_max * block_size - 1) / (s->v_max * block_size);

    } else if(!s->ls) { /* skip this for JPEG-LS */

        h = s->h_max / s->h_scount[0];

        v = s->v_max / s->v_scount[0];

        s->mb_width  = (s->width  + h * block_size - 1) / (h * block_size);

        s->mb_height = (s->height + v * block_size - 1) / (v * block_size);

        s->nb_blocks[0] = 1;

        s->h_scount[0] = 1;

        s->v_scount[0] = 1;

    if(s->avctx->debug & FF_DEBUG_PICT_INFO)

        av_log(s->avctx, AV_LOG_DEBUG, "%s %s p:%d >>:%d ilv:%d bits:%d %s\n", s->lossless ? "lossless" : "sequencial DCT", s->rgb ? "RGB" : "",

               predictor, point_transform, ilv, s->bits,

               s->pegasus_rct ? "PRCT" : (s->rct ? "RCT" : ""));

    /* mjpeg-b can have padding bytes between sos and image data, skip them */

    for (i = s->mjpb_skiptosod; i > 0; i--)

        skip_bits(&s->gb, 8);

    if(s->lossless){

        if(CONFIG_JPEGLS_DECODER && s->ls){

//            for(){

//            reset_ls_coding_parameters(s, 0);

            if(ff_jpegls_decode_picture(s, predictor, point_transform, ilv) < 0)

        }else{

            if(s->rgb){

                if(ljpeg_decode_rgb_scan(s, predictor, point_transform) < 0)

            }else{

                if(ljpeg_decode_yuv_scan(s, predictor, point_transform) < 0)

    }else{

        if(s->progressive && predictor) {

            if(mjpeg_decode_scan_progressive_ac(s, predictor, ilv, prev_shift, point_transform) < 0)

        } else {

            if(mjpeg_decode_scan(s, nb_components, prev_shift, point_transform) < 0)

    emms_c();

    return 0;

 out_of_range:

    av_log(s->avctx, AV_LOG_ERROR, "decode_sos: ac/dc index out of range\n");


static void adx_decode(short *out,const unsigned char *in,PREV *prev)

{

	int scale = ((in[0]<<8)|(in[1]));

	int i;

	int s0,s1,s2,d;

//	printf("%x ",scale);

	in+=2;

	s1 = prev->s1;

	s2 = prev->s2;

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

		d = in[i];

		// d>>=4; if (d&8) d-=16;

		d = ((signed char)d >> 4);

		s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14;

		CLIP(s0);

		*out++=s0;

		s2 = s1;

		s1 = s0;

		d = in[i];

		//d&=15; if (d&8) d-=16;

		d = ((signed char)(d<<4) >> 4);

		s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14;

		CLIP(s0);

		*out++=s0;

		s2 = s1;

		s1 = s0;

	}

	prev->s1 = s1;

	prev->s2 = s2;

}


static void spapr_dr_connector_class_init(ObjectClass *k, void *data)

{

    DeviceClass *dk = DEVICE_CLASS(k);

    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);

    dk->reset = reset;

    dk->realize = realize;

    dk->unrealize = unrealize;

    drck->set_isolation_state = set_isolation_state;

    drck->set_indicator_state = set_indicator_state;

    drck->set_allocation_state = set_allocation_state;

    drck->get_index = get_index;

    drck->get_type = get_type;

    drck->get_name = get_name;

    drck->get_fdt = get_fdt;

    drck->set_configured = set_configured;

    drck->entity_sense = entity_sense;

    drck->attach = attach;

    drck->detach = detach;

    drck->release_pending = release_pending;

}


int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf,

                          const uint8_t *searched_pc)

{

    return tcg_gen_code_common(s, gen_code_buf, 1, searched_pc);

}


static av_cold int libopus_decode_init(AVCodecContext *avc)
{
    struct libopus_context *opus = avc->priv_data;
    int ret, channel_map = 0, gain_db = 0, nb_streams, nb_coupled;
    uint8_t mapping_arr[8] = { 0, 1 }, *mapping;
    avc->sample_rate    = 48000;
    avc->sample_fmt     = avc->request_sample_fmt == AV_SAMPLE_FMT_FLT ?
                          AV_SAMPLE_FMT_FLT : AV_SAMPLE_FMT_S16;
    avc->channel_layout = avc->channels > 8 ? 0 :
                          ff_vorbis_channel_layouts[avc->channels - 1];
    if (avc->extradata_size >= OPUS_HEAD_SIZE) {
        gain_db     = sign_extend(AV_RL16(avc->extradata + 16), 16);
        channel_map = AV_RL8 (avc->extradata + 18);
    if (avc->extradata_size >= OPUS_HEAD_SIZE + 2 + avc->channels) {
        nb_streams = avc->extradata[OPUS_HEAD_SIZE + 0];
        nb_coupled = avc->extradata[OPUS_HEAD_SIZE + 1];
        if (nb_streams + nb_coupled != avc->channels)
            av_log(avc, AV_LOG_WARNING, "Inconsistent channel mapping.\n");
        mapping = avc->extradata + OPUS_HEAD_SIZE + 2;
    } else {
        if (avc->channels > 2 || channel_map) {
            av_log(avc, AV_LOG_ERROR,
                   "No channel mapping for %d channels.\n", avc->channels);
            return AVERROR(EINVAL);
        nb_streams = 1;
        nb_coupled = avc->channels > 1;
        mapping    = mapping_arr;
    if (avc->channels > 2 && avc->channels <= 8) {
        const uint8_t *vorbis_offset = ff_vorbis_channel_layout_offsets[avc->channels - 1];
        int ch;
        /* Remap channels from Vorbis order to libav order */
        for (ch = 0; ch < avc->channels; ch++)
            mapping_arr[ch] = mapping[vorbis_offset[ch]];
        mapping = mapping_arr;
    opus->dec = opus_multistream_decoder_create(avc->sample_rate, avc->channels,
                                                nb_streams, nb_coupled,
                                                mapping, &ret);
    if (!opus->dec) {
        av_log(avc, AV_LOG_ERROR, "Unable to create decoder: %s\n",
               opus_strerror(ret));
        return ff_opus_error_to_averror(ret);
    ret = opus_multistream_decoder_ctl(opus->dec, OPUS_SET_GAIN(gain_db));
    if (ret != OPUS_OK)
        av_log(avc, AV_LOG_WARNING, "Failed to set gain: %s\n",
               opus_strerror(ret));
    avc->delay = 3840;  /* Decoder delay (in samples) at 48kHz */
    return 0;


gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,

                               int search_pc)

{

    uint16_t *gen_opc_end;

    uint32_t pc_start;

    unsigned int insn_len;

    int j, lj;

    struct DisasContext ctx;

    struct DisasContext *dc = &ctx;

    uint32_t next_page_start;

    target_ulong npc;

    int num_insns;

    int max_insns;

    qemu_log_try_set_file(stderr);

    if (env->pregs[PR_VR] == 32) {

        dc->decoder = crisv32_decoder;

        dc->clear_locked_irq = 0;

    } else {

        dc->decoder = crisv10_decoder;

        dc->clear_locked_irq = 1;

    }

    /* Odd PC indicates that branch is rexecuting due to exception in the

     * delayslot, like in real hw.

     */

    pc_start = tb->pc & ~1;

    dc->env = env;

    dc->tb = tb;

    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;

    dc->is_jmp = DISAS_NEXT;

    dc->ppc = pc_start;

    dc->pc = pc_start;

    dc->singlestep_enabled = env->singlestep_enabled;

    dc->flags_uptodate = 1;

    dc->flagx_known = 1;

    dc->flags_x = tb->flags & X_FLAG;

    dc->cc_x_uptodate = 0;

    dc->cc_mask = 0;

    dc->update_cc = 0;

    dc->clear_prefix = 0;

    cris_update_cc_op(dc, CC_OP_FLAGS, 4);

    dc->cc_size_uptodate = -1;

    /* Decode TB flags.  */

    dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \

            | X_FLAG | PFIX_FLAG);

    dc->delayed_branch = !!(tb->flags & 7);

    if (dc->delayed_branch) {

        dc->jmp = JMP_INDIRECT;

    } else {

        dc->jmp = JMP_NOJMP;

    }

    dc->cpustate_changed = 0;

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {

        qemu_log(

                "srch=%d pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n"

                "pid=%x usp=%x\n"

                "%x.%x.%x.%x\n"

                "%x.%x.%x.%x\n"

                "%x.%x.%x.%x\n"

                "%x.%x.%x.%x\n",

                search_pc, dc->pc, dc->ppc,

                (uint64_t)tb->flags,

                env->btarget, (unsigned)tb->flags & 7,

                env->pregs[PR_CCS],

                env->pregs[PR_PID], env->pregs[PR_USP],

                env->regs[0], env->regs[1], env->regs[2], env->regs[3],

                env->regs[4], env->regs[5], env->regs[6], env->regs[7],

                env->regs[8], env->regs[9],

                env->regs[10], env->regs[11],

                env->regs[12], env->regs[13],

                env->regs[14], env->regs[15]);

        qemu_log("--------------\n");

        qemu_log("IN: %s\n", lookup_symbol(pc_start));

    }

    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;

    lj = -1;

    num_insns = 0;

    max_insns = tb->cflags & CF_COUNT_MASK;

    if (max_insns == 0) {

        max_insns = CF_COUNT_MASK;

    }

    gen_icount_start();

    do {

        check_breakpoint(env, dc);

        if (search_pc) {

            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

            if (lj < j) {

                lj++;

                while (lj < j) {

                    tcg_ctx.gen_opc_instr_start[lj++] = 0;

                }

            }

            if (dc->delayed_branch == 1) {

                tcg_ctx.gen_opc_pc[lj] = dc->ppc | 1;

            } else {

                tcg_ctx.gen_opc_pc[lj] = dc->pc;

            }

            tcg_ctx.gen_opc_instr_start[lj] = 1;

            tcg_ctx.gen_opc_icount[lj] = num_insns;

        }

        /* Pretty disas.  */

        LOG_DIS("%8.8x:\t", dc->pc);

        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {

            gen_io_start();

        }

        dc->clear_x = 1;

        insn_len = dc->decoder(env, dc);

        dc->ppc = dc->pc;

        dc->pc += insn_len;

        if (dc->clear_x) {

            cris_clear_x_flag(dc);

        }

        num_insns++;

        /* Check for delayed branches here. If we do it before

           actually generating any host code, the simulator will just

           loop doing nothing for on this program location.  */

        if (dc->delayed_branch) {

            dc->delayed_branch--;

            if (dc->delayed_branch == 0) {

                if (tb->flags & 7) {

                    t_gen_mov_env_TN(dslot, tcg_const_tl(0));

                }

                if (dc->cpustate_changed || !dc->flagx_known

                    || (dc->flags_x != (tb->flags & X_FLAG))) {

                    cris_store_direct_jmp(dc);

                }

                if (dc->clear_locked_irq) {

                    dc->clear_locked_irq = 0;

                    t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));

                }

                if (dc->jmp == JMP_DIRECT_CC) {

                    int l1;

                    l1 = gen_new_label();

                    cris_evaluate_flags(dc);

                    /* Conditional jmp.  */

                    tcg_gen_brcondi_tl(TCG_COND_EQ,

                               env_btaken, 0, l1);

                    gen_goto_tb(dc, 1, dc->jmp_pc);

                    gen_set_label(l1);

                    gen_goto_tb(dc, 0, dc->pc);

                    dc->is_jmp = DISAS_TB_JUMP;

                    dc->jmp = JMP_NOJMP;

                } else if (dc->jmp == JMP_DIRECT) {

                    cris_evaluate_flags(dc);

                    gen_goto_tb(dc, 0, dc->jmp_pc);

                    dc->is_jmp = DISAS_TB_JUMP;

                    dc->jmp = JMP_NOJMP;

                } else {

                    t_gen_cc_jmp(env_btarget, tcg_const_tl(dc->pc));

                    dc->is_jmp = DISAS_JUMP;

                }

                break;

            }

        }

        /* If we are rexecuting a branch due to exceptions on

           delay slots dont break.  */

        if (!(tb->pc & 1) && env->singlestep_enabled) {

            break;

        }

    } while (!dc->is_jmp && !dc->cpustate_changed

            && tcg_ctx.gen_opc_ptr < gen_opc_end

            && !singlestep

            && (dc->pc < next_page_start)

            && num_insns < max_insns);

    if (dc->clear_locked_irq) {

        t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));

    }

    npc = dc->pc;

        if (tb->cflags & CF_LAST_IO)

            gen_io_end();

    /* Force an update if the per-tb cpu state has changed.  */

    if (dc->is_jmp == DISAS_NEXT

        && (dc->cpustate_changed || !dc->flagx_known

        || (dc->flags_x != (tb->flags & X_FLAG)))) {

        dc->is_jmp = DISAS_UPDATE;

        tcg_gen_movi_tl(env_pc, npc);

    }

    /* Broken branch+delayslot sequence.  */

    if (dc->delayed_branch == 1) {

        /* Set env->dslot to the size of the branch insn.  */

        t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));

        cris_store_direct_jmp(dc);

    }

    cris_evaluate_flags(dc);

    if (unlikely(env->singlestep_enabled)) {

        if (dc->is_jmp == DISAS_NEXT) {

            tcg_gen_movi_tl(env_pc, npc);

        }

        t_gen_raise_exception(EXCP_DEBUG);

    } else {

        switch (dc->is_jmp) {

        case DISAS_NEXT:

            gen_goto_tb(dc, 1, npc);

            break;

        default:

        case DISAS_JUMP:

        case DISAS_UPDATE:

            /* indicate that the hash table must be used

                   to find the next TB */

            tcg_gen_exit_tb(0);

            break;

        case DISAS_SWI:

        case DISAS_TB_JUMP:

            /* nothing more to generate */

            break;

        }

    }

    gen_icount_end(tb, num_insns);

    *tcg_ctx.gen_opc_ptr = INDEX_op_end;

    if (search_pc) {

        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

        lj++;

        while (lj <= j) {

            tcg_ctx.gen_opc_instr_start[lj++] = 0;

        }

    } else {

        tb->size = dc->pc - pc_start;

        tb->icount = num_insns;

    }

#ifdef DEBUG_DISAS

#if !DISAS_CRIS

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {

        log_target_disas(env, pc_start, dc->pc - pc_start,

                                 dc->env->pregs[PR_VR]);

        qemu_log("\nisize=%d osize=%td\n",

            dc->pc - pc_start, tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf);

    }

#endif

#endif

}


int fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,

                        void *callback_opaque, uint8_t *data, size_t len)

{

    int arch = !!(key & FW_CFG_ARCH_LOCAL);

    if (!(key & FW_CFG_WRITE_CHANNEL))

        return 0;

    key &= FW_CFG_ENTRY_MASK;

    if (key >= FW_CFG_MAX_ENTRY || len > 65535)

        return 0;

    s->entries[arch][key].data = data;

    s->entries[arch][key].len = len;

    s->entries[arch][key].callback_opaque = callback_opaque;

    s->entries[arch][key].callback = callback;

    return 1;

}


void do_subfmeo_64 (void)

{

    T1 = T0;

    T0 = ~T0 + xer_ca - 1;

    if (likely(!((uint64_t)~T1 & ((uint64_t)~T1 ^ (uint64_t)T0) &

                 (1ULL << 63)))) {

        xer_ov = 0;

    } else {

        xer_so = 1;

        xer_ov = 1;

    }

    if (likely((uint64_t)T1 != UINT64_MAX))

        xer_ca = 1;

}


static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s)

{

    int tileno, compno;

    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) {

        if (s->tile[tileno].comp) {

            for (compno = 0; compno < s->ncomponents; compno++) {

                Jpeg2000Component *comp     = s->tile[tileno].comp   + compno;

                Jpeg2000CodingStyle *codsty = s->tile[tileno].codsty + compno;

                ff_jpeg2000_cleanup(comp, codsty);

            }

            av_freep(&s->tile[tileno].comp);

        }

    }

    av_freep(&s->tile);

    s->numXtiles = s->numYtiles = 0;

}


static void quantize_and_encode_band_cost_ESC_mips(struct AACEncContext *s,

                                                   PutBitContext *pb, const float *in, float *out,

                                                   const float *scaled, int size, int scale_idx,

                                                   int cb, const float lambda, const float uplim,

                                                   int *bits, const float ROUNDING)

{

    const float Q34 = ff_aac_pow34sf_tab[POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];

    const float IQ  = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];

    int i;

    int qc1, qc2, qc3, qc4;

    uint8_t  *p_bits    = (uint8_t* )ff_aac_spectral_bits[cb-1];

    uint16_t *p_codes   = (uint16_t*)ff_aac_spectral_codes[cb-1];

    float    *p_vectors = (float*   )ff_aac_codebook_vectors[cb-1];

    abs_pow34_v(s->scoefs, in, size);

    scaled = s->scoefs;

    if (cb < 11) {

        for (i = 0; i < size; i += 4) {

            int curidx, curidx2, sign1, count1, sign2, count2;

            int *in_int = (int *)&in[i];

            uint8_t v_bits;

            unsigned int v_codes;

            int t0, t1, t2, t3, t4;

            const float *vec1, *vec2;

            qc1 = scaled[i  ] * Q34 + ROUNDING;

            qc2 = scaled[i+1] * Q34 + ROUNDING;

            qc3 = scaled[i+2] * Q34 + ROUNDING;

            qc4 = scaled[i+3] * Q34 + ROUNDING;

            __asm__ volatile (

                ".set push                                  \n\t"

                ".set noreorder                             \n\t"

                "ori        %[t4],      $zero,      16      \n\t"

                "ori        %[sign1],   $zero,      0       \n\t"

                "ori        %[sign2],   $zero,      0       \n\t"

                "slt        %[t0],      %[t4],      %[qc1]  \n\t"

                "slt        %[t1],      %[t4],      %[qc2]  \n\t"

                "slt        %[t2],      %[t4],      %[qc3]  \n\t"

                "slt        %[t3],      %[t4],      %[qc4]  \n\t"

                "movn       %[qc1],     %[t4],      %[t0]   \n\t"

                "movn       %[qc2],     %[t4],      %[t1]   \n\t"

                "movn       %[qc3],     %[t4],      %[t2]   \n\t"

                "movn       %[qc4],     %[t4],      %[t3]   \n\t"

                "lw         %[t0],      0(%[in_int])        \n\t"

                "lw         %[t1],      4(%[in_int])        \n\t"

                "lw         %[t2],      8(%[in_int])        \n\t"

                "lw         %[t3],      12(%[in_int])       \n\t"

                "slt        %[t0],      %[t0],      $zero   \n\t"

                "movn       %[sign1],   %[t0],      %[qc1]  \n\t"

                "slt        %[t2],      %[t2],      $zero   \n\t"

                "movn       %[sign2],   %[t2],      %[qc3]  \n\t"

                "slt        %[t1],      %[t1],      $zero   \n\t"

                "sll        %[t0],      %[sign1],   1       \n\t"

                "or         %[t0],      %[t0],      %[t1]   \n\t"

                "movn       %[sign1],   %[t0],      %[qc2]  \n\t"

                "slt        %[t3],      %[t3],      $zero   \n\t"

                "sll        %[t0],      %[sign2],   1       \n\t"

                "or         %[t0],      %[t0],      %[t3]   \n\t"

                "movn       %[sign2],   %[t0],      %[qc4]  \n\t"

                "slt        %[count1],  $zero,      %[qc1]  \n\t"

                "slt        %[t1],      $zero,      %[qc2]  \n\t"

                "slt        %[count2],  $zero,      %[qc3]  \n\t"

                "slt        %[t2],      $zero,      %[qc4]  \n\t"

                "addu       %[count1],  %[count1],  %[t1]   \n\t"

                "addu       %[count2],  %[count2],  %[t2]   \n\t"

                ".set pop                                   \n\t"

                : [qc1]"+r"(qc1), [qc2]"+r"(qc2),

                  [qc3]"+r"(qc3), [qc4]"+r"(qc4),

                  [sign1]"=&r"(sign1), [count1]"=&r"(count1),

                  [sign2]"=&r"(sign2), [count2]"=&r"(count2),

                  [t0]"=&r"(t0), [t1]"=&r"(t1), [t2]"=&r"(t2), [t3]"=&r"(t3),

                  [t4]"=&r"(t4)

                : [in_int]"r"(in_int)

                : "memory"

            );

            curidx = 17 * qc1;

            curidx += qc2;

            curidx2 = 17 * qc3;

            curidx2 += qc4;

            v_codes = (p_codes[curidx] << count1) | sign1;

            v_bits  = p_bits[curidx] + count1;

            put_bits(pb, v_bits, v_codes);

            v_codes = (p_codes[curidx2] << count2) | sign2;

            v_bits  = p_bits[curidx2] + count2;

            put_bits(pb, v_bits, v_codes);

            if (out) {

               vec1 = &p_vectors[curidx*2 ];

               vec2 = &p_vectors[curidx2*2];

               out[i+0] = copysignf(vec1[0] * IQ, in[i+0]);

               out[i+1] = copysignf(vec1[1] * IQ, in[i+1]);

               out[i+2] = copysignf(vec2[0] * IQ, in[i+2]);

               out[i+3] = copysignf(vec2[1] * IQ, in[i+3]);

            }

        }

    } else {

        for (i = 0; i < size; i += 4) {

            int curidx, curidx2, sign1, count1, sign2, count2;

            int *in_int = (int *)&in[i];

            uint8_t v_bits;

            unsigned int v_codes;

            int c1, c2, c3, c4;

            int t0, t1, t2, t3, t4;

            const float *vec1, *vec2;

            qc1 = scaled[i  ] * Q34 + ROUNDING;

            qc2 = scaled[i+1] * Q34 + ROUNDING;

            qc3 = scaled[i+2] * Q34 + ROUNDING;

            qc4 = scaled[i+3] * Q34 + ROUNDING;

            __asm__ volatile (

                ".set push                                  \n\t"

                ".set noreorder                             \n\t"

                "ori        %[t4],      $zero,      16      \n\t"

                "ori        %[sign1],   $zero,      0       \n\t"

                "ori        %[sign2],   $zero,      0       \n\t"

                "shll_s.w   %[c1],      %[qc1],     18      \n\t"

                "shll_s.w   %[c2],      %[qc2],     18      \n\t"

                "shll_s.w   %[c3],      %[qc3],     18      \n\t"

                "shll_s.w   %[c4],      %[qc4],     18      \n\t"

                "srl        %[c1],      %[c1],      18      \n\t"

                "srl        %[c2],      %[c2],      18      \n\t"

                "srl        %[c3],      %[c3],      18      \n\t"

                "srl        %[c4],      %[c4],      18      \n\t"

                "slt        %[t0],      %[t4],      %[qc1]  \n\t"

                "slt        %[t1],      %[t4],      %[qc2]  \n\t"

                "slt        %[t2],      %[t4],      %[qc3]  \n\t"

                "slt        %[t3],      %[t4],      %[qc4]  \n\t"

                "movn       %[qc1],     %[t4],      %[t0]   \n\t"

                "movn       %[qc2],     %[t4],      %[t1]   \n\t"

                "movn       %[qc3],     %[t4],      %[t2]   \n\t"

                "movn       %[qc4],     %[t4],      %[t3]   \n\t"

                "lw         %[t0],      0(%[in_int])        \n\t"

                "lw         %[t1],      4(%[in_int])        \n\t"

                "lw         %[t2],      8(%[in_int])        \n\t"

                "lw         %[t3],      12(%[in_int])       \n\t"

                "slt        %[t0],      %[t0],      $zero   \n\t"

                "movn       %[sign1],   %[t0],      %[qc1]  \n\t"

                "slt        %[t2],      %[t2],      $zero   \n\t"

                "movn       %[sign2],   %[t2],      %[qc3]  \n\t"

                "slt        %[t1],      %[t1],      $zero   \n\t"

                "sll        %[t0],      %[sign1],   1       \n\t"

                "or         %[t0],      %[t0],      %[t1]   \n\t"

                "movn       %[sign1],   %[t0],      %[qc2]  \n\t"

                "slt        %[t3],      %[t3],      $zero   \n\t"

                "sll        %[t0],      %[sign2],   1       \n\t"

                "or         %[t0],      %[t0],      %[t3]   \n\t"

                "movn       %[sign2],   %[t0],      %[qc4]  \n\t"

                "slt        %[count1],  $zero,      %[qc1]  \n\t"

                "slt        %[t1],      $zero,      %[qc2]  \n\t"

                "slt        %[count2],  $zero,      %[qc3]  \n\t"

                "slt        %[t2],      $zero,      %[qc4]  \n\t"

                "addu       %[count1],  %[count1],  %[t1]   \n\t"

                "addu       %[count2],  %[count2],  %[t2]   \n\t"

                ".set pop                                   \n\t"

                : [qc1]"+r"(qc1), [qc2]"+r"(qc2),

                  [qc3]"+r"(qc3), [qc4]"+r"(qc4),

                  [sign1]"=&r"(sign1), [count1]"=&r"(count1),

                  [sign2]"=&r"(sign2), [count2]"=&r"(count2),

                  [c1]"=&r"(c1), [c2]"=&r"(c2),

                  [c3]"=&r"(c3), [c4]"=&r"(c4),

                  [t0]"=&r"(t0), [t1]"=&r"(t1), [t2]"=&r"(t2), [t3]"=&r"(t3),

                  [t4]"=&r"(t4)

                : [in_int]"r"(in_int)

                : "memory"

            );

            curidx = 17 * qc1;

            curidx += qc2;

            curidx2 = 17 * qc3;

            curidx2 += qc4;

            v_codes = (p_codes[curidx] << count1) | sign1;

            v_bits  = p_bits[curidx] + count1;

            put_bits(pb, v_bits, v_codes);

            if (p_vectors[curidx*2  ] == 64.0f) {

                int len = av_log2(c1);

                v_codes = (((1 << (len - 3)) - 2) << len) | (c1 & ((1 << len) - 1));

                put_bits(pb, len * 2 - 3, v_codes);

            }

            if (p_vectors[curidx*2+1] == 64.0f) {

                int len = av_log2(c2);

                v_codes = (((1 << (len - 3)) - 2) << len) | (c2 & ((1 << len) - 1));

                put_bits(pb, len*2-3, v_codes);

            }

            v_codes = (p_codes[curidx2] << count2) | sign2;

            v_bits  = p_bits[curidx2] + count2;

            put_bits(pb, v_bits, v_codes);

            if (p_vectors[curidx2*2  ] == 64.0f) {

                int len = av_log2(c3);

                v_codes = (((1 << (len - 3)) - 2) << len) | (c3 & ((1 << len) - 1));

                put_bits(pb, len* 2 - 3, v_codes);

            }

            if (p_vectors[curidx2*2+1] == 64.0f) {

                int len = av_log2(c4);

                v_codes = (((1 << (len - 3)) - 2) << len) | (c4 & ((1 << len) - 1));

                put_bits(pb, len * 2 - 3, v_codes);

            }

            if (out) {

               vec1 = &p_vectors[curidx*2];

               vec2 = &p_vectors[curidx2*2];

               out[i+0] = copysignf(c1 * cbrtf(c1) * IQ, in[i+0]);

               out[i+1] = copysignf(c2 * cbrtf(c2) * IQ, in[i+1]);

               out[i+2] = copysignf(c3 * cbrtf(c3) * IQ, in[i+2]);

               out[i+3] = copysignf(c4 * cbrtf(c4) * IQ, in[i+3]);

            }

        }

    }

}


static int vc9_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            uint8_t *buf, int buf_size)

{

    VC9Context *v = avctx->priv_data;

    int ret = FRAME_SKIPED, len, start_code;

    AVFrame *pict = data;

    uint8_t *tmp_buf;

    v->avctx = avctx;

    //buf_size = 0 -> last frame

    if (!buf_size) return 0;

    len = avpicture_get_size(avctx->pix_fmt, avctx->width,

                             avctx->height);

    tmp_buf = (uint8_t *)av_mallocz(len);

    avpicture_fill((AVPicture *)pict, tmp_buf, avctx->pix_fmt,

                   avctx->width, avctx->height);

    if (avctx->codec_id == CODEC_ID_WMV3)

    {

	init_get_bits(&v->gb, buf, buf_size*8);

	av_log(avctx, AV_LOG_INFO, "Frame: %i bits to decode\n", buf_size*8);

#if HAS_ADVANCED_PROFILE

	if (v->profile > PROFILE_MAIN)

	{

    	    if (advanced_decode_picture_header(v) == FRAME_SKIPED) return buf_size;

    	    switch(v->pict_type)

    	    {

    		case I_TYPE: ret = advanced_decode_i_mbs(v); break;

	        case P_TYPE: ret = decode_p_mbs(v); break;

    		case B_TYPE:

    		case BI_TYPE: ret = decode_b_mbs(v); break;

    		default: ret = FRAME_SKIPED;

    	    }

    	    if (ret == FRAME_SKIPED) return buf_size; //We ignore for now failures

	}

	else

#endif

	{

    	    if (standard_decode_picture_header(v) == FRAME_SKIPED) return buf_size;

    	    switch(v->pict_type)

	    {

    		case I_TYPE: ret = standard_decode_i_mbs(v); break;

    		case P_TYPE: ret = decode_p_mbs(v); break;

    		case B_TYPE:

    		case BI_TYPE: ret = decode_b_mbs(v); break;

    		default: ret = FRAME_SKIPED;

    	    }

    	    if (ret == FRAME_SKIPED) return buf_size;

	}

	/* Size of the output data = image */

	av_log(avctx, AV_LOG_DEBUG, "Consumed %i/%i bits\n",

           get_bits_count(&v->gb), buf_size*8);

    }

    else

    {

#if 0

	// search for IDU's

	// FIXME

	uint32_t scp = 0;

	int scs = 0, i = 0;

	while (i < buf_size)

	{

	    for (; i < buf_size && scp != 0x000001; i++)

		scp = ((scp<<8)|buf[i])&0xffffff;

	    if (scp != 0x000001)

		break; // eof ?

	    scs = buf[i++];

	    init_get_bits(&v->gb, buf+i, (buf_size-i)*8);

	    switch(scs)

	    {

		case 0xf:

		    decode_sequence_header(avctx, &v->gb);

		    break;

		// to be finished

	    }

	    i += get_bits_count(&v->gb)*8;

	}

#else

	av_abort();

#endif

    }

    *data_size = len;

    /* Fake consumption of all data */

    return buf_size; //Number of bytes consumed

}


static int compand_delay(AVFilterContext *ctx, AVFrame *frame)

{

    CompandContext *s    = ctx->priv;

    AVFilterLink *inlink = ctx->inputs[0];

    const int channels = inlink->channels;

    const int nb_samples = frame->nb_samples;

    int chan, i, av_uninit(dindex), oindex, av_uninit(count);

    AVFrame *out_frame   = NULL;

    if (s->pts == AV_NOPTS_VALUE) {

        s->pts = (frame->pts == AV_NOPTS_VALUE) ? 0 : frame->pts;

    }

    av_assert1(channels > 0); /* would corrupt delay_count and delay_index */

    for (chan = 0; chan < channels; chan++) {

        AVFrame *delay_frame = s->delay_frame;

        const double *src = (double *)frame->extended_data[chan];

        double *dbuf      = (double *)delay_frame->extended_data[chan];

        ChanParam *cp        = &s->channels[chan];

        double *dst;

        count  = s->delay_count;

        dindex = s->delay_index;

        for (i = 0, oindex = 0; i < nb_samples; i++) {

            const double in = src[i];

            update_volume(cp, fabs(in));

            if (count >= s->delay_samples) {

                if (!out_frame) {

                    out_frame = ff_get_audio_buffer(inlink, nb_samples - i);

                    if (!out_frame) {

                        av_frame_free(&frame);

                        return AVERROR(ENOMEM);

                    }

                    av_frame_copy_props(out_frame, frame);

                    out_frame->pts = s->pts;

                    s->pts += av_rescale_q(nb_samples - i,

                        (AVRational){ 1, inlink->sample_rate },

                        inlink->time_base);

                }

                dst = (double *)out_frame->extended_data[chan];

                dst[oindex++] = av_clipd(dbuf[dindex] *

                        get_volume(s, cp->volume), -1, 1);

            } else {

                count++;

            }

            dbuf[dindex] = in;

            dindex = MOD(dindex + 1, s->delay_samples);

        }

    }

    s->delay_count = count;

    s->delay_index = dindex;

    av_frame_free(&frame);

    return out_frame ? ff_filter_frame(ctx->outputs[0], out_frame) : 0;

}


static void vc1_overlap_block(MpegEncContext *s, DCTELEM block[64], int n, int do_hor, int do_vert)

{

    int i;

    if(do_hor) { //TODO

    }

    if(do_vert) { //TODO

    }

    for(i = 0; i < 64; i++)

        block[i] += 128;

}


static int32_t parse_gain(const char *gain)

{

    char *fraction;

    int  scale = 10000;

    int32_t mb = 0;

    int db;

    if (!gain)

        return INT32_MIN;

    gain += strspn(gain, " \t");

    db = strtol(gain, &fraction, 0);

    if (*fraction++ == '.') {

        while (av_isdigit(*fraction) && scale) {

            mb += scale * (*fraction - '0');

            scale /= 10;

            fraction++;

        }

    }

    if (abs(db) > (INT32_MAX - mb) / 100000)

        return INT32_MIN;

    return db * 100000 + FFSIGN(db) * mb;

}


int ffurl_read(URLContext *h, unsigned char *buf, int size)

{

    if (h->flags & AVIO_FLAG_WRITE)

        return AVERROR(EIO);

    return retry_transfer_wrapper(h, buf, size, 1, h->prot->url_read);

}


static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = spapr_vio_bridge_init;

    dc->no_user = 1;

}


int kvm_arch_init_vcpu(CPUState *env)

{

    struct {

        struct kvm_cpuid2 cpuid;

        struct kvm_cpuid_entry2 entries[100];

    } __attribute__((packed)) cpuid_data;

    uint32_t limit, i, j, cpuid_i;

    uint32_t eax, ebx, ecx, edx;

    cpuid_i = 0;

    cpu_x86_cpuid(env, 0, 0, &eax, &ebx, &ecx, &edx);

    limit = eax;

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

        struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];

        switch (i) {

        case 2: {

            /* Keep reading function 2 till all the input is received */

            int times;

            cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);

            times = eax & 0xff;

            c->function = i;

            c->flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;

            c->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;

            c->eax = eax;

            c->ebx = ebx;

            c->ecx = ecx;

            c->edx = edx;

            for (j = 1; j < times; ++j) {

                cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);

                c->function = i;

                c->flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;

                c->eax = eax;

                c->ebx = ebx;

                c->ecx = ecx;

                c->edx = edx;

                c = &cpuid_data.entries[++cpuid_i];

            }

            break;

        }

        case 4:

        case 0xb:

        case 0xd:

            for (j = 0; ; j++) {

                cpu_x86_cpuid(env, i, j, &eax, &ebx, &ecx, &edx);

                c->function = i;

                c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX;

                c->index = j;

                c->eax = eax;

                c->ebx = ebx;

                c->ecx = ecx;

                c->edx = edx;

                c = &cpuid_data.entries[++cpuid_i];

                if (i == 4 && eax == 0)

                    break;

                if (i == 0xb && !(ecx & 0xff00))

                    break;

                if (i == 0xd && eax == 0)

                    break;

            }

            break;

        default:

            cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);

            c->function = i;

            c->eax = eax;

            c->ebx = ebx;

            c->ecx = ecx;

            c->edx = edx;

            break;

        }

    }

    cpu_x86_cpuid(env, 0x80000000, 0, &eax, &ebx, &ecx, &edx);

    limit = eax;

    for (i = 0x80000000; i <= limit; i++) {

        struct kvm_cpuid_entry2 *c = &cpuid_data.entries[cpuid_i++];

        cpu_x86_cpuid(env, i, 0, &eax, &ebx, &ecx, &edx);

        c->function = i;

        c->eax = eax;

        c->ebx = ebx;

        c->ecx = ecx;

        c->edx = edx;

    }

    cpuid_data.cpuid.nent = cpuid_i;

    return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data);

}


static int webm_dash_manifest_read_header(AVFormatContext *s)

{

    char *buf;

    int ret = matroska_read_header(s);

    MatroskaTrack *tracks;

    MatroskaDemuxContext *matroska = s->priv_data;

    if (ret) {

        av_log(s, AV_LOG_ERROR, "Failed to read file headers\n");

        return -1;

    if (!matroska->is_live) {

        buf = av_asprintf("%g", matroska->duration);

        if (!buf) return AVERROR(ENOMEM);

        av_dict_set(&s->streams[0]->metadata, DURATION, buf, 0);

        av_free(buf);

        // initialization range

        // 5 is the offset of Cluster ID.

        av_dict_set_int(&s->streams[0]->metadata, INITIALIZATION_RANGE, avio_tell(s->pb) - 5, 0);

    // basename of the file

    buf = strrchr(s->filename, '/');

    av_dict_set(&s->streams[0]->metadata, FILENAME, buf ? ++buf : s->filename, 0);

    // track number

    tracks = matroska->tracks.elem;

    av_dict_set_int(&s->streams[0]->metadata, TRACK_NUMBER, tracks[0].num, 0);

    // parse the cues and populate Cue related fields

    return matroska->is_live ? 0 : webm_dash_manifest_cues(s);


static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,

                       VLCcode *codes, int flags)

{

    int table_size, table_index, index, code_prefix, symbol, subtable_bits;

    int i, j, k, n, nb, inc;

    uint32_t code;

    VLC_TYPE (*table)[2];

    table_size = 1 << table_nb_bits;

    if (table_nb_bits > 30)

       return -1;

    table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC);

    av_dlog(NULL, "new table index=%d size=%d\n", table_index, table_size);

    if (table_index < 0)

        return table_index;

    table = &vlc->table[table_index];

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

        table[i][1] = 0; //bits

        table[i][0] = -1; //codes

    }

    /* first pass: map codes and compute auxiliary table sizes */

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

        n      = codes[i].bits;

        code   = codes[i].code;

        symbol = codes[i].symbol;

        av_dlog(NULL, "i=%d n=%d code=0x%x\n", i, n, code);

        if (n <= table_nb_bits) {

            /* no need to add another table */

            j = code >> (32 - table_nb_bits);

            nb = 1 << (table_nb_bits - n);

            inc = 1;

            if (flags & INIT_VLC_LE) {

                j = bitswap_32(code);

                inc = 1 << n;

            }

            for (k = 0; k < nb; k++) {

                av_dlog(NULL, "%4x: code=%d n=%d\n", j, i, n);

                if (table[j][1] /*bits*/ != 0) {

                    av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");

                    return AVERROR_INVALIDDATA;

                }

                table[j][1] = n; //bits

                table[j][0] = symbol;

                j += inc;

            }

        } else {

            /* fill auxiliary table recursively */

            n -= table_nb_bits;

            code_prefix = code >> (32 - table_nb_bits);

            subtable_bits = n;

            codes[i].bits = n;

            codes[i].code = code << table_nb_bits;

            for (k = i+1; k < nb_codes; k++) {

                n = codes[k].bits - table_nb_bits;

                if (n <= 0)

                    break;

                code = codes[k].code;

                if (code >> (32 - table_nb_bits) != code_prefix)

                    break;

                codes[k].bits = n;

                codes[k].code = code << table_nb_bits;

                subtable_bits = FFMAX(subtable_bits, n);

            }

            subtable_bits = FFMIN(subtable_bits, table_nb_bits);

            j = (flags & INIT_VLC_LE) ? bitswap_32(code_prefix) >> (32 - table_nb_bits) : code_prefix;

            table[j][1] = -subtable_bits;

            av_dlog(NULL, "%4x: n=%d (subtable)\n",

                    j, codes[i].bits + table_nb_bits);

            index = build_table(vlc, subtable_bits, k-i, codes+i, flags);

            if (index < 0)

                return index;

            /* note: realloc has been done, so reload tables */

            table = &vlc->table[table_index];

            table[j][0] = index; //code

            i = k-1;

        }

    }

    return table_index;

}