static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)

{

    uint32_t palcode;

    int32_t disp21, disp16;

#ifndef CONFIG_USER_ONLY

    int32_t disp12;

#endif

    uint16_t fn11;

    uint8_t opc, ra, rb, rc, fpfn, fn7, islit, real_islit;

    uint8_t lit;

    ExitStatus ret;

    /* Decode all instruction fields */

    opc = insn >> 26;

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

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

    rc = insn & 0x1F;

    real_islit = 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);

#ifndef CONFIG_USER_ONLY

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

#endif

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

    fpfn = fn11 & 0x3F;

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

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

              opc, ra, rb, rc, disp16);

    ret = NO_EXIT;

    switch (opc) {

    case 0x00:

        /* CALL_PAL */

        ret = gen_call_pal(ctx, palcode);

        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->tb->flags & TB_FLAGS_AMASK_BWX) {

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

            break;

        }

        goto invalid_opc;

    case 0x0B:

        /* LDQ_U */

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

        break;

    case 0x0C:

        /* LDWU */

        if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {

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

            break;

        }

        goto invalid_opc;

    case 0x0D:

        /* STW */

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

        break;

    case 0x0E:

        /* STB */

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

        break;

    case 0x0F:

        /* STQ_U */

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

        break;

    case 0x10:

        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_NE, ra, rb, rc, islit, lit, 1);

            break;

        case 0x16:

            /* CMOVLBC */

            gen_cmov(TCG_COND_EQ, 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_EQ, ra, rb, rc, islit, lit, 0);

            break;

        case 0x26:

            /* CMOVNE */

            gen_cmov(TCG_COND_NE, 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_LT, ra, rb, rc, islit, lit, 0);

            break;

        case 0x46:

            /* CMOVGE */

            gen_cmov(TCG_COND_GE, 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)) {

                uint64_t amask = ctx->tb->flags >> TB_FLAGS_AMASK_SHIFT;

                if (islit) {

                    tcg_gen_movi_i64(cpu_ir[rc], lit & ~amask);

                } else {

                    tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rb], ~amask);

                }

            }

            break;

        case 0x64:

            /* CMOVLE */

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

            break;

        case 0x66:

            /* CMOVGT */

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

            break;

        case 0x6C:

            /* IMPLVER */

            if (rc != 31) {

                tcg_gen_movi_i64(cpu_ir[rc], ctx->implver);

            }

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x12:

        switch (fn7) {

        case 0x02:

            /* MSKBL */

            gen_msk_l(ra, rb, rc, islit, lit, 0x01);

            break;

        case 0x06:

            /* EXTBL */

            gen_ext_l(ra, rb, rc, islit, lit, 0x01);

            break;

        case 0x0B:

            /* INSBL */

            gen_ins_l(ra, rb, rc, islit, lit, 0x01);

            break;

        case 0x12:

            /* MSKWL */

            gen_msk_l(ra, rb, rc, islit, lit, 0x03);

            break;

        case 0x16:

            /* EXTWL */

            gen_ext_l(ra, rb, rc, islit, lit, 0x03);

            break;

        case 0x1B:

            /* INSWL */

            gen_ins_l(ra, rb, rc, islit, lit, 0x03);

            break;

        case 0x22:

            /* MSKLL */

            gen_msk_l(ra, rb, rc, islit, lit, 0x0f);

            break;

        case 0x26:

            /* EXTLL */

            gen_ext_l(ra, rb, rc, islit, lit, 0x0f);

            break;

        case 0x2B:

            /* INSLL */

            gen_ins_l(ra, rb, rc, islit, lit, 0x0f);

            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_msk_l(ra, rb, rc, islit, lit, 0xff);

            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(ra, rb, rc, islit, lit, 0xff);

            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_ins_l(ra, rb, rc, islit, lit, 0xff);

            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_msk_h(ra, rb, rc, islit, lit, 0x03);

            break;

        case 0x57:

            /* INSWH */

            gen_ins_h(ra, rb, rc, islit, lit, 0x03);

            break;

        case 0x5A:

            /* EXTWH */

            gen_ext_h(ra, rb, rc, islit, lit, 0x03);

            break;

        case 0x62:

            /* MSKLH */

            gen_msk_h(ra, rb, rc, islit, lit, 0x0f);

            break;

        case 0x67:

            /* INSLH */

            gen_ins_h(ra, rb, rc, islit, lit, 0x0f);

            break;

        case 0x6A:

            /* EXTLH */

            gen_ext_h(ra, rb, rc, islit, lit, 0x0f);

            break;

        case 0x72:

            /* MSKQH */

            gen_msk_h(ra, rb, rc, islit, lit, 0xff);

            break;

        case 0x77:

            /* INSQH */

            gen_ins_h(ra, rb, rc, islit, lit, 0xff);

            break;

        case 0x7A:

            /* EXTQH */

            gen_ext_h(ra, rb, rc, islit, lit, 0xff);

            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 */

            {

                TCGv low;

                if (unlikely(rc == 31)){

                    break;

                }

                if (ra == 31) {

                    tcg_gen_movi_i64(cpu_ir[rc], 0);

                    break;

                }

                low = tcg_temp_new();

                if (islit) {

                    tcg_gen_movi_tl(low, lit);

                    tcg_gen_mulu2_i64(low, cpu_ir[rc], cpu_ir[ra], low);

                } else {

                    tcg_gen_mulu2_i64(low, cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);

                }

                tcg_temp_free(low);

            }

            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) { /* fn11 & 0x3F */

        case 0x04:

            /* ITOFS */

            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {

                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->tb->flags & TB_FLAGS_AMASK_FIX) {

                gen_fsqrtf(rb, rc);

                break;

            }

            goto invalid_opc;

        case 0x0B:

            /* SQRTS */

            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {

                gen_fsqrts(ctx, rb, rc, fn11);

                break;

            }

            goto invalid_opc;

        case 0x14:

            /* ITOFF */

            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {

                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->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {

                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->tb->flags & TB_FLAGS_AMASK_FIX) {

                gen_fsqrtg(rb, rc);

                break;

            }

            goto invalid_opc;

        case 0x02B:

            /* SQRTT */

            if (ctx->tb->flags & TB_FLAGS_AMASK_FIX) {

                gen_fsqrtt(ctx, rb, rc, fn11);

                break;

            }

            goto invalid_opc;

        default:

            goto invalid_opc;

        }

        break;

    case 0x15:

        /* VAX floating point */

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

        switch (fpfn) { /* fn11 & 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 */

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

        case 0x00:

            /* ADDS */

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

            break;

        case 0x01:

            /* SUBS */

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

            break;

        case 0x02:

            /* MULS */

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

            break;

        case 0x03:

            /* DIVS */

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

            break;

        case 0x20:

            /* ADDT */

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

            break;

        case 0x21:

            /* SUBT */

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

            break;

        case 0x22:

            /* MULT */

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

            break;

        case 0x23:

            /* DIVT */

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

            break;

        case 0x24:

            /* CMPTUN */

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

            break;

        case 0x25:

            /* CMPTEQ */

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

            break;

        case 0x26:

            /* CMPTLT */

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

            break;

        case 0x27:

            /* CMPTLE */

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

            break;

        case 0x2C:

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

                /* CVTST */

                gen_fcvtst(ctx, rb, rc, fn11);

            } else {

                /* CVTTS */

                gen_fcvtts(ctx, rb, rc, fn11);

            }

            break;

        case 0x2F:

            /* CVTTQ */

            gen_fcvttq(ctx, rb, rc, fn11);

            break;

        case 0x3C:

            /* CVTQS */

            gen_fcvtqs(ctx, rb, rc, fn11);

            break;

        case 0x3E:

            /* CVTQT */

            gen_fcvtqt(ctx, rb, rc, fn11);

            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 */

                    if (ra == 31) {

                        tcg_gen_movi_i64(cpu_fir[rc], 0);

                    } else {

                        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_env, cpu_fir[ra]);

            } else {

                TCGv tmp = tcg_const_i64(0);

                gen_helper_store_fpcr(cpu_env, tmp);

                tcg_temp_free(tmp);

            }

            break;

        case 0x025:

            /* MF_FPCR */

            if (likely(ra != 31)) {

                gen_helper_load_fpcr(cpu_fir[ra], cpu_env);

            }

            break;

        case 0x02A:

            /* FCMOVEQ */

            gen_fcmov(TCG_COND_EQ, ra, rb, rc);

            break;

        case 0x02B:

            /* FCMOVNE */

            gen_fcmov(TCG_COND_NE, ra, rb, rc);

            break;

        case 0x02C:

            /* FCMOVLT */

            gen_fcmov(TCG_COND_LT, ra, rb, rc);

            break;

        case 0x02D:

            /* FCMOVGE */

            gen_fcmov(TCG_COND_GE, ra, rb, rc);

            break;

        case 0x02E:

            /* FCMOVLE */

            gen_fcmov(TCG_COND_LE, ra, rb, rc);

            break;

        case 0x02F:

            /* FCMOVGT */

            gen_fcmov(TCG_COND_GT, ra, rb, rc);

            break;

        case 0x030:

            /* CVTQL */

            gen_fcvtql(rb, rc);

            break;

        case 0x130:

            /* CVTQL/V */

        case 0x530:

            /* CVTQL/SV */

            /* ??? I'm pretty sure there's nothing that /sv needs to do that

               /v doesn't do.  The only thing I can think is that /sv is a

               valid instruction merely for completeness in the ISA.  */

            gen_fcvtql_v(ctx, rb, rc);

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x18:

        switch ((uint16_t)disp16) {

        case 0x0000:

            /* TRAPB */

            /* No-op.  */

            break;

        case 0x0400:

            /* EXCB */

            /* No-op.  */

            break;

        case 0x4000:

            /* MB */

            /* 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) {

                if (use_icount) {

                    gen_io_start();

                    gen_helper_load_pcc(cpu_ir[ra], cpu_env);

                    gen_io_end();

                    ret = EXIT_PC_STALE;

                } else {

                    gen_helper_load_pcc(cpu_ir[ra], cpu_env);

                }

            }

            break;

        case 0xE000:

            /* RC */

            gen_rx(ra, 0);

            break;

        case 0xE800:

            /* ECB */

            break;

        case 0xF000:

            /* RS */

            gen_rx(ra, 1);

            break;

        case 0xF800:

            /* WH64 */

            /* No-op */

            break;

        default:

            goto invalid_opc;

        }

        break;

    case 0x19:

        /* HW_MFPR (PALcode) */

#ifndef CONFIG_USER_ONLY

        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {

            return gen_mfpr(ra, insn & 0xffff);

        }

#endif

        goto invalid_opc;

    case 0x1A:

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

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

        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);

        }

        ret = EXIT_PC_UPDATED;

        break;

    case 0x1B:

        /* HW_LD (PALcode) */

#ifndef CONFIG_USER_ONLY

        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {

            TCGv addr;

            if (ra == 31) {

                break;

            }

            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 (hw_ldl/p) */

                gen_helper_ldl_phys(cpu_ir[ra], cpu_env, addr);

                break;

            case 0x1:

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

                gen_helper_ldq_phys(cpu_ir[ra], cpu_env, addr);

                break;

            case 0x2:

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

                gen_helper_ldl_l_phys(cpu_ir[ra], cpu_env, addr);

                break;

            case 0x3:

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

                gen_helper_ldq_l_phys(cpu_ir[ra], cpu_env, addr);

                break;

            case 0x4:

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

                goto invalid_opc;

            case 0x5:

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

                goto invalid_opc;

                break;

            case 0x6:

                /* Incpu_ir[ra]id */

                goto invalid_opc;

            case 0x7:

                /* Incpu_ir[ra]id */

                goto invalid_opc;

            case 0x8:

                /* Longword virtual access (hw_ldl) */

                goto invalid_opc;

            case 0x9:

                /* Quadword virtual access (hw_ldq) */

                goto invalid_opc;

            case 0xA:

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

                tcg_gen_qemu_ld_i64(cpu_ir[ra], addr, MMU_KERNEL_IDX, MO_LESL);

                break;

            case 0xB:

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

                tcg_gen_qemu_ld_i64(cpu_ir[ra], addr, MMU_KERNEL_IDX, MO_LEQ);

                break;

            case 0xC:

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

                goto invalid_opc;

            case 0xD:

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

                goto invalid_opc;

            case 0xE:

                /* Longword virtual access with alternate access mode and

                   protection checks (hw_ldl/wa) */

                tcg_gen_qemu_ld_i64(cpu_ir[ra], addr, MMU_USER_IDX, MO_LESL);

                break;

            case 0xF:

                /* Quadword virtual access with alternate access mode and

                   protection checks (hw_ldq/wa) */

                tcg_gen_qemu_ld_i64(cpu_ir[ra], addr, MMU_USER_IDX, MO_LEQ);

                break;

            }

            tcg_temp_free(addr);

            break;

        }

#endif

        goto invalid_opc;

    case 0x1C:

        switch (fn7) {

        case 0x00:

            /* SEXTB */

            if ((ctx->tb->flags & TB_FLAGS_AMASK_BWX) == 0) {

                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->tb->flags & TB_FLAGS_AMASK_BWX) {

                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;

            }

            goto invalid_opc;

        case 0x30:

            /* CTPOP */

            if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {

                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;

            }

            goto invalid_opc;

        case 0x31:

            /* PERR */

            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {

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

                break;

            }

            goto invalid_opc;

        case 0x32:

            /* CTLZ */

            if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {

                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;

            }

            goto invalid_opc;

        case 0x33:

            /* CTTZ */

            if (ctx->tb->flags & TB_FLAGS_AMASK_CIX) {

                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;

            }

            goto invalid_opc;

        case 0x34:

            /* UNPKBW */

            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {

                if (real_islit || ra != 31) {

                    goto invalid_opc;

                }

                gen_unpkbw(rb, rc);

                break;

            }

            goto invalid_opc;

        case 0x35:

            /* UNPKBL */

            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {

                if (real_islit || ra != 31) {

                    goto invalid_opc;

                }

                gen_unpkbl(rb, rc);

                break;

            }

            goto invalid_opc;

        case 0x36:

            /* PKWB */

            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {

                if (real_islit || ra != 31) {

                    goto invalid_opc;

                }

                gen_pkwb(rb, rc);

                break;

            }

            goto invalid_opc;

        case 0x37:

            /* PKLB */

            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {

                if (real_islit || ra != 31) {

                    goto invalid_opc;

                }

                gen_pklb(rb, rc);

                break;

            }

            goto invalid_opc;

        case 0x38:

            /* MINSB8 */

            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {

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

                break;

            }

            goto invalid_opc;

        case 0x39:

            /* MINSW4 */

            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {

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

                break;

            }

            goto invalid_opc;

        case 0x3A:

            /* MINUB8 */

            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {

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

                break;

            }

            goto invalid_opc;

        case 0x3B:

            /* MINUW4 */

            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {

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

                break;

            }

            goto invalid_opc;

        case 0x3C:

            /* MAXUB8 */

            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {

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

                break;

            }

            goto invalid_opc;

        case 0x3D:

            /* MAXUW4 */

            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {

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

                break;

            }

            goto invalid_opc;

        case 0x3E:

            /* MAXSB8 */

            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {

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

                break;

            }

            goto invalid_opc;

        case 0x3F:

            /* MAXSW4 */

            if (ctx->tb->flags & TB_FLAGS_AMASK_MVI) {

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

                break;

            }

            goto invalid_opc;

        case 0x70:

            /* FTOIT */

            if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {

                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->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {

                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) */

#ifndef CONFIG_USER_ONLY

        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {

            return gen_mtpr(ctx, rb, insn & 0xffff);

        }

#endif

        goto invalid_opc;

    case 0x1E:

        /* HW_RET (PALcode) */

#ifndef CONFIG_USER_ONLY

        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {

            if (rb == 31) {

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

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

                   emulation PALcode, so continue to accept it.  */

                TCGv tmp = tcg_temp_new();

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

                gen_helper_hw_ret(cpu_env, tmp);

                tcg_temp_free(tmp);

            } else {

                gen_helper_hw_ret(cpu_env, cpu_ir[rb]);

            }

            ret = EXIT_PC_UPDATED;

            break;

        }

#endif

        goto invalid_opc;

    case 0x1F:

        /* HW_ST (PALcode) */

#ifndef CONFIG_USER_ONLY

        if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {

            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_phys(cpu_env, addr, val);

                break;

            case 0x1:

                /* Quadword physical access */

                gen_helper_stq_phys(cpu_env, addr, val);

                break;

            case 0x2:

                /* Longword physical access with lock */

                gen_helper_stl_c_phys(val, cpu_env, addr, val);

                break;

            case 0x3:

                /* Quadword physical access with lock */

                gen_helper_stq_c_phys(val, cpu_env, addr, val);

                break;

            case 0x4:

                /* Longword virtual access */

                goto invalid_opc;

            case 0x5:

                /* Quadword virtual access */

                goto invalid_opc;

            case 0x6:

                /* Invalid */

                goto invalid_opc;

            case 0x7:

                /* Invalid */

                goto invalid_opc;

            case 0x8:

                /* Invalid */

                goto invalid_opc;

            case 0x9:

                /* Invalid */

                goto invalid_opc;

            case 0xA:

                /* Invalid */

                goto invalid_opc;

            case 0xB:

                /* Invalid */

                goto invalid_opc;

            case 0xC:

                /* Longword virtual access with alternate access mode */

                goto invalid_opc;

            case 0xD:

                /* Quadword virtual access with alternate access mode */

                goto invalid_opc;

            case 0xE:

                /* Invalid */

                goto invalid_opc;

            case 0xF:

                /* Invalid */

                goto invalid_opc;

            }

            if (ra == 31) {

                tcg_temp_free(val);

            }

            tcg_temp_free(addr);

            break;

        }

#endif

        goto invalid_opc;

    case 0x20:

        /* LDF */

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

        break;

    case 0x21:

        /* LDG */

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

        break;

    case 0x22:

        /* LDS */

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

        break;

    case 0x23:

        /* LDT */

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

        break;

    case 0x24:

        /* STF */

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

        break;

    case 0x25:

        /* STG */

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

        break;

    case 0x26:

        /* STS */

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

        break;

    case 0x27:

        /* STT */

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

        break;

    case 0x28:

        /* LDL */

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

        break;

    case 0x29:

        /* LDQ */

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

        break;

    case 0x2A:

        /* LDL_L */

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

        break;

    case 0x2B:

        /* LDQ_L */

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

        break;

    case 0x2C:

        /* STL */

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

        break;

    case 0x2D:

        /* STQ */

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

        break;

    case 0x2E:

        /* STL_C */

        ret = gen_store_conditional(ctx, ra, rb, disp16, 0);

        break;

    case 0x2F:

        /* STQ_C */

        ret = gen_store_conditional(ctx, ra, rb, disp16, 1);

        break;

    case 0x30:

        /* BR */

        ret = gen_bdirect(ctx, ra, disp21);

        break;

    case 0x31: /* FBEQ */

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

        break;

    case 0x32: /* FBLT */

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

        break;

    case 0x33: /* FBLE */

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

        break;

    case 0x34:

        /* BSR */

        ret = gen_bdirect(ctx, ra, disp21);

        break;

    case 0x35: /* FBNE */

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

        break;

    case 0x36: /* FBGE */

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

        break;

    case 0x37: /* FBGT */

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

        break;

    case 0x38:

        /* BLBC */

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

        break;

    case 0x39:

        /* BEQ */

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

        break;

    case 0x3A:

        /* BLT */

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

        break;

    case 0x3B:

        /* BLE */

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

        break;

    case 0x3C:

        /* BLBS */

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

        break;

    case 0x3D:

        /* BNE */

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

        break;

    case 0x3E:

        /* BGE */

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

        break;

    case 0x3F:

        /* BGT */

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

        break;

    invalid_opc:

        ret = gen_invalid(ctx);

        break;

    }

    return ret;

}


inline static void RENAME(hcscale)(SwsContext *c, uint16_t *dst, long dstWidth, const uint8_t *src1, const uint8_t *src2,

                                   int srcW, int xInc, int flags, const int16_t *hChrFilter,

                                   const int16_t *hChrFilterPos, int hChrFilterSize,

                                   int srcFormat, uint8_t *formatConvBuffer,

                                   uint32_t *pal)

{

    int32_t av_unused *mmx2FilterPos = c->chrMmx2FilterPos;

    int16_t av_unused *mmx2Filter    = c->chrMmx2Filter;

    int     av_unused canMMX2BeUsed  = c->canMMX2BeUsed;

    void    av_unused *mmx2FilterCode= c->chrMmx2FilterCode;

    if (isGray(srcFormat) || srcFormat==PIX_FMT_MONOBLACK || srcFormat==PIX_FMT_MONOWHITE)

        return;

    if (srcFormat==PIX_FMT_RGB32_1 || srcFormat==PIX_FMT_BGR32_1) {

        src1 += ALT32_CORR;

        src2 += ALT32_CORR;

    }

    if (srcFormat==PIX_FMT_RGB48LE) {

        src1++;

        src2++;

    }

    if (c->hcscale_internal) {

        c->hcscale_internal(formatConvBuffer, formatConvBuffer+VOFW, src1, src2, srcW, pal);

        src1= formatConvBuffer;

        src2= formatConvBuffer+VOFW;

    }

#if COMPILE_TEMPLATE_MMX

    // Use the new MMX scaler if the MMX2 one can't be used (it is faster than the x86 ASM one).

    if (!(flags&SWS_FAST_BILINEAR) || (!canMMX2BeUsed))

#else

    if (!(flags&SWS_FAST_BILINEAR))

#endif

    {

        c->hScale(dst     , dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);

        c->hScale(dst+VOFW, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);

    } else { // fast bilinear upscale / crap downscale

#if ARCH_X86 && CONFIG_GPL

#if COMPILE_TEMPLATE_MMX2

        int i;

#if defined(PIC)

        DECLARE_ALIGNED(8, uint64_t, ebxsave);

#endif

        if (canMMX2BeUsed) {

            __asm__ volatile(

#if defined(PIC)

                "mov          %%"REG_b", %6         \n\t"

#endif

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

                "mov                 %0, %%"REG_c"  \n\t"

                "mov                 %1, %%"REG_D"  \n\t"

                "mov                 %2, %%"REG_d"  \n\t"

                "mov                 %3, %%"REG_b"  \n\t"

                "xor          %%"REG_a", %%"REG_a"  \n\t" // i

                PREFETCH"   (%%"REG_c")             \n\t"

                PREFETCH" 32(%%"REG_c")             \n\t"

                PREFETCH" 64(%%"REG_c")             \n\t"

                CALL_MMX2_FILTER_CODE

                CALL_MMX2_FILTER_CODE

                CALL_MMX2_FILTER_CODE

                CALL_MMX2_FILTER_CODE

                "xor          %%"REG_a", %%"REG_a"  \n\t" // i

                "mov                 %5, %%"REG_c"  \n\t" // src

                "mov                 %1, %%"REG_D"  \n\t" // buf1

                "add              $"AV_STRINGIFY(VOF)", %%"REG_D"  \n\t"

                PREFETCH"   (%%"REG_c")             \n\t"

                PREFETCH" 32(%%"REG_c")             \n\t"

                PREFETCH" 64(%%"REG_c")             \n\t"

                CALL_MMX2_FILTER_CODE

                CALL_MMX2_FILTER_CODE

                CALL_MMX2_FILTER_CODE

                CALL_MMX2_FILTER_CODE

#if defined(PIC)

                "mov %6, %%"REG_b"    \n\t"

#endif

                :: "m" (src1), "m" (dst), "m" (mmx2Filter), "m" (mmx2FilterPos),

                "m" (mmx2FilterCode), "m" (src2)

#if defined(PIC)

                ,"m" (ebxsave)

#endif

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

#if !defined(PIC)

                ,"%"REG_b

#endif

            );

            for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) {

                //printf("%d %d %d\n", dstWidth, i, srcW);

                dst[i] = src1[srcW-1]*128;

                dst[i+VOFW] = src2[srcW-1]*128;

            }

        } else {

#endif /* COMPILE_TEMPLATE_MMX2 */

            x86_reg xInc_shr16 = (x86_reg) (xInc >> 16);

            uint16_t xInc_mask = xInc & 0xffff;

            __asm__ volatile(

                "xor %%"REG_a", %%"REG_a"               \n\t" // i

                "xor %%"REG_d", %%"REG_d"               \n\t" // xx

                "xorl    %%ecx, %%ecx                   \n\t" // xalpha

                ASMALIGN(4)

                "1:                                     \n\t"

                "mov        %0, %%"REG_S"               \n\t"

                "movzbl  (%%"REG_S", %%"REG_d"), %%edi  \n\t" //src[xx]

                "movzbl 1(%%"REG_S", %%"REG_d"), %%esi  \n\t" //src[xx+1]

                FAST_BILINEAR_X86

                "movw     %%si, (%%"REG_D", %%"REG_a", 2)   \n\t"

                "movzbl    (%5, %%"REG_d"), %%edi       \n\t" //src[xx]

                "movzbl   1(%5, %%"REG_d"), %%esi       \n\t" //src[xx+1]

                FAST_BILINEAR_X86

                "movw     %%si, "AV_STRINGIFY(VOF)"(%%"REG_D", %%"REG_a", 2)   \n\t"

                "addw       %4, %%cx                    \n\t" //xalpha += xInc&0xFFFF

                "adc        %3, %%"REG_d"               \n\t" //xx+= xInc>>16 + carry

                "add        $1, %%"REG_a"               \n\t"

                "cmp        %2, %%"REG_a"               \n\t"

                " jb        1b                          \n\t"

/* GCC 3.3 makes MPlayer crash on IA-32 machines when using "g" operand here,

   which is needed to support GCC 4.0. */

#if ARCH_X86_64 && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))

                :: "m" (src1), "m" (dst), "g" (dstWidth), "m" (xInc_shr16), "m" (xInc_mask),

#else

                :: "m" (src1), "m" (dst), "m" (dstWidth), "m" (xInc_shr16), "m" (xInc_mask),

#endif

                "r" (src2)

                : "%"REG_a, "%"REG_d, "%ecx", "%"REG_D, "%esi"

            );

#if COMPILE_TEMPLATE_MMX2

        } //if MMX2 can't be used

#endif

#else

        c->hcscale_fast(c, dst, dstWidth, src1, src2, srcW, xInc);

#endif /* ARCH_X86 */

    }

    if(c->srcRange != c->dstRange && !(isRGB(c->dstFormat) || isBGR(c->dstFormat))) {

        int i;

        //FIXME all pal and rgb srcFormats could do this convertion as well

        //FIXME all scalers more complex than bilinear could do half of this transform

        if(c->srcRange) {

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

                dst[i     ]= (dst[i     ]*1799 + 4081085)>>11; //1469

                dst[i+VOFW]= (dst[i+VOFW]*1799 + 4081085)>>11; //1469

            }

        } else {

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

                dst[i     ]= (FFMIN(dst[i     ],30775)*4663 - 9289992)>>12; //-264

                dst[i+VOFW]= (FFMIN(dst[i+VOFW],30775)*4663 - 9289992)>>12; //-264

            }

        }

    }

}


float32 HELPER(ucf64_abss)(float32 a)

{

    return float32_abs(a);

}


int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2)

{

   return pthread_equal(thread1->thread, thread2->thread);

}


static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr,

                                                            uint32_t val)

{

    IVShmemState *s = opaque;

    uint64_t write_one = 1;

    uint16_t dest = val >> 16;

    uint16_t vector = val & 0xff;

    addr &= 0xfc;

    IVSHMEM_DPRINTF("writing to addr " TARGET_FMT_plx "\n", addr);

    switch (addr)

    {

        case INTRMASK:

            ivshmem_IntrMask_write(s, val);

            break;

        case INTRSTATUS:

            ivshmem_IntrStatus_write(s, val);

            break;

        case DOORBELL:

            /* check that dest VM ID is reasonable */

            if ((dest < 0) || (dest > s->max_peer)) {

                IVSHMEM_DPRINTF("Invalid destination VM ID (%d)\n", dest);

                break;

            }

            /* check doorbell range */

            if ((vector >= 0) && (vector < s->peers[dest].nb_eventfds)) {

                IVSHMEM_DPRINTF("Writing %" PRId64 " to VM %d on vector %d\n",

                                                    write_one, dest, vector);

                if (write(s->peers[dest].eventfds[vector],

                                                    &(write_one), 8) != 8) {

                    IVSHMEM_DPRINTF("error writing to eventfd\n");

                }

            }

            break;

        default:

            IVSHMEM_DPRINTF("Invalid VM Doorbell VM %d\n", dest);

    }

}


static inline void gen_outs(DisasContext *s, TCGMemOp ot)

{

    if (use_icount)

        gen_io_start();

    gen_string_movl_A0_ESI(s);

    gen_op_ld_v(s, ot, cpu_T[0], cpu_A0);

    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);

    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);

    tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[0]);

    gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);

    gen_op_movl_T0_Dshift(ot);

    gen_op_add_reg_T0(s->aflag, R_ESI);

    if (use_icount)

        gen_io_end();

}


void test_fcmp(double a, double b)

{

    long eflags, fpus;

    fpu_clear_exceptions();

    asm("fcom %2\n"

        "fstsw %%ax\n"

        : "=a" (fpus)

        : "t" (a), "u" (b));

    printf("fcom(%f %f)=%04lx \n",

           a, b, fpus & (0x4500 | FPUS_EMASK));

    fpu_clear_exceptions();

    asm("fucom %2\n"

        "fstsw %%ax\n"

        : "=a" (fpus)

        : "t" (a), "u" (b));

    printf("fucom(%f %f)=%04lx\n",

           a, b, fpus & (0x4500 | FPUS_EMASK));

    if (TEST_FCOMI) {

        /* test f(u)comi instruction */

        fpu_clear_exceptions();

        asm("fcomi %3, %2\n"

            "fstsw %%ax\n"

            "pushf\n"

            "pop %0\n"

            : "=r" (eflags), "=a" (fpus)

            : "t" (a), "u" (b));

        printf("fcomi(%f %f)=%04lx %02lx\n",

               a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));

        fpu_clear_exceptions();

        asm("fucomi %3, %2\n"

            "fstsw %%ax\n"

            "pushf\n"

            "pop %0\n"

            : "=r" (eflags), "=a" (fpus)

            : "t" (a), "u" (b));

        printf("fucomi(%f %f)=%04lx %02lx\n",

               a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C));

    }

    fpu_clear_exceptions();

    asm volatile("fxam\n"

                 "fstsw %%ax\n"

                 : "=a" (fpus)

                 : "t" (a));

    printf("fxam(%f)=%04lx\n", a, fpus & 0x4700);

    fpu_clear_exceptions();

}


void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,

                             hwaddr paddr, MemTxAttrs attrs, int prot,

                             int mmu_idx, target_ulong size)

{

    CPUArchState *env = cpu->env_ptr;

    MemoryRegionSection *section;

    unsigned int index;

    target_ulong address;

    target_ulong code_address;

    uintptr_t addend;

    CPUTLBEntry *te;

    hwaddr iotlb, xlat, sz;

    unsigned vidx = env->vtlb_index++ % CPU_VTLB_SIZE;

    int asidx = cpu_asidx_from_attrs(cpu, attrs);

    assert_cpu_is_self(cpu);

    assert(size >= TARGET_PAGE_SIZE);

    if (size != TARGET_PAGE_SIZE) {

        tlb_add_large_page(env, vaddr, size);

    }

    sz = size;

    section = address_space_translate_for_iotlb(cpu, asidx, paddr, &xlat, &sz);

    assert(sz >= TARGET_PAGE_SIZE);

    tlb_debug("vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx

              " prot=%x idx=%d\n",

              vaddr, paddr, prot, mmu_idx);

    address = vaddr;

    if (!memory_region_is_ram(section->mr) && !memory_region_is_romd(section->mr)) {

        /* IO memory case */

        address |= TLB_MMIO;

        addend = 0;

    } else {

        /* TLB_MMIO for rom/romd handled below */

        addend = (uintptr_t)memory_region_get_ram_ptr(section->mr) + xlat;

    }

    code_address = address;

    iotlb = memory_region_section_get_iotlb(cpu, section, vaddr, paddr, xlat,

                                            prot, &address);

    index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);

    te = &env->tlb_table[mmu_idx][index];

    /* do not discard the translation in te, evict it into a victim tlb */

    env->tlb_v_table[mmu_idx][vidx] = *te;

    env->iotlb_v[mmu_idx][vidx] = env->iotlb[mmu_idx][index];

    /* refill the tlb */

    env->iotlb[mmu_idx][index].addr = iotlb - vaddr;

    env->iotlb[mmu_idx][index].attrs = attrs;

    te->addend = addend - vaddr;

    if (prot & PAGE_READ) {

        te->addr_read = address;

    } else {

        te->addr_read = -1;

    }

    if (prot & PAGE_EXEC) {

        te->addr_code = code_address;

    } else {

        te->addr_code = -1;

    }

    if (prot & PAGE_WRITE) {

        if ((memory_region_is_ram(section->mr) && section->readonly)

            || memory_region_is_romd(section->mr)) {

            /* Write access calls the I/O callback.  */

            te->addr_write = address | TLB_MMIO;

        } else if (memory_region_is_ram(section->mr)

                   && cpu_physical_memory_is_clean(

                        memory_region_get_ram_addr(section->mr) + xlat)) {

            te->addr_write = address | TLB_NOTDIRTY;

        } else {

            te->addr_write = address;

        }

    } else {

        te->addr_write = -1;

    }

}


static int qcrypto_cipher_init_des_rfb(QCryptoCipher *cipher,

                                       const uint8_t *key, size_t nkey,

                                       Error **errp)

{

    QCryptoCipherBuiltin *ctxt;

    if (cipher->mode != QCRYPTO_CIPHER_MODE_ECB) {

        error_setg(errp, "Unsupported cipher mode %d", cipher->mode);

        return -1;

    }

    ctxt = g_new0(QCryptoCipherBuiltin, 1);

    ctxt->state.desrfb.key = g_new0(uint8_t, nkey);

    memcpy(ctxt->state.desrfb.key, key, nkey);

    ctxt->state.desrfb.nkey = nkey;

    ctxt->free = qcrypto_cipher_free_des_rfb;

    ctxt->setiv = qcrypto_cipher_setiv_des_rfb;

    ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb;

    ctxt->decrypt = qcrypto_cipher_decrypt_des_rfb;

    cipher->opaque = ctxt;

    return 0;

}


static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len,

                                    bool is_legacy)

{

    int ret;

    VqInfoBlock info;

    VqInfoBlockLegacy linfo;

    size_t info_len = is_legacy ? sizeof(linfo) : sizeof(info);

    if (check_len) {

        if (ccw.count != info_len) {

            return -EINVAL;

        }

    } else if (ccw.count < info_len) {

        /* Can't execute command. */

        return -EINVAL;

    }

    if (!ccw.cda) {

        return -EFAULT;

    }

    if (is_legacy) {

        linfo.queue = address_space_ldq_be(&address_space_memory, ccw.cda,

                                           MEMTXATTRS_UNSPECIFIED, NULL);

        linfo.align = address_space_ldl_be(&address_space_memory,

                                           ccw.cda + sizeof(linfo.queue),

                                           MEMTXATTRS_UNSPECIFIED,

                                           NULL);

        linfo.index = address_space_lduw_be(&address_space_memory,

                                            ccw.cda + sizeof(linfo.queue)

                                            + sizeof(linfo.align),

                                            MEMTXATTRS_UNSPECIFIED,

                                            NULL);

        linfo.num = address_space_lduw_be(&address_space_memory,

                                          ccw.cda + sizeof(linfo.queue)

                                          + sizeof(linfo.align)

                                          + sizeof(linfo.index),

                                          MEMTXATTRS_UNSPECIFIED,

                                          NULL);

        ret = virtio_ccw_set_vqs(sch, NULL, &linfo);

    } else {

        info.desc = address_space_ldq_be(&address_space_memory, ccw.cda,

                                           MEMTXATTRS_UNSPECIFIED, NULL);

        info.index = address_space_lduw_be(&address_space_memory,

                                           ccw.cda + sizeof(info.desc)

                                           + sizeof(info.res0),

                                           MEMTXATTRS_UNSPECIFIED, NULL);

        info.num = address_space_lduw_be(&address_space_memory,

                                         ccw.cda + sizeof(info.desc)

                                         + sizeof(info.res0)

                                         + sizeof(info.index),

                                         MEMTXATTRS_UNSPECIFIED, NULL);

        info.avail = address_space_ldq_be(&address_space_memory,

                                          ccw.cda + sizeof(info.desc)

                                          + sizeof(info.res0)

                                          + sizeof(info.index)

                                          + sizeof(info.num),

                                          MEMTXATTRS_UNSPECIFIED, NULL);

        info.used = address_space_ldq_be(&address_space_memory,

                                         ccw.cda + sizeof(info.desc)

                                         + sizeof(info.res0)

                                         + sizeof(info.index)

                                         + sizeof(info.num)

                                         + sizeof(info.avail),

                                         MEMTXATTRS_UNSPECIFIED, NULL);

        ret = virtio_ccw_set_vqs(sch, &info, NULL);

    }

    sch->curr_status.scsw.count = 0;

    return ret;

}


static void vnc_client_cache_addr(VncState *client)

{

    Error *err = NULL;

    client->info = g_malloc0(sizeof(*client->info));

    client->info->base = g_malloc0(sizeof(*client->info->base));

    vnc_init_basic_info_from_remote_addr(client->csock, client->info->base,

                                         &err);

    if (err) {

        qapi_free_VncClientInfo(client->info);

        client->info = NULL;

        error_free(err);

    }

}


int kvm_irqchip_add_irqfd(KVMState *s, int fd, int virq)

{

    return kvm_irqchip_assign_irqfd(s, fd, virq, true);

}


static gboolean udp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)

{

    CharDriverState *chr = opaque;

    NetCharDriver *s = chr->opaque;

    gsize bytes_read = 0;

    GIOStatus status;

    if (s->max_size == 0)

        return FALSE;

    status = g_io_channel_read_chars(s->chan, (gchar *)s->buf, sizeof(s->buf),

                                     &bytes_read, NULL);

    s->bufcnt = bytes_read;

    s->bufptr = s->bufcnt;

    if (status != G_IO_STATUS_NORMAL) {

        return FALSE;

    }

    s->bufptr = 0;

    while (s->max_size > 0 && s->bufptr < s->bufcnt) {

        qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);

        s->bufptr++;

        s->max_size = qemu_chr_be_can_write(chr);

    }

    return TRUE;

}


PCIBus *pci_prep_init(qemu_irq *pic)

{

    PREPPCIState *s;

    PCIDevice *d;

    int PPC_io_memory;

    s = qemu_mallocz(sizeof(PREPPCIState));

    s->bus = pci_register_bus(prep_set_irq, prep_map_irq, pic, 0, 2);

    register_ioport_write(0xcf8, 4, 4, pci_prep_addr_writel, s);

    register_ioport_read(0xcf8, 4, 4, pci_prep_addr_readl, s);

    register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s);

    register_ioport_write(0xcfc, 4, 2, pci_host_data_writew, s);

    register_ioport_write(0xcfc, 4, 4, pci_host_data_writel, s);

    register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);

    register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);

    register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);

    PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read,

                                           PPC_PCIIO_write, s);

    cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);

    /* PCI host bridge */

    d = pci_register_device(s->bus, "PREP Host Bridge - Motorola Raven",

                            sizeof(PCIDevice), 0, NULL, NULL);

    d->config[0x00] = 0x57; // vendor_id : Motorola

    d->config[0x01] = 0x10;

    d->config[0x02] = 0x01; // device_id : Raven

    d->config[0x03] = 0x48;

    d->config[0x08] = 0x00; // revision

    d->config[0x0A] = 0x00; // class_sub = pci host

    d->config[0x0B] = 0x06; // class_base = PCI_bridge

    d->config[0x0C] = 0x08; // cache_line_size

    d->config[0x0D] = 0x10; // latency_timer

    d->config[0x0E] = 0x00; // header_type

    d->config[0x34] = 0x00; // capabilities_pointer

    return s->bus;

}


static int raw_init_encoder(AVCodecContext *avctx)

{

    avctx->coded_frame = (AVFrame *)avctx->priv_data;

    avctx->coded_frame->pict_type = FF_I_TYPE;

    avctx->coded_frame->key_frame = 1;

    avctx->codec_tag = findFourCC(avctx->pix_fmt);

    return 0;

}


static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)

{

    v->res_rtm_flag = 1;

    v->level = get_bits(gb, 3);

    if(v->level >= 5)

    {

        av_log(v->s.avctx, AV_LOG_ERROR, "Reserved LEVEL %i\n",v->level);

    }

    v->chromaformat = get_bits(gb, 2);

    if (v->chromaformat != 1)

    {

        av_log(v->s.avctx, AV_LOG_ERROR,

               "Only 4:2:0 chroma format supported\n");

        return -1;

    }

    // (fps-2)/4 (->30)

    v->frmrtq_postproc = get_bits(gb, 3); //common

    // (bitrate-32kbps)/64kbps

    v->bitrtq_postproc = get_bits(gb, 5); //common

    v->postprocflag = get_bits(gb, 1); //common

    v->s.avctx->coded_width = (get_bits(gb, 12) + 1) << 1;

    v->s.avctx->coded_height = (get_bits(gb, 12) + 1) << 1;

    v->broadcast = get_bits1(gb);

    v->interlace = get_bits1(gb);

    if(v->interlace){

        av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced mode not supported (yet)\n");

        return -1;

    }

    v->tfcntrflag = get_bits1(gb);

    v->finterpflag = get_bits1(gb);

    get_bits1(gb); // reserved

    v->psf = get_bits1(gb);

    if(v->psf) { //PsF, 6.1.13

        av_log(v->s.avctx, AV_LOG_ERROR, "Progressive Segmented Frame mode: not supported (yet)\n");

        return -1;

    }

    if(get_bits1(gb)) { //Display Info - decoding is not affected by it

        int w, h, ar = 0;

        av_log(v->s.avctx, AV_LOG_INFO, "Display extended info:\n");

        w = get_bits(gb, 14);

        h = get_bits(gb, 14);

        av_log(v->s.avctx, AV_LOG_INFO, "Display dimensions: %ix%i\n", w, h);

        //TODO: store aspect ratio in AVCodecContext

        if(get_bits1(gb))

            ar = get_bits(gb, 4);

        if(ar == 15) {

            w = get_bits(gb, 8);

            h = get_bits(gb, 8);

        }

        if(get_bits1(gb)){ //framerate stuff

            if(get_bits1(gb)) {

                get_bits(gb, 16);

            } else {

                get_bits(gb, 8);

                get_bits(gb, 4);

            }

        }

        if(get_bits1(gb)){

            v->color_prim = get_bits(gb, 8);

            v->transfer_char = get_bits(gb, 8);

            v->matrix_coef = get_bits(gb, 8);

        }

    }

    v->hrd_param_flag = get_bits1(gb);

    if(v->hrd_param_flag) {

        int i;

        v->hrd_num_leaky_buckets = get_bits(gb, 5);

        get_bits(gb, 4); //bitrate exponent

        get_bits(gb, 4); //buffer size exponent

        for(i = 0; i < v->hrd_num_leaky_buckets; i++) {

            get_bits(gb, 16); //hrd_rate[n]

            get_bits(gb, 16); //hrd_buffer[n]

        }

    }

    return 0;

}


int page_unprotect(target_ulong address, uintptr_t pc, void *puc)

{

    unsigned int prot;

    PageDesc *p;

    target_ulong host_start, host_end, addr;

    /* Technically this isn't safe inside a signal handler.  However we

       know this only ever happens in a synchronous SEGV handler, so in

       practice it seems to be ok.  */

    mmap_lock();

    p = page_find(address >> TARGET_PAGE_BITS);

    if (!p) {

        mmap_unlock();

        return 0;

    }

    /* if the page was really writable, then we change its

       protection back to writable */

    if ((p->flags & PAGE_WRITE_ORG) && !(p->flags & PAGE_WRITE)) {

        host_start = address & qemu_host_page_mask;

        host_end = host_start + qemu_host_page_size;

        prot = 0;

        for (addr = host_start ; addr < host_end ; addr += TARGET_PAGE_SIZE) {

            p = page_find(addr >> TARGET_PAGE_BITS);

            p->flags |= PAGE_WRITE;

            prot |= p->flags;

            /* and since the content will be modified, we must invalidate

               the corresponding translated code. */

            tb_invalidate_phys_page(addr, pc, puc);

#ifdef DEBUG_TB_CHECK

            tb_invalidate_check(addr);

#endif

        }

        mprotect((void *)g2h(host_start), qemu_host_page_size,

                 prot & PAGE_BITS);

        mmap_unlock();

        return 1;

    }

    mmap_unlock();

    return 0;

}


void ff_put_h264_qpel8_mc23_msa(uint8_t *dst, const uint8_t *src,

                                ptrdiff_t stride)

{

    avc_luma_midv_qrt_8w_msa(src - (2 * stride) - 2, stride, dst, stride, 8, 1);

}


static int film_probe(AVProbeData *p)

{

    if (p->buf_size < 4)

        return 0;

    if (AV_RB32(&p->buf[0]) != FILM_TAG)

        return 0;

    return AVPROBE_SCORE_MAX;

}


static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val,

                       unsigned int size, int mem_index)

{

    int l1 = gen_new_label();

    TCGv taddr = tcg_temp_local_new();

    TCGv tval = tcg_temp_local_new();

    TCGv t1 = tcg_temp_local_new();

    dc->postinc = 0;

    cris_evaluate_flags(dc);

    tcg_gen_mov_tl(taddr, addr);

    tcg_gen_mov_tl(tval, val);

    /* Store only if F flag isn't set */

    tcg_gen_andi_tl(t1, cpu_PR[PR_CCS], F_FLAG_V10);

    tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);

    if (size == 1) {

        tcg_gen_qemu_st8(tval, taddr, mem_index);

    } else if (size == 2) {

        tcg_gen_qemu_st16(tval, taddr, mem_index);

    } else {

        tcg_gen_qemu_st32(tval, taddr, mem_index);

    }

    gen_set_label(l1);

    tcg_gen_shri_tl(t1, t1, 1);  /* shift F to P position */

    tcg_gen_or_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], t1); /*P=F*/

    tcg_temp_free(t1);

    tcg_temp_free(tval);

    tcg_temp_free(taddr);

}


static void ide_trim_bh_cb(void *opaque)

{

    TrimAIOCB *iocb = opaque;

    iocb->common.cb(iocb->common.opaque, iocb->ret);

    qemu_bh_delete(iocb->bh);

    iocb->bh = NULL;

    qemu_aio_unref(iocb);

}


static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,

                            abi_long cmd, abi_long arg)

{

    void *argptr;

    struct dm_ioctl *host_dm;

    abi_long guest_data;

    uint32_t guest_data_size;

    int target_size;

    const argtype *arg_type = ie->arg_type;

    abi_long ret;

    void *big_buf = NULL;

    char *host_data;

    arg_type++;

    target_size = thunk_type_size(arg_type, 0);

    argptr = lock_user(VERIFY_READ, arg, target_size, 1);

    if (!argptr) {

        ret = -TARGET_EFAULT;

        goto out;

    }

    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);

    unlock_user(argptr, arg, 0);

    /* buf_temp is too small, so fetch things into a bigger buffer */

    big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);

    memcpy(big_buf, buf_temp, target_size);

    buf_temp = big_buf;

    host_dm = big_buf;

    guest_data = arg + host_dm->data_start;

    if ((guest_data - arg) < 0) {

        ret = -EINVAL;

        goto out;

    }

    guest_data_size = host_dm->data_size - host_dm->data_start;

    host_data = (char*)host_dm + host_dm->data_start;

    argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);

    switch (ie->host_cmd) {

    case DM_REMOVE_ALL:

    case DM_LIST_DEVICES:

    case DM_DEV_CREATE:

    case DM_DEV_REMOVE:

    case DM_DEV_SUSPEND:

    case DM_DEV_STATUS:

    case DM_DEV_WAIT:

    case DM_TABLE_STATUS:

    case DM_TABLE_CLEAR:

    case DM_TABLE_DEPS:

    case DM_LIST_VERSIONS:

        /* no input data */

        break;

    case DM_DEV_RENAME:

    case DM_DEV_SET_GEOMETRY:

        /* data contains only strings */

        memcpy(host_data, argptr, guest_data_size);

        break;

    case DM_TARGET_MSG:

        memcpy(host_data, argptr, guest_data_size);

        *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);

        break;

    case DM_TABLE_LOAD:

    {

        void *gspec = argptr;

        void *cur_data = host_data;

        const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };

        int spec_size = thunk_type_size(arg_type, 0);

        int i;

        for (i = 0; i < host_dm->target_count; i++) {

            struct dm_target_spec *spec = cur_data;

            uint32_t next;

            int slen;

            thunk_convert(spec, gspec, arg_type, THUNK_HOST);

            slen = strlen((char*)gspec + spec_size) + 1;

            next = spec->next;

            spec->next = sizeof(*spec) + slen;

            strcpy((char*)&spec[1], gspec + spec_size);

            gspec += next;

            cur_data += spec->next;

        }

        break;

    }

    default:

        ret = -TARGET_EINVAL;

        goto out;

    }

    unlock_user(argptr, guest_data, 0);

    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));

    if (!is_error(ret)) {

        guest_data = arg + host_dm->data_start;

        guest_data_size = host_dm->data_size - host_dm->data_start;

        argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);

        switch (ie->host_cmd) {

        case DM_REMOVE_ALL:

        case DM_DEV_CREATE:

        case DM_DEV_REMOVE:

        case DM_DEV_RENAME:

        case DM_DEV_SUSPEND:

        case DM_DEV_STATUS:

        case DM_TABLE_LOAD:

        case DM_TABLE_CLEAR:

        case DM_TARGET_MSG:

        case DM_DEV_SET_GEOMETRY:

            /* no return data */

            break;

        case DM_LIST_DEVICES:

        {

            struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;

            uint32_t remaining_data = guest_data_size;

            void *cur_data = argptr;

            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };

            int nl_size = 12; /* can't use thunk_size due to alignment */

            while (1) {

                uint32_t next = nl->next;

                if (next) {

                    nl->next = nl_size + (strlen(nl->name) + 1);

                }

                if (remaining_data < nl->next) {

                    host_dm->flags |= DM_BUFFER_FULL_FLAG;

                    break;

                }

                thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);

                strcpy(cur_data + nl_size, nl->name);

                cur_data += nl->next;

                remaining_data -= nl->next;

                if (!next) {

                    break;

                }

                nl = (void*)nl + next;

            }

            break;

        }

        case DM_DEV_WAIT:

        case DM_TABLE_STATUS:

        {

            struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;

            void *cur_data = argptr;

            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };

            int spec_size = thunk_type_size(arg_type, 0);

            int i;

            for (i = 0; i < host_dm->target_count; i++) {

                uint32_t next = spec->next;

                int slen = strlen((char*)&spec[1]) + 1;

                spec->next = (cur_data - argptr) + spec_size + slen;

                if (guest_data_size < spec->next) {

                    host_dm->flags |= DM_BUFFER_FULL_FLAG;

                    break;

                }

                thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);

                strcpy(cur_data + spec_size, (char*)&spec[1]);

                cur_data = argptr + spec->next;

                spec = (void*)host_dm + host_dm->data_start + next;

            }

            break;

        }

        case DM_TABLE_DEPS:

        {

            void *hdata = (void*)host_dm + host_dm->data_start;

            int count = *(uint32_t*)hdata;

            uint64_t *hdev = hdata + 8;

            uint64_t *gdev = argptr + 8;

            int i;

            *(uint32_t*)argptr = tswap32(count);

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

                *gdev = tswap64(*hdev);

                gdev++;

                hdev++;

            }

            break;

        }

        case DM_LIST_VERSIONS:

        {

            struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;

            uint32_t remaining_data = guest_data_size;

            void *cur_data = argptr;

            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };

            int vers_size = thunk_type_size(arg_type, 0);

            while (1) {

                uint32_t next = vers->next;

                if (next) {

                    vers->next = vers_size + (strlen(vers->name) + 1);

                }

                if (remaining_data < vers->next) {

                    host_dm->flags |= DM_BUFFER_FULL_FLAG;

                    break;

                }

                thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);

                strcpy(cur_data + vers_size, vers->name);

                cur_data += vers->next;

                remaining_data -= vers->next;

                if (!next) {

                    break;

                }

                vers = (void*)vers + next;

            }

            break;

        }

        default:

            ret = -TARGET_EINVAL;

            goto out;

        }

        unlock_user(argptr, guest_data, guest_data_size);

        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);

        if (!argptr) {

            ret = -TARGET_EFAULT;

            goto out;

        }

        thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);

        unlock_user(argptr, arg, target_size);

    }

out:

    if (big_buf) {

        free(big_buf);

    }

    return ret;

}


static int dxva2_retrieve_data(AVCodecContext *s, AVFrame *frame)

{

    InputStream        *ist = s->opaque;

    DXVA2Context       *ctx = ist->hwaccel_ctx;

    int                ret;

    ret = av_hwframe_transfer_data(ctx->tmp_frame, frame, 0);

    if (ret < 0)

        return ret;

    ret = av_frame_copy_props(ctx->tmp_frame, frame);

    if (ret < 0) {

        av_frame_unref(ctx->tmp_frame);

        return ret;

    }

    av_frame_unref(frame);

    av_frame_move_ref(frame, ctx->tmp_frame);

    return 0;

}


void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,

                    uint8_t *segment, uint8_t *ref, int layout)

{

    VP56RangeCoder *c = &s->c;

    if (s->segmentation.update_map)

        *segment = vp8_rac_get_tree(c, vp8_segmentid_tree, s->prob->segmentid);

    else if (s->segmentation.enabled)

        *segment = ref ? *ref : *segment;

    mb->segment = *segment;

    mb->skip = s->mbskip_enabled ? vp56_rac_get_prob(c, s->prob->mbskip) : 0;

    if (s->keyframe) {

        mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_intra,

                                    vp8_pred16x16_prob_intra);

        if (mb->mode == MODE_I4x4) {

            decode_intra4x4_modes(s, c, mb, mb_x, 1, layout);

        } else {

            const uint32_t modes = vp8_pred4x4_mode[mb->mode] * 0x01010101u;

            if (s->mb_layout == 1)

                AV_WN32A(mb->intra4x4_pred_mode_top, modes);

            else

                AV_WN32A(s->intra4x4_pred_mode_top + 4 * mb_x, modes);

            AV_WN32A(s->intra4x4_pred_mode_left, modes);

        }

        mb->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree,

                                                vp8_pred8x8c_prob_intra);

        mb->ref_frame        = VP56_FRAME_CURRENT;

    } else if (vp56_rac_get_prob_branchy(c, s->prob->intra)) {

        // inter MB, 16.2

        if (vp56_rac_get_prob_branchy(c, s->prob->last))

            mb->ref_frame =

                vp56_rac_get_prob(c, s->prob->golden) ? VP56_FRAME_GOLDEN2 /* altref */

                                                      : VP56_FRAME_GOLDEN;

        else

            mb->ref_frame = VP56_FRAME_PREVIOUS;

        s->ref_count[mb->ref_frame - 1]++;

        // motion vectors, 16.3

        decode_mvs(s, mb, mb_x, mb_y, layout);

    } else {

        // intra MB, 16.1

        mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_inter, s->prob->pred16x16);

        if (mb->mode == MODE_I4x4)

            decode_intra4x4_modes(s, c, mb, mb_x, 0, layout);

        mb->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree,

                                                s->prob->pred8x8c);

        mb->ref_frame        = VP56_FRAME_CURRENT;

        mb->partitioning     = VP8_SPLITMVMODE_NONE;

        AV_ZERO32(&mb->bmv[0]);

    }

}


static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)

{

    uint32_t op;

    /* make sure instructions are on a halfword boundary */

    if (ctx->pc & 0x1) {

        env->CP0_BadVAddr = ctx->pc;

        generate_exception(ctx, EXCP_AdEL);

        ctx->bstate = BS_STOP;

        return 2;

    }

    op = (ctx->opcode >> 10) & 0x3f;

    /* Enforce properly-sized instructions in a delay slot */

    if (ctx->hflags & MIPS_HFLAG_BMASK) {

        int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;

        switch (op) {

        case POOL32A:

        case POOL32B:

        case POOL32I:

        case POOL32C:

        case ADDI32:

        case ADDIU32:

        case ORI32:

        case XORI32:

        case SLTI32:

        case SLTIU32:

        case ANDI32:

        case JALX32:

        case LBU32:

        case LHU32:

        case POOL32F:

        case JALS32:

        case BEQ32:

        case BNE32:

        case J32:

        case JAL32:

        case SB32:

        case SH32:

        case POOL32S:

        case ADDIUPC:

        case SWC132:

        case SDC132:

        case SD32:

        case SW32:

        case LB32:

        case LH32:

        case DADDIU32:

        case LWC132:

        case LDC132:

        case LD32:

        case LW32:

            if (bits & MIPS_HFLAG_BDS16) {

                generate_exception(ctx, EXCP_RI);

                /* Just stop translation; the user is confused.  */

                ctx->bstate = BS_STOP;

                return 2;

            }

            break;

        case POOL16A:

        case POOL16B:

        case POOL16C:

        case LWGP16:

        case POOL16F:

        case LBU16:

        case LHU16:

        case LWSP16:

        case LW16:

        case SB16:

        case SH16:

        case SWSP16:

        case SW16:

        case MOVE16:

        case ANDI16:

        case POOL16D:

        case POOL16E:

        case BEQZ16:

        case BNEZ16:

        case B16:

        case LI16:

            if (bits & MIPS_HFLAG_BDS32) {

                generate_exception(ctx, EXCP_RI);

                /* Just stop translation; the user is confused.  */

                ctx->bstate = BS_STOP;

                return 2;

            }

            break;

        default:

            break;

        }

    }

    switch (op) {

    case POOL16A:

        {

            int rd = mmreg(uMIPS_RD(ctx->opcode));

            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));

            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));

            uint32_t opc = 0;

            switch (ctx->opcode & 0x1) {

            case ADDU16:

                opc = OPC_ADDU;

                break;

            case SUBU16:

                opc = OPC_SUBU;

                break;

            }

            gen_arith(ctx, opc, rd, rs1, rs2);

        }

        break;

    case POOL16B:

        {

            int rd = mmreg(uMIPS_RD(ctx->opcode));

            int rs = mmreg(uMIPS_RS(ctx->opcode));

            int amount = (ctx->opcode >> 1) & 0x7;

            uint32_t opc = 0;

            amount = amount == 0 ? 8 : amount;

            switch (ctx->opcode & 0x1) {

            case SLL16:

                opc = OPC_SLL;

                break;

            case SRL16:

                opc = OPC_SRL;

                break;

            }

            gen_shift_imm(ctx, opc, rd, rs, amount);

        }

        break;

    case POOL16C:

        gen_pool16c_insn(ctx, is_branch);

        break;

    case LWGP16:

        {

            int rd = mmreg(uMIPS_RD(ctx->opcode));

            int rb = 28;            /* GP */

            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;

            gen_ld(ctx, OPC_LW, rd, rb, offset);

        }

        break;

    case POOL16F:

        if (ctx->opcode & 1) {

            generate_exception(ctx, EXCP_RI);

        } else {

            /* MOVEP */

            int enc_dest = uMIPS_RD(ctx->opcode);

            int enc_rt = uMIPS_RS2(ctx->opcode);

            int enc_rs = uMIPS_RS1(ctx->opcode);

            int rd, rs, re, rt;

            static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };

            static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };

            static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };

            rd = rd_enc[enc_dest];

            re = re_enc[enc_dest];

            rs = rs_rt_enc[enc_rs];

            rt = rs_rt_enc[enc_rt];

            gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);

            gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);

        }

        break;

    case LBU16:

        {

            int rd = mmreg(uMIPS_RD(ctx->opcode));

            int rb = mmreg(uMIPS_RS(ctx->opcode));

            int16_t offset = ZIMM(ctx->opcode, 0, 4);

            offset = (offset == 0xf ? -1 : offset);

            gen_ld(ctx, OPC_LBU, rd, rb, offset);

        }

        break;

    case LHU16:

        {

            int rd = mmreg(uMIPS_RD(ctx->opcode));

            int rb = mmreg(uMIPS_RS(ctx->opcode));

            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;

            gen_ld(ctx, OPC_LHU, rd, rb, offset);

        }

        break;

    case LWSP16:

        {

            int rd = (ctx->opcode >> 5) & 0x1f;

            int rb = 29;            /* SP */

            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;

            gen_ld(ctx, OPC_LW, rd, rb, offset);

        }

        break;

    case LW16:

        {

            int rd = mmreg(uMIPS_RD(ctx->opcode));

            int rb = mmreg(uMIPS_RS(ctx->opcode));

            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;

            gen_ld(ctx, OPC_LW, rd, rb, offset);

        }

        break;

    case SB16:

        {

            int rd = mmreg2(uMIPS_RD(ctx->opcode));

            int rb = mmreg(uMIPS_RS(ctx->opcode));

            int16_t offset = ZIMM(ctx->opcode, 0, 4);

            gen_st(ctx, OPC_SB, rd, rb, offset);

        }

        break;

    case SH16:

        {

            int rd = mmreg2(uMIPS_RD(ctx->opcode));

            int rb = mmreg(uMIPS_RS(ctx->opcode));

            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;

            gen_st(ctx, OPC_SH, rd, rb, offset);

        }

        break;

    case SWSP16:

        {

            int rd = (ctx->opcode >> 5) & 0x1f;

            int rb = 29;            /* SP */

            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;

            gen_st(ctx, OPC_SW, rd, rb, offset);

        }

        break;

    case SW16:

        {

            int rd = mmreg2(uMIPS_RD(ctx->opcode));

            int rb = mmreg(uMIPS_RS(ctx->opcode));

            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;

            gen_st(ctx, OPC_SW, rd, rb, offset);

        }

        break;

    case MOVE16:

        {

            int rd = uMIPS_RD5(ctx->opcode);

            int rs = uMIPS_RS5(ctx->opcode);

            gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);

        }

        break;

    case ANDI16:

        gen_andi16(ctx);

        break;

    case POOL16D:

        switch (ctx->opcode & 0x1) {

        case ADDIUS5:

            gen_addius5(ctx);

            break;

        case ADDIUSP:

            gen_addiusp(ctx);

            break;

        }

        break;

    case POOL16E:

        switch (ctx->opcode & 0x1) {

        case ADDIUR2:

            gen_addiur2(ctx);

            break;

        case ADDIUR1SP:

            gen_addiur1sp(ctx);

            break;

        }

        break;

    case B16:

        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,

                           SIMM(ctx->opcode, 0, 10) << 1);

        *is_branch = 1;

        break;

    case BNEZ16:

    case BEQZ16:

        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,

                           mmreg(uMIPS_RD(ctx->opcode)),

                           0, SIMM(ctx->opcode, 0, 7) << 1);

        *is_branch = 1;

        break;

    case LI16:

        {

            int reg = mmreg(uMIPS_RD(ctx->opcode));

            int imm = ZIMM(ctx->opcode, 0, 7);

            imm = (imm == 0x7f ? -1 : imm);

            tcg_gen_movi_tl(cpu_gpr[reg], imm);

        }

        break;

    case RES_20:

    case RES_28:

    case RES_29:

    case RES_30:

    case RES_31:

    case RES_38:

    case RES_39:

        generate_exception(ctx, EXCP_RI);

        break;

    default:

        decode_micromips32_opc (env, ctx, op, is_branch);

        return 4;

    }

    return 2;

}