static int wrapped_avframe_encode(AVCodecContext *avctx, AVPacket *pkt,

                     const AVFrame *frame, int *got_packet)

{

    AVFrame *wrapped = av_frame_clone(frame);

    if (!wrapped)

        return AVERROR(ENOMEM);

    pkt->buf = av_buffer_create((uint8_t *)wrapped, sizeof(*wrapped),

                                wrapped_avframe_release_buffer, NULL,

                                AV_BUFFER_FLAG_READONLY);

    if (!pkt->buf) {

        av_frame_free(&wrapped);

        return AVERROR(ENOMEM);

    }

    pkt->data = (uint8_t *)wrapped;

    pkt->size = sizeof(*wrapped);

    pkt->flags |= AV_PKT_FLAG_KEY;

    *got_packet = 1;

    return 0;

}


static int kvm_s390_check_enable_cmma(KVMState *s)

{

    struct kvm_device_attr attr = {

        .group = KVM_S390_VM_MEM_CTRL,

        .attr = KVM_S390_VM_MEM_ENABLE_CMMA,

    };

    return kvm_vm_ioctl(s, KVM_HAS_DEVICE_ATTR, &attr);

}


void tcg_optimize(TCGContext *s)

{

    int oi, oi_next, nb_temps, nb_globals;

    /* Array VALS has an element for each temp.

       If this temp holds a constant then its value is kept in VALS' element.

       If this temp is a copy of other ones then the other copies are

       available through the doubly linked circular list. */

    nb_temps = s->nb_temps;

    nb_globals = s->nb_globals;

    reset_all_temps(nb_temps);

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

        tcg_target_ulong mask, partmask, affected;

        int nb_oargs, nb_iargs, i;

        TCGArg tmp;

        TCGOp * const op = &s->gen_op_buf[oi];

        TCGArg * const args = &s->gen_opparam_buf[op->args];

        TCGOpcode opc = op->opc;

        const TCGOpDef *def = &tcg_op_defs[opc];

        oi_next = op->next;

        if (opc == INDEX_op_call) {

            nb_oargs = op->callo;

            nb_iargs = op->calli;

        } else {

            nb_oargs = def->nb_oargs;

            nb_iargs = def->nb_iargs;

        }

        /* Do copy propagation */

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

            if (temps[args[i]].state == TCG_TEMP_COPY) {

                args[i] = find_better_copy(s, args[i]);

            }

        }

        /* For commutative operations make constant second argument */

        switch (opc) {

        CASE_OP_32_64(add):

        CASE_OP_32_64(mul):

        CASE_OP_32_64(and):

        CASE_OP_32_64(or):

        CASE_OP_32_64(xor):

        CASE_OP_32_64(eqv):

        CASE_OP_32_64(nand):

        CASE_OP_32_64(nor):

        CASE_OP_32_64(muluh):

        CASE_OP_32_64(mulsh):

            swap_commutative(args[0], &args[1], &args[2]);

            break;

        CASE_OP_32_64(brcond):

            if (swap_commutative(-1, &args[0], &args[1])) {

                args[2] = tcg_swap_cond(args[2]);

            }

            break;

        CASE_OP_32_64(setcond):

            if (swap_commutative(args[0], &args[1], &args[2])) {

                args[3] = tcg_swap_cond(args[3]);

            }

            break;

        CASE_OP_32_64(movcond):

            if (swap_commutative(-1, &args[1], &args[2])) {

                args[5] = tcg_swap_cond(args[5]);

            }

            /* For movcond, we canonicalize the "false" input reg to match

               the destination reg so that the tcg backend can implement

               a "move if true" operation.  */

            if (swap_commutative(args[0], &args[4], &args[3])) {

                args[5] = tcg_invert_cond(args[5]);

            }

            break;

        CASE_OP_32_64(add2):

            swap_commutative(args[0], &args[2], &args[4]);

            swap_commutative(args[1], &args[3], &args[5]);

            break;

        CASE_OP_32_64(mulu2):

        CASE_OP_32_64(muls2):

            swap_commutative(args[0], &args[2], &args[3]);

            break;

        case INDEX_op_brcond2_i32:

            if (swap_commutative2(&args[0], &args[2])) {

                args[4] = tcg_swap_cond(args[4]);

            }

            break;

        case INDEX_op_setcond2_i32:

            if (swap_commutative2(&args[1], &args[3])) {

                args[5] = tcg_swap_cond(args[5]);

            }

            break;

        default:

            break;

        }

        /* Simplify expressions for "shift/rot r, 0, a => movi r, 0",

           and "sub r, 0, a => neg r, a" case.  */

        switch (opc) {

        CASE_OP_32_64(shl):

        CASE_OP_32_64(shr):

        CASE_OP_32_64(sar):

        CASE_OP_32_64(rotl):

        CASE_OP_32_64(rotr):

            if (temps[args[1]].state == TCG_TEMP_CONST

                && temps[args[1]].val == 0) {

                tcg_opt_gen_movi(s, op, args, args[0], 0);

                continue;

            }

            break;

        CASE_OP_32_64(sub):

            {

                TCGOpcode neg_op;

                bool have_neg;

                if (temps[args[2]].state == TCG_TEMP_CONST) {

                    /* Proceed with possible constant folding. */

                    break;

                }

                if (opc == INDEX_op_sub_i32) {

                    neg_op = INDEX_op_neg_i32;

                    have_neg = TCG_TARGET_HAS_neg_i32;

                } else {

                    neg_op = INDEX_op_neg_i64;

                    have_neg = TCG_TARGET_HAS_neg_i64;

                }

                if (!have_neg) {

                    break;

                }

                if (temps[args[1]].state == TCG_TEMP_CONST

                    && temps[args[1]].val == 0) {

                    op->opc = neg_op;

                    reset_temp(args[0]);

                    args[1] = args[2];

                    continue;

                }

            }

            break;

        CASE_OP_32_64(xor):

        CASE_OP_32_64(nand):

            if (temps[args[1]].state != TCG_TEMP_CONST

                && temps[args[2]].state == TCG_TEMP_CONST

                && temps[args[2]].val == -1) {

                i = 1;

                goto try_not;

            }

            break;

        CASE_OP_32_64(nor):

            if (temps[args[1]].state != TCG_TEMP_CONST

                && temps[args[2]].state == TCG_TEMP_CONST

                && temps[args[2]].val == 0) {

                i = 1;

                goto try_not;

            }

            break;

        CASE_OP_32_64(andc):

            if (temps[args[2]].state != TCG_TEMP_CONST

                && temps[args[1]].state == TCG_TEMP_CONST

                && temps[args[1]].val == -1) {

                i = 2;

                goto try_not;

            }

            break;

        CASE_OP_32_64(orc):

        CASE_OP_32_64(eqv):

            if (temps[args[2]].state != TCG_TEMP_CONST

                && temps[args[1]].state == TCG_TEMP_CONST

                && temps[args[1]].val == 0) {

                i = 2;

                goto try_not;

            }

            break;

        try_not:

            {

                TCGOpcode not_op;

                bool have_not;

                if (def->flags & TCG_OPF_64BIT) {

                    not_op = INDEX_op_not_i64;

                    have_not = TCG_TARGET_HAS_not_i64;

                } else {

                    not_op = INDEX_op_not_i32;

                    have_not = TCG_TARGET_HAS_not_i32;

                }

                if (!have_not) {

                    break;

                }

                op->opc = not_op;

                reset_temp(args[0]);

                args[1] = args[i];

                continue;

            }

        default:

            break;

        }

        /* Simplify expression for "op r, a, const => mov r, a" cases */

        switch (opc) {

        CASE_OP_32_64(add):

        CASE_OP_32_64(sub):

        CASE_OP_32_64(shl):

        CASE_OP_32_64(shr):

        CASE_OP_32_64(sar):

        CASE_OP_32_64(rotl):

        CASE_OP_32_64(rotr):

        CASE_OP_32_64(or):

        CASE_OP_32_64(xor):

        CASE_OP_32_64(andc):

            if (temps[args[1]].state != TCG_TEMP_CONST

                && temps[args[2]].state == TCG_TEMP_CONST

                && temps[args[2]].val == 0) {

                tcg_opt_gen_mov(s, op, args, args[0], args[1]);

                continue;

            }

            break;

        CASE_OP_32_64(and):

        CASE_OP_32_64(orc):

        CASE_OP_32_64(eqv):

            if (temps[args[1]].state != TCG_TEMP_CONST

                && temps[args[2]].state == TCG_TEMP_CONST

                && temps[args[2]].val == -1) {

                tcg_opt_gen_mov(s, op, args, args[0], args[1]);

                continue;

            }

            break;

        default:

            break;

        }

        /* Simplify using known-zero bits. Currently only ops with a single

           output argument is supported. */

        mask = -1;

        affected = -1;

        switch (opc) {

        CASE_OP_32_64(ext8s):

            if ((temps[args[1]].mask & 0x80) != 0) {

                break;

            }

        CASE_OP_32_64(ext8u):

            mask = 0xff;

            goto and_const;

        CASE_OP_32_64(ext16s):

            if ((temps[args[1]].mask & 0x8000) != 0) {

                break;

            }

        CASE_OP_32_64(ext16u):

            mask = 0xffff;

            goto and_const;

        case INDEX_op_ext32s_i64:

            if ((temps[args[1]].mask & 0x80000000) != 0) {

                break;

            }

        case INDEX_op_ext32u_i64:

            mask = 0xffffffffU;

            goto and_const;

        CASE_OP_32_64(and):

            mask = temps[args[2]].mask;

            if (temps[args[2]].state == TCG_TEMP_CONST) {

        and_const:

                affected = temps[args[1]].mask & ~mask;

            }

            mask = temps[args[1]].mask & mask;

            break;

        CASE_OP_32_64(andc):

            /* Known-zeros does not imply known-ones.  Therefore unless

               args[2] is constant, we can't infer anything from it.  */

            if (temps[args[2]].state == TCG_TEMP_CONST) {

                mask = ~temps[args[2]].mask;

                goto and_const;

            }

            /* But we certainly know nothing outside args[1] may be set. */

            mask = temps[args[1]].mask;

            break;

        case INDEX_op_sar_i32:

            if (temps[args[2]].state == TCG_TEMP_CONST) {

                tmp = temps[args[2]].val & 31;

                mask = (int32_t)temps[args[1]].mask >> tmp;

            }

            break;

        case INDEX_op_sar_i64:

            if (temps[args[2]].state == TCG_TEMP_CONST) {

                tmp = temps[args[2]].val & 63;

                mask = (int64_t)temps[args[1]].mask >> tmp;

            }

            break;

        case INDEX_op_shr_i32:

            if (temps[args[2]].state == TCG_TEMP_CONST) {

                tmp = temps[args[2]].val & 31;

                mask = (uint32_t)temps[args[1]].mask >> tmp;

            }

            break;

        case INDEX_op_shr_i64:

            if (temps[args[2]].state == TCG_TEMP_CONST) {

                tmp = temps[args[2]].val & 63;

                mask = (uint64_t)temps[args[1]].mask >> tmp;

            }

            break;

        case INDEX_op_trunc_shr_i32:

            mask = (uint64_t)temps[args[1]].mask >> args[2];

            break;

        CASE_OP_32_64(shl):

            if (temps[args[2]].state == TCG_TEMP_CONST) {

                tmp = temps[args[2]].val & (TCG_TARGET_REG_BITS - 1);

                mask = temps[args[1]].mask << tmp;

            }

            break;

        CASE_OP_32_64(neg):

            /* Set to 1 all bits to the left of the rightmost.  */

            mask = -(temps[args[1]].mask & -temps[args[1]].mask);

            break;

        CASE_OP_32_64(deposit):

            mask = deposit64(temps[args[1]].mask, args[3], args[4],

                             temps[args[2]].mask);

            break;

        CASE_OP_32_64(or):

        CASE_OP_32_64(xor):

            mask = temps[args[1]].mask | temps[args[2]].mask;

            break;

        CASE_OP_32_64(setcond):

        case INDEX_op_setcond2_i32:

            mask = 1;

            break;

        CASE_OP_32_64(movcond):

            mask = temps[args[3]].mask | temps[args[4]].mask;

            break;

        CASE_OP_32_64(ld8u):

            mask = 0xff;

            break;

        CASE_OP_32_64(ld16u):

            mask = 0xffff;

            break;

        case INDEX_op_ld32u_i64:

            mask = 0xffffffffu;

            break;

        CASE_OP_32_64(qemu_ld):

            {

                TCGMemOpIdx oi = args[nb_oargs + nb_iargs];

                TCGMemOp mop = get_memop(oi);

                if (!(mop & MO_SIGN)) {

                    mask = (2ULL << ((8 << (mop & MO_SIZE)) - 1)) - 1;

                }

            }

            break;

        default:

            break;

        }

        /* 32-bit ops generate 32-bit results.  For the result is zero test

           below, we can ignore high bits, but for further optimizations we

           need to record that the high bits contain garbage.  */

        partmask = mask;

        if (!(def->flags & TCG_OPF_64BIT)) {

            mask |= ~(tcg_target_ulong)0xffffffffu;

            partmask &= 0xffffffffu;

            affected &= 0xffffffffu;

        }

        if (partmask == 0) {

            assert(nb_oargs == 1);

            tcg_opt_gen_movi(s, op, args, args[0], 0);

            continue;

        }

        if (affected == 0) {

            assert(nb_oargs == 1);

            tcg_opt_gen_mov(s, op, args, args[0], args[1]);

            continue;

        }

        /* Simplify expression for "op r, a, 0 => movi r, 0" cases */

        switch (opc) {

        CASE_OP_32_64(and):

        CASE_OP_32_64(mul):

        CASE_OP_32_64(muluh):

        CASE_OP_32_64(mulsh):

            if ((temps[args[2]].state == TCG_TEMP_CONST

                && temps[args[2]].val == 0)) {

                tcg_opt_gen_movi(s, op, args, args[0], 0);

                continue;

            }

            break;

        default:

            break;

        }

        /* Simplify expression for "op r, a, a => mov r, a" cases */

        switch (opc) {

        CASE_OP_32_64(or):

        CASE_OP_32_64(and):

            if (temps_are_copies(args[1], args[2])) {

                tcg_opt_gen_mov(s, op, args, args[0], args[1]);

                continue;

            }

            break;

        default:

            break;

        }

        /* Simplify expression for "op r, a, a => movi r, 0" cases */

        switch (opc) {

        CASE_OP_32_64(andc):

        CASE_OP_32_64(sub):

        CASE_OP_32_64(xor):

            if (temps_are_copies(args[1], args[2])) {

                tcg_opt_gen_movi(s, op, args, args[0], 0);

                continue;

            }

            break;

        default:

            break;

        }

        /* Propagate constants through copy operations and do constant

           folding.  Constants will be substituted to arguments by register

           allocator where needed and possible.  Also detect copies. */

        switch (opc) {

        CASE_OP_32_64(mov):

            tcg_opt_gen_mov(s, op, args, args[0], args[1]);

            break;

        CASE_OP_32_64(movi):

            tcg_opt_gen_movi(s, op, args, args[0], args[1]);

            break;

        CASE_OP_32_64(not):

        CASE_OP_32_64(neg):

        CASE_OP_32_64(ext8s):

        CASE_OP_32_64(ext8u):

        CASE_OP_32_64(ext16s):

        CASE_OP_32_64(ext16u):

        case INDEX_op_ext32s_i64:

        case INDEX_op_ext32u_i64:

            if (temps[args[1]].state == TCG_TEMP_CONST) {

                tmp = do_constant_folding(opc, temps[args[1]].val, 0);

                tcg_opt_gen_movi(s, op, args, args[0], tmp);

                break;

            }

            goto do_default;

        case INDEX_op_trunc_shr_i32:

            if (temps[args[1]].state == TCG_TEMP_CONST) {

                tmp = do_constant_folding(opc, temps[args[1]].val, args[2]);

                tcg_opt_gen_movi(s, op, args, args[0], tmp);

                break;

            }

            goto do_default;

        CASE_OP_32_64(add):

        CASE_OP_32_64(sub):

        CASE_OP_32_64(mul):

        CASE_OP_32_64(or):

        CASE_OP_32_64(and):

        CASE_OP_32_64(xor):

        CASE_OP_32_64(shl):

        CASE_OP_32_64(shr):

        CASE_OP_32_64(sar):

        CASE_OP_32_64(rotl):

        CASE_OP_32_64(rotr):

        CASE_OP_32_64(andc):

        CASE_OP_32_64(orc):

        CASE_OP_32_64(eqv):

        CASE_OP_32_64(nand):

        CASE_OP_32_64(nor):

        CASE_OP_32_64(muluh):

        CASE_OP_32_64(mulsh):

        CASE_OP_32_64(div):

        CASE_OP_32_64(divu):

        CASE_OP_32_64(rem):

        CASE_OP_32_64(remu):

            if (temps[args[1]].state == TCG_TEMP_CONST

                && temps[args[2]].state == TCG_TEMP_CONST) {

                tmp = do_constant_folding(opc, temps[args[1]].val,

                                          temps[args[2]].val);

                tcg_opt_gen_movi(s, op, args, args[0], tmp);

                break;

            }

            goto do_default;

        CASE_OP_32_64(deposit):

            if (temps[args[1]].state == TCG_TEMP_CONST

                && temps[args[2]].state == TCG_TEMP_CONST) {

                tmp = deposit64(temps[args[1]].val, args[3], args[4],

                                temps[args[2]].val);

                tcg_opt_gen_movi(s, op, args, args[0], tmp);

                break;

            }

            goto do_default;

        CASE_OP_32_64(setcond):

            tmp = do_constant_folding_cond(opc, args[1], args[2], args[3]);

            if (tmp != 2) {

                tcg_opt_gen_movi(s, op, args, args[0], tmp);

                break;

            }

            goto do_default;

        CASE_OP_32_64(brcond):

            tmp = do_constant_folding_cond(opc, args[0], args[1], args[2]);

            if (tmp != 2) {

                if (tmp) {

                    reset_all_temps(nb_temps);

                    op->opc = INDEX_op_br;

                    args[0] = args[3];

                } else {

                    tcg_op_remove(s, op);

                }

                break;

            }

            goto do_default;

        CASE_OP_32_64(movcond):

            tmp = do_constant_folding_cond(opc, args[1], args[2], args[5]);

            if (tmp != 2) {

                tcg_opt_gen_mov(s, op, args, args[0], args[4-tmp]);

                break;

            }

            goto do_default;

        case INDEX_op_add2_i32:

        case INDEX_op_sub2_i32:

            if (temps[args[2]].state == TCG_TEMP_CONST

                && temps[args[3]].state == TCG_TEMP_CONST

                && temps[args[4]].state == TCG_TEMP_CONST

                && temps[args[5]].state == TCG_TEMP_CONST) {

                uint32_t al = temps[args[2]].val;

                uint32_t ah = temps[args[3]].val;

                uint32_t bl = temps[args[4]].val;

                uint32_t bh = temps[args[5]].val;

                uint64_t a = ((uint64_t)ah << 32) | al;

                uint64_t b = ((uint64_t)bh << 32) | bl;

                TCGArg rl, rh;

                TCGOp *op2 = insert_op_before(s, op, INDEX_op_movi_i32, 2);

                TCGArg *args2 = &s->gen_opparam_buf[op2->args];

                if (opc == INDEX_op_add2_i32) {

                    a += b;

                } else {

                    a -= b;

                }

                rl = args[0];

                rh = args[1];

                tcg_opt_gen_movi(s, op, args, rl, (int32_t)a);

                tcg_opt_gen_movi(s, op2, args2, rh, (int32_t)(a >> 32));

                /* We've done all we need to do with the movi.  Skip it.  */

                oi_next = op2->next;

                break;

            }

            goto do_default;

        case INDEX_op_mulu2_i32:

            if (temps[args[2]].state == TCG_TEMP_CONST

                && temps[args[3]].state == TCG_TEMP_CONST) {

                uint32_t a = temps[args[2]].val;

                uint32_t b = temps[args[3]].val;

                uint64_t r = (uint64_t)a * b;

                TCGArg rl, rh;

                TCGOp *op2 = insert_op_before(s, op, INDEX_op_movi_i32, 2);

                TCGArg *args2 = &s->gen_opparam_buf[op2->args];

                rl = args[0];

                rh = args[1];

                tcg_opt_gen_movi(s, op, args, rl, (int32_t)r);

                tcg_opt_gen_movi(s, op2, args2, rh, (int32_t)(r >> 32));

                /* We've done all we need to do with the movi.  Skip it.  */

                oi_next = op2->next;

                break;

            }

            goto do_default;

        case INDEX_op_brcond2_i32:

            tmp = do_constant_folding_cond2(&args[0], &args[2], args[4]);

            if (tmp != 2) {

                if (tmp) {

            do_brcond_true:

                    reset_all_temps(nb_temps);

                    op->opc = INDEX_op_br;

                    args[0] = args[5];

                } else {

            do_brcond_false:

                    tcg_op_remove(s, op);

                }

            } else if ((args[4] == TCG_COND_LT || args[4] == TCG_COND_GE)

                       && temps[args[2]].state == TCG_TEMP_CONST

                       && temps[args[3]].state == TCG_TEMP_CONST

                       && temps[args[2]].val == 0

                       && temps[args[3]].val == 0) {

                /* Simplify LT/GE comparisons vs zero to a single compare

                   vs the high word of the input.  */

            do_brcond_high:

                reset_all_temps(nb_temps);

                op->opc = INDEX_op_brcond_i32;

                args[0] = args[1];

                args[1] = args[3];

                args[2] = args[4];

                args[3] = args[5];

            } else if (args[4] == TCG_COND_EQ) {

                /* Simplify EQ comparisons where one of the pairs

                   can be simplified.  */

                tmp = do_constant_folding_cond(INDEX_op_brcond_i32,

                                               args[0], args[2], TCG_COND_EQ);

                if (tmp == 0) {

                    goto do_brcond_false;

                } else if (tmp == 1) {

                    goto do_brcond_high;

                }

                tmp = do_constant_folding_cond(INDEX_op_brcond_i32,

                                               args[1], args[3], TCG_COND_EQ);

                if (tmp == 0) {

                    goto do_brcond_false;

                } else if (tmp != 1) {

                    goto do_default;

                }

            do_brcond_low:

                reset_all_temps(nb_temps);

                op->opc = INDEX_op_brcond_i32;

                args[1] = args[2];

                args[2] = args[4];

                args[3] = args[5];

            } else if (args[4] == TCG_COND_NE) {

                /* Simplify NE comparisons where one of the pairs

                   can be simplified.  */

                tmp = do_constant_folding_cond(INDEX_op_brcond_i32,

                                               args[0], args[2], TCG_COND_NE);

                if (tmp == 0) {

                    goto do_brcond_high;

                } else if (tmp == 1) {

                    goto do_brcond_true;

                }

                tmp = do_constant_folding_cond(INDEX_op_brcond_i32,

                                               args[1], args[3], TCG_COND_NE);

                if (tmp == 0) {

                    goto do_brcond_low;

                } else if (tmp == 1) {

                    goto do_brcond_true;

                }

                goto do_default;

            } else {

                goto do_default;

            }

            break;

        case INDEX_op_setcond2_i32:

            tmp = do_constant_folding_cond2(&args[1], &args[3], args[5]);

            if (tmp != 2) {

            do_setcond_const:

                tcg_opt_gen_movi(s, op, args, args[0], tmp);

            } else if ((args[5] == TCG_COND_LT || args[5] == TCG_COND_GE)

                       && temps[args[3]].state == TCG_TEMP_CONST

                       && temps[args[4]].state == TCG_TEMP_CONST

                       && temps[args[3]].val == 0

                       && temps[args[4]].val == 0) {

                /* Simplify LT/GE comparisons vs zero to a single compare

                   vs the high word of the input.  */

            do_setcond_high:

                reset_temp(args[0]);

                temps[args[0]].mask = 1;

                op->opc = INDEX_op_setcond_i32;

                args[1] = args[2];

                args[2] = args[4];

                args[3] = args[5];

            } else if (args[5] == TCG_COND_EQ) {

                /* Simplify EQ comparisons where one of the pairs

                   can be simplified.  */

                tmp = do_constant_folding_cond(INDEX_op_setcond_i32,

                                               args[1], args[3], TCG_COND_EQ);

                if (tmp == 0) {

                    goto do_setcond_const;

                } else if (tmp == 1) {

                    goto do_setcond_high;

                }

                tmp = do_constant_folding_cond(INDEX_op_setcond_i32,

                                               args[2], args[4], TCG_COND_EQ);

                if (tmp == 0) {

                    goto do_setcond_high;

                } else if (tmp != 1) {

                    goto do_default;

                }

            do_setcond_low:

                reset_temp(args[0]);

                temps[args[0]].mask = 1;

                op->opc = INDEX_op_setcond_i32;

                args[2] = args[3];

                args[3] = args[5];

            } else if (args[5] == TCG_COND_NE) {

                /* Simplify NE comparisons where one of the pairs

                   can be simplified.  */

                tmp = do_constant_folding_cond(INDEX_op_setcond_i32,

                                               args[1], args[3], TCG_COND_NE);

                if (tmp == 0) {

                    goto do_setcond_high;

                } else if (tmp == 1) {

                    goto do_setcond_const;

                }

                tmp = do_constant_folding_cond(INDEX_op_setcond_i32,

                                               args[2], args[4], TCG_COND_NE);

                if (tmp == 0) {

                    goto do_setcond_low;

                } else if (tmp == 1) {

                    goto do_setcond_const;

                }

                goto do_default;

            } else {

                goto do_default;

            }

            break;

        case INDEX_op_call:

            if (!(args[nb_oargs + nb_iargs + 1]

                  & (TCG_CALL_NO_READ_GLOBALS | TCG_CALL_NO_WRITE_GLOBALS))) {

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

                    reset_temp(i);

                }

            }

            goto do_reset_output;

        default:

        do_default:

            /* Default case: we know nothing about operation (or were unable

               to compute the operation result) so no propagation is done.

               We trash everything if the operation is the end of a basic

               block, otherwise we only trash the output args.  "mask" is

               the non-zero bits mask for the first output arg.  */

            if (def->flags & TCG_OPF_BB_END) {

                reset_all_temps(nb_temps);

            } else {

        do_reset_output:

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

                    reset_temp(args[i]);

                    /* Save the corresponding known-zero bits mask for the

                       first output argument (only one supported so far). */

                    if (i == 0) {

                        temps[args[i]].mask = mask;

                    }

                }

            }

            break;

        }

    }

}


static int net_host_check_device(const char *device)

{

    int i;

    const char *valid_param_list[] = { "tap", "socket", "dump"

#ifdef CONFIG_NET_BRIDGE

                                       , "bridge"

#endif

#ifdef CONFIG_SLIRP

                                       ,"user"

#endif

#ifdef CONFIG_VDE

                                       ,"vde"

#endif

    };

    for (i = 0; i < ARRAY_SIZE(valid_param_list); i++) {

        if (!strncmp(valid_param_list[i], device,

                     strlen(valid_param_list[i])))

            return 1;

    }

    return 0;

}


uint32_t pci_default_read_config(PCIDevice *d,

                                 uint32_t address, int len)

{

    uint32_t val;

    switch(len) {

    default:

    case 4:

	if (address <= 0xfc) {

            val = pci_get_long(d->config + address);

	    break;

	}

	/* fall through */

    case 2:

        if (address <= 0xfe) {

            val = pci_get_word(d->config + address);

	    break;

	}

	/* fall through */

    case 1:

        val = pci_get_byte(d->config + address);

        break;

    }

    return val;

}


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

{

    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    DeviceClass *dc = DEVICE_CLASS(klass);

    k->init = l2x0_priv_init;

    dc->vmsd = &vmstate_l2x0;

    dc->no_user = 1;

    dc->props = l2x0_properties;

    dc->reset = l2x0_priv_reset;

}


int MPV_encode_init(AVCodecContext *avctx)

{

    MpegEncContext *s = avctx->priv_data;

    int i;

    avctx->pix_fmt = PIX_FMT_YUV420P;

    s->bit_rate = avctx->bit_rate;

    s->bit_rate_tolerance = avctx->bit_rate_tolerance;

    s->frame_rate = avctx->frame_rate;

    s->width = avctx->width;

    s->height = avctx->height;

    s->gop_size = avctx->gop_size;

    s->rtp_mode = avctx->rtp_mode;

    s->rtp_payload_size = avctx->rtp_payload_size;

    if (avctx->rtp_callback)

        s->rtp_callback = avctx->rtp_callback;

    s->qmin= avctx->qmin;

    s->qmax= avctx->qmax;

    s->max_qdiff= avctx->max_qdiff;

    s->qcompress= avctx->qcompress;

    s->qblur= avctx->qblur;

    s->b_quant_factor= avctx->b_quant_factor;

    s->avctx = avctx;

    s->aspect_ratio_info= avctx->aspect_ratio_info;

    s->flags= avctx->flags;

    s->max_b_frames= avctx->max_b_frames;

    s->rc_strategy= avctx->rc_strategy;

    s->b_frame_strategy= avctx->b_frame_strategy;

    s->codec_id= avctx->codec->id;

    if (s->gop_size <= 1) {

        s->intra_only = 1;

        s->gop_size = 12;

    } else {

        s->intra_only = 0;

    }

    /* ME algorithm */

    if (avctx->me_method == 0)

        /* For compatibility */

        s->me_method = motion_estimation_method;

    else

        s->me_method = avctx->me_method;

    /* Fixed QSCALE */

    s->fixed_qscale = (avctx->flags & CODEC_FLAG_QSCALE);

    switch(avctx->codec->id) {

    case CODEC_ID_MPEG1VIDEO:

        s->out_format = FMT_MPEG1;

        avctx->delay=0; //FIXME not sure, should check the spec

        break;

    case CODEC_ID_MJPEG:

        s->out_format = FMT_MJPEG;

        s->intra_only = 1; /* force intra only for jpeg */

        s->mjpeg_write_tables = 1; /* write all tables */

	s->mjpeg_data_only_frames = 0; /* write all the needed headers */

        s->mjpeg_vsample[0] = 2; /* set up default sampling factors */

        s->mjpeg_vsample[1] = 1; /* the only currently supported values */

        s->mjpeg_vsample[2] = 1;

        s->mjpeg_hsample[0] = 2;

        s->mjpeg_hsample[1] = 1;

        s->mjpeg_hsample[2] = 1;

        if (mjpeg_init(s) < 0)

            return -1;

        avctx->delay=0;

        break;

    case CODEC_ID_H263:

        if (h263_get_picture_format(s->width, s->height) == 7) {

            printf("Input picture size isn't suitable for h263 codec! try h263+\n");

            return -1;

        }

        s->out_format = FMT_H263;

        avctx->delay=0;

        break;

    case CODEC_ID_H263P:

        s->out_format = FMT_H263;

        s->rtp_mode = 1;

        s->rtp_payload_size = 1200;

        s->h263_plus = 1;

        s->unrestricted_mv = 1;

        s->h263_aic = 1;

        /* These are just to be sure */

        s->umvplus = 0;

        s->umvplus_dec = 0;

        avctx->delay=0;

        break;

    case CODEC_ID_RV10:

        s->out_format = FMT_H263;

        s->h263_rv10 = 1;

        avctx->delay=0;

        break;

    case CODEC_ID_MPEG4:

        s->out_format = FMT_H263;

        s->h263_pred = 1;

        s->unrestricted_mv = 1;

        s->has_b_frames= s->max_b_frames ? 1 : 0;

        s->low_delay=0;

        avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1);

        break;

    case CODEC_ID_MSMPEG4V1:

        s->out_format = FMT_H263;

        s->h263_msmpeg4 = 1;

        s->h263_pred = 1;

        s->unrestricted_mv = 1;

        s->msmpeg4_version= 1;

        avctx->delay=0;

        break;

    case CODEC_ID_MSMPEG4V2:

        s->out_format = FMT_H263;

        s->h263_msmpeg4 = 1;

        s->h263_pred = 1;

        s->unrestricted_mv = 1;

        s->msmpeg4_version= 2;

        avctx->delay=0;

        break;

    case CODEC_ID_MSMPEG4V3:

        s->out_format = FMT_H263;

        s->h263_msmpeg4 = 1;

        s->h263_pred = 1;

        s->unrestricted_mv = 1;

        s->msmpeg4_version= 3;

        avctx->delay=0;

        break;

    default:

        return -1;

    }

    if((s->flags&CODEC_FLAG_4MV) && !(s->flags&CODEC_FLAG_HQ)){

        printf("4MV is currently only supported in HQ mode\n");

        return -1;

    }

    { /* set up some save defaults, some codecs might override them later */

        static int done=0;

        if(!done){

            int i;

            done=1;

            memset(default_mv_penalty, 0, sizeof(UINT16)*(MAX_FCODE+1)*(2*MAX_MV+1));

            memset(default_fcode_tab , 0, sizeof(UINT8)*(2*MAX_MV+1));

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

                default_fcode_tab[i + MAX_MV]= 1;

            }

        }

    }

    s->mv_penalty= default_mv_penalty;

    s->fcode_tab= default_fcode_tab;

    if (s->out_format == FMT_H263)

        h263_encode_init(s);

    else if (s->out_format == FMT_MPEG1)

        mpeg1_encode_init(s);

    /* dont use mv_penalty table for crap MV as it would be confused */

    if (s->me_method < ME_EPZS) s->mv_penalty = default_mv_penalty;

    s->encoding = 1;

    /* init */

    if (MPV_common_init(s) < 0)

        return -1;

    /* init default q matrix */

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

        if(s->out_format == FMT_H263)

            s->intra_matrix[i] = default_non_intra_matrix[i];

        else

            s->intra_matrix[i] = default_intra_matrix[i];

        s->inter_matrix[i] = default_non_intra_matrix[i];

    }

    /* precompute matrix */

    /* for mjpeg, we do include qscale in the matrix */

    if (s->out_format != FMT_MJPEG) {

        convert_matrix(s->q_intra_matrix, s->q_intra_matrix16, s->q_intra_matrix16_bias,

                       s->intra_matrix, s->intra_quant_bias);

        convert_matrix(s->q_inter_matrix, s->q_inter_matrix16, s->q_inter_matrix16_bias,

                       s->inter_matrix, s->inter_quant_bias);

    }

    if(ff_rate_control_init(s) < 0)

        return -1;

    s->picture_number = 0;

    s->picture_in_gop_number = 0;

    s->fake_picture_number = 0;

    /* motion detector init */

    s->f_code = 1;

    s->b_code = 1;

    return 0;

}


static void inline xan_wc3_output_pixel_run(XanContext *s,

    unsigned char *pixel_buffer, int x, int y, int pixel_count)

{

    int stride;

    int line_inc;

    int index;

    int current_x;

    int width = s->avctx->width;

    unsigned char pix;

    unsigned char *palette_plane;

    unsigned char *y_plane;

    unsigned char *u_plane;

    unsigned char *v_plane;

    unsigned char *rgb_plane;

    unsigned short *rgb16_plane;

    unsigned short *palette16;

    unsigned int *rgb32_plane;

    unsigned int *palette32;

    switch (s->avctx->pix_fmt) {

    case PIX_FMT_PAL8:

        palette_plane = s->current_frame.data[0];

        stride = s->current_frame.linesize[0];

        line_inc = stride - width;

        index = y * stride + x;

        current_x = x;

        while(pixel_count--) {

            /* don't do a memcpy() here; keyframes generally copy an entire

             * frame of data and the stride needs to be accounted for */

            palette_plane[index++] = *pixel_buffer++;

            ADVANCE_CURRENT_X();

        }

        break;

    case PIX_FMT_RGB555:

    case PIX_FMT_RGB565:

        rgb16_plane = (unsigned short *)s->current_frame.data[0];

        palette16 = (unsigned short *)s->palette;

        stride = s->current_frame.linesize[0] / 2;

        line_inc = stride - width;

        index = y * stride + x;

        current_x = x;

        while(pixel_count--) {

            rgb16_plane[index++] = palette16[*pixel_buffer++];

            ADVANCE_CURRENT_X();

        }

        break;

    case PIX_FMT_RGB24:

    case PIX_FMT_BGR24:

        rgb_plane = s->current_frame.data[0];

        stride = s->current_frame.linesize[0];

        line_inc = stride - width * 3;

        index = y * stride + x * 3;

        current_x = x;

        while(pixel_count--) {

            pix = *pixel_buffer++;

            rgb_plane[index++] = s->palette[pix * 4 + 0];

            rgb_plane[index++] = s->palette[pix * 4 + 1];

            rgb_plane[index++] = s->palette[pix * 4 + 2];

            ADVANCE_CURRENT_X();

        }

        break;

    case PIX_FMT_RGBA32:

        rgb32_plane = (unsigned int *)s->current_frame.data[0];

        palette32 = (unsigned int *)s->palette;

        stride = s->current_frame.linesize[0] / 4;

        line_inc = stride - width;

        index = y * stride + x;

        current_x = x;

        while(pixel_count--) {

            rgb32_plane[index++] = palette32[*pixel_buffer++];

            ADVANCE_CURRENT_X();

        }

        break;

    case PIX_FMT_YUV444P:

        y_plane = s->current_frame.data[0];

        u_plane = s->current_frame.data[1];

        v_plane = s->current_frame.data[2];

        stride = s->current_frame.linesize[0];

        line_inc = stride - width;

        index = y * stride + x;

        current_x = x;

        while(pixel_count--) {

            pix = *pixel_buffer++;

            y_plane[index] = s->palette[pix * 4 + 0];

            u_plane[index] = s->palette[pix * 4 + 1];

            v_plane[index] = s->palette[pix * 4 + 2];

            index++;

            ADVANCE_CURRENT_X();

        }

        break;

    default:

        av_log(s->avctx, AV_LOG_ERROR, " Xan WC3: Unhandled colorspace\n");

        break;

    }

}


const char *bdrv_get_format_name(BlockDriverState *bs)

{

    return bs->drv ? bs->drv->format_name : NULL;

}


static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOVAtom atom)

{

    AVStream *st = c->fc->streams[c->fc->nb_streams-1];

    uint32_t type;

    uint32_t ctype;

    get_byte(pb); /* version */

    get_be24(pb); /* flags */

    /* component type */

    ctype = get_le32(pb);

    type = get_le32(pb); /* component subtype */

    dprintf(c->fc, "ctype= %c%c%c%c (0x%08x)\n", *((char *)&ctype), ((char *)&ctype)[1],

            ((char *)&ctype)[2], ((char *)&ctype)[3], (int) ctype);

    dprintf(c->fc, "stype= %c%c%c%c\n",

            *((char *)&type), ((char *)&type)[1], ((char *)&type)[2], ((char *)&type)[3]);

    if(!ctype)

        c->isom = 1;

    if     (type == MKTAG('v','i','d','e'))

        st->codec->codec_type = CODEC_TYPE_VIDEO;

    else if(type == MKTAG('s','o','u','n'))

        st->codec->codec_type = CODEC_TYPE_AUDIO;

    else if(type == MKTAG('m','1','a',' '))

        st->codec->codec_id = CODEC_ID_MP2;

    else if(type == MKTAG('s','u','b','p')) {

        st->codec->codec_type = CODEC_TYPE_SUBTITLE;

    }

    get_be32(pb); /* component  manufacture */

    get_be32(pb); /* component flags */

    get_be32(pb); /* component flags mask */

    if(atom.size <= 24)

        return 0; /* nothing left to read */

    url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));

    return 0;

}


static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)

{

    target_ulong msr, new_msr, vector;

    int srr0, srr1, asrr0, asrr1;

    int lpes0, lpes1, lev;

    if (0) {

        /* XXX: find a suitable condition to enable the hypervisor mode */

        lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;

        lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;

    } else {

        /* Those values ensure we won't enter the hypervisor mode */

        lpes0 = 0;

        lpes1 = 1;

    }

    qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx

                  " => %08x (%02x)\n", env->nip, excp, env->error_code);

    /* new srr1 value excluding must-be-zero bits */

    msr = env->msr & ~0x783f0000ULL;

    /* new interrupt handler msr */

    new_msr = env->msr & ((target_ulong)1 << MSR_ME);

    /* target registers */

    srr0 = SPR_SRR0;

    srr1 = SPR_SRR1;

    asrr0 = -1;

    asrr1 = -1;

    switch (excp) {

    case POWERPC_EXCP_NONE:

        /* Should never happen */

        return;

    case POWERPC_EXCP_CRITICAL:    /* Critical input                         */

        switch (excp_model) {

        case POWERPC_EXCP_40x:

            srr0 = SPR_40x_SRR2;

            srr1 = SPR_40x_SRR3;

            break;

        case POWERPC_EXCP_BOOKE:

            srr0 = SPR_BOOKE_CSRR0;

            srr1 = SPR_BOOKE_CSRR1;

            break;

        case POWERPC_EXCP_G2:

            break;

        default:

            goto excp_invalid;

        }

        goto store_next;

    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */

        if (msr_me == 0) {

            /* Machine check exception is not enabled.

             * Enter checkstop state.

             */

            if (qemu_log_enabled()) {

                qemu_log("Machine check while not allowed. "

                        "Entering checkstop state\n");

            } else {

                fprintf(stderr, "Machine check while not allowed. "

                        "Entering checkstop state\n");

            }

            env->halted = 1;

            env->interrupt_request |= CPU_INTERRUPT_EXITTB;

        }

        if (0) {

            /* XXX: find a suitable condition to enable the hypervisor mode */

            new_msr |= (target_ulong)MSR_HVB;

        }

        /* machine check exceptions don't have ME set */

        new_msr &= ~((target_ulong)1 << MSR_ME);

        /* XXX: should also have something loaded in DAR / DSISR */

        switch (excp_model) {

        case POWERPC_EXCP_40x:

            srr0 = SPR_40x_SRR2;

            srr1 = SPR_40x_SRR3;

            break;

        case POWERPC_EXCP_BOOKE:

            srr0 = SPR_BOOKE_MCSRR0;

            srr1 = SPR_BOOKE_MCSRR1;

            asrr0 = SPR_BOOKE_CSRR0;

            asrr1 = SPR_BOOKE_CSRR1;

            break;

        default:

            break;

        }

        goto store_next;

    case POWERPC_EXCP_DSI:       /* Data storage exception                   */

        LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx

                 "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */

        LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx

                 "\n", msr, env->nip);

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        msr |= env->error_code;

        goto store_next;

    case POWERPC_EXCP_EXTERNAL:  /* External input                           */

        if (lpes0 == 1)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        /* XXX: this is false */

        /* Get rS/rD and rA from faulting opcode */

        env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;

        goto store_current;

    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */

        switch (env->error_code & ~0xF) {

        case POWERPC_EXCP_FP:

            if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {

                LOG_EXCP("Ignore floating point exception\n");

                env->exception_index = POWERPC_EXCP_NONE;

                env->error_code = 0;

                return;

            }

            if (lpes1 == 0)

                new_msr |= (target_ulong)MSR_HVB;

            msr |= 0x00100000;

            if (msr_fe0 == msr_fe1)

                goto store_next;

            msr |= 0x00010000;

            break;

        case POWERPC_EXCP_INVAL:

            LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);

            if (lpes1 == 0)

                new_msr |= (target_ulong)MSR_HVB;

            msr |= 0x00080000;

            env->spr[SPR_BOOKE_ESR] = ESR_PIL;

            break;

        case POWERPC_EXCP_PRIV:

            if (lpes1 == 0)

                new_msr |= (target_ulong)MSR_HVB;

            msr |= 0x00040000;

            env->spr[SPR_BOOKE_ESR] = ESR_PPR;

            break;

        case POWERPC_EXCP_TRAP:

            if (lpes1 == 0)

                new_msr |= (target_ulong)MSR_HVB;

            msr |= 0x00020000;

            env->spr[SPR_BOOKE_ESR] = ESR_PTR;

            break;

        default:

            /* Should never occur */

            cpu_abort(env, "Invalid program exception %d. Aborting\n",

                      env->error_code);

            break;

        }

        goto store_current;

    case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_current;

    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */

        dump_syscall(env);

        lev = env->error_code;

        if ((lev == 1) && cpu_ppc_hypercall) {

            cpu_ppc_hypercall(env);

            return;

        }

        if (lev == 1 || (lpes0 == 0 && lpes1 == 0))

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */

        goto store_current;

    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */

        /* FIT on 4xx */

        LOG_EXCP("FIT exception\n");

        goto store_next;

    case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */

        LOG_EXCP("WDT exception\n");

        switch (excp_model) {

        case POWERPC_EXCP_BOOKE:

            srr0 = SPR_BOOKE_CSRR0;

            srr1 = SPR_BOOKE_CSRR1;

            break;

        default:

            break;

        }

        goto store_next;

    case POWERPC_EXCP_DTLB:      /* Data TLB error                           */

        goto store_next;

    case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */

        goto store_next;

    case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */

        switch (excp_model) {

        case POWERPC_EXCP_BOOKE:

            srr0 = SPR_BOOKE_DSRR0;

            srr1 = SPR_BOOKE_DSRR1;

            asrr0 = SPR_BOOKE_CSRR0;

            asrr1 = SPR_BOOKE_CSRR1;

            break;

        default:

            break;

        }

        /* XXX: TODO */

        cpu_abort(env, "Debug exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */

        env->spr[SPR_BOOKE_ESR] = ESR_SPV;

        goto store_current;

    case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */

        /* XXX: TODO */

        cpu_abort(env, "Embedded floating point data exception "

                  "is not implemented yet !\n");

        env->spr[SPR_BOOKE_ESR] = ESR_SPV;

        goto store_next;

    case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */

        /* XXX: TODO */

        cpu_abort(env, "Embedded floating point round exception "

                  "is not implemented yet !\n");

        env->spr[SPR_BOOKE_ESR] = ESR_SPV;

        goto store_next;

    case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */

        /* XXX: TODO */

        cpu_abort(env,

                  "Performance counter exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */

        goto store_next;

    case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */

        srr0 = SPR_BOOKE_CSRR0;

        srr1 = SPR_BOOKE_CSRR1;

        goto store_next;

    case POWERPC_EXCP_RESET:     /* System reset exception                   */

        if (msr_pow) {

            /* indicate that we resumed from power save mode */

            msr |= 0x10000;

        } else {

            new_msr &= ~((target_ulong)1 << MSR_ME);

        }

        if (0) {

            /* XXX: find a suitable condition to enable the hypervisor mode */

            new_msr |= (target_ulong)MSR_HVB;

        }

        goto store_next;

    case POWERPC_EXCP_DSEG:      /* Data segment exception                   */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_TRACE:     /* Trace exception                          */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_current;

    case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */

        LOG_EXCP("PIT exception\n");

        goto store_next;

    case POWERPC_EXCP_IO:        /* IO error exception                       */

        /* XXX: TODO */

        cpu_abort(env, "601 IO error exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_RUNM:      /* Run mode exception                       */

        /* XXX: TODO */

        cpu_abort(env, "601 run mode exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_EMUL:      /* Emulation trap exception                 */

        /* XXX: TODO */

        cpu_abort(env, "602 emulation trap exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */

        if (lpes1 == 0) /* XXX: check this */

            new_msr |= (target_ulong)MSR_HVB;

        switch (excp_model) {

        case POWERPC_EXCP_602:

        case POWERPC_EXCP_603:

        case POWERPC_EXCP_603E:

        case POWERPC_EXCP_G2:

            goto tlb_miss_tgpr;

        case POWERPC_EXCP_7x5:

            goto tlb_miss;

        case POWERPC_EXCP_74xx:

            goto tlb_miss_74xx;

        default:

            cpu_abort(env, "Invalid instruction TLB miss exception\n");

            break;

        }

        break;

    case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */

        if (lpes1 == 0) /* XXX: check this */

            new_msr |= (target_ulong)MSR_HVB;

        switch (excp_model) {

        case POWERPC_EXCP_602:

        case POWERPC_EXCP_603:

        case POWERPC_EXCP_603E:

        case POWERPC_EXCP_G2:

            goto tlb_miss_tgpr;

        case POWERPC_EXCP_7x5:

            goto tlb_miss;

        case POWERPC_EXCP_74xx:

            goto tlb_miss_74xx;

        default:

            cpu_abort(env, "Invalid data load TLB miss exception\n");

            break;

        }

        break;

    case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */

        if (lpes1 == 0) /* XXX: check this */

            new_msr |= (target_ulong)MSR_HVB;

        switch (excp_model) {

        case POWERPC_EXCP_602:

        case POWERPC_EXCP_603:

        case POWERPC_EXCP_603E:

        case POWERPC_EXCP_G2:

        tlb_miss_tgpr:

            /* Swap temporary saved registers with GPRs */

            if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {

                new_msr |= (target_ulong)1 << MSR_TGPR;

                hreg_swap_gpr_tgpr(env);

            }

            goto tlb_miss;

        case POWERPC_EXCP_7x5:

        tlb_miss:

#if defined (DEBUG_SOFTWARE_TLB)

            if (qemu_log_enabled()) {

                const char *es;

                target_ulong *miss, *cmp;

                int en;

                if (excp == POWERPC_EXCP_IFTLB) {

                    es = "I";

                    en = 'I';

                    miss = &env->spr[SPR_IMISS];

                    cmp = &env->spr[SPR_ICMP];

                } else {

                    if (excp == POWERPC_EXCP_DLTLB)

                        es = "DL";

                    else

                        es = "DS";

                    en = 'D';

                    miss = &env->spr[SPR_DMISS];

                    cmp = &env->spr[SPR_DCMP];

                }

                qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "

                         TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "

                         TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,

                         env->spr[SPR_HASH1], env->spr[SPR_HASH2],

                         env->error_code);

            }

#endif

            msr |= env->crf[0] << 28;

            msr |= env->error_code; /* key, D/I, S/L bits */

            /* Set way using a LRU mechanism */

            msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;

            break;

        case POWERPC_EXCP_74xx:

        tlb_miss_74xx:

#if defined (DEBUG_SOFTWARE_TLB)

            if (qemu_log_enabled()) {

                const char *es;

                target_ulong *miss, *cmp;

                int en;

                if (excp == POWERPC_EXCP_IFTLB) {

                    es = "I";

                    en = 'I';

                    miss = &env->spr[SPR_TLBMISS];

                    cmp = &env->spr[SPR_PTEHI];

                } else {

                    if (excp == POWERPC_EXCP_DLTLB)

                        es = "DL";

                    else

                        es = "DS";

                    en = 'D';

                    miss = &env->spr[SPR_TLBMISS];

                    cmp = &env->spr[SPR_PTEHI];

                }

                qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "

                         TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,

                         env->error_code);

            }

#endif

            msr |= env->error_code; /* key bit */

            break;

        default:

            cpu_abort(env, "Invalid data store TLB miss exception\n");

            break;

        }

        goto store_next;

    case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */

        /* XXX: TODO */

        cpu_abort(env, "Floating point assist exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */

        /* XXX: TODO */

        cpu_abort(env, "DABR exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */

        /* XXX: TODO */

        cpu_abort(env, "IABR exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_SMI:       /* System management interrupt              */

        /* XXX: TODO */

        cpu_abort(env, "SMI exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */

        /* XXX: TODO */

        cpu_abort(env, "Thermal management exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        /* XXX: TODO */

        cpu_abort(env,

                  "Performance counter exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */

        /* XXX: TODO */

        cpu_abort(env, "VPU assist exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_SOFTP:     /* Soft patch exception                     */

        /* XXX: TODO */

        cpu_abort(env,

                  "970 soft-patch exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */

        /* XXX: TODO */

        cpu_abort(env,

                  "970 maintenance exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */

        /* XXX: TODO */

        cpu_abort(env, "Maskable external exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */

        /* XXX: TODO */

        cpu_abort(env, "Non maskable external exception "

                  "is not implemented yet !\n");

        goto store_next;

    default:

    excp_invalid:

        cpu_abort(env, "Invalid PowerPC exception %d. Aborting\n", excp);

        break;

    store_current:

        /* save current instruction location */

        env->spr[srr0] = env->nip - 4;

        break;

    store_next:

        /* save next instruction location */

        env->spr[srr0] = env->nip;

        break;

    }

    /* Save MSR */

    env->spr[srr1] = msr;

    /* If any alternate SRR register are defined, duplicate saved values */

    if (asrr0 != -1)

        env->spr[asrr0] = env->spr[srr0];

    if (asrr1 != -1)

        env->spr[asrr1] = env->spr[srr1];

    /* If we disactivated any translation, flush TLBs */

    if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))

        tlb_flush(env, 1);

    if (msr_ile) {

        new_msr |= (target_ulong)1 << MSR_LE;

    }

    /* Jump to handler */

    vector = env->excp_vectors[excp];

    if (vector == (target_ulong)-1ULL) {

        cpu_abort(env, "Raised an exception without defined vector %d\n",

                  excp);

    }

    vector |= env->excp_prefix;

#if defined(TARGET_PPC64)

    if (excp_model == POWERPC_EXCP_BOOKE) {

        if (!msr_icm) {

            vector = (uint32_t)vector;

        } else {

            new_msr |= (target_ulong)1 << MSR_CM;

        }

    } else {

        if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {

            vector = (uint32_t)vector;

        } else {

            new_msr |= (target_ulong)1 << MSR_SF;

        }

    }

#endif

    /* XXX: we don't use hreg_store_msr here as already have treated

     *      any special case that could occur. Just store MSR and update hflags

     */

    env->msr = new_msr & env->msr_mask;

    hreg_compute_hflags(env);

    env->nip = vector;

    /* Reset exception state */

    env->exception_index = POWERPC_EXCP_NONE;

    env->error_code = 0;

    if ((env->mmu_model == POWERPC_MMU_BOOKE) ||

        (env->mmu_model == POWERPC_MMU_BOOKE206)) {

        /* XXX: The BookE changes address space when switching modes,

                we should probably implement that as different MMU indexes,

                but for the moment we do it the slow way and flush all.  */

        tlb_flush(env, 1);

    }

}


static int mxf_read_cryptographic_context(MXFCryptoContext *cryptocontext, ByteIOContext *pb, int tag, int size, UID uid)

{

    if (size != 16)

        return -1;

    if (IS_KLV_KEY(uid, mxf_crypto_source_container_ul))

        get_buffer(pb, cryptocontext->source_container_ul, 16);

    return 0;

}


static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr)

{

    VhostUserMsg msg = { 0 };

    int err;

    assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);

    /* If guest supports GUEST_ANNOUNCE do nothing */

    if (virtio_has_feature(dev->acked_features, VIRTIO_NET_F_GUEST_ANNOUNCE)) {

        return 0;

    }

    /* if backend supports VHOST_USER_PROTOCOL_F_RARP ask it to send the RARP */

    if (virtio_has_feature(dev->protocol_features,

                           VHOST_USER_PROTOCOL_F_RARP)) {

        msg.request = VHOST_USER_SEND_RARP;

        msg.flags = VHOST_USER_VERSION;

        memcpy((char *)&msg.u64, mac_addr, 6);

        msg.size = sizeof(m.u64);

        err = vhost_user_write(dev, &msg, NULL, 0);

        return err;

    }

    return -1;

}


static void assert_file_overwrite(const char *filename)

{

    if (file_overwrite && no_file_overwrite) {

        fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n");

        exit_program(1);

    }

    if (!file_overwrite &&

        (strchr(filename, ':') == NULL || filename[1] == ':' ||

         av_strstart(filename, "file:", NULL))) {

        if (avio_check(filename, 0) == 0) {

            if (stdin_interaction && !no_file_overwrite) {

                fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);

                fflush(stderr);

                term_exit();

                signal(SIGINT, SIG_DFL);

                if (!read_yesno()) {

                    av_log(NULL, AV_LOG_FATAL, "Not overwriting - exiting\n");

                    exit_program(1);

                }

                term_init();

            }

            else {

                av_log(NULL, AV_LOG_FATAL, "File '%s' already exists. Exiting.\n", filename);

                exit_program(1);

            }

        }

    }

}


void do_tlbwr (void)

{

    int r = cpu_mips_get_random(env);

    invalidate_tlb(r, 1);

    fill_tlb(r);

}


static void raw_close(BlockDriverState *bs)

{

}


static void gen_interrupt(DisasContext *s, int intno,

                          target_ulong cur_eip, target_ulong next_eip)

{

    gen_update_cc_op(s);

    gen_jmp_im(cur_eip);

    gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),

                               tcg_const_i32(next_eip - cur_eip));

    s->is_jmp = DISAS_TB_JUMP;

}


static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int len)

{

    DPRINTF("Warning: attempted read from physical address "

            "0x" TARGET_FMT_plx " in xen platform mmio space\n", addr);

    return 0;

}


int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,

                              int mmu_idx, int is_softmmu)

{

    target_ulong virt_addr, vaddr;

    target_phys_addr_t paddr;

    int error_code = 0, prot, ret = 0, access_index;

    error_code = get_physical_address(env, &paddr, &prot, &access_index,

                                      address, rw, mmu_idx);

    if (error_code == 0) {

        virt_addr = address & TARGET_PAGE_MASK;

        vaddr = virt_addr + ((address & TARGET_PAGE_MASK) &

                             (TARGET_PAGE_SIZE - 1));

#ifdef DEBUG_MMU

        printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64

               "\n", address, paddr, vaddr);

#endif

        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);

        return ret;

    }

    // XXX

    return 1;

}


static av_cold int oggvorbis_init_encoder(vorbis_info *vi,

                                          AVCodecContext *avctx)

{

    OggVorbisContext *s = avctx->priv_data;

    double cfreq;

    int ret;

    if (avctx->flags & CODEC_FLAG_QSCALE) {

        /* variable bitrate

         * NOTE: we use the oggenc range of -1 to 10 for global_quality for

         *       user convenience, but libvorbis uses -0.1 to 1.0

         */

        float q = avctx->global_quality / (float)FF_QP2LAMBDA;

        if ((ret = vorbis_encode_setup_vbr(vi, avctx->channels,

                                           avctx->sample_rate,

                                           q / 10.0)))

            goto error;

    } else {

        int minrate = avctx->rc_min_rate > 0 ? avctx->rc_min_rate : -1;

        int maxrate = avctx->rc_min_rate > 0 ? avctx->rc_max_rate : -1;

        /* average bitrate */

        if ((ret = vorbis_encode_setup_managed(vi, avctx->channels,

                                               avctx->sample_rate, minrate,

                                               avctx->bit_rate, maxrate)))

            goto error;

        /* variable bitrate by estimate, disable slow rate management */

        if (minrate == -1 && maxrate == -1)

            if ((ret = vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET, NULL)))

                goto error;

    }

    /* cutoff frequency */

    if (avctx->cutoff > 0) {

        cfreq = avctx->cutoff / 1000.0;

        if ((ret = vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq)))

            goto error;

    }

    /* impulse block bias */

    if (s->iblock) {

        if ((ret = vorbis_encode_ctl(vi, OV_ECTL_IBLOCK_SET, &s->iblock)))

            goto error;

    }

    if ((ret = vorbis_encode_setup_init(vi)))

        goto error;

    return 0;

error:

    return vorbis_error_to_averror(ret);

}


DriveInfo *drive_init(QemuOpts *opts, void *opaque,

                      int *fatal_error)

{

    const char *buf;

    const char *file = NULL;

    char devname[128];

    const char *serial;

    const char *mediastr = "";

    BlockInterfaceType type;

    enum { MEDIA_DISK, MEDIA_CDROM } media;

    int bus_id, unit_id;

    int cyls, heads, secs, translation;

    BlockDriver *drv = NULL;

    QEMUMachine *machine = opaque;

    int max_devs;

    int index;

    int cache;

    int aio = 0;

    int bdrv_flags, onerror;

    const char *devaddr;

    DriveInfo *dinfo;

    int snapshot = 0;

    *fatal_error = 1;

    translation = BIOS_ATA_TRANSLATION_AUTO;

    cache = 1;

    if (machine && machine->use_scsi) {

        type = IF_SCSI;

        max_devs = MAX_SCSI_DEVS;

        pstrcpy(devname, sizeof(devname), "scsi");

    } else {

        type = IF_IDE;

        max_devs = MAX_IDE_DEVS;

        pstrcpy(devname, sizeof(devname), "ide");

    }

    media = MEDIA_DISK;

    /* extract parameters */

    bus_id  = qemu_opt_get_number(opts, "bus", 0);

    unit_id = qemu_opt_get_number(opts, "unit", -1);

    index   = qemu_opt_get_number(opts, "index", -1);

    cyls  = qemu_opt_get_number(opts, "cyls", 0);

    heads = qemu_opt_get_number(opts, "heads", 0);

    secs  = qemu_opt_get_number(opts, "secs", 0);

    snapshot = qemu_opt_get_bool(opts, "snapshot", 0);

    file = qemu_opt_get(opts, "file");

    serial = qemu_opt_get(opts, "serial");

    if ((buf = qemu_opt_get(opts, "if")) != NULL) {

        pstrcpy(devname, sizeof(devname), buf);

        if (!strcmp(buf, "ide")) {

	    type = IF_IDE;

            max_devs = MAX_IDE_DEVS;

        } else if (!strcmp(buf, "scsi")) {

	    type = IF_SCSI;

            max_devs = MAX_SCSI_DEVS;

        } else if (!strcmp(buf, "floppy")) {

	    type = IF_FLOPPY;

            max_devs = 0;

        } else if (!strcmp(buf, "pflash")) {

	    type = IF_PFLASH;

            max_devs = 0;

	} else if (!strcmp(buf, "mtd")) {

	    type = IF_MTD;

            max_devs = 0;

	} else if (!strcmp(buf, "sd")) {

	    type = IF_SD;

            max_devs = 0;

        } else if (!strcmp(buf, "virtio")) {

            type = IF_VIRTIO;

            max_devs = 0;

	} else if (!strcmp(buf, "xen")) {

	    type = IF_XEN;

            max_devs = 0;

	} else if (!strcmp(buf, "none")) {

	    type = IF_NONE;

            max_devs = 0;

	} else {

            fprintf(stderr, "qemu: unsupported bus type '%s'\n", buf);

            return NULL;

	}

    }

    if (cyls || heads || secs) {

        if (cyls < 1 || cyls > 16383) {

            fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", buf);

	    return NULL;

	}

        if (heads < 1 || heads > 16) {

            fprintf(stderr, "qemu: '%s' invalid physical heads number\n", buf);

	    return NULL;

	}

        if (secs < 1 || secs > 63) {

            fprintf(stderr, "qemu: '%s' invalid physical secs number\n", buf);

	    return NULL;

	}

    }

    if ((buf = qemu_opt_get(opts, "trans")) != NULL) {

        if (!cyls) {

            fprintf(stderr,

                    "qemu: '%s' trans must be used with cyls,heads and secs\n",

                    buf);

            return NULL;

        }

        if (!strcmp(buf, "none"))

            translation = BIOS_ATA_TRANSLATION_NONE;

        else if (!strcmp(buf, "lba"))

            translation = BIOS_ATA_TRANSLATION_LBA;

        else if (!strcmp(buf, "auto"))

            translation = BIOS_ATA_TRANSLATION_AUTO;

	else {

            fprintf(stderr, "qemu: '%s' invalid translation type\n", buf);

	    return NULL;

	}

    }

    if ((buf = qemu_opt_get(opts, "media")) != NULL) {

        if (!strcmp(buf, "disk")) {

	    media = MEDIA_DISK;

	} else if (!strcmp(buf, "cdrom")) {

            if (cyls || secs || heads) {

                fprintf(stderr,

                        "qemu: '%s' invalid physical CHS format\n", buf);

	        return NULL;

            }

	    media = MEDIA_CDROM;

	} else {

	    fprintf(stderr, "qemu: '%s' invalid media\n", buf);

	    return NULL;

	}

    }

    if ((buf = qemu_opt_get(opts, "cache")) != NULL) {

        if (!strcmp(buf, "off") || !strcmp(buf, "none"))

            cache = 0;

        else if (!strcmp(buf, "writethrough"))

            cache = 1;

        else if (!strcmp(buf, "writeback"))

            cache = 2;

        else {

           fprintf(stderr, "qemu: invalid cache option\n");

           return NULL;

        }

    }

#ifdef CONFIG_LINUX_AIO

    if ((buf = qemu_opt_get(opts, "aio")) != NULL) {

        if (!strcmp(buf, "threads"))

            aio = 0;

        else if (!strcmp(buf, "native"))

            aio = 1;

        else {

           fprintf(stderr, "qemu: invalid aio option\n");

           return NULL;

        }

    }

#endif

    if ((buf = qemu_opt_get(opts, "format")) != NULL) {

       if (strcmp(buf, "?") == 0) {

            fprintf(stderr, "qemu: Supported formats:");

            bdrv_iterate_format(bdrv_format_print, NULL);

            fprintf(stderr, "\n");

	    return NULL;

        }

        drv = bdrv_find_format(buf);

        if (!drv) {

            fprintf(stderr, "qemu: '%s' invalid format\n", buf);

            return NULL;

        }

    }

    onerror = BLOCK_ERR_STOP_ENOSPC;

    if ((buf = qemu_opt_get(opts, "werror")) != NULL) {

        if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {

            fprintf(stderr, "werror is no supported by this format\n");

            return NULL;

        }

        if (!strcmp(buf, "ignore"))

            onerror = BLOCK_ERR_IGNORE;

        else if (!strcmp(buf, "enospc"))

            onerror = BLOCK_ERR_STOP_ENOSPC;

        else if (!strcmp(buf, "stop"))

            onerror = BLOCK_ERR_STOP_ANY;

        else if (!strcmp(buf, "report"))

            onerror = BLOCK_ERR_REPORT;

        else {

            fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);

            return NULL;

        }

    }

    if ((devaddr = qemu_opt_get(opts, "addr")) != NULL) {

        if (type != IF_VIRTIO) {

            fprintf(stderr, "addr is not supported\n");

            return NULL;

        }

    }

    /* compute bus and unit according index */

    if (index != -1) {

        if (bus_id != 0 || unit_id != -1) {

            fprintf(stderr,

                    "qemu: index cannot be used with bus and unit\n");

            return NULL;

        }

        if (max_devs == 0)

        {

            unit_id = index;

            bus_id = 0;

        } else {

            unit_id = index % max_devs;

            bus_id = index / max_devs;

        }

    }

    /* if user doesn't specify a unit_id,

     * try to find the first free

     */

    if (unit_id == -1) {

       unit_id = 0;

       while (drive_get(type, bus_id, unit_id) != NULL) {

           unit_id++;

           if (max_devs && unit_id >= max_devs) {

               unit_id -= max_devs;

               bus_id++;

           }

       }

    }

    /* check unit id */

    if (max_devs && unit_id >= max_devs) {

        fprintf(stderr, "qemu: unit %d too big (max is %d)\n",

                unit_id, max_devs - 1);

        return NULL;

    }

    /*

     * ignore multiple definitions

     */

    if (drive_get(type, bus_id, unit_id) != NULL) {

        *fatal_error = 0;

        return NULL;

    }

    /* init */

    dinfo = qemu_mallocz(sizeof(*dinfo));

    if ((buf = qemu_opts_id(opts)) != NULL) {

        dinfo->id = qemu_strdup(buf);

    } else {

        /* no id supplied -> create one */

        dinfo->id = qemu_mallocz(32);

        if (type == IF_IDE || type == IF_SCSI)

            mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";

        if (max_devs)

            snprintf(dinfo->id, 32, "%s%i%s%i",

                     devname, bus_id, mediastr, unit_id);

        else

            snprintf(dinfo->id, 32, "%s%s%i",

                     devname, mediastr, unit_id);

    }

    dinfo->bdrv = bdrv_new(dinfo->id);

    dinfo->devaddr = devaddr;

    dinfo->type = type;

    dinfo->bus = bus_id;

    dinfo->unit = unit_id;

    dinfo->onerror = onerror;

    dinfo->opts = opts;

    if (serial)

        strncpy(dinfo->serial, serial, sizeof(serial));

    TAILQ_INSERT_TAIL(&drives, dinfo, next);

    switch(type) {

    case IF_IDE:

    case IF_SCSI:

    case IF_XEN:

        switch(media) {

	case MEDIA_DISK:

            if (cyls != 0) {

                bdrv_set_geometry_hint(dinfo->bdrv, cyls, heads, secs);

                bdrv_set_translation_hint(dinfo->bdrv, translation);

            }

	    break;

	case MEDIA_CDROM:

            bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);

	    break;

	}

        break;

    case IF_SD:

        /* FIXME: This isn't really a floppy, but it's a reasonable

           approximation.  */

    case IF_FLOPPY:

        bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_FLOPPY);

        break;

    case IF_PFLASH:

    case IF_MTD:

    case IF_NONE:

        break;

    case IF_VIRTIO:

        /* add virtio block device */

        opts = qemu_opts_create(&qemu_device_opts, NULL, 0);

        qemu_opt_set(opts, "driver", "virtio-blk-pci");

        qemu_opt_set(opts, "drive", dinfo->id);

        if (devaddr)

            qemu_opt_set(opts, "addr", devaddr);

        break;

    case IF_COUNT:

        abort();

    }

    if (!file) {

        *fatal_error = 0;

        return NULL;

    }

    bdrv_flags = 0;

    if (snapshot) {

        bdrv_flags |= BDRV_O_SNAPSHOT;

        cache = 2; /* always use write-back with snapshot */

    }

    if (cache == 0) /* no caching */

        bdrv_flags |= BDRV_O_NOCACHE;

    else if (cache == 2) /* write-back */

        bdrv_flags |= BDRV_O_CACHE_WB;

    if (aio == 1) {

        bdrv_flags |= BDRV_O_NATIVE_AIO;

    } else {

        bdrv_flags &= ~BDRV_O_NATIVE_AIO;

    }

    if (bdrv_open2(dinfo->bdrv, file, bdrv_flags, drv) < 0) {

        fprintf(stderr, "qemu: could not open disk image %s\n",

                        file);

        return NULL;

    }

    if (bdrv_key_required(dinfo->bdrv))

        autostart = 0;

    *fatal_error = 0;

    return dinfo;

}


static int mpegts_write_header(AVFormatContext *s)

{

    MpegTSWrite *ts = s->priv_data;

    MpegTSWriteStream *ts_st;

    MpegTSService *service;

    AVStream *st, *pcr_st = NULL;

    AVDictionaryEntry *title, *provider;

    int i, j;

    const char *service_name;

    const char *provider_name;

    int *pids;

    int ret;

    if (s->max_delay < 0) /* Not set by the caller */

        s->max_delay = 0;

    // round up to a whole number of TS packets

    ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14;

    ts->tsid = ts->transport_stream_id;

    ts->onid = ts->original_network_id;

    /* allocate a single DVB service */

    title = av_dict_get(s->metadata, "service_name", NULL, 0);

    if (!title)

        title = av_dict_get(s->metadata, "title", NULL, 0);

    service_name = title ? title->value : DEFAULT_SERVICE_NAME;

    provider = av_dict_get(s->metadata, "service_provider", NULL, 0);

    provider_name = provider ? provider->value : DEFAULT_PROVIDER_NAME;

    service = mpegts_add_service(ts, ts->service_id, provider_name, service_name);

    service->pmt.write_packet = section_write_packet;

    service->pmt.opaque = s;

    service->pmt.cc = 15;

    ts->pat.pid = PAT_PID;

    ts->pat.cc = 15; // Initialize at 15 so that it wraps and be equal to 0 for the first packet we write

    ts->pat.write_packet = section_write_packet;

    ts->pat.opaque = s;

    ts->sdt.pid = SDT_PID;

    ts->sdt.cc = 15;

    ts->sdt.write_packet = section_write_packet;

    ts->sdt.opaque = s;

    pids = av_malloc(s->nb_streams * sizeof(*pids));

    if (!pids)

        return AVERROR(ENOMEM);

    /* assign pids to each stream */

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

        st = s->streams[i];

        avpriv_set_pts_info(st, 33, 1, 90000);

        ts_st = av_mallocz(sizeof(MpegTSWriteStream));

        if (!ts_st) {

            ret = AVERROR(ENOMEM);

            goto fail;

        }

        st->priv_data = ts_st;

        ts_st->payload = av_mallocz(ts->pes_payload_size);

        if (!ts_st->payload) {

            ret = AVERROR(ENOMEM);

            goto fail;

        }

        ts_st->service = service;

        /* MPEG pid values < 16 are reserved. Applications which set st->id in

         * this range are assigned a calculated pid. */

        if (st->id < 16) {

            ts_st->pid = ts->start_pid + i;

        } else if (st->id < 0x1FFF) {

            ts_st->pid = st->id;

        } else {

            av_log(s, AV_LOG_ERROR, "Invalid stream id %d, must be less than 8191\n", st->id);

            ret = AVERROR(EINVAL);

            goto fail;

        }

        if (ts_st->pid == service->pmt.pid) {

            av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);

            ret = AVERROR(EINVAL);

            goto fail;

        }

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

            if (pids[j] == ts_st->pid) {

                av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);

                ret = AVERROR(EINVAL);

                goto fail;

            }

        pids[i] = ts_st->pid;

        ts_st->payload_pts = AV_NOPTS_VALUE;

        ts_st->payload_dts = AV_NOPTS_VALUE;

        ts_st->first_pts_check = 1;

        ts_st->cc = 15;

        /* update PCR pid by using the first video stream */

        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&

            service->pcr_pid == 0x1fff) {

            service->pcr_pid = ts_st->pid;

            pcr_st = st;

        }

        if (st->codec->codec_id == AV_CODEC_ID_AAC &&

            st->codec->extradata_size > 0)

        {

            AVStream *ast;

            ts_st->amux = avformat_alloc_context();

            if (!ts_st->amux) {

                ret = AVERROR(ENOMEM);

                goto fail;

            }

            ts_st->amux->oformat = av_guess_format((ts->flags & MPEGTS_FLAG_AAC_LATM) ? "latm" : "adts", NULL, NULL);

            if (!ts_st->amux->oformat) {

                ret = AVERROR(EINVAL);

                goto fail;

            }

            ast = avformat_new_stream(ts_st->amux, NULL);

            ret = avcodec_copy_context(ast->codec, st->codec);

            if (ret != 0)

                goto fail;

            ret = avformat_write_header(ts_st->amux, NULL);

            if (ret < 0)

                goto fail;

        }

    }

    av_free(pids);

    /* if no video stream, use the first stream as PCR */

    if (service->pcr_pid == 0x1fff && s->nb_streams > 0) {

        pcr_st = s->streams[0];

        ts_st = pcr_st->priv_data;

        service->pcr_pid = ts_st->pid;

    }

    if (ts->mux_rate > 1) {

        service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) /

            (TS_PACKET_SIZE * 8 * 1000);

        ts->sdt_packet_period      = (ts->mux_rate * SDT_RETRANS_TIME) /

            (TS_PACKET_SIZE * 8 * 1000);

        ts->pat_packet_period      = (ts->mux_rate * PAT_RETRANS_TIME) /

            (TS_PACKET_SIZE * 8 * 1000);

        ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE);

    } else {

        /* Arbitrary values, PAT/PMT could be written on key frames */

        ts->sdt_packet_period = 200;

        ts->pat_packet_period = 40;

        if (pcr_st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {

            if (!pcr_st->codec->frame_size) {

                av_log(s, AV_LOG_WARNING, "frame size not set\n");

                service->pcr_packet_period =

                    pcr_st->codec->sample_rate/(10*512);

            } else {

                service->pcr_packet_period =

                    pcr_st->codec->sample_rate/(10*pcr_st->codec->frame_size);

            }

        } else {

            // max delta PCR 0.1s

            service->pcr_packet_period =

                pcr_st->codec->time_base.den/(10*pcr_st->codec->time_base.num);

        }

    }

    // output a PCR as soon as possible

    service->pcr_packet_count = service->pcr_packet_period;

    ts->pat_packet_count = ts->pat_packet_period-1;

    ts->sdt_packet_count = ts->sdt_packet_period-1;

    if (ts->mux_rate == 1)

        av_log(s, AV_LOG_VERBOSE, "muxrate VBR, ");

    else

        av_log(s, AV_LOG_VERBOSE, "muxrate %d, ", ts->mux_rate);

    av_log(s, AV_LOG_VERBOSE, "pcr every %d pkts, "

           "sdt every %d, pat/pmt every %d pkts\n",

           service->pcr_packet_period,

           ts->sdt_packet_period, ts->pat_packet_period);

    avio_flush(s->pb);

    return 0;

 fail:

    av_free(pids);

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

        MpegTSWriteStream *ts_st;

        st = s->streams[i];

        ts_st = st->priv_data;

        if (ts_st) {

            av_freep(&ts_st->payload);

            if (ts_st->amux) {

                avformat_free_context(ts_st->amux);

                ts_st->amux = NULL;

            }

        }

        av_freep(&st->priv_data);

    }

    return ret;

}


static int htab_save_setup(QEMUFile *f, void *opaque)

{

    sPAPRMachineState *spapr = opaque;

    /* "Iteration" header */

    qemu_put_be32(f, spapr->htab_shift);

    if (spapr->htab) {

        spapr->htab_save_index = 0;

        spapr->htab_first_pass = true;

    } else {

        assert(kvm_enabled());

        spapr->htab_fd = kvmppc_get_htab_fd(false);

        spapr->htab_fd_stale = false;

        if (spapr->htab_fd < 0) {

            fprintf(stderr, "Unable to open fd for reading hash table from KVM: %s\n",

                    strerror(errno));

            return -1;

        }

    }

    return 0;

}


int pci_drive_hot_add(Monitor *mon, const QDict *qdict, DriveInfo *dinfo)

{

    int dom, pci_bus;

    unsigned slot;

    PCIDevice *dev;

    const char *pci_addr = qdict_get_str(qdict, "pci_addr");

    switch (dinfo->type) {

    case IF_SCSI:

        if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) {

            goto err;

        }

        dev = pci_find_device(pci_find_root_bus(dom), pci_bus,

                              PCI_DEVFN(slot, 0));

        if (!dev) {

            monitor_printf(mon, "no pci device with address %s\n", pci_addr);

            goto err;

        }

        if (scsi_hot_add(mon, &dev->qdev, dinfo, 1) != 0) {

            goto err;

        }

        break;

    default:

        monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type);

        goto err;

    }

    return 0;

err:

    return -1;

}


static int read_ir(AVFilterLink *link, AVFrame *frame)

{

    AVFilterContext *ctx = link->dst;

    AudioFIRContext *s = ctx->priv;

    int nb_taps, max_nb_taps;

    av_audio_fifo_write(s->fifo[1], (void **)frame->extended_data,

                        frame->nb_samples);

    av_frame_free(&frame);

    nb_taps = av_audio_fifo_size(s->fifo[1]);

    max_nb_taps = MAX_IR_DURATION * ctx->outputs[0]->sample_rate;

    if (nb_taps > max_nb_taps) {

        av_log(ctx, AV_LOG_ERROR, "Too big number of coefficients: %d > %d.\n", nb_taps, max_nb_taps);

        return AVERROR(EINVAL);

    }

    return 0;

}


void cpu_loop(CPUSH4State *env)

{

    CPUState *cs = CPU(sh_env_get_cpu(env));

    int trapnr, ret;

    target_siginfo_t info;

    while (1) {

        cpu_exec_start(cs);

        trapnr = cpu_sh4_exec(cs);

        cpu_exec_end(cs);

        switch (trapnr) {

        case 0x160:

            env->pc += 2;

            ret = do_syscall(env,

                             env->gregs[3],

                             env->gregs[4],

                             env->gregs[5],

                             env->gregs[6],

                             env->gregs[7],

                             env->gregs[0],

                             env->gregs[1],

                             0, 0);

            env->gregs[0] = ret;

            break;

        case EXCP_INTERRUPT:

            /* just indicate that signals should be handled asap */

            break;

        case EXCP_DEBUG:

            {

                int sig;

                sig = gdb_handlesig(cs, TARGET_SIGTRAP);

                if (sig)

                  {

                    info.si_signo = sig;

                    info.si_errno = 0;

                    info.si_code = TARGET_TRAP_BRKPT;

                    queue_signal(env, info.si_signo, &info);

                  }

            }

            break;

	case 0xa0:

	case 0xc0:

            info.si_signo = TARGET_SIGSEGV;

            info.si_errno = 0;

            info.si_code = TARGET_SEGV_MAPERR;

            info._sifields._sigfault._addr = env->tea;

            queue_signal(env, info.si_signo, &info);

	    break;

        default:

            printf ("Unhandled trap: 0x%x\n", trapnr);

            cpu_dump_state(cs, stderr, fprintf, 0);

            exit(EXIT_FAILURE);

        }

        process_pending_signals (env);

    }

}


static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)

{

    gen_helper_fcmps(cpu_env, r_rs1, r_rs2);

}


static void set_sigp_status(SigpInfo *si, uint64_t status)

{

    *si->status_reg &= 0xffffffff00000000ULL;

    *si->status_reg |= status;

    si->cc = SIGP_CC_STATUS_STORED;

}


static VirtIOSCSIReq *virtio_scsi_pop_req(VirtIOSCSI *s, VirtQueue *vq)

{

    VirtIOSCSIReq *req;

    req = g_malloc(sizeof(*req));

    if (!virtqueue_pop(vq, &req->elem)) {

        g_free(req);

        return NULL;

    }

    virtio_scsi_parse_req(s, vq, req);

    return req;

}


void OPPROTO op_divb_AL_T0(void)

{

    unsigned int num, den, q, r;

    num = (EAX & 0xffff);

    den = (T0 & 0xff);

    if (den == 0) {

        raise_exception(EXCP00_DIVZ);

    }

    q = (num / den) & 0xff;

    r = (num % den) & 0xff;

    EAX = (EAX & ~0xffff) | (r << 8) | q;

}


static inline void gen_op_eval_bgu(TCGv dst, TCGv_i32 src)

{

    gen_mov_reg_Z(cpu_tmp0, src);

    gen_mov_reg_C(dst, src);

    tcg_gen_or_tl(dst, dst, cpu_tmp0);

    tcg_gen_xori_tl(dst, dst, 0x1);

}


static void test_pxe_virtio_pci(void)

{

    test_pxe_one("-device virtio-net-pci,netdev=" NETNAME, false);

}


int ff_scale_eval_dimensions(void *log_ctx,

    const char *w_expr, const char *h_expr,

    AVFilterLink *inlink, AVFilterLink *outlink,

    int *ret_w, int *ret_h)

{

    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);

    const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(outlink->format);

    const char *expr;

    int w, h;

    int factor_w, factor_h;

    int eval_w, eval_h;

    int ret;

    double var_values[VARS_NB], res;

    var_values[VAR_PI]    = M_PI;

    var_values[VAR_PHI]   = M_PHI;

    var_values[VAR_E]     = M_E;

    var_values[VAR_IN_W]  = var_values[VAR_IW] = inlink->w;

    var_values[VAR_IN_H]  = var_values[VAR_IH] = inlink->h;

    var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;

    var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;

    var_values[VAR_A]     = (double) inlink->w / inlink->h;

    var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ?

        (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;

    var_values[VAR_DAR]   = var_values[VAR_A] * var_values[VAR_SAR];

    var_values[VAR_HSUB]  = 1 << desc->log2_chroma_w;

    var_values[VAR_VSUB]  = 1 << desc->log2_chroma_h;

    var_values[VAR_OHSUB] = 1 << out_desc->log2_chroma_w;

    var_values[VAR_OVSUB] = 1 << out_desc->log2_chroma_h;

    /* evaluate width and height */

    av_expr_parse_and_eval(&res, (expr = w_expr),

                           var_names, var_values,

                           NULL, NULL, NULL, NULL, NULL, 0, log_ctx);

    eval_w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;

    if ((ret = av_expr_parse_and_eval(&res, (expr = h_expr),

                                      var_names, var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, log_ctx)) < 0)

        goto fail;

    eval_h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res;

    /* evaluate again the width, as it may depend on the output height */

    if ((ret = av_expr_parse_and_eval(&res, (expr = w_expr),

                                      var_names, var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, log_ctx)) < 0)

        goto fail;

    eval_w = res;

    w = eval_w;

    h = eval_h;

    /* Check if it is requested that the result has to be divisible by a some

     * factor (w or h = -n with n being the factor). */

    factor_w = 1;

    factor_h = 1;

    if (w < -1) {

        factor_w = -w;

    }

    if (h < -1) {

        factor_h = -h;

    }

    if (w < 0 && h < 0)

        eval_w = eval_h = 0;

    if (!(w = eval_w))

        w = inlink->w;

    if (!(h = eval_h))

        h = inlink->h;

    /* Make sure that the result is divisible by the factor we determined

     * earlier. If no factor was set, it is nothing will happen as the default

     * factor is 1 */

    if (w < 0)

        w = av_rescale(h, inlink->w, inlink->h * factor_w) * factor_w;

    if (h < 0)

        h = av_rescale(w, inlink->h, inlink->w * factor_h) * factor_h;

    *ret_w = w;

    *ret_h = h;

    return 0;

fail:

    av_log(log_ctx, AV_LOG_ERROR,

           "Error when evaluating the expression '%s'.\n"

           "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n",

           expr, w_expr, h_expr);

    return ret;

}


static int parse_strk(AVFormatContext *s,

                      FourxmDemuxContext *fourxm, uint8_t *buf, int size)

{

    AVStream *st;

    int track;

    /* check that there is enough data */

    if (size != strk_SIZE)

        return AVERROR_INVALIDDATA;

    track = AV_RL32(buf + 8);

    if (track + 1 > fourxm->track_count) {

        if (av_reallocp_array(&fourxm->tracks, track + 1, sizeof(AudioTrack)))

            return AVERROR(ENOMEM);

        memset(&fourxm->tracks[fourxm->track_count], 0,

               sizeof(AudioTrack) * (track + 1 - fourxm->track_count));

        fourxm->track_count = track + 1;

    }

    fourxm->tracks[track].adpcm       = AV_RL32(buf + 12);

    fourxm->tracks[track].channels    = AV_RL32(buf + 36);

    fourxm->tracks[track].sample_rate = AV_RL32(buf + 40);

    fourxm->tracks[track].bits        = AV_RL32(buf + 44);

    fourxm->tracks[track].audio_pts   = 0;

    if (fourxm->tracks[track].channels    <= 0 ||

        fourxm->tracks[track].sample_rate <= 0 ||

        fourxm->tracks[track].bits        < 0) {

        av_log(s, AV_LOG_ERROR, "audio header invalid\n");

        return AVERROR_INVALIDDATA;

    }

    /* allocate a new AVStream */

    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    st->id = track;

    avpriv_set_pts_info(st, 60, 1, fourxm->tracks[track].sample_rate);

    fourxm->tracks[track].stream_index = st->index;

    st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;

    st->codec->codec_tag             = 0;

    st->codec->channels              = fourxm->tracks[track].channels;

    st->codec->sample_rate           = fourxm->tracks[track].sample_rate;

    st->codec->bits_per_coded_sample = fourxm->tracks[track].bits;

    st->codec->bit_rate              = st->codec->channels *

                                       st->codec->sample_rate *

                                       st->codec->bits_per_coded_sample;

    st->codec->block_align           = st->codec->channels *

                                       st->codec->bits_per_coded_sample;

    if (fourxm->tracks[track].adpcm){

        st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM;

    } else if (st->codec->bits_per_coded_sample == 8) {

        st->codec->codec_id = AV_CODEC_ID_PCM_U8;

    } else

        st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;

    return 0;

}


static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,

                                       TCGv var)

{

    int val, rm, shift, shiftop;

    TCGv offset;

    if (!(insn & (1 << 25))) {

        /* immediate */

        val = insn & 0xfff;

        if (!(insn & (1 << 23)))

            val = -val;

        if (val != 0)

            tcg_gen_addi_i32(var, var, val);

    } else {

        /* shift/register */

        rm = (insn) & 0xf;

        shift = (insn >> 7) & 0x1f;

        shiftop = (insn >> 5) & 3;

        offset = load_reg(s, rm);

        gen_arm_shift_im(offset, shiftop, shift, 0);

        if (!(insn & (1 << 23)))

            tcg_gen_sub_i32(var, var, offset);

        else

            tcg_gen_add_i32(var, var, offset);

        dead_tmp(offset);

    }

}


static int count_contiguous_clusters(int nb_clusters, int cluster_size,

        uint64_t *l2_table, uint64_t stop_flags)

{

    int i;

    QCow2ClusterType first_cluster_type;

    uint64_t mask = stop_flags | L2E_OFFSET_MASK | QCOW_OFLAG_COMPRESSED;

    uint64_t first_entry = be64_to_cpu(l2_table[0]);

    uint64_t offset = first_entry & mask;

    if (!offset) {

        return 0;

    }

    /* must be allocated */

    first_cluster_type = qcow2_get_cluster_type(first_entry);

    assert(first_cluster_type == QCOW2_CLUSTER_NORMAL ||

           (first_cluster_type == QCOW2_CLUSTER_ZERO &&

            (first_entry & L2E_OFFSET_MASK) != 0));

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

        uint64_t l2_entry = be64_to_cpu(l2_table[i]) & mask;

        if (offset + (uint64_t) i * cluster_size != l2_entry) {

            break;

        }

    }

	return i;

}


static inline int name_to_handle(int dirfd, const char *name,

                                 struct file_handle *fh, int *mnt_id, int flags)

{

    return syscall(__NR_name_to_handle_at, dirfd, name, fh, mnt_id, flags);

}


static void generate_bootsect(uint32_t gpr[8], uint16_t segs[6], uint16_t ip)

{

    uint8_t bootsect[512], *p;

    int i;

    int hda;

    hda = drive_get_index(IF_IDE, 0, 0);

    if (hda == -1) {

	fprintf(stderr, "A disk image must be given for 'hda' when booting "

		"a Linux kernel\n(if you really don't want it, use /dev/zero)\n");

	exit(1);

    }

    memset(bootsect, 0, sizeof(bootsect));

    /* Copy the MSDOS partition table if possible */

    bdrv_read(drives_table[hda].bdrv, 0, bootsect, 1);

    /* Make sure we have a partition signature */

    bootsect[510] = 0x55;

    bootsect[511] = 0xaa;

    /* Actual code */

    p = bootsect;

    *p++ = 0xfa;		/* CLI */

    *p++ = 0xfc;		/* CLD */

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

	if (i == 1)		/* Skip CS */

	    continue;

	*p++ = 0xb8;		/* MOV AX,imm16 */

	*p++ = segs[i];

	*p++ = segs[i] >> 8;

	*p++ = 0x8e;		/* MOV <seg>,AX */

	*p++ = 0xc0 + (i << 3);

    }

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

	*p++ = 0x66;		/* 32-bit operand size */

	*p++ = 0xb8 + i;	/* MOV <reg>,imm32 */

	*p++ = gpr[i];

	*p++ = gpr[i] >> 8;

	*p++ = gpr[i] >> 16;

	*p++ = gpr[i] >> 24;

    }

    *p++ = 0xea;		/* JMP FAR */

    *p++ = ip;			/* IP */

    *p++ = ip >> 8;

    *p++ = segs[1];		/* CS */

    *p++ = segs[1] >> 8;

    bdrv_set_boot_sector(drives_table[hda].bdrv, bootsect, sizeof(bootsect));

}


static inline int blah (int32_t i)

{

    if (i > 0x43c07fff)

        return 32767;

    else if (i < 0x43bf8000)

        return -32768;

    else

        return i - 0x43c00000;

}