static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)

{

    int32_t disp21, disp16, disp12 __attribute__((unused));

    uint16_t fn11;

    uint8_t opc, ra, rb, rc, fpfn, fn7, lit;

    bool islit, real_islit;

    TCGv va, vb, vc, tmp, tmp2;

    TCGv_i32 t32;

    DisasJumpType ret;

    /* Decode all instruction fields */

    opc = extract32(insn, 26, 6);

    ra = extract32(insn, 21, 5);

    rb = extract32(insn, 16, 5);

    rc = extract32(insn, 0, 5);

    real_islit = islit = extract32(insn, 12, 1);

    lit = extract32(insn, 13, 8);

    disp21 = sextract32(insn, 0, 21);

    disp16 = sextract32(insn, 0, 16);

    disp12 = sextract32(insn, 0, 12);

    fn11 = extract32(insn, 5, 11);

    fpfn = extract32(insn, 5, 6);

    fn7 = extract32(insn, 5, 7);

    if (rb == 31 && !islit) {

        islit = true;

        lit = 0;

    }

    ret = DISAS_NEXT;

    switch (opc) {

    case 0x00:

        /* CALL_PAL */

        ret = gen_call_pal(ctx, insn & 0x03ffffff);

        break;

    case 0x01:

        /* OPC01 */

        goto invalid_opc;

    case 0x02:

        /* OPC02 */

        goto invalid_opc;

    case 0x03:

        /* OPC03 */

        goto invalid_opc;

    case 0x04:

        /* OPC04 */

        goto invalid_opc;

    case 0x05:

        /* OPC05 */

        goto invalid_opc;

    case 0x06:

        /* OPC06 */

        goto invalid_opc;

    case 0x07:

        /* OPC07 */

        goto invalid_opc;

    case 0x09:

        /* LDAH */

        disp16 = (uint32_t)disp16 << 16;

        /* fall through */

    case 0x08:

        /* LDA */

        va = dest_gpr(ctx, ra);

        /* It's worth special-casing immediate loads.  */

        if (rb == 31) {

            tcg_gen_movi_i64(va, disp16);

        } else {

            tcg_gen_addi_i64(va, load_gpr(ctx, rb), disp16);

        }

        break;

    case 0x0A:

        /* LDBU */

        REQUIRE_AMASK(BWX);

        gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);

        break;

    case 0x0B:

        /* LDQ_U */

        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);

        break;

    case 0x0C:

        /* LDWU */

        REQUIRE_AMASK(BWX);

        gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);

        break;

    case 0x0D:

        /* STW */

        REQUIRE_AMASK(BWX);

        gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0);

        break;

    case 0x0E:

        /* STB */

        REQUIRE_AMASK(BWX);

        gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0);

        break;

    case 0x0F:

        /* STQ_U */

        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1);

        break;

    case 0x10:

        vc = dest_gpr(ctx, rc);

        vb = load_gpr_lit(ctx, rb, lit, islit);

        if (ra == 31) {

            if (fn7 == 0x00) {

                /* Special case ADDL as SEXTL.  */

                tcg_gen_ext32s_i64(vc, vb);

                break;

            }

            if (fn7 == 0x29) {

                /* Special case SUBQ as NEGQ.  */

                tcg_gen_neg_i64(vc, vb);

                break;

            }

        }

        va = load_gpr(ctx, ra);

        switch (fn7) {

        case 0x00:

            /* ADDL */

            tcg_gen_add_i64(vc, va, vb);

            tcg_gen_ext32s_i64(vc, vc);

            break;

        case 0x02:

            /* S4ADDL */

            tmp = tcg_temp_new();

            tcg_gen_shli_i64(tmp, va, 2);

            tcg_gen_add_i64(tmp, tmp, vb);

            tcg_gen_ext32s_i64(vc, tmp);

            tcg_temp_free(tmp);

            break;

        case 0x09:

            /* SUBL */

            tcg_gen_sub_i64(vc, va, vb);

            tcg_gen_ext32s_i64(vc, vc);

            break;

        case 0x0B:

            /* S4SUBL */

            tmp = tcg_temp_new();

            tcg_gen_shli_i64(tmp, va, 2);

            tcg_gen_sub_i64(tmp, tmp, vb);

            tcg_gen_ext32s_i64(vc, tmp);

            tcg_temp_free(tmp);

            break;

        case 0x0F:

            /* CMPBGE */

            if (ra == 31) {

                /* Special case 0 >= X as X == 0.  */

                gen_helper_cmpbe0(vc, vb);

            } else {

                gen_helper_cmpbge(vc, va, vb);

            }

            break;

        case 0x12:

            /* S8ADDL */

            tmp = tcg_temp_new();

            tcg_gen_shli_i64(tmp, va, 3);

            tcg_gen_add_i64(tmp, tmp, vb);

            tcg_gen_ext32s_i64(vc, tmp);

            tcg_temp_free(tmp);

            break;

        case 0x1B:

            /* S8SUBL */

            tmp = tcg_temp_new();

            tcg_gen_shli_i64(tmp, va, 3);

            tcg_gen_sub_i64(tmp, tmp, vb);

            tcg_gen_ext32s_i64(vc, tmp);

            tcg_temp_free(tmp);

            break;

        case 0x1D:

            /* CMPULT */

            tcg_gen_setcond_i64(TCG_COND_LTU, vc, va, vb);

            break;

        case 0x20:

            /* ADDQ */

            tcg_gen_add_i64(vc, va, vb);

            break;

        case 0x22:

            /* S4ADDQ */

            tmp = tcg_temp_new();

            tcg_gen_shli_i64(tmp, va, 2);

            tcg_gen_add_i64(vc, tmp, vb);

            tcg_temp_free(tmp);

            break;

        case 0x29:

            /* SUBQ */

            tcg_gen_sub_i64(vc, va, vb);

            break;

        case 0x2B:

            /* S4SUBQ */

            tmp = tcg_temp_new();

            tcg_gen_shli_i64(tmp, va, 2);

            tcg_gen_sub_i64(vc, tmp, vb);

            tcg_temp_free(tmp);

            break;

        case 0x2D:

            /* CMPEQ */

            tcg_gen_setcond_i64(TCG_COND_EQ, vc, va, vb);

            break;

        case 0x32:

            /* S8ADDQ */

            tmp = tcg_temp_new();

            tcg_gen_shli_i64(tmp, va, 3);

            tcg_gen_add_i64(vc, tmp, vb);

            tcg_temp_free(tmp);

            break;

        case 0x3B:

            /* S8SUBQ */

            tmp = tcg_temp_new();

            tcg_gen_shli_i64(tmp, va, 3);

            tcg_gen_sub_i64(vc, tmp, vb);

            tcg_temp_free(tmp);

            break;

        case 0x3D:

            /* CMPULE */

            tcg_gen_setcond_i64(TCG_COND_LEU, vc, va, vb);

            break;

        case 0x40:

            /* ADDL/V */

            tmp = tcg_temp_new();

            tcg_gen_ext32s_i64(tmp, va);

            tcg_gen_ext32s_i64(vc, vb);

            tcg_gen_add_i64(tmp, tmp, vc);

            tcg_gen_ext32s_i64(vc, tmp);

            gen_helper_check_overflow(cpu_env, vc, tmp);

            tcg_temp_free(tmp);

            break;

        case 0x49:

            /* SUBL/V */

            tmp = tcg_temp_new();

            tcg_gen_ext32s_i64(tmp, va);

            tcg_gen_ext32s_i64(vc, vb);

            tcg_gen_sub_i64(tmp, tmp, vc);

            tcg_gen_ext32s_i64(vc, tmp);

            gen_helper_check_overflow(cpu_env, vc, tmp);

            tcg_temp_free(tmp);

            break;

        case 0x4D:

            /* CMPLT */

            tcg_gen_setcond_i64(TCG_COND_LT, vc, va, vb);

            break;

        case 0x60:

            /* ADDQ/V */

            tmp = tcg_temp_new();

            tmp2 = tcg_temp_new();

            tcg_gen_eqv_i64(tmp, va, vb);

            tcg_gen_mov_i64(tmp2, va);

            tcg_gen_add_i64(vc, va, vb);

            tcg_gen_xor_i64(tmp2, tmp2, vc);

            tcg_gen_and_i64(tmp, tmp, tmp2);

            tcg_gen_shri_i64(tmp, tmp, 63);

            tcg_gen_movi_i64(tmp2, 0);

            gen_helper_check_overflow(cpu_env, tmp, tmp2);

            tcg_temp_free(tmp);

            tcg_temp_free(tmp2);

            break;

        case 0x69:

            /* SUBQ/V */

            tmp = tcg_temp_new();

            tmp2 = tcg_temp_new();

            tcg_gen_xor_i64(tmp, va, vb);

            tcg_gen_mov_i64(tmp2, va);

            tcg_gen_sub_i64(vc, va, vb);

            tcg_gen_xor_i64(tmp2, tmp2, vc);

            tcg_gen_and_i64(tmp, tmp, tmp2);

            tcg_gen_shri_i64(tmp, tmp, 63);

            tcg_gen_movi_i64(tmp2, 0);

            gen_helper_check_overflow(cpu_env, tmp, tmp2);

            tcg_temp_free(tmp);

            tcg_temp_free(tmp2);

            break;

        case 0x6D:

            /* CMPLE */

            tcg_gen_setcond_i64(TCG_COND_LE, vc, va, vb);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x11:

        if (fn7 == 0x20) {

            if (rc == 31) {

                /* Special case BIS as NOP.  */

                break;

            }

            if (ra == 31) {

                /* Special case BIS as MOV.  */

                vc = dest_gpr(ctx, rc);

                if (islit) {

                    tcg_gen_movi_i64(vc, lit);

                } else {

                    tcg_gen_mov_i64(vc, load_gpr(ctx, rb));

                }

                break;

            }

        }

        vc = dest_gpr(ctx, rc);

        vb = load_gpr_lit(ctx, rb, lit, islit);

        if (fn7 == 0x28 && ra == 31) {

            /* Special case ORNOT as NOT.  */

            tcg_gen_not_i64(vc, vb);

            break;

        }

        va = load_gpr(ctx, ra);

        switch (fn7) {

        case 0x00:

            /* AND */

            tcg_gen_and_i64(vc, va, vb);

            break;

        case 0x08:

            /* BIC */

            tcg_gen_andc_i64(vc, va, vb);

            break;

        case 0x14:

            /* CMOVLBS */

            tmp = tcg_temp_new();

            tcg_gen_andi_i64(tmp, va, 1);

            tcg_gen_movcond_i64(TCG_COND_NE, vc, tmp, load_zero(ctx),

                                vb, load_gpr(ctx, rc));

            tcg_temp_free(tmp);

            break;

        case 0x16:

            /* CMOVLBC */

            tmp = tcg_temp_new();

            tcg_gen_andi_i64(tmp, va, 1);

            tcg_gen_movcond_i64(TCG_COND_EQ, vc, tmp, load_zero(ctx),

                                vb, load_gpr(ctx, rc));

            tcg_temp_free(tmp);

            break;

        case 0x20:

            /* BIS */

            tcg_gen_or_i64(vc, va, vb);

            break;

        case 0x24:

            /* CMOVEQ */

            tcg_gen_movcond_i64(TCG_COND_EQ, vc, va, load_zero(ctx),

                                vb, load_gpr(ctx, rc));

            break;

        case 0x26:

            /* CMOVNE */

            tcg_gen_movcond_i64(TCG_COND_NE, vc, va, load_zero(ctx),

                                vb, load_gpr(ctx, rc));

            break;

        case 0x28:

            /* ORNOT */

            tcg_gen_orc_i64(vc, va, vb);

            break;

        case 0x40:

            /* XOR */

            tcg_gen_xor_i64(vc, va, vb);

            break;

        case 0x44:

            /* CMOVLT */

            tcg_gen_movcond_i64(TCG_COND_LT, vc, va, load_zero(ctx),

                                vb, load_gpr(ctx, rc));

            break;

        case 0x46:

            /* CMOVGE */

            tcg_gen_movcond_i64(TCG_COND_GE, vc, va, load_zero(ctx),

                                vb, load_gpr(ctx, rc));

            break;

        case 0x48:

            /* EQV */

            tcg_gen_eqv_i64(vc, va, vb);

            break;

        case 0x61:

            /* AMASK */

            REQUIRE_REG_31(ra);

            tcg_gen_andi_i64(vc, vb, ~ctx->amask);

            break;

        case 0x64:

            /* CMOVLE */

            tcg_gen_movcond_i64(TCG_COND_LE, vc, va, load_zero(ctx),

                                vb, load_gpr(ctx, rc));

            break;

        case 0x66:

            /* CMOVGT */

            tcg_gen_movcond_i64(TCG_COND_GT, vc, va, load_zero(ctx),

                                vb, load_gpr(ctx, rc));

            break;

        case 0x6C:

            /* IMPLVER */

            REQUIRE_REG_31(ra);

            tcg_gen_movi_i64(vc, ctx->implver);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x12:

        vc = dest_gpr(ctx, rc);

        va = load_gpr(ctx, ra);

        switch (fn7) {

        case 0x02:

            /* MSKBL */

            gen_msk_l(ctx, vc, va, rb, islit, lit, 0x01);

            break;

        case 0x06:

            /* EXTBL */

            gen_ext_l(ctx, vc, va, rb, islit, lit, 0x01);

            break;

        case 0x0B:

            /* INSBL */

            gen_ins_l(ctx, vc, va, rb, islit, lit, 0x01);

            break;

        case 0x12:

            /* MSKWL */

            gen_msk_l(ctx, vc, va, rb, islit, lit, 0x03);

            break;

        case 0x16:

            /* EXTWL */

            gen_ext_l(ctx, vc, va, rb, islit, lit, 0x03);

            break;

        case 0x1B:

            /* INSWL */

            gen_ins_l(ctx, vc, va, rb, islit, lit, 0x03);

            break;

        case 0x22:

            /* MSKLL */

            gen_msk_l(ctx, vc, va, rb, islit, lit, 0x0f);

            break;

        case 0x26:

            /* EXTLL */

            gen_ext_l(ctx, vc, va, rb, islit, lit, 0x0f);

            break;

        case 0x2B:

            /* INSLL */

            gen_ins_l(ctx, vc, va, rb, islit, lit, 0x0f);

            break;

        case 0x30:

            /* ZAP */

            if (islit) {

                gen_zapnoti(vc, va, ~lit);

            } else {

                gen_helper_zap(vc, va, load_gpr(ctx, rb));

            }

            break;

        case 0x31:

            /* ZAPNOT */

            if (islit) {

                gen_zapnoti(vc, va, lit);

            } else {

                gen_helper_zapnot(vc, va, load_gpr(ctx, rb));

            }

            break;

        case 0x32:

            /* MSKQL */

            gen_msk_l(ctx, vc, va, rb, islit, lit, 0xff);

            break;

        case 0x34:

            /* SRL */

            if (islit) {

                tcg_gen_shri_i64(vc, va, lit & 0x3f);

            } else {

                tmp = tcg_temp_new();

                vb = load_gpr(ctx, rb);

                tcg_gen_andi_i64(tmp, vb, 0x3f);

                tcg_gen_shr_i64(vc, va, tmp);

                tcg_temp_free(tmp);

            }

            break;

        case 0x36:

            /* EXTQL */

            gen_ext_l(ctx, vc, va, rb, islit, lit, 0xff);

            break;

        case 0x39:

            /* SLL */

            if (islit) {

                tcg_gen_shli_i64(vc, va, lit & 0x3f);

            } else {

                tmp = tcg_temp_new();

                vb = load_gpr(ctx, rb);

                tcg_gen_andi_i64(tmp, vb, 0x3f);

                tcg_gen_shl_i64(vc, va, tmp);

                tcg_temp_free(tmp);

            }

            break;

        case 0x3B:

            /* INSQL */

            gen_ins_l(ctx, vc, va, rb, islit, lit, 0xff);

            break;

        case 0x3C:

            /* SRA */

            if (islit) {

                tcg_gen_sari_i64(vc, va, lit & 0x3f);

            } else {

                tmp = tcg_temp_new();

                vb = load_gpr(ctx, rb);

                tcg_gen_andi_i64(tmp, vb, 0x3f);

                tcg_gen_sar_i64(vc, va, tmp);

                tcg_temp_free(tmp);

            }

            break;

        case 0x52:

            /* MSKWH */

            gen_msk_h(ctx, vc, va, rb, islit, lit, 0x03);

            break;

        case 0x57:

            /* INSWH */

            gen_ins_h(ctx, vc, va, rb, islit, lit, 0x03);

            break;

        case 0x5A:

            /* EXTWH */

            gen_ext_h(ctx, vc, va, rb, islit, lit, 0x03);

            break;

        case 0x62:

            /* MSKLH */

            gen_msk_h(ctx, vc, va, rb, islit, lit, 0x0f);

            break;

        case 0x67:

            /* INSLH */

            gen_ins_h(ctx, vc, va, rb, islit, lit, 0x0f);

            break;

        case 0x6A:

            /* EXTLH */

            gen_ext_h(ctx, vc, va, rb, islit, lit, 0x0f);

            break;

        case 0x72:

            /* MSKQH */

            gen_msk_h(ctx, vc, va, rb, islit, lit, 0xff);

            break;

        case 0x77:

            /* INSQH */

            gen_ins_h(ctx, vc, va, rb, islit, lit, 0xff);

            break;

        case 0x7A:

            /* EXTQH */

            gen_ext_h(ctx, vc, va, rb, islit, lit, 0xff);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x13:

        vc = dest_gpr(ctx, rc);

        vb = load_gpr_lit(ctx, rb, lit, islit);

        va = load_gpr(ctx, ra);

        switch (fn7) {

        case 0x00:

            /* MULL */

            tcg_gen_mul_i64(vc, va, vb);

            tcg_gen_ext32s_i64(vc, vc);

            break;

        case 0x20:

            /* MULQ */

            tcg_gen_mul_i64(vc, va, vb);

            break;

        case 0x30:

            /* UMULH */

            tmp = tcg_temp_new();

            tcg_gen_mulu2_i64(tmp, vc, va, vb);

            tcg_temp_free(tmp);

            break;

        case 0x40:

            /* MULL/V */

            tmp = tcg_temp_new();

            tcg_gen_ext32s_i64(tmp, va);

            tcg_gen_ext32s_i64(vc, vb);

            tcg_gen_mul_i64(tmp, tmp, vc);

            tcg_gen_ext32s_i64(vc, tmp);

            gen_helper_check_overflow(cpu_env, vc, tmp);

            tcg_temp_free(tmp);

            break;

        case 0x60:

            /* MULQ/V */

            tmp = tcg_temp_new();

            tmp2 = tcg_temp_new();

            tcg_gen_muls2_i64(vc, tmp, va, vb);

            tcg_gen_sari_i64(tmp2, vc, 63);

            gen_helper_check_overflow(cpu_env, tmp, tmp2);

            tcg_temp_free(tmp);

            tcg_temp_free(tmp2);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x14:

        REQUIRE_AMASK(FIX);

        vc = dest_fpr(ctx, rc);

        switch (fpfn) { /* fn11 & 0x3F */

        case 0x04:

            /* ITOFS */

            REQUIRE_REG_31(rb);

            t32 = tcg_temp_new_i32();

            va = load_gpr(ctx, ra);

            tcg_gen_extrl_i64_i32(t32, va);

            gen_helper_memory_to_s(vc, t32);

            tcg_temp_free_i32(t32);

            break;

        case 0x0A:

            /* SQRTF */

            REQUIRE_REG_31(ra);

            vb = load_fpr(ctx, rb);

            gen_helper_sqrtf(vc, cpu_env, vb);

            break;

        case 0x0B:

            /* SQRTS */

            REQUIRE_REG_31(ra);

            gen_sqrts(ctx, rb, rc, fn11);

            break;

        case 0x14:

            /* ITOFF */

            REQUIRE_REG_31(rb);

            t32 = tcg_temp_new_i32();

            va = load_gpr(ctx, ra);

            tcg_gen_extrl_i64_i32(t32, va);

            gen_helper_memory_to_f(vc, t32);

            tcg_temp_free_i32(t32);

            break;

        case 0x24:

            /* ITOFT */

            REQUIRE_REG_31(rb);

            va = load_gpr(ctx, ra);

            tcg_gen_mov_i64(vc, va);

            break;

        case 0x2A:

            /* SQRTG */

            REQUIRE_REG_31(ra);

            vb = load_fpr(ctx, rb);

            gen_helper_sqrtg(vc, cpu_env, vb);

            break;

        case 0x02B:

            /* SQRTT */

            REQUIRE_REG_31(ra);

            gen_sqrtt(ctx, rb, rc, fn11);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x15:

        /* VAX floating point */

        /* XXX: rounding mode and trap are ignored (!) */

        vc = dest_fpr(ctx, rc);

        vb = load_fpr(ctx, rb);

        va = load_fpr(ctx, ra);

        switch (fpfn) { /* fn11 & 0x3F */

        case 0x00:

            /* ADDF */

            gen_helper_addf(vc, cpu_env, va, vb);

            break;

        case 0x01:

            /* SUBF */

            gen_helper_subf(vc, cpu_env, va, vb);

            break;

        case 0x02:

            /* MULF */

            gen_helper_mulf(vc, cpu_env, va, vb);

            break;

        case 0x03:

            /* DIVF */

            gen_helper_divf(vc, cpu_env, va, vb);

            break;

        case 0x1E:

            /* CVTDG -- TODO */

            REQUIRE_REG_31(ra);

            goto invalid_opc;

        case 0x20:

            /* ADDG */

            gen_helper_addg(vc, cpu_env, va, vb);

            break;

        case 0x21:

            /* SUBG */

            gen_helper_subg(vc, cpu_env, va, vb);

            break;

        case 0x22:

            /* MULG */

            gen_helper_mulg(vc, cpu_env, va, vb);

            break;

        case 0x23:

            /* DIVG */

            gen_helper_divg(vc, cpu_env, va, vb);

            break;

        case 0x25:

            /* CMPGEQ */

            gen_helper_cmpgeq(vc, cpu_env, va, vb);

            break;

        case 0x26:

            /* CMPGLT */

            gen_helper_cmpglt(vc, cpu_env, va, vb);

            break;

        case 0x27:

            /* CMPGLE */

            gen_helper_cmpgle(vc, cpu_env, va, vb);

            break;

        case 0x2C:

            /* CVTGF */

            REQUIRE_REG_31(ra);

            gen_helper_cvtgf(vc, cpu_env, vb);

            break;

        case 0x2D:

            /* CVTGD -- TODO */

            REQUIRE_REG_31(ra);

            goto invalid_opc;

        case 0x2F:

            /* CVTGQ */

            REQUIRE_REG_31(ra);

            gen_helper_cvtgq(vc, cpu_env, vb);

            break;

        case 0x3C:

            /* CVTQF */

            REQUIRE_REG_31(ra);

            gen_helper_cvtqf(vc, cpu_env, vb);

            break;

        case 0x3E:

            /* CVTQG */

            REQUIRE_REG_31(ra);

            gen_helper_cvtqg(vc, cpu_env, vb);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x16:

        /* IEEE floating-point */

        switch (fpfn) { /* fn11 & 0x3F */

        case 0x00:

            /* ADDS */

            gen_adds(ctx, ra, rb, rc, fn11);

            break;

        case 0x01:

            /* SUBS */

            gen_subs(ctx, ra, rb, rc, fn11);

            break;

        case 0x02:

            /* MULS */

            gen_muls(ctx, ra, rb, rc, fn11);

            break;

        case 0x03:

            /* DIVS */

            gen_divs(ctx, ra, rb, rc, fn11);

            break;

        case 0x20:

            /* ADDT */

            gen_addt(ctx, ra, rb, rc, fn11);

            break;

        case 0x21:

            /* SUBT */

            gen_subt(ctx, ra, rb, rc, fn11);

            break;

        case 0x22:

            /* MULT */

            gen_mult(ctx, ra, rb, rc, fn11);

            break;

        case 0x23:

            /* DIVT */

            gen_divt(ctx, ra, rb, rc, fn11);

            break;

        case 0x24:

            /* CMPTUN */

            gen_cmptun(ctx, ra, rb, rc, fn11);

            break;

        case 0x25:

            /* CMPTEQ */

            gen_cmpteq(ctx, ra, rb, rc, fn11);

            break;

        case 0x26:

            /* CMPTLT */

            gen_cmptlt(ctx, ra, rb, rc, fn11);

            break;

        case 0x27:

            /* CMPTLE */

            gen_cmptle(ctx, ra, rb, rc, fn11);

            break;

        case 0x2C:

            REQUIRE_REG_31(ra);

            if (fn11 == 0x2AC || fn11 == 0x6AC) {

                /* CVTST */

                gen_cvtst(ctx, rb, rc, fn11);

            } else {

                /* CVTTS */

                gen_cvtts(ctx, rb, rc, fn11);

            }

            break;

        case 0x2F:

            /* CVTTQ */

            REQUIRE_REG_31(ra);

            gen_cvttq(ctx, rb, rc, fn11);

            break;

        case 0x3C:

            /* CVTQS */

            REQUIRE_REG_31(ra);

            gen_cvtqs(ctx, rb, rc, fn11);

            break;

        case 0x3E:

            /* CVTQT */

            REQUIRE_REG_31(ra);

            gen_cvtqt(ctx, rb, rc, fn11);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x17:

        switch (fn11) {

        case 0x010:

            /* CVTLQ */

            REQUIRE_REG_31(ra);

            vc = dest_fpr(ctx, rc);

            vb = load_fpr(ctx, rb);

            gen_cvtlq(vc, vb);

            break;

        case 0x020:

            /* CPYS */

            if (rc == 31) {

                /* Special case CPYS as FNOP.  */

            } else {

                vc = dest_fpr(ctx, rc);

                va = load_fpr(ctx, ra);

                if (ra == rb) {

                    /* Special case CPYS as FMOV.  */

                    tcg_gen_mov_i64(vc, va);

                } else {

                    vb = load_fpr(ctx, rb);

                    gen_cpy_mask(vc, va, vb, 0, 0x8000000000000000ULL);

                }

            }

            break;

        case 0x021:

            /* CPYSN */

            vc = dest_fpr(ctx, rc);

            vb = load_fpr(ctx, rb);

            va = load_fpr(ctx, ra);

            gen_cpy_mask(vc, va, vb, 1, 0x8000000000000000ULL);

            break;

        case 0x022:

            /* CPYSE */

            vc = dest_fpr(ctx, rc);

            vb = load_fpr(ctx, rb);

            va = load_fpr(ctx, ra);

            gen_cpy_mask(vc, va, vb, 0, 0xFFF0000000000000ULL);

            break;

        case 0x024:

            /* MT_FPCR */

            va = load_fpr(ctx, ra);

            gen_helper_store_fpcr(cpu_env, va);

            if (ctx->tb_rm == QUAL_RM_D) {

                /* Re-do the copy of the rounding mode to fp_status

                   the next time we use dynamic rounding.  */

                ctx->tb_rm = -1;

            }

            break;

        case 0x025:

            /* MF_FPCR */

            va = dest_fpr(ctx, ra);

            gen_helper_load_fpcr(va, cpu_env);

            break;

        case 0x02A:

            /* FCMOVEQ */

            gen_fcmov(ctx, TCG_COND_EQ, ra, rb, rc);

            break;

        case 0x02B:

            /* FCMOVNE */

            gen_fcmov(ctx, TCG_COND_NE, ra, rb, rc);

            break;

        case 0x02C:

            /* FCMOVLT */

            gen_fcmov(ctx, TCG_COND_LT, ra, rb, rc);

            break;

        case 0x02D:

            /* FCMOVGE */

            gen_fcmov(ctx, TCG_COND_GE, ra, rb, rc);

            break;

        case 0x02E:

            /* FCMOVLE */

            gen_fcmov(ctx, TCG_COND_LE, ra, rb, rc);

            break;

        case 0x02F:

            /* FCMOVGT */

            gen_fcmov(ctx, TCG_COND_GT, ra, rb, rc);

            break;

        case 0x030: /* CVTQL */

        case 0x130: /* CVTQL/V */

        case 0x530: /* CVTQL/SV */

            REQUIRE_REG_31(ra);

            vc = dest_fpr(ctx, rc);

            vb = load_fpr(ctx, rb);

            gen_helper_cvtql(vc, cpu_env, vb);

            gen_fp_exc_raise(rc, fn11);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x18:

        switch ((uint16_t)disp16) {

        case 0x0000:

            /* TRAPB */

            /* No-op.  */

            break;

        case 0x0400:

            /* EXCB */

            /* No-op.  */

            break;

        case 0x4000:

            /* MB */

            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);

            break;

        case 0x4400:

            /* WMB */

            tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);

            break;

        case 0x8000:

            /* FETCH */

            /* No-op */

            break;

        case 0xA000:

            /* FETCH_M */

            /* No-op */

            break;

        case 0xC000:

            /* RPCC */

            va = dest_gpr(ctx, ra);

            if (ctx->base.tb->cflags & CF_USE_ICOUNT) {

                gen_io_start();

                gen_helper_load_pcc(va, cpu_env);

                gen_io_end();

                ret = DISAS_PC_STALE;

            } else {

                gen_helper_load_pcc(va, cpu_env);

            }

            break;

        case 0xE000:

            /* RC */

            gen_rx(ctx, ra, 0);

            break;

        case 0xE800:

            /* ECB */

            break;

        case 0xF000:

            /* RS */

            gen_rx(ctx, ra, 1);

            break;

        case 0xF800:

            /* WH64 */

            /* No-op */

            break;

        case 0xFC00:

            /* WH64EN */

            /* No-op */

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x19:

        /* HW_MFPR (PALcode) */

#ifndef CONFIG_USER_ONLY

        REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);

        va = dest_gpr(ctx, ra);

        ret = gen_mfpr(ctx, va, insn & 0xffff);

        break;

#else

        goto invalid_opc;

#endif

    case 0x1A:

        /* JMP, JSR, RET, JSR_COROUTINE.  These only differ by the branch

           prediction stack action, which of course we don't implement.  */

        vb = load_gpr(ctx, rb);

        tcg_gen_andi_i64(cpu_pc, vb, ~3);

        if (ra != 31) {

            tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next);

        }

        ret = DISAS_PC_UPDATED;

        break;

    case 0x1B:

        /* HW_LD (PALcode) */

#ifndef CONFIG_USER_ONLY

        REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);

        {

            TCGv addr = tcg_temp_new();

            vb = load_gpr(ctx, rb);

            va = dest_gpr(ctx, ra);

            tcg_gen_addi_i64(addr, vb, disp12);

            switch ((insn >> 12) & 0xF) {

            case 0x0:

                /* Longword physical access (hw_ldl/p) */

                tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LESL);

                break;

            case 0x1:

                /* Quadword physical access (hw_ldq/p) */

                tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEQ);

                break;

            case 0x2:

                /* Longword physical access with lock (hw_ldl_l/p) */

                gen_qemu_ldl_l(va, addr, MMU_PHYS_IDX);

                break;

            case 0x3:

                /* Quadword physical access with lock (hw_ldq_l/p) */

                gen_qemu_ldq_l(va, addr, MMU_PHYS_IDX);

                break;

            case 0x4:

                /* Longword virtual PTE fetch (hw_ldl/v) */

                goto invalid_opc;

            case 0x5:

                /* Quadword virtual PTE fetch (hw_ldq/v) */

                goto invalid_opc;

                break;

            case 0x6:

                /* Invalid */

                goto invalid_opc;

            case 0x7:

                /* Invaliid */

                goto invalid_opc;

            case 0x8:

                /* Longword virtual access (hw_ldl) */

                goto invalid_opc;

            case 0x9:

                /* Quadword virtual access (hw_ldq) */

                goto invalid_opc;

            case 0xA:

                /* Longword virtual access with protection check (hw_ldl/w) */

                tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX, MO_LESL);

                break;

            case 0xB:

                /* Quadword virtual access with protection check (hw_ldq/w) */

                tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX, MO_LEQ);

                break;

            case 0xC:

                /* Longword virtual access with alt access mode (hw_ldl/a)*/

                goto invalid_opc;

            case 0xD:

                /* Quadword virtual access with alt access mode (hw_ldq/a) */

                goto invalid_opc;

            case 0xE:

                /* Longword virtual access with alternate access mode and

                   protection checks (hw_ldl/wa) */

                tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX, MO_LESL);

                break;

            case 0xF:

                /* Quadword virtual access with alternate access mode and

                   protection checks (hw_ldq/wa) */

                tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX, MO_LEQ);

                break;

            }

            tcg_temp_free(addr);

            break;

        }

#else

        goto invalid_opc;

#endif

    case 0x1C:

        vc = dest_gpr(ctx, rc);

        if (fn7 == 0x70) {

            /* FTOIT */

            REQUIRE_AMASK(FIX);

            REQUIRE_REG_31(rb);

            va = load_fpr(ctx, ra);

            tcg_gen_mov_i64(vc, va);

            break;

        } else if (fn7 == 0x78) {

            /* FTOIS */

            REQUIRE_AMASK(FIX);

            REQUIRE_REG_31(rb);

            t32 = tcg_temp_new_i32();

            va = load_fpr(ctx, ra);

            gen_helper_s_to_memory(t32, va);

            tcg_gen_ext_i32_i64(vc, t32);

            tcg_temp_free_i32(t32);

            break;

        }

        vb = load_gpr_lit(ctx, rb, lit, islit);

        switch (fn7) {

        case 0x00:

            /* SEXTB */

            REQUIRE_AMASK(BWX);

            REQUIRE_REG_31(ra);

            tcg_gen_ext8s_i64(vc, vb);

            break;

        case 0x01:

            /* SEXTW */

            REQUIRE_AMASK(BWX);

            REQUIRE_REG_31(ra);

            tcg_gen_ext16s_i64(vc, vb);

            break;

        case 0x30:

            /* CTPOP */

            REQUIRE_AMASK(CIX);

            REQUIRE_REG_31(ra);

            REQUIRE_NO_LIT;

            tcg_gen_ctpop_i64(vc, vb);

            break;

        case 0x31:

            /* PERR */

            REQUIRE_AMASK(MVI);

            REQUIRE_NO_LIT;

            va = load_gpr(ctx, ra);

            gen_helper_perr(vc, va, vb);

            break;

        case 0x32:

            /* CTLZ */

            REQUIRE_AMASK(CIX);

            REQUIRE_REG_31(ra);

            REQUIRE_NO_LIT;

            tcg_gen_clzi_i64(vc, vb, 64);

            break;

        case 0x33:

            /* CTTZ */

            REQUIRE_AMASK(CIX);

            REQUIRE_REG_31(ra);

            REQUIRE_NO_LIT;

            tcg_gen_ctzi_i64(vc, vb, 64);

            break;

        case 0x34:

            /* UNPKBW */

            REQUIRE_AMASK(MVI);

            REQUIRE_REG_31(ra);

            REQUIRE_NO_LIT;

            gen_helper_unpkbw(vc, vb);

            break;

        case 0x35:

            /* UNPKBL */

            REQUIRE_AMASK(MVI);

            REQUIRE_REG_31(ra);

            REQUIRE_NO_LIT;

            gen_helper_unpkbl(vc, vb);

            break;

        case 0x36:

            /* PKWB */

            REQUIRE_AMASK(MVI);

            REQUIRE_REG_31(ra);

            REQUIRE_NO_LIT;

            gen_helper_pkwb(vc, vb);

            break;

        case 0x37:

            /* PKLB */

            REQUIRE_AMASK(MVI);

            REQUIRE_REG_31(ra);

            REQUIRE_NO_LIT;

            gen_helper_pklb(vc, vb);

            break;

        case 0x38:

            /* MINSB8 */

            REQUIRE_AMASK(MVI);

            va = load_gpr(ctx, ra);

            gen_helper_minsb8(vc, va, vb);

            break;

        case 0x39:

            /* MINSW4 */

            REQUIRE_AMASK(MVI);

            va = load_gpr(ctx, ra);

            gen_helper_minsw4(vc, va, vb);

            break;

        case 0x3A:

            /* MINUB8 */

            REQUIRE_AMASK(MVI);

            va = load_gpr(ctx, ra);

            gen_helper_minub8(vc, va, vb);

            break;

        case 0x3B:

            /* MINUW4 */

            REQUIRE_AMASK(MVI);

            va = load_gpr(ctx, ra);

            gen_helper_minuw4(vc, va, vb);

            break;

        case 0x3C:

            /* MAXUB8 */

            REQUIRE_AMASK(MVI);

            va = load_gpr(ctx, ra);

            gen_helper_maxub8(vc, va, vb);

            break;

        case 0x3D:

            /* MAXUW4 */

            REQUIRE_AMASK(MVI);

            va = load_gpr(ctx, ra);

            gen_helper_maxuw4(vc, va, vb);

            break;

        case 0x3E:

            /* MAXSB8 */

            REQUIRE_AMASK(MVI);

            va = load_gpr(ctx, ra);

            gen_helper_maxsb8(vc, va, vb);

            break;

        case 0x3F:

            /* MAXSW4 */

            REQUIRE_AMASK(MVI);

            va = load_gpr(ctx, ra);

            gen_helper_maxsw4(vc, va, vb);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x1D:

        /* HW_MTPR (PALcode) */

#ifndef CONFIG_USER_ONLY

        REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);

        vb = load_gpr(ctx, rb);

        ret = gen_mtpr(ctx, vb, insn & 0xffff);

        break;

#else

        goto invalid_opc;

#endif

    case 0x1E:

        /* HW_RET (PALcode) */

#ifndef CONFIG_USER_ONLY

        REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);

        if (rb == 31) {

            /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return

               address from EXC_ADDR.  This turns out to be useful for our

               emulation PALcode, so continue to accept it.  */

            ctx->lit = vb = tcg_temp_new();

            tcg_gen_ld_i64(vb, cpu_env, offsetof(CPUAlphaState, exc_addr));

        } else {

            vb = load_gpr(ctx, rb);

        }

        tcg_gen_movi_i64(cpu_lock_addr, -1);

        tmp = tcg_temp_new();

        tcg_gen_movi_i64(tmp, 0);

        st_flag_byte(tmp, ENV_FLAG_RX_SHIFT);

        tcg_gen_andi_i64(tmp, vb, 1);

        st_flag_byte(tmp, ENV_FLAG_PAL_SHIFT);

        tcg_temp_free(tmp);

        tcg_gen_andi_i64(cpu_pc, vb, ~3);

        /* Allow interrupts to be recognized right away.  */

        ret = DISAS_PC_UPDATED_NOCHAIN;

        break;

#else

        goto invalid_opc;

#endif

    case 0x1F:

        /* HW_ST (PALcode) */

#ifndef CONFIG_USER_ONLY

        REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);

        {

            switch ((insn >> 12) & 0xF) {

            case 0x0:

                /* Longword physical access */

                va = load_gpr(ctx, ra);

                vb = load_gpr(ctx, rb);

                tmp = tcg_temp_new();

                tcg_gen_addi_i64(tmp, vb, disp12);

                tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LESL);

                tcg_temp_free(tmp);

                break;

            case 0x1:

                /* Quadword physical access */

                va = load_gpr(ctx, ra);

                vb = load_gpr(ctx, rb);

                tmp = tcg_temp_new();

                tcg_gen_addi_i64(tmp, vb, disp12);

                tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LEQ);

                tcg_temp_free(tmp);

                break;

            case 0x2:

                /* Longword physical access with lock */

                ret = gen_store_conditional(ctx, ra, rb, disp12,

                                            MMU_PHYS_IDX, MO_LESL);

                break;

            case 0x3:

                /* Quadword physical access with lock */

                ret = gen_store_conditional(ctx, ra, rb, disp12,

                                            MMU_PHYS_IDX, MO_LEQ);

                break;

            case 0x4:

                /* Longword virtual access */

                goto invalid_opc;

            case 0x5:

                /* Quadword virtual access */

                goto invalid_opc;

            case 0x6:

                /* Invalid */

                goto invalid_opc;

            case 0x7:

                /* Invalid */

                goto invalid_opc;

            case 0x8:

                /* Invalid */

                goto invalid_opc;

            case 0x9:

                /* Invalid */

                goto invalid_opc;

            case 0xA:

                /* Invalid */

                goto invalid_opc;

            case 0xB:

                /* Invalid */

                goto invalid_opc;

            case 0xC:

                /* Longword virtual access with alternate access mode */

                goto invalid_opc;

            case 0xD:

                /* Quadword virtual access with alternate access mode */

                goto invalid_opc;

            case 0xE:

                /* Invalid */

                goto invalid_opc;

            case 0xF:

                /* Invalid */

                goto invalid_opc;

            }

            break;

        }

#else

        goto invalid_opc;

#endif

    case 0x20:

        /* LDF */

        gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);

        break;

    case 0x21:

        /* LDG */

        gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);

        break;

    case 0x22:

        /* LDS */

        gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);

        break;

    case 0x23:

        /* LDT */

        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);

        break;

    case 0x24:

        /* STF */

        gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0);

        break;

    case 0x25:

        /* STG */

        gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0);

        break;

    case 0x26:

        /* STS */

        gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0);

        break;

    case 0x27:

        /* STT */

        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0);

        break;

    case 0x28:

        /* LDL */

        gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);

        break;

    case 0x29:

        /* LDQ */

        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);

        break;

    case 0x2A:

        /* LDL_L */

        gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);

        break;

    case 0x2B:

        /* LDQ_L */

        gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);

        break;

    case 0x2C:

        /* STL */

        gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0);

        break;

    case 0x2D:

        /* STQ */

        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0);

        break;

    case 0x2E:

        /* STL_C */

        ret = gen_store_conditional(ctx, ra, rb, disp16,

                                    ctx->mem_idx, MO_LESL);

        break;

    case 0x2F:

        /* STQ_C */

        ret = gen_store_conditional(ctx, ra, rb, disp16,

                                    ctx->mem_idx, MO_LEQ);

        break;

    case 0x30:

        /* BR */

        ret = gen_bdirect(ctx, ra, disp21);

        break;

    case 0x31: /* FBEQ */

        ret = gen_fbcond(ctx, TCG_COND_EQ, ra, disp21);

        break;

    case 0x32: /* FBLT */

        ret = gen_fbcond(ctx, TCG_COND_LT, ra, disp21);

        break;

    case 0x33: /* FBLE */

        ret = gen_fbcond(ctx, TCG_COND_LE, ra, disp21);

        break;

    case 0x34:

        /* BSR */

        ret = gen_bdirect(ctx, ra, disp21);

        break;

    case 0x35: /* FBNE */

        ret = gen_fbcond(ctx, TCG_COND_NE, ra, disp21);

        break;

    case 0x36: /* FBGE */

        ret = gen_fbcond(ctx, TCG_COND_GE, ra, disp21);

        break;

    case 0x37: /* FBGT */

        ret = gen_fbcond(ctx, TCG_COND_GT, ra, disp21);

        break;

    case 0x38:

        /* BLBC */

        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);

        break;

    case 0x39:

        /* BEQ */

        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);

        break;

    case 0x3A:

        /* BLT */

        ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);

        break;

    case 0x3B:

        /* BLE */

        ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);

        break;

    case 0x3C:

        /* BLBS */

        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);

        break;

    case 0x3D:

        /* BNE */

        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);

        break;

    case 0x3E:

        /* BGE */

        ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);

        break;

    case 0x3F:

        /* BGT */

        ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);

        break;

    invalid_opc:

        ret = gen_invalid(ctx);

        break;

    }

    return ret;

}


static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,

                              target_ulong opcode, target_ulong *args)

{

    CPUPPCState *env = &cpu->env;

    target_ulong flags = args[0];

    target_ulong pte_index = args[1];

    target_ulong avpn = args[2];

    hwaddr hpte;

    target_ulong v, r, rb;

    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {

        return H_PARAMETER;

    }

    hpte = pte_index * HASH_PTE_SIZE_64;

    v = ppc_hash64_load_hpte0(env, hpte);

    r = ppc_hash64_load_hpte1(env, hpte);

    if ((v & HPTE64_V_VALID) == 0 ||

        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {

        return H_NOT_FOUND;

    }

    r &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |

           HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);

    r |= (flags << 55) & HPTE64_R_PP0;

    r |= (flags << 48) & HPTE64_R_KEY_HI;

    r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);

    rb = compute_tlbie_rb(v, r, pte_index);

    ppc_hash64_store_hpte0(env, hpte, (v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY);

    ppc_tlb_invalidate_one(env, rb);

    ppc_hash64_store_hpte1(env, hpte, r);

    /* Don't need a memory barrier, due to qemu's global lock */

    ppc_hash64_store_hpte0(env, hpte, v | HPTE64_V_HPTE_DIRTY);

    return H_SUCCESS;

}


void do_op_602_mfrom (void)

{

    if (likely(T0 < 602)) {

#ifdef USE_MFROM_ROM_TABLE

#include "mfrom_table.c"

        T0 = mfrom_ROM_table[T0];

#else

        double d;

        /* Extremly decomposed:

         *                    -T0 / 256

         * T0 = 256 * log10(10          + 1.0) + 0.5

         */

        d = T0;

        d = float64_div(d, 256, &env->fp_status);

        d = float64_chs(d);

        d = exp10(d); // XXX: use float emulation function

        d = float64_add(d, 1.0, &env->fp_status);

        d = log10(d); // XXX: use float emulation function

        d = float64_mul(d, 256, &env->fp_status);

        d = float64_add(d, 0.5, &env->fp_status);

        T0 = float64_round_to_int(d, &env->fp_status);

#endif

    } else {

        T0 = 0;

    }

}


static int mpc8_decode_frame(AVCodecContext * avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    MPCContext *c = avctx->priv_data;

    GetBitContext gb2, *gb = &gb2;

    int i, j, k, ch, cnt, res, t;

    Band *bands = c->bands;

    int off, out_size;

    int maxband, keyframe;

    int last[2];

    out_size = MPC_FRAME_SIZE * 2 * avctx->channels;

    if (*data_size < out_size) {

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

        return AVERROR(EINVAL);

    }

    keyframe = c->cur_frame == 0;

    if(keyframe){

        memset(c->Q, 0, sizeof(c->Q));

        c->last_bits_used = 0;

    }

    init_get_bits(gb, buf, buf_size * 8);

    skip_bits(gb, c->last_bits_used & 7);

    if(keyframe)

        maxband = mpc8_get_mod_golomb(gb, c->maxbands + 1);

    else{

        maxband = c->last_max_band + get_vlc2(gb, band_vlc.table, MPC8_BANDS_BITS, 2);

        if(maxband > 32) maxband -= 33;

    }

    c->last_max_band = maxband;

    /* read subband indexes */

    if(maxband){

        last[0] = last[1] = 0;

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

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

                last[ch] = get_vlc2(gb, res_vlc[last[ch] > 2].table, MPC8_RES_BITS, 2) + last[ch];

                if(last[ch] > 15) last[ch] -= 17;

                bands[i].res[ch] = last[ch];

            }

        }

        if(c->MSS){

            int mask;

            cnt = 0;

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

                if(bands[i].res[0] || bands[i].res[1])

                    cnt++;

            t = mpc8_get_mod_golomb(gb, cnt);

            mask = mpc8_get_mask(gb, cnt, t);

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

                if(bands[i].res[0] || bands[i].res[1]){

                    bands[i].msf = mask & 1;

                    mask >>= 1;

                }

        }

    }

    for(i = maxband; i < c->maxbands; i++)

        bands[i].res[0] = bands[i].res[1] = 0;

    if(keyframe){

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

            c->oldDSCF[0][i] = c->oldDSCF[1][i] = 1;

    }

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

        if(bands[i].res[0] || bands[i].res[1]){

            cnt = !!bands[i].res[0] + !!bands[i].res[1] - 1;

            if(cnt >= 0){

                t = get_vlc2(gb, scfi_vlc[cnt].table, scfi_vlc[cnt].bits, 1);

                if(bands[i].res[0]) bands[i].scfi[0] = t >> (2 * cnt);

                if(bands[i].res[1]) bands[i].scfi[1] = t & 3;

            }

        }

    }

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

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

            if(!bands[i].res[ch]) continue;

            if(c->oldDSCF[ch][i]){

                bands[i].scf_idx[ch][0] = get_bits(gb, 7) - 6;

                c->oldDSCF[ch][i] = 0;

            }else{

                t = get_vlc2(gb, dscf_vlc[1].table, MPC8_DSCF1_BITS, 2);

                if(t == 64)

                    t += get_bits(gb, 6);

                bands[i].scf_idx[ch][0] = ((bands[i].scf_idx[ch][2] + t - 25) & 0x7F) - 6;

            }

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

                if((bands[i].scfi[ch] << j) & 2)

                    bands[i].scf_idx[ch][j + 1] = bands[i].scf_idx[ch][j];

                else{

                    t = get_vlc2(gb, dscf_vlc[0].table, MPC8_DSCF0_BITS, 2);

                    if(t == 31)

                        t = 64 + get_bits(gb, 6);

                    bands[i].scf_idx[ch][j + 1] = ((bands[i].scf_idx[ch][j] + t - 25) & 0x7F) - 6;

                }

            }

        }

    }

    for(i = 0, off = 0; i < maxband; i++, off += SAMPLES_PER_BAND){

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

            res = bands[i].res[ch];

            switch(res){

            case -1:

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

                    c->Q[ch][off + j] = (av_lfg_get(&c->rnd) & 0x3FC) - 510;

                break;

            case 0:

                break;

            case 1:

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

                    cnt = get_vlc2(gb, q1_vlc.table, MPC8_Q1_BITS, 2);

                    t = mpc8_get_mask(gb, 18, cnt);

                    for(k = 0; k < SAMPLES_PER_BAND / 2; k++, t <<= 1)

                        c->Q[ch][off + j + k] = (t & 0x20000) ? (get_bits1(gb) << 1) - 1 : 0;

                }

                break;

            case 2:

                cnt = 6;//2*mpc8_thres[res]

                for(j = 0; j < SAMPLES_PER_BAND; j += 3){

                    t = get_vlc2(gb, q2_vlc[cnt > 3].table, MPC8_Q2_BITS, 2);

                    c->Q[ch][off + j + 0] = mpc8_idx50[t];

                    c->Q[ch][off + j + 1] = mpc8_idx51[t];

                    c->Q[ch][off + j + 2] = mpc8_idx52[t];

                    cnt = (cnt >> 1) + mpc8_huffq2[t];

                }

                break;

            case 3:

            case 4:

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

                    t = get_vlc2(gb, q3_vlc[res - 3].table, MPC8_Q3_BITS, 2) + q3_offsets[res - 3];

                    c->Q[ch][off + j + 1] = t >> 4;

                    c->Q[ch][off + j + 0] = (t & 8) ? (t & 0xF) - 16 : (t & 0xF);

                }

                break;

            case 5:

            case 6:

            case 7:

            case 8:

                cnt = 2 * mpc8_thres[res];

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

                    t = get_vlc2(gb, quant_vlc[res - 5][cnt > mpc8_thres[res]].table, quant_vlc[res - 5][cnt > mpc8_thres[res]].bits, 2) + quant_offsets[res - 5];

                    c->Q[ch][off + j] = t;

                    cnt = (cnt >> 1) + FFABS(c->Q[ch][off + j]);

                }

                break;

            default:

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

                    c->Q[ch][off + j] = get_vlc2(gb, q9up_vlc.table, MPC8_Q9UP_BITS, 2);

                    if(res != 9){

                        c->Q[ch][off + j] <<= res - 9;

                        c->Q[ch][off + j] |= get_bits(gb, res - 9);

                    }

                    c->Q[ch][off + j] -= (1 << (res - 2)) - 1;

                }

            }

        }

    }

    ff_mpc_dequantize_and_synth(c, maxband, data, avctx->channels);

    c->cur_frame++;

    c->last_bits_used = get_bits_count(gb);

    if(c->cur_frame >= c->frames)

        c->cur_frame = 0;

    *data_size =  out_size;

    return c->cur_frame ? c->last_bits_used >> 3 : buf_size;

}


static void backup_set_speed(BlockJob *job, int64_t speed, Error **errp)

{

    BackupBlockJob *s = container_of(job, BackupBlockJob, common);

    if (speed < 0) {

        error_setg(errp, QERR_INVALID_PARAMETER, "speed");

        return;

    }

    ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE, SLICE_TIME);

}


static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,

                                           struct XenDevOps *ops)

{

    struct XenDevice *xendev;

    char *dom0;

    xendev = xen_be_find_xendev(type, dom, dev);

    if (xendev) {

        return xendev;

    }

    /* init new xendev */

    xendev = g_malloc0(ops->size);

    xendev->type  = type;

    xendev->dom   = dom;

    xendev->dev   = dev;

    xendev->ops   = ops;

    dom0 = xs_get_domain_path(xenstore, 0);

    snprintf(xendev->be, sizeof(xendev->be), "%s/backend/%s/%d/%d",

             dom0, xendev->type, xendev->dom, xendev->dev);

    snprintf(xendev->name, sizeof(xendev->name), "%s-%d",

             xendev->type, xendev->dev);

    free(dom0);

    xendev->debug      = debug;

    xendev->local_port = -1;

    xendev->evtchndev = xen_xc_evtchn_open(NULL, 0);

    if (xendev->evtchndev == XC_HANDLER_INITIAL_VALUE) {

        xen_be_printf(NULL, 0, "can't open evtchn device\n");

        g_free(xendev);

        return NULL;

    }

    fcntl(xc_evtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);

    if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {

        xendev->gnttabdev = xen_xc_gnttab_open(NULL, 0);

        if (xendev->gnttabdev == XC_HANDLER_INITIAL_VALUE) {

            xen_be_printf(NULL, 0, "can't open gnttab device\n");

            xc_evtchn_close(xendev->evtchndev);

            g_free(xendev);

            return NULL;

        }

    } else {

        xendev->gnttabdev = XC_HANDLER_INITIAL_VALUE;

    }

    QTAILQ_INSERT_TAIL(&xendevs, xendev, next);

    if (xendev->ops->alloc) {

        xendev->ops->alloc(xendev);

    }

    return xendev;

}


int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
                                              AVPacket *avpkt,
                                              const AVFrame *frame,
                                              int *got_packet_ptr)
{
    AVFrame *extended_frame = NULL;
    AVFrame *padded_frame = NULL;
    int ret;
    AVPacket user_pkt = *avpkt;
    int needs_realloc = !user_pkt.data;
    *got_packet_ptr = 0;
    if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) {
        av_free_packet(avpkt);
        av_init_packet(avpkt);
        return 0;
    }
    /* ensure that extended_data is properly set */
    if (frame && !frame->extended_data) {
        if (av_sample_fmt_is_planar(avctx->sample_fmt) &&
            avctx->channels > AV_NUM_DATA_POINTERS) {
            av_log(avctx, AV_LOG_ERROR, "Encoding to a planar sample format, "
                                        "with more than %d channels, but extended_data is not set.\n",
                   AV_NUM_DATA_POINTERS);
            return AVERROR(EINVAL);
        }
        av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n");
        extended_frame = av_frame_alloc();
        if (!extended_frame)
            return AVERROR(ENOMEM);
        memcpy(extended_frame, frame, sizeof(AVFrame));
        extended_frame->extended_data = extended_frame->data;
        frame = extended_frame;
    }
    /* extract audio service type metadata */
    if (frame) {
        AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_AUDIO_SERVICE_TYPE);
        if (sd && sd->size >= sizeof(enum AVAudioServiceType))
            avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data;
    }
    /* check for valid frame size */
    if (frame) {
        if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) {
            if (frame->nb_samples > avctx->frame_size) {
                av_log(avctx, AV_LOG_ERROR, "more samples than frame size (avcodec_encode_audio2)\n");
                ret = AVERROR(EINVAL);
                goto end;
            }
        } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) {
            if (frame->nb_samples < avctx->frame_size &&
                !avctx->internal->last_audio_frame) {
                ret = pad_last_frame(avctx, &padded_frame, frame);
                if (ret < 0)
                    goto end;
                frame = padded_frame;
                avctx->internal->last_audio_frame = 1;
            }
            if (frame->nb_samples != avctx->frame_size) {
                av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d) (avcodec_encode_audio2)\n", frame->nb_samples, avctx->frame_size);
                ret = AVERROR(EINVAL);
                goto end;
            }
        }
    }
    ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr);
    if (!ret) {
        if (*got_packet_ptr) {
            if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) {
                if (avpkt->pts == AV_NOPTS_VALUE)
                    avpkt->pts = frame->pts;
                if (!avpkt->duration)
                    avpkt->duration = ff_samples_to_time_base(avctx,
                                                              frame->nb_samples);
            }
            avpkt->dts = avpkt->pts;
        } else {
            avpkt->size = 0;
        }
    }
    if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) {
        needs_realloc = 0;
        if (user_pkt.data) {
            if (user_pkt.size >= avpkt->size) {
                memcpy(user_pkt.data, avpkt->data, avpkt->size);
            } else {
                av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size);
                avpkt->size = user_pkt.size;
                ret = -1;
            }
            avpkt->buf      = user_pkt.buf;
            avpkt->data     = user_pkt.data;
#if FF_API_DESTRUCT_PACKET
FF_DISABLE_DEPRECATION_WARNINGS
            avpkt->destruct = user_pkt.destruct;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
        } else {
            if (av_dup_packet(avpkt) < 0) {
                ret = AVERROR(ENOMEM);
            }
        }
    }
    if (!ret) {
        if (needs_realloc && avpkt->data) {
            ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE);
            if (ret >= 0)
                avpkt->data = avpkt->buf->data;
        }
        avctx->frame_number++;
    }
    if (ret < 0 || !*got_packet_ptr) {
        av_free_packet(avpkt);
        av_init_packet(avpkt);
        goto end;
    }
    /* NOTE: if we add any audio encoders which output non-keyframe packets,
     *       this needs to be moved to the encoders, but for now we can do it
     *       here to simplify things */
    avpkt->flags |= AV_PKT_FLAG_KEY;
end:
    av_frame_free(&padded_frame);
    av_free(extended_frame);
#if FF_API_AUDIOENC_DELAY
    avctx->delay = avctx->initial_padding;
#endif
    return ret;
}


static int iff_read_packet(AVFormatContext *s,

                           AVPacket *pkt)

{

    IffDemuxContext *iff = s->priv_data;

    AVIOContext *pb = s->pb;

    AVStream *st = s->streams[0];

    int ret;

    int64_t pos = avio_tell(pb);

    if (pos >= iff->body_end)

        return AVERROR_EOF;

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

        if (st->codec->codec_tag == ID_MAUD) {

            ret = av_get_packet(pb, pkt, FFMIN(iff->body_end - pos, 1024 * st->codec->block_align));

        } else {

            ret = av_get_packet(pb, pkt, iff->body_size);

        }

    } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {

        uint8_t *buf;

        if (av_new_packet(pkt, iff->body_size + 2) < 0) {

            return AVERROR(ENOMEM);

        }

        buf = pkt->data;

        bytestream_put_be16(&buf, 2);

        ret = avio_read(pb, buf, iff->body_size);

    } else {

        av_assert0(0);

    }

    if (pos == iff->body_pos)

        pkt->flags |= AV_PKT_FLAG_KEY;

    if (ret < 0)

        return ret;

    pkt->stream_index = 0;

    return ret;

}


static void virtio_blk_save_device(VirtIODevice *vdev, QEMUFile *f)

{

    VirtIOBlock *s = VIRTIO_BLK(vdev);

    VirtIOBlockReq *req = s->rq;

    while (req) {

        qemu_put_sbyte(f, 1);

        qemu_put_buffer(f, (unsigned char *)req->elem,

                        sizeof(VirtQueueElement));

        req = req->next;

    }

    qemu_put_sbyte(f, 0);

}


static inline void RENAME(yuv2packedX)(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,

				    int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,

			    uint8_t *dest, long dstW, long dstY)

{

#ifdef HAVE_MMX

    long dummy=0;

    if(c->flags & SWS_ACCURATE_RND){

                switch(c->dstFormat){

                case PIX_FMT_RGB32:

                                YSCALEYUV2PACKEDX_ACCURATE

				YSCALEYUV2RGBX

				WRITEBGR32(%4, %5, %%REGa)

                                YSCALEYUV2PACKEDX_END

                        return;

                case PIX_FMT_BGR24:

                                YSCALEYUV2PACKEDX_ACCURATE

				YSCALEYUV2RGBX

				"lea (%%"REG_a", %%"REG_a", 2), %%"REG_c"\n\t" //FIXME optimize

				"add %4, %%"REG_c"			\n\t"

				WRITEBGR24(%%REGc, %5, %%REGa)

			:: "r" (&c->redDither),

			   "m" (dummy), "m" (dummy), "m" (dummy),

			   "r" (dest), "m" (dstW)

			: "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S

			);

                        return;

                case PIX_FMT_BGR555:

                                YSCALEYUV2PACKEDX_ACCURATE

				YSCALEYUV2RGBX

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

				"paddusb "MANGLE(b5Dither)", %%mm2\n\t"

				"paddusb "MANGLE(g5Dither)", %%mm4\n\t"

				"paddusb "MANGLE(r5Dither)", %%mm5\n\t"

#endif

				WRITEBGR15(%4, %5, %%REGa)

                                YSCALEYUV2PACKEDX_END

                        return;

                case PIX_FMT_BGR565:

                                YSCALEYUV2PACKEDX_ACCURATE

				YSCALEYUV2RGBX

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

				"paddusb "MANGLE(b5Dither)", %%mm2\n\t"

				"paddusb "MANGLE(g6Dither)", %%mm4\n\t"

				"paddusb "MANGLE(r5Dither)", %%mm5\n\t"

#endif

				WRITEBGR16(%4, %5, %%REGa)

                                YSCALEYUV2PACKEDX_END

                        return;

                case PIX_FMT_YUYV422:

				YSCALEYUV2PACKEDX_ACCURATE

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

				"psraw $3, %%mm3		\n\t"

				"psraw $3, %%mm4		\n\t"

				"psraw $3, %%mm1		\n\t"

				"psraw $3, %%mm7		\n\t"

				WRITEYUY2(%4, %5, %%REGa)

                                YSCALEYUV2PACKEDX_END

                        return;

                }

    }else{

	switch(c->dstFormat)

	{

	case PIX_FMT_RGB32:

                                YSCALEYUV2PACKEDX

				YSCALEYUV2RGBX

				WRITEBGR32(%4, %5, %%REGa)

                                YSCALEYUV2PACKEDX_END

		return;

	case PIX_FMT_BGR24:

                                YSCALEYUV2PACKEDX

				YSCALEYUV2RGBX

				"lea (%%"REG_a", %%"REG_a", 2), %%"REG_c"\n\t" //FIXME optimize

				"add %4, %%"REG_c"			\n\t"

				WRITEBGR24(%%REGc, %5, %%REGa)

			:: "r" (&c->redDither),

			   "m" (dummy), "m" (dummy), "m" (dummy),

			   "r" (dest), "m" (dstW)

			: "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S

			);

		return;

	case PIX_FMT_BGR555:

                                YSCALEYUV2PACKEDX

				YSCALEYUV2RGBX

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

				"paddusb "MANGLE(b5Dither)", %%mm2\n\t"

				"paddusb "MANGLE(g5Dither)", %%mm4\n\t"

				"paddusb "MANGLE(r5Dither)", %%mm5\n\t"

#endif

				WRITEBGR15(%4, %5, %%REGa)

                                YSCALEYUV2PACKEDX_END

		return;

	case PIX_FMT_BGR565:

                                YSCALEYUV2PACKEDX

				YSCALEYUV2RGBX

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

				"paddusb "MANGLE(b5Dither)", %%mm2\n\t"

				"paddusb "MANGLE(g6Dither)", %%mm4\n\t"

				"paddusb "MANGLE(r5Dither)", %%mm5\n\t"

#endif

				WRITEBGR16(%4, %5, %%REGa)

                                YSCALEYUV2PACKEDX_END

		return;

	case PIX_FMT_YUYV422:

				YSCALEYUV2PACKEDX

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

				"psraw $3, %%mm3		\n\t"

				"psraw $3, %%mm4		\n\t"

				"psraw $3, %%mm1		\n\t"

				"psraw $3, %%mm7		\n\t"

				WRITEYUY2(%4, %5, %%REGa)

                                YSCALEYUV2PACKEDX_END

		return;

        }

    }

#endif

#ifdef HAVE_ALTIVEC

		/* The following list of supported dstFormat values should

		   match what's found in the body of altivec_yuv2packedX() */

		if(c->dstFormat==PIX_FMT_ABGR  || c->dstFormat==PIX_FMT_BGRA  ||

		   c->dstFormat==PIX_FMT_BGR24 || c->dstFormat==PIX_FMT_RGB24 ||

		   c->dstFormat==PIX_FMT_RGBA  || c->dstFormat==PIX_FMT_ARGB)

			altivec_yuv2packedX (c, lumFilter, lumSrc, lumFilterSize,

				    chrFilter, chrSrc, chrFilterSize,

				    dest, dstW, dstY);

		else

#endif

			yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize,

				    chrFilter, chrSrc, chrFilterSize,

				    dest, dstW, dstY);

}


static void virtio_net_save(QEMUFile *f, void *opaque)

{

    VirtIONet *n = opaque;

    virtio_save(&n->vdev, f);

    qemu_put_buffer(f, n->mac, ETH_ALEN);

    qemu_put_be32(f, n->tx_timer_active);

    qemu_put_be32(f, n->mergeable_rx_bufs);

    qemu_put_be16(f, n->status);

    qemu_put_byte(f, n->promisc);

    qemu_put_byte(f, n->allmulti);

    qemu_put_be32(f, n->mac_table.in_use);

    qemu_put_buffer(f, n->mac_table.macs, n->mac_table.in_use * ETH_ALEN);

    qemu_put_buffer(f, (uint8_t *)n->vlans, MAX_VLAN >> 3);

    qemu_put_be32(f, 0); /* vnet-hdr placeholder */

    qemu_put_byte(f, n->mac_table.multi_overflow);

    qemu_put_byte(f, n->mac_table.uni_overflow);

    qemu_put_byte(f, n->alluni);

    qemu_put_byte(f, n->nomulti);

    qemu_put_byte(f, n->nouni);

    qemu_put_byte(f, n->nobcast);

}


static int set_palette(AVFrame * frame, const uint8_t * palette_buffer, int buf_size)

{

    uint32_t * palette = (uint32_t *)frame->data[1];

    int a;

    if (buf_size < 256*3)

        return AVERROR_INVALIDDATA;

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

        palette[a] = AV_RB24(&palette_buffer[a * 3]) * 4;

    }

    frame->palette_has_changed = 1;

    return 256*3;

}


static int build_def_list(Picture *def, Picture **in, int len, int is_long, int sel)

{

    int  i[2] = { 0 };

    int index = 0;

    while (i[0] < len || i[1] < len) {

        while (i[0] < len && !(in[i[0]] && (in[i[0]]->reference & sel)))

            i[0]++;

        while (i[1] < len && !(in[i[1]] && (in[i[1]]->reference & (sel ^ 3))))

            i[1]++;

        if (i[0] < len) {

            in[i[0]]->pic_id = is_long ? i[0] : in[i[0]]->frame_num;

            split_field_copy(&def[index++], in[i[0]++], sel, 1);

        }

        if (i[1] < len) {

            in[i[1]]->pic_id = is_long ? i[1] : in[i[1]]->frame_num;

            split_field_copy(&def[index++], in[i[1]++], sel ^ 3, 0);

        }

    }

    return index;

}


static void vnc_init_timer(VncDisplay *vd)

{

    vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;

    if (vd->timer == NULL && !QTAILQ_EMPTY(&vd->clients)) {

        vd->timer = qemu_new_timer_ms(rt_clock, vnc_refresh, vd);

        vnc_dpy_resize(dcl, vd->ds);

        vnc_refresh(vd);

    }

}


static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,

                              const AVFrame *frame, int *got_packet_ptr)

{

    int n, i, ch, st, pkt_size, ret;

    const int16_t *samples;

    int16_t **samples_p;

    uint8_t *dst;

    ADPCMEncodeContext *c = avctx->priv_data;

    uint8_t *buf;

    samples = (const int16_t *)frame->data[0];

    samples_p = (int16_t **)frame->extended_data;

    st = avctx->channels == 2;

    if (avctx->codec_id == AV_CODEC_ID_ADPCM_SWF)

        pkt_size = (2 + avctx->channels * (22 + 4 * (frame->nb_samples - 1)) + 7) / 8;

    else

        pkt_size = avctx->block_align;

    if ((ret = ff_alloc_packet2(avctx, avpkt, pkt_size)))

        return ret;

    dst = avpkt->data;

    switch(avctx->codec->id) {

    case AV_CODEC_ID_ADPCM_IMA_WAV:

    {

        int blocks, j;

        blocks = (frame->nb_samples - 1) / 8;

        for (ch = 0; ch < avctx->channels; ch++) {

            ADPCMChannelStatus *status = &c->status[ch];

            status->prev_sample = samples_p[ch][0];

            /* status->step_index = 0;

               XXX: not sure how to init the state machine */

            bytestream_put_le16(&dst, status->prev_sample);

            *dst++ = status->step_index;

            *dst++ = 0; /* unknown */

        }

        /* stereo: 4 bytes (8 samples) for left, 4 bytes for right */

        if (avctx->trellis > 0) {

            FF_ALLOC_OR_GOTO(avctx, buf, avctx->channels * blocks * 8, error);

            for (ch = 0; ch < avctx->channels; ch++) {

                adpcm_compress_trellis(avctx, &samples_p[ch][1],

                                       buf + ch * blocks * 8, &c->status[ch],

                                       blocks * 8, 1);

            }

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

                for (ch = 0; ch < avctx->channels; ch++) {

                    uint8_t *buf1 = buf + ch * blocks * 8 + i * 8;

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

                        *dst++ = buf1[j] | (buf1[j + 1] << 4);

                }

            }

            av_free(buf);

        } else {

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

                for (ch = 0; ch < avctx->channels; ch++) {

                    ADPCMChannelStatus *status = &c->status[ch];

                    const int16_t *smp = &samples_p[ch][1 + i * 8];

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

                        uint8_t v = adpcm_ima_compress_sample(status, smp[j    ]);

                        v        |= adpcm_ima_compress_sample(status, smp[j + 1]) << 4;

                        *dst++ = v;

                    }

                }

            }

        }

        break;

    }

    case AV_CODEC_ID_ADPCM_IMA_QT:

    {

        PutBitContext pb;

        init_put_bits(&pb, dst, pkt_size * 8);

        for (ch = 0; ch < avctx->channels; ch++) {

            ADPCMChannelStatus *status = &c->status[ch];

            put_bits(&pb, 9, (status->prev_sample & 0xFFFF) >> 7);

            put_bits(&pb, 7,  status->step_index);

            if (avctx->trellis > 0) {

                uint8_t buf[64];

                adpcm_compress_trellis(avctx, &samples_p[ch][1], buf, status,

                                       64, 1);

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

                    put_bits(&pb, 4, buf[i ^ 1]);

            } else {

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

                    int t1, t2;

                    t1 = adpcm_ima_qt_compress_sample(status, samples_p[ch][i    ]);

                    t2 = adpcm_ima_qt_compress_sample(status, samples_p[ch][i + 1]);

                    put_bits(&pb, 4, t2);

                    put_bits(&pb, 4, t1);

                }

            }

        }

        flush_put_bits(&pb);

        break;

    }

    case AV_CODEC_ID_ADPCM_SWF:

    {

        PutBitContext pb;

        init_put_bits(&pb, dst, pkt_size * 8);

        n = frame->nb_samples - 1;

        // store AdpcmCodeSize

        put_bits(&pb, 2, 2);    // set 4-bit flash adpcm format

        // init the encoder state

        for (i = 0; i < avctx->channels; i++) {

            // clip step so it fits 6 bits

            c->status[i].step_index = av_clip(c->status[i].step_index, 0, 63);

            put_sbits(&pb, 16, samples[i]);

            put_bits(&pb, 6, c->status[i].step_index);

            c->status[i].prev_sample = samples[i];

        }

        if (avctx->trellis > 0) {

            FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error);

            adpcm_compress_trellis(avctx, samples + avctx->channels, buf,

                                   &c->status[0], n, avctx->channels);

            if (avctx->channels == 2)

                adpcm_compress_trellis(avctx, samples + avctx->channels + 1,

                                       buf + n, &c->status[1], n,

                                       avctx->channels);

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

                put_bits(&pb, 4, buf[i]);

                if (avctx->channels == 2)

                    put_bits(&pb, 4, buf[n + i]);

            }

            av_free(buf);

        } else {

            for (i = 1; i < frame->nb_samples; i++) {

                put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[0],

                         samples[avctx->channels * i]));

                if (avctx->channels == 2)

                    put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[1],

                             samples[2 * i + 1]));

            }

        }

        flush_put_bits(&pb);

        break;

    }

    case AV_CODEC_ID_ADPCM_MS:

        for (i = 0; i < avctx->channels; i++) {

            int predictor = 0;

            *dst++ = predictor;

            c->status[i].coeff1 = ff_adpcm_AdaptCoeff1[predictor];

            c->status[i].coeff2 = ff_adpcm_AdaptCoeff2[predictor];

        }

        for (i = 0; i < avctx->channels; i++) {

            if (c->status[i].idelta < 16)

                c->status[i].idelta = 16;

            bytestream_put_le16(&dst, c->status[i].idelta);

        }

        for (i = 0; i < avctx->channels; i++)

            c->status[i].sample2= *samples++;

        for (i = 0; i < avctx->channels; i++) {

            c->status[i].sample1 = *samples++;

            bytestream_put_le16(&dst, c->status[i].sample1);

        }

        for (i = 0; i < avctx->channels; i++)

            bytestream_put_le16(&dst, c->status[i].sample2);

        if (avctx->trellis > 0) {

            n = avctx->block_align - 7 * avctx->channels;

            FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error);

            if (avctx->channels == 1) {

                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n,

                                       avctx->channels);

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

                    *dst++ = (buf[i] << 4) | buf[i + 1];

            } else {

                adpcm_compress_trellis(avctx, samples,     buf,

                                       &c->status[0], n, avctx->channels);

                adpcm_compress_trellis(avctx, samples + 1, buf + n,

                                       &c->status[1], n, avctx->channels);

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

                    *dst++ = (buf[i] << 4) | buf[n + i];

            }

            av_free(buf);

        } else {

            for (i = 7 * avctx->channels; i < avctx->block_align; i++) {

                int nibble;

                nibble  = adpcm_ms_compress_sample(&c->status[ 0], *samples++) << 4;

                nibble |= adpcm_ms_compress_sample(&c->status[st], *samples++);

                *dst++  = nibble;

            }

        }

        break;

    case AV_CODEC_ID_ADPCM_YAMAHA:

        n = frame->nb_samples / 2;

        if (avctx->trellis > 0) {

            FF_ALLOC_OR_GOTO(avctx, buf, 2 * n * 2, error);

            n *= 2;

            if (avctx->channels == 1) {

                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n,

                                       avctx->channels);

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

                    *dst++ = buf[i] | (buf[i + 1] << 4);

            } else {

                adpcm_compress_trellis(avctx, samples,     buf,

                                       &c->status[0], n, avctx->channels);

                adpcm_compress_trellis(avctx, samples + 1, buf + n,

                                       &c->status[1], n, avctx->channels);

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

                    *dst++ = buf[i] | (buf[n + i] << 4);

            }

            av_free(buf);

        } else

            for (n *= avctx->channels; n > 0; n--) {

                int nibble;

                nibble  = adpcm_yamaha_compress_sample(&c->status[ 0], *samples++);

                nibble |= adpcm_yamaha_compress_sample(&c->status[st], *samples++) << 4;

                *dst++  = nibble;

            }

        break;

    default:

        return AVERROR(EINVAL);

    }

    avpkt->size = pkt_size;

    *got_packet_ptr = 1;

    return 0;

error:

    return AVERROR(ENOMEM);

}


static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,

                                                  TranslationBlock *tb,

                                                  int search_pc)

{

    struct DisasContext ctx, *dc = &ctx;

    uint16_t *gen_opc_end;

    uint32_t pc_start;

    int j, k;

    uint32_t next_page_start;

    int num_insns;

    int max_insns;

    qemu_log_try_set_file(stderr);

    pc_start = tb->pc;

    dc->tb = tb;

    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;

    dc->is_jmp = DISAS_NEXT;

    dc->ppc = pc_start;

    dc->pc = pc_start;

    dc->flags = cpu->env.cpucfgr;

    dc->mem_idx = cpu_mmu_index(&cpu->env);

    dc->synced_flags = dc->tb_flags = tb->flags;

    dc->delayed_branch = !!(dc->tb_flags & D_FLAG);

    dc->singlestep_enabled = cpu->env.singlestep_enabled;

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {

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

        log_cpu_state(&cpu->env, 0);

    }

    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;

    k = -1;

    num_insns = 0;

    max_insns = tb->cflags & CF_COUNT_MASK;

    if (max_insns == 0) {

        max_insns = CF_COUNT_MASK;

    }

    gen_icount_start();

    do {

        check_breakpoint(cpu, dc);

        if (search_pc) {

            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

            if (k < j) {

                k++;

                while (k < j) {

                    tcg_ctx.gen_opc_instr_start[k++] = 0;

                }

            }

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

            tcg_ctx.gen_opc_instr_start[k] = 1;

            tcg_ctx.gen_opc_icount[k] = num_insns;

        }

        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {

            tcg_gen_debug_insn_start(dc->pc);

        }

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

            gen_io_start();

        }

        dc->ppc = dc->pc - 4;

        dc->npc = dc->pc + 4;

        tcg_gen_movi_tl(cpu_ppc, dc->ppc);

        tcg_gen_movi_tl(cpu_npc, dc->npc);

        disas_openrisc_insn(dc, cpu);

        dc->pc = dc->npc;

        num_insns++;

        /* delay slot */

        if (dc->delayed_branch) {

            dc->delayed_branch--;

            if (!dc->delayed_branch) {

                dc->tb_flags &= ~D_FLAG;

                gen_sync_flags(dc);

                tcg_gen_mov_tl(cpu_pc, jmp_pc);

                tcg_gen_mov_tl(cpu_npc, jmp_pc);

                tcg_gen_movi_tl(jmp_pc, 0);

                tcg_gen_exit_tb(0);

                dc->is_jmp = DISAS_JUMP;

                break;

            }

        }

    } while (!dc->is_jmp

             && tcg_ctx.gen_opc_ptr < gen_opc_end

             && !cpu->env.singlestep_enabled

             && !singlestep

             && (dc->pc < next_page_start)

             && num_insns < max_insns);

    if (tb->cflags & CF_LAST_IO) {

        gen_io_end();

    }

    if (dc->is_jmp == DISAS_NEXT) {

        dc->is_jmp = DISAS_UPDATE;

        tcg_gen_movi_tl(cpu_pc, dc->pc);

    }

    if (unlikely(cpu->env.singlestep_enabled)) {

        if (dc->is_jmp == DISAS_NEXT) {

            tcg_gen_movi_tl(cpu_pc, dc->pc);

        }

        gen_exception(dc, EXCP_DEBUG);

    } else {

        switch (dc->is_jmp) {

        case DISAS_NEXT:

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

            break;

        default:

        case DISAS_JUMP:

            break;

        case DISAS_UPDATE:

            /* indicate that the hash table must be used

               to find the next TB */

            tcg_gen_exit_tb(0);

            break;

        case DISAS_TB_JUMP:

            /* nothing more to generate */

            break;

        }

    }

    gen_icount_end(tb, num_insns);

    *tcg_ctx.gen_opc_ptr = INDEX_op_end;

    if (search_pc) {

        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

        k++;

        while (k <= j) {

            tcg_ctx.gen_opc_instr_start[k++] = 0;

        }

    } else {

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

        tb->icount = num_insns;

    }

#ifdef DEBUG_DISAS

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {

        qemu_log("\n");

        log_target_disas(&cpu->env, pc_start, dc->pc - pc_start, 0);

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

            dc->pc - pc_start, tcg_ctx.gen_opc_ptr -

            tcg_ctx.gen_opc_buf);

    }

#endif

}


static int ism_write_header(AVFormatContext *s)

{

    SmoothStreamingContext *c = s->priv_data;

    int ret = 0, i;

    AVOutputFormat *oformat;

    mkdir(s->filename, 0777);

    oformat = av_guess_format("ismv", NULL, NULL);

    if (!oformat) {

        ret = AVERROR_MUXER_NOT_FOUND;

        goto fail;

    }

    c->streams = av_mallocz(sizeof(*c->streams) * s->nb_streams);

    if (!c->streams) {

        ret = AVERROR(ENOMEM);

        goto fail;

    }

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

        OutputStream *os = &c->streams[i];

        AVFormatContext *ctx;

        AVStream *st;

        AVDictionary *opts = NULL;

        char buf[10];

        if (!s->streams[i]->codec->bit_rate) {

            av_log(s, AV_LOG_ERROR, "No bit rate set for stream %d\n", i);

            ret = AVERROR(EINVAL);

            goto fail;

        }

        snprintf(os->dirname, sizeof(os->dirname), "%s/QualityLevels(%d)", s->filename, s->streams[i]->codec->bit_rate);

        mkdir(os->dirname, 0777);

        ctx = avformat_alloc_context();

        if (!ctx) {

            ret = AVERROR(ENOMEM);

            goto fail;

        }

        os->ctx = ctx;

        ctx->oformat = oformat;

        ctx->interrupt_callback = s->interrupt_callback;

        if (!(st = avformat_new_stream(ctx, NULL))) {

            ret = AVERROR(ENOMEM);

            goto fail;

        }

        avcodec_copy_context(st->codec, s->streams[i]->codec);

        st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;

        ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf), AVIO_FLAG_WRITE, os, NULL, ism_write, ism_seek);

        if (!ctx->pb) {

            ret = AVERROR(ENOMEM);

            goto fail;

        }

        snprintf(buf, sizeof(buf), "%d", c->lookahead_count);

        av_dict_set(&opts, "ism_lookahead", buf, 0);

        av_dict_set(&opts, "movflags", "frag_custom", 0);

        if ((ret = avformat_write_header(ctx, &opts)) < 0) {

             goto fail;

        }

        os->ctx_inited = 1;

        avio_flush(ctx->pb);

        av_dict_free(&opts);

        s->streams[i]->time_base = st->time_base;

        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {

            c->has_video = 1;

            os->stream_type_tag = "video";

            if (st->codec->codec_id == AV_CODEC_ID_H264) {

                os->fourcc = "H264";

            } else if (st->codec->codec_id == AV_CODEC_ID_VC1) {

                os->fourcc = "WVC1";

            } else {

                av_log(s, AV_LOG_ERROR, "Unsupported video codec\n");

                ret = AVERROR(EINVAL);

                goto fail;

            }

        } else {

            c->has_audio = 1;

            os->stream_type_tag = "audio";

            if (st->codec->codec_id == AV_CODEC_ID_AAC) {

                os->fourcc = "AACL";

                os->audio_tag = 0xff;

            } else if (st->codec->codec_id == AV_CODEC_ID_WMAPRO) {

                os->fourcc = "WMAP";

                os->audio_tag = 0x0162;

            } else {

                av_log(s, AV_LOG_ERROR, "Unsupported audio codec\n");

                ret = AVERROR(EINVAL);

                goto fail;

            }

            os->packet_size = st->codec->block_align ? st->codec->block_align : 4;

        }

        get_private_data(os);

    }

    if (!c->has_video && c->min_frag_duration <= 0) {

        av_log(s, AV_LOG_WARNING, "no video stream and no min frag duration set\n");

        ret = AVERROR(EINVAL);

    }

    ret = write_manifest(s, 0);

fail:

    if (ret)

        ism_free(s);

    return ret;

}


static void gradfun_filter_line_mmxext(uint8_t *dst, uint8_t *src, uint16_t *dc,

                                       int width, int thresh,

                                       const uint16_t *dithers)

{

    intptr_t x;

    if (width & 3) {

        x = width & ~3;

        ff_gradfun_filter_line_c(dst + x, src + x, dc + x / 2, width - x, thresh, dithers);

        width = x;

    }

    x = -width;

    __asm__ volatile(

        "movd          %4, %%mm5 \n"

        "pxor       %%mm7, %%mm7 \n"

        "pshufw $0, %%mm5, %%mm5 \n"

        "movq          %6, %%mm6 \n"

        "movq          %5, %%mm4 \n"

        "1: \n"

        "movd     (%2,%0), %%mm0 \n"

        "movd     (%3,%0), %%mm1 \n"

        "punpcklbw  %%mm7, %%mm0 \n"

        "punpcklwd  %%mm1, %%mm1 \n"

        "psllw         $7, %%mm0 \n"

        "pxor       %%mm2, %%mm2 \n"

        "psubw      %%mm0, %%mm1 \n" // delta = dc - pix

        "psubw      %%mm1, %%mm2 \n"

        "pmaxsw     %%mm1, %%mm2 \n"

        "pmulhuw    %%mm5, %%mm2 \n" // m = abs(delta) * thresh >> 16

        "psubw      %%mm6, %%mm2 \n"

        "pminsw     %%mm7, %%mm2 \n" // m = -max(0, 127-m)

        "pmullw     %%mm2, %%mm2 \n"

        "paddw      %%mm4, %%mm0 \n" // pix += dither

        "pmulhw     %%mm2, %%mm1 \n"

        "psllw         $2, %%mm1 \n" // m = m*m*delta >> 14

        "paddw      %%mm1, %%mm0 \n" // pix += m

        "psraw         $7, %%mm0 \n"

        "packuswb   %%mm0, %%mm0 \n"

        "movd       %%mm0, (%1,%0) \n" // dst = clip(pix>>7)

        "add           $4, %0 \n"

        "jl 1b \n"

        "emms \n"

        :"+r"(x)

        :"r"(dst+width), "r"(src+width), "r"(dc+width/2),

         "rm"(thresh), "m"(*dithers), "m"(*pw_7f)

        :"memory"

    );

}


static void bdrv_mirror_top_refresh_filename(BlockDriverState *bs, QDict *opts)

{

    bdrv_refresh_filename(bs->backing->bs);

    pstrcpy(bs->exact_filename, sizeof(bs->exact_filename),

            bs->backing->bs->filename);


static CharDriverState *qemu_chr_open_file_out(QemuOpts *opts)

{

    int fd_out;

    TFR(fd_out = open(qemu_opt_get(opts, "path"),

                      O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));

    if (fd_out < 0)

        return NULL;

    return qemu_chr_open_fd(-1, fd_out);

}


static SchroBuffer *find_next_parse_unit(SchroParseUnitContext *parse_ctx)

{

    SchroBuffer *enc_buf = NULL;

    int next_pu_offset = 0;

    unsigned char *in_buf;

    if (parse_ctx->buf_size < 13 ||

        parse_ctx->buf[0] != 'B' ||

        parse_ctx->buf[1] != 'B' ||

        parse_ctx->buf[2] != 'C' ||

        parse_ctx->buf[3] != 'D')

        return NULL;

    next_pu_offset = (parse_ctx->buf[5] << 24) +

                     (parse_ctx->buf[6] << 16) +

                     (parse_ctx->buf[7] <<  8) +

                      parse_ctx->buf[8];

    if (next_pu_offset == 0 &&

        SCHRO_PARSE_CODE_IS_END_OF_SEQUENCE(parse_ctx->buf[4]))

        next_pu_offset = 13;

    if (next_pu_offset <= 0 || parse_ctx->buf_size < next_pu_offset)

        return NULL;

    in_buf = av_malloc(next_pu_offset);

    if (!in_buf) {

        av_log(parse_ctx, AV_LOG_ERROR, "Unable to allocate input buffer\n");

        return NULL;

    }

    memcpy(in_buf, parse_ctx->buf, next_pu_offset);

    enc_buf       = schro_buffer_new_with_data(in_buf, next_pu_offset);

    enc_buf->free = libschroedinger_decode_buffer_free;

    enc_buf->priv = in_buf;

    parse_ctx->buf      += next_pu_offset;

    parse_ctx->buf_size -= next_pu_offset;

    return enc_buf;

}


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

    int i, mb_x, mb_y;

    uint16_t buffer[2048][4];

    int left[3], top[3], topleft[3];

    const int linesize= s->linesize[0];

    const int mask= (1<<s->bits)-1;

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

        buffer[0][i]= 1 << (s->bits + point_transform - 1);

    }

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

        const int modified_predictor= mb_y ? predictor : 1;

        uint8_t *ptr = s->picture.data[0] + (linesize * mb_y);

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

            ptr += linesize >> 1;

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

            top[i]= left[i]= topleft[i]= buffer[0][i];

        }

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

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

                s->restart_count = s->restart_interval;

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

                int pred;

                topleft[i]= top[i];

                top[i]= buffer[mb_x][i];

                PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);

                left[i]=

                buffer[mb_x][i]= mask & (pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform));

            }

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

                align_get_bits(&s->gb);

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

            }

        }

        if(s->rct){

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

                ptr[4*mb_x+1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200)>>2);

                ptr[4*mb_x+0] = buffer[mb_x][1] + ptr[4*mb_x+1];

                ptr[4*mb_x+2] = buffer[mb_x][2] + ptr[4*mb_x+1];

            }

        }else if(s->pegasus_rct){

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

                ptr[4*mb_x+1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2])>>2);

                ptr[4*mb_x+0] = buffer[mb_x][1] + ptr[4*mb_x+1];

                ptr[4*mb_x+2] = buffer[mb_x][2] + ptr[4*mb_x+1];

            }

        }else{

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

                ptr[4*mb_x+0] = buffer[mb_x][0];

                ptr[4*mb_x+1] = buffer[mb_x][1];

                ptr[4*mb_x+2] = buffer[mb_x][2];

            }

        }

    }

    return 0;

}


static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, DCTELEM *block,

                                    int n, int qscale, int *overflow)

{

    const uint8_t *scantable= ctx->intra_scantable.scantable;

    const int *qmat = ctx->q_intra_matrix[qscale];

    int last_non_zero = 0;

    ctx->dsp.fdct(block);

    // Divide by 4 with rounding, to compensate scaling of DCT coefficients

    block[0] = (block[0] + 2) >> 2;

    for (int i = 1; i < 64; ++i) {

        int j = scantable[i];

        int sign = block[j] >> 31;

        int level = (block[j] ^ sign) - sign;

        level = level * qmat[j] >> DNX10BIT_QMAT_SHIFT;

        block[j] = (level ^ sign) - sign;

        if (level)

            last_non_zero = i;

    }

    return last_non_zero;

}


static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y,

                             int16_t (*mv_table)[2], int ref_index, int f_code)

{

    MotionEstContext * const c= &s->me;

    int mx = 0, my = 0, dmin = 0;

    int P[10][2];

    const int shift= 1+s->quarter_sample;

    const int mot_stride = s->mb_stride;

    const int mot_xy = mb_y*mot_stride + mb_x;

    uint8_t * const mv_penalty= c->mv_penalty[f_code] + MAX_MV;

    int mv_scale;

    c->penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);

    c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);

    c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);

    c->current_mv_penalty= mv_penalty;

    get_limits(s, 16*mb_x, 16*mb_y);

    if (s->motion_est != FF_ME_ZERO) {

        P_LEFT[0] = mv_table[mot_xy - 1][0];

        P_LEFT[1] = mv_table[mot_xy - 1][1];

        if (P_LEFT[0] > (c->xmax << shift)) P_LEFT[0] = (c->xmax << shift);

        /* special case for first line */

        if (!s->first_slice_line) {

            P_TOP[0]      = mv_table[mot_xy - mot_stride    ][0];

            P_TOP[1]      = mv_table[mot_xy - mot_stride    ][1];

            P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1][0];

            P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1][1];

            if (P_TOP[1] > (c->ymax << shift)) P_TOP[1] = (c->ymax << shift);

            if (P_TOPRIGHT[0] < (c->xmin << shift)) P_TOPRIGHT[0] = (c->xmin << shift);

            if (P_TOPRIGHT[1] > (c->ymax << shift)) P_TOPRIGHT[1] = (c->ymax << shift);

            P_MEDIAN[0] = mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);

            P_MEDIAN[1] = mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);

        }

        c->pred_x = P_LEFT[0];

        c->pred_y = P_LEFT[1];

        if(mv_table == s->b_forw_mv_table){

            mv_scale= (s->pb_time<<16) / (s->pp_time<<shift);

        }else{

            mv_scale= ((s->pb_time - s->pp_time)<<16) / (s->pp_time<<shift);

        }

        dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, ref_index, s->p_mv_table, mv_scale, 0, 16);

    }

    dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, ref_index, 0, 16);

    if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)

        dmin= get_mb_score(s, mx, my, 0, ref_index, 0, 16, 1);

//    s->mb_type[mb_y*s->mb_width + mb_x]= mb_type;

    mv_table[mot_xy][0]= mx;

    mv_table[mot_xy][1]= my;

    return dmin;

}


static av_cold int XAVS_close(AVCodecContext *avctx)

{

    XavsContext *x4 = avctx->priv_data;

    av_freep(&avctx->extradata);

    av_free(x4->sei);

    av_freep(&x4->pts_buffer);

    if (x4->enc)

        xavs_encoder_close(x4->enc);

    av_frame_free(&avctx->coded_frame);

    return 0;

}


int vhdx_parse_log(BlockDriverState *bs, BDRVVHDXState *s, bool *flushed)

{

    int ret = 0;

    VHDXHeader *hdr;

    VHDXLogSequence logs = { 0 };

    hdr = s->headers[s->curr_header];

    *flushed = false;

    /* s->log.hdr is freed in vhdx_close() */

    if (s->log.hdr == NULL) {

        s->log.hdr = qemu_blockalign(bs, sizeof(VHDXLogEntryHeader));

    }

    s->log.offset = hdr->log_offset;

    s->log.length = hdr->log_length;

    if (s->log.offset < VHDX_LOG_MIN_SIZE ||

        s->log.offset % VHDX_LOG_MIN_SIZE) {

        ret = -EINVAL;

        goto exit;

    }

    /* per spec, only log version of 0 is supported */

    if (hdr->log_version != 0) {

        ret = -EINVAL;

        goto exit;

    }

    /* If either the log guid, or log length is zero,

     * then a replay log is not present */

    if (guid_eq(hdr->log_guid, zero_guid)) {

        goto exit;

    }

    if (hdr->log_length == 0) {

        goto exit;

    }

    if (hdr->log_length % VHDX_LOG_MIN_SIZE) {

        ret = -EINVAL;

        goto exit;

    }

    /* The log is present, we need to find if and where there is an active

     * sequence of valid entries present in the log.  */

    ret = vhdx_log_search(bs, s, &logs);

    if (ret < 0) {

        goto exit;

    }

    if (logs.valid) {

        /* now flush the log */

        ret = vhdx_log_flush(bs, s, &logs);

        if (ret < 0) {

            goto exit;

        }

        *flushed = true;

    }

exit:

    return ret;

}