static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)

{

    const char *rn = "invalid";

    if (sel != 0)

        check_insn(ctx, ISA_MIPS32);

    switch (reg) {

    case 0:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));

            rn = "Index";

            break;

        case 1:

            check_insn(ctx, ASE_MT);

            gen_helper_mfc0_mvpcontrol(arg, cpu_env);

            rn = "MVPControl";

            break;

        case 2:

            check_insn(ctx, ASE_MT);

            gen_helper_mfc0_mvpconf0(arg, cpu_env);

            rn = "MVPConf0";

            break;

        case 3:

            check_insn(ctx, ASE_MT);

            gen_helper_mfc0_mvpconf1(arg, cpu_env);

            rn = "MVPConf1";

            break;

        default:

            goto die;

        }

        break;

    case 1:

        switch (sel) {

        case 0:

            gen_helper_mfc0_random(arg, cpu_env);

            rn = "Random";

            break;

        case 1:

            check_insn(ctx, ASE_MT);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));

            rn = "VPEControl";

            break;

        case 2:

            check_insn(ctx, ASE_MT);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));

            rn = "VPEConf0";

            break;

        case 3:

            check_insn(ctx, ASE_MT);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));

            rn = "VPEConf1";

            break;

        case 4:

            check_insn(ctx, ASE_MT);

            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));

            rn = "YQMask";

            break;

        case 5:

            check_insn(ctx, ASE_MT);

            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));

            rn = "VPESchedule";

            break;

        case 6:

            check_insn(ctx, ASE_MT);

            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));

            rn = "VPEScheFBack";

            break;

        case 7:

            check_insn(ctx, ASE_MT);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));

            rn = "VPEOpt";

            break;

        default:

            goto die;

        }

        break;

    case 2:

        switch (sel) {

        case 0:

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));

#if defined(TARGET_MIPS64)

            if (ctx->rxi) {

                TCGv tmp = tcg_temp_new();

                tcg_gen_andi_tl(tmp, arg, (3ull << 62));

                tcg_gen_shri_tl(tmp, tmp, 32);

                tcg_gen_or_tl(arg, arg, tmp);

                tcg_temp_free(tmp);

            }

#endif

            tcg_gen_ext32s_tl(arg, arg);

            rn = "EntryLo0";

            break;

        case 1:

            check_insn(ctx, ASE_MT);

            gen_helper_mfc0_tcstatus(arg, cpu_env);

            rn = "TCStatus";

            break;

        case 2:

            check_insn(ctx, ASE_MT);

            gen_helper_mfc0_tcbind(arg, cpu_env);

            rn = "TCBind";

            break;

        case 3:

            check_insn(ctx, ASE_MT);

            gen_helper_mfc0_tcrestart(arg, cpu_env);

            rn = "TCRestart";

            break;

        case 4:

            check_insn(ctx, ASE_MT);

            gen_helper_mfc0_tchalt(arg, cpu_env);

            rn = "TCHalt";

            break;

        case 5:

            check_insn(ctx, ASE_MT);

            gen_helper_mfc0_tccontext(arg, cpu_env);

            rn = "TCContext";

            break;

        case 6:

            check_insn(ctx, ASE_MT);

            gen_helper_mfc0_tcschedule(arg, cpu_env);

            rn = "TCSchedule";

            break;

        case 7:

            check_insn(ctx, ASE_MT);

            gen_helper_mfc0_tcschefback(arg, cpu_env);

            rn = "TCScheFBack";

            break;

        default:

            goto die;

        }

        break;

    case 3:

        switch (sel) {

        case 0:

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));

#if defined(TARGET_MIPS64)

            if (ctx->rxi) {

                TCGv tmp = tcg_temp_new();

                tcg_gen_andi_tl(tmp, arg, (3ull << 62));

                tcg_gen_shri_tl(tmp, tmp, 32);

                tcg_gen_or_tl(arg, arg, tmp);

                tcg_temp_free(tmp);

            }

#endif

            tcg_gen_ext32s_tl(arg, arg);

            rn = "EntryLo1";

            break;

        default:

            goto die;

        }

        break;

    case 4:

        switch (sel) {

        case 0:

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "Context";

            break;

        case 1:

//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */

            rn = "ContextConfig";

            goto die;

//            break;

        case 2:

            if (ctx->ulri) {

                tcg_gen_ld32s_tl(arg, cpu_env,

                                 offsetof(CPUMIPSState,

                                          active_tc.CP0_UserLocal));

                rn = "UserLocal";

            } else {

                tcg_gen_movi_tl(arg, 0);

            }

            break;

        default:

            goto die;

        }

        break;

    case 5:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));

            rn = "PageMask";

            break;

        case 1:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));

            rn = "PageGrain";

            break;

        default:

            goto die;

        }

        break;

    case 6:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));

            rn = "Wired";

            break;

        case 1:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));

            rn = "SRSConf0";

            break;

        case 2:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));

            rn = "SRSConf1";

            break;

        case 3:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));

            rn = "SRSConf2";

            break;

        case 4:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));

            rn = "SRSConf3";

            break;

        case 5:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));

            rn = "SRSConf4";

            break;

        default:

            goto die;

        }

        break;

    case 7:

        switch (sel) {

        case 0:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));

            rn = "HWREna";

            break;

        default:

            goto die;

        }

        break;

    case 8:

        switch (sel) {

        case 0:

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "BadVAddr";

            break;

        case 1:

            if (ctx->bi) {

                gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));

                rn = "BadInstr";

            } else {

                gen_mfc0_unimplemented(ctx, arg);

            }

            break;

        case 2:

            if (ctx->bp) {

                gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));

                rn = "BadInstrP";

            } else {

                gen_mfc0_unimplemented(ctx, arg);

            }

            break;

        default:

            goto die;

        }

        break;

    case 9:

        switch (sel) {

        case 0:

            /* Mark as an IO operation because we read the time.  */

            if (use_icount)

                gen_io_start();

            gen_helper_mfc0_count(arg, cpu_env);

            if (use_icount) {

                gen_io_end();

            }

            /* Break the TB to be able to take timer interrupts immediately

               after reading count.  */

            ctx->bstate = BS_STOP;

            rn = "Count";

            break;

        /* 6,7 are implementation dependent */

        default:

            goto die;

        }

        break;

    case 10:

        switch (sel) {

        case 0:

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "EntryHi";

            break;

        default:

            goto die;

        }

        break;

    case 11:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));

            rn = "Compare";

            break;

        /* 6,7 are implementation dependent */

        default:

            goto die;

        }

        break;

    case 12:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));

            rn = "Status";

            break;

        case 1:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));

            rn = "IntCtl";

            break;

        case 2:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));

            rn = "SRSCtl";

            break;

        case 3:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));

            rn = "SRSMap";

            break;

        default:

            goto die;

       }

        break;

    case 13:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));

            rn = "Cause";

            break;

        default:

            goto die;

       }

        break;

    case 14:

        switch (sel) {

        case 0:

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "EPC";

            break;

        default:

            goto die;

        }

        break;

    case 15:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));

            rn = "PRid";

            break;

        case 1:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));

            rn = "EBase";

            break;

        default:

            goto die;

       }

        break;

    case 16:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));

            rn = "Config";

            break;

        case 1:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));

            rn = "Config1";

            break;

        case 2:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));

            rn = "Config2";

            break;

        case 3:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));

            rn = "Config3";

            break;

        case 4:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));

            rn = "Config4";

            break;

        case 5:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));

            rn = "Config5";

            break;

        /* 6,7 are implementation dependent */

        case 6:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));

            rn = "Config6";

            break;

        case 7:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));

            rn = "Config7";

            break;

        default:

            goto die;

        }

        break;

    case 17:

        switch (sel) {

        case 0:

            gen_helper_mfc0_lladdr(arg, cpu_env);

            rn = "LLAddr";

            break;

        default:

            goto die;

        }

        break;

    case 18:

        switch (sel) {

        case 0 ... 7:

            gen_helper_1e0i(mfc0_watchlo, arg, sel);

            rn = "WatchLo";

            break;

        default:

            goto die;

        }

        break;

    case 19:

        switch (sel) {

        case 0 ...7:

            gen_helper_1e0i(mfc0_watchhi, arg, sel);

            rn = "WatchHi";

            break;

        default:

            goto die;

        }

        break;

    case 20:

        switch (sel) {

        case 0:

#if defined(TARGET_MIPS64)

            check_insn(ctx, ISA_MIPS3);

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "XContext";

            break;

#endif

        default:

            goto die;

        }

        break;

    case 21:

       /* Officially reserved, but sel 0 is used for R1x000 framemask */

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));

            rn = "Framemask";

            break;

        default:

            goto die;

        }

        break;

    case 22:

        tcg_gen_movi_tl(arg, 0); /* unimplemented */

        rn = "'Diagnostic"; /* implementation dependent */

        break;

    case 23:

        switch (sel) {

        case 0:

            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */

            rn = "Debug";

            break;

        case 1:

//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */

            rn = "TraceControl";

//            break;

        case 2:

//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */

            rn = "TraceControl2";

//            break;

        case 3:

//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */

            rn = "UserTraceData";

//            break;

        case 4:

//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */

            rn = "TraceBPC";

//            break;

        default:

            goto die;

        }

        break;

    case 24:

        switch (sel) {

        case 0:

            /* EJTAG support */

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "DEPC";

            break;

        default:

            goto die;

        }

        break;

    case 25:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));

            rn = "Performance0";

            break;

        case 1:

//            gen_helper_mfc0_performance1(arg);

            rn = "Performance1";

//            break;

        case 2:

//            gen_helper_mfc0_performance2(arg);

            rn = "Performance2";

//            break;

        case 3:

//            gen_helper_mfc0_performance3(arg);

            rn = "Performance3";

//            break;

        case 4:

//            gen_helper_mfc0_performance4(arg);

            rn = "Performance4";

//            break;

        case 5:

//            gen_helper_mfc0_performance5(arg);

            rn = "Performance5";

//            break;

        case 6:

//            gen_helper_mfc0_performance6(arg);

            rn = "Performance6";

//            break;

        case 7:

//            gen_helper_mfc0_performance7(arg);

            rn = "Performance7";

//            break;

        default:

            goto die;

        }

        break;

    case 26:

        tcg_gen_movi_tl(arg, 0); /* unimplemented */

        rn = "ECC";

        break;

    case 27:

        switch (sel) {

        case 0 ... 3:

            tcg_gen_movi_tl(arg, 0); /* unimplemented */

            rn = "CacheErr";

            break;

        default:

            goto die;

        }

        break;

    case 28:

        switch (sel) {

        case 0:

        case 2:

        case 4:

        case 6:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));

            rn = "TagLo";

            break;

        case 1:

        case 3:

        case 5:

        case 7:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));

            rn = "DataLo";

            break;

        default:

            goto die;

        }

        break;

    case 29:

        switch (sel) {

        case 0:

        case 2:

        case 4:

        case 6:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));

            rn = "TagHi";

            break;

        case 1:

        case 3:

        case 5:

        case 7:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));

            rn = "DataHi";

            break;

        default:

            goto die;

        }

        break;

    case 30:

        switch (sel) {

        case 0:

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "ErrorEPC";

            break;

        default:

            goto die;

        }

        break;

    case 31:

        switch (sel) {

        case 0:

            /* EJTAG support */

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));

            rn = "DESAVE";

            break;

        case 2 ... 7:

            if (ctx->kscrexist & (1 << sel)) {

                tcg_gen_ld_tl(arg, cpu_env,

                              offsetof(CPUMIPSState, CP0_KScratch[sel-2]));

                tcg_gen_ext32s_tl(arg, arg);

                rn = "KScratch";

            } else {

                gen_mfc0_unimplemented(ctx, arg);

            }

            break;

        default:

            goto die;

        }

        break;

    default:

       goto die;

    }

    (void)rn; /* avoid a compiler warning */

    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);

    return;

die:

    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);

    generate_exception(ctx, EXCP_RI);

}


static int64_t cvtnum(const char *s)

{

    char *end;

    return qemu_strtosz_suffix(s, &end, QEMU_STRTOSZ_DEFSUFFIX_B);

}


static void qpci_spapr_io_writeb(QPCIBus *bus, void *addr, uint8_t value)

{

    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);

    uint64_t port = (uintptr_t)addr;

    if (port < s->pio.size) {

        writeb(s->pio_cpu_base + port, value);

    } else {

        writeb(s->mmio_cpu_base + port, value);

    }

}


static void *rcu_q_updater(void *arg)

{

    int j, target_el;

    long long n_updates_local = 0;

    long long n_removed_local = 0;

    struct list_element *el, *prev_el;

    *(struct rcu_reader_data **)arg = &rcu_reader;

    atomic_inc(&nthreadsrunning);

    while (goflag == GOFLAG_INIT) {

        g_usleep(1000);

    }

    while (goflag == GOFLAG_RUN) {

        target_el = select_random_el(RCU_Q_LEN);

        j = 0;

        /* FOREACH_RCU could work here but let's use both macros */

        QLIST_FOREACH_SAFE_RCU(prev_el, &Q_list_head, entry, el) {

            j++;

            if (target_el == j) {

                QLIST_REMOVE_RCU(prev_el, entry);

                /* may be more than one updater in the future */

                call_rcu1(&prev_el->rcu, reclaim_list_el);

                n_removed_local++;

                break;

            }

        }

        if (goflag == GOFLAG_STOP) {

            break;

        }

        target_el = select_random_el(RCU_Q_LEN);

        j = 0;

        QLIST_FOREACH_RCU(el, &Q_list_head, entry) {

            j++;

            if (target_el == j) {

                prev_el = g_new(struct list_element, 1);

                atomic_add(&n_nodes, 1);

                prev_el->val = atomic_read(&n_nodes);

                QLIST_INSERT_BEFORE_RCU(el, prev_el, entry);

                break;

            }

        }

        n_updates_local += 2;

        synchronize_rcu();

    }

    synchronize_rcu();

    atomic_add(&n_updates, n_updates_local);

    atomic_add(&n_nodes_removed, n_removed_local);

    return NULL;

}


int Configure(void **ctxp, int argc, char *argv[])

{

    ContextInfo *ci;

    int c;

    *ctxp = av_mallocz(sizeof(ContextInfo));

    ci = (ContextInfo *) *ctxp;

    optind = 1;

    ci->dir = "/tmp";

    ci->threshold = 100;

    ci->file_limit = 100;

    ci->min_interval = 1000000;

    ci->inset = 10;     /* Percent */

    while ((c = getopt(argc, argv, "w:i:dh:s:v:zl:t:D:")) > 0) {

        switch (c) {

            case 'h':

                dorange(optarg, &ci->dark.h, &ci->bright.h, 360);

                break;

            case 's':

                dorange(optarg, &ci->dark.s, &ci->bright.s, 255);

                break;

            case 'v':

                dorange(optarg, &ci->dark.v, &ci->bright.v, 255);

                break;

            case 'z':

                ci->zapping = 1;

                break;

            case 'l':

                ci->file_limit = atoi(optarg);

                break;

            case 'i':

                ci->min_interval = 1000000 * atof(optarg);

                break;

            case 't':

                ci->threshold = atof(optarg) * 1000;

                if (ci->threshold > 1000 || ci->threshold < 0) {

                    av_log(NULL, AV_LOG_ERROR, "Invalid threshold value '%s' (range is 0-1)\n", optarg);

                    return -1;

                }

                break;

            case 'w':

                ci->min_width = atoi(optarg);

                break;

            case 'd':

                ci->debug++;

                break;

            case 'D':

                ci->dir = av_strdup(optarg);

                break;

            default:

                av_log(NULL, AV_LOG_ERROR, "Unrecognized argument '%s'\n", argv[optind]);

                return -1;

        }

    }

    av_log(NULL, AV_LOG_INFO, "Fish detector configured:\n");

    av_log(NULL, AV_LOG_INFO, "    HSV range: %d,%d,%d - %d,%d,%d\n",

                        ci->dark.h,

                        ci->dark.s,

                        ci->dark.v,

                        ci->bright.h,

                        ci->bright.s,

                        ci->bright.v);

    av_log(NULL, AV_LOG_INFO, "    Threshold is %d%% pixels\n", ci->threshold / 10);

    return 0;

}


static int local_chown(FsContext *ctx, const char *path, uid_t uid, gid_t gid)

{

    return chown(rpath(ctx, path), uid, gid);

}


static void disas_arm_insn(DisasContext *s, unsigned int insn)

{

    unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;

    TCGv_i32 tmp;

    TCGv_i32 tmp2;

    TCGv_i32 tmp3;

    TCGv_i32 addr;

    TCGv_i64 tmp64;

    /* M variants do not implement ARM mode.  */

    if (arm_dc_feature(s, ARM_FEATURE_M)) {

        goto illegal_op;

    }

    cond = insn >> 28;

    if (cond == 0xf){

        /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we

         * choose to UNDEF. In ARMv5 and above the space is used

         * for miscellaneous unconditional instructions.

         */

        ARCH(5);

        /* Unconditional instructions.  */

        if (((insn >> 25) & 7) == 1) {

            /* NEON Data processing.  */

            if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {

                goto illegal_op;

            }

            if (disas_neon_data_insn(s, insn)) {

                goto illegal_op;

            }

            return;

        }

        if ((insn & 0x0f100000) == 0x04000000) {

            /* NEON load/store.  */

            if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {

                goto illegal_op;

            }

            if (disas_neon_ls_insn(s, insn)) {

                goto illegal_op;

            }

            return;

        }

        if ((insn & 0x0f000e10) == 0x0e000a00) {

            /* VFP.  */

            if (disas_vfp_insn(s, insn)) {

                goto illegal_op;

            }

            return;

        }

        if (((insn & 0x0f30f000) == 0x0510f000) ||

            ((insn & 0x0f30f010) == 0x0710f000)) {

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

                /* PLDW; v7MP */

                if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {

                    goto illegal_op;

                }

            }

            /* Otherwise PLD; v5TE+ */

            ARCH(5TE);

            return;

        }

        if (((insn & 0x0f70f000) == 0x0450f000) ||

            ((insn & 0x0f70f010) == 0x0650f000)) {

            ARCH(7);

            return; /* PLI; V7 */

        }

        if (((insn & 0x0f700000) == 0x04100000) ||

            ((insn & 0x0f700010) == 0x06100000)) {

            if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {

                goto illegal_op;

            }

            return; /* v7MP: Unallocated memory hint: must NOP */

        }

        if ((insn & 0x0ffffdff) == 0x01010000) {

            ARCH(6);

            /* setend */

            if (((insn >> 9) & 1) != s->bswap_code) {

                /* Dynamic endianness switching not implemented. */

                qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");

                goto illegal_op;

            }

            return;

        } else if ((insn & 0x0fffff00) == 0x057ff000) {

            switch ((insn >> 4) & 0xf) {

            case 1: /* clrex */

                ARCH(6K);

                gen_clrex(s);

                return;

            case 4: /* dsb */

            case 5: /* dmb */

                ARCH(7);

                /* We don't emulate caches so these are a no-op.  */

                return;

            case 6: /* isb */

                /* We need to break the TB after this insn to execute

                 * self-modifying code correctly and also to take

                 * any pending interrupts immediately.

                 */

                gen_lookup_tb(s);

                return;

            default:

                goto illegal_op;

            }

        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {

            /* srs */

            if (IS_USER(s)) {

                goto illegal_op;

            }

            ARCH(6);

            gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));

            return;

        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {

            /* rfe */

            int32_t offset;

            if (IS_USER(s))

                goto illegal_op;

            ARCH(6);

            rn = (insn >> 16) & 0xf;

            addr = load_reg(s, rn);

            i = (insn >> 23) & 3;

            switch (i) {

            case 0: offset = -4; break; /* DA */

            case 1: offset = 0; break; /* IA */

            case 2: offset = -8; break; /* DB */

            case 3: offset = 4; break; /* IB */

            default: abort();

            }

            if (offset)

                tcg_gen_addi_i32(addr, addr, offset);

            /* Load PC into tmp and CPSR into tmp2.  */

            tmp = tcg_temp_new_i32();

            gen_aa32_ld32u(tmp, addr, get_mem_index(s));

            tcg_gen_addi_i32(addr, addr, 4);

            tmp2 = tcg_temp_new_i32();

            gen_aa32_ld32u(tmp2, addr, get_mem_index(s));

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

                /* Base writeback.  */

                switch (i) {

                case 0: offset = -8; break;

                case 1: offset = 4; break;

                case 2: offset = -4; break;

                case 3: offset = 0; break;

                default: abort();

                }

                if (offset)

                    tcg_gen_addi_i32(addr, addr, offset);

                store_reg(s, rn, addr);

            } else {

                tcg_temp_free_i32(addr);

            }

            gen_rfe(s, tmp, tmp2);

            return;

        } else if ((insn & 0x0e000000) == 0x0a000000) {

            /* branch link and change to thumb (blx <offset>) */

            int32_t offset;

            val = (uint32_t)s->pc;

            tmp = tcg_temp_new_i32();

            tcg_gen_movi_i32(tmp, val);

            store_reg(s, 14, tmp);

            /* Sign-extend the 24-bit offset */

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

            /* offset * 4 + bit24 * 2 + (thumb bit) */

            val += (offset << 2) | ((insn >> 23) & 2) | 1;

            /* pipeline offset */

            val += 4;

            /* protected by ARCH(5); above, near the start of uncond block */

            gen_bx_im(s, val);

            return;

        } else if ((insn & 0x0e000f00) == 0x0c000100) {

            if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {

                /* iWMMXt register transfer.  */

                if (extract32(s->c15_cpar, 1, 1)) {

                    if (!disas_iwmmxt_insn(s, insn)) {

                        return;

                    }

                }

            }

        } else if ((insn & 0x0fe00000) == 0x0c400000) {

            /* Coprocessor double register transfer.  */

            ARCH(5TE);

        } else if ((insn & 0x0f000010) == 0x0e000010) {

            /* Additional coprocessor register transfer.  */

        } else if ((insn & 0x0ff10020) == 0x01000000) {

            uint32_t mask;

            uint32_t val;

            /* cps (privileged) */

            if (IS_USER(s))

                return;

            mask = val = 0;

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

                if (insn & (1 << 8))

                    mask |= CPSR_A;

                if (insn & (1 << 7))

                    mask |= CPSR_I;

                if (insn & (1 << 6))

                    mask |= CPSR_F;

                if (insn & (1 << 18))

                    val |= mask;

            }

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

                mask |= CPSR_M;

                val |= (insn & 0x1f);

            }

            if (mask) {

                gen_set_psr_im(s, mask, 0, val);

            }

            return;

        }

        goto illegal_op;

    }

    if (cond != 0xe) {

        /* if not always execute, we generate a conditional jump to

           next instruction */

        s->condlabel = gen_new_label();

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

        s->condjmp = 1;

    }

    if ((insn & 0x0f900000) == 0x03000000) {

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

            ARCH(6T2);

            rd = (insn >> 12) & 0xf;

            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);

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

                /* MOVW */

                tmp = tcg_temp_new_i32();

                tcg_gen_movi_i32(tmp, val);

            } else {

                /* MOVT */

                tmp = load_reg(s, rd);

                tcg_gen_ext16u_i32(tmp, tmp);

                tcg_gen_ori_i32(tmp, tmp, val << 16);

            }

            store_reg(s, rd, tmp);

        } else {

            if (((insn >> 12) & 0xf) != 0xf)

                goto illegal_op;

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

                gen_nop_hint(s, insn & 0xff);

            } else {

                /* CPSR = immediate */

                val = insn & 0xff;

                shift = ((insn >> 8) & 0xf) * 2;

                if (shift)

                    val = (val >> shift) | (val << (32 - shift));

                i = ((insn & (1 << 22)) != 0);

                if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),

                                   i, val)) {

                    goto illegal_op;

                }

            }

        }

    } else if ((insn & 0x0f900000) == 0x01000000

               && (insn & 0x00000090) != 0x00000090) {

        /* miscellaneous instructions */

        op1 = (insn >> 21) & 3;

        sh = (insn >> 4) & 0xf;

        rm = insn & 0xf;

        switch (sh) {

        case 0x0: /* move program status register */

            if (op1 & 1) {

                /* PSR = reg */

                tmp = load_reg(s, rm);

                i = ((op1 & 2) != 0);

                if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))

                    goto illegal_op;

            } else {

                /* reg = PSR */

                rd = (insn >> 12) & 0xf;

                if (op1 & 2) {

                    if (IS_USER(s))

                        goto illegal_op;

                    tmp = load_cpu_field(spsr);

                } else {

                    tmp = tcg_temp_new_i32();

                    gen_helper_cpsr_read(tmp, cpu_env);

                }

                store_reg(s, rd, tmp);

            }

            break;

        case 0x1:

            if (op1 == 1) {

                /* branch/exchange thumb (bx).  */

                ARCH(4T);

                tmp = load_reg(s, rm);

                gen_bx(s, tmp);

            } else if (op1 == 3) {

                /* clz */

                ARCH(5);

                rd = (insn >> 12) & 0xf;

                tmp = load_reg(s, rm);

                gen_helper_clz(tmp, tmp);

                store_reg(s, rd, tmp);

            } else {

                goto illegal_op;

            }

            break;

        case 0x2:

            if (op1 == 1) {

                ARCH(5J); /* bxj */

                /* Trivial implementation equivalent to bx.  */

                tmp = load_reg(s, rm);

                gen_bx(s, tmp);

            } else {

                goto illegal_op;

            }

            break;

        case 0x3:

            if (op1 != 1)

              goto illegal_op;

            ARCH(5);

            /* branch link/exchange thumb (blx) */

            tmp = load_reg(s, rm);

            tmp2 = tcg_temp_new_i32();

            tcg_gen_movi_i32(tmp2, s->pc);

            store_reg(s, 14, tmp2);

            gen_bx(s, tmp);

            break;

        case 0x4:

        {

            /* crc32/crc32c */

            uint32_t c = extract32(insn, 8, 4);

            /* Check this CPU supports ARMv8 CRC instructions.

             * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.

             * Bits 8, 10 and 11 should be zero.

             */

            if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||

                (c & 0xd) != 0) {

                goto illegal_op;

            }

            rn = extract32(insn, 16, 4);

            rd = extract32(insn, 12, 4);

            tmp = load_reg(s, rn);

            tmp2 = load_reg(s, rm);

            if (op1 == 0) {

                tcg_gen_andi_i32(tmp2, tmp2, 0xff);

            } else if (op1 == 1) {

                tcg_gen_andi_i32(tmp2, tmp2, 0xffff);

            }

            tmp3 = tcg_const_i32(1 << op1);

            if (c & 0x2) {

                gen_helper_crc32c(tmp, tmp, tmp2, tmp3);

            } else {

                gen_helper_crc32(tmp, tmp, tmp2, tmp3);

            }

            tcg_temp_free_i32(tmp2);

            tcg_temp_free_i32(tmp3);

            store_reg(s, rd, tmp);

            break;

        }

        case 0x5: /* saturating add/subtract */

            ARCH(5TE);

            rd = (insn >> 12) & 0xf;

            rn = (insn >> 16) & 0xf;

            tmp = load_reg(s, rm);

            tmp2 = load_reg(s, rn);

            if (op1 & 2)

                gen_helper_double_saturate(tmp2, cpu_env, tmp2);

            if (op1 & 1)

                gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);

            else

                gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);

            tcg_temp_free_i32(tmp2);

            store_reg(s, rd, tmp);

            break;

        case 7:

        {

            int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);

            switch (op1) {

            case 1:

                /* bkpt */

                ARCH(5);

                gen_exception_insn(s, 4, EXCP_BKPT,

                                   syn_aa32_bkpt(imm16, false),

                                   default_exception_el(s));

                break;

            case 2:

                /* Hypervisor call (v7) */

                ARCH(7);

                if (IS_USER(s)) {

                    goto illegal_op;

                }

                gen_hvc(s, imm16);

                break;

            case 3:

                /* Secure monitor call (v6+) */

                ARCH(6K);

                if (IS_USER(s)) {

                    goto illegal_op;

                }

                gen_smc(s);

                break;

            default:

                goto illegal_op;

            }

            break;

        }

        case 0x8: /* signed multiply */

        case 0xa:

        case 0xc:

        case 0xe:

            ARCH(5TE);

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

            rn = (insn >> 12) & 0xf;

            rd = (insn >> 16) & 0xf;

            if (op1 == 1) {

                /* (32 * 16) >> 16 */

                tmp = load_reg(s, rm);

                tmp2 = load_reg(s, rs);

                if (sh & 4)

                    tcg_gen_sari_i32(tmp2, tmp2, 16);

                else

                    gen_sxth(tmp2);

                tmp64 = gen_muls_i64_i32(tmp, tmp2);

                tcg_gen_shri_i64(tmp64, tmp64, 16);

                tmp = tcg_temp_new_i32();

                tcg_gen_extrl_i64_i32(tmp, tmp64);

                tcg_temp_free_i64(tmp64);

                if ((sh & 2) == 0) {

                    tmp2 = load_reg(s, rn);

                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);

                    tcg_temp_free_i32(tmp2);

                }

                store_reg(s, rd, tmp);

            } else {

                /* 16 * 16 */

                tmp = load_reg(s, rm);

                tmp2 = load_reg(s, rs);

                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);

                tcg_temp_free_i32(tmp2);

                if (op1 == 2) {

                    tmp64 = tcg_temp_new_i64();

                    tcg_gen_ext_i32_i64(tmp64, tmp);

                    tcg_temp_free_i32(tmp);

                    gen_addq(s, tmp64, rn, rd);

                    gen_storeq_reg(s, rn, rd, tmp64);

                    tcg_temp_free_i64(tmp64);

                } else {

                    if (op1 == 0) {

                        tmp2 = load_reg(s, rn);

                        gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);

                        tcg_temp_free_i32(tmp2);

                    }

                    store_reg(s, rd, tmp);

                }

            }

            break;

        default:

            goto illegal_op;

        }

    } else if (((insn & 0x0e000000) == 0 &&

                (insn & 0x00000090) != 0x90) ||

               ((insn & 0x0e000000) == (1 << 25))) {

        int set_cc, logic_cc, shiftop;

        op1 = (insn >> 21) & 0xf;

        set_cc = (insn >> 20) & 1;

        logic_cc = table_logic_cc[op1] & set_cc;

        /* data processing instruction */

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

            /* immediate operand */

            val = insn & 0xff;

            shift = ((insn >> 8) & 0xf) * 2;

            if (shift) {

                val = (val >> shift) | (val << (32 - shift));

            }

            tmp2 = tcg_temp_new_i32();

            tcg_gen_movi_i32(tmp2, val);

            if (logic_cc && shift) {

                gen_set_CF_bit31(tmp2);

            }

        } else {

            /* register */

            rm = (insn) & 0xf;

            tmp2 = load_reg(s, rm);

            shiftop = (insn >> 5) & 3;

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

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

                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);

            } else {

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

                tmp = load_reg(s, rs);

                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);

            }

        }

        if (op1 != 0x0f && op1 != 0x0d) {

            rn = (insn >> 16) & 0xf;

            tmp = load_reg(s, rn);

        } else {

            TCGV_UNUSED_I32(tmp);

        }

        rd = (insn >> 12) & 0xf;

        switch(op1) {

        case 0x00:

            tcg_gen_and_i32(tmp, tmp, tmp2);

            if (logic_cc) {

                gen_logic_CC(tmp);

            }

            store_reg_bx(s, rd, tmp);

            break;

        case 0x01:

            tcg_gen_xor_i32(tmp, tmp, tmp2);

            if (logic_cc) {

                gen_logic_CC(tmp);

            }

            store_reg_bx(s, rd, tmp);

            break;

        case 0x02:

            if (set_cc && rd == 15) {

                /* SUBS r15, ... is used for exception return.  */

                if (IS_USER(s)) {

                    goto illegal_op;

                }

                gen_sub_CC(tmp, tmp, tmp2);

                gen_exception_return(s, tmp);

            } else {

                if (set_cc) {

                    gen_sub_CC(tmp, tmp, tmp2);

                } else {

                    tcg_gen_sub_i32(tmp, tmp, tmp2);

                }

                store_reg_bx(s, rd, tmp);

            }

            break;

        case 0x03:

            if (set_cc) {

                gen_sub_CC(tmp, tmp2, tmp);

            } else {

                tcg_gen_sub_i32(tmp, tmp2, tmp);

            }

            store_reg_bx(s, rd, tmp);

            break;

        case 0x04:

            if (set_cc) {

                gen_add_CC(tmp, tmp, tmp2);

            } else {

                tcg_gen_add_i32(tmp, tmp, tmp2);

            }

            store_reg_bx(s, rd, tmp);

            break;

        case 0x05:

            if (set_cc) {

                gen_adc_CC(tmp, tmp, tmp2);

            } else {

                gen_add_carry(tmp, tmp, tmp2);

            }

            store_reg_bx(s, rd, tmp);

            break;

        case 0x06:

            if (set_cc) {

                gen_sbc_CC(tmp, tmp, tmp2);

            } else {

                gen_sub_carry(tmp, tmp, tmp2);

            }

            store_reg_bx(s, rd, tmp);

            break;

        case 0x07:

            if (set_cc) {

                gen_sbc_CC(tmp, tmp2, tmp);

            } else {

                gen_sub_carry(tmp, tmp2, tmp);

            }

            store_reg_bx(s, rd, tmp);

            break;

        case 0x08:

            if (set_cc) {

                tcg_gen_and_i32(tmp, tmp, tmp2);

                gen_logic_CC(tmp);

            }

            tcg_temp_free_i32(tmp);

            break;

        case 0x09:

            if (set_cc) {

                tcg_gen_xor_i32(tmp, tmp, tmp2);

                gen_logic_CC(tmp);

            }

            tcg_temp_free_i32(tmp);

            break;

        case 0x0a:

            if (set_cc) {

                gen_sub_CC(tmp, tmp, tmp2);

            }

            tcg_temp_free_i32(tmp);

            break;

        case 0x0b:

            if (set_cc) {

                gen_add_CC(tmp, tmp, tmp2);

            }

            tcg_temp_free_i32(tmp);

            break;

        case 0x0c:

            tcg_gen_or_i32(tmp, tmp, tmp2);

            if (logic_cc) {

                gen_logic_CC(tmp);

            }

            store_reg_bx(s, rd, tmp);

            break;

        case 0x0d:

            if (logic_cc && rd == 15) {

                /* MOVS r15, ... is used for exception return.  */

                if (IS_USER(s)) {

                    goto illegal_op;

                }

                gen_exception_return(s, tmp2);

            } else {

                if (logic_cc) {

                    gen_logic_CC(tmp2);

                }

                store_reg_bx(s, rd, tmp2);

            }

            break;

        case 0x0e:

            tcg_gen_andc_i32(tmp, tmp, tmp2);

            if (logic_cc) {

                gen_logic_CC(tmp);

            }

            store_reg_bx(s, rd, tmp);

            break;

        default:

        case 0x0f:

            tcg_gen_not_i32(tmp2, tmp2);

            if (logic_cc) {

                gen_logic_CC(tmp2);

            }

            store_reg_bx(s, rd, tmp2);

            break;

        }

        if (op1 != 0x0f && op1 != 0x0d) {

            tcg_temp_free_i32(tmp2);

        }

    } else {

        /* other instructions */

        op1 = (insn >> 24) & 0xf;

        switch(op1) {

        case 0x0:

        case 0x1:

            /* multiplies, extra load/stores */

            sh = (insn >> 5) & 3;

            if (sh == 0) {

                if (op1 == 0x0) {

                    rd = (insn >> 16) & 0xf;

                    rn = (insn >> 12) & 0xf;

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

                    rm = (insn) & 0xf;

                    op1 = (insn >> 20) & 0xf;

                    switch (op1) {

                    case 0: case 1: case 2: case 3: case 6:

                        /* 32 bit mul */

                        tmp = load_reg(s, rs);

                        tmp2 = load_reg(s, rm);

                        tcg_gen_mul_i32(tmp, tmp, tmp2);

                        tcg_temp_free_i32(tmp2);

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

                            /* Subtract (mls) */

                            ARCH(6T2);

                            tmp2 = load_reg(s, rn);

                            tcg_gen_sub_i32(tmp, tmp2, tmp);

                            tcg_temp_free_i32(tmp2);

                        } else if (insn & (1 << 21)) {

                            /* Add */

                            tmp2 = load_reg(s, rn);

                            tcg_gen_add_i32(tmp, tmp, tmp2);

                            tcg_temp_free_i32(tmp2);

                        }

                        if (insn & (1 << 20))

                            gen_logic_CC(tmp);

                        store_reg(s, rd, tmp);

                        break;

                    case 4:

                        /* 64 bit mul double accumulate (UMAAL) */

                        ARCH(6);

                        tmp = load_reg(s, rs);

                        tmp2 = load_reg(s, rm);

                        tmp64 = gen_mulu_i64_i32(tmp, tmp2);

                        gen_addq_lo(s, tmp64, rn);

                        gen_addq_lo(s, tmp64, rd);

                        gen_storeq_reg(s, rn, rd, tmp64);

                        tcg_temp_free_i64(tmp64);

                        break;

                    case 8: case 9: case 10: case 11:

                    case 12: case 13: case 14: case 15:

                        /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */

                        tmp = load_reg(s, rs);

                        tmp2 = load_reg(s, rm);

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

                            tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);

                        } else {

                            tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);

                        }

                        if (insn & (1 << 21)) { /* mult accumulate */

                            TCGv_i32 al = load_reg(s, rn);

                            TCGv_i32 ah = load_reg(s, rd);

                            tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);

                            tcg_temp_free_i32(al);

                            tcg_temp_free_i32(ah);

                        }

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

                            gen_logicq_cc(tmp, tmp2);

                        }

                        store_reg(s, rn, tmp);

                        store_reg(s, rd, tmp2);

                        break;

                    default:

                        goto illegal_op;

                    }

                } else {

                    rn = (insn >> 16) & 0xf;

                    rd = (insn >> 12) & 0xf;

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

                        /* load/store exclusive */

                        int op2 = (insn >> 8) & 3;

                        op1 = (insn >> 21) & 0x3;

                        switch (op2) {

                        case 0: /* lda/stl */

                            if (op1 == 1) {

                                goto illegal_op;

                            }

                            ARCH(8);

                            break;

                        case 1: /* reserved */

                            goto illegal_op;

                        case 2: /* ldaex/stlex */

                            ARCH(8);

                            break;

                        case 3: /* ldrex/strex */

                            if (op1) {

                                ARCH(6K);

                            } else {

                                ARCH(6);

                            }

                            break;

                        }

                        addr = tcg_temp_local_new_i32();

                        load_reg_var(s, addr, rn);

                        /* Since the emulation does not have barriers,

                           the acquire/release semantics need no special

                           handling */

                        if (op2 == 0) {

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

                                tmp = tcg_temp_new_i32();

                                switch (op1) {

                                case 0: /* lda */

                                    gen_aa32_ld32u(tmp, addr, get_mem_index(s));

                                    break;

                                case 2: /* ldab */

                                    gen_aa32_ld8u(tmp, addr, get_mem_index(s));

                                    break;

                                case 3: /* ldah */

                                    gen_aa32_ld16u(tmp, addr, get_mem_index(s));

                                    break;

                                default:

                                    abort();

                                }

                                store_reg(s, rd, tmp);

                            } else {

                                rm = insn & 0xf;

                                tmp = load_reg(s, rm);

                                switch (op1) {

                                case 0: /* stl */

                                    gen_aa32_st32(tmp, addr, get_mem_index(s));

                                    break;

                                case 2: /* stlb */

                                    gen_aa32_st8(tmp, addr, get_mem_index(s));

                                    break;

                                case 3: /* stlh */

                                    gen_aa32_st16(tmp, addr, get_mem_index(s));

                                    break;

                                default:

                                    abort();

                                }

                                tcg_temp_free_i32(tmp);

                            }

                        } else if (insn & (1 << 20)) {

                            switch (op1) {

                            case 0: /* ldrex */

                                gen_load_exclusive(s, rd, 15, addr, 2);

                                break;

                            case 1: /* ldrexd */

                                gen_load_exclusive(s, rd, rd + 1, addr, 3);

                                break;

                            case 2: /* ldrexb */

                                gen_load_exclusive(s, rd, 15, addr, 0);

                                break;

                            case 3: /* ldrexh */

                                gen_load_exclusive(s, rd, 15, addr, 1);

                                break;

                            default:

                                abort();

                            }

                        } else {

                            rm = insn & 0xf;

                            switch (op1) {

                            case 0:  /*  strex */

                                gen_store_exclusive(s, rd, rm, 15, addr, 2);

                                break;

                            case 1: /*  strexd */

                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);

                                break;

                            case 2: /*  strexb */

                                gen_store_exclusive(s, rd, rm, 15, addr, 0);

                                break;

                            case 3: /* strexh */

                                gen_store_exclusive(s, rd, rm, 15, addr, 1);

                                break;

                            default:

                                abort();

                            }

                        }

                        tcg_temp_free_i32(addr);

                    } else {

                        /* SWP instruction */

                        rm = (insn) & 0xf;

                        /* ??? This is not really atomic.  However we know

                           we never have multiple CPUs running in parallel,

                           so it is good enough.  */

                        addr = load_reg(s, rn);

                        tmp = load_reg(s, rm);

                        tmp2 = tcg_temp_new_i32();

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

                            gen_aa32_ld8u(tmp2, addr, get_mem_index(s));

                            gen_aa32_st8(tmp, addr, get_mem_index(s));

                        } else {

                            gen_aa32_ld32u(tmp2, addr, get_mem_index(s));

                            gen_aa32_st32(tmp, addr, get_mem_index(s));

                        }

                        tcg_temp_free_i32(tmp);

                        tcg_temp_free_i32(addr);

                        store_reg(s, rd, tmp2);

                    }

                }

            } else {

                int address_offset;

                bool load = insn & (1 << 20);

                bool doubleword = false;

                /* Misc load/store */

                rn = (insn >> 16) & 0xf;

                rd = (insn >> 12) & 0xf;

                if (!load && (sh & 2)) {

                    /* doubleword */

                    ARCH(5TE);

                    if (rd & 1) {

                        /* UNPREDICTABLE; we choose to UNDEF */

                        goto illegal_op;

                    }

                    load = (sh & 1) == 0;

                    doubleword = true;

                }

                addr = load_reg(s, rn);

                if (insn & (1 << 24))

                    gen_add_datah_offset(s, insn, 0, addr);

                address_offset = 0;

                if (doubleword) {

                    if (!load) {

                        /* store */

                        tmp = load_reg(s, rd);

                        gen_aa32_st32(tmp, addr, get_mem_index(s));

                        tcg_temp_free_i32(tmp);

                        tcg_gen_addi_i32(addr, addr, 4);

                        tmp = load_reg(s, rd + 1);

                        gen_aa32_st32(tmp, addr, get_mem_index(s));

                        tcg_temp_free_i32(tmp);

                    } else {

                        /* load */

                        tmp = tcg_temp_new_i32();

                        gen_aa32_ld32u(tmp, addr, get_mem_index(s));

                        store_reg(s, rd, tmp);

                        tcg_gen_addi_i32(addr, addr, 4);

                        tmp = tcg_temp_new_i32();

                        gen_aa32_ld32u(tmp, addr, get_mem_index(s));

                        rd++;

                    }

                    address_offset = -4;

                } else if (load) {

                    /* load */

                    tmp = tcg_temp_new_i32();

                    switch (sh) {

                    case 1:

                        gen_aa32_ld16u(tmp, addr, get_mem_index(s));

                        break;

                    case 2:

                        gen_aa32_ld8s(tmp, addr, get_mem_index(s));

                        break;

                    default:

                    case 3:

                        gen_aa32_ld16s(tmp, addr, get_mem_index(s));

                        break;

                    }

                } else {

                    /* store */

                    tmp = load_reg(s, rd);

                    gen_aa32_st16(tmp, addr, get_mem_index(s));

                    tcg_temp_free_i32(tmp);

                }

                /* Perform base writeback before the loaded value to

                   ensure correct behavior with overlapping index registers.

                   ldrd with base writeback is undefined if the

                   destination and index registers overlap.  */

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

                    gen_add_datah_offset(s, insn, address_offset, addr);

                    store_reg(s, rn, addr);

                } else if (insn & (1 << 21)) {

                    if (address_offset)

                        tcg_gen_addi_i32(addr, addr, address_offset);

                    store_reg(s, rn, addr);

                } else {

                    tcg_temp_free_i32(addr);

                }

                if (load) {

                    /* Complete the load.  */

                    store_reg(s, rd, tmp);

                }

            }

            break;

        case 0x4:

        case 0x5:

            goto do_ldst;

        case 0x6:

        case 0x7:

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

                ARCH(6);

                /* Armv6 Media instructions.  */

                rm = insn & 0xf;

                rn = (insn >> 16) & 0xf;

                rd = (insn >> 12) & 0xf;

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

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

                case 0: /* Parallel add/subtract.  */

                    op1 = (insn >> 20) & 7;

                    tmp = load_reg(s, rn);

                    tmp2 = load_reg(s, rm);

                    sh = (insn >> 5) & 7;

                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)

                        goto illegal_op;

                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);

                    tcg_temp_free_i32(tmp2);

                    store_reg(s, rd, tmp);

                    break;

                case 1:

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

                        /* Halfword pack.  */

                        tmp = load_reg(s, rn);

                        tmp2 = load_reg(s, rm);

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

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

                            /* pkhtb */

                            if (shift == 0)

                                shift = 31;

                            tcg_gen_sari_i32(tmp2, tmp2, shift);

                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);

                            tcg_gen_ext16u_i32(tmp2, tmp2);

                        } else {

                            /* pkhbt */

                            if (shift)

                                tcg_gen_shli_i32(tmp2, tmp2, shift);

                            tcg_gen_ext16u_i32(tmp, tmp);

                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);

                        }

                        tcg_gen_or_i32(tmp, tmp, tmp2);

                        tcg_temp_free_i32(tmp2);

                        store_reg(s, rd, tmp);

                    } else if ((insn & 0x00200020) == 0x00200000) {

                        /* [us]sat */

                        tmp = load_reg(s, rm);

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

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

                            if (shift == 0)

                                shift = 31;

                            tcg_gen_sari_i32(tmp, tmp, shift);

                        } else {

                            tcg_gen_shli_i32(tmp, tmp, shift);

                        }

                        sh = (insn >> 16) & 0x1f;

                        tmp2 = tcg_const_i32(sh);

                        if (insn & (1 << 22))

                          gen_helper_usat(tmp, cpu_env, tmp, tmp2);

                        else

                          gen_helper_ssat(tmp, cpu_env, tmp, tmp2);

                        tcg_temp_free_i32(tmp2);

                        store_reg(s, rd, tmp);

                    } else if ((insn & 0x00300fe0) == 0x00200f20) {

                        /* [us]sat16 */

                        tmp = load_reg(s, rm);

                        sh = (insn >> 16) & 0x1f;

                        tmp2 = tcg_const_i32(sh);

                        if (insn & (1 << 22))

                          gen_helper_usat16(tmp, cpu_env, tmp, tmp2);

                        else

                          gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);

                        tcg_temp_free_i32(tmp2);

                        store_reg(s, rd, tmp);

                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {

                        /* Select bytes.  */

                        tmp = load_reg(s, rn);

                        tmp2 = load_reg(s, rm);

                        tmp3 = tcg_temp_new_i32();

                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));

                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);

                        tcg_temp_free_i32(tmp3);

                        tcg_temp_free_i32(tmp2);

                        store_reg(s, rd, tmp);

                    } else if ((insn & 0x000003e0) == 0x00000060) {

                        tmp = load_reg(s, rm);

                        shift = (insn >> 10) & 3;

                        /* ??? In many cases it's not necessary to do a

                           rotate, a shift is sufficient.  */

                        if (shift != 0)

                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);

                        op1 = (insn >> 20) & 7;

                        switch (op1) {

                        case 0: gen_sxtb16(tmp);  break;

                        case 2: gen_sxtb(tmp);    break;

                        case 3: gen_sxth(tmp);    break;

                        case 4: gen_uxtb16(tmp);  break;

                        case 6: gen_uxtb(tmp);    break;

                        case 7: gen_uxth(tmp);    break;

                        default: goto illegal_op;

                        }

                        if (rn != 15) {

                            tmp2 = load_reg(s, rn);

                            if ((op1 & 3) == 0) {

                                gen_add16(tmp, tmp2);

                            } else {

                                tcg_gen_add_i32(tmp, tmp, tmp2);

                                tcg_temp_free_i32(tmp2);

                            }

                        }

                        store_reg(s, rd, tmp);

                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {

                        /* rev */

                        tmp = load_reg(s, rm);

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

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

                                gen_revsh(tmp);

                            } else {

                                ARCH(6T2);

                                gen_helper_rbit(tmp, tmp);

                            }

                        } else {

                            if (insn & (1 << 7))

                                gen_rev16(tmp);

                            else

                                tcg_gen_bswap32_i32(tmp, tmp);

                        }

                        store_reg(s, rd, tmp);

                    } else {

                        goto illegal_op;

                    }

                    break;

                case 2: /* Multiplies (Type 3).  */

                    switch ((insn >> 20) & 0x7) {

                    case 5:

                        if (((insn >> 6) ^ (insn >> 7)) & 1) {

                            /* op2 not 00x or 11x : UNDEF */

                            goto illegal_op;

                        }

                        /* Signed multiply most significant [accumulate].

                           (SMMUL, SMMLA, SMMLS) */

                        tmp = load_reg(s, rm);

                        tmp2 = load_reg(s, rs);

                        tmp64 = gen_muls_i64_i32(tmp, tmp2);

                        if (rd != 15) {

                            tmp = load_reg(s, rd);

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

                                tmp64 = gen_subq_msw(tmp64, tmp);

                            } else {

                                tmp64 = gen_addq_msw(tmp64, tmp);

                            }

                        }

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

                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);

                        }

                        tcg_gen_shri_i64(tmp64, tmp64, 32);

                        tmp = tcg_temp_new_i32();

                        tcg_gen_extrl_i64_i32(tmp, tmp64);

                        tcg_temp_free_i64(tmp64);

                        store_reg(s, rn, tmp);

                        break;

                    case 0:

                    case 4:

                        /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */

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

                            goto illegal_op;

                        }

                        tmp = load_reg(s, rm);

                        tmp2 = load_reg(s, rs);

                        if (insn & (1 << 5))

                            gen_swap_half(tmp2);

                        gen_smul_dual(tmp, tmp2);

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

                            /* smlald, smlsld */

                            TCGv_i64 tmp64_2;

                            tmp64 = tcg_temp_new_i64();

                            tmp64_2 = tcg_temp_new_i64();

                            tcg_gen_ext_i32_i64(tmp64, tmp);

                            tcg_gen_ext_i32_i64(tmp64_2, tmp2);

                            tcg_temp_free_i32(tmp);

                            tcg_temp_free_i32(tmp2);

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

                                tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);

                            } else {

                                tcg_gen_add_i64(tmp64, tmp64, tmp64_2);

                            }

                            tcg_temp_free_i64(tmp64_2);

                            gen_addq(s, tmp64, rd, rn);

                            gen_storeq_reg(s, rd, rn, tmp64);

                            tcg_temp_free_i64(tmp64);

                        } else {

                            /* smuad, smusd, smlad, smlsd */

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

                                /* This subtraction cannot overflow. */

                                tcg_gen_sub_i32(tmp, tmp, tmp2);

                            } else {

                                /* This addition cannot overflow 32 bits;

                                 * however it may overflow considered as a

                                 * signed operation, in which case we must set

                                 * the Q flag.

                                 */

                                gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);

                            }

                            tcg_temp_free_i32(tmp2);

                            if (rd != 15)

                              {

                                tmp2 = load_reg(s, rd);

                                gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);

                                tcg_temp_free_i32(tmp2);

                              }

                            store_reg(s, rn, tmp);

                        }

                        break;

                    case 1:

                    case 3:

                        /* SDIV, UDIV */

                        if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {

                            goto illegal_op;

                        }

                        if (((insn >> 5) & 7) || (rd != 15)) {

                            goto illegal_op;

                        }

                        tmp = load_reg(s, rm);

                        tmp2 = load_reg(s, rs);

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

                            gen_helper_udiv(tmp, tmp, tmp2);

                        } else {

                            gen_helper_sdiv(tmp, tmp, tmp2);

                        }

                        tcg_temp_free_i32(tmp2);

                        store_reg(s, rn, tmp);

                        break;

                    default:

                        goto illegal_op;

                    }

                    break;

                case 3:

                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);

                    switch (op1) {

                    case 0: /* Unsigned sum of absolute differences.  */

                        ARCH(6);

                        tmp = load_reg(s, rm);

                        tmp2 = load_reg(s, rs);

                        gen_helper_usad8(tmp, tmp, tmp2);

                        tcg_temp_free_i32(tmp2);

                        if (rd != 15) {

                            tmp2 = load_reg(s, rd);

                            tcg_gen_add_i32(tmp, tmp, tmp2);

                            tcg_temp_free_i32(tmp2);

                        }

                        store_reg(s, rn, tmp);

                        break;

                    case 0x20: case 0x24: case 0x28: case 0x2c:

                        /* Bitfield insert/clear.  */

                        ARCH(6T2);

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

                        i = (insn >> 16) & 0x1f;

                        if (i < shift) {

                            /* UNPREDICTABLE; we choose to UNDEF */

                            goto illegal_op;

                        }

                        i = i + 1 - shift;

                        if (rm == 15) {

                            tmp = tcg_temp_new_i32();

                            tcg_gen_movi_i32(tmp, 0);

                        } else {

                            tmp = load_reg(s, rm);

                        }

                        if (i != 32) {

                            tmp2 = load_reg(s, rd);

                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);

                            tcg_temp_free_i32(tmp2);

                        }

                        store_reg(s, rd, tmp);

                        break;

                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */

                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */

                        ARCH(6T2);

                        tmp = load_reg(s, rm);

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

                        i = ((insn >> 16) & 0x1f) + 1;

                        if (shift + i > 32)

                            goto illegal_op;

                        if (i < 32) {

                            if (op1 & 0x20) {

                                gen_ubfx(tmp, shift, (1u << i) - 1);

                            } else {

                                gen_sbfx(tmp, shift, i);

                            }

                        }

                        store_reg(s, rd, tmp);

                        break;

                    default:

                        goto illegal_op;

                    }

                    break;

                }

                break;

            }

        do_ldst:

            /* Check for undefined extension instructions

             * per the ARM Bible IE:

             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx

             */

            sh = (0xf << 20) | (0xf << 4);

            if (op1 == 0x7 && ((insn & sh) == sh))

            {

                goto illegal_op;

            }

            /* load/store byte/word */

            rn = (insn >> 16) & 0xf;

            rd = (insn >> 12) & 0xf;

            tmp2 = load_reg(s, rn);

            if ((insn & 0x01200000) == 0x00200000) {

                /* ldrt/strt */

                i = get_a32_user_mem_index(s);

            } else {

                i = get_mem_index(s);

            }

            if (insn & (1 << 24))

                gen_add_data_offset(s, insn, tmp2);

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

                /* load */

                tmp = tcg_temp_new_i32();

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

                    gen_aa32_ld8u(tmp, tmp2, i);

                } else {

                    gen_aa32_ld32u(tmp, tmp2, i);

                }

            } else {

                /* store */

                tmp = load_reg(s, rd);

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

                    gen_aa32_st8(tmp, tmp2, i);

                } else {

                    gen_aa32_st32(tmp, tmp2, i);

                }

                tcg_temp_free_i32(tmp);

            }

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

                gen_add_data_offset(s, insn, tmp2);

                store_reg(s, rn, tmp2);

            } else if (insn & (1 << 21)) {

                store_reg(s, rn, tmp2);

            } else {

                tcg_temp_free_i32(tmp2);

            }

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

                /* Complete the load.  */

                store_reg_from_load(s, rd, tmp);

            }

            break;

        case 0x08:

        case 0x09:

            {

                int j, n, loaded_base;

                bool exc_return = false;

                bool is_load = extract32(insn, 20, 1);

                bool user = false;

                TCGv_i32 loaded_var;

                /* load/store multiple words */

                /* XXX: store correct base if write back */

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

                    /* LDM (user), LDM (exception return) and STM (user) */

                    if (IS_USER(s))

                        goto illegal_op; /* only usable in supervisor mode */

                    if (is_load && extract32(insn, 15, 1)) {

                        exc_return = true;

                    } else {

                        user = true;

                    }

                }

                rn = (insn >> 16) & 0xf;

                addr = load_reg(s, rn);

                /* compute total size */

                loaded_base = 0;

                TCGV_UNUSED_I32(loaded_var);

                n = 0;

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

                    if (insn & (1 << i))

                        n++;

                }

                /* XXX: test invalid n == 0 case ? */

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

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

                        /* pre increment */

                        tcg_gen_addi_i32(addr, addr, 4);

                    } else {

                        /* post increment */

                    }

                } else {

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

                        /* pre decrement */

                        tcg_gen_addi_i32(addr, addr, -(n * 4));

                    } else {

                        /* post decrement */

                        if (n != 1)

                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));

                    }

                }

                j = 0;

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

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

                        if (is_load) {

                            /* load */

                            tmp = tcg_temp_new_i32();

                            gen_aa32_ld32u(tmp, addr, get_mem_index(s));

                            if (user) {

                                tmp2 = tcg_const_i32(i);

                                gen_helper_set_user_reg(cpu_env, tmp2, tmp);

                                tcg_temp_free_i32(tmp2);

                                tcg_temp_free_i32(tmp);

                            } else if (i == rn) {

                                loaded_var = tmp;

                                loaded_base = 1;

                            } else {

                                store_reg_from_load(s, i, tmp);

                            }

                        } else {

                            /* store */

                            if (i == 15) {

                                /* special case: r15 = PC + 8 */

                                val = (long)s->pc + 4;

                                tmp = tcg_temp_new_i32();

                                tcg_gen_movi_i32(tmp, val);

                            } else if (user) {

                                tmp = tcg_temp_new_i32();

                                tmp2 = tcg_const_i32(i);

                                gen_helper_get_user_reg(tmp, cpu_env, tmp2);

                                tcg_temp_free_i32(tmp2);

                            } else {

                                tmp = load_reg(s, i);

                            }

                            gen_aa32_st32(tmp, addr, get_mem_index(s));

                            tcg_temp_free_i32(tmp);

                        }

                        j++;

                        /* no need to add after the last transfer */

                        if (j != n)

                            tcg_gen_addi_i32(addr, addr, 4);

                    }

                }

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

                    /* write back */

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

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

                            /* pre increment */

                        } else {

                            /* post increment */

                            tcg_gen_addi_i32(addr, addr, 4);

                        }

                    } else {

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

                            /* pre decrement */

                            if (n != 1)

                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));

                        } else {

                            /* post decrement */

                            tcg_gen_addi_i32(addr, addr, -(n * 4));

                        }

                    }

                    store_reg(s, rn, addr);

                } else {

                    tcg_temp_free_i32(addr);

                }

                if (loaded_base) {

                    store_reg(s, rn, loaded_var);

                }

                if (exc_return) {

                    /* Restore CPSR from SPSR.  */

                    tmp = load_cpu_field(spsr);

                    gen_set_cpsr(tmp, CPSR_ERET_MASK);

                    tcg_temp_free_i32(tmp);

                    s->is_jmp = DISAS_JUMP;

                }

            }

            break;

        case 0xa:

        case 0xb:

            {

                int32_t offset;

                /* branch (and link) */

                val = (int32_t)s->pc;

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

                    tmp = tcg_temp_new_i32();

                    tcg_gen_movi_i32(tmp, val);

                    store_reg(s, 14, tmp);

                }

                offset = sextract32(insn << 2, 0, 26);

                val += offset + 4;

                gen_jmp(s, val);

            }

            break;

        case 0xc:

        case 0xd:

        case 0xe:

            if (((insn >> 8) & 0xe) == 10) {

                /* VFP.  */

                if (disas_vfp_insn(s, insn)) {

                    goto illegal_op;

                }

            } else if (disas_coproc_insn(s, insn)) {

                /* Coprocessor.  */

                goto illegal_op;

            }

            break;

        case 0xf:

            /* swi */

            gen_set_pc_im(s, s->pc);

            s->svc_imm = extract32(insn, 0, 24);

            s->is_jmp = DISAS_SWI;

            break;

        default:

        illegal_op:

            gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),

                               default_exception_el(s));

            break;

        }

    }

}


int64_t bdrv_getlength(BlockDriverState *bs)

{

    BlockDriver *drv = bs->drv;

    if (!drv)

        return -ENOMEDIUM;

    if (bs->growable || bs->removable) {

        if (drv->bdrv_getlength) {

            return drv->bdrv_getlength(bs);

        }

    }

    return bs->total_sectors * BDRV_SECTOR_SIZE;

}


static void test_after_failed_device_add(void)

{

    QDict *response;

    QDict *error;

    qtest_start("-drive if=none,id=drive0");

    /* Make device_add fail.  If this leaks the virtio-blk-pci device then a

     * reference to drive0 will also be held (via qdev properties).

     */

    response = qmp("{'execute': 'device_add',"

                   " 'arguments': {"

                   "   'driver': 'virtio-blk-pci',"

                   "   'drive': 'drive0'"

                   "}}");

    g_assert(response);

    error = qdict_get_qdict(response, "error");

    g_assert_cmpstr(qdict_get_try_str(error, "class"), ==, "GenericError");

    QDECREF(response);

    /* Delete the drive */

    drive_del();

    /* Try to re-add the drive.  This fails with duplicate IDs if a leaked

     * virtio-blk-pci exists that holds a reference to the old drive0.

     */

    drive_add();

    qtest_end();

}


static void xen_io_del(MemoryListener *listener,

                       MemoryRegionSection *section)

{

    XenIOState *state = container_of(listener, XenIOState, io_listener);

    xen_unmap_io_section(xen_xc, xen_domid, state->ioservid, section);

    memory_region_unref(section->mr);

}


static void mipsnet_receive(void *opaque, const uint8_t *buf, size_t size)

{

    MIPSnetState *s = opaque;

#ifdef DEBUG_MIPSNET_RECEIVE

    printf("mipsnet: receiving len=%d\n", size);

#endif

    if (!mipsnet_can_receive(opaque))

        return;

    s->busy = 1;

    /* Just accept everything. */

    /* Write packet data. */

    memcpy(s->rx_buffer, buf, size);

    s->rx_count = size;

    s->rx_read = 0;

    /* Now we can signal we have received something. */

    s->intctl |= MIPSNET_INTCTL_RXDONE;

    mipsnet_update_irq(s);

}


int kvm_s390_set_mem_limit(KVMState *s, uint64_t new_limit, uint64_t *hw_limit)

{

    int rc;

    struct kvm_device_attr attr = {

        .group = KVM_S390_VM_MEM_CTRL,

        .attr = KVM_S390_VM_MEM_LIMIT_SIZE,

        .addr = (uint64_t) &new_limit,

    };

    if (!kvm_s390_supports_mem_limit(s)) {

        return 0;

    }

    rc = kvm_s390_query_mem_limit(s, hw_limit);

    if (rc) {

        return rc;

    } else if (*hw_limit < new_limit) {

        return -E2BIG;

    }

    return kvm_vm_ioctl(s, KVM_SET_DEVICE_ATTR, &attr);

}


static int ra144_decode_frame(AVCodecContext * avctx, void *vdata,

                              int *data_size, const uint8_t *buf, int buf_size)

{

    static const uint8_t sizes[10] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};

    unsigned int refl_rms[4];    // RMS of the reflection coefficients

    uint16_t block_coefs[4][30]; // LPC coefficients of each sub-block

    unsigned int lpc_refl[10];   // LPC reflection coefficients of the frame

    int i, c;

    int16_t *data = vdata;

    unsigned int energy;

    RA144Context *ractx = avctx->priv_data;

    GetBitContext gb;

    if(buf_size < 20) {

        av_log(avctx, AV_LOG_ERROR,

               "Frame too small (%d bytes). Truncated file?\n", buf_size);

        *data_size = 0;

        return buf_size;

    }

    init_get_bits(&gb, buf, 20 * 8);

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

        lpc_refl[i] = lpc_refl_cb[i][get_bits(&gb, sizes[i])];

    eval_coefs(ractx->lpc_coef[0], lpc_refl);

    ractx->lpc_refl_rms[0] = rms(lpc_refl);

    energy = energy_tab[get_bits(&gb, 5)];

    refl_rms[0] = interp(ractx, block_coefs[0], 0, 1, ractx->old_energy);

    refl_rms[1] = interp(ractx, block_coefs[1], 1, energy <= ractx->old_energy,

                    t_sqrt(energy*ractx->old_energy) >> 12);

    refl_rms[2] = interp(ractx, block_coefs[2], 2, 0, energy);

    refl_rms[3] = rescale_rms(ractx->lpc_refl_rms[0], energy);

    int_to_int16(block_coefs[3], ractx->lpc_coef[0]);

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

        do_output_subblock(ractx, block_coefs[c], refl_rms[c], &gb);

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

            *data++ = av_clip_int16(ractx->curr_sblock[i + 10] << 2);

    }

    ractx->old_energy = energy;

    ractx->lpc_refl_rms[1] = ractx->lpc_refl_rms[0];

    FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]);

    *data_size = 2*160;

    return 20;

}


static void read_vec_element(DisasContext *s, TCGv_i64 tcg_dest, int srcidx,

                             int element, TCGMemOp memop)

{

    int vect_off = vec_reg_offset(srcidx, element, memop & MO_SIZE);

    switch (memop) {

    case MO_8:

        tcg_gen_ld8u_i64(tcg_dest, cpu_env, vect_off);

        break;

    case MO_16:

        tcg_gen_ld16u_i64(tcg_dest, cpu_env, vect_off);

        break;

    case MO_32:

        tcg_gen_ld32u_i64(tcg_dest, cpu_env, vect_off);

        break;

    case MO_8|MO_SIGN:

        tcg_gen_ld8s_i64(tcg_dest, cpu_env, vect_off);

        break;

    case MO_16|MO_SIGN:

        tcg_gen_ld16s_i64(tcg_dest, cpu_env, vect_off);

        break;

    case MO_32|MO_SIGN:

        tcg_gen_ld32s_i64(tcg_dest, cpu_env, vect_off);

        break;

    case MO_64:

    case MO_64|MO_SIGN:

        tcg_gen_ld_i64(tcg_dest, cpu_env, vect_off);

        break;

    default:

        g_assert_not_reached();

    }

}


int qemu_boot_set(const char *boot_order)

{

    if (!boot_set_handler) {

        return -EINVAL;

    }

    return boot_set_handler(boot_set_opaque, boot_order);

}


static ssize_t local_readlink(FsContext *ctx, const char *path,

                                char *buf, size_t bufsz)

{

    return readlink(rpath(ctx, path), buf, bufsz);

}


void unix_start_incoming_migration(const char *path, Error **errp)

{

    SocketAddressLegacy *saddr = unix_build_address(path);

    socket_start_incoming_migration(saddr, errp);

}


void tcg_gen_atomic_cmpxchg_i32(TCGv_i32 retv, TCGv addr, TCGv_i32 cmpv,

                                TCGv_i32 newv, TCGArg idx, TCGMemOp memop)

{

    memop = tcg_canonicalize_memop(memop, 0, 0);

    if (!parallel_cpus) {

        TCGv_i32 t1 = tcg_temp_new_i32();

        TCGv_i32 t2 = tcg_temp_new_i32();

        tcg_gen_ext_i32(t2, cmpv, memop & MO_SIZE);

        tcg_gen_qemu_ld_i32(t1, addr, idx, memop & ~MO_SIGN);

        tcg_gen_movcond_i32(TCG_COND_EQ, t2, t1, t2, newv, t1);

        tcg_gen_qemu_st_i32(t2, addr, idx, memop);

        tcg_temp_free_i32(t2);

        if (memop & MO_SIGN) {

            tcg_gen_ext_i32(retv, t1, memop);

        } else {

            tcg_gen_mov_i32(retv, t1);

        }

        tcg_temp_free_i32(t1);

    } else {

        gen_atomic_cx_i32 gen;

        gen = table_cmpxchg[memop & (MO_SIZE | MO_BSWAP)];

        tcg_debug_assert(gen != NULL);

#ifdef CONFIG_SOFTMMU

        {

            TCGv_i32 oi = tcg_const_i32(make_memop_idx(memop & ~MO_SIGN, idx));

            gen(retv, tcg_ctx.tcg_env, addr, cmpv, newv, oi);

            tcg_temp_free_i32(oi);

        }

#else

        gen(retv, tcg_ctx.tcg_env, addr, cmpv, newv);

#endif

        if (memop & MO_SIGN) {

            tcg_gen_ext_i32(retv, retv, memop);

        }

    }

}


static void rtce_init(VIOsPAPRDevice *dev)

{

    size_t size = (dev->rtce_window_size >> SPAPR_VIO_TCE_PAGE_SHIFT)

        * sizeof(VIOsPAPR_RTCE);

    if (size) {

        dev->rtce_table = g_malloc0(size);

    }

}


BlockAIOCB *ide_issue_trim(BlockDriverState *bs,

        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,

        BlockCompletionFunc *cb, void *opaque)

{

    TrimAIOCB *iocb;

    iocb = qemu_aio_get(&trim_aiocb_info, bs, cb, opaque);

    iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);

    iocb->ret = 0;

    iocb->qiov = qiov;

    iocb->i = -1;

    iocb->j = 0;

    ide_issue_trim_cb(iocb, 0);

    return &iocb->common;

}


uint32_t lduw_phys(target_phys_addr_t addr)

{

    return lduw_phys_internal(addr, DEVICE_NATIVE_ENDIAN);

}


static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int size)

{

    DiracContext *s   = avctx->priv_data;

    DiracFrame *pic   = NULL;

    int ret, i, parse_code = buf[4];

    unsigned tmp;

    if (size < DATA_UNIT_HEADER_SIZE)

        return -1;

    init_get_bits(&s->gb, &buf[13], 8*(size - DATA_UNIT_HEADER_SIZE));

    if (parse_code == pc_seq_header) {

        if (s->seen_sequence_header)

            return 0;

        /* [DIRAC_STD] 10. Sequence header */

        if (avpriv_dirac_parse_sequence_header(avctx, &s->gb, &s->source))

            return -1;

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

        if (alloc_sequence_buffers(s))

            return -1;

        s->seen_sequence_header = 1;

    } else if (parse_code == pc_eos) { /* [DIRAC_STD] End of Sequence */

        free_sequence_buffers(s);

        s->seen_sequence_header = 0;

    } else if (parse_code == pc_aux_data) {

        if (buf[13] == 1) {     /* encoder implementation/version */

            int ver[3];

            /* versions older than 1.0.8 don't store quant delta for

               subbands with only one codeblock */

            if (sscanf(buf+14, "Schroedinger %d.%d.%d", ver, ver+1, ver+2) == 3)

                if (ver[0] == 1 && ver[1] == 0 && ver[2] <= 7)

                    s->old_delta_quant = 1;

        }

    } else if (parse_code & 0x8) {  /* picture data unit */

        if (!s->seen_sequence_header) {

            av_log(avctx, AV_LOG_DEBUG, "Dropping frame without sequence header\n");

            return -1;

        }

        /* find an unused frame */

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

            if (s->all_frames[i].avframe->data[0] == NULL)

                pic = &s->all_frames[i];

        if (!pic) {

            av_log(avctx, AV_LOG_ERROR, "framelist full\n");

            return -1;

        }

        av_frame_unref(pic->avframe);

        /* [DIRAC_STD] Defined in 9.6.1 ... */

        tmp            =  parse_code & 0x03;                   /* [DIRAC_STD] num_refs()      */

        if (tmp > 2) {

            av_log(avctx, AV_LOG_ERROR, "num_refs of 3\n");

            return -1;

        }

        s->num_refs    = tmp;

        s->is_arith    = (parse_code & 0x48) == 0x08;          /* [DIRAC_STD] using_ac()      */

        s->low_delay   = (parse_code & 0x88) == 0x88;          /* [DIRAC_STD] is_low_delay()  */

        pic->avframe->reference = (parse_code & 0x0C) == 0x0C;  /* [DIRAC_STD]  is_reference() */

        pic->avframe->key_frame = s->num_refs == 0;             /* [DIRAC_STD] is_intra()      */

        pic->avframe->pict_type = s->num_refs + 1;              /* Definition of AVPictureType in avutil.h */

        if ((ret = get_buffer_with_edge(avctx, pic->avframe, (parse_code & 0x0C) == 0x0C ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)

            return ret;

        s->current_picture = pic;

        s->plane[0].stride = pic->avframe->linesize[0];

        s->plane[1].stride = pic->avframe->linesize[1];

        s->plane[2].stride = pic->avframe->linesize[2];

        if (alloc_buffers(s, FFMAX3(FFABS(s->plane[0].stride), FFABS(s->plane[1].stride), FFABS(s->plane[2].stride))) < 0)

            return AVERROR(ENOMEM);

        /* [DIRAC_STD] 11.1 Picture parse. picture_parse() */

        if (dirac_decode_picture_header(s))

            return -1;

        /* [DIRAC_STD] 13.0 Transform data syntax. transform_data() */

        if (dirac_decode_frame_internal(s))

            return -1;

    }

    return 0;

}


static int h264_parse(AVCodecParserContext *s,

                      AVCodecContext *avctx,

                      uint8_t **poutbuf, int *poutbuf_size,

                      const uint8_t *buf, int buf_size)

{

    H264Context *h = s->priv_data;

    ParseContext *pc = &h->s.parse_context;

    int next;

    if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){

        next= buf_size;

    }else{

        next= find_frame_end(h, buf, buf_size);

        if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {

            *poutbuf = NULL;

            *poutbuf_size = 0;

            return buf_size;

        }

        if(next<0){

            find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state

        }

    }

    *poutbuf = (uint8_t *)buf;

    *poutbuf_size = buf_size;

    return next;

}


av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)

{

    const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8;

    if (avctx->lowres==1) {

        c->idct_put  = ff_jref_idct4_put;

        c->idct_add  = ff_jref_idct4_add;

        c->idct      = ff_j_rev_dct4;

        c->perm_type = FF_IDCT_PERM_NONE;

    } else if (avctx->lowres==2) {

        c->idct_put  = ff_jref_idct2_put;

        c->idct_add  = ff_jref_idct2_add;

        c->idct      = ff_j_rev_dct2;

        c->perm_type = FF_IDCT_PERM_NONE;

    } else if (avctx->lowres==3) {

        c->idct_put  = ff_jref_idct1_put;

        c->idct_add  = ff_jref_idct1_add;

        c->idct      = ff_j_rev_dct1;

        c->perm_type = FF_IDCT_PERM_NONE;

    } else {

        if (avctx->bits_per_raw_sample == 10) {

            c->idct_put              = ff_simple_idct_put_10;

            c->idct_add              = ff_simple_idct_add_10;

            c->idct                  = ff_simple_idct_10;

            c->perm_type             = FF_IDCT_PERM_NONE;

        } else if (avctx->bits_per_raw_sample == 12) {

            c->idct_put              = ff_simple_idct_put_12;

            c->idct_add              = ff_simple_idct_add_12;

            c->idct                  = ff_simple_idct_12;

            c->perm_type             = FF_IDCT_PERM_NONE;

        } else {

            if (avctx->idct_algo == FF_IDCT_INT) {

                c->idct_put  = ff_jref_idct_put;

                c->idct_add  = ff_jref_idct_add;

                c->idct      = ff_j_rev_dct;

                c->perm_type = FF_IDCT_PERM_LIBMPEG2;

            } else if (avctx->idct_algo == FF_IDCT_FAAN) {

                c->idct_put  = ff_faanidct_put;

                c->idct_add  = ff_faanidct_add;

                c->idct      = ff_faanidct;

                c->perm_type = FF_IDCT_PERM_NONE;

            } else { // accurate/default

                c->idct_put  = ff_simple_idct_put_8;

                c->idct_add  = ff_simple_idct_add_8;

                c->idct      = ff_simple_idct_8;

                c->perm_type = FF_IDCT_PERM_NONE;

            }

        }

    }

    c->put_pixels_clamped        = put_pixels_clamped_c;

    c->put_signed_pixels_clamped = put_signed_pixels_clamped_c;

    c->add_pixels_clamped        = add_pixels_clamped_c;

    ff_put_pixels_clamped = c->put_pixels_clamped;

    ff_add_pixels_clamped = c->add_pixels_clamped;

    if (CONFIG_MPEG4_DECODER && avctx->idct_algo == FF_IDCT_XVID)

        ff_xvid_idct_init(c, avctx);

    if (ARCH_ALPHA)

        ff_idctdsp_init_alpha(c, avctx, high_bit_depth);

    if (ARCH_ARM)

        ff_idctdsp_init_arm(c, avctx, high_bit_depth);

    if (ARCH_PPC)

        ff_idctdsp_init_ppc(c, avctx, high_bit_depth);

    if (ARCH_X86)

        ff_idctdsp_init_x86(c, avctx, high_bit_depth);

    ff_init_scantable_permutation(c->idct_permutation,

                                  c->perm_type);

}