static void eval_cond_jmp(DisasContext *dc, TCGv pc_true, TCGv pc_false)

{

    int l1;

    l1 = gen_new_label();

    /* Conditional jmp.  */

    tcg_gen_mov_tl(cpu_SR[SR_PC], pc_false);

    tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);

    tcg_gen_mov_tl(cpu_SR[SR_PC], pc_true);

    gen_set_label(l1);

}


void parse_numa_opts(MachineState *ms)

{

    int i;

    const CPUArchIdList *possible_cpus;

    MachineClass *mc = MACHINE_GET_CLASS(ms);

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

        numa_info[i].node_cpu = bitmap_new(max_cpus);

    }

    if (qemu_opts_foreach(qemu_find_opts("numa"), parse_numa, ms, NULL)) {

        exit(1);

    }

    assert(max_numa_nodeid <= MAX_NODES);

    /* No support for sparse NUMA node IDs yet: */

    for (i = max_numa_nodeid - 1; i >= 0; i--) {

        /* Report large node IDs first, to make mistakes easier to spot */

        if (!numa_info[i].present) {

            error_report("numa: Node ID missing: %d", i);

            exit(1);

        }

    }

    /* This must be always true if all nodes are present: */

    assert(nb_numa_nodes == max_numa_nodeid);

    if (nb_numa_nodes > 0) {

        uint64_t numa_total;

        if (nb_numa_nodes > MAX_NODES) {

            nb_numa_nodes = MAX_NODES;

        }

        /* If no memory size is given for any node, assume the default case

         * and distribute the available memory equally across all nodes

         */

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

            if (numa_info[i].node_mem != 0) {

                break;

            }

        }

        if (i == nb_numa_nodes) {

            assert(mc->numa_auto_assign_ram);

            mc->numa_auto_assign_ram(mc, numa_info, nb_numa_nodes, ram_size);

        }

        numa_total = 0;

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

            numa_total += numa_info[i].node_mem;

        }

        if (numa_total != ram_size) {

            error_report("total memory for NUMA nodes (0x%" PRIx64 ")"

                         " should equal RAM size (0x" RAM_ADDR_FMT ")",

                         numa_total, ram_size);

            exit(1);

        }

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

            QLIST_INIT(&numa_info[i].addr);

        }

        numa_set_mem_ranges();

        /* assign CPUs to nodes using board provided default mapping */

        if (!mc->cpu_index_to_instance_props || !mc->possible_cpu_arch_ids) {

            error_report("default CPUs to NUMA node mapping isn't supported");

            exit(1);

        }

        possible_cpus = mc->possible_cpu_arch_ids(ms);

        for (i = 0; i < possible_cpus->len; i++) {

            if (possible_cpus->cpus[i].props.has_node_id) {

                break;

            }

        }

        /* no CPUs are assigned to NUMA nodes */

        if (i == possible_cpus->len) {

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

                CpuInstanceProperties props;

                /* fetch default mapping from board and enable it */

                props = mc->cpu_index_to_instance_props(ms, i);

                props.has_node_id = true;

                set_bit(i, numa_info[props.node_id].node_cpu);

                machine_set_cpu_numa_node(ms, &props, &error_fatal);

            }

        }

        validate_numa_cpus();

        /* QEMU needs at least all unique node pair distances to build

         * the whole NUMA distance table. QEMU treats the distance table

         * as symmetric by default, i.e. distance A->B == distance B->A.

         * Thus, QEMU is able to complete the distance table

         * initialization even though only distance A->B is provided and

         * distance B->A is not. QEMU knows the distance of a node to

         * itself is always 10, so A->A distances may be omitted. When

         * the distances of two nodes of a pair differ, i.e. distance

         * A->B != distance B->A, then that means the distance table is

         * asymmetric. In this case, the distances for both directions

         * of all node pairs are required.

         */

        if (have_numa_distance) {

            /* Validate enough NUMA distance information was provided. */

            validate_numa_distance();

            /* Validation succeeded, now fill in any missing distances. */

            complete_init_numa_distance();

        }

    } else {

        numa_set_mem_node_id(0, ram_size, 0);

    }

}


void tcg_dump_ops(TCGContext *s)

{

    char buf[128];

    TCGOp *op;

    int oi;

    for (oi = s->gen_first_op_idx; oi >= 0; oi = op->next) {

        int i, k, nb_oargs, nb_iargs, nb_cargs;

        const TCGOpDef *def;

        const TCGArg *args;

        TCGOpcode c;

        op = &s->gen_op_buf[oi];

        c = op->opc;

        def = &tcg_op_defs[c];

        args = &s->gen_opparam_buf[op->args];

        if (c == INDEX_op_insn_start) {

            qemu_log("%s ----", oi != s->gen_first_op_idx ? "\n" : "");

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

                target_ulong a;

#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS

                a = ((target_ulong)args[i * 2 + 1] << 32) | args[i * 2];

#else

                a = args[i];

#endif

                qemu_log(" " TARGET_FMT_lx, a);

            }

        } else if (c == INDEX_op_call) {

            /* variable number of arguments */

            nb_oargs = op->callo;

            nb_iargs = op->calli;

            nb_cargs = def->nb_cargs;

            /* function name, flags, out args */

            qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name,

                     tcg_find_helper(s, args[nb_oargs + nb_iargs]),

                     args[nb_oargs + nb_iargs + 1], nb_oargs);

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

                qemu_log(",%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),

                                                   args[i]));

            }

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

                TCGArg arg = args[nb_oargs + i];

                const char *t = "<dummy>";

                if (arg != TCG_CALL_DUMMY_ARG) {

                    t = tcg_get_arg_str_idx(s, buf, sizeof(buf), arg);

                }

                qemu_log(",%s", t);

            }

        } else {

            qemu_log(" %s ", def->name);

            nb_oargs = def->nb_oargs;

            nb_iargs = def->nb_iargs;

            nb_cargs = def->nb_cargs;

            k = 0;

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

                if (k != 0) {

                    qemu_log(",");

                }

                qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),

                                                   args[k++]));

            }

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

                if (k != 0) {

                    qemu_log(",");

                }

                qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),

                                                   args[k++]));

            }

            switch (c) {

            case INDEX_op_brcond_i32:

            case INDEX_op_setcond_i32:

            case INDEX_op_movcond_i32:

            case INDEX_op_brcond2_i32:

            case INDEX_op_setcond2_i32:

            case INDEX_op_brcond_i64:

            case INDEX_op_setcond_i64:

            case INDEX_op_movcond_i64:

                if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {

                    qemu_log(",%s", cond_name[args[k++]]);

                } else {

                    qemu_log(",$0x%" TCG_PRIlx, args[k++]);

                }

                i = 1;

                break;

            case INDEX_op_qemu_ld_i32:

            case INDEX_op_qemu_st_i32:

            case INDEX_op_qemu_ld_i64:

            case INDEX_op_qemu_st_i64:

                {

                    TCGMemOpIdx oi = args[k++];

                    TCGMemOp op = get_memop(oi);

                    unsigned ix = get_mmuidx(oi);

                    if (op & ~(MO_AMASK | MO_BSWAP | MO_SSIZE)) {

                        qemu_log(",$0x%x,%u", op, ix);

                    } else {

                        const char *s_al = "", *s_op;

                        if (op & MO_AMASK) {

                            if ((op & MO_AMASK) == MO_ALIGN) {

                                s_al = "al+";

                            } else {

                                s_al = "un+";

                            }

                        }

                        s_op = ldst_name[op & (MO_BSWAP | MO_SSIZE)];

                        qemu_log(",%s%s,%u", s_al, s_op, ix);

                    }

                    i = 1;

                }

                break;

            default:

                i = 0;

                break;

            }

            switch (c) {

            case INDEX_op_set_label:

            case INDEX_op_br:

            case INDEX_op_brcond_i32:

            case INDEX_op_brcond_i64:

            case INDEX_op_brcond2_i32:

                qemu_log("%s$L%d", k ? "," : "", arg_label(args[k])->id);

                i++, k++;

                break;

            default:

                break;

            }

            for (; i < nb_cargs; i++, k++) {

                qemu_log("%s$0x%" TCG_PRIlx, k ? "," : "", args[k]);

            }

        }

        qemu_log("\n");

    }

}


static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,

                           Error **errp)

{

    CPUPPCState *env = &cpu->env;

    /* Set time-base frequency to 512 MHz */

    cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);

    /* Enable PAPR mode in TCG or KVM */

    cpu_ppc_set_papr(cpu, PPC_VIRTUAL_HYPERVISOR(spapr));

    if (spapr->max_compat_pvr) {

        Error *local_err = NULL;

        ppc_set_compat(cpu, spapr->max_compat_pvr, &local_err);

        if (local_err) {

            error_propagate(errp, local_err);

            return;

        }

    }

    qemu_register_reset(spapr_cpu_reset, cpu);

    spapr_cpu_reset(cpu);

}


uint32_t HELPER(lcdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)

{

    env->fregs[f1].d = float64_chs(env->fregs[f2].d);

    return set_cc_nz_f64(env->fregs[f1].d);

}


static int no_run_out (HWVoiceOut *hw, int live)

{

    NoVoiceOut *no = (NoVoiceOut *) hw;

    int decr, samples;

    int64_t now;

    int64_t ticks;

    int64_t bytes;

    now = qemu_get_clock (vm_clock);

    ticks = now - no->old_ticks;

    bytes = muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());

    bytes = audio_MIN (bytes, INT_MAX);

    samples = bytes >> hw->info.shift;

    no->old_ticks = now;

    decr = audio_MIN (live, samples);

    hw->rpos = (hw->rpos + decr) % hw->samples;

    return decr;

}


void do_interrupt(int intno, int is_int, int error_code,

                  unsigned int next_eip, int is_hw)

{

#ifdef DEBUG_PCALL

    if (loglevel) {

        static int count;

        fprintf(logfile, "%d: interrupt: vector=%02x error_code=%04x int=%d\n",

                count, intno, error_code, is_int);

        cpu_x86_dump_state(env, logfile, X86_DUMP_CCOP);

#if 0

        {

            int i;

            uint8_t *ptr;

            printf("       code=");

            ptr = env->segs[R_CS].base + env->eip;

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

                printf(" %02x", ldub(ptr + i));

            }

            printf("\n");

        }

#endif

        count++;

    }

#endif

    if (env->cr[0] & CR0_PE_MASK) {

        do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);

    } else {

        do_interrupt_real(intno, is_int, error_code, next_eip);

    }

}


static void coroutine_fn wait_for_overlapping_requests(BlockDriverState *bs,

        int64_t offset, unsigned int bytes)

{

    BdrvTrackedRequest *req;

    int64_t cluster_offset;

    unsigned int cluster_bytes;

    bool retry;

    /* If we touch the same cluster it counts as an overlap.  This guarantees

     * that allocating writes will be serialized and not race with each other

     * for the same cluster.  For example, in copy-on-read it ensures that the

     * CoR read and write operations are atomic and guest writes cannot

     * interleave between them.

     */

    round_bytes_to_clusters(bs, offset, bytes, &cluster_offset, &cluster_bytes);

    do {

        retry = false;

        QLIST_FOREACH(req, &bs->tracked_requests, list) {

            if (tracked_request_overlaps(req, cluster_offset, cluster_bytes)) {

                /* Hitting this means there was a reentrant request, for

                 * example, a block driver issuing nested requests.  This must

                 * never happen since it means deadlock.

                 */

                assert(qemu_coroutine_self() != req->co);

                qemu_co_queue_wait(&req->wait_queue);

                retry = true;

                break;

            }

        }

    } while (retry);

}


static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb,

                                   dirac_source_params *source)

{

    AVRational frame_rate = {0,0};

    unsigned luma_depth = 8, luma_offset = 16;

    int idx;

    int chroma_x_shift, chroma_y_shift;

    /* [DIRAC_STD] 10.3.2 Frame size. frame_size(video_params) */

    /* [DIRAC_STD] custom_dimensions_flag */

    if (get_bits1(gb)) {

        source->width  = svq3_get_ue_golomb(gb); /* [DIRAC_STD] FRAME_WIDTH  */

        source->height = svq3_get_ue_golomb(gb); /* [DIRAC_STD] FRAME_HEIGHT */

    }

    /* [DIRAC_STD] 10.3.3 Chroma Sampling Format.

     *  chroma_sampling_format(video_params) */

    /* [DIRAC_STD] custom_chroma_format_flag */

    if (get_bits1(gb))

        /* [DIRAC_STD] CHROMA_FORMAT_INDEX */

        source->chroma_format = svq3_get_ue_golomb(gb);

    if (source->chroma_format > 2U) {

        av_log(avctx, AV_LOG_ERROR, "Unknown chroma format %d\n",

               source->chroma_format);

        return AVERROR_INVALIDDATA;

    }

    /* [DIRAC_STD] 10.3.4 Scan Format. scan_format(video_params) */

    /* [DIRAC_STD] custom_scan_format_flag */

    if (get_bits1(gb))

        /* [DIRAC_STD] SOURCE_SAMPLING */

        source->interlaced = svq3_get_ue_golomb(gb);

    if (source->interlaced > 1U)

        return AVERROR_INVALIDDATA;

    /* [DIRAC_STD] 10.3.5 Frame Rate. frame_rate(video_params) */

    if (get_bits1(gb)) { /* [DIRAC_STD] custom_frame_rate_flag */

        source->frame_rate_index = svq3_get_ue_golomb(gb);

        if (source->frame_rate_index > 10U)

            return AVERROR_INVALIDDATA;

        if (!source->frame_rate_index) {

            /* [DIRAC_STD] FRAME_RATE_NUMER */

            frame_rate.num = svq3_get_ue_golomb(gb);

            /* [DIRAC_STD] FRAME_RATE_DENOM */

            frame_rate.den = svq3_get_ue_golomb(gb);

        }

    }

    /* [DIRAC_STD] preset_frame_rate(video_params, index) */

    if (source->frame_rate_index > 0) {

        if (source->frame_rate_index <= 8)

            frame_rate = ff_mpeg12_frame_rate_tab[source->frame_rate_index];

        else

             /* [DIRAC_STD] Table 10.3 values 9-10 */

            frame_rate = dirac_frame_rate[source->frame_rate_index-9];

    }

    av_reduce(&avctx->time_base.num, &avctx->time_base.den,

              frame_rate.den, frame_rate.num, 1<<30);

    /* [DIRAC_STD] 10.3.6 Pixel Aspect Ratio.

     * pixel_aspect_ratio(video_params) */

    if (get_bits1(gb)) { /* [DIRAC_STD] custom_pixel_aspect_ratio_flag */

         /* [DIRAC_STD] index */

        source->aspect_ratio_index = svq3_get_ue_golomb(gb);

        if (source->aspect_ratio_index > 6U)

            return AVERROR_INVALIDDATA;

        if (!source->aspect_ratio_index) {

            avctx->sample_aspect_ratio.num = svq3_get_ue_golomb(gb);

            avctx->sample_aspect_ratio.den = svq3_get_ue_golomb(gb);

        }

    }

    /* [DIRAC_STD] Take value from Table 10.4 Available preset pixel

     *  aspect ratio values */

    if (source->aspect_ratio_index > 0)

        avctx->sample_aspect_ratio =

            dirac_preset_aspect_ratios[source->aspect_ratio_index-1];

    /* [DIRAC_STD] 10.3.7 Clean area. clean_area(video_params) */

    if (get_bits1(gb)) { /* [DIRAC_STD] custom_clean_area_flag */

        /* [DIRAC_STD] CLEAN_WIDTH */

        source->clean_width        = svq3_get_ue_golomb(gb);

         /* [DIRAC_STD] CLEAN_HEIGHT */

        source->clean_height       = svq3_get_ue_golomb(gb);

         /* [DIRAC_STD] CLEAN_LEFT_OFFSET */

        source->clean_left_offset  = svq3_get_ue_golomb(gb);

        /* [DIRAC_STD] CLEAN_RIGHT_OFFSET */

        source->clean_right_offset = svq3_get_ue_golomb(gb);

    }

    /* [DIRAC_STD] 10.3.8 Signal range. signal_range(video_params)

     * WARNING: Some adaptation seems to be done using the

     * AVCOL_RANGE_MPEG/JPEG values */

    if (get_bits1(gb)) { /* [DIRAC_STD] custom_signal_range_flag */

        /* [DIRAC_STD] index */

        source->pixel_range_index = svq3_get_ue_golomb(gb);

        if (source->pixel_range_index > 4U)

            return AVERROR_INVALIDDATA;

        /* This assumes either fullrange or MPEG levels only */

        if (!source->pixel_range_index) {

            luma_offset = svq3_get_ue_golomb(gb);

            luma_depth  = av_log2(svq3_get_ue_golomb(gb))+1;

            svq3_get_ue_golomb(gb); /* chroma offset    */

            svq3_get_ue_golomb(gb); /* chroma excursion */

            avctx->color_range = luma_offset ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;

        }

    }

    /* [DIRAC_STD] Table 10.5

     * Available signal range presets <--> pixel_range_presets */

    if (source->pixel_range_index > 0) {

        idx                = source->pixel_range_index-1;

        luma_depth         = pixel_range_presets[idx].bitdepth;

        avctx->color_range = pixel_range_presets[idx].color_range;

    }

    if (luma_depth > 8)

        av_log(avctx, AV_LOG_WARNING, "Bitdepth greater than 8\n");

    avctx->pix_fmt = dirac_pix_fmt[!luma_offset][source->chroma_format];

    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_x_shift, &chroma_y_shift);

    if (!(source->width % (1<<chroma_x_shift)) || !(source->height % (1<<chroma_y_shift))) {

        av_log(avctx, AV_LOG_ERROR, "Dimensions must be a integer multiply of the chroma subsampling\n");

        return AVERROR_INVALIDDATA;

    }

    /* [DIRAC_STD] 10.3.9 Colour specification. colour_spec(video_params) */

    if (get_bits1(gb)) { /* [DIRAC_STD] custom_colour_spec_flag */

         /* [DIRAC_STD] index */

        idx = source->color_spec_index = svq3_get_ue_golomb(gb);

        if (source->color_spec_index > 4U)

            return AVERROR_INVALIDDATA;

        avctx->color_primaries = dirac_color_presets[idx].color_primaries;

        avctx->colorspace      = dirac_color_presets[idx].colorspace;

        avctx->color_trc       = dirac_color_presets[idx].color_trc;

        if (!source->color_spec_index) {

            /* [DIRAC_STD] 10.3.9.1 Colour primaries */

            if (get_bits1(gb)) {

                idx = svq3_get_ue_golomb(gb);

                if (idx < 3U)

                    avctx->color_primaries = dirac_primaries[idx];

            }

            /* [DIRAC_STD] 10.3.9.2 Colour matrix */

            if (get_bits1(gb)) {

                idx = svq3_get_ue_golomb(gb);

                if (!idx)

                    avctx->colorspace = AVCOL_SPC_BT709;

                else if (idx == 1)

                    avctx->colorspace = AVCOL_SPC_BT470BG;

            }

            /* [DIRAC_STD] 10.3.9.3 Transfer function */

            if (get_bits1(gb) && !svq3_get_ue_golomb(gb))

                avctx->color_trc = AVCOL_TRC_BT709;

        }

    } else {

        idx = source->color_spec_index;

        avctx->color_primaries = dirac_color_presets[idx].color_primaries;

        avctx->colorspace      = dirac_color_presets[idx].colorspace;

        avctx->color_trc       = dirac_color_presets[idx].color_trc;

    }

    return 0;

}


static void grlib_gptimer_write(void *opaque, target_phys_addr_t addr,

                                uint64_t value, unsigned size)

{

    GPTimerUnit        *unit = opaque;

    target_phys_addr_t  timer_addr;

    int                 id;

    addr &= 0xff;

    /* Unit registers */

    switch (addr) {

    case SCALER_OFFSET:

        value &= 0xFFFF; /* clean up the value */

        unit->scaler = value;

        trace_grlib_gptimer_writel(-1, addr, unit->scaler);

        return;

    case SCALER_RELOAD_OFFSET:

        value &= 0xFFFF; /* clean up the value */

        unit->reload = value;

        trace_grlib_gptimer_writel(-1, addr, unit->reload);

        grlib_gptimer_set_scaler(unit, value);

        return;

    case CONFIG_OFFSET:

        /* Read Only (disable timer freeze not supported) */

        trace_grlib_gptimer_writel(-1, addr, 0);

        return;

    default:

        break;

    }

    timer_addr = (addr % TIMER_BASE);

    id         = (addr - TIMER_BASE) / TIMER_BASE;

    if (id >= 0 && id < unit->nr_timers) {

        /* GPTimer registers */

        switch (timer_addr) {

        case COUNTER_OFFSET:

            trace_grlib_gptimer_writel(id, addr, value);

            unit->timers[id].counter = value;

            grlib_gptimer_enable(&unit->timers[id]);

            return;

        case COUNTER_RELOAD_OFFSET:

            trace_grlib_gptimer_writel(id, addr, value);

            unit->timers[id].reload = value;

            return;

        case CONFIG_OFFSET:

            trace_grlib_gptimer_writel(id, addr, value);

            if (value & GPTIMER_INT_PENDING) {

                /* clear pending bit */

                value &= ~GPTIMER_INT_PENDING;

            } else {

                /* keep pending bit */

                value |= unit->timers[id].config & GPTIMER_INT_PENDING;

            }

            unit->timers[id].config = value;

            /* gptimer_restart calls gptimer_enable, so if "enable" and "load"

               bits are present, we just have to call restart. */

            if (value & GPTIMER_LOAD) {

                grlib_gptimer_restart(&unit->timers[id]);

            } else if (value & GPTIMER_ENABLE) {

                grlib_gptimer_enable(&unit->timers[id]);

            }

            /* These fields must always be read as 0 */

            value &= ~(GPTIMER_LOAD & GPTIMER_DEBUG_HALT);

            unit->timers[id].config = value;

            return;

        default:

            break;

        }

    }

    trace_grlib_gptimer_writel(-1, addr, value);

}


static bool cmd_write_multiple(IDEState *s, uint8_t cmd)

{

    bool lba48 = (cmd == WIN_MULTWRITE_EXT);

    int n;

    if (!s->bs || !s->mult_sectors) {

        ide_abort_command(s);

        return true;

    }

    ide_cmd_lba48_transform(s, lba48);

    s->req_nb_sectors = s->mult_sectors;

    n = MIN(s->nsector, s->req_nb_sectors);

    s->status = SEEK_STAT | READY_STAT;

    ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);

    s->media_changed = 1;

    return false;

}


static int pxb_map_irq_fn(PCIDevice *pci_dev, int pin)

{

    PCIDevice *pxb = pci_dev->bus->parent_dev;

    /*

     * The bios does not index the pxb slot number when

     * it computes the IRQ because it resides on bus 0

     * and not on the current bus.

     * However QEMU routes the irq through bus 0 and adds

     * the pxb slot to the IRQ computation of the PXB

     * device.

     *

     * Synchronize between bios and QEMU by canceling

     * pxb's effect.

     */

    return pin - PCI_SLOT(pxb->devfn);

}


static int flac_read_header(AVFormatContext *s,

                             AVFormatParameters *ap)

{

    int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;

    uint8_t header[4];

    uint8_t *buffer=NULL;

    AVStream *st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

    st->codec->codec_id = CODEC_ID_FLAC;

    st->need_parsing = AVSTREAM_PARSE_FULL;

    /* the parameters will be extracted from the compressed bitstream */

    /* if fLaC marker is not found, assume there is no header */

    if (avio_rl32(s->pb) != MKTAG('f','L','a','C')) {

        avio_seek(s->pb, -4, SEEK_CUR);

        return 0;

    }

    /* process metadata blocks */

    while (!s->pb->eof_reached && !metadata_last) {

        avio_read(s->pb, header, 4);

        avpriv_flac_parse_block_header(header, &metadata_last, &metadata_type,

                                   &metadata_size);

        switch (metadata_type) {

        /* allocate and read metadata block for supported types */

        case FLAC_METADATA_TYPE_STREAMINFO:

        case FLAC_METADATA_TYPE_CUESHEET:

        case FLAC_METADATA_TYPE_VORBIS_COMMENT:

            buffer = av_mallocz(metadata_size + FF_INPUT_BUFFER_PADDING_SIZE);

            if (!buffer) {

                return AVERROR(ENOMEM);

            }

            if (avio_read(s->pb, buffer, metadata_size) != metadata_size) {

                av_freep(&buffer);

                return AVERROR(EIO);

            }

            break;

        /* skip metadata block for unsupported types */

        default:

            ret = avio_skip(s->pb, metadata_size);

            if (ret < 0)

                return ret;

        }

        if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) {

            FLACStreaminfo si;

            /* STREAMINFO can only occur once */

            if (found_streaminfo) {

                av_freep(&buffer);

                return AVERROR_INVALIDDATA;

            }

            if (metadata_size != FLAC_STREAMINFO_SIZE) {

                av_freep(&buffer);

                return AVERROR_INVALIDDATA;

            }

            found_streaminfo = 1;

            st->codec->extradata      = buffer;

            st->codec->extradata_size = metadata_size;

            buffer = NULL;

            /* get codec params from STREAMINFO header */

            avpriv_flac_parse_streaminfo(st->codec, &si, st->codec->extradata);

            /* set time base and duration */

            if (si.samplerate > 0) {

                avpriv_set_pts_info(st, 64, 1, si.samplerate);

                if (si.samples > 0)

                    st->duration = si.samples;

            }

        } else if (metadata_type == FLAC_METADATA_TYPE_CUESHEET) {

            uint8_t isrc[13];

            uint64_t start;

            const uint8_t *offset;

            int i, j, chapters, track, ti;

            if (metadata_size < 431)

                return AVERROR_INVALIDDATA;

            offset = buffer + 395;

            chapters = bytestream_get_byte(&offset) - 1;

            if (chapters <= 0)

                return AVERROR_INVALIDDATA;

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

                if (offset + 36 - buffer > metadata_size)

                    return AVERROR_INVALIDDATA;

                start = bytestream_get_be64(&offset);

                track = bytestream_get_byte(&offset);

                bytestream_get_buffer(&offset, isrc, 12);

                isrc[12] = 0;

                offset += 14;

                ti = bytestream_get_byte(&offset);

                if (ti <= 0) return AVERROR_INVALIDDATA;

                for (j = 0; j < ti; j++)

                    offset += 12;

                avpriv_new_chapter(s, track, st->time_base, start, AV_NOPTS_VALUE, isrc);

            }

        } else {

            /* STREAMINFO must be the first block */

            if (!found_streaminfo) {

                av_freep(&buffer);

                return AVERROR_INVALIDDATA;

            }

            /* process supported blocks other than STREAMINFO */

            if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) {

                if (ff_vorbis_comment(s, &s->metadata, buffer, metadata_size)) {

                    av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n");

                }

            }

            av_freep(&buffer);

        }

    }

    return 0;

}


static void vc1_loop_filter(uint8_t* src, int step, int stride, int len, int pq)

{

    int i;

    int filt3;

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

        filt3 = vc1_filter_line(src + 2*step, stride, pq);

        if(filt3){

            vc1_filter_line(src + 0*step, stride, pq);

            vc1_filter_line(src + 1*step, stride, pq);

            vc1_filter_line(src + 3*step, stride, pq);

        }

        src += step * 4;

    }

}


static av_cold int nvenc_open_session(AVCodecContext *avctx)

{

    NvencContext *ctx = avctx->priv_data;

    NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;

    NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;

    NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS encode_session_params = { 0 };

    NVENCSTATUS nv_status;

    encode_session_params.version = NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER;

    encode_session_params.apiVersion = NVENCAPI_VERSION;

    encode_session_params.device = ctx->cu_context;

    encode_session_params.deviceType = NV_ENC_DEVICE_TYPE_CUDA;

    nv_status = p_nvenc->nvEncOpenEncodeSessionEx(&encode_session_params, &ctx->nvencoder);

    if (nv_status != NV_ENC_SUCCESS) {

        ctx->nvencoder = NULL;

        return nvenc_print_error(avctx, nv_status, "OpenEncodeSessionEx failed");

    }

    return 0;

}


static int parse_playlist(HLSContext *c, const char *url,

                          struct variant *var, AVIOContext *in)

{

    int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0;

    int64_t duration = 0;

    enum KeyType key_type = KEY_NONE;

    uint8_t iv[16] = "";

    int has_iv = 0;

    char key[MAX_URL_SIZE] = "";

    char line[1024];

    const char *ptr;

    int close_in = 0;

    uint8_t *new_url = NULL;

    if (!in) {

        close_in = 1;

        if ((ret = avio_open2(&in, url, AVIO_FLAG_READ,

                              c->interrupt_callback, NULL)) < 0)

            return ret;

    }

    if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)

        url = new_url;

    read_chomp_line(in, line, sizeof(line));

    if (strcmp(line, "#EXTM3U")) {

        ret = AVERROR_INVALIDDATA;

        goto fail;

    }

    if (var) {

        free_segment_list(var);

        var->finished = 0;

    }

    while (!in->eof_reached) {

        read_chomp_line(in, line, sizeof(line));

        if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {

            struct variant_info info = {{0}};

            is_variant = 1;

            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,

                               &info);

            bandwidth = atoi(info.bandwidth);

        } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {

            struct key_info info = {{0}};

            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_key_args,

                               &info);

            key_type = KEY_NONE;

            has_iv = 0;

            if (!strcmp(info.method, "AES-128"))

                key_type = KEY_AES_128;

            if (!strncmp(info.iv, "0x", 2) || !strncmp(info.iv, "0X", 2)) {

                ff_hex_to_data(iv, info.iv + 2);

                has_iv = 1;

            }

            av_strlcpy(key, info.uri, sizeof(key));

        } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {

            if (!var) {

                var = new_variant(c, 0, url, NULL);

                if (!var) {

                    ret = AVERROR(ENOMEM);

                    goto fail;

                }

            }

            var->target_duration = atoi(ptr) * AV_TIME_BASE;

        } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {

            if (!var) {

                var = new_variant(c, 0, url, NULL);

                if (!var) {

                    ret = AVERROR(ENOMEM);

                    goto fail;

                }

            }

            var->start_seq_no = atoi(ptr);

        } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {

            if (var)

                var->finished = 1;

        } else if (av_strstart(line, "#EXTINF:", &ptr)) {

            is_segment = 1;

            duration   = atof(ptr) * AV_TIME_BASE;

        } else if (av_strstart(line, "#", NULL)) {

            continue;

        } else if (line[0]) {

            if (is_variant) {

                if (!new_variant(c, bandwidth, line, url)) {

                    ret = AVERROR(ENOMEM);

                    goto fail;

                }

                is_variant = 0;

                bandwidth  = 0;

            }

            if (is_segment) {

                struct segment *seg;

                if (!var) {

                    var = new_variant(c, 0, url, NULL);

                    if (!var) {

                        ret = AVERROR(ENOMEM);

                        goto fail;

                    }

                }

                seg = av_malloc(sizeof(struct segment));

                if (!seg) {

                    ret = AVERROR(ENOMEM);

                    goto fail;

                }

                seg->duration = duration;

                seg->key_type = key_type;

                if (has_iv) {

                    memcpy(seg->iv, iv, sizeof(iv));

                } else {

                    int seq = var->start_seq_no + var->n_segments;

                    memset(seg->iv, 0, sizeof(seg->iv));

                    AV_WB32(seg->iv + 12, seq);

                }

                ff_make_absolute_url(seg->key, sizeof(seg->key), url, key);

                ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);

                dynarray_add(&var->segments, &var->n_segments, seg);

                is_segment = 0;

            }

        }

    }

    if (var)

        var->last_load_time = av_gettime_relative();

fail:

    av_free(new_url);

    if (close_in)

        avio_close(in);

    return ret;

}


static int decode_mb_i(AVSContext *h, int cbp_code) {

    GetBitContext *gb = &h->s.gb;

    int block, pred_mode_uv;

    uint8_t top[18];

    uint8_t *left = NULL;

    uint8_t *d;

    ff_cavs_init_mb(h);

    /* get intra prediction modes from stream */

    for(block=0;block<4;block++) {

        int nA,nB,predpred;

        int pos = ff_cavs_scan3x3[block];

        nA = h->pred_mode_Y[pos-1];

        nB = h->pred_mode_Y[pos-3];

        predpred = FFMIN(nA,nB);

        if(predpred == NOT_AVAIL) // if either is not available

            predpred = INTRA_L_LP;

        if(!get_bits1(gb)){

            int rem_mode= get_bits(gb, 2);

            predpred = rem_mode + (rem_mode >= predpred);

        }

        h->pred_mode_Y[pos] = predpred;

    }

    pred_mode_uv = get_ue_golomb(gb);

    if(pred_mode_uv > 6) {

        av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n");

        return -1;

    }

    ff_cavs_modify_mb_i(h, &pred_mode_uv);

    /* get coded block pattern */

    if(h->pic_type == AV_PICTURE_TYPE_I)

        cbp_code = get_ue_golomb(gb);

    if(cbp_code > 63){

        av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra cbp\n");

        return -1;

    }

    h->cbp = cbp_tab[cbp_code][0];

    if(h->cbp && !h->qp_fixed)

        h->qp = (h->qp + get_se_golomb(gb)) & 63; //qp_delta

    /* luma intra prediction interleaved with residual decode/transform/add */

    for(block=0;block<4;block++) {

        d = h->cy + h->luma_scan[block];

        ff_cavs_load_intra_pred_luma(h, top, &left, block);

        h->intra_pred_l[h->pred_mode_Y[ff_cavs_scan3x3[block]]]

            (d, top, left, h->l_stride);

        if(h->cbp & (1<<block))

            decode_residual_block(h,gb,ff_cavs_intra_dec,1,h->qp,d,h->l_stride);

    }

    /* chroma intra prediction */

    ff_cavs_load_intra_pred_chroma(h);

    h->intra_pred_c[pred_mode_uv](h->cu, &h->top_border_u[h->mbx*10],

                                  h->left_border_u, h->c_stride);

    h->intra_pred_c[pred_mode_uv](h->cv, &h->top_border_v[h->mbx*10],

                                  h->left_border_v, h->c_stride);

    decode_residual_chroma(h);

    ff_cavs_filter(h,I_8X8);

    set_mv_intra(h);

    return 0;

}


static void test_visitor_in_alternate(TestInputVisitorData *data,

                                      const void *unused)

{

    Visitor *v;

    Error *err = NULL;

    UserDefAlternate *tmp;

    v = visitor_input_test_init(data, "42");

    visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);

    g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_I);

    g_assert_cmpint(tmp->u.i, ==, 42);

    qapi_free_UserDefAlternate(tmp);

    v = visitor_input_test_init(data, "'string'");

    visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);

    g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_S);

    g_assert_cmpstr(tmp->u.s, ==, "string");

    qapi_free_UserDefAlternate(tmp);

    v = visitor_input_test_init(data, "false");

    visit_type_UserDefAlternate(v, &tmp, NULL, &err);

    g_assert(err);

    error_free(err);

    err = NULL;

    qapi_free_UserDefAlternate(tmp);

}


void qht_statistics_init(struct qht *ht, struct qht_stats *stats)

{

    struct qht_map *map;

    int i;

    map = atomic_rcu_read(&ht->map);

    stats->head_buckets = map->n_buckets;

    stats->used_head_buckets = 0;

    stats->entries = 0;

    qdist_init(&stats->chain);

    qdist_init(&stats->occupancy);

    for (i = 0; i < map->n_buckets; i++) {

        struct qht_bucket *head = &map->buckets[i];

        struct qht_bucket *b;

        unsigned int version;

        size_t buckets;

        size_t entries;

        int j;

        do {

            version = seqlock_read_begin(&head->sequence);

            buckets = 0;

            entries = 0;

            b = head;

            do {

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

                    if (atomic_read(&b->pointers[j]) == NULL) {

                        break;

                    }

                    entries++;

                }

                buckets++;

                b = atomic_rcu_read(&b->next);

            } while (b);

        } while (seqlock_read_retry(&head->sequence, version));

        if (entries) {

            qdist_inc(&stats->chain, buckets);

            qdist_inc(&stats->occupancy,

                      (double)entries / QHT_BUCKET_ENTRIES / buckets);

            stats->used_head_buckets++;

            stats->entries += entries;

        } else {

            qdist_inc(&stats->occupancy, 0);

        }

    }

}


void qemu_system_vmstop_request(RunState state)

{

    vmstop_requested = state;

    qemu_notify_event();

}


static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, int frame_off)

{

    unsigned val, saved_val = 0;

    int tmplen = src_len;

    const uint8_t *src, *source_end = source + src_len;

    uint8_t *frame_end = frame + SCREEN_WIDE * SCREEN_HIGH;

    uint8_t *dst, *dst_end;

    int len, mask;

    int forward = (frame_off <= -SCREEN_WIDE) || (frame_off >= 0);

    int read_two_nibbles, flag;

    int advance_mode;

    int mode = 0;

    int i;

    if (src_len <= 0)

        return AVERROR_INVALIDDATA;

    if (forward) {

        src = source;

        dst = frame;

        dst_end = frame_end;

    } else {

        src = source + src_len - 1;

        dst = frame_end - 1;

        dst_end = frame - 1;

    }

    for (;;) {

        int shift = 0;

        flag = 0;

        /* The mode/len decoding is a bit strange:

         * values are coded as variable-length codes with nibble units,

         * code end is signalled by two top bits in the nibble being nonzero.

         * And since data is bytepacked and we read two nibbles at a time,

         * we may get a nibble belonging to the next code.

         * Hence this convoluted loop.

         */

        if (!mode || (tmplen == 4)) {

            if (src < source || src >= source_end)

                return AVERROR_INVALIDDATA;

            val = *src;

            read_two_nibbles = 1;

        } else {

            val = saved_val;

            read_two_nibbles = 0;

        }

        if (!(val & 0xC)) {

            for (;;) {

                if(shift>22)

                    return -1;

                if (!read_two_nibbles) {

                    if (src < source || src >= source_end)

                        return AVERROR_INVALIDDATA;

                    shift += 2;

                    val |= *src << shift;

                    if (*src & 0xC)

                        break;

                }

                // two upper bits of the nibble is zero,

                // so shift top nibble value down into their place

                read_two_nibbles = 0;

                shift += 2;

                mask = (1 << shift) - 1;

                val = ((val >> 2) & ~mask) | (val & mask);

                NEXT_BYTE(src);

                if ((val & (0xC << shift))) {

                    flag = 1;

                    break;

                }

            }

        } else if (mode) {

            flag = tmplen != 4;

        }

        if (flag) {

            tmplen = 4;

        } else {

            saved_val = val >> (4 + shift);

            tmplen = 0;

            val &= (1 << (shift + 4)) - 1;

            NEXT_BYTE(src);

        }

        advance_mode = val & 1;

        len = (val >> 1) - 1;

        av_assert0(len>0);

        mode += 1 + advance_mode;

        if (mode >= 4)

            mode -= 3;

        if (len <= 0 || FFABS(dst_end - dst) < len)

            return AVERROR_INVALIDDATA;

        switch (mode) {

        case 1:

            if (forward) {

                if (dst - frame + SCREEN_WIDE < frame_off ||

                        dst - frame + SCREEN_WIDE + frame_off < 0 ||

                        frame_end - dst < frame_off + len ||

                        frame_end - dst < len)

                    return AVERROR_INVALIDDATA;

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

                    dst[i] = dst[frame_off + i];

                dst += len;

            } else {

                dst -= len;

                if (dst - frame + SCREEN_WIDE < frame_off ||

                        dst - frame + SCREEN_WIDE + frame_off < 0 ||

                        frame_end - dst < frame_off + len ||

                        frame_end - dst < len)

                    return AVERROR_INVALIDDATA;

                for (i = len - 1; i >= 0; i--)

                    dst[i] = dst[frame_off + i];

            }

            break;

        case 2:

            if (forward) {

                if (source + src_len - src < len)

                    return AVERROR_INVALIDDATA;

                memcpy(dst, src, len);

                dst += len;

                src += len;

            } else {

                if (src - source < len)

                    return AVERROR_INVALIDDATA;

                dst -= len;

                src -= len;

                memcpy(dst, src, len);

            }

            break;

        case 3:

            val = forward ? dst[-1] : dst[1];

            if (forward) {

                memset(dst, val, len);

                dst += len;

            } else {

                dst -= len;

                memset(dst, val, len);

            }

            break;

        }

        if (dst == dst_end)

            return 0;

    }

}


static size_t save_page_header(RAMState *rs, RAMBlock *block, ram_addr_t offset)

{

    size_t size, len;

    if (block == rs->last_sent_block) {

        offset |= RAM_SAVE_FLAG_CONTINUE;

    }

    qemu_put_be64(rs->f, offset);

    size = 8;

    if (!(offset & RAM_SAVE_FLAG_CONTINUE)) {

        len = strlen(block->idstr);

        qemu_put_byte(rs->f, len);

        qemu_put_buffer(rs->f, (uint8_t *)block->idstr, len);

        size += 1 + len;

        rs->last_sent_block = block;

    }

    return size;

}


static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num,

                              pcibus_t addr, pcibus_t size, int type)

{

    EBUS_DPRINTF("Mapping region %d registers at %" FMT_PCIBUS "\n",

                 region_num, addr);

    switch (region_num) {

    case 0:

        isa_mmio_init(addr, 0x1000000);

        break;

    case 1:

        isa_mmio_init(addr, 0x800000);

        break;

    }

}


int ff_wma_end(AVCodecContext *avctx)

{

    WMACodecContext *s = avctx->priv_data;

    int i;

    for(i = 0; i < s->nb_block_sizes; i++)

        ff_mdct_end(&s->mdct_ctx[i]);

    for(i = 0; i < s->nb_block_sizes; i++)

        av_free(s->windows[i]);

    if (s->use_exp_vlc) {

        free_vlc(&s->exp_vlc);

    }

    if (s->use_noise_coding) {

        free_vlc(&s->hgain_vlc);

    }

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

        free_vlc(&s->coef_vlc[i]);

        av_free(s->run_table[i]);

        av_free(s->level_table[i]);

    }

    return 0;

}


int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src)

{

    int ret, i;

    av_assert0(!dst->f->buf[0]);

    av_assert0(src->f->buf[0]);

    av_assert0(src->tf.f == src->f);

    dst->tf.f = dst->f;

    ret = ff_thread_ref_frame(&dst->tf, &src->tf);

    if (ret < 0)

        goto fail;

    dst->qscale_table_buf = av_buffer_ref(src->qscale_table_buf);

    dst->mb_type_buf      = av_buffer_ref(src->mb_type_buf);

    if (!dst->qscale_table_buf || !dst->mb_type_buf)

        goto fail;

    dst->qscale_table = src->qscale_table;

    dst->mb_type      = src->mb_type;

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

        dst->motion_val_buf[i] = av_buffer_ref(src->motion_val_buf[i]);

        dst->ref_index_buf[i]  = av_buffer_ref(src->ref_index_buf[i]);

        if (!dst->motion_val_buf[i] || !dst->ref_index_buf[i])

            goto fail;

        dst->motion_val[i] = src->motion_val[i];

        dst->ref_index[i]  = src->ref_index[i];

    }

    if (src->hwaccel_picture_private) {

        dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);

        if (!dst->hwaccel_priv_buf)

            goto fail;

        dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;

    }

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

        dst->field_poc[i] = src->field_poc[i];

    memcpy(dst->ref_poc,   src->ref_poc,   sizeof(src->ref_poc));

    memcpy(dst->ref_count, src->ref_count, sizeof(src->ref_count));

    dst->poc           = src->poc;

    dst->frame_num     = src->frame_num;

    dst->mmco_reset    = src->mmco_reset;

    dst->long_ref      = src->long_ref;

    dst->mbaff         = src->mbaff;

    dst->field_picture = src->field_picture;

    dst->reference     = src->reference;

    dst->recovered     = src->recovered;

    dst->invalid_gap   = src->invalid_gap;

    dst->sei_recovery_frame_cnt = src->sei_recovery_frame_cnt;

    return 0;

fail:

    ff_h264_unref_picture(h, dst);

    return ret;

}


static void arm926_initfn(Object *obj)

{

    ARMCPU *cpu = ARM_CPU(obj);

    cpu->dtb_compatible = "arm,arm926";

    set_feature(&cpu->env, ARM_FEATURE_V5);

    set_feature(&cpu->env, ARM_FEATURE_VFP);

    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);

    set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);

    cpu->midr = 0x41069265;

    cpu->reset_fpsid = 0x41011090;

    cpu->ctr = 0x1dd20d2;

    cpu->reset_sctlr = 0x00090078;

}


static int get_cluster_offset(BlockDriverState *bs,

                              VmdkExtent *extent,

                              VmdkMetaData *m_data,

                              uint64_t offset,

                              bool allocate,

                              uint64_t *cluster_offset,

                              uint64_t skip_start_sector,

                              uint64_t skip_end_sector)

{

    unsigned int l1_index, l2_offset, l2_index;

    int min_index, i, j;

    uint32_t min_count, *l2_table;

    bool zeroed = false;

    int64_t ret;

    int32_t cluster_sector;

    if (m_data) {

        m_data->valid = 0;

    }

    if (extent->flat) {

        *cluster_offset = extent->flat_start_offset;

        return VMDK_OK;

    }

    offset -= (extent->end_sector - extent->sectors) * SECTOR_SIZE;

    l1_index = (offset >> 9) / extent->l1_entry_sectors;

    if (l1_index >= extent->l1_size) {

        return VMDK_ERROR;

    }

    l2_offset = extent->l1_table[l1_index];

    if (!l2_offset) {

        return VMDK_UNALLOC;

    }

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

        if (l2_offset == extent->l2_cache_offsets[i]) {

            /* increment the hit count */

            if (++extent->l2_cache_counts[i] == 0xffffffff) {

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

                    extent->l2_cache_counts[j] >>= 1;

                }

            }

            l2_table = extent->l2_cache + (i * extent->l2_size);

            goto found;

        }

    }

    /* not found: load a new entry in the least used one */

    min_index = 0;

    min_count = 0xffffffff;

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

        if (extent->l2_cache_counts[i] < min_count) {

            min_count = extent->l2_cache_counts[i];

            min_index = i;

        }

    }

    l2_table = extent->l2_cache + (min_index * extent->l2_size);

    if (bdrv_pread(

                extent->file,

                (int64_t)l2_offset * 512,

                l2_table,

                extent->l2_size * sizeof(uint32_t)

            ) != extent->l2_size * sizeof(uint32_t)) {

        return VMDK_ERROR;

    }

    extent->l2_cache_offsets[min_index] = l2_offset;

    extent->l2_cache_counts[min_index] = 1;

 found:

    l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;

    cluster_sector = le32_to_cpu(l2_table[l2_index]);

    if (m_data) {

        m_data->valid = 1;

        m_data->l1_index = l1_index;

        m_data->l2_index = l2_index;

        m_data->l2_offset = l2_offset;

        m_data->l2_cache_entry = &l2_table[l2_index];

    }

    if (extent->has_zero_grain && cluster_sector == VMDK_GTE_ZEROED) {

        zeroed = true;

    }

    if (!cluster_sector || zeroed) {

        if (!allocate) {

            return zeroed ? VMDK_ZEROED : VMDK_UNALLOC;

        }

        cluster_sector = extent->next_cluster_sector;

        extent->next_cluster_sector += extent->cluster_sectors;

        /* First of all we write grain itself, to avoid race condition

         * that may to corrupt the image.

         * This problem may occur because of insufficient space on host disk

         * or inappropriate VM shutdown.

         */

        ret = get_whole_cluster(bs, extent,

                                cluster_sector,

                                offset >> BDRV_SECTOR_BITS,

                                skip_start_sector, skip_end_sector);

        if (ret) {

            return ret;

        }

    }

    *cluster_offset = cluster_sector << BDRV_SECTOR_BITS;

    return VMDK_OK;

}


static int check(AVIOContext *pb, int64_t pos, uint32_t *ret_header)

{

    int64_t ret = avio_seek(pb, pos, SEEK_SET);

    uint8_t header_buf[4];

    unsigned header;

    MPADecodeHeader sd;

    if (ret < 0)

        return CHECK_SEEK_FAILED;

    ret = avio_read(pb, &header_buf[0], 4);

    if (ret < 0)

        return CHECK_SEEK_FAILED;

    header = AV_RB32(&header_buf[0]);

    if (ff_mpa_check_header(header) < 0)

        return CHECK_WRONG_HEADER;

    if (avpriv_mpegaudio_decode_header(&sd, header) == 1)

        return CHECK_WRONG_HEADER;

    if (ret_header)

        *ret_header = header;

    return sd.frame_size;

}


static uint64_t icp_pit_read(void *opaque, hwaddr offset,

                             unsigned size)

{

    icp_pit_state *s = (icp_pit_state *)opaque;

    int n;

    /* ??? Don't know the PrimeCell ID for this device.  */

    n = offset >> 8;

    if (n > 2) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad timer %d\n", __func__, n);

    }

    return arm_timer_read(s->timer[n], offset & 0xff);

}


static void get_aac_sample_rates(AVFormatContext *s, AVCodecContext *codec,

                                 int *sample_rate, int *output_sample_rate)

{

    MPEG4AudioConfig mp4ac;

    if (avpriv_mpeg4audio_get_config(&mp4ac, codec->extradata,

                                     codec->extradata_size * 8, 1) < 0) {

        av_log(s, AV_LOG_WARNING,

               "Error parsing AAC extradata, unable to determine samplerate.\n");

        return;

    }

    *sample_rate        = mp4ac.sample_rate;

    *output_sample_rate = mp4ac.ext_sample_rate;

}


static void inter_recon(AVCodecContext *ctx)

{

    static const uint8_t bwlog_tab[2][N_BS_SIZES] = {

        { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 },

        { 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 },

    };

    VP9Context *s = ctx->priv_data;

    VP9Block *b = s->b;

    int row = s->row, col = s->col;

    ThreadFrame *tref1 = &s->refs[s->refidx[b->ref[0]]];

    AVFrame *ref1 = tref1->f;

    ThreadFrame *tref2 = b->comp ? &s->refs[s->refidx[b->ref[1]]] : NULL;

    AVFrame *ref2 = b->comp ? tref2->f : NULL;

    int w = ctx->width, h = ctx->height;

    ptrdiff_t ls_y = s->y_stride, ls_uv = s->uv_stride;

    // y inter pred

    if (b->bs > BS_8x8) {

        if (b->bs == BS_8x4) {

            mc_luma_dir(s, s->dsp.mc[3][b->filter][0], s->dst[0], ls_y,

                        ref1->data[0], ref1->linesize[0], tref1,

                        row << 3, col << 3, &b->mv[0][0], 8, 4, w, h);

            mc_luma_dir(s, s->dsp.mc[3][b->filter][0],

                        s->dst[0] + 4 * ls_y, ls_y,

                        ref1->data[0], ref1->linesize[0], tref1,

                        (row << 3) + 4, col << 3, &b->mv[2][0], 8, 4, w, h);

            if (b->comp) {

                mc_luma_dir(s, s->dsp.mc[3][b->filter][1], s->dst[0], ls_y,

                            ref2->data[0], ref2->linesize[0], tref2,

                            row << 3, col << 3, &b->mv[0][1], 8, 4, w, h);

                mc_luma_dir(s, s->dsp.mc[3][b->filter][1],

                            s->dst[0] + 4 * ls_y, ls_y,

                            ref2->data[0], ref2->linesize[0], tref2,

                            (row << 3) + 4, col << 3, &b->mv[2][1], 8, 4, w, h);

            }

        } else if (b->bs == BS_4x8) {

            mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0], ls_y,

                        ref1->data[0], ref1->linesize[0], tref1,

                        row << 3, col << 3, &b->mv[0][0], 4, 8, w, h);

            mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0] + 4, ls_y,

                        ref1->data[0], ref1->linesize[0], tref1,

                        row << 3, (col << 3) + 4, &b->mv[1][0], 4, 8, w, h);

            if (b->comp) {

                mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0], ls_y,

                            ref2->data[0], ref2->linesize[0], tref2,

                            row << 3, col << 3, &b->mv[0][1], 4, 8, w, h);

                mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0] + 4, ls_y,

                            ref2->data[0], ref2->linesize[0], tref2,

                            row << 3, (col << 3) + 4, &b->mv[1][1], 4, 8, w, h);

            }

        } else {

            av_assert2(b->bs == BS_4x4);

            // FIXME if two horizontally adjacent blocks have the same MV,

            // do a w8 instead of a w4 call

            mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0], ls_y,

                        ref1->data[0], ref1->linesize[0], tref1,

                        row << 3, col << 3, &b->mv[0][0], 4, 4, w, h);

            mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0] + 4, ls_y,

                        ref1->data[0], ref1->linesize[0], tref1,

                        row << 3, (col << 3) + 4, &b->mv[1][0], 4, 4, w, h);

            mc_luma_dir(s, s->dsp.mc[4][b->filter][0],

                        s->dst[0] + 4 * ls_y, ls_y,

                        ref1->data[0], ref1->linesize[0], tref1,

                        (row << 3) + 4, col << 3, &b->mv[2][0], 4, 4, w, h);

            mc_luma_dir(s, s->dsp.mc[4][b->filter][0],

                        s->dst[0] + 4 * ls_y + 4, ls_y,

                        ref1->data[0], ref1->linesize[0], tref1,

                        (row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, w, h);

            if (b->comp) {

                mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0], ls_y,

                            ref2->data[0], ref2->linesize[0], tref2,

                            row << 3, col << 3, &b->mv[0][1], 4, 4, w, h);

                mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0] + 4, ls_y,

                            ref2->data[0], ref2->linesize[0], tref2,

                            row << 3, (col << 3) + 4, &b->mv[1][1], 4, 4, w, h);

                mc_luma_dir(s, s->dsp.mc[4][b->filter][1],

                            s->dst[0] + 4 * ls_y, ls_y,

                            ref2->data[0], ref2->linesize[0], tref2,

                            (row << 3) + 4, col << 3, &b->mv[2][1], 4, 4, w, h);

                mc_luma_dir(s, s->dsp.mc[4][b->filter][1],

                            s->dst[0] + 4 * ls_y + 4, ls_y,

                            ref2->data[0], ref2->linesize[0], tref2,

                            (row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, w, h);

            }

        }

    } else {

        int bwl = bwlog_tab[0][b->bs];

        int bw = bwh_tab[0][b->bs][0] * 4, bh = bwh_tab[0][b->bs][1] * 4;

        mc_luma_dir(s, s->dsp.mc[bwl][b->filter][0], s->dst[0], ls_y,

                    ref1->data[0], ref1->linesize[0], tref1,

                    row << 3, col << 3, &b->mv[0][0],bw, bh, w, h);

        if (b->comp)

            mc_luma_dir(s, s->dsp.mc[bwl][b->filter][1], s->dst[0], ls_y,

                        ref2->data[0], ref2->linesize[0], tref2,

                        row << 3, col << 3, &b->mv[0][1], bw, bh, w, h);

    }

    // uv inter pred

    {

        int bwl = bwlog_tab[1][b->bs];

        int bw = bwh_tab[1][b->bs][0] * 4, bh = bwh_tab[1][b->bs][1] * 4;

        VP56mv mvuv;

        w = (w + 1) >> 1;

        h = (h + 1) >> 1;

        if (b->bs > BS_8x8) {

            mvuv.x = ROUNDED_DIV(b->mv[0][0].x + b->mv[1][0].x + b->mv[2][0].x + b->mv[3][0].x, 4);

            mvuv.y = ROUNDED_DIV(b->mv[0][0].y + b->mv[1][0].y + b->mv[2][0].y + b->mv[3][0].y, 4);

        } else {

            mvuv = b->mv[0][0];

        }

        mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][0],

                      s->dst[1], s->dst[2], ls_uv,

                      ref1->data[1], ref1->linesize[1],

                      ref1->data[2], ref1->linesize[2], tref1,

                      row << 2, col << 2, &mvuv, bw, bh, w, h);

        if (b->comp) {

            if (b->bs > BS_8x8) {

                mvuv.x = ROUNDED_DIV(b->mv[0][1].x + b->mv[1][1].x + b->mv[2][1].x + b->mv[3][1].x, 4);

                mvuv.y = ROUNDED_DIV(b->mv[0][1].y + b->mv[1][1].y + b->mv[2][1].y + b->mv[3][1].y, 4);

            } else {

                mvuv = b->mv[0][1];

            }

            mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][1],

                          s->dst[1], s->dst[2], ls_uv,

                          ref2->data[1], ref2->linesize[1],

                          ref2->data[2], ref2->linesize[2], tref2,

                          row << 2, col << 2, &mvuv, bw, bh, w, h);

        }

    }

    if (!b->skip) {

        /* mostly copied intra_reconn() */

        int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n;

        int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2);

        int end_x = FFMIN(2 * (s->cols - col), w4);

        int end_y = FFMIN(2 * (s->rows - row), h4);

        int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;

        int uvstep1d = 1 << b->uvtx, p;

        uint8_t *dst = s->dst[0];

        // y itxfm add

        for (n = 0, y = 0; y < end_y; y += step1d) {

            uint8_t *ptr = dst;

            for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d, n += step) {

                int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];

                if (eob)

                    s->dsp.itxfm_add[tx][DCT_DCT](ptr, s->y_stride,

                                                  s->block + 16 * n, eob);

            }

            dst += 4 * s->y_stride * step1d;

        }

        // uv itxfm add

        h4 >>= 1;

        w4 >>= 1;

        end_x >>= 1;

        end_y >>= 1;

        step = 1 << (b->uvtx * 2);

        for (p = 0; p < 2; p++) {

            dst = s->dst[p + 1];

            for (n = 0, y = 0; y < end_y; y += uvstep1d) {

                uint8_t *ptr = dst;

                for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d, n += step) {

                    int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n];

                    if (eob)

                        s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride,

                                                        s->uvblock[p] + 16 * n, eob);

                }

                dst += 4 * uvstep1d * s->uv_stride;

            }

        }

    }

}


static void matroska_merge_packets(AVPacket *out, AVPacket *in)

{

    out->data = av_realloc(out->data, out->size+in->size);

    memcpy(out->data+out->size, in->data, in->size);

    out->size += in->size;

    av_destruct_packet(in);

    av_free(in);

}


static int decode_pal(MSS12Context *ctx, ArithCoder *acoder)

{

    int i, ncol, r, g, b;

    uint32_t *pal = ctx->pal + 256 - ctx->free_colours;

    if (!ctx->free_colours)

        return 0;

    ncol = arith_get_number(acoder, ctx->free_colours + 1);

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

        r = arith_get_bits(acoder, 8);

        g = arith_get_bits(acoder, 8);

        b = arith_get_bits(acoder, 8);

        *pal++ = (0xFF << 24) | (r << 16) | (g << 8) | b;

    }

    return !!ncol;

}


int ff_mpeg4_decode_video_packet_header(MpegEncContext *s)

{

    int mb_num_bits= av_log2(s->mb_num - 1) + 1;

    int header_extension=0, mb_num, len;

    /* is there enough space left for a video packet + header */

    if( get_bits_count(&s->gb) > s->gb.size_in_bits-20) return -1;

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

        if(get_bits1(&s->gb)) break;

    }

    if(len!=ff_mpeg4_get_video_packet_prefix_length(s)){

        av_log(s->avctx, AV_LOG_ERROR, "marker does not match f_code\n");

        return -1;

    }

    if(s->shape != RECT_SHAPE){

        header_extension= get_bits1(&s->gb);

        //FIXME more stuff here

    }

    mb_num= get_bits(&s->gb, mb_num_bits);

    if(mb_num>=s->mb_num){

        av_log(s->avctx, AV_LOG_ERROR, "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num);

        return -1;

    }

    if(s->pict_type == AV_PICTURE_TYPE_B){

        int mb_x = 0, mb_y = 0;

        while (s->next_picture.mbskip_table[s->mb_index2xy[mb_num]]) {

            if (!mb_x)

                ff_thread_await_progress(&s->next_picture_ptr->tf, mb_y++, 0);

            mb_num++;

            if (++mb_x == s->mb_width) mb_x = 0;

        }

        if(mb_num >= s->mb_num) return -1; // slice contains just skipped MBs which where already decoded

    }

    s->mb_x= mb_num % s->mb_width;

    s->mb_y= mb_num / s->mb_width;

    if(s->shape != BIN_ONLY_SHAPE){

        int qscale= get_bits(&s->gb, s->quant_precision);

        if(qscale)

            s->chroma_qscale=s->qscale= qscale;

    }

    if(s->shape == RECT_SHAPE){

        header_extension= get_bits1(&s->gb);

    }

    if(header_extension){

        int time_incr=0;

        while (get_bits1(&s->gb) != 0)

            time_incr++;

        check_marker(&s->gb, "before time_increment in video packed header");

        skip_bits(&s->gb, s->time_increment_bits); /* time_increment */

        check_marker(&s->gb, "before vop_coding_type in video packed header");

        skip_bits(&s->gb, 2); /* vop coding type */

        //FIXME not rect stuff here

        if(s->shape != BIN_ONLY_SHAPE){

            skip_bits(&s->gb, 3); /* intra dc vlc threshold */

//FIXME don't just ignore everything

            if(s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){

                mpeg4_decode_sprite_trajectory(s, &s->gb);

                av_log(s->avctx, AV_LOG_ERROR, "untested\n");

            }

            //FIXME reduced res stuff here

            if (s->pict_type != AV_PICTURE_TYPE_I) {

                int f_code = get_bits(&s->gb, 3);       /* fcode_for */

                if(f_code==0){

                    av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (f_code=0)\n");

                }

            }

            if (s->pict_type == AV_PICTURE_TYPE_B) {

                int b_code = get_bits(&s->gb, 3);

                if(b_code==0){

                    av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (b_code=0)\n");

                }

            }

        }

    }

    //FIXME new-pred stuff

    return 0;

}


static inline void gen_intermediate_code_internal(CPUState *env,

                                                  TranslationBlock *tb,

                                                  int search_pc)

{

    DisasContext dc1, *dc = &dc1;

    CPUBreakpoint *bp;

    uint16_t *gen_opc_end;

    int j, lj;

    target_ulong pc_start;

    uint32_t next_page_start;

    int num_insns;

    int max_insns;

    /* generate intermediate code */

    num_temps = 0;

    pc_start = tb->pc;

    dc->tb = tb;

    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

    dc->is_jmp = DISAS_NEXT;

    dc->pc = pc_start;

    dc->singlestep_enabled = env->singlestep_enabled;

    dc->condjmp = 0;

    dc->thumb = ARM_TBFLAG_THUMB(tb->flags);

    dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;

    dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;

#if !defined(CONFIG_USER_ONLY)

    dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);

#endif

    dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);

    dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);

    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);

    cpu_F0s = tcg_temp_new_i32();

    cpu_F1s = tcg_temp_new_i32();

    cpu_F0d = tcg_temp_new_i64();

    cpu_F1d = tcg_temp_new_i64();

    cpu_V0 = cpu_F0d;

    cpu_V1 = cpu_F1d;

    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */

    cpu_M0 = tcg_temp_new_i64();

    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();

    /* A note on handling of the condexec (IT) bits:

     *

     * We want to avoid the overhead of having to write the updated condexec

     * bits back to the CPUState for every instruction in an IT block. So:

     * (1) if the condexec bits are not already zero then we write

     * zero back into the CPUState now. This avoids complications trying

     * to do it at the end of the block. (For example if we don't do this

     * it's hard to identify whether we can safely skip writing condexec

     * at the end of the TB, which we definitely want to do for the case

     * where a TB doesn't do anything with the IT state at all.)

     * (2) if we are going to leave the TB then we call gen_set_condexec()

     * which will write the correct value into CPUState if zero is wrong.

     * This is done both for leaving the TB at the end, and for leaving

     * it because of an exception we know will happen, which is done in

     * gen_exception_insn(). The latter is necessary because we need to

     * leave the TB with the PC/IT state just prior to execution of the

     * instruction which caused the exception.

     * (3) if we leave the TB unexpectedly (eg a data abort on a load)

     * then the CPUState will be wrong and we need to reset it.

     * This is handled in the same way as restoration of the

     * PC in these situations: we will be called again with search_pc=1

     * and generate a mapping of the condexec bits for each PC in

     * gen_opc_condexec_bits[]. gen_pc_load[] then uses this to restore

     * the condexec bits.

     *

     * Note that there are no instructions which can read the condexec

     * bits, and none which can write non-static values to them, so

     * we don't need to care about whether CPUState is correct in the

     * middle of a TB.

     */

    /* Reset the conditional execution bits immediately. This avoids

       complications trying to do it at the end of the block.  */

    if (dc->condexec_mask || dc->condexec_cond)

      {

        TCGv tmp = new_tmp();

        tcg_gen_movi_i32(tmp, 0);

        store_cpu_field(tmp, condexec_bits);

      }

    do {

#ifdef CONFIG_USER_ONLY

        /* Intercept jump to the magic kernel page.  */

        if (dc->pc >= 0xffff0000) {

            /* We always get here via a jump, so know we are not in a

               conditional execution block.  */

            gen_exception(EXCP_KERNEL_TRAP);

            dc->is_jmp = DISAS_UPDATE;

            break;

        }

#else

        if (dc->pc >= 0xfffffff0 && IS_M(env)) {

            /* We always get here via a jump, so know we are not in a

               conditional execution block.  */

            gen_exception(EXCP_EXCEPTION_EXIT);

            dc->is_jmp = DISAS_UPDATE;

            break;

        }

#endif

        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {

            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {

                if (bp->pc == dc->pc) {

                    gen_exception_insn(dc, 0, EXCP_DEBUG);

                    /* Advance PC so that clearing the breakpoint will

                       invalidate this TB.  */

                    dc->pc += 2;

                    goto done_generating;

                    break;

                }

            }

        }

        if (search_pc) {

            j = gen_opc_ptr - gen_opc_buf;

            if (lj < j) {

                lj++;

                while (lj < j)

                    gen_opc_instr_start[lj++] = 0;

            }

            gen_opc_pc[lj] = dc->pc;

            gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);

            gen_opc_instr_start[lj] = 1;

            gen_opc_icount[lj] = num_insns;

        }

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

            gen_io_start();

        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {

            tcg_gen_debug_insn_start(dc->pc);

        }

        if (dc->thumb) {

            disas_thumb_insn(env, dc);

            if (dc->condexec_mask) {

                dc->condexec_cond = (dc->condexec_cond & 0xe)

                                   | ((dc->condexec_mask >> 4) & 1);

                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;

                if (dc->condexec_mask == 0) {

                    dc->condexec_cond = 0;

                }

            }

        } else {

            disas_arm_insn(env, dc);

        }

        if (num_temps) {

            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);

            num_temps = 0;

        }

        if (dc->condjmp && !dc->is_jmp) {

            gen_set_label(dc->condlabel);

            dc->condjmp = 0;

        }

        /* Translation stops when a conditional branch is encountered.

         * Otherwise the subsequent code could get translated several times.

         * Also stop translation when a page boundary is reached.  This

         * ensures prefetch aborts occur at the right place.  */

        num_insns ++;

    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&

             !env->singlestep_enabled &&

             !singlestep &&

             dc->pc < next_page_start &&

             num_insns < max_insns);

    if (tb->cflags & CF_LAST_IO) {

        if (dc->condjmp) {

            /* FIXME:  This can theoretically happen with self-modifying

               code.  */

            cpu_abort(env, "IO on conditional branch instruction");

        }

        gen_io_end();

    }

    /* At this stage dc->condjmp will only be set when the skipped

       instruction was a conditional branch or trap, and the PC has

       already been written.  */

    if (unlikely(env->singlestep_enabled)) {

        /* Make sure the pc is updated, and raise a debug exception.  */

        if (dc->condjmp) {

            gen_set_condexec(dc);

            if (dc->is_jmp == DISAS_SWI) {

                gen_exception(EXCP_SWI);

            } else {

                gen_exception(EXCP_DEBUG);

            }

            gen_set_label(dc->condlabel);

        }

        if (dc->condjmp || !dc->is_jmp) {

            gen_set_pc_im(dc->pc);

            dc->condjmp = 0;

        }

        gen_set_condexec(dc);

        if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {

            gen_exception(EXCP_SWI);

        } else {

            /* FIXME: Single stepping a WFI insn will not halt

               the CPU.  */

            gen_exception(EXCP_DEBUG);

        }

    } else {

        /* While branches must always occur at the end of an IT block,

           there are a few other things that can cause us to terminate

           the TB in the middel of an IT block:

            - Exception generating instructions (bkpt, swi, undefined).

            - Page boundaries.

            - Hardware watchpoints.

           Hardware breakpoints have already been handled and skip this code.

         */

        gen_set_condexec(dc);

        switch(dc->is_jmp) {

        case DISAS_NEXT:

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

            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_TB_JUMP:

            /* nothing more to generate */

            break;

        case DISAS_WFI:

            gen_helper_wfi();

            break;

        case DISAS_SWI:

            gen_exception(EXCP_SWI);

            break;

        }

        if (dc->condjmp) {

            gen_set_label(dc->condlabel);

            gen_set_condexec(dc);

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

            dc->condjmp = 0;

        }

    }

done_generating:

    gen_icount_end(tb, num_insns);

    *gen_opc_ptr = INDEX_op_end;

#ifdef DEBUG_DISAS

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {

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

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

        log_target_disas(pc_start, dc->pc - pc_start, dc->thumb);

        qemu_log("\n");

    }

#endif

    if (search_pc) {

        j = gen_opc_ptr - gen_opc_buf;

        lj++;

        while (lj <= j)

            gen_opc_instr_start[lj++] = 0;

    } else {

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

        tb->icount = num_insns;

    }

}


static int write_representation(AVFormatContext *s, AVStream *stream, int id,

                                int output_width, int output_height,

                                int output_sample_rate) {

    AVDictionaryEntry *irange = av_dict_get(stream->metadata, INITIALIZATION_RANGE, NULL, 0);

    AVDictionaryEntry *cues_start = av_dict_get(stream->metadata, CUES_START, NULL, 0);

    AVDictionaryEntry *cues_end = av_dict_get(stream->metadata, CUES_END, NULL, 0);

    AVDictionaryEntry *filename = av_dict_get(stream->metadata, FILENAME, NULL, 0);

    AVDictionaryEntry *bandwidth = av_dict_get(stream->metadata, BANDWIDTH, NULL, 0);

    if (!irange || cues_start == NULL || cues_end == NULL || filename == NULL ||

        !bandwidth) {

        return -1;

    }

    avio_printf(s->pb, "<Representation id=\"%d\"", id);

    avio_printf(s->pb, " bandwidth=\"%s\"", bandwidth->value);

    if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO && output_width)

        avio_printf(s->pb, " width=\"%d\"", stream->codec->width);

    if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO && output_height)

        avio_printf(s->pb, " height=\"%d\"", stream->codec->height);

    if (stream->codec->codec_type = AVMEDIA_TYPE_AUDIO && output_sample_rate)

        avio_printf(s->pb, " audioSamplingRate=\"%d\"", stream->codec->sample_rate);

    avio_printf(s->pb, ">\n");

    avio_printf(s->pb, "<BaseURL>%s</BaseURL>\n", filename->value);

    avio_printf(s->pb, "<SegmentBase\n");

    avio_printf(s->pb, "  indexRange=\"%s-%s\">\n", cues_start->value, cues_end->value);

    avio_printf(s->pb, "<Initialization\n");

    avio_printf(s->pb, "  range=\"0-%s\" />\n", irange->value);

    avio_printf(s->pb, "</SegmentBase>\n");

    avio_printf(s->pb, "</Representation>\n");

    return 0;

}


static int thp_read_header(AVFormatContext *s,

                           AVFormatParameters *ap)

{

    ThpDemuxContext *thp = s->priv_data;

    AVStream *st;

    AVIOContext *pb = s->pb;

    int64_t fsize= avio_size(pb);

    int i;

    /* Read the file header.  */

                           avio_rb32(pb); /* Skip Magic.  */

    thp->version         = avio_rb32(pb);

                           avio_rb32(pb); /* Max buf size.  */

                           avio_rb32(pb); /* Max samples.  */

    thp->fps             = av_d2q(av_int2float(avio_rb32(pb)), INT_MAX);

    thp->framecnt        = avio_rb32(pb);

    thp->first_framesz   = avio_rb32(pb);

    thp->data_size       = avio_rb32(pb);

    if(fsize>0 && (!thp->data_size || fsize < thp->data_size))

        thp->data_size= fsize;

    thp->compoff         = avio_rb32(pb);

                           avio_rb32(pb); /* offsetDataOffset.  */

    thp->first_frame     = avio_rb32(pb);

    thp->last_frame      = avio_rb32(pb);

    thp->next_framesz    = thp->first_framesz;

    thp->next_frame      = thp->first_frame;

    /* Read the component structure.  */

    avio_seek (pb, thp->compoff, SEEK_SET);

    thp->compcount       = avio_rb32(pb);

    /* Read the list of component types.  */

    avio_read(pb, thp->components, 16);

    for (i = 0; i < thp->compcount; i++) {

        if (thp->components[i] == 0) {

            if (thp->vst != 0)

                break;

            /* Video component.  */

            st = avformat_new_stream(s, NULL);

            if (!st)

                return AVERROR(ENOMEM);

            /* The denominator and numerator are switched because 1/fps

               is required.  */

            avpriv_set_pts_info(st, 64, thp->fps.den, thp->fps.num);

            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

            st->codec->codec_id = CODEC_ID_THP;

            st->codec->codec_tag = 0;  /* no fourcc */

            st->codec->width = avio_rb32(pb);

            st->codec->height = avio_rb32(pb);

            st->codec->sample_rate = av_q2d(thp->fps);

            thp->vst = st;

            thp->video_stream_index = st->index;

            if (thp->version == 0x11000)

                avio_rb32(pb); /* Unknown.  */

        } else if (thp->components[i] == 1) {

            if (thp->has_audio != 0)

                break;

            /* Audio component.  */

            st = avformat_new_stream(s, NULL);

            if (!st)

                return AVERROR(ENOMEM);

            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

            st->codec->codec_id = CODEC_ID_ADPCM_THP;

            st->codec->codec_tag = 0;  /* no fourcc */

            st->codec->channels    = avio_rb32(pb); /* numChannels.  */

            st->codec->sample_rate = avio_rb32(pb); /* Frequency.  */

            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);

            thp->audio_stream_index = st->index;

            thp->has_audio = 1;

        }

    }

    return 0;

}


void av_free(void *ptr)

{

#if CONFIG_MEMALIGN_HACK

    if (ptr)

        free((char *)ptr - ((char *)ptr)[-1]);

#elif HAVE_ALIGNED_MALLOC

    _aligned_free(ptr);

#else

    free(ptr);

#endif

}


static inline int check_bidir_mv(MpegEncContext * s,

                   int motion_fx, int motion_fy,

                   int motion_bx, int motion_by,

                   int pred_fx, int pred_fy,

                   int pred_bx, int pred_by,

                   int size, int h)

{

    //FIXME optimize?

    //FIXME better f_code prediction (max mv & distance)

    //FIXME pointers

    MotionEstContext * const c= &s->me;

    uint8_t * const mv_penalty_f= c->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame

    uint8_t * const mv_penalty_b= c->mv_penalty[s->b_code] + MAX_MV; // f_code of the prev frame

    int stride= c->stride;

    uint8_t *dest_y = c->scratchpad;

    uint8_t *ptr;

    int dxy;

    int src_x, src_y;

    int fbmin;

    uint8_t **src_data= c->src[0];

    uint8_t **ref_data= c->ref[0];

    uint8_t **ref2_data= c->ref[2];

    if(s->quarter_sample){

        dxy = ((motion_fy & 3) << 2) | (motion_fx & 3);

        src_x = motion_fx >> 2;

        src_y = motion_fy >> 2;

        ptr = ref_data[0] + (src_y * stride) + src_x;

        s->qdsp.put_qpel_pixels_tab[0][dxy](dest_y, ptr, stride);

        dxy = ((motion_by & 3) << 2) | (motion_bx & 3);

        src_x = motion_bx >> 2;

        src_y = motion_by >> 2;

        ptr = ref2_data[0] + (src_y * stride) + src_x;

        s->qdsp.avg_qpel_pixels_tab[size][dxy](dest_y, ptr, stride);

    }else{

        dxy = ((motion_fy & 1) << 1) | (motion_fx & 1);

        src_x = motion_fx >> 1;

        src_y = motion_fy >> 1;

        ptr = ref_data[0] + (src_y * stride) + src_x;

        s->hdsp.put_pixels_tab[size][dxy](dest_y    , ptr    , stride, h);

        dxy = ((motion_by & 1) << 1) | (motion_bx & 1);

        src_x = motion_bx >> 1;

        src_y = motion_by >> 1;

        ptr = ref2_data[0] + (src_y * stride) + src_x;

        s->hdsp.avg_pixels_tab[size][dxy](dest_y    , ptr    , stride, h);

    }

    fbmin = (mv_penalty_f[motion_fx-pred_fx] + mv_penalty_f[motion_fy-pred_fy])*c->mb_penalty_factor

           +(mv_penalty_b[motion_bx-pred_bx] + mv_penalty_b[motion_by-pred_by])*c->mb_penalty_factor

           + s->mecc.mb_cmp[size](s, src_data[0], dest_y, stride, h); // FIXME new_pic

    if(c->avctx->mb_cmp&FF_CMP_CHROMA){

    }

    //FIXME CHROMA !!!

    return fbmin;

}


static int init_prec(Jpeg2000Band *band,

                     Jpeg2000ResLevel *reslevel,

                     Jpeg2000Component *comp,

                     int precno, int bandno, int reslevelno,

                     int log2_band_prec_width,

                     int log2_band_prec_height)

{

    Jpeg2000Prec *prec = band->prec + precno;

    int nb_codeblocks, cblkno;

    prec->decoded_layers = 0;

    /* TODO: Explain formula for JPEG200 DCINEMA. */

    /* TODO: Verify with previous count of codeblocks per band */

    /* Compute P_x0 */

    prec->coord[0][0] = ((band->coord[0][0] >> log2_band_prec_width) + precno % reslevel->num_precincts_x) *

                        (1 << log2_band_prec_width);

    /* Compute P_y0 */

    prec->coord[1][0] = ((band->coord[1][0] >> log2_band_prec_height) + precno / reslevel->num_precincts_x) *

                        (1 << log2_band_prec_height);

    /* Compute P_x1 */

    prec->coord[0][1] = prec->coord[0][0] +

                        (1 << log2_band_prec_width);

    prec->coord[0][0] = FFMAX(prec->coord[0][0], band->coord[0][0]);

    prec->coord[0][1] = FFMIN(prec->coord[0][1], band->coord[0][1]);

    /* Compute P_y1 */

    prec->coord[1][1] = prec->coord[1][0] +

                        (1 << log2_band_prec_height);

    prec->coord[1][0] = FFMAX(prec->coord[1][0], band->coord[1][0]);

    prec->coord[1][1] = FFMIN(prec->coord[1][1], band->coord[1][1]);

    prec->nb_codeblocks_width =

        ff_jpeg2000_ceildivpow2(prec->coord[0][1],

                                band->log2_cblk_width)

        - (prec->coord[0][0] >> band->log2_cblk_width);

    prec->nb_codeblocks_height =

        ff_jpeg2000_ceildivpow2(prec->coord[1][1],

                                band->log2_cblk_height)

        - (prec->coord[1][0] >> band->log2_cblk_height);

    /* Tag trees initialization */

    prec->cblkincl =

        ff_jpeg2000_tag_tree_init(prec->nb_codeblocks_width,

                                  prec->nb_codeblocks_height);

    if (!prec->cblkincl)

        return AVERROR(ENOMEM);

    prec->zerobits =

        ff_jpeg2000_tag_tree_init(prec->nb_codeblocks_width,

                                  prec->nb_codeblocks_height);

    if (!prec->zerobits)

        return AVERROR(ENOMEM);

    if (prec->nb_codeblocks_width * (uint64_t)prec->nb_codeblocks_height > INT_MAX) {

        prec->cblk = NULL;

        return AVERROR(ENOMEM);

    }

    nb_codeblocks = prec->nb_codeblocks_width * prec->nb_codeblocks_height;

    prec->cblk = av_mallocz_array(nb_codeblocks, sizeof(*prec->cblk));

    if (!prec->cblk)

        return AVERROR(ENOMEM);

    for (cblkno = 0; cblkno < nb_codeblocks; cblkno++) {

        Jpeg2000Cblk *cblk = prec->cblk + cblkno;

        int Cx0, Cy0;

        /* Compute coordinates of codeblocks */

        /* Compute Cx0*/

        Cx0 = ((prec->coord[0][0]) >> band->log2_cblk_width) << band->log2_cblk_width;

        Cx0 = Cx0 + ((cblkno % prec->nb_codeblocks_width)  << band->log2_cblk_width);

        cblk->coord[0][0] = FFMAX(Cx0, prec->coord[0][0]);

        /* Compute Cy0*/

        Cy0 = ((prec->coord[1][0]) >> band->log2_cblk_height) << band->log2_cblk_height;

        Cy0 = Cy0 + ((cblkno / prec->nb_codeblocks_width)   << band->log2_cblk_height);

        cblk->coord[1][0] = FFMAX(Cy0, prec->coord[1][0]);

        /* Compute Cx1 */

        cblk->coord[0][1] = FFMIN(Cx0 + (1 << band->log2_cblk_width),

                                  prec->coord[0][1]);

        /* Compute Cy1 */

        cblk->coord[1][1] = FFMIN(Cy0 + (1 << band->log2_cblk_height),

                                  prec->coord[1][1]);

        /* Update code-blocks coordinates according sub-band position */

        if ((bandno + !!reslevelno) & 1) {

            cblk->coord[0][0] += comp->reslevel[reslevelno-1].coord[0][1] -

                                 comp->reslevel[reslevelno-1].coord[0][0];

            cblk->coord[0][1] += comp->reslevel[reslevelno-1].coord[0][1] -

                                 comp->reslevel[reslevelno-1].coord[0][0];

        }

        if ((bandno + !!reslevelno) & 2) {

            cblk->coord[1][0] += comp->reslevel[reslevelno-1].coord[1][1] -

                                 comp->reslevel[reslevelno-1].coord[1][0];

            cblk->coord[1][1] += comp->reslevel[reslevelno-1].coord[1][1] -

                                 comp->reslevel[reslevelno-1].coord[1][0];

        }

        cblk->zero      = 0;

        cblk->lblock    = 3;

        cblk->length    = 0;

        memset(cblk->lengthinc, 0, sizeof(cblk->lengthinc));

        cblk->npasses   = 0;

    }

    return 0;

}


static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,

                                  const uint8_t *buf, int nb_sectors)

{

    BDRVQcowState *s = bs->opaque;

    z_stream strm;

    int ret, out_len;

    uint8_t *out_buf;

    uint64_t cluster_offset;

    if (nb_sectors == 0) {

        /* align end of file to a sector boundary to ease reading with

           sector based I/Os */

        cluster_offset = bdrv_getlength(bs->file);

        cluster_offset = (cluster_offset + 511) & ~511;

        bdrv_truncate(bs->file, cluster_offset);

        return 0;

    }

    if (nb_sectors != s->cluster_sectors) {

        ret = -EINVAL;

        /* Zero-pad last write if image size is not cluster aligned */

        if (sector_num + nb_sectors == bs->total_sectors &&

            nb_sectors < s->cluster_sectors) {

            uint8_t *pad_buf = qemu_blockalign(bs, s->cluster_size);

            memset(pad_buf, 0, s->cluster_size);

            memcpy(pad_buf, buf, nb_sectors * BDRV_SECTOR_SIZE);

            ret = qcow2_write_compressed(bs, sector_num,

                                         pad_buf, s->cluster_sectors);

            qemu_vfree(pad_buf);

        }

        return ret;

    }

    out_buf = g_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);

    /* best compression, small window, no zlib header */

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

    ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,

                       Z_DEFLATED, -12,

                       9, Z_DEFAULT_STRATEGY);

    if (ret != 0) {

        ret = -EINVAL;

        goto fail;

    }

    strm.avail_in = s->cluster_size;

    strm.next_in = (uint8_t *)buf;

    strm.avail_out = s->cluster_size;

    strm.next_out = out_buf;

    ret = deflate(&strm, Z_FINISH);

    if (ret != Z_STREAM_END && ret != Z_OK) {

        deflateEnd(&strm);

        ret = -EINVAL;

        goto fail;

    }

    out_len = strm.next_out - out_buf;

    deflateEnd(&strm);

    if (ret != Z_STREAM_END || out_len >= s->cluster_size) {

        /* could not compress: write normal cluster */

        ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,

                sector_num * BDRV_SECTOR_SIZE,

                s->cluster_sectors * BDRV_SECTOR_SIZE);

        if (ret < 0) {

            goto fail;

        }

        ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors);

        if (ret < 0) {

            goto fail;

        }

    } else {

        cluster_offset = qcow2_alloc_compressed_cluster_offset(bs,

            sector_num << 9, out_len);

        if (!cluster_offset) {

            ret = -EIO;

            goto fail;

        }

        cluster_offset &= s->cluster_offset_mask;

        ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,

                cluster_offset, out_len);

        if (ret < 0) {

            goto fail;

        }

        BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);

        ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len);

        if (ret < 0) {

            goto fail;

        }

    }

    ret = 0;

fail:

    g_free(out_buf);

    return ret;

}


static void test_init(void)

{

    uint64_t barsize;

    dev = get_device();

    dev_base = qpci_iomap(dev, 0, &barsize);

    g_assert(dev_base != NULL);

    qpci_device_enable(dev);

    test_timer();

}


void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)

{

    PowerPCCPU *cpu = ppc_env_get_cpu(env);

    CPUState *cs = CPU(cpu);

    DisasContext ctx, *ctxp = &ctx;

    opc_handler_t **table, *handler;

    target_ulong pc_start;

    int num_insns;

    int max_insns;

    pc_start = tb->pc;

    ctx.nip = pc_start;

    ctx.tb = tb;

    ctx.exception = POWERPC_EXCP_NONE;

    ctx.spr_cb = env->spr_cb;

    ctx.pr = msr_pr;

    ctx.mem_idx = env->dmmu_idx;

    ctx.dr = msr_dr;

#if !defined(CONFIG_USER_ONLY)

    ctx.hv = msr_hv || !env->has_hv_mode;

#endif

    ctx.insns_flags = env->insns_flags;

    ctx.insns_flags2 = env->insns_flags2;

    ctx.access_type = -1;

    ctx.le_mode = !!(env->hflags & (1 << MSR_LE));

    ctx.default_tcg_memop_mask = ctx.le_mode ? MO_LE : MO_BE;

#if defined(TARGET_PPC64)

    ctx.sf_mode = msr_is_64bit(env, env->msr);

    ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);

#endif

    if (env->mmu_model == POWERPC_MMU_32B ||

        env->mmu_model == POWERPC_MMU_601 ||

        (env->mmu_model & POWERPC_MMU_64B))

            ctx.lazy_tlb_flush = true;

    ctx.fpu_enabled = !!msr_fp;

    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)

        ctx.spe_enabled = !!msr_spe;

    else

        ctx.spe_enabled = false;

    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)

        ctx.altivec_enabled = !!msr_vr;

    else

        ctx.altivec_enabled = false;

    if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) {

        ctx.vsx_enabled = !!msr_vsx;

    } else {

        ctx.vsx_enabled = false;

    }

#if defined(TARGET_PPC64)

    if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {

        ctx.tm_enabled = !!msr_tm;

    } else {

        ctx.tm_enabled = false;

    }

#endif

    if ((env->flags & POWERPC_FLAG_SE) && msr_se)

        ctx.singlestep_enabled = CPU_SINGLE_STEP;

    else

        ctx.singlestep_enabled = 0;

    if ((env->flags & POWERPC_FLAG_BE) && msr_be)

        ctx.singlestep_enabled |= CPU_BRANCH_STEP;

    if (unlikely(cs->singlestep_enabled)) {

        ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;

    }

#if defined (DO_SINGLE_STEP) && 0

    /* Single step trace mode */

    msr_se = 1;

#endif

    num_insns = 0;

    max_insns = tb->cflags & CF_COUNT_MASK;

    if (max_insns == 0) {

        max_insns = CF_COUNT_MASK;

    }

    if (max_insns > TCG_MAX_INSNS) {

        max_insns = TCG_MAX_INSNS;

    }

    gen_tb_start(tb);

    tcg_clear_temp_count();

    /* Set env in case of segfault during code fetch */

    while (ctx.exception == POWERPC_EXCP_NONE && !tcg_op_buf_full()) {

        tcg_gen_insn_start(ctx.nip);

        num_insns++;

        if (unlikely(cpu_breakpoint_test(cs, ctx.nip, BP_ANY))) {

            gen_debug_exception(ctxp);

            /* The address covered by the breakpoint must be included in

               [tb->pc, tb->pc + tb->size) in order to for it to be

               properly cleared -- thus we increment the PC here so that

               the logic setting tb->size below does the right thing.  */

            ctx.nip += 4;

            break;

        }

        LOG_DISAS("----------------\n");

        LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",

                  ctx.nip, ctx.mem_idx, (int)msr_ir);

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

            gen_io_start();

        if (unlikely(need_byteswap(&ctx))) {

            ctx.opcode = bswap32(cpu_ldl_code(env, ctx.nip));

        } else {

            ctx.opcode = cpu_ldl_code(env, ctx.nip);

        }

        LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",

                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),

                    opc3(ctx.opcode), ctx.le_mode ? "little" : "big");

        ctx.nip += 4;

        table = env->opcodes;

        handler = table[opc1(ctx.opcode)];

        if (is_indirect_opcode(handler)) {

            table = ind_table(handler);

            handler = table[opc2(ctx.opcode)];

            if (is_indirect_opcode(handler)) {

                table = ind_table(handler);

                handler = table[opc3(ctx.opcode)];

            }

        }

        /* Is opcode *REALLY* valid ? */

        if (unlikely(handler->handler == &gen_invalid)) {

            qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: "

                          "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",

                          opc1(ctx.opcode), opc2(ctx.opcode),

                          opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);

        } else {

            uint32_t inval;

            if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) {

                inval = handler->inval2;

            } else {

                inval = handler->inval1;

            }

            if (unlikely((ctx.opcode & inval) != 0)) {

                qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: "

                              "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",

                              ctx.opcode & inval, opc1(ctx.opcode),

                              opc2(ctx.opcode), opc3(ctx.opcode),

                              ctx.opcode, ctx.nip - 4);

                gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);

                break;

            }

        }

        (*(handler->handler))(&ctx);

#if defined(DO_PPC_STATISTICS)

        handler->count++;

#endif

        /* Check trace mode exceptions */

        if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&

                     (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&

                     ctx.exception != POWERPC_SYSCALL &&

                     ctx.exception != POWERPC_EXCP_TRAP &&

                     ctx.exception != POWERPC_EXCP_BRANCH)) {

            gen_exception(ctxp, POWERPC_EXCP_TRACE);

        } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||

                            (cs->singlestep_enabled) ||

                            singlestep ||

                            num_insns >= max_insns)) {

            /* if we reach a page boundary or are single stepping, stop

             * generation

             */

            break;

        }

        if (tcg_check_temp_count()) {

            fprintf(stderr, "Opcode %02x %02x %02x (%08x) leaked temporaries\n",

                    opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode),

                    ctx.opcode);

            exit(1);

        }

    }

    if (tb->cflags & CF_LAST_IO)

        gen_io_end();

    if (ctx.exception == POWERPC_EXCP_NONE) {

        gen_goto_tb(&ctx, 0, ctx.nip);

    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {

        if (unlikely(cs->singlestep_enabled)) {

            gen_debug_exception(ctxp);

        }

        /* Generate the return instruction */

        tcg_gen_exit_tb(0);

    }

    gen_tb_end(tb, num_insns);

    tb->size = ctx.nip - pc_start;

    tb->icount = num_insns;

#if defined(DEBUG_DISAS)

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)

        && qemu_log_in_addr_range(pc_start)) {

        int flags;

        flags = env->bfd_mach;

        flags |= ctx.le_mode << 16;

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

        log_target_disas(cs, pc_start, ctx.nip - pc_start, flags);

        qemu_log("\n");

    }

#endif

}


static void smptebars_fill_picture(AVFilterContext *ctx, AVFrame *picref)

{

    TestSourceContext *test = ctx->priv;

    FFDrawColor color;

    int r_w, r_h, w_h, p_w, p_h, i, tmp, x = 0;

    const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format);

    r_w = FFALIGN((test->w + 6) / 7, 1 << pixdesc->log2_chroma_w);

    r_h = FFALIGN(test->h * 2 / 3, 1 << pixdesc->log2_chroma_h);

    w_h = FFALIGN(test->h * 3 / 4 - r_h,  1 << pixdesc->log2_chroma_h);

    p_w = FFALIGN(r_w * 5 / 4, 1 << pixdesc->log2_chroma_w);

    p_h = test->h - w_h - r_h;

#define DRAW_COLOR(rgba, x, y, w, h)                                    \

    ff_draw_color(&test->draw, &color, rgba);                           \

    ff_fill_rectangle(&test->draw, &color,                              \

                      picref->data, picref->linesize, x, y, w, h)       \

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

        DRAW_COLOR(rainbow[i], x, 0,   FFMIN(r_w, test->w - x), r_h);

        DRAW_COLOR(wobnair[i], x, r_h, FFMIN(r_w, test->w - x), w_h);

        x += r_w;

    }

    x = 0;

    DRAW_COLOR(i_pixel, x, r_h + w_h, p_w, p_h);

    x += p_w;

    DRAW_COLOR(white, x, r_h + w_h, p_w, p_h);

    x += p_w;

    DRAW_COLOR(q_pixel, x, r_h + w_h, p_w, p_h);

    x += p_w;

    tmp = FFALIGN(5 * r_w - x,  1 << pixdesc->log2_chroma_w);

    DRAW_COLOR(black, x, r_h + w_h, tmp, p_h);

    x += tmp;

    tmp = FFALIGN(r_w / 3,  1 << pixdesc->log2_chroma_w);

    DRAW_COLOR(neg4ire, x, r_h + w_h, tmp, p_h);

    x += tmp;

    DRAW_COLOR(black, x, r_h + w_h, tmp, p_h);

    x += tmp;

    DRAW_COLOR(pos4ire, x, r_h + w_h, tmp, p_h);

    x += tmp;

    DRAW_COLOR(black, x, r_h + w_h, test->w - x, p_h);

}