static always_inline int translate_one (DisasContext *ctx, uint32_t insn)

{

    uint32_t palcode;

    int32_t disp21, disp16, disp12;

    uint16_t fn11, fn16;

    uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit;

    uint8_t lit;

    int ret;

    /* Decode all instruction fields */

    opc = insn >> 26;

    ra = (insn >> 21) & 0x1F;

    rb = (insn >> 16) & 0x1F;

    rc = insn & 0x1F;

    sbz = (insn >> 13) & 0x07;

    islit = (insn >> 12) & 1;

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

        islit = 1;

        lit = 0;

    } else

        lit = (insn >> 13) & 0xFF;

    palcode = insn & 0x03FFFFFF;

    disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;

    disp16 = (int16_t)(insn & 0x0000FFFF);

    disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;

    fn16 = insn & 0x0000FFFF;

    fn11 = (insn >> 5) & 0x000007FF;

    fpfn = fn11 & 0x3F;

    fn7 = (insn >> 5) & 0x0000007F;

    fn2 = (insn >> 5) & 0x00000003;

    ret = 0;

    LOG_DISAS("opc %02x ra %d rb %d rc %d disp16 %04x\n",

              opc, ra, rb, rc, disp16);

    switch (opc) {

    case 0x00:

        /* CALL_PAL */

        if (palcode >= 0x80 && palcode < 0xC0) {

            /* Unprivileged PAL call */

            gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x1F) << 6), 0);

#if !defined (CONFIG_USER_ONLY)

        } else if (palcode < 0x40) {

            /* Privileged PAL code */

            if (ctx->mem_idx & 1)

                goto invalid_opc;

            else

                gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);

#endif

        } else {

            /* Invalid PAL call */

            goto invalid_opc;

        }

        ret = 3;

        break;

    case 0x01:

        /* OPC01 */

        goto invalid_opc;

    case 0x02:

        /* OPC02 */

        goto invalid_opc;

    case 0x03:

        /* OPC03 */

        goto invalid_opc;

    case 0x04:

        /* OPC04 */

        goto invalid_opc;

    case 0x05:

        /* OPC05 */

        goto invalid_opc;

    case 0x06:

        /* OPC06 */

        goto invalid_opc;

    case 0x07:

        /* OPC07 */

        goto invalid_opc;

    case 0x08:

        /* LDA */

        if (likely(ra != 31)) {

            if (rb != 31)

                tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16);

            else

                tcg_gen_movi_i64(cpu_ir[ra], disp16);

        }

        break;

    case 0x09:

        /* LDAH */

        if (likely(ra != 31)) {

            if (rb != 31)

                tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16 << 16);

            else

                tcg_gen_movi_i64(cpu_ir[ra], disp16 << 16);

        }

        break;

    case 0x0A:

        /* LDBU */

        if (!(ctx->amask & AMASK_BWX))

            goto invalid_opc;

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

        break;

    case 0x0B:

        /* LDQ_U */

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

        break;

    case 0x0C:

        /* LDWU */

        if (!(ctx->amask & AMASK_BWX))

            goto invalid_opc;

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

        break;

    case 0x0D:

        /* STW */

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

        break;

    case 0x0E:

        /* STB */

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

        break;

    case 0x0F:

        /* STQ_U */

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

        break;

    case 0x10:

        switch (fn7) {

        case 0x00:

            /* ADDL */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    if (islit) {

                        tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);

                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);

                    } else {

                        tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);

                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);

                    }

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], lit);

                    else

                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);

                }

            }

            break;

        case 0x02:

            /* S4ADDL */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    TCGv tmp = tcg_temp_new();

                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);

                    if (islit)

                        tcg_gen_addi_i64(tmp, tmp, lit);

                    else

                        tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);

                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);

                    tcg_temp_free(tmp);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], lit);

                    else

                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);

                }

            }

            break;

        case 0x09:

            /* SUBL */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    if (islit)

                        tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);

                    else

                        tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);

                    tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], -lit);

                    else {

                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);

                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);

                }

            }

            break;

        case 0x0B:

            /* S4SUBL */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    TCGv tmp = tcg_temp_new();

                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);

                    if (islit)

                        tcg_gen_subi_i64(tmp, tmp, lit);

                    else

                        tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);

                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);

                    tcg_temp_free(tmp);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], -lit);

                    else {

                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);

                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);

                    }

                }

            }

            break;

        case 0x0F:

            /* CMPBGE */

            gen_cmpbge(ra, rb, rc, islit, lit);

            break;

        case 0x12:

            /* S8ADDL */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    TCGv tmp = tcg_temp_new();

                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);

                    if (islit)

                        tcg_gen_addi_i64(tmp, tmp, lit);

                    else

                        tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);

                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);

                    tcg_temp_free(tmp);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], lit);

                    else

                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);

                }

            }

            break;

        case 0x1B:

            /* S8SUBL */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    TCGv tmp = tcg_temp_new();

                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);

                    if (islit)

                        tcg_gen_subi_i64(tmp, tmp, lit);

                    else

                       tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);

                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);

                    tcg_temp_free(tmp);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], -lit);

                    else

                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);

                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);

                    }

                }

            }

            break;

        case 0x1D:

            /* CMPULT */

            gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit);

            break;

        case 0x20:

            /* ADDQ */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    if (islit)

                        tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);

                    else

                        tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], lit);

                    else

                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);

                }

            }

            break;

        case 0x22:

            /* S4ADDQ */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    TCGv tmp = tcg_temp_new();

                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);

                    if (islit)

                        tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);

                    else

                        tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);

                    tcg_temp_free(tmp);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], lit);

                    else

                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);

                }

            }

            break;

        case 0x29:

            /* SUBQ */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    if (islit)

                        tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);

                    else

                        tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], -lit);

                    else

                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);

                }

            }

            break;

        case 0x2B:

            /* S4SUBQ */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    TCGv tmp = tcg_temp_new();

                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);

                    if (islit)

                        tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);

                    else

                        tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);

                    tcg_temp_free(tmp);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], -lit);

                    else

                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);

                }

            }

            break;

        case 0x2D:

            /* CMPEQ */

            gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit);

            break;

        case 0x32:

            /* S8ADDQ */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    TCGv tmp = tcg_temp_new();

                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);

                    if (islit)

                        tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);

                    else

                        tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);

                    tcg_temp_free(tmp);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], lit);

                    else

                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);

                }

            }

            break;

        case 0x3B:

            /* S8SUBQ */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    TCGv tmp = tcg_temp_new();

                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);

                    if (islit)

                        tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);

                    else

                        tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);

                    tcg_temp_free(tmp);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], -lit);

                    else

                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);

                }

            }

            break;

        case 0x3D:

            /* CMPULE */

            gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit);

            break;

        case 0x40:

            /* ADDL/V */

            gen_addlv(ra, rb, rc, islit, lit);

            break;

        case 0x49:

            /* SUBL/V */

            gen_sublv(ra, rb, rc, islit, lit);

            break;

        case 0x4D:

            /* CMPLT */

            gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit);

            break;

        case 0x60:

            /* ADDQ/V */

            gen_addqv(ra, rb, rc, islit, lit);

            break;

        case 0x69:

            /* SUBQ/V */

            gen_subqv(ra, rb, rc, islit, lit);

            break;

        case 0x6D:

            /* CMPLE */

            gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x11:

        switch (fn7) {

        case 0x00:

            /* AND */

            if (likely(rc != 31)) {

                if (ra == 31)

                    tcg_gen_movi_i64(cpu_ir[rc], 0);

                else if (islit)

                    tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);

                else

                    tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);

            }

            break;

        case 0x08:

            /* BIC */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    if (islit)

                        tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);

                    else

                        tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);

                } else

                    tcg_gen_movi_i64(cpu_ir[rc], 0);

            }

            break;

        case 0x14:

            /* CMOVLBS */

            gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);

            break;

        case 0x16:

            /* CMOVLBC */

            gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);

            break;

        case 0x20:

            /* BIS */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    if (islit)

                        tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);

                    else

                        tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], lit);

                    else

                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);

                }

            }

            break;

        case 0x24:

            /* CMOVEQ */

            gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);

            break;

        case 0x26:

            /* CMOVNE */

            gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);

            break;

        case 0x28:

            /* ORNOT */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    if (islit)

                        tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);

                    else

                        tcg_gen_orc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], ~lit);

                    else

                        tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);

                }

            }

            break;

        case 0x40:

            /* XOR */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    if (islit)

                        tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);

                    else

                        tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], lit);

                    else

                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);

                }

            }

            break;

        case 0x44:

            /* CMOVLT */

            gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);

            break;

        case 0x46:

            /* CMOVGE */

            gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);

            break;

        case 0x48:

            /* EQV */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    if (islit)

                        tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);

                    else

                        tcg_gen_eqv_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);

                } else {

                    if (islit)

                        tcg_gen_movi_i64(cpu_ir[rc], ~lit);

                    else

                        tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);

                }

            }

            break;

        case 0x61:

            /* AMASK */

            if (likely(rc != 31)) {

                if (islit)

                    tcg_gen_movi_i64(cpu_ir[rc], helper_amask(lit));

                else

                    gen_helper_amask(cpu_ir[rc], cpu_ir[rb]);

            }

            break;

        case 0x64:

            /* CMOVLE */

            gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);

            break;

        case 0x66:

            /* CMOVGT */

            gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);

            break;

        case 0x6C:

            /* IMPLVER */

            if (rc != 31)

                gen_helper_load_implver(cpu_ir[rc]);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x12:

        switch (fn7) {

        case 0x02:

            /* MSKBL */

            gen_mskbl(ra, rb, rc, islit, lit);

            break;

        case 0x06:

            /* EXTBL */

            gen_ext_l(&tcg_gen_ext8u_i64, ra, rb, rc, islit, lit);

            break;

        case 0x0B:

            /* INSBL */

            gen_insbl(ra, rb, rc, islit, lit);

            break;

        case 0x12:

            /* MSKWL */

            gen_mskwl(ra, rb, rc, islit, lit);

            break;

        case 0x16:

            /* EXTWL */

            gen_ext_l(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);

            break;

        case 0x1B:

            /* INSWL */

            gen_inswl(ra, rb, rc, islit, lit);

            break;

        case 0x22:

            /* MSKLL */

            gen_mskll(ra, rb, rc, islit, lit);

            break;

        case 0x26:

            /* EXTLL */

            gen_ext_l(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit);

            break;

        case 0x2B:

            /* INSLL */

            gen_insll(ra, rb, rc, islit, lit);

            break;

        case 0x30:

            /* ZAP */

            gen_zap(ra, rb, rc, islit, lit);

            break;

        case 0x31:

            /* ZAPNOT */

            gen_zapnot(ra, rb, rc, islit, lit);

            break;

        case 0x32:

            /* MSKQL */

            gen_mskql(ra, rb, rc, islit, lit);

            break;

        case 0x34:

            /* SRL */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    if (islit)

                        tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);

                    else {

                        TCGv shift = tcg_temp_new();

                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);

                        tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);

                        tcg_temp_free(shift);

                    }

                } else

                    tcg_gen_movi_i64(cpu_ir[rc], 0);

            }

            break;

        case 0x36:

            /* EXTQL */

            gen_ext_l(NULL, ra, rb, rc, islit, lit);

            break;

        case 0x39:

            /* SLL */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    if (islit)

                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);

                    else {

                        TCGv shift = tcg_temp_new();

                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);

                        tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);

                        tcg_temp_free(shift);

                    }

                } else

                    tcg_gen_movi_i64(cpu_ir[rc], 0);

            }

            break;

        case 0x3B:

            /* INSQL */

            gen_insql(ra, rb, rc, islit, lit);

            break;

        case 0x3C:

            /* SRA */

            if (likely(rc != 31)) {

                if (ra != 31) {

                    if (islit)

                        tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);

                    else {

                        TCGv shift = tcg_temp_new();

                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);

                        tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);

                        tcg_temp_free(shift);

                    }

                } else

                    tcg_gen_movi_i64(cpu_ir[rc], 0);

            }

            break;

        case 0x52:

            /* MSKWH */

            gen_mskwh(ra, rb, rc, islit, lit);

            break;

        case 0x57:

            /* INSWH */

            gen_inswh(ra, rb, rc, islit, lit);

            break;

        case 0x5A:

            /* EXTWH */

            gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);

            break;

        case 0x62:

            /* MSKLH */

            gen_msklh(ra, rb, rc, islit, lit);

            break;

        case 0x67:

            /* INSLH */

            gen_inslh(ra, rb, rc, islit, lit);

            break;

        case 0x6A:

            /* EXTLH */

            gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);

            break;

        case 0x72:

            /* MSKQH */

            gen_mskqh(ra, rb, rc, islit, lit);

            break;

        case 0x77:

            /* INSQH */

            gen_insqh(ra, rb, rc, islit, lit);

            break;

        case 0x7A:

            /* EXTQH */

            gen_ext_h(NULL, ra, rb, rc, islit, lit);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x13:

        switch (fn7) {

        case 0x00:

            /* MULL */

            if (likely(rc != 31)) {

                if (ra == 31)

                    tcg_gen_movi_i64(cpu_ir[rc], 0);

                else {

                    if (islit)

                        tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);

                    else

                        tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);

                    tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);

                }

            }

            break;

        case 0x20:

            /* MULQ */

            if (likely(rc != 31)) {

                if (ra == 31)

                    tcg_gen_movi_i64(cpu_ir[rc], 0);

                else if (islit)

                    tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);

                else

                    tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);

            }

            break;

        case 0x30:

            /* UMULH */

            gen_umulh(ra, rb, rc, islit, lit);

            break;

        case 0x40:

            /* MULL/V */

            gen_mullv(ra, rb, rc, islit, lit);

            break;

        case 0x60:

            /* MULQ/V */

            gen_mulqv(ra, rb, rc, islit, lit);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x14:

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

        case 0x04:

            /* ITOFS */

            if (!(ctx->amask & AMASK_FIX))

                goto invalid_opc;

            if (likely(rc != 31)) {

                if (ra != 31) {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);

                    gen_helper_memory_to_s(cpu_fir[rc], tmp);

                    tcg_temp_free_i32(tmp);

                } else

                    tcg_gen_movi_i64(cpu_fir[rc], 0);

            }

            break;

        case 0x0A:

            /* SQRTF */

            if (!(ctx->amask & AMASK_FIX))

                goto invalid_opc;

            gen_fsqrtf(rb, rc);

            break;

        case 0x0B:

            /* SQRTS */

            if (!(ctx->amask & AMASK_FIX))

                goto invalid_opc;

            gen_fsqrts(rb, rc);

            break;

        case 0x14:

            /* ITOFF */

            if (!(ctx->amask & AMASK_FIX))

                goto invalid_opc;

            if (likely(rc != 31)) {

                if (ra != 31) {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);

                    gen_helper_memory_to_f(cpu_fir[rc], tmp);

                    tcg_temp_free_i32(tmp);

                } else

                    tcg_gen_movi_i64(cpu_fir[rc], 0);

            }

            break;

        case 0x24:

            /* ITOFT */

            if (!(ctx->amask & AMASK_FIX))

                goto invalid_opc;

            if (likely(rc != 31)) {

                if (ra != 31)

                    tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]);

                else

                    tcg_gen_movi_i64(cpu_fir[rc], 0);

            }

            break;

        case 0x2A:

            /* SQRTG */

            if (!(ctx->amask & AMASK_FIX))

                goto invalid_opc;

            gen_fsqrtg(rb, rc);

            break;

        case 0x02B:

            /* SQRTT */

            if (!(ctx->amask & AMASK_FIX))

                goto invalid_opc;

            gen_fsqrtt(rb, rc);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x15:

        /* VAX floating point */

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

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

        case 0x00:

            /* ADDF */

            gen_faddf(ra, rb, rc);

            break;

        case 0x01:

            /* SUBF */

            gen_fsubf(ra, rb, rc);

            break;

        case 0x02:

            /* MULF */

            gen_fmulf(ra, rb, rc);

            break;

        case 0x03:

            /* DIVF */

            gen_fdivf(ra, rb, rc);

            break;

        case 0x1E:

            /* CVTDG */

#if 0 // TODO

            gen_fcvtdg(rb, rc);

#else

            goto invalid_opc;

#endif

            break;

        case 0x20:

            /* ADDG */

            gen_faddg(ra, rb, rc);

            break;

        case 0x21:

            /* SUBG */

            gen_fsubg(ra, rb, rc);

            break;

        case 0x22:

            /* MULG */

            gen_fmulg(ra, rb, rc);

            break;

        case 0x23:

            /* DIVG */

            gen_fdivg(ra, rb, rc);

            break;

        case 0x25:

            /* CMPGEQ */

            gen_fcmpgeq(ra, rb, rc);

            break;

        case 0x26:

            /* CMPGLT */

            gen_fcmpglt(ra, rb, rc);

            break;

        case 0x27:

            /* CMPGLE */

            gen_fcmpgle(ra, rb, rc);

            break;

        case 0x2C:

            /* CVTGF */

            gen_fcvtgf(rb, rc);

            break;

        case 0x2D:

            /* CVTGD */

#if 0 // TODO

            gen_fcvtgd(rb, rc);

#else

            goto invalid_opc;

#endif

            break;

        case 0x2F:

            /* CVTGQ */

            gen_fcvtgq(rb, rc);

            break;

        case 0x3C:

            /* CVTQF */

            gen_fcvtqf(rb, rc);

            break;

        case 0x3E:

            /* CVTQG */

            gen_fcvtqg(rb, rc);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x16:

        /* IEEE floating-point */

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

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

        case 0x00:

            /* ADDS */

            gen_fadds(ra, rb, rc);

            break;

        case 0x01:

            /* SUBS */

            gen_fsubs(ra, rb, rc);

            break;

        case 0x02:

            /* MULS */

            gen_fmuls(ra, rb, rc);

            break;

        case 0x03:

            /* DIVS */

            gen_fdivs(ra, rb, rc);

            break;

        case 0x20:

            /* ADDT */

            gen_faddt(ra, rb, rc);

            break;

        case 0x21:

            /* SUBT */

            gen_fsubt(ra, rb, rc);

            break;

        case 0x22:

            /* MULT */

            gen_fmult(ra, rb, rc);

            break;

        case 0x23:

            /* DIVT */

            gen_fdivt(ra, rb, rc);

            break;

        case 0x24:

            /* CMPTUN */

            gen_fcmptun(ra, rb, rc);

            break;

        case 0x25:

            /* CMPTEQ */

            gen_fcmpteq(ra, rb, rc);

            break;

        case 0x26:

            /* CMPTLT */

            gen_fcmptlt(ra, rb, rc);

            break;

        case 0x27:

            /* CMPTLE */

            gen_fcmptle(ra, rb, rc);

            break;

        case 0x2C:

            /* XXX: incorrect */

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

                /* CVTST */

                gen_fcvtst(rb, rc);

            } else {

                /* CVTTS */

                gen_fcvtts(rb, rc);

            }

            break;

        case 0x2F:

            /* CVTTQ */

            gen_fcvttq(rb, rc);

            break;

        case 0x3C:

            /* CVTQS */

            gen_fcvtqs(rb, rc);

            break;

        case 0x3E:

            /* CVTQT */

            gen_fcvtqt(rb, rc);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x17:

        switch (fn11) {

        case 0x010:

            /* CVTLQ */

            gen_fcvtlq(rb, rc);

            break;

        case 0x020:

            if (likely(rc != 31)) {

                if (ra == rb)

                    /* FMOV */

                    tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);

                else

                    /* CPYS */

                    gen_fcpys(ra, rb, rc);

            }

            break;

        case 0x021:

            /* CPYSN */

            gen_fcpysn(ra, rb, rc);

            break;

        case 0x022:

            /* CPYSE */

            gen_fcpyse(ra, rb, rc);

            break;

        case 0x024:

            /* MT_FPCR */

            if (likely(ra != 31))

                gen_helper_store_fpcr(cpu_fir[ra]);

            else {

                TCGv tmp = tcg_const_i64(0);

                gen_helper_store_fpcr(tmp);

                tcg_temp_free(tmp);

            }

            break;

        case 0x025:

            /* MF_FPCR */

            if (likely(ra != 31))

                gen_helper_load_fpcr(cpu_fir[ra]);

            break;

        case 0x02A:

            /* FCMOVEQ */

            gen_fcmpfeq(ra, rb, rc);

            break;

        case 0x02B:

            /* FCMOVNE */

            gen_fcmpfne(ra, rb, rc);

            break;

        case 0x02C:

            /* FCMOVLT */

            gen_fcmpflt(ra, rb, rc);

            break;

        case 0x02D:

            /* FCMOVGE */

            gen_fcmpfge(ra, rb, rc);

            break;

        case 0x02E:

            /* FCMOVLE */

            gen_fcmpfle(ra, rb, rc);

            break;

        case 0x02F:

            /* FCMOVGT */

            gen_fcmpfgt(ra, rb, rc);

            break;

        case 0x030:

            /* CVTQL */

            gen_fcvtql(rb, rc);

            break;

        case 0x130:

            /* CVTQL/V */

            gen_fcvtqlv(rb, rc);

            break;

        case 0x530:

            /* CVTQL/SV */

            gen_fcvtqlsv(rb, rc);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x18:

        switch ((uint16_t)disp16) {

        case 0x0000:

            /* TRAPB */

            /* No-op. Just exit from the current tb */

            ret = 2;

            break;

        case 0x0400:

            /* EXCB */

            /* No-op. Just exit from the current tb */

            ret = 2;

            break;

        case 0x4000:

            /* MB */

            /* No-op */

            break;

        case 0x4400:

            /* WMB */

            /* No-op */

            break;

        case 0x8000:

            /* FETCH */

            /* No-op */

            break;

        case 0xA000:

            /* FETCH_M */

            /* No-op */

            break;

        case 0xC000:

            /* RPCC */

            if (ra != 31)

                gen_helper_load_pcc(cpu_ir[ra]);

            break;

        case 0xE000:

            /* RC */

            if (ra != 31)

                gen_helper_rc(cpu_ir[ra]);

            break;

        case 0xE800:

            /* ECB */

            /* XXX: TODO: evict tb cache at address rb */

#if 0

            ret = 2;

#else

            goto invalid_opc;

#endif

            break;

        case 0xF000:

            /* RS */

            if (ra != 31)

                gen_helper_rs(cpu_ir[ra]);

            break;

        case 0xF800:

            /* WH64 */

            /* No-op */

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x19:

        /* HW_MFPR (PALcode) */

#if defined (CONFIG_USER_ONLY)

        goto invalid_opc;

#else

        if (!ctx->pal_mode)

            goto invalid_opc;

        if (ra != 31) {

            TCGv tmp = tcg_const_i32(insn & 0xFF);

            gen_helper_mfpr(cpu_ir[ra], tmp, cpu_ir[ra]);

            tcg_temp_free(tmp);

        }

        break;

#endif

    case 0x1A:

        if (rb != 31)

            tcg_gen_andi_i64(cpu_pc, cpu_ir[rb], ~3);

        else

            tcg_gen_movi_i64(cpu_pc, 0);

        if (ra != 31)

            tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);

        /* Those four jumps only differ by the branch prediction hint */

        switch (fn2) {

        case 0x0:

            /* JMP */

            break;

        case 0x1:

            /* JSR */

            break;

        case 0x2:

            /* RET */

            break;

        case 0x3:

            /* JSR_COROUTINE */

            break;

        }

        ret = 1;

        break;

    case 0x1B:

        /* HW_LD (PALcode) */

#if defined (CONFIG_USER_ONLY)

        goto invalid_opc;

#else

        if (!ctx->pal_mode)

            goto invalid_opc;

        if (ra != 31) {

            TCGv addr = tcg_temp_new();

            if (rb != 31)

                tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);

            else

                tcg_gen_movi_i64(addr, disp12);

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

            case 0x0:

                /* Longword physical access */

                gen_helper_ldl_raw(cpu_ir[ra], addr);

                break;

            case 0x1:

                /* Quadword physical access */

                gen_helper_ldq_raw(cpu_ir[ra], addr);

                break;

            case 0x2:

                /* Longword physical access with lock */

                gen_helper_ldl_l_raw(cpu_ir[ra], addr);

                break;

            case 0x3:

                /* Quadword physical access with lock */

                gen_helper_ldq_l_raw(cpu_ir[ra], addr);

                break;

            case 0x4:

                /* Longword virtual PTE fetch */

                gen_helper_ldl_kernel(cpu_ir[ra], addr);

                break;

            case 0x5:

                /* Quadword virtual PTE fetch */

                gen_helper_ldq_kernel(cpu_ir[ra], addr);

                break;

            case 0x6:

                /* Incpu_ir[ra]id */

                goto incpu_ir[ra]id_opc;

            case 0x7:

                /* Incpu_ir[ra]id */

                goto incpu_ir[ra]id_opc;

            case 0x8:

                /* Longword virtual access */

                gen_helper_st_virt_to_phys(addr, addr);

                gen_helper_ldl_raw(cpu_ir[ra], addr);

                break;

            case 0x9:

                /* Quadword virtual access */

                gen_helper_st_virt_to_phys(addr, addr);

                gen_helper_ldq_raw(cpu_ir[ra], addr);

                break;

            case 0xA:

                /* Longword virtual access with protection check */

                tcg_gen_qemu_ld32s(cpu_ir[ra], addr, ctx->flags);

                break;

            case 0xB:

                /* Quadword virtual access with protection check */

                tcg_gen_qemu_ld64(cpu_ir[ra], addr, ctx->flags);

                break;

            case 0xC:

                /* Longword virtual access with altenate access mode */

                gen_helper_set_alt_mode();

                gen_helper_st_virt_to_phys(addr, addr);

                gen_helper_ldl_raw(cpu_ir[ra], addr);

                gen_helper_restore_mode();

                break;

            case 0xD:

                /* Quadword virtual access with altenate access mode */

                gen_helper_set_alt_mode();

                gen_helper_st_virt_to_phys(addr, addr);

                gen_helper_ldq_raw(cpu_ir[ra], addr);

                gen_helper_restore_mode();

                break;

            case 0xE:

                /* Longword virtual access with alternate access mode and

                 * protection checks

                 */

                gen_helper_set_alt_mode();

                gen_helper_ldl_data(cpu_ir[ra], addr);

                gen_helper_restore_mode();

                break;

            case 0xF:

                /* Quadword virtual access with alternate access mode and

                 * protection checks

                 */

                gen_helper_set_alt_mode();

                gen_helper_ldq_data(cpu_ir[ra], addr);

                gen_helper_restore_mode();

                break;

            }

            tcg_temp_free(addr);

        }

        break;

#endif

    case 0x1C:

        switch (fn7) {

        case 0x00:

            /* SEXTB */

            if (!(ctx->amask & AMASK_BWX))

                goto invalid_opc;

            if (likely(rc != 31)) {

                if (islit)

                    tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));

                else

                    tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]);

            }

            break;

        case 0x01:

            /* SEXTW */

            if (!(ctx->amask & AMASK_BWX))

                goto invalid_opc;

            if (likely(rc != 31)) {

                if (islit)

                    tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));

                else

                    tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);

            }

            break;

        case 0x30:

            /* CTPOP */

            if (!(ctx->amask & AMASK_CIX))

                goto invalid_opc;

            if (likely(rc != 31)) {

                if (islit)

                    tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));

                else

                    gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]);

            }

            break;

        case 0x31:

            /* PERR */

            if (!(ctx->amask & AMASK_MVI))

                goto invalid_opc;

            /* XXX: TODO */

            goto invalid_opc;

            break;

        case 0x32:

            /* CTLZ */

            if (!(ctx->amask & AMASK_CIX))

                goto invalid_opc;

            if (likely(rc != 31)) {

                if (islit)

                    tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));

                else

                    gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]);

            }

            break;

        case 0x33:

            /* CTTZ */

            if (!(ctx->amask & AMASK_CIX))

                goto invalid_opc;

            if (likely(rc != 31)) {

                if (islit)

                    tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));

                else

                    gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]);

            }

            break;

        case 0x34:

            /* UNPKBW */

            if (!(ctx->amask & AMASK_MVI))

                goto invalid_opc;

            /* XXX: TODO */

            goto invalid_opc;

            break;

        case 0x35:

            /* UNPKWL */

            if (!(ctx->amask & AMASK_MVI))

                goto invalid_opc;

            /* XXX: TODO */

            goto invalid_opc;

            break;

        case 0x36:

            /* PKWB */

            if (!(ctx->amask & AMASK_MVI))

                goto invalid_opc;

            /* XXX: TODO */

            goto invalid_opc;

            break;

        case 0x37:

            /* PKLB */

            if (!(ctx->amask & AMASK_MVI))

                goto invalid_opc;

            /* XXX: TODO */

            goto invalid_opc;

            break;

        case 0x38:

            /* MINSB8 */

            if (!(ctx->amask & AMASK_MVI))

                goto invalid_opc;

            /* XXX: TODO */

            goto invalid_opc;

            break;

        case 0x39:

            /* MINSW4 */

            if (!(ctx->amask & AMASK_MVI))

                goto invalid_opc;

            /* XXX: TODO */

            goto invalid_opc;

            break;

        case 0x3A:

            /* MINUB8 */

            if (!(ctx->amask & AMASK_MVI))

                goto invalid_opc;

            /* XXX: TODO */

            goto invalid_opc;

            break;

        case 0x3B:

            /* MINUW4 */

            if (!(ctx->amask & AMASK_MVI))

                goto invalid_opc;

            /* XXX: TODO */

            goto invalid_opc;

            break;

        case 0x3C:

            /* MAXUB8 */

            if (!(ctx->amask & AMASK_MVI))

                goto invalid_opc;

            /* XXX: TODO */

            goto invalid_opc;

            break;

        case 0x3D:

            /* MAXUW4 */

            if (!(ctx->amask & AMASK_MVI))

                goto invalid_opc;

            /* XXX: TODO */

            goto invalid_opc;

            break;

        case 0x3E:

            /* MAXSB8 */

            if (!(ctx->amask & AMASK_MVI))

                goto invalid_opc;

            /* XXX: TODO */

            goto invalid_opc;

            break;

        case 0x3F:

            /* MAXSW4 */

            if (!(ctx->amask & AMASK_MVI))

                goto invalid_opc;

            /* XXX: TODO */

            goto invalid_opc;

            break;

        case 0x70:

            /* FTOIT */

            if (!(ctx->amask & AMASK_FIX))

                goto invalid_opc;

            if (likely(rc != 31)) {

                if (ra != 31)

                    tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]);

                else

                    tcg_gen_movi_i64(cpu_ir[rc], 0);

            }

            break;

        case 0x78:

            /* FTOIS */

            if (!(ctx->amask & AMASK_FIX))

                goto invalid_opc;

            if (rc != 31) {

                TCGv_i32 tmp1 = tcg_temp_new_i32();

                if (ra != 31)

                    gen_helper_s_to_memory(tmp1, cpu_fir[ra]);

                else {

                    TCGv tmp2 = tcg_const_i64(0);

                    gen_helper_s_to_memory(tmp1, tmp2);

                    tcg_temp_free(tmp2);

                }

                tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1);

                tcg_temp_free_i32(tmp1);

            }

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x1D:

        /* HW_MTPR (PALcode) */

#if defined (CONFIG_USER_ONLY)

        goto invalid_opc;

#else

        if (!ctx->pal_mode)

            goto invalid_opc;

        else {

            TCGv tmp1 = tcg_const_i32(insn & 0xFF);

            if (ra != 31)

                gen_helper_mtpr(tmp1, cpu_ir[ra]);

            else {

                TCGv tmp2 = tcg_const_i64(0);

                gen_helper_mtpr(tmp1, tmp2);

                tcg_temp_free(tmp2);

            }

            tcg_temp_free(tmp1);

            ret = 2;

        }

        break;

#endif

    case 0x1E:

        /* HW_REI (PALcode) */

#if defined (CONFIG_USER_ONLY)

        goto invalid_opc;

#else

        if (!ctx->pal_mode)

            goto invalid_opc;

        if (rb == 31) {

            /* "Old" alpha */

            gen_helper_hw_rei();

        } else {

            TCGv tmp;

            if (ra != 31) {

                tmp = tcg_temp_new();

                tcg_gen_addi_i64(tmp, cpu_ir[rb], (((int64_t)insn << 51) >> 51));

            } else

                tmp = tcg_const_i64(((int64_t)insn << 51) >> 51);

            gen_helper_hw_ret(tmp);

            tcg_temp_free(tmp);

        }

        ret = 2;

        break;

#endif

    case 0x1F:

        /* HW_ST (PALcode) */

#if defined (CONFIG_USER_ONLY)

        goto invalid_opc;

#else

        if (!ctx->pal_mode)

            goto invalid_opc;

        else {

            TCGv addr, val;

            addr = tcg_temp_new();

            if (rb != 31)

                tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);

            else

                tcg_gen_movi_i64(addr, disp12);

            if (ra != 31)

                val = cpu_ir[ra];

            else {

                val = tcg_temp_new();

                tcg_gen_movi_i64(val, 0);

            }

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

            case 0x0:

                /* Longword physical access */

                gen_helper_stl_raw(val, addr);

                break;

            case 0x1:

                /* Quadword physical access */

                gen_helper_stq_raw(val, addr);

                break;

            case 0x2:

                /* Longword physical access with lock */

                gen_helper_stl_c_raw(val, val, addr);

                break;

            case 0x3:

                /* Quadword physical access with lock */

                gen_helper_stq_c_raw(val, val, addr);

                break;

            case 0x4:

                /* Longword virtual access */

                gen_helper_st_virt_to_phys(addr, addr);

                gen_helper_stl_raw(val, addr);

                break;

            case 0x5:

                /* Quadword virtual access */

                gen_helper_st_virt_to_phys(addr, addr);

                gen_helper_stq_raw(val, addr);

                break;

            case 0x6:

                /* Invalid */

                goto invalid_opc;

            case 0x7:

                /* Invalid */

                goto invalid_opc;

            case 0x8:

                /* Invalid */

                goto invalid_opc;

            case 0x9:

                /* Invalid */

                goto invalid_opc;

            case 0xA:

                /* Invalid */

                goto invalid_opc;

            case 0xB:

                /* Invalid */

                goto invalid_opc;

            case 0xC:

                /* Longword virtual access with alternate access mode */

                gen_helper_set_alt_mode();

                gen_helper_st_virt_to_phys(addr, addr);

                gen_helper_stl_raw(val, addr);

                gen_helper_restore_mode();

                break;

            case 0xD:

                /* Quadword virtual access with alternate access mode */

                gen_helper_set_alt_mode();

                gen_helper_st_virt_to_phys(addr, addr);

                gen_helper_stl_raw(val, addr);

                gen_helper_restore_mode();

                break;

            case 0xE:

                /* Invalid */

                goto invalid_opc;

            case 0xF:

                /* Invalid */

                goto invalid_opc;

            }

            if (ra == 31)

                tcg_temp_free(val);

            tcg_temp_free(addr);

        }

        break;

#endif

    case 0x20:

        /* LDF */

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

        break;

    case 0x21:

        /* LDG */

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

        break;

    case 0x22:

        /* LDS */

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

        break;

    case 0x23:

        /* LDT */

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

        break;

    case 0x24:

        /* STF */

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

        break;

    case 0x25:

        /* STG */

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

        break;

    case 0x26:

        /* STS */

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

        break;

    case 0x27:

        /* STT */

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

        break;

    case 0x28:

        /* LDL */

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

        break;

    case 0x29:

        /* LDQ */

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

        break;

    case 0x2A:

        /* LDL_L */

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

        break;

    case 0x2B:

        /* LDQ_L */

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

        break;

    case 0x2C:

        /* STL */

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

        break;

    case 0x2D:

        /* STQ */

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

        break;

    case 0x2E:

        /* STL_C */

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

        break;

    case 0x2F:

        /* STQ_C */

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

        break;

    case 0x30:

        /* BR */

        if (ra != 31)

            tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);

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

        ret = 1;

        break;

    case 0x31: /* FBEQ */

    case 0x32: /* FBLT */

    case 0x33: /* FBLE */

        gen_fbcond(ctx, opc, ra, disp16);

        ret = 1;

        break;

    case 0x34:

        /* BSR */

        if (ra != 31)

            tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);

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

        ret = 1;

        break;

    case 0x35: /* FBNE */

    case 0x36: /* FBGE */

    case 0x37: /* FBGT */

        gen_fbcond(ctx, opc, ra, disp16);

        ret = 1;

        break;

    case 0x38:

        /* BLBC */

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

        ret = 1;

        break;

    case 0x39:

        /* BEQ */

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

        ret = 1;

        break;

    case 0x3A:

        /* BLT */

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

        ret = 1;

        break;

    case 0x3B:

        /* BLE */

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

        ret = 1;

        break;

    case 0x3C:

        /* BLBS */

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

        ret = 1;

        break;

    case 0x3D:

        /* BNE */

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

        ret = 1;

        break;

    case 0x3E:

        /* BGE */

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

        ret = 1;

        break;

    case 0x3F:

        /* BGT */

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

        ret = 1;

        break;

    invalid_opc:

        gen_invalid(ctx);

        ret = 3;

        break;

    }

    return ret;

}


void helper_restore_mode (void)

{

    env->ps = (env->ps & ~0xC) | env->saved_mode;

}


void pc_init_pci64_hole(PcPciInfo *pci_info, uint64_t pci_hole64_start,

                        uint64_t pci_hole64_size)

{

    if ((sizeof(hwaddr) == 4) || (!pci_hole64_size)) {

        return;

    }

    /*

     * BIOS does not set MTRR entries for the 64 bit window, so no need to

     * align address to power of two.  Align address at 1G, this makes sure

     * it can be exactly covered with a PAT entry even when using huge

     * pages.

     */

    pci_info->w64.begin = ROUND_UP(pci_hole64_start, 0x1ULL << 30);

    pci_info->w64.end = pci_info->w64.begin + pci_hole64_size;

    assert(pci_info->w64.begin <= pci_info->w64.end);

}


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

                                const char *name, void *value, size_t size)

{

    char buffer[PATH_MAX];

    if (strncmp(name, "user.virtfs.", 12) == 0) {

        /*

         * Don't allow fetch of user.virtfs namesapce

         * in case of mapped security

         */

        errno = ENOATTR;

        return -1;

    }

    return lgetxattr(rpath(ctx, path, buffer), name, value, size);

}


void arm_load_kernel(CPUState *env, struct arm_boot_info *info)

{

    int kernel_size;

    int initrd_size;

    int n;

    int is_linux = 0;

    uint64_t elf_entry;

    target_phys_addr_t entry;

    int big_endian;

    /* Load the kernel.  */

    if (!info->kernel_filename) {

        fprintf(stderr, "Kernel image must be specified\n");

        exit(1);

    }

    if (!info->secondary_cpu_reset_hook) {

        info->secondary_cpu_reset_hook = default_reset_secondary;

    }

    if (!info->write_secondary_boot) {

        info->write_secondary_boot = default_write_secondary;

    }

    if (info->nb_cpus == 0)

        info->nb_cpus = 1;

#ifdef TARGET_WORDS_BIGENDIAN

    big_endian = 1;

#else

    big_endian = 0;

#endif

    /* Assume that raw images are linux kernels, and ELF images are not.  */

    kernel_size = load_elf(info->kernel_filename, NULL, NULL, &elf_entry,

                           NULL, NULL, big_endian, ELF_MACHINE, 1);

    entry = elf_entry;

    if (kernel_size < 0) {

        kernel_size = load_uimage(info->kernel_filename, &entry, NULL,

                                  &is_linux);

    }

    if (kernel_size < 0) {

        entry = info->loader_start + KERNEL_LOAD_ADDR;

        kernel_size = load_image_targphys(info->kernel_filename, entry,

                                          ram_size - KERNEL_LOAD_ADDR);

        is_linux = 1;

    }

    if (kernel_size < 0) {

        fprintf(stderr, "qemu: could not load kernel '%s'\n",

                info->kernel_filename);

        exit(1);

    }

    info->entry = entry;

    if (is_linux) {

        if (info->initrd_filename) {

            initrd_size = load_image_targphys(info->initrd_filename,

                                              info->loader_start

                                              + INITRD_LOAD_ADDR,

                                              ram_size - INITRD_LOAD_ADDR);

            if (initrd_size < 0) {

                fprintf(stderr, "qemu: could not load initrd '%s'\n",

                        info->initrd_filename);

                exit(1);

            }

        } else {

            initrd_size = 0;

        }

        bootloader[1] |= info->board_id & 0xff;

        bootloader[2] |= (info->board_id >> 8) & 0xff;

        bootloader[5] = info->loader_start + KERNEL_ARGS_ADDR;

        bootloader[6] = entry;

        for (n = 0; n < sizeof(bootloader) / 4; n++) {

            bootloader[n] = tswap32(bootloader[n]);

        }

        rom_add_blob_fixed("bootloader", bootloader, sizeof(bootloader),

                           info->loader_start);

        if (info->nb_cpus > 1) {

            info->write_secondary_boot(env, info);

        }

        info->initrd_size = initrd_size;

    }

    info->is_linux = is_linux;

    for (; env; env = env->next_cpu) {

        env->boot_info = info;

        qemu_register_reset(do_cpu_reset, env);

    }

}


static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,

                                           uint16_t domain_id, hwaddr addr,

                                           uint8_t am)

{

    IntelIOMMUNotifierNode *node;

    VTDContextEntry ce;

    int ret;

    QLIST_FOREACH(node, &(s->notifiers_list), next) {

        VTDAddressSpace *vtd_as = node->vtd_as;

        ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),

                                       vtd_as->devfn, &ce);

        if (!ret && domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) {

            vtd_page_walk(&ce, addr, addr + (1 << am) * VTD_PAGE_SIZE,

                          vtd_page_invalidate_notify_hook,

                          (void *)&vtd_as->iommu, true);

        }

    }

}


int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq)

{

    int rc;

    uint8_t byte;

    if (!dev->crq.qsize) {

        fprintf(stderr, "spapr_vio_send_creq on uninitialized queue\n");

        return -1;

    }

    /* Maybe do a fast path for KVM just writing to the pages */

    rc = spapr_vio_dma_read(dev, dev->crq.qladdr + dev->crq.qnext, &byte, 1);

    if (rc) {

        return rc;

    }

    if (byte != 0) {

        return 1;

    }

    rc = spapr_vio_dma_write(dev, dev->crq.qladdr + dev->crq.qnext + 8,

                             &crq[8], 8);

    if (rc) {

        return rc;

    }

    kvmppc_eieio();

    rc = spapr_vio_dma_write(dev, dev->crq.qladdr + dev->crq.qnext, crq, 8);

    if (rc) {

        return rc;

    }

    dev->crq.qnext = (dev->crq.qnext + 16) % dev->crq.qsize;

    if (dev->signal_state & 1) {

        qemu_irq_pulse(dev->qirq);

    }

    return 0;

}


static void qnull_visit_test(void)

{

    QObject *obj;

    QmpOutputVisitor *qov;

    Visitor *v;

    /*

     * Most tests of interactions between QObject and visitors are in

     * test-qmp-*-visitor; but these tests live here because they

     * depend on layering violations to check qnull_ refcnt.

     */

    g_assert(qnull_.refcnt == 1);

    obj = qnull();

    v = qmp_input_visitor_new(obj, true);

    qobject_decref(obj);

    visit_type_null(v, NULL, &error_abort);

    visit_free(v);

    qov = qmp_output_visitor_new();

    visit_type_null(qmp_output_get_visitor(qov), NULL, &error_abort);

    obj = qmp_output_get_qobject(qov);

    g_assert(obj == &qnull_);

    qobject_decref(obj);

    qmp_output_visitor_cleanup(qov);

    g_assert(qnull_.refcnt == 1);

}


vcard_emul_find_vreader_from_slot(PK11SlotInfo *slot)

{

    VReaderList *reader_list = vreader_get_reader_list();

    VReaderListEntry *current_entry = NULL;

    if (reader_list == NULL) {

        return NULL;

    }

    for (current_entry = vreader_list_get_first(reader_list); current_entry;

                        current_entry = vreader_list_get_next(current_entry)) {

        VReader *reader = vreader_list_get_reader(current_entry);

        VReaderEmul *reader_emul = vreader_get_private(reader);

        if (reader_emul->slot == slot) {

            vreader_list_delete(reader_list);

            return reader;

        }

        vreader_free(reader);

    }

    vreader_list_delete(reader_list);

    return NULL;

}


void qemu_del_polling_cb(PollingFunc *func, void *opaque)

{

    PollingEntry **ppe, *pe;

    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {

        pe = *ppe;

        if (pe->func == func && pe->opaque == opaque) {

            *ppe = pe->next;

            g_free(pe);

            break;

        }

    }

}


static void test_vector_dmul_scalar(const double *src0, const double *src1)

{

    LOCAL_ALIGNED_32(double, cdst, [LEN]);

    LOCAL_ALIGNED_32(double, odst, [LEN]);

    int i;

    declare_func(void, double *dst, const double *src, double mul, int len);

    call_ref(cdst, src0, src1[0], LEN);

    call_new(odst, src0, src1[0], LEN);

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

        if (!double_near_abs_eps(cdst[i], odst[i], DBL_EPSILON)) {

            fprintf(stderr, "%d: %- .12f - %- .12f = % .12g\n", i,

                    cdst[i], odst[i], cdst[i] - odst[i]);

            fail();

            break;

        }

    }

    bench_new(odst, src0, src1[0], LEN);

}


static void show_packet(WriterContext *w, AVFormatContext *fmt_ctx, AVPacket *pkt, int packet_idx)

{

    char val_str[128];

    AVStream *st = fmt_ctx->streams[pkt->stream_index];

    struct print_buf pbuf = {.s = NULL};

    print_section_header("packet");

    print_str("codec_type",       av_x_if_null(av_get_media_type_string(st->codec->codec_type), "unknown"));

    print_int("stream_index",     pkt->stream_index);

    print_ts  ("pts",             pkt->pts);

    print_time("pts_time",        pkt->pts, &st->time_base);

    print_ts  ("dts",             pkt->dts);

    print_time("dts_time",        pkt->dts, &st->time_base);

    print_ts  ("duration",        pkt->duration);

    print_time("duration_time",   pkt->duration, &st->time_base);

    print_val("size",             pkt->size, unit_byte_str);

    print_fmt("pos",   "%"PRId64, pkt->pos);

    print_fmt("flags", "%c",      pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_');

    print_section_footer("packet");

    av_free(pbuf.s);

    fflush(stdout);

}


static int event_thread(void *arg)

{

    AVFormatContext *s = arg;

    SDLContext *sdl = s->priv_data;

    int flags = SDL_BASE_FLAGS | (sdl->window_fullscreen ? SDL_FULLSCREEN : 0);

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

    AVCodecContext *encctx = st->codec;

    /* initialization */

    if (SDL_Init(SDL_INIT_VIDEO) != 0) {

        av_log(s, AV_LOG_ERROR, "Unable to initialize SDL: %s\n", SDL_GetError());

        sdl->init_ret = AVERROR(EINVAL);

        goto init_end;

    }

    SDL_WM_SetCaption(sdl->window_title, sdl->icon_title);

    sdl->surface = SDL_SetVideoMode(sdl->window_width, sdl->window_height,

                                    24, flags);

    if (!sdl->surface) {

        av_log(sdl, AV_LOG_ERROR, "Unable to set video mode: %s\n", SDL_GetError());

        sdl->init_ret = AVERROR(EINVAL);

        goto init_end;

    }

    sdl->overlay = SDL_CreateYUVOverlay(encctx->width, encctx->height,

                                        sdl->overlay_fmt, sdl->surface);

    if (!sdl->overlay || sdl->overlay->pitches[0] < encctx->width) {

        av_log(s, AV_LOG_ERROR,

               "SDL does not support an overlay with size of %dx%d pixels\n",

               encctx->width, encctx->height);

        sdl->init_ret = AVERROR(EINVAL);

        goto init_end;

    }

    sdl->init_ret = 0;

    av_log(s, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s -> w:%d h:%d\n",

           encctx->width, encctx->height, av_get_pix_fmt_name(encctx->pix_fmt),

           sdl->overlay_rect.w, sdl->overlay_rect.h);

init_end:

    SDL_LockMutex(sdl->mutex);

    sdl->inited = 1;

    SDL_UnlockMutex(sdl->mutex);

    SDL_CondSignal(sdl->init_cond);

    if (sdl->init_ret < 0)

        return sdl->init_ret;

    /* event loop */

    while (!sdl->quit) {

        int ret;

        SDL_Event event;

        SDL_PumpEvents();

        ret = SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_ALLEVENTS);

        if (ret < 0)

            av_log(s, AV_LOG_ERROR, "Error when getting SDL event: %s\n", SDL_GetError());

        if (ret <= 0)

            continue;

        switch (event.type) {

        case SDL_KEYDOWN:

            switch (event.key.keysym.sym) {

            case SDLK_ESCAPE:

            case SDLK_q:

                sdl->quit = 1;

                break;

            }

            break;

        case SDL_QUIT:

            sdl->quit = 1;

            break;

        case SDL_VIDEORESIZE:

            sdl->window_width  = event.resize.w;

            sdl->window_height = event.resize.h;

            SDL_LockMutex(sdl->mutex);

            sdl->surface = SDL_SetVideoMode(sdl->window_width, sdl->window_height, 24, SDL_BASE_FLAGS);

            if (!sdl->surface) {

                av_log(s, AV_LOG_ERROR, "Failed to set SDL video mode: %s\n", SDL_GetError());

                sdl->quit = 1;

            } else {

                compute_overlay_rect(s);

            }

            SDL_UnlockMutex(sdl->mutex);

            break;

        default:

            break;

        }

    }

    return 0;

}


static int write_elf_loads(DumpState *s)

{

    hwaddr offset;

    MemoryMapping *memory_mapping;

    uint32_t phdr_index = 1;

    int ret;

    uint32_t max_index;

    if (s->have_section) {

        max_index = s->sh_info;

    } else {

        max_index = s->phdr_num;

    }

    QTAILQ_FOREACH(memory_mapping, &s->list.head, next) {

        offset = get_offset(memory_mapping->phys_addr, s);

        if (s->dump_info.d_class == ELFCLASS64) {

            ret = write_elf64_load(s, memory_mapping, phdr_index++, offset);

        } else {

            ret = write_elf32_load(s, memory_mapping, phdr_index++, offset);

        }

        if (ret < 0) {

            return -1;

        }

        if (phdr_index >= max_index) {

            break;

        }

    }

    return 0;

}


static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,

                            int opc)

{

    int addr_regl, addr_reg1, addr_meml;

    int data_regl, data_regh, data_reg1, data_reg2;

    int mem_index, s_bits;

#if defined(CONFIG_SOFTMMU)

    void *label1_ptr, *label2_ptr;

    int sp_args;

#endif

#if TARGET_LONG_BITS == 64

# if defined(CONFIG_SOFTMMU)

    uint8_t *label3_ptr;

# endif

    int addr_regh, addr_reg2, addr_memh;

#endif

    data_regl = *args++;

    if (opc == 3)

        data_regh = *args++;

    else

        data_regh = 0;

    addr_regl = *args++;

#if TARGET_LONG_BITS == 64

    addr_regh = *args++;

#endif

    mem_index = *args;

    s_bits = opc & 3;

    if (opc == 3) {

#if defined(TCG_TARGET_WORDS_BIGENDIAN)

        data_reg1 = data_regh;

        data_reg2 = data_regl;

#else

        data_reg1 = data_regl;

        data_reg2 = data_regh;

#endif

    } else {

        data_reg1 = data_regl;

        data_reg2 = 0;

    }

#if TARGET_LONG_BITS == 64

# if defined(TCG_TARGET_WORDS_BIGENDIAN)

    addr_reg1 = addr_regh;

    addr_reg2 = addr_regl;

    addr_memh = 0;

    addr_meml = 4;

# else

    addr_reg1 = addr_regl;

    addr_reg2 = addr_regh;

    addr_memh = 4;

    addr_meml = 0;

# endif

#else

    addr_reg1 = addr_regl;

    addr_meml = 0;

#endif

#if defined(CONFIG_SOFTMMU)

    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);

    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);

    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);

    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,

                    offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_meml);

    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));

    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);

# if TARGET_LONG_BITS == 64

    label3_ptr = s->code_ptr;

    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);

    tcg_out_nop(s);

    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,

                    offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_memh);

    label1_ptr = s->code_ptr;

    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);

    tcg_out_nop(s);

    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);

# else

    label1_ptr = s->code_ptr;

    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);

    tcg_out_nop(s);

# endif

    /* slow path */

    sp_args = TCG_REG_A0;

    tcg_out_mov(s, sp_args++, addr_reg1);

# if TARGET_LONG_BITS == 64

    tcg_out_mov(s, sp_args++, addr_reg2);

# endif

    tcg_out_movi(s, TCG_TYPE_I32, sp_args++, mem_index);

    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);

    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);

    tcg_out_nop(s);

    switch(opc) {

    case 0:

        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);

        break;

    case 0 | 4:

        tcg_out_opc_sa(s, OPC_SLL, TCG_REG_V0, TCG_REG_V0, 24);

        tcg_out_opc_sa(s, OPC_SRA, data_reg1, TCG_REG_V0, 24);

        break;

    case 1:

        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);

        break;

    case 1 | 4:

        tcg_out_opc_sa(s, OPC_SLL, TCG_REG_V0, TCG_REG_V0, 16);

        tcg_out_opc_sa(s, OPC_SRA, data_reg1, TCG_REG_V0, 16);

        break;

    case 2:

        tcg_out_mov(s, data_reg1, TCG_REG_V0);

        break;

    case 3:

        tcg_out_mov(s, data_reg2, TCG_REG_V1);

        tcg_out_mov(s, data_reg1, TCG_REG_V0);

        break;

    default:

        tcg_abort();

    }

    label2_ptr = s->code_ptr;

    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);

    tcg_out_nop(s);

    /* label1: fast path */

    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);

    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,

                    offsetof(CPUState, tlb_table[mem_index][0].addend) + addr_meml);

    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);

#else

    if (GUEST_BASE == (int16_t)GUEST_BASE) {

        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_reg1, GUEST_BASE);

    } else {

        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);

        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_reg1);

    }

#endif

    switch(opc) {

    case 0:

        tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);

        break;

    case 0 | 4:

        tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);

        break;

    case 1:

        if (TCG_NEED_BSWAP) {

            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);

            tcg_out_bswap16(s, data_reg1, TCG_REG_T0);

        } else {

            tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);

        }

        break;

    case 1 | 4:

        if (TCG_NEED_BSWAP) {

            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);

            tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);

        } else {

            tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);

        }

        break;

    case 2:

        if (TCG_NEED_BSWAP) {

            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);

            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);

        } else {

            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);

        }

        break;

    case 3:

        if (TCG_NEED_BSWAP) {

            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);

            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);

            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);

            tcg_out_bswap32(s, data_reg2, TCG_REG_T0);

        } else {

            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);

            tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);

        }

        break;

    default:

        tcg_abort();

    }

#if defined(CONFIG_SOFTMMU)

    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);

#endif

}


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

{

    RAMBlock *block;

    bytes_transferred = 0;

    reset_ram_globals();

    if (migrate_use_xbzrle()) {

        XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() /

                                  TARGET_PAGE_SIZE,

                                  TARGET_PAGE_SIZE);

        if (!XBZRLE.cache) {

            DPRINTF("Error creating cache\n");

            return -1;

        }

        XBZRLE.encoded_buf = g_malloc0(TARGET_PAGE_SIZE);

        XBZRLE.current_buf = g_malloc(TARGET_PAGE_SIZE);

        acct_clear();

    }

    /* Make sure all dirty bits are set */

    QLIST_FOREACH(block, &ram_list.blocks, next) {

        migration_bitmap_set_dirty(block->mr, block->length);

    }

    memory_global_dirty_log_start();

    memory_global_sync_dirty_bitmap(get_system_memory());

    qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);

    QLIST_FOREACH(block, &ram_list.blocks, next) {

        qemu_put_byte(f, strlen(block->idstr));

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

        qemu_put_be64(f, block->length);

    }

    qemu_put_be64(f, RAM_SAVE_FLAG_EOS);

    return 0;

}


static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)

{

    int bus_offset;

    if (pci_dev->devfn & 1)

        bus_offset = 16;

    else

        bus_offset = 0;

    return (bus_offset + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;

}


static void xics_reset(void *opaque)

{

    struct icp_state *icp = (struct icp_state *)opaque;

    struct ics_state *ics = icp->ics;

    int i;

    for (i = 0; i < icp->nr_servers; i++) {

        icp->ss[i].xirr = 0;

        icp->ss[i].pending_priority = 0;

        icp->ss[i].mfrr = 0xff;

        /* Make all outputs are deasserted */

        qemu_set_irq(icp->ss[i].output, 0);

    }

    for (i = 0; i < ics->nr_irqs; i++) {

        /* Reset everything *except* the type */

        ics->irqs[i].server = 0;

        ics->irqs[i].status = 0;

        ics->irqs[i].priority = 0xff;

        ics->irqs[i].saved_priority = 0xff;

    }

}


static uint64_t assigned_dev_ioport_rw(AssignedDevRegion *dev_region,

                                       target_phys_addr_t addr, int size,

                                       uint64_t *data)

{

    uint64_t val = 0;

    int fd = dev_region->region->resource_fd;

    if (fd >= 0) {

        if (data) {

            DEBUG("pwrite data=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx

                  ", addr="TARGET_FMT_plx"\n", *data, size, addr, addr);

            if (pwrite(fd, data, size, addr) != size) {

                error_report("%s - pwrite failed %s",

                             __func__, strerror(errno));

            }

        } else {

            if (pread(fd, &val, size, addr) != size) {

                error_report("%s - pread failed %s",

                             __func__, strerror(errno));

                val = (1UL << (size * 8)) - 1;

            }

            DEBUG("pread val=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx

                  ", addr=" TARGET_FMT_plx "\n", val, size, addr, addr);

        }

    } else {

        uint32_t port = addr + dev_region->u.r_baseport;

        if (data) {

            DEBUG("out data=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx

                  ", host=%x\n", *data, size, addr, port);

            switch (size) {

            case 1:

                outb(*data, port);

                break;

            case 2:

                outw(*data, port);

                break;

            case 4:

                outl(*data, port);

                break;

            }

        } else {

            switch (size) {

            case 1:

                val = inb(port);

                break;

            case 2:

                val = inw(port);

                break;

            case 4:

                val = inl(port);

                break;

            }

            DEBUG("in data=%" PRIx64 ", size=%d, e_phys=" TARGET_FMT_plx

                  ", host=%x\n", val, size, addr, port);

        }

    }

    return val;

}


int nbd_client_co_pwritev(BlockDriverState *bs, uint64_t offset,

                          uint64_t bytes, QEMUIOVector *qiov, int flags)

{

    NbdClientSession *client = nbd_get_client_session(bs);

    struct nbd_request request = {

        .type = NBD_CMD_WRITE,

        .from = offset,

        .len = bytes,

    };

    struct nbd_reply reply;

    ssize_t ret;

    if (flags & BDRV_REQ_FUA) {

        assert(client->nbdflags & NBD_FLAG_SEND_FUA);

        request.type |= NBD_CMD_FLAG_FUA;

    }

    assert(bytes <= NBD_MAX_BUFFER_SIZE);

    nbd_coroutine_start(client, &request);

    ret = nbd_co_send_request(bs, &request, qiov);

    if (ret < 0) {

        reply.error = -ret;

    } else {

        nbd_co_receive_reply(client, &request, &reply, NULL);

    }

    nbd_coroutine_end(client, &request);

    return -reply.error;

}


static void gen_ldf_asi(DisasContext *dc, TCGv addr,

                        int insn, int size, int rd)

{

    TCGv_i32 r_asi, r_size, r_rd;

    r_asi = gen_get_asi(dc, insn);

    r_size = tcg_const_i32(size);

    r_rd = tcg_const_i32(rd);

    gen_helper_ldf_asi(cpu_env, addr, r_asi, r_size, r_rd);

    tcg_temp_free_i32(r_rd);

    tcg_temp_free_i32(r_size);

    tcg_temp_free_i32(r_asi);

}


static int64_t qemu_next_deadline(void)

{

    int64_t delta;

    if (active_timers[QEMU_CLOCK_VIRTUAL]) {

        delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -

                     qemu_get_clock(vm_clock);

    } else {

        /* To avoid problems with overflow limit this to 2^32.  */

        delta = INT32_MAX;

    }

    if (delta < 0)

        delta = 0;

    return delta;

}


int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port)

{

    struct socket *so;

    struct socket *head = (is_udp ? &udb : &tcb);

    struct sockaddr_in addr;

    int port = htons(host_port);

    socklen_t addr_len;

    int n = 0;

 loop_again:

    for (so = head->so_next; so != head; so = so->so_next) {

        addr_len = sizeof(addr);

        if (getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&

            addr.sin_addr.s_addr == host_addr.s_addr &&

            addr.sin_port == port) {

            close(so->s);

            sofree(so);

            n++;

            goto loop_again;

        }

    }

    return n;

}


static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr,

                             uint64_t asc, target_ulong *raddr, int *flags,

                             int rw)

{

    uint64_t asce = 0;

    int level, new_level;

    int r;

    switch (asc) {

    case PSW_ASC_PRIMARY:

        PTE_DPRINTF("%s: asc=primary\n", __func__);

        asce = env->cregs[1];

        break;

    case PSW_ASC_SECONDARY:

        PTE_DPRINTF("%s: asc=secondary\n", __func__);

        asce = env->cregs[7];

        break;

    case PSW_ASC_HOME:

        PTE_DPRINTF("%s: asc=home\n", __func__);

        asce = env->cregs[13];

        break;

    }

    if (asce & _ASCE_REAL_SPACE) {

        /* direct mapping */

        *raddr = vaddr;

        return 0;

    }

    switch (asce & _ASCE_TYPE_MASK) {

    case _ASCE_TYPE_REGION1:

        break;

    case _ASCE_TYPE_REGION2:

        if (vaddr & 0xffe0000000000000ULL) {

            DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64

                    " 0xffe0000000000000ULL\n", __func__, vaddr);

            trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw);

            return -1;

        }

        break;

    case _ASCE_TYPE_REGION3:

        if (vaddr & 0xfffffc0000000000ULL) {

            DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64

                    " 0xfffffc0000000000ULL\n", __func__, vaddr);

            trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw);

            return -1;

        }

        break;

    case _ASCE_TYPE_SEGMENT:

        if (vaddr & 0xffffffff80000000ULL) {

            DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64

                    " 0xffffffff80000000ULL\n", __func__, vaddr);

            trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw);

            return -1;

        }

        break;

    }

    /* fake level above current */

    level = asce & _ASCE_TYPE_MASK;

    new_level = level + 4;

    asce = (asce & ~_ASCE_TYPE_MASK) | (new_level & _ASCE_TYPE_MASK);

    r = mmu_translate_asce(env, vaddr, asc, asce, new_level, raddr, flags, rw);

    if ((rw == 1) && !(*flags & PAGE_WRITE)) {

        trigger_prot_fault(env, vaddr, asc);

        return -1;

    }

    return r;

}


static void kvm_arm_machine_init_done(Notifier *notifier, void *data)

{

    KVMDevice *kd, *tkd;

    memory_listener_unregister(&devlistener);

    QSLIST_FOREACH_SAFE(kd, &kvm_devices_head, entries, tkd) {

        if (kd->kda.addr != -1) {

            if (kvm_vm_ioctl(kvm_state, KVM_ARM_SET_DEVICE_ADDR,

                             &kd->kda) < 0) {

                fprintf(stderr, "KVM_ARM_SET_DEVICE_ADDRESS failed: %s\n",

                        strerror(errno));

                abort();

            }

        }

        memory_region_unref(kd->mr);

        g_free(kd);

    }

}


static void dec_sru(DisasContext *dc)

{

    if (dc->format == OP_FMT_RI) {

        LOG_DIS("srui r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm5);

    } else {

        LOG_DIS("sru r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);

    }

    if (dc->format == OP_FMT_RI) {

        if (!(dc->features & LM32_FEATURE_SHIFT) && (dc->imm5 != 1)) {

            qemu_log_mask(LOG_GUEST_ERROR,

                    "hardware shifter is not available\n");

            t_gen_illegal_insn(dc);

            return;

        }

        tcg_gen_shri_tl(cpu_R[dc->r1], cpu_R[dc->r0], dc->imm5);

    } else {

        int l1 = gen_new_label();

        int l2 = gen_new_label();

        TCGv t0 = tcg_temp_local_new();

        tcg_gen_andi_tl(t0, cpu_R[dc->r1], 0x1f);

        if (!(dc->features & LM32_FEATURE_SHIFT)) {

            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 1, l1);

            t_gen_illegal_insn(dc);

            tcg_gen_br(l2);

        }

        gen_set_label(l1);

        tcg_gen_shr_tl(cpu_R[dc->r2], cpu_R[dc->r0], t0);

        gen_set_label(l2);

        tcg_temp_free(t0);

    }

}


static void test_visitor_in_native_list_string(TestInputVisitorData *data,

                                               const void *unused)

{

    UserDefNativeListUnion *cvalue = NULL;

    strList *elem = NULL;

    Visitor *v;

    GString *gstr_list = g_string_new("");

    GString *gstr_union = g_string_new("");

    int i;

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

        g_string_append_printf(gstr_list, "'%d'", i);

        if (i != 31) {

            g_string_append(gstr_list, ", ");

        }

    }

    g_string_append_printf(gstr_union,  "{ 'type': 'string', 'data': [ %s ] }",

                           gstr_list->str);

    v = visitor_input_test_init_raw(data,  gstr_union->str);

    visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);

    g_assert(cvalue != NULL);

    g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);

    for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) {

        gchar str[8];

        sprintf(str, "%d", i);

        g_assert_cmpstr(elem->value, ==, str);

    }

    g_string_free(gstr_union, true);

    g_string_free(gstr_list, true);

    qapi_free_UserDefNativeListUnion(cvalue);

}


static int kvm_get_xsave(CPUState *env)

{

#ifdef KVM_CAP_XSAVE

    struct kvm_xsave* xsave;

    int ret, i;

    uint16_t cwd, swd, twd, fop;

    if (!kvm_has_xsave())

        return kvm_get_fpu(env);

    xsave = qemu_memalign(4096, sizeof(struct kvm_xsave));

    ret = kvm_vcpu_ioctl(env, KVM_GET_XSAVE, xsave);

    if (ret < 0) {

        qemu_free(xsave);

        return ret;

    }

    cwd = (uint16_t)xsave->region[0];

    swd = (uint16_t)(xsave->region[0] >> 16);

    twd = (uint16_t)xsave->region[1];

    fop = (uint16_t)(xsave->region[1] >> 16);

    env->fpstt = (swd >> 11) & 7;

    env->fpus = swd;

    env->fpuc = cwd;

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

        env->fptags[i] = !((twd >> i) & 1);

    env->mxcsr = xsave->region[XSAVE_MXCSR];

    memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE],

            sizeof env->fpregs);

    memcpy(env->xmm_regs, &xsave->region[XSAVE_XMM_SPACE],

            sizeof env->xmm_regs);

    env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV];

    memcpy(env->ymmh_regs, &xsave->region[XSAVE_YMMH_SPACE],

            sizeof env->ymmh_regs);

    qemu_free(xsave);

    return 0;

#else

    return kvm_get_fpu(env);

#endif

}


void do_migrate_set_speed(Monitor *mon, const QDict *qdict)

{

    double d;

    char *ptr;

    FdMigrationState *s;

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

    d = strtod(value, &ptr);

    switch (*ptr) {

    case 'G': case 'g':

        d *= 1024;

    case 'M': case 'm':

        d *= 1024;

    case 'K': case 'k':

        d *= 1024;

    default:

        break;

    }

    max_throttle = (uint32_t)d;

    s = migrate_to_fms(current_migration);

    if (s && s->file) {

        qemu_file_set_rate_limit(s->file, max_throttle);

    }

}


static int nbd_opt_go(QIOChannel *ioc, const char *wantname,

                      NBDExportInfo *info, Error **errp)

{

    nbd_opt_reply reply;

    uint32_t len = strlen(wantname);

    uint16_t type;

    int error;

    char *buf;

    /* The protocol requires that the server send NBD_INFO_EXPORT with

     * a non-zero flags (at least NBD_FLAG_HAS_FLAGS must be set); so

     * flags still 0 is a witness of a broken server. */

    info->flags = 0;

    trace_nbd_opt_go_start(wantname);

    buf = g_malloc(4 + len + 2 + 1);

    stl_be_p(buf, len);

    memcpy(buf + 4, wantname, len);

    /* No requests, live with whatever server sends */

    stw_be_p(buf + 4 + len, 0);

    if (nbd_send_option_request(ioc, NBD_OPT_GO, len + 6, buf, errp) < 0) {

        return -1;

    }

    while (1) {

        if (nbd_receive_option_reply(ioc, NBD_OPT_GO, &reply, errp) < 0) {

            return -1;

        }

        error = nbd_handle_reply_err(ioc, &reply, errp);

        if (error <= 0) {

            return error;

        }

        len = reply.length;

        if (reply.type == NBD_REP_ACK) {

            /* Server is done sending info and moved into transmission

               phase, but make sure it sent flags */

            if (len) {

                error_setg(errp, "server sent invalid NBD_REP_ACK");

                nbd_send_opt_abort(ioc);

                return -1;

            }

            if (!info->flags) {

                error_setg(errp, "broken server omitted NBD_INFO_EXPORT");

                nbd_send_opt_abort(ioc);

                return -1;

            }

            trace_nbd_opt_go_success();

            return 1;

        }

        if (reply.type != NBD_REP_INFO) {

            error_setg(errp, "unexpected reply type %" PRIx32 ", expected %x",

                       reply.type, NBD_REP_INFO);

            nbd_send_opt_abort(ioc);

            return -1;

        }

        if (len < sizeof(type)) {

            error_setg(errp, "NBD_REP_INFO length %" PRIu32 " is too short",

                       len);

            nbd_send_opt_abort(ioc);

            return -1;

        }

        if (nbd_read(ioc, &type, sizeof(type), errp) < 0) {

            error_prepend(errp, "failed to read info type");

            nbd_send_opt_abort(ioc);

            return -1;

        }

        len -= sizeof(type);

        be16_to_cpus(&type);

        switch (type) {

        case NBD_INFO_EXPORT:

            if (len != sizeof(info->size) + sizeof(info->flags)) {

                error_setg(errp, "remaining export info len %" PRIu32

                           " is unexpected size", len);

                nbd_send_opt_abort(ioc);

                return -1;

            }

            if (nbd_read(ioc, &info->size, sizeof(info->size), errp) < 0) {

                error_prepend(errp, "failed to read info size");

                nbd_send_opt_abort(ioc);

                return -1;

            }

            be64_to_cpus(&info->size);

            if (nbd_read(ioc, &info->flags, sizeof(info->flags), errp) < 0) {

                error_prepend(errp, "failed to read info flags");

                nbd_send_opt_abort(ioc);

                return -1;

            }

            be16_to_cpus(&info->flags);

            trace_nbd_receive_negotiate_size_flags(info->size, info->flags);

            break;

        default:

            trace_nbd_opt_go_info_unknown(type, nbd_info_lookup(type));

            if (nbd_drop(ioc, len, errp) < 0) {

                error_prepend(errp, "Failed to read info payload");

                nbd_send_opt_abort(ioc);

                return -1;

            }

            break;

        }

    }

}


void s390_crw_mchk(S390CPU *cpu)

{

    if (kvm_enabled()) {

        kvm_s390_crw_mchk(cpu);

    } else {

        cpu_inject_crw_mchk(cpu);

    }

}


static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)

{

    DisasContext *dc = container_of(dcbase, DisasContext, base);

    CPUARMState *env = cpu->env_ptr;

    if (dc->ss_active && !dc->pstate_ss) {

        /* Singlestep state is Active-pending.

         * If we're in this state at the start of a TB then either

         *  a) we just took an exception to an EL which is being debugged

         *     and this is the first insn in the exception handler

         *  b) debug exceptions were masked and we just unmasked them

         *     without changing EL (eg by clearing PSTATE.D)

         * In either case we're going to take a swstep exception in the

         * "did not step an insn" case, and so the syndrome ISV and EX

         * bits should be zero.

         */

        assert(dc->base.num_insns == 1);

        gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),

                      default_exception_el(dc));

        dc->base.is_jmp = DISAS_NORETURN;

    } else {

        disas_a64_insn(env, dc);

    }

    if (dc->base.is_jmp == DISAS_NEXT) {

        if (dc->ss_active || dc->pc >= dc->next_page_start) {

            dc->base.is_jmp = DISAS_TOO_MANY;

        }

    }

    dc->base.pc_next = dc->pc;

    translator_loop_temp_check(&dc->base);

}


int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,

                          CPUBreakpoint **breakpoint)

{

#if defined(TARGET_HAS_ICE)

    CPUBreakpoint *bp;

    bp = g_malloc(sizeof(*bp));

    bp->pc = pc;

    bp->flags = flags;

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

    if (flags & BP_GDB) {

        QTAILQ_INSERT_HEAD(&cpu->breakpoints, bp, entry);

    } else {

        QTAILQ_INSERT_TAIL(&cpu->breakpoints, bp, entry);

    }

    breakpoint_invalidate(cpu, pc);

    if (breakpoint) {

        *breakpoint = bp;

    }

    return 0;

#else

    return -ENOSYS;

#endif

}


static uint64_t msix_pba_mmio_read(void *opaque, target_phys_addr_t addr,

                                   unsigned size)

{

    PCIDevice *dev = opaque;

    return pci_get_long(dev->msix_pba + addr);

}


static void mcf_fec_write(void *opaque, target_phys_addr_t addr,

                          uint64_t value, unsigned size)

{

    mcf_fec_state *s = (mcf_fec_state *)opaque;

    switch (addr & 0x3ff) {

    case 0x004:

        s->eir &= ~value;

        break;

    case 0x008:

        s->eimr = value;

        break;

    case 0x010: /* RDAR */

        if ((s->ecr & FEC_EN) && !s->rx_enabled) {

            DPRINTF("RX enable\n");

            mcf_fec_enable_rx(s);

        }

        break;

    case 0x014: /* TDAR */

        if (s->ecr & FEC_EN) {

            mcf_fec_do_tx(s);

        }

        break;

    case 0x024:

        s->ecr = value;

        if (value & FEC_RESET) {

            DPRINTF("Reset\n");

            mcf_fec_reset(s);

        }

        if ((s->ecr & FEC_EN) == 0) {

            s->rx_enabled = 0;

        }

        break;

    case 0x040:

        /* TODO: Implement MII.  */

        s->mmfr = value;

        break;

    case 0x044:

        s->mscr = value & 0xfe;

        break;

    case 0x064:

        /* TODO: Implement MIB.  */

        break;

    case 0x084:

        s->rcr = value & 0x07ff003f;

        /* TODO: Implement LOOP mode.  */

        break;

    case 0x0c4: /* TCR */

        /* We transmit immediately, so raise GRA immediately.  */

        s->tcr = value;

        if (value & 1)

            s->eir |= FEC_INT_GRA;

        break;

    case 0x0e4: /* PALR */

        s->conf.macaddr.a[0] = value >> 24;

        s->conf.macaddr.a[1] = value >> 16;

        s->conf.macaddr.a[2] = value >> 8;

        s->conf.macaddr.a[3] = value;

        break;

    case 0x0e8: /* PAUR */

        s->conf.macaddr.a[4] = value >> 24;

        s->conf.macaddr.a[5] = value >> 16;

        break;

    case 0x0ec:

        /* OPD */

        break;

    case 0x118:

    case 0x11c:

    case 0x120:

    case 0x124:

        /* TODO: implement MAC hash filtering.  */

        break;

    case 0x144:

        s->tfwr = value & 3;

        break;

    case 0x14c:

        /* FRBR writes ignored.  */

        break;

    case 0x150:

        s->rfsr = (value & 0x3fc) | 0x400;

        break;

    case 0x180:

        s->erdsr = value & ~3;

        s->rx_descriptor = s->erdsr;

        break;

    case 0x184:

        s->etdsr = value & ~3;

        s->tx_descriptor = s->etdsr;

        break;

    case 0x188:

        s->emrbr = value & 0x7f0;

        break;

    default:

        hw_error("mcf_fec_write Bad address 0x%x\n", (int)addr);

    }

    mcf_fec_update(s);

}


static void process_incoming_migration_co(void *opaque)

{

    QEMUFile *f = opaque;

    Error *local_err = NULL;

    int ret;

    migration_incoming_state_new(f);

    migrate_generate_event(MIGRATION_STATUS_ACTIVE);

    ret = qemu_loadvm_state(f);

    qemu_fclose(f);

    free_xbzrle_decoded_buf();

    migration_incoming_state_destroy();

    if (ret < 0) {

        migrate_generate_event(MIGRATION_STATUS_FAILED);

        error_report("load of migration failed: %s", strerror(-ret));

        migrate_decompress_threads_join();

        exit(EXIT_FAILURE);

    }

    migrate_generate_event(MIGRATION_STATUS_COMPLETED);

    qemu_announce_self();

    /* Make sure all file formats flush their mutable metadata */

    bdrv_invalidate_cache_all(&local_err);

    if (local_err) {

        error_report_err(local_err);

        migrate_decompress_threads_join();

        exit(EXIT_FAILURE);

    }

    /* If global state section was not received or we are in running

       state, we need to obey autostart. Any other state is set with

       runstate_set. */

    if (!global_state_received() ||

        global_state_get_runstate() == RUN_STATE_RUNNING) {

        if (autostart) {

            vm_start();

        } else {

            runstate_set(RUN_STATE_PAUSED);

        }

    } else {

        runstate_set(global_state_get_runstate());

    }

    migrate_decompress_threads_join();

}