static void disas_thumb_insn(CPUState *env, DisasContext *s)

{

    uint32_t val, insn, op, rm, rn, rd, shift, cond;

    int32_t offset;

    int i;

    TCGv tmp;

    TCGv tmp2;

    TCGv addr;

    if (s->condexec_mask) {

        cond = s->condexec_cond;

        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */

          s->condlabel = gen_new_label();

          gen_test_cc(cond ^ 1, s->condlabel);

          s->condjmp = 1;

        }

    }

    insn = lduw_code(s->pc);

    s->pc += 2;

    switch (insn >> 12) {

    case 0: case 1:

        rd = insn & 7;

        op = (insn >> 11) & 3;

        if (op == 3) {

            /* add/subtract */

            rn = (insn >> 3) & 7;

            tmp = load_reg(s, rn);

            if (insn & (1 << 10)) {

                /* immediate */

                tmp2 = tcg_temp_new_i32();

                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);

            } else {

                /* reg */

                rm = (insn >> 6) & 7;

                tmp2 = load_reg(s, rm);

            }

            if (insn & (1 << 9)) {

                if (s->condexec_mask)

                    tcg_gen_sub_i32(tmp, tmp, tmp2);

                else

                    gen_helper_sub_cc(tmp, tmp, tmp2);

            } else {

                if (s->condexec_mask)

                    tcg_gen_add_i32(tmp, tmp, tmp2);

                else

                    gen_helper_add_cc(tmp, tmp, tmp2);

            }

            tcg_temp_free_i32(tmp2);

            store_reg(s, rd, tmp);

        } else {

            /* shift immediate */

            rm = (insn >> 3) & 7;

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

            tmp = load_reg(s, rm);

            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            store_reg(s, rd, tmp);

        }

        break;

    case 2: case 3:

        /* arithmetic large immediate */

        op = (insn >> 11) & 3;

        rd = (insn >> 8) & 0x7;

        if (op == 0) { /* mov */

            tmp = tcg_temp_new_i32();

            tcg_gen_movi_i32(tmp, insn & 0xff);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            store_reg(s, rd, tmp);

        } else {

            tmp = load_reg(s, rd);

            tmp2 = tcg_temp_new_i32();

            tcg_gen_movi_i32(tmp2, insn & 0xff);

            switch (op) {

            case 1: /* cmp */

                gen_helper_sub_cc(tmp, tmp, tmp2);

                tcg_temp_free_i32(tmp);

                tcg_temp_free_i32(tmp2);

                break;

            case 2: /* add */

                if (s->condexec_mask)

                    tcg_gen_add_i32(tmp, tmp, tmp2);

                else

                    gen_helper_add_cc(tmp, tmp, tmp2);

                tcg_temp_free_i32(tmp2);

                store_reg(s, rd, tmp);

                break;

            case 3: /* sub */

                if (s->condexec_mask)

                    tcg_gen_sub_i32(tmp, tmp, tmp2);

                else

                    gen_helper_sub_cc(tmp, tmp, tmp2);

                tcg_temp_free_i32(tmp2);

                store_reg(s, rd, tmp);

                break;

            }

        }

        break;

    case 4:

        if (insn & (1 << 11)) {

            rd = (insn >> 8) & 7;

            /* load pc-relative.  Bit 1 of PC is ignored.  */

            val = s->pc + 2 + ((insn & 0xff) * 4);

            val &= ~(uint32_t)2;

            addr = tcg_temp_new_i32();

            tcg_gen_movi_i32(addr, val);

            tmp = gen_ld32(addr, IS_USER(s));

            tcg_temp_free_i32(addr);

            store_reg(s, rd, tmp);

            break;

        }

        if (insn & (1 << 10)) {

            /* data processing extended or blx */

            rd = (insn & 7) | ((insn >> 4) & 8);

            rm = (insn >> 3) & 0xf;

            op = (insn >> 8) & 3;

            switch (op) {

            case 0: /* add */

                tmp = load_reg(s, rd);

                tmp2 = load_reg(s, rm);

                tcg_gen_add_i32(tmp, tmp, tmp2);

                tcg_temp_free_i32(tmp2);

                store_reg(s, rd, tmp);

                break;

            case 1: /* cmp */

                tmp = load_reg(s, rd);

                tmp2 = load_reg(s, rm);

                gen_helper_sub_cc(tmp, tmp, tmp2);

                tcg_temp_free_i32(tmp2);

                tcg_temp_free_i32(tmp);

                break;

            case 2: /* mov/cpy */

                tmp = load_reg(s, rm);

                store_reg(s, rd, tmp);

                break;

            case 3:/* branch [and link] exchange thumb register */

                tmp = load_reg(s, rm);

                if (insn & (1 << 7)) {

                    val = (uint32_t)s->pc | 1;

                    tmp2 = tcg_temp_new_i32();

                    tcg_gen_movi_i32(tmp2, val);

                    store_reg(s, 14, tmp2);

                }

                gen_bx(s, tmp);

                break;

            }

            break;

        }

        /* data processing register */

        rd = insn & 7;

        rm = (insn >> 3) & 7;

        op = (insn >> 6) & 0xf;

        if (op == 2 || op == 3 || op == 4 || op == 7) {

            /* the shift/rotate ops want the operands backwards */

            val = rm;

            rm = rd;

            rd = val;

            val = 1;

        } else {

            val = 0;

        }

        if (op == 9) { /* neg */

            tmp = tcg_temp_new_i32();

            tcg_gen_movi_i32(tmp, 0);

        } else if (op != 0xf) { /* mvn doesn't read its first operand */

            tmp = load_reg(s, rd);

        } else {

            TCGV_UNUSED(tmp);

        }

        tmp2 = load_reg(s, rm);

        switch (op) {

        case 0x0: /* and */

            tcg_gen_and_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0x1: /* eor */

            tcg_gen_xor_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0x2: /* lsl */

            if (s->condexec_mask) {

                gen_helper_shl(tmp2, tmp2, tmp);

            } else {

                gen_helper_shl_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x3: /* lsr */

            if (s->condexec_mask) {

                gen_helper_shr(tmp2, tmp2, tmp);

            } else {

                gen_helper_shr_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x4: /* asr */

            if (s->condexec_mask) {

                gen_helper_sar(tmp2, tmp2, tmp);

            } else {

                gen_helper_sar_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x5: /* adc */

            if (s->condexec_mask)

                gen_adc(tmp, tmp2);

            else

                gen_helper_adc_cc(tmp, tmp, tmp2);

            break;

        case 0x6: /* sbc */

            if (s->condexec_mask)

                gen_sub_carry(tmp, tmp, tmp2);

            else

                gen_helper_sbc_cc(tmp, tmp, tmp2);

            break;

        case 0x7: /* ror */

            if (s->condexec_mask) {

                tcg_gen_andi_i32(tmp, tmp, 0x1f);

                tcg_gen_rotr_i32(tmp2, tmp2, tmp);

            } else {

                gen_helper_ror_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x8: /* tst */

            tcg_gen_and_i32(tmp, tmp, tmp2);

            gen_logic_CC(tmp);

            rd = 16;

            break;

        case 0x9: /* neg */

            if (s->condexec_mask)

                tcg_gen_neg_i32(tmp, tmp2);

            else

                gen_helper_sub_cc(tmp, tmp, tmp2);

            break;

        case 0xa: /* cmp */

            gen_helper_sub_cc(tmp, tmp, tmp2);

            rd = 16;

            break;

        case 0xb: /* cmn */

            gen_helper_add_cc(tmp, tmp, tmp2);

            rd = 16;

            break;

        case 0xc: /* orr */

            tcg_gen_or_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xd: /* mul */

            tcg_gen_mul_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xe: /* bic */

            tcg_gen_andc_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xf: /* mvn */

            tcg_gen_not_i32(tmp2, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp2);

            val = 1;

            rm = rd;

            break;

        }

        if (rd != 16) {

            if (val) {

                store_reg(s, rm, tmp2);

                if (op != 0xf)

                    tcg_temp_free_i32(tmp);

            } else {

                store_reg(s, rd, tmp);

                tcg_temp_free_i32(tmp2);

            }

        } else {

            tcg_temp_free_i32(tmp);

            tcg_temp_free_i32(tmp2);

        }

        break;

    case 5:

        /* load/store register offset.  */

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        rm = (insn >> 6) & 7;

        op = (insn >> 9) & 7;

        addr = load_reg(s, rn);

        tmp = load_reg(s, rm);

        tcg_gen_add_i32(addr, addr, tmp);

        tcg_temp_free_i32(tmp);

        if (op < 3) /* store */

            tmp = load_reg(s, rd);

        switch (op) {

        case 0: /* str */

            gen_st32(tmp, addr, IS_USER(s));

            break;

        case 1: /* strh */

            gen_st16(tmp, addr, IS_USER(s));

            break;

        case 2: /* strb */

            gen_st8(tmp, addr, IS_USER(s));

            break;

        case 3: /* ldrsb */

            tmp = gen_ld8s(addr, IS_USER(s));

            break;

        case 4: /* ldr */

            tmp = gen_ld32(addr, IS_USER(s));

            break;

        case 5: /* ldrh */

            tmp = gen_ld16u(addr, IS_USER(s));

            break;

        case 6: /* ldrb */

            tmp = gen_ld8u(addr, IS_USER(s));

            break;

        case 7: /* ldrsh */

            tmp = gen_ld16s(addr, IS_USER(s));

            break;

        }

        if (op >= 3) /* load */

            store_reg(s, rd, tmp);

        tcg_temp_free_i32(addr);

        break;

    case 6:

        /* load/store word immediate offset */

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(s, rn);

        val = (insn >> 4) & 0x7c;

        tcg_gen_addi_i32(addr, addr, val);

        if (insn & (1 << 11)) {

            /* load */

            tmp = gen_ld32(addr, IS_USER(s));

            store_reg(s, rd, tmp);

        } else {

            /* store */

            tmp = load_reg(s, rd);

            gen_st32(tmp, addr, IS_USER(s));

        }

        tcg_temp_free_i32(addr);

        break;

    case 7:

        /* load/store byte immediate offset */

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(s, rn);

        val = (insn >> 6) & 0x1f;

        tcg_gen_addi_i32(addr, addr, val);

        if (insn & (1 << 11)) {

            /* load */

            tmp = gen_ld8u(addr, IS_USER(s));

            store_reg(s, rd, tmp);

        } else {

            /* store */

            tmp = load_reg(s, rd);

            gen_st8(tmp, addr, IS_USER(s));

        }

        tcg_temp_free_i32(addr);

        break;

    case 8:

        /* load/store halfword immediate offset */

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(s, rn);

        val = (insn >> 5) & 0x3e;

        tcg_gen_addi_i32(addr, addr, val);

        if (insn & (1 << 11)) {

            /* load */

            tmp = gen_ld16u(addr, IS_USER(s));

            store_reg(s, rd, tmp);

        } else {

            /* store */

            tmp = load_reg(s, rd);

            gen_st16(tmp, addr, IS_USER(s));

        }

        tcg_temp_free_i32(addr);

        break;

    case 9:

        /* load/store from stack */

        rd = (insn >> 8) & 7;

        addr = load_reg(s, 13);

        val = (insn & 0xff) * 4;

        tcg_gen_addi_i32(addr, addr, val);

        if (insn & (1 << 11)) {

            /* load */

            tmp = gen_ld32(addr, IS_USER(s));

            store_reg(s, rd, tmp);

        } else {

            /* store */

            tmp = load_reg(s, rd);

            gen_st32(tmp, addr, IS_USER(s));

        }

        tcg_temp_free_i32(addr);

        break;

    case 10:

        /* add to high reg */

        rd = (insn >> 8) & 7;

        if (insn & (1 << 11)) {

            /* SP */

            tmp = load_reg(s, 13);

        } else {

            /* PC. bit 1 is ignored.  */

            tmp = tcg_temp_new_i32();

            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);

        }

        val = (insn & 0xff) * 4;

        tcg_gen_addi_i32(tmp, tmp, val);

        store_reg(s, rd, tmp);

        break;

    case 11:

        /* misc */

        op = (insn >> 8) & 0xf;

        switch (op) {

        case 0:

            /* adjust stack pointer */

            tmp = load_reg(s, 13);

            val = (insn & 0x7f) * 4;

            if (insn & (1 << 7))

                val = -(int32_t)val;

            tcg_gen_addi_i32(tmp, tmp, val);

            store_reg(s, 13, tmp);

            break;

        case 2: /* sign/zero extend.  */

            ARCH(6);

            rd = insn & 7;

            rm = (insn >> 3) & 7;

            tmp = load_reg(s, rm);

            switch ((insn >> 6) & 3) {

            case 0: gen_sxth(tmp); break;

            case 1: gen_sxtb(tmp); break;

            case 2: gen_uxth(tmp); break;

            case 3: gen_uxtb(tmp); break;

            }

            store_reg(s, rd, tmp);

            break;

        case 4: case 5: case 0xc: case 0xd:

            /* push/pop */

            addr = load_reg(s, 13);

            if (insn & (1 << 8))

                offset = 4;

            else

                offset = 0;

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

                if (insn & (1 << i))

                    offset += 4;

            }

            if ((insn & (1 << 11)) == 0) {

                tcg_gen_addi_i32(addr, addr, -offset);

            }

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

                if (insn & (1 << i)) {

                    if (insn & (1 << 11)) {

                        /* pop */

                        tmp = gen_ld32(addr, IS_USER(s));

                        store_reg(s, i, tmp);

                    } else {

                        /* push */

                        tmp = load_reg(s, i);

                        gen_st32(tmp, addr, IS_USER(s));

                    }

                    /* advance to the next address.  */

                    tcg_gen_addi_i32(addr, addr, 4);

                }

            }

            TCGV_UNUSED(tmp);

            if (insn & (1 << 8)) {

                if (insn & (1 << 11)) {

                    /* pop pc */

                    tmp = gen_ld32(addr, IS_USER(s));

                    /* don't set the pc until the rest of the instruction

                       has completed */

                } else {

                    /* push lr */

                    tmp = load_reg(s, 14);

                    gen_st32(tmp, addr, IS_USER(s));

                }

                tcg_gen_addi_i32(addr, addr, 4);

            }

            if ((insn & (1 << 11)) == 0) {

                tcg_gen_addi_i32(addr, addr, -offset);

            }

            /* write back the new stack pointer */

            store_reg(s, 13, addr);

            /* set the new PC value */

            if ((insn & 0x0900) == 0x0900)

                gen_bx(s, tmp);

            break;

        case 1: case 3: case 9: case 11: /* czb */

            rm = insn & 7;

            tmp = load_reg(s, rm);

            s->condlabel = gen_new_label();

            s->condjmp = 1;

            if (insn & (1 << 11))

                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);

            else

                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);

            tcg_temp_free_i32(tmp);

            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;

            val = (uint32_t)s->pc + 2;

            val += offset;

            gen_jmp(s, val);

            break;

        case 15: /* IT, nop-hint.  */

            if ((insn & 0xf) == 0) {

                gen_nop_hint(s, (insn >> 4) & 0xf);

                break;

            }

            /* If Then.  */

            s->condexec_cond = (insn >> 4) & 0xe;

            s->condexec_mask = insn & 0x1f;

            /* No actual code generated for this insn, just setup state.  */

            break;

        case 0xe: /* bkpt */

            gen_exception_insn(s, 2, EXCP_BKPT);

            break;

        case 0xa: /* rev */

            ARCH(6);

            rn = (insn >> 3) & 0x7;

            rd = insn & 0x7;

            tmp = load_reg(s, rn);

            switch ((insn >> 6) & 3) {

            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;

            case 1: gen_rev16(tmp); break;

            case 3: gen_revsh(tmp); break;

            default: goto illegal_op;

            }

            store_reg(s, rd, tmp);

            break;

        case 6: /* cps */

            ARCH(6);

            if (IS_USER(s))

                break;

            if (IS_M(env)) {

                tmp = tcg_const_i32((insn & (1 << 4)) != 0);

                /* PRIMASK */

                if (insn & 1) {

                    addr = tcg_const_i32(16);

                    gen_helper_v7m_msr(cpu_env, addr, tmp);

                    tcg_temp_free_i32(addr);

                }

                /* FAULTMASK */

                if (insn & 2) {

                    addr = tcg_const_i32(17);

                    gen_helper_v7m_msr(cpu_env, addr, tmp);

                    tcg_temp_free_i32(addr);

                }

                tcg_temp_free_i32(tmp);

                gen_lookup_tb(s);

            } else {

                if (insn & (1 << 4))

                    shift = CPSR_A | CPSR_I | CPSR_F;

                else

                    shift = 0;

                gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);

            }

            break;

        default:

            goto undef;

        }

        break;

    case 12:

        /* load/store multiple */

        rn = (insn >> 8) & 0x7;

        addr = load_reg(s, rn);

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

            if (insn & (1 << i)) {

                if (insn & (1 << 11)) {

                    /* load */

                    tmp = gen_ld32(addr, IS_USER(s));

                    store_reg(s, i, tmp);

                } else {

                    /* store */

                    tmp = load_reg(s, i);

                    gen_st32(tmp, addr, IS_USER(s));

                }

                /* advance to the next address */

                tcg_gen_addi_i32(addr, addr, 4);

            }

        }

        /* Base register writeback.  */

        if ((insn & (1 << rn)) == 0) {

            store_reg(s, rn, addr);

        } else {

            tcg_temp_free_i32(addr);

        }

        break;

    case 13:

        /* conditional branch or swi */

        cond = (insn >> 8) & 0xf;

        if (cond == 0xe)

            goto undef;

        if (cond == 0xf) {

            /* swi */

            gen_set_pc_im(s->pc);

            s->is_jmp = DISAS_SWI;

            break;

        }

        /* generate a conditional jump to next instruction */

        s->condlabel = gen_new_label();

        gen_test_cc(cond ^ 1, s->condlabel);

        s->condjmp = 1;

        /* jump to the offset */

        val = (uint32_t)s->pc + 2;

        offset = ((int32_t)insn << 24) >> 24;

        val += offset << 1;

        gen_jmp(s, val);

        break;

    case 14:

        if (insn & (1 << 11)) {

            if (disas_thumb2_insn(env, s, insn))

              goto undef32;

            break;

        }

        /* unconditional branch */

        val = (uint32_t)s->pc;

        offset = ((int32_t)insn << 21) >> 21;

        val += (offset << 1) + 2;

        gen_jmp(s, val);

        break;

    case 15:

        if (disas_thumb2_insn(env, s, insn))

            goto undef32;

        break;

    }

    return;

undef32:

    gen_exception_insn(s, 4, EXCP_UDEF);

    return;

illegal_op:

undef:

    gen_exception_insn(s, 2, EXCP_UDEF);

}


static int ape_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    APEContext *s = avctx->priv_data;

    int16_t *samples = data;

    int nblocks;

    int i, n;

    int blockstodecode;

    int bytes_used;

    /* should not happen but who knows */

    if (BLOCKS_PER_LOOP * 2 * avctx->channels > *data_size) {

        av_log (avctx, AV_LOG_ERROR, "Output buffer is too small.\n");

        return AVERROR(EINVAL);

    }

    if(!s->samples){

        void *tmp_data = av_realloc(s->data, (buf_size + 3) & ~3);

        if (!tmp_data)

            return AVERROR(ENOMEM);

        s->data = tmp_data;

        s->dsp.bswap_buf((uint32_t*)s->data, (const uint32_t*)buf, buf_size >> 2);

        s->ptr = s->last_ptr = s->data;

        s->data_end = s->data + buf_size;

        nblocks = s->samples = bytestream_get_be32(&s->ptr);

        n =  bytestream_get_be32(&s->ptr);

        if(n < 0 || n > 3){

            av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n");

            s->data = NULL;

            return AVERROR_INVALIDDATA;

        }

        s->ptr += n;

        s->currentframeblocks = nblocks;

        buf += 4;

        if (s->samples <= 0) {

            *data_size = 0;

            return buf_size;

        }

        memset(s->decoded0,  0, sizeof(s->decoded0));

        memset(s->decoded1,  0, sizeof(s->decoded1));

        /* Initialize the frame decoder */

        init_frame_decoder(s);

    }

    if (!s->data) {

        *data_size = 0;

        return buf_size;

    }

    nblocks = s->samples;

    blockstodecode = FFMIN(BLOCKS_PER_LOOP, nblocks);

    s->error=0;

    if ((s->channels == 1) || (s->frameflags & APE_FRAMECODE_PSEUDO_STEREO))

        ape_unpack_mono(s, blockstodecode);

    else

        ape_unpack_stereo(s, blockstodecode);

    emms_c();

    if(s->error || s->ptr > s->data_end){

        s->samples=0;

        av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");

        return AVERROR_INVALIDDATA;

    }

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

        *samples++ = s->decoded0[i];

        if(s->channels == 2)

            *samples++ = s->decoded1[i];

    }

    s->samples -= blockstodecode;

    *data_size = blockstodecode * 2 * s->channels;

    bytes_used = s->samples ? s->ptr - s->last_ptr : buf_size;

    s->last_ptr = s->ptr;

    return bytes_used;

}


static void aarch64_numa_cpu(const void *data)

{

    char *cli;

    QDict *resp;

    QList *cpus;

    const QObject *e;

    cli = make_cli(data, "-smp 2 "

        "-numa node,nodeid=0 -numa node,nodeid=1 "

        "-numa cpu,node-id=1,thread-id=0 "

        "-numa cpu,node-id=0,thread-id=1");

    qtest_start(cli);

    cpus = get_cpus(&resp);

    g_assert(cpus);

    while ((e = qlist_pop(cpus))) {

        QDict *cpu, *props;

        int64_t thread, node;

        cpu = qobject_to_qdict(e);

        g_assert(qdict_haskey(cpu, "props"));

        props = qdict_get_qdict(cpu, "props");

        g_assert(qdict_haskey(props, "node-id"));

        node = qdict_get_int(props, "node-id");

        g_assert(qdict_haskey(props, "thread-id"));

        thread = qdict_get_int(props, "thread-id");

        if (thread == 0) {

            g_assert_cmpint(node, ==, 1);

        } else if (thread == 1) {

            g_assert_cmpint(node, ==, 0);

        } else {

            g_assert(false);

        }

    }

    QDECREF(resp);

    qtest_end();

    g_free(cli);

}


static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,

                        VLC *table, int coeff_index,

                        int first_fragment, int last_fragment,

                        int eob_run)

{

    int i;

    int token;

    int zero_run = 0;

    DCTELEM coeff = 0;

    Vp3Fragment *fragment;

    uint8_t *perm= s->scantable.permutated;

    int bits_to_get;

    if ((first_fragment >= s->fragment_count) ||

        (last_fragment >= s->fragment_count)) {

        av_log(s->avctx, AV_LOG_ERROR, "  vp3:unpack_vlcs(): bad fragment number (%d -> %d ?)\n",

            first_fragment, last_fragment);

        return 0;

    }

    for (i = first_fragment; i <= last_fragment; i++) {

        int fragment_num = s->coded_fragment_list[i];

        if (s->coeff_counts[fragment_num] > coeff_index)

            continue;

        fragment = &s->all_fragments[fragment_num];

        if (!eob_run) {

            /* decode a VLC into a token */

            token = get_vlc2(gb, table->table, 5, 3);

            /* use the token to get a zero run, a coefficient, and an eob run */

            if (token <= 6) {

                eob_run = eob_run_base[token];

                if (eob_run_get_bits[token])

                    eob_run += get_bits(gb, eob_run_get_bits[token]);

                coeff = zero_run = 0;

            } else {

                bits_to_get = coeff_get_bits[token];

                if (!bits_to_get)

                    coeff = coeff_tables[token][0];

                else

                    coeff = coeff_tables[token][get_bits(gb, bits_to_get)];

                zero_run = zero_run_base[token];

                if (zero_run_get_bits[token])

                    zero_run += get_bits(gb, zero_run_get_bits[token]);

            }

        }

        if (!eob_run) {

            s->coeff_counts[fragment_num] += zero_run;

            if (s->coeff_counts[fragment_num] < 64){

                fragment->next_coeff->coeff= coeff;

                fragment->next_coeff->index= perm[s->coeff_counts[fragment_num]++]; //FIXME perm here already?

                fragment->next_coeff->next= s->next_coeff;

                s->next_coeff->next=NULL;

                fragment->next_coeff= s->next_coeff++;

            }

        } else {

            s->coeff_counts[fragment_num] |= 128;

            eob_run--;

        }

    }

    return eob_run;

}


static inline void vmxnet3_ring_init(Vmxnet3Ring *ring,

                                     hwaddr pa,

                                     size_t size,

                                     size_t cell_size,

                                     bool zero_region)

{

    ring->pa = pa;

    ring->size = size;

    ring->cell_size = cell_size;

    ring->gen = VMXNET3_INIT_GEN;

    ring->next = 0;

    if (zero_region) {

        vmw_shmem_set(pa, 0, size * cell_size);

    }

}


uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr)

{

    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);

    uint16_t val;

    k->get_config(vdev, vdev->config);

    if (addr > (vdev->config_len - sizeof(val)))

        return (uint32_t)-1;

    val = lduw_p(vdev->config + addr);

    return val;

}


static int get_qcx(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q)

{

    int i, x;

    if (s->buf_end - s->buf < 1)

        return AVERROR_INVALIDDATA;

    x = bytestream_get_byte(&s->buf); // Sqcd

    q->nguardbits = x >> 5;

    q->quantsty   = x & 0x1f;

    if (q->quantsty == JPEG2000_QSTY_NONE) {

        n -= 3;

        if (s->buf_end - s->buf < n)

            return AVERROR_INVALIDDATA;

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

            q->expn[i] = bytestream_get_byte(&s->buf) >> 3;

    } else if (q->quantsty == JPEG2000_QSTY_SI) {

        if (s->buf_end - s->buf < 2)

            return AVERROR_INVALIDDATA;

        x          = bytestream_get_be16(&s->buf);

        q->expn[0] = x >> 11;

        q->mant[0] = x & 0x7ff;

        for (i = 1; i < JPEG2000_MAX_DECLEVELS * 3; i++) {

            int curexpn = FFMAX(0, q->expn[0] - (i - 1) / 3);

            q->expn[i] = curexpn;

            q->mant[i] = q->mant[0];

        }

    } else {

        n = (n - 3) >> 1;

        if (s->buf_end - s->buf < n)

            return AVERROR_INVALIDDATA;

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

            x          = bytestream_get_be16(&s->buf);

            q->expn[i] = x >> 11;

            q->mant[i] = x & 0x7ff;

        }

    }

    return 0;

}


static void qemu_kvm_eat_signals(CPUState *env)

{

    struct timespec ts = { 0, 0 };

    siginfo_t siginfo;

    sigset_t waitset;

    sigset_t chkset;

    int r;

    sigemptyset(&waitset);

    sigaddset(&waitset, SIG_IPI);

    sigaddset(&waitset, SIGBUS);

    do {

        r = sigtimedwait(&waitset, &siginfo, &ts);

        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {

            perror("sigtimedwait");

            exit(1);

        }

        switch (r) {

        case SIGBUS:

            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {

                sigbus_reraise();

            }

            break;

        default:

            break;

        }

        r = sigpending(&chkset);

        if (r == -1) {

            perror("sigpending");

            exit(1);

        }

    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));

#ifndef CONFIG_IOTHREAD

    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {

        qemu_notify_event();

    }

#endif

}


static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)

{

    int64_t total_size = 0;

    MOVAtom a;

    int i;

    if (atom.size < 0)

        atom.size = INT64_MAX;

    while (total_size + 8 <= atom.size && !url_feof(pb)) {

        int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;

        a.size = atom.size;

        a.type=0;

        if (atom.size >= 8) {

            a.size = avio_rb32(pb);

            a.type = avio_rl32(pb);

            total_size += 8;

            if (a.size == 1) { /* 64 bit extended size */

                a.size = avio_rb64(pb) - 8;

                total_size += 8;

            }

        }

        av_dlog(c->fc, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n",

                a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size);

        if (a.size == 0) {

            a.size = atom.size - total_size + 8;

            if (a.size <= 8)

                break;

        }

        a.size -= 8;

        if (a.size < 0)

            break;

        a.size = FFMIN(a.size, atom.size - total_size);

        for (i = 0; mov_default_parse_table[i].type; i++)

            if (mov_default_parse_table[i].type == a.type) {

                parse = mov_default_parse_table[i].parse;

                break;

            }

        // container is user data

        if (!parse && (atom.type == MKTAG('u','d','t','a') ||

                       atom.type == MKTAG('i','l','s','t')))

            parse = mov_read_udta_string;

        if (!parse) { /* skip leaf atoms data */

            avio_skip(pb, a.size);

        } else {

            int64_t start_pos = avio_tell(pb);

            int64_t left;

            int err = parse(c, pb, a);

            if (err < 0)

                return err;

            if (c->found_moov && c->found_mdat &&

                (!pb->seekable || start_pos + a.size == avio_size(pb)))

                return 0;

            left = a.size - avio_tell(pb) + start_pos;

            if (left > 0) /* skip garbage at atom end */

                avio_skip(pb, left);

        }

        total_size += a.size;

    }

    if (total_size < atom.size && atom.size < 0x7ffff)

        avio_skip(pb, atom.size - total_size);

    return 0;

}


int check_intra_pred8x8_mode_emuedge(int mode, int mb_x, int mb_y)

{

    switch (mode) {

    case DC_PRED8x8:

        return check_dc_pred8x8_mode(mode, mb_x, mb_y);

    case VERT_PRED8x8:

        return !mb_y ? DC_127_PRED8x8 : mode;

    case HOR_PRED8x8:

        return !mb_x ? DC_129_PRED8x8 : mode;

    case PLANE_PRED8x8: /* TM */

        return check_tm_pred8x8_mode(mode, mb_x, mb_y);

    }

    return mode;

}


static int jpeg_write_trailer(AVFormatContext *s1)

{

    JpegContext *s = s1->priv_data;

    av_free(s);

    return 0;

}


static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, int point_transform){

    int i, mb_x, mb_y;

    const int nb_components=3;

    for(mb_y = 0; mb_y < s->mb_height; mb_y++) {

        for(mb_x = 0; mb_x < s->mb_width; mb_x++) {

            if (s->restart_interval && !s->restart_count)

                s->restart_count = s->restart_interval;

            if(mb_x==0 || mb_y==0 || s->interlaced){

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

                    uint8_t *ptr;

                    int n, h, v, x, y, c, j, linesize;

                    n = s->nb_blocks[i];

                    c = s->comp_index[i];

                    h = s->h_scount[i];

                    v = s->v_scount[i];

                    x = 0;

                    y = 0;

                    linesize= s->linesize[c];

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

                        int pred;

                        ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap

                        if(y==0 && mb_y==0){

                            if(x==0 && mb_x==0){

                                pred= 128 << point_transform;

                            }else{

                                pred= ptr[-1];

                            }

                        }else{

                            if(x==0 && mb_x==0){

                                pred= ptr[-linesize];

                            }else{

                                PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);

                            }

                        }

                        if (s->interlaced && s->bottom_field)

                            ptr += linesize >> 1;

                        *ptr= pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform);

                        if (++x == h) {

                            x = 0;

                            y++;

                        }

                    }

                }

            }else{

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

                    uint8_t *ptr;

                    int n, h, v, x, y, c, j, linesize;

                    n = s->nb_blocks[i];

                    c = s->comp_index[i];

                    h = s->h_scount[i];

                    v = s->v_scount[i];

                    x = 0;

                    y = 0;

                    linesize= s->linesize[c];

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

                        int pred;

                        ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap

                        PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);

                        *ptr= pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform);

                        if (++x == h) {

                            x = 0;

                            y++;

                        }

                    }

                }

            }

            if (s->restart_interval && !--s->restart_count) {

                align_get_bits(&s->gb);

                skip_bits(&s->gb, 16); /* skip RSTn */

            }

        }

    }

    return 0;

}


static void filter_mb_mbaff_edgecv( H264Context *h, uint8_t *pix, int stride, const int16_t bS[7], int bsi, int qp ) {

    const int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);

    int index_a = qp - qp_bd_offset + h->slice_alpha_c0_offset;

    int alpha = alpha_table[index_a];

    int beta  = beta_table[qp - qp_bd_offset + h->slice_beta_offset];

    if (alpha ==0 || beta == 0) return;

    if( bS[0] < 4 ) {

        int8_t tc[4];

        tc[0] = tc0_table[index_a][bS[0*bsi]] + 1;

        tc[1] = tc0_table[index_a][bS[1*bsi]] + 1;

        tc[2] = tc0_table[index_a][bS[2*bsi]] + 1;

        tc[3] = tc0_table[index_a][bS[3*bsi]] + 1;

        h->h264dsp.h264_h_loop_filter_chroma_mbaff(pix, stride, alpha, beta, tc);

    } else {

        h->h264dsp.h264_h_loop_filter_chroma_mbaff_intra(pix, stride, alpha, beta);

    }

}


int cmdutils_read_file(const char *filename, char **bufptr, size_t *size)

{

    int ret;

    FILE *f = fopen(filename, "rb");

    if (!f) {

        av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename,

               strerror(errno));

        return AVERROR(errno);

    }

    fseek(f, 0, SEEK_END);

    *size = ftell(f);

    fseek(f, 0, SEEK_SET);

    *bufptr = av_malloc(*size + 1);

    if (!*bufptr) {

        av_log(NULL, AV_LOG_ERROR, "Could not allocate file buffer\n");

        fclose(f);

        return AVERROR(ENOMEM);

    }

    ret = fread(*bufptr, 1, *size, f);

    if (ret < *size) {

        av_free(*bufptr);

        if (ferror(f)) {

            av_log(NULL, AV_LOG_ERROR, "Error while reading file '%s': %s\n",

                   filename, strerror(errno));

            ret = AVERROR(errno);

        } else

            ret = AVERROR_EOF;

    } else {

        ret = 0;

        (*bufptr)[(*size)++] = '\0';

    }

    fclose(f);

    return ret;

}


static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *dir_ptr, int encoding)

{

    int a, b, c, wrap, pred, scale, ret;

    int16_t *dc_val;

    /* find prediction */

    if (n < 4) {

        scale = s->y_dc_scale;

    } else {

        scale = s->c_dc_scale;

    }

    if(IS_3IV1)

        scale= 8;

    wrap= s->block_wrap[n];

    dc_val = s->dc_val[0] + s->block_index[n];

    /* B C

     * A X

     */

    a = dc_val[ - 1];

    b = dc_val[ - 1 - wrap];

    c = dc_val[ - wrap];

    /* outside slice handling (we can't do that by memset as we need the dc for error resilience) */

    if(s->first_slice_line && n!=3){

        if(n!=2) b=c= 1024;

        if(n!=1 && s->mb_x == s->resync_mb_x) b=a= 1024;

    }

    if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1){

        if(n==0 || n==4 || n==5)

            b=1024;

    }

    if (abs(a - b) < abs(b - c)) {

        pred = c;

        *dir_ptr = 1; /* top */

    } else {

        pred = a;

        *dir_ptr = 0; /* left */

    }

    /* we assume pred is positive */

    pred = FASTDIV((pred + (scale >> 1)), scale);

    if(encoding){

        ret = level - pred;

    }else{

        level += pred;

        ret= level;

        if(s->error_recognition>=3){

            if(level<0){

                av_log(s->avctx, AV_LOG_ERROR, "dc<0 at %dx%d\n", s->mb_x, s->mb_y);

                return -1;

            }

            if(level*scale > 2048 + scale){

                av_log(s->avctx, AV_LOG_ERROR, "dc overflow at %dx%d\n", s->mb_x, s->mb_y);

                return -1;

            }

        }

    }

    level *=scale;

    if(level&(~2047)){

        if(level<0)

            level=0;

        else if(!(s->workaround_bugs&FF_BUG_DC_CLIP))

            level=2047;

    }

    dc_val[0]= level;

    return ret;

}


void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN])

{

    const uint32_t broadcast_addr =

        ~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr;

    ArpTable *arptbl = &slirp->arp_table;

    int i;

    DEBUG_CALL("arp_table_add");

    DEBUG_ARG("ip = 0x%x", ip_addr);

    DEBUG_ARGS((dfd, " hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",

                ethaddr[0], ethaddr[1], ethaddr[2],

                ethaddr[3], ethaddr[4], ethaddr[5]));

    /* Check 0.0.0.0/8 invalid source-only addresses */

    assert((ip_addr & htonl(~(0xf << 28))) != 0);

    if (ip_addr == 0xffffffff || ip_addr == broadcast_addr) {

        /* Do not register broadcast addresses */

        return;

    }

    /* Search for an entry */

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

        if (arptbl->table[i].ar_sip == ip_addr) {

            /* Update the entry */

            memcpy(arptbl->table[i].ar_sha, ethaddr, ETH_ALEN);

            return;

        }

    }

    /* No entry found, create a new one */

    arptbl->table[arptbl->next_victim].ar_sip = ip_addr;

    memcpy(arptbl->table[arptbl->next_victim].ar_sha,  ethaddr, ETH_ALEN);

    arptbl->next_victim = (arptbl->next_victim + 1) % ARP_TABLE_SIZE;

}


static void encode_subband_c0run(SnowContext *s, SubBand *b, DWTELEM *src, DWTELEM *parent, int stride, int orientation){

    const int w= b->width;

    const int h= b->height;

    int x, y;

    if(1){

        int run=0;

        int runs[w*h];

        int run_index=0;

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

            for(x=0; x<w; x++){

                int v, p=0;

                int /*ll=0, */l=0, lt=0, t=0, rt=0;

                v= src[x + y*stride];

                if(y){

                    t= src[x + (y-1)*stride];

                    if(x){

                        lt= src[x - 1 + (y-1)*stride];

                    }

                    if(x + 1 < w){

                        rt= src[x + 1 + (y-1)*stride];

                    }

                }

                if(x){

                    l= src[x - 1 + y*stride];

                    /*if(x > 1){

                        if(orientation==1) ll= src[y + (x-2)*stride];

                        else               ll= src[x - 2 + y*stride];

                    }*/

                }

                if(parent){

                    int px= x>>1;

                    int py= y>>1;

                    if(px<b->parent->width && py<b->parent->height)

                        p= parent[px + py*2*stride];

                }

                if(!(/*ll|*/l|lt|t|rt|p)){

                    if(v){

                        runs[run_index++]= run;

                        run=0;

                    }else{

                        run++;

                    }

                }

            }

        }

        runs[run_index++]= run;

        run_index=0;

        run= runs[run_index++];

        put_symbol2(&s->c, b->state[1], run, 3);

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

            for(x=0; x<w; x++){

                int v, p=0;

                int /*ll=0, */l=0, lt=0, t=0, rt=0;

                v= src[x + y*stride];

                if(y){

                    t= src[x + (y-1)*stride];

                    if(x){

                        lt= src[x - 1 + (y-1)*stride];

                    }

                    if(x + 1 < w){

                        rt= src[x + 1 + (y-1)*stride];

                    }

                }

                if(x){

                    l= src[x - 1 + y*stride];

                    /*if(x > 1){

                        if(orientation==1) ll= src[y + (x-2)*stride];

                        else               ll= src[x - 2 + y*stride];

                    }*/

                }

                if(parent){

                    int px= x>>1;

                    int py= y>>1;

                    if(px<b->parent->width && py<b->parent->height)

                        p= parent[px + py*2*stride];

                }

                if(/*ll|*/l|lt|t|rt|p){

                    int context= av_log2(/*ABS(ll) + */3*ABS(l) + ABS(lt) + 2*ABS(t) + ABS(rt) + ABS(p));

                    put_rac(&s->c, &b->state[0][context], !!v);

                }else{

                    if(!run){

                        run= runs[run_index++];

                        put_symbol2(&s->c, b->state[1], run, 3);

                        assert(v);

                    }else{

                        run--;

                        assert(!v);

                    }

                }

                if(v){

                    int context= av_log2(/*ABS(ll) + */3*ABS(l) + ABS(lt) + 2*ABS(t) + ABS(rt) + ABS(p));

                    put_symbol2(&s->c, b->state[context + 2], ABS(v)-1, context-4);

                    put_rac(&s->c, &b->state[0][16 + 1 + 3 + quant3b[l&0xFF] + 3*quant3b[t&0xFF]], v<0);

                }

            }

        }

    }

}


void do_fctiwz (void)

{

    union {

        double d;

        uint64_t i;

    } p;

    /* XXX: higher bits are not supposed to be significant.

     *      to make tests easier, return the same as a real PowerPC 750 (aka G3)

     */

    p.i = float64_to_int32_round_to_zero(FT0, &env->fp_status);

    p.i |= 0xFFF80000ULL << 32;

    FT0 = p.d;

}


static void bdrv_ioctl_bh_cb(void *opaque)

{

    BdrvIoctlCompletionData *data = opaque;

    bdrv_co_io_em_complete(data->co, -ENOTSUP);

    qemu_bh_delete(data->bh);

}


static int tcp_write(URLContext *h, const uint8_t *buf, int size)

{

    TCPContext *s = h->priv_data;

    int ret, size1, fd_max, len;

    fd_set wfds;

    struct timeval tv;

    size1 = size;

    while (size > 0) {

        if (url_interrupt_cb())

            return AVERROR(EINTR);

        fd_max = s->fd;

        FD_ZERO(&wfds);

        FD_SET(s->fd, &wfds);

        tv.tv_sec = 0;

        tv.tv_usec = 100 * 1000;

        ret = select(fd_max + 1, NULL, &wfds, NULL, &tv);

        if (ret > 0 && FD_ISSET(s->fd, &wfds)) {

            len = send(s->fd, buf, size, 0);

            if (len < 0) {

                if (ff_neterrno() != FF_NETERROR(EINTR) &&

                    ff_neterrno() != FF_NETERROR(EAGAIN))

                    return ff_neterrno();

                continue;

            }

            size -= len;

            buf += len;

        } else if (ret < 0) {

            if (ff_neterrno() == FF_NETERROR(EINTR))

                continue;

            return -1;

        }

    }

    return size1 - size;

}


static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size)

{

    int cb_size          = 1 << log2_cb_size;

    HEVCLocalContext *lc = &s->HEVClc;

    int log2_min_cb_size = s->sps->log2_min_cb_size;

    int length           = cb_size >> log2_min_cb_size;

    int min_cb_width     = s->sps->min_cb_width;

    int x_cb             = x0 >> log2_min_cb_size;

    int y_cb             = y0 >> log2_min_cb_size;

    int x, y;

    lc->cu.x                = x0;

    lc->cu.y                = y0;

    lc->cu.rqt_root_cbf     = 1;

    lc->cu.pred_mode        = MODE_INTRA;

    lc->cu.part_mode        = PART_2Nx2N;

    lc->cu.intra_split_flag = 0;

    lc->cu.pcm_flag         = 0;

    SAMPLE_CTB(s->skip_flag, x_cb, y_cb) = 0;

    for (x = 0; x < 4; x++)

        lc->pu.intra_pred_mode[x] = 1;

    if (s->pps->transquant_bypass_enable_flag) {

        lc->cu.cu_transquant_bypass_flag = ff_hevc_cu_transquant_bypass_flag_decode(s);

        if (lc->cu.cu_transquant_bypass_flag)

            set_deblocking_bypass(s, x0, y0, log2_cb_size);

    } else

        lc->cu.cu_transquant_bypass_flag = 0;

    if (s->sh.slice_type != I_SLICE) {

        uint8_t skip_flag = ff_hevc_skip_flag_decode(s, x0, y0, x_cb, y_cb);

        lc->cu.pred_mode = MODE_SKIP;

        x = y_cb * min_cb_width + x_cb;

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

            memset(&s->skip_flag[x], skip_flag, length);

            x += min_cb_width;

        }

        lc->cu.pred_mode = skip_flag ? MODE_SKIP : MODE_INTER;

    }

    if (SAMPLE_CTB(s->skip_flag, x_cb, y_cb)) {

        hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 0);

        intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);

        if (!s->sh.disable_deblocking_filter_flag)

            ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size,

                                                  lc->slice_or_tiles_up_boundary,

                                                  lc->slice_or_tiles_left_boundary);

    } else {

        if (s->sh.slice_type != I_SLICE)

            lc->cu.pred_mode = ff_hevc_pred_mode_decode(s);

        if (lc->cu.pred_mode != MODE_INTRA ||

            log2_cb_size == s->sps->log2_min_cb_size) {

            lc->cu.part_mode        = ff_hevc_part_mode_decode(s, log2_cb_size);

            lc->cu.intra_split_flag = lc->cu.part_mode == PART_NxN &&

                                      lc->cu.pred_mode == MODE_INTRA;

        }

        if (lc->cu.pred_mode == MODE_INTRA) {

            if (lc->cu.part_mode == PART_2Nx2N && s->sps->pcm_enabled_flag &&

                log2_cb_size >= s->sps->pcm.log2_min_pcm_cb_size &&

                log2_cb_size <= s->sps->pcm.log2_max_pcm_cb_size) {

                lc->cu.pcm_flag = ff_hevc_pcm_flag_decode(s);

            }

            if (lc->cu.pcm_flag) {

                int ret;

                intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);

                ret = hls_pcm_sample(s, x0, y0, log2_cb_size);

                if (s->sps->pcm.loop_filter_disable_flag)

                    set_deblocking_bypass(s, x0, y0, log2_cb_size);

                if (ret < 0)

                    return ret;

            } else {

                intra_prediction_unit(s, x0, y0, log2_cb_size);

            }

        } else {

            intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);

            switch (lc->cu.part_mode) {

            case PART_2Nx2N:

                hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 0);

                break;

            case PART_2NxN:

                hls_prediction_unit(s, x0, y0,               cb_size, cb_size / 2, log2_cb_size, 0);

                hls_prediction_unit(s, x0, y0 + cb_size / 2, cb_size, cb_size / 2, log2_cb_size, 1);

                break;

            case PART_Nx2N:

                hls_prediction_unit(s, x0,               y0, cb_size / 2, cb_size, log2_cb_size, 0);

                hls_prediction_unit(s, x0 + cb_size / 2, y0, cb_size / 2, cb_size, log2_cb_size, 1);

                break;

            case PART_2NxnU:

                hls_prediction_unit(s, x0, y0,               cb_size, cb_size     / 4, log2_cb_size, 0);

                hls_prediction_unit(s, x0, y0 + cb_size / 4, cb_size, cb_size * 3 / 4, log2_cb_size, 1);

                break;

            case PART_2NxnD:

                hls_prediction_unit(s, x0, y0,                   cb_size, cb_size * 3 / 4, log2_cb_size, 0);

                hls_prediction_unit(s, x0, y0 + cb_size * 3 / 4, cb_size, cb_size     / 4, log2_cb_size, 1);

                break;

            case PART_nLx2N:

                hls_prediction_unit(s, x0,               y0, cb_size     / 4, cb_size, log2_cb_size, 0);

                hls_prediction_unit(s, x0 + cb_size / 4, y0, cb_size * 3 / 4, cb_size, log2_cb_size, 1);

                break;

            case PART_nRx2N:

                hls_prediction_unit(s, x0,                   y0, cb_size * 3 / 4, cb_size, log2_cb_size, 0);

                hls_prediction_unit(s, x0 + cb_size * 3 / 4, y0, cb_size     / 4, cb_size, log2_cb_size, 1);

                break;

            case PART_NxN:

                hls_prediction_unit(s, x0,               y0,               cb_size / 2, cb_size / 2, log2_cb_size, 0);

                hls_prediction_unit(s, x0 + cb_size / 2, y0,               cb_size / 2, cb_size / 2, log2_cb_size, 1);

                hls_prediction_unit(s, x0,               y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 2);

                hls_prediction_unit(s, x0 + cb_size / 2, y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 3);

                break;

            }

        }

        if (!lc->cu.pcm_flag) {

            if (lc->cu.pred_mode != MODE_INTRA &&

                !(lc->cu.part_mode == PART_2Nx2N && lc->pu.merge_flag)) {

                lc->cu.rqt_root_cbf = ff_hevc_no_residual_syntax_flag_decode(s);

            }

            if (lc->cu.rqt_root_cbf) {

                lc->cu.max_trafo_depth = lc->cu.pred_mode == MODE_INTRA ?

                                         s->sps->max_transform_hierarchy_depth_intra + lc->cu.intra_split_flag :

                                         s->sps->max_transform_hierarchy_depth_inter;

                hls_transform_tree(s, x0, y0, x0, y0, x0, y0, log2_cb_size,

                                   log2_cb_size, 0, 0);

            } else {

                if (!s->sh.disable_deblocking_filter_flag)

                    ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size,

                                                          lc->slice_or_tiles_up_boundary,

                                                          lc->slice_or_tiles_left_boundary);

            }

        }

    }

    if (s->pps->cu_qp_delta_enabled_flag && lc->tu.is_cu_qp_delta_coded == 0)

        ff_hevc_set_qPy(s, x0, y0, x0, y0, log2_cb_size);

    x = y_cb * min_cb_width + x_cb;

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

        memset(&s->qp_y_tab[x], lc->qp_y, length);

        x += min_cb_width;

    }

    set_ct_depth(s, x0, y0, log2_cb_size, lc->ct.depth);

    return 0;

}


static int alloc_buffer(InputStream *ist, FrameBuffer **pbuf)

{

    AVCodecContext *s = ist->st->codec;

    FrameBuffer  *buf = av_mallocz(sizeof(*buf));

    int ret;

    const int pixel_size = av_pix_fmt_descriptors[s->pix_fmt].comp[0].step_minus1+1;

    int h_chroma_shift, v_chroma_shift;

    int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails on svq1

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

    if (!buf)

        return AVERROR(ENOMEM);

    if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {

        w += 2*edge;

        h += 2*edge;

    }

    avcodec_align_dimensions(s, &w, &h);

    if ((ret = av_image_alloc(buf->base, buf->linesize, w, h,

                              s->pix_fmt, 32)) < 0) {

        av_freep(&buf);

        return ret;

    }

    /* XXX this shouldn't be needed, but some tests break without this line

     * those decoders are buggy and need to be fixed.

     * the following tests fail:

     * bethsoft-vid, cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit

     */

    memset(buf->base[0], 128, ret);

    avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);

    for (int i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {

        const int h_shift = i==0 ? 0 : h_chroma_shift;

        const int v_shift = i==0 ? 0 : v_chroma_shift;

        if (s->flags & CODEC_FLAG_EMU_EDGE)

            buf->data[i] = buf->base[i];

        else

            buf->data[i] = buf->base[i] +

                           FFALIGN((buf->linesize[i]*edge >> v_shift) +

                                   (pixel_size*edge >> h_shift), 32);

    }

    buf->w       = s->width;

    buf->h       = s->height;

    buf->pix_fmt = s->pix_fmt;

    buf->ist     = ist;

    *pbuf = buf;

    return 0;

}


static av_cold int tqi_decode_init(AVCodecContext *avctx)

{

    TqiContext *t = avctx->priv_data;

    ff_blockdsp_init(&t->bdsp, avctx);

    ff_bswapdsp_init(&t->bsdsp);

    ff_idctdsp_init(&t->idsp, avctx);

    ff_init_scantable_permutation(t->idsp.idct_permutation, FF_IDCT_PERM_NONE);

    ff_init_scantable(t->idsp.idct_permutation, &t->intra_scantable, ff_zigzag_direct);

    avctx->framerate = (AVRational){ 15, 1 };

    avctx->pix_fmt = AV_PIX_FMT_YUV420P;

    ff_mpeg12_init_vlcs();

    return 0;

}


static int pred_weight_table(H264Context *h)

{

    int list, i;

    int luma_def, chroma_def;

    h->use_weight             = 0;

    h->use_weight_chroma      = 0;

    h->luma_log2_weight_denom = get_ue_golomb(&h->gb);

    if (h->sps.chroma_format_idc)

        h->chroma_log2_weight_denom = get_ue_golomb(&h->gb);

    luma_def   = 1 << h->luma_log2_weight_denom;

    chroma_def = 1 << h->chroma_log2_weight_denom;

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

        h->luma_weight_flag[list]   = 0;

        h->chroma_weight_flag[list] = 0;

        for (i = 0; i < h->ref_count[list]; i++) {

            int luma_weight_flag, chroma_weight_flag;

            luma_weight_flag = get_bits1(&h->gb);

            if (luma_weight_flag) {

                h->luma_weight[i][list][0] = get_se_golomb(&h->gb);

                h->luma_weight[i][list][1] = get_se_golomb(&h->gb);

                if (h->luma_weight[i][list][0] != luma_def ||

                    h->luma_weight[i][list][1] != 0) {

                    h->use_weight             = 1;

                    h->luma_weight_flag[list] = 1;

                }

            } else {

                h->luma_weight[i][list][0] = luma_def;

                h->luma_weight[i][list][1] = 0;

            }

            if (h->sps.chroma_format_idc) {

                chroma_weight_flag = get_bits1(&h->gb);

                if (chroma_weight_flag) {

                    int j;

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

                        h->chroma_weight[i][list][j][0] = get_se_golomb(&h->gb);

                        h->chroma_weight[i][list][j][1] = get_se_golomb(&h->gb);

                        if (h->chroma_weight[i][list][j][0] != chroma_def ||

                            h->chroma_weight[i][list][j][1] != 0) {

                            h->use_weight_chroma        = 1;

                            h->chroma_weight_flag[list] = 1;

                        }

                    }

                } else {

                    int j;

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

                        h->chroma_weight[i][list][j][0] = chroma_def;

                        h->chroma_weight[i][list][j][1] = 0;

                    }

                }

            }

        }

        if (h->slice_type_nos != AV_PICTURE_TYPE_B)

            break;

    }

    h->use_weight = h->use_weight || h->use_weight_chroma;

    return 0;

}


static void rtl8139_cplus_transmit(RTL8139State *s)

{

    int txcount = 0;

    while (rtl8139_cplus_transmit_one(s))

    {

        ++txcount;

    }

    /* Mark transfer completed */

    if (!txcount)

    {

        DPRINTF("C+ mode : transmitter queue stalled, current TxDesc = %d\n",

            s->currCPlusTxDesc);

    }

    else

    {

        /* update interrupt status */

        s->IntrStatus |= TxOK;

        rtl8139_update_irq(s);

    }

}


static int local_utimensat(FsContext *s, V9fsPath *fs_path,

                           const struct timespec *buf)

{

    char buffer[PATH_MAX];

    char *path = fs_path->data;

    return qemu_utimens(rpath(s, path, buffer), buf);

}


int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,

                          CPUBreakpoint **breakpoint)

{

#if defined(TARGET_HAS_ICE)

    CPUBreakpoint *bp;

    bp = qemu_malloc(sizeof(*bp));

    bp->pc = pc;

    bp->flags = flags;

    /* keep all GDB-injected breakpoints in front */

    if (flags & BP_GDB)

        TAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);

    else

        TAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);

    breakpoint_invalidate(env, pc);

    if (breakpoint)

        *breakpoint = bp;

    return 0;

#else

    return -ENOSYS;

#endif

}


static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata,

                                AVFormatContext *s, const char *magic,

                                ID3v2ExtraMeta **extra_meta)

{

    int len, ret;

    uint8_t buf[ID3v2_HEADER_SIZE];

    int found_header;

    int64_t off;

    do {

        /* save the current offset in case there's nothing to read/skip */

        off = avio_tell(pb);

        ret = avio_read(pb, buf, ID3v2_HEADER_SIZE);

        if (ret != ID3v2_HEADER_SIZE) {

            avio_seek(pb, off, SEEK_SET);

            break;

        }

        found_header = ff_id3v2_match(buf, magic);

        if (found_header) {

            /* parse ID3v2 header */

            len = ((buf[6] & 0x7f) << 21) |

                  ((buf[7] & 0x7f) << 14) |

                  ((buf[8] & 0x7f) << 7) |

                   (buf[9] & 0x7f);

            id3v2_parse(pb, metadata, s, len, buf[3], buf[5], extra_meta);

        } else {

            avio_seek(pb, off, SEEK_SET);

        }

    } while (found_header);

    ff_metadata_conv(metadata, NULL, ff_id3v2_34_metadata_conv);

    ff_metadata_conv(metadata, NULL, id3v2_2_metadata_conv);

    ff_metadata_conv(metadata, NULL, ff_id3v2_4_metadata_conv);

    merge_date(metadata);

}


static always_inline void gen_fbcond (DisasContext *ctx,

                                      void* func,

                                      int ra, int32_t disp16)

{

    int l1, l2;

    TCGv tmp;

    l1 = gen_new_label();

    l2 = gen_new_label();

    if (ra != 31) {

        tmp = tcg_temp_new(TCG_TYPE_I64);

        tcg_gen_helper_1_1(func, tmp, cpu_fir[ra]);

    } else  {

        tmp = tcg_const_i64(0);

        tcg_gen_helper_1_1(func, tmp, tmp);

    }

    tcg_gen_brcondi_i64(TCG_COND_NE, tmp, 0, l1);

    tcg_gen_movi_i64(cpu_pc, ctx->pc);

    tcg_gen_br(l2);

    gen_set_label(l1);

    tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp16 << 2));

    gen_set_label(l2);

}


static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,

                                                  int64_t sector_num,

                                                  int nb_sectors, int *pnum,

                                                  BlockDriverState **file)

{

    IscsiLun *iscsilun = bs->opaque;

    struct scsi_get_lba_status *lbas = NULL;

    struct scsi_lba_status_descriptor *lbasd = NULL;

    struct IscsiTask iTask;

    int64_t ret;

    iscsi_co_init_iscsitask(iscsilun, &iTask);

    if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {

        ret = -EINVAL;

        goto out;

    }

    /* default to all sectors allocated */

    ret = BDRV_BLOCK_DATA;

    ret |= (sector_num << BDRV_SECTOR_BITS) | BDRV_BLOCK_OFFSET_VALID;

    *pnum = nb_sectors;

    /* LUN does not support logical block provisioning */

    if (!iscsilun->lbpme) {

        goto out;

    }

retry:

    if (iscsi_get_lba_status_task(iscsilun->iscsi, iscsilun->lun,

                                  sector_qemu2lun(sector_num, iscsilun),

                                  8 + 16, iscsi_co_generic_cb,

                                  &iTask) == NULL) {

        ret = -ENOMEM;

        goto out;

    }

    while (!iTask.complete) {

        iscsi_set_events(iscsilun);

        qemu_coroutine_yield();

    }

    if (iTask.do_retry) {

        if (iTask.task != NULL) {

            scsi_free_scsi_task(iTask.task);

            iTask.task = NULL;

        }

        iTask.complete = 0;

        goto retry;

    }

    if (iTask.status != SCSI_STATUS_GOOD) {

        /* in case the get_lba_status_callout fails (i.e.

         * because the device is busy or the cmd is not

         * supported) we pretend all blocks are allocated

         * for backwards compatibility */

        goto out;

    }

    lbas = scsi_datain_unmarshall(iTask.task);

    if (lbas == NULL) {

        ret = -EIO;

        goto out;

    }

    lbasd = &lbas->descriptors[0];

    if (sector_qemu2lun(sector_num, iscsilun) != lbasd->lba) {

        ret = -EIO;

        goto out;

    }

    *pnum = sector_lun2qemu(lbasd->num_blocks, iscsilun);

    if (lbasd->provisioning == SCSI_PROVISIONING_TYPE_DEALLOCATED ||

        lbasd->provisioning == SCSI_PROVISIONING_TYPE_ANCHORED) {

        ret &= ~BDRV_BLOCK_DATA;

        if (iscsilun->lbprz) {

            ret |= BDRV_BLOCK_ZERO;

        }

    }

    if (ret & BDRV_BLOCK_ZERO) {

        iscsi_allocationmap_clear(iscsilun, sector_num, *pnum);

    } else {

        iscsi_allocationmap_set(iscsilun, sector_num, *pnum);

    }

    if (*pnum > nb_sectors) {

        *pnum = nb_sectors;

    }

out:

    if (iTask.task != NULL) {

        scsi_free_scsi_task(iTask.task);

    }

    if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID) {

        *file = bs;

    }

    return ret;

}


static void vnc_tight_stop(VncState *vs)

{

    // switch back to normal output/zlib buffers

    vs->tight = vs->output;

    vs->output = vs->tight_tmp;

}


void aio_set_fd_handler(AioContext *ctx,

                        int fd,

                        bool is_external,

                        IOHandler *io_read,

                        IOHandler *io_write,

                        AioPollFn *io_poll,

                        void *opaque)

{

    abort();

}


int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,

        uint32_t vaddr, int is_write, int mmu_idx,

        uint32_t *paddr, uint32_t *page_size, unsigned *access)

{

    if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {

        return get_physical_addr_mmu(env, update_tlb,

                vaddr, is_write, mmu_idx, paddr, page_size, access, true);

    } else if (xtensa_option_bits_enabled(env->config,

                XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |

                XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION))) {

        return get_physical_addr_region(env, vaddr, is_write, mmu_idx,

                paddr, page_size, access);

    } else {

        *paddr = vaddr;

        *page_size = TARGET_PAGE_SIZE;

        *access = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_BYPASS;

        return 0;

    }

}


static int usb_msd_handle_control(USBDevice *dev, int request, int value,

                                  int index, int length, uint8_t *data)

{

    MSDState *s = (MSDState *)dev;

    int ret;

    ret = usb_desc_handle_control(dev, request, value, index, length, data);

    if (ret >= 0) {

        return ret;

    }

    ret = 0;

    switch (request) {

    case DeviceRequest | USB_REQ_GET_STATUS:

        data[0] = (1 << USB_DEVICE_SELF_POWERED) |

            (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);

        data[1] = 0x00;

        ret = 2;

        break;

    case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:

        if (value == USB_DEVICE_REMOTE_WAKEUP) {

            dev->remote_wakeup = 0;

        } else {

            goto fail;

        }

        ret = 0;

        break;

    case DeviceOutRequest | USB_REQ_SET_FEATURE:

        if (value == USB_DEVICE_REMOTE_WAKEUP) {

            dev->remote_wakeup = 1;

        } else {

            goto fail;

        }

        ret = 0;

        break;

    case DeviceRequest | USB_REQ_GET_CONFIGURATION:

        data[0] = 1;

        ret = 1;

        break;

    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:

        ret = 0;

        break;

    case DeviceRequest | USB_REQ_GET_INTERFACE:

        data[0] = 0;

        ret = 1;

        break;

    case DeviceOutRequest | USB_REQ_SET_INTERFACE:

        ret = 0;

        break;

    case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:

        ret = 0;

        break;

    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:

        ret = 0;

        break;

        /* Class specific requests.  */

    case ClassInterfaceOutRequest | MassStorageReset:

        /* Reset state ready for the next CBW.  */

        s->mode = USB_MSDM_CBW;

        ret = 0;

        break;

    case ClassInterfaceRequest | GetMaxLun:

        data[0] = 0;

        ret = 1;

        break;

    default:

    fail:

        ret = USB_RET_STALL;

        break;

    }

    return ret;

}


static int tftp_send_oack(struct tftp_session *spt,

                          const char *keys[], uint32_t values[], int nb,

                          struct tftp_t *recv_tp)

{

    struct sockaddr_in saddr, daddr;

    struct mbuf *m;

    struct tftp_t *tp;

    int i, n = 0;

    m = m_get(spt->slirp);

    if (!m)

	return -1;

    memset(m->m_data, 0, m->m_size);

    m->m_data += IF_MAXLINKHDR;

    tp = (void *)m->m_data;

    m->m_data += sizeof(struct udpiphdr);

    tp->tp_op = htons(TFTP_OACK);

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

        n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s",

                      keys[i]) + 1;

        n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%u",

                      values[i]) + 1;

    }

    saddr.sin_addr = recv_tp->ip.ip_dst;

    saddr.sin_port = recv_tp->udp.uh_dport;

    daddr.sin_addr = spt->client_ip;

    daddr.sin_port = spt->client_port;

    m->m_len = sizeof(struct tftp_t) - 514 + n -

        sizeof(struct ip) - sizeof(struct udphdr);

    udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);

    return 0;

}


void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr)

{

    int has_video, has_audio, i, j;

    AVFormatContext *ic;

    has_video = 0;

    has_audio = 0;

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

        ic = input_files[j];

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

            AVCodecContext *enc = &ic->streams[i]->codec;

            switch(enc->codec_type) {

            case CODEC_TYPE_AUDIO:

                has_audio = 1;

                break;

            case CODEC_TYPE_VIDEO:

                has_video = 1;

                break;

            default:

                abort();

            }

        }

    }

    *has_video_ptr = has_video;

    *has_audio_ptr = has_audio;

}


static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,

    uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m)

{

    BDRVQcow2State *s = bs->opaque;

    int l2_index;

    uint64_t *l2_table;

    uint64_t entry;

    unsigned int nb_clusters;

    int ret;

    uint64_t alloc_cluster_offset;

    trace_qcow2_handle_alloc(qemu_coroutine_self(), guest_offset, *host_offset,

                             *bytes);

    assert(*bytes > 0);

    /*

     * Calculate the number of clusters to look for. We stop at L2 table

     * boundaries to keep things simple.

     */

    nb_clusters =

        size_to_clusters(s, offset_into_cluster(s, guest_offset) + *bytes);

    l2_index = offset_to_l2_index(s, guest_offset);

    nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);

    /* Find L2 entry for the first involved cluster */

    ret = get_cluster_table(bs, guest_offset, &l2_table, &l2_index);

    if (ret < 0) {

        return ret;

    }

    entry = be64_to_cpu(l2_table[l2_index]);

    /* For the moment, overwrite compressed clusters one by one */

    if (entry & QCOW_OFLAG_COMPRESSED) {

        nb_clusters = 1;

    } else {

        nb_clusters = count_cow_clusters(s, nb_clusters, l2_table, l2_index);

    }

    /* This function is only called when there were no non-COW clusters, so if

     * we can't find any unallocated or COW clusters either, something is

     * wrong with our code. */

    assert(nb_clusters > 0);

    qcow2_cache_put(bs, s->l2_table_cache, (void **) &l2_table);

    /* Allocate, if necessary at a given offset in the image file */

    alloc_cluster_offset = start_of_cluster(s, *host_offset);

    ret = do_alloc_cluster_offset(bs, guest_offset, &alloc_cluster_offset,

                                  &nb_clusters);

    if (ret < 0) {

        goto fail;

    }

    /* Can't extend contiguous allocation */

    if (nb_clusters == 0) {

        *bytes = 0;

        return 0;

    }

    /* !*host_offset would overwrite the image header and is reserved for "no

     * host offset preferred". If 0 was a valid host offset, it'd trigger the

     * following overlap check; do that now to avoid having an invalid value in

     * *host_offset. */

    if (!alloc_cluster_offset) {

        ret = qcow2_pre_write_overlap_check(bs, 0, alloc_cluster_offset,

                                            nb_clusters * s->cluster_size);

        assert(ret < 0);

        goto fail;

    }

    /*

     * Save info needed for meta data update.

     *

     * requested_sectors: Number of sectors from the start of the first

     * newly allocated cluster to the end of the (possibly shortened

     * before) write request.

     *

     * avail_sectors: Number of sectors from the start of the first

     * newly allocated to the end of the last newly allocated cluster.

     *

     * nb_sectors: The number of sectors from the start of the first

     * newly allocated cluster to the end of the area that the write

     * request actually writes to (excluding COW at the end)

     */

    int requested_sectors =

        (*bytes + offset_into_cluster(s, guest_offset))

        >> BDRV_SECTOR_BITS;

    int avail_sectors = nb_clusters

                        << (s->cluster_bits - BDRV_SECTOR_BITS);

    int alloc_n_start = offset_into_cluster(s, guest_offset)

                        >> BDRV_SECTOR_BITS;

    int nb_sectors = MIN(requested_sectors, avail_sectors);

    QCowL2Meta *old_m = *m;

    *m = g_malloc0(sizeof(**m));

    **m = (QCowL2Meta) {

        .next           = old_m,

        .alloc_offset   = alloc_cluster_offset,

        .offset         = start_of_cluster(s, guest_offset),

        .nb_clusters    = nb_clusters,

        .nb_available   = nb_sectors,

        .cow_start = {

            .offset     = 0,

            .nb_sectors = alloc_n_start,

        },

        .cow_end = {

            .offset     = nb_sectors * BDRV_SECTOR_SIZE,

            .nb_sectors = avail_sectors - nb_sectors,

        },

    };

    qemu_co_queue_init(&(*m)->dependent_requests);

    QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight);

    *host_offset = alloc_cluster_offset + offset_into_cluster(s, guest_offset);

    *bytes = MIN(*bytes, (nb_sectors * BDRV_SECTOR_SIZE)

                         - offset_into_cluster(s, guest_offset));

    assert(*bytes != 0);

    return 1;

fail:

    if (*m && (*m)->nb_clusters > 0) {

        QLIST_REMOVE(*m, next_in_flight);

    }

    return ret;

}


static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,

                             const char *model, const char *name,

                             const char *ifname, const char *script,

                             const char *downscript, const char *vhostfdname,

                             int vnet_hdr, int fd, Error **errp)

{

    Error *err = NULL;

    TAPState *s = net_tap_fd_init(peer, model, name, fd, vnet_hdr);

    int vhostfd;

    tap_set_sndbuf(s->fd, tap, &err);

    if (err) {

        error_propagate(errp, err);

        return;

    }

    if (tap->has_fd || tap->has_fds) {

        snprintf(s->nc.info_str, sizeof(s->nc.info_str), "fd=%d", fd);

    } else if (tap->has_helper) {

        snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s",

                 tap->helper);

    } else {

        snprintf(s->nc.info_str, sizeof(s->nc.info_str),

                 "ifname=%s,script=%s,downscript=%s", ifname, script,

                 downscript);

        if (strcmp(downscript, "no") != 0) {

            snprintf(s->down_script, sizeof(s->down_script), "%s", downscript);

            snprintf(s->down_script_arg, sizeof(s->down_script_arg),

                     "%s", ifname);

        }

    }

    if (tap->has_vhost ? tap->vhost :

        vhostfdname || (tap->has_vhostforce && tap->vhostforce)) {

        VhostNetOptions options;

        options.backend_type = VHOST_BACKEND_TYPE_KERNEL;

        options.net_backend = &s->nc;

        if (tap->has_vhostfd || tap->has_vhostfds) {

            vhostfd = monitor_fd_param(cur_mon, vhostfdname, &err);

            if (vhostfd == -1) {

                error_propagate(errp, err);

                return;

            }

        } else {

            vhostfd = open("/dev/vhost-net", O_RDWR);

            if (vhostfd < 0) {

                error_setg_errno(errp, errno,

                                 "tap: open vhost char device failed");

                return;

            }

        }

        options.opaque = (void *)(uintptr_t)vhostfd;

        s->vhost_net = vhost_net_init(&options);

        if (!s->vhost_net) {

            error_setg(errp,

                       "vhost-net requested but could not be initialized");

            return;

        }

    } else if (tap->has_vhostfd || tap->has_vhostfds) {

        error_setg(errp, "vhostfd= is not valid without vhost");

    }

}


static int virtio_balloon_init_pci(PCIDevice *pci_dev)

{

    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);

    VirtIODevice *vdev;

    vdev = virtio_balloon_init(&pci_dev->qdev);

    virtio_init_pci(proxy, vdev,

                    PCI_VENDOR_ID_REDHAT_QUMRANET,

                    PCI_DEVICE_ID_VIRTIO_BALLOON,

                    PCI_CLASS_MEMORY_RAM,

                    0x00);

    return 0;

}


static void bochs_refresh_limits(BlockDriverState *bs, Error **errp)

{

    bs->request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O supported */

}


static void spr_write_sdr1 (void *opaque, int sprn)

{

    DisasContext *ctx = opaque;

    gen_op_store_sdr1();

    RET_STOP(ctx);

}


static int uart_can_receive(void *opaque)

{

    UartState *s = (UartState *)opaque;

    return RX_FIFO_SIZE - s->rx_count;

}


vmdk_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,

               QEMUIOVector *qiov, int flags)

{

    BDRVVmdkState *s = bs->opaque;

    int ret;

    uint64_t n_bytes, offset_in_cluster;

    VmdkExtent *extent = NULL;

    QEMUIOVector local_qiov;

    uint64_t cluster_offset;

    uint64_t bytes_done = 0;

    qemu_iovec_init(&local_qiov, qiov->niov);

    qemu_co_mutex_lock(&s->lock);

    while (bytes > 0) {

        extent = find_extent(s, offset >> BDRV_SECTOR_BITS, extent);

        if (!extent) {

            ret = -EIO;

            goto fail;

        }

        ret = get_cluster_offset(bs, extent, NULL,

                                 offset, false, &cluster_offset, 0, 0);

        offset_in_cluster = vmdk_find_offset_in_cluster(extent, offset);

        n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE

                             - offset_in_cluster);

        if (ret != VMDK_OK) {

            /* if not allocated, try to read from parent image, if exist */

            if (bs->backing && ret != VMDK_ZEROED) {

                if (!vmdk_is_cid_valid(bs)) {

                    ret = -EINVAL;

                    goto fail;

                }

                qemu_iovec_reset(&local_qiov);

                qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);

                ret = bdrv_co_preadv(bs->backing->bs, offset, n_bytes,

                                     &local_qiov, 0);

                if (ret < 0) {

                    goto fail;

                }

            } else {

                qemu_iovec_memset(qiov, bytes_done, 0, n_bytes);

            }

        } else {

            qemu_iovec_reset(&local_qiov);

            qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);

            ret = vmdk_read_extent(extent, cluster_offset, offset_in_cluster,

                                   &local_qiov, n_bytes);

            if (ret) {

                goto fail;

            }

        }

        bytes -= n_bytes;

        offset += n_bytes;

        bytes_done += n_bytes;

    }

    ret = 0;

fail:

    qemu_co_mutex_unlock(&s->lock);

    qemu_iovec_destroy(&local_qiov);

    return ret;

}


void cpu_ppc_store_hdecr (CPUPPCState *env, uint32_t value)

{

    PowerPCCPU *cpu = ppc_env_get_cpu(env);

    _cpu_ppc_store_hdecr(cpu, cpu_ppc_load_hdecr(env), value, 0);

}


static uint32_t syborg_virtio_readl(void *opaque, target_phys_addr_t offset)

{

    SyborgVirtIOProxy *s = opaque;

    VirtIODevice *vdev = s->vdev;

    uint32_t ret;

    DPRINTF("readl 0x%x\n", (int)offset);

    if (offset >= SYBORG_VIRTIO_CONFIG) {

        return virtio_config_readl(vdev, offset - SYBORG_VIRTIO_CONFIG);

    }

    switch(offset >> 2) {

    case SYBORG_VIRTIO_ID:

        ret = SYBORG_ID_VIRTIO;

        break;

    case SYBORG_VIRTIO_DEVTYPE:

        ret = s->id;

        break;

    case SYBORG_VIRTIO_HOST_FEATURES:

        ret = vdev->get_features(vdev);

        ret |= vdev->binding->get_features(s);

        break;

    case SYBORG_VIRTIO_GUEST_FEATURES:

        ret = vdev->guest_features;

        break;

    case SYBORG_VIRTIO_QUEUE_BASE:

        ret = virtio_queue_get_addr(vdev, vdev->queue_sel);

        break;

    case SYBORG_VIRTIO_QUEUE_NUM:

        ret = virtio_queue_get_num(vdev, vdev->queue_sel);

        break;

    case SYBORG_VIRTIO_QUEUE_SEL:

        ret = vdev->queue_sel;

        break;

    case SYBORG_VIRTIO_STATUS:

        ret = vdev->status;

        break;

    case SYBORG_VIRTIO_INT_ENABLE:

        ret = s->int_enable;

        break;

    case SYBORG_VIRTIO_INT_STATUS:

        ret = vdev->isr;

        break;

    default:

        BADF("Bad read offset 0x%x\n", (int)offset);

        return 0;

    }

    return ret;

}


static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq)

{

    uint16_t old, new;

    bool v;

    /* Always notify when queue is empty (when feature acknowledge) */

    if (((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) &&

         !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx)) {

        return true;

    }

    if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {

        return !(vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT);

    }

    v = vq->signalled_used_valid;

    vq->signalled_used_valid = true;

    old = vq->signalled_used;

    new = vq->signalled_used = vring_used_idx(vq);

    return !v || vring_need_event(vring_used_event(vq), new, old);

}


static void guess_mv(ERContext *s)

{

    uint8_t *fixed = s->er_temp_buffer;

#define MV_FROZEN    3

#define MV_CHANGED   2

#define MV_UNCHANGED 1

    const int mb_stride = s->mb_stride;

    const int mb_width  = s->mb_width;

    const int mb_height = s->mb_height;

    int i, depth, num_avail;

    int mb_x, mb_y, mot_step, mot_stride;

    set_mv_strides(s, &mot_step, &mot_stride);

    num_avail = 0;

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

        const int mb_xy = s->mb_index2xy[i];

        int f = 0;

        int error = s->error_status_table[mb_xy];

        if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))

            f = MV_FROZEN; // intra // FIXME check

        if (!(error & ER_MV_ERROR))

            f = MV_FROZEN; // inter with undamaged MV

        fixed[mb_xy] = f;

        if (f == MV_FROZEN)

            num_avail++;

    }

    if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) ||

        num_avail <= mb_width / 2) {

        for (mb_y = 0; mb_y < s->mb_height; mb_y++) {

            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {

                const int mb_xy = mb_x + mb_y * s->mb_stride;

                int mv_dir = (s->last_pic.f && s->last_pic.f->data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD;

                if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))

                    continue;

                if (!(s->error_status_table[mb_xy] & ER_MV_ERROR))

                    continue;

                s->mv[0][0][0] = 0;

                s->mv[0][0][1] = 0;

                s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,

                             mb_x, mb_y, 0, 0);

            }

        }

        return;

    }

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

        int changed, pass, none_left;

        none_left = 1;

        changed   = 1;

        for (pass = 0; (changed || pass < 2) && pass < 10; pass++) {

            int mb_x, mb_y;

            int score_sum = 0;

            changed = 0;

            for (mb_y = 0; mb_y < s->mb_height; mb_y++) {

                for (mb_x = 0; mb_x < s->mb_width; mb_x++) {

                    const int mb_xy        = mb_x + mb_y * s->mb_stride;

                    int mv_predictor[8][2] = { { 0 } };

                    int ref[8]             = { 0 };

                    int pred_count         = 0;

                    int j;

                    int best_score         = 256 * 256 * 256 * 64;

                    int best_pred          = 0;

                    const int mot_index    = (mb_x + mb_y * mot_stride) * mot_step;

                    int prev_x, prev_y, prev_ref;

                    if ((mb_x ^ mb_y ^ pass) & 1)

                        continue;

                    if (fixed[mb_xy] == MV_FROZEN)

                        continue;

                    assert(!IS_INTRA(s->cur_pic.mb_type[mb_xy]));

                    assert(s->last_pic && s->last_pic.f->data[0]);

                    j = 0;

                    if (mb_x > 0             && fixed[mb_xy - 1]         == MV_FROZEN)

                        j = 1;

                    if (mb_x + 1 < mb_width  && fixed[mb_xy + 1]         == MV_FROZEN)

                        j = 1;

                    if (mb_y > 0             && fixed[mb_xy - mb_stride] == MV_FROZEN)

                        j = 1;

                    if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] == MV_FROZEN)

                        j = 1;

                    if (j == 0)

                        continue;

                    j = 0;

                    if (mb_x > 0             && fixed[mb_xy - 1        ] == MV_CHANGED)

                        j = 1;

                    if (mb_x + 1 < mb_width  && fixed[mb_xy + 1        ] == MV_CHANGED)

                        j = 1;

                    if (mb_y > 0             && fixed[mb_xy - mb_stride] == MV_CHANGED)

                        j = 1;

                    if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] == MV_CHANGED)

                        j = 1;

                    if (j == 0 && pass > 1)

                        continue;

                    none_left = 0;

                    if (mb_x > 0 && fixed[mb_xy - 1]) {

                        mv_predictor[pred_count][0] =

                            s->cur_pic.motion_val[0][mot_index - mot_step][0];

                        mv_predictor[pred_count][1] =

                            s->cur_pic.motion_val[0][mot_index - mot_step][1];

                        ref[pred_count] =

                            s->cur_pic.ref_index[0][4 * (mb_xy - 1)];

                        pred_count++;

                    }

                    if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {

                        mv_predictor[pred_count][0] =

                            s->cur_pic.motion_val[0][mot_index + mot_step][0];

                        mv_predictor[pred_count][1] =

                            s->cur_pic.motion_val[0][mot_index + mot_step][1];

                        ref[pred_count] =

                            s->cur_pic.ref_index[0][4 * (mb_xy + 1)];

                        pred_count++;

                    }

                    if (mb_y > 0 && fixed[mb_xy - mb_stride]) {

                        mv_predictor[pred_count][0] =

                            s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][0];

                        mv_predictor[pred_count][1] =

                            s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][1];

                        ref[pred_count] =

                            s->cur_pic.ref_index[0][4 * (mb_xy - s->mb_stride)];

                        pred_count++;

                    }

                    if (mb_y + 1<mb_height && fixed[mb_xy + mb_stride]) {

                        mv_predictor[pred_count][0] =

                            s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][0];

                        mv_predictor[pred_count][1] =

                            s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][1];

                        ref[pred_count] =

                            s->cur_pic.ref_index[0][4 * (mb_xy + s->mb_stride)];

                        pred_count++;

                    }

                    if (pred_count == 0)

                        continue;

                    if (pred_count > 1) {

                        int sum_x = 0, sum_y = 0, sum_r = 0;

                        int max_x, max_y, min_x, min_y, max_r, min_r;

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

                            sum_x += mv_predictor[j][0];

                            sum_y += mv_predictor[j][1];

                            sum_r += ref[j];

                            if (j && ref[j] != ref[j - 1])

                                goto skip_mean_and_median;

                        }

                        /* mean */

                        mv_predictor[pred_count][0] = sum_x / j;

                        mv_predictor[pred_count][1] = sum_y / j;

                                 ref[pred_count]    = sum_r / j;

                        /* median */

                        if (pred_count >= 3) {

                            min_y = min_x = min_r =  99999;

                            max_y = max_x = max_r = -99999;

                        } else {

                            min_x = min_y = max_x = max_y = min_r = max_r = 0;

                        }

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

                            max_x = FFMAX(max_x, mv_predictor[j][0]);

                            max_y = FFMAX(max_y, mv_predictor[j][1]);

                            max_r = FFMAX(max_r, ref[j]);

                            min_x = FFMIN(min_x, mv_predictor[j][0]);

                            min_y = FFMIN(min_y, mv_predictor[j][1]);

                            min_r = FFMIN(min_r, ref[j]);

                        }

                        mv_predictor[pred_count + 1][0] = sum_x - max_x - min_x;

                        mv_predictor[pred_count + 1][1] = sum_y - max_y - min_y;

                                 ref[pred_count + 1]    = sum_r - max_r - min_r;

                        if (pred_count == 4) {

                            mv_predictor[pred_count + 1][0] /= 2;

                            mv_predictor[pred_count + 1][1] /= 2;

                                     ref[pred_count + 1]    /= 2;

                        }

                        pred_count += 2;

                    }

skip_mean_and_median:

                    /* zero MV */

                    pred_count++;

                    if (!fixed[mb_xy]) {

                        if (s->avctx->codec_id == AV_CODEC_ID_H264) {

                            // FIXME

                        } else {

                            ff_thread_await_progress(s->last_pic.tf,

                                                     mb_y, 0);

                        }

                        if (!s->last_pic.motion_val[0] ||

                            !s->last_pic.ref_index[0])

                            goto skip_last_mv;

                        prev_x   = s->last_pic.motion_val[0][mot_index][0];

                        prev_y   = s->last_pic.motion_val[0][mot_index][1];

                        prev_ref = s->last_pic.ref_index[0][4 * mb_xy];

                    } else {

                        prev_x   = s->cur_pic.motion_val[0][mot_index][0];

                        prev_y   = s->cur_pic.motion_val[0][mot_index][1];

                        prev_ref = s->cur_pic.ref_index[0][4 * mb_xy];

                    }

                    /* last MV */

                    mv_predictor[pred_count][0] = prev_x;

                    mv_predictor[pred_count][1] = prev_y;

                             ref[pred_count]    = prev_ref;

                    pred_count++;

skip_last_mv:

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

                        int *linesize = s->cur_pic.f->linesize;

                        int score = 0;

                        uint8_t *src = s->cur_pic.f->data[0] +

                                       mb_x * 16 + mb_y * 16 * linesize[0];

                        s->cur_pic.motion_val[0][mot_index][0] =

                            s->mv[0][0][0] = mv_predictor[j][0];

                        s->cur_pic.motion_val[0][mot_index][1] =

                            s->mv[0][0][1] = mv_predictor[j][1];

                        // predictor intra or otherwise not available

                        if (ref[j] < 0)

                            continue;

                        s->decode_mb(s->opaque, ref[j], MV_DIR_FORWARD,

                                     MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);

                        if (mb_x > 0 && fixed[mb_xy - 1]) {

                            int k;

                            for (k = 0; k < 16; k++)

                                score += FFABS(src[k * linesize[0] - 1] -

                                               src[k * linesize[0]]);

                        }

                        if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {

                            int k;

                            for (k = 0; k < 16; k++)

                                score += FFABS(src[k * linesize[0] + 15] -

                                               src[k * linesize[0] + 16]);

                        }

                        if (mb_y > 0 && fixed[mb_xy - mb_stride]) {

                            int k;

                            for (k = 0; k < 16; k++)

                                score += FFABS(src[k - linesize[0]] - src[k]);

                        }

                        if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride]) {

                            int k;

                            for (k = 0; k < 16; k++)

                                score += FFABS(src[k + linesize[0] * 15] -

                                               src[k + linesize[0] * 16]);

                        }

                        if (score <= best_score) { // <= will favor the last MV

                            best_score = score;

                            best_pred  = j;

                        }

                    }

                    score_sum += best_score;

                    s->mv[0][0][0] = mv_predictor[best_pred][0];

                    s->mv[0][0][1] = mv_predictor[best_pred][1];

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

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

                            s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];

                            s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];

                        }

                    s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD,

                                 MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);

                    if (s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y) {

                        fixed[mb_xy] = MV_CHANGED;

                        changed++;

                    } else

                        fixed[mb_xy] = MV_UNCHANGED;

                }

            }

        }

        if (none_left)

            return;

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

            int mb_xy = s->mb_index2xy[i];

            if (fixed[mb_xy])

                fixed[mb_xy] = MV_FROZEN;

        }

    }

}


void qtest_qmp_discard_response(QTestState *s, const char *fmt, ...)

{

    va_list ap;

    va_start(ap, fmt);

    qtest_qmpv_discard_response(s, fmt, ap);

    va_end(ap);

}


static MTPData *usb_mtp_get_partial_object(MTPState *s, MTPControl *c,

                                           MTPObject *o)

{

    MTPData *d = usb_mtp_data_alloc(c);

    off_t offset;

    trace_usb_mtp_op_get_partial_object(s->dev.addr, o->handle, o->path,

                                        c->argv[1], c->argv[2]);

    d->fd = open(o->path, O_RDONLY);

    if (d->fd == -1) {

        return NULL;

    }

    offset = c->argv[1];

    if (offset > o->stat.st_size) {

        offset = o->stat.st_size;

    }

    lseek(d->fd, offset, SEEK_SET);

    d->length = c->argv[2];

    if (d->length > o->stat.st_size - offset) {

        d->length = o->stat.st_size - offset;

    }

    return d;

}


static void set_int16(Object *obj, Visitor *v, void *opaque,

                      const char *name, Error **errp)

{

    DeviceState *dev = DEVICE(obj);

    Property *prop = opaque;

    int16_t *ptr = qdev_get_prop_ptr(dev, prop);

    Error *local_err = NULL;

    int64_t value;

    if (dev->state != DEV_STATE_CREATED) {

        error_set(errp, QERR_PERMISSION_DENIED);

        return;

    }

    visit_type_int(v, &value, name, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        return;

    }

    if (value > prop->info->min && value <= prop->info->max) {

        *ptr = value;

    } else {

        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,

                  dev->id?:"", name, value, prop->info->min,

                  prop->info->max);

    }

}