static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)

{

#define HAS_OPTION_BITS(opt) do { \

        if (!option_bits_enabled(dc, opt)) { \

            qemu_log("Option is not enabled %s:%d\n", \

                    __FILE__, __LINE__); \

            goto invalid_opcode; \

        } \

    } while (0)

#define HAS_OPTION(opt) HAS_OPTION_BITS(XTENSA_OPTION_BIT(opt))

#define TBD() qemu_log("TBD(pc = %08x): %s:%d\n", dc->pc, __FILE__, __LINE__)

#define RESERVED() do { \

        qemu_log("RESERVED(pc = %08x, %02x%02x%02x): %s:%d\n", \

                dc->pc, b0, b1, b2, __FILE__, __LINE__); \

        goto invalid_opcode; \

    } while (0)

#ifdef TARGET_WORDS_BIGENDIAN

#define OP0 (((b0) & 0xf0) >> 4)

#define OP1 (((b2) & 0xf0) >> 4)

#define OP2 ((b2) & 0xf)

#define RRR_R ((b1) & 0xf)

#define RRR_S (((b1) & 0xf0) >> 4)

#define RRR_T ((b0) & 0xf)

#else

#define OP0 (((b0) & 0xf))

#define OP1 (((b2) & 0xf))

#define OP2 (((b2) & 0xf0) >> 4)

#define RRR_R (((b1) & 0xf0) >> 4)

#define RRR_S (((b1) & 0xf))

#define RRR_T (((b0) & 0xf0) >> 4)

#endif

#define RRR_X ((RRR_R & 0x4) >> 2)

#define RRR_Y ((RRR_T & 0x4) >> 2)

#define RRR_W (RRR_R & 0x3)

#define RRRN_R RRR_R

#define RRRN_S RRR_S

#define RRRN_T RRR_T

#define RRI8_R RRR_R

#define RRI8_S RRR_S

#define RRI8_T RRR_T

#define RRI8_IMM8 (b2)

#define RRI8_IMM8_SE ((((b2) & 0x80) ? 0xffffff00 : 0) | RRI8_IMM8)

#ifdef TARGET_WORDS_BIGENDIAN

#define RI16_IMM16 (((b1) << 8) | (b2))

#else

#define RI16_IMM16 (((b2) << 8) | (b1))

#endif

#ifdef TARGET_WORDS_BIGENDIAN

#define CALL_N (((b0) & 0xc) >> 2)

#define CALL_OFFSET ((((b0) & 0x3) << 16) | ((b1) << 8) | (b2))

#else

#define CALL_N (((b0) & 0x30) >> 4)

#define CALL_OFFSET ((((b0) & 0xc0) >> 6) | ((b1) << 2) | ((b2) << 10))

#endif

#define CALL_OFFSET_SE \

    (((CALL_OFFSET & 0x20000) ? 0xfffc0000 : 0) | CALL_OFFSET)

#define CALLX_N CALL_N

#ifdef TARGET_WORDS_BIGENDIAN

#define CALLX_M ((b0) & 0x3)

#else

#define CALLX_M (((b0) & 0xc0) >> 6)

#endif

#define CALLX_S RRR_S

#define BRI12_M CALLX_M

#define BRI12_S RRR_S

#ifdef TARGET_WORDS_BIGENDIAN

#define BRI12_IMM12 ((((b1) & 0xf) << 8) | (b2))

#else

#define BRI12_IMM12 ((((b1) & 0xf0) >> 4) | ((b2) << 4))

#endif

#define BRI12_IMM12_SE (((BRI12_IMM12 & 0x800) ? 0xfffff000 : 0) | BRI12_IMM12)

#define BRI8_M BRI12_M

#define BRI8_R RRI8_R

#define BRI8_S RRI8_S

#define BRI8_IMM8 RRI8_IMM8

#define BRI8_IMM8_SE RRI8_IMM8_SE

#define RSR_SR (b1)

    uint8_t b0 = cpu_ldub_code(env, dc->pc);

    uint8_t b1 = cpu_ldub_code(env, dc->pc + 1);

    uint8_t b2 = 0;

    static const uint32_t B4CONST[] = {

        0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256

    };

    static const uint32_t B4CONSTU[] = {

        32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256

    };

    if (OP0 >= 8) {

        dc->next_pc = dc->pc + 2;

        HAS_OPTION(XTENSA_OPTION_CODE_DENSITY);

    } else {

        dc->next_pc = dc->pc + 3;

        b2 = cpu_ldub_code(env, dc->pc + 2);

    }

    switch (OP0) {

    case 0: /*QRST*/

        switch (OP1) {

        case 0: /*RST0*/

            switch (OP2) {

            case 0: /*ST0*/

                if ((RRR_R & 0xc) == 0x8) {

                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);

                }

                switch (RRR_R) {

                case 0: /*SNM0*/

                    switch (CALLX_M) {

                    case 0: /*ILL*/

                        gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);

                        break;

                    case 1: /*reserved*/

                        RESERVED();

                        break;

                    case 2: /*JR*/

                        switch (CALLX_N) {

                        case 0: /*RET*/

                        case 2: /*JX*/

                            gen_window_check1(dc, CALLX_S);

                            gen_jump(dc, cpu_R[CALLX_S]);

                            break;

                        case 1: /*RETWw*/

                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                            {

                                TCGv_i32 tmp = tcg_const_i32(dc->pc);

                                gen_advance_ccount(dc);

                                gen_helper_retw(tmp, cpu_env, tmp);

                                gen_jump(dc, tmp);

                                tcg_temp_free(tmp);

                            }

                            break;

                        case 3: /*reserved*/

                            RESERVED();

                            break;

                        }

                        break;

                    case 3: /*CALLX*/

                        gen_window_check2(dc, CALLX_S, CALLX_N << 2);

                        switch (CALLX_N) {

                        case 0: /*CALLX0*/

                            {

                                TCGv_i32 tmp = tcg_temp_new_i32();

                                tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);

                                tcg_gen_movi_i32(cpu_R[0], dc->next_pc);

                                gen_jump(dc, tmp);

                                tcg_temp_free(tmp);

                            }

                            break;

                        case 1: /*CALLX4w*/

                        case 2: /*CALLX8w*/

                        case 3: /*CALLX12w*/

                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                            {

                                TCGv_i32 tmp = tcg_temp_new_i32();

                                tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);

                                gen_callw(dc, CALLX_N, tmp);

                                tcg_temp_free(tmp);

                            }

                            break;

                        }

                        break;

                    }

                    break;

                case 1: /*MOVSPw*/

                    HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                    gen_window_check2(dc, RRR_T, RRR_S);

                    {

                        TCGv_i32 pc = tcg_const_i32(dc->pc);

                        gen_advance_ccount(dc);

                        gen_helper_movsp(cpu_env, pc);

                        tcg_gen_mov_i32(cpu_R[RRR_T], cpu_R[RRR_S]);

                        tcg_temp_free(pc);

                    }

                    break;

                case 2: /*SYNC*/

                    switch (RRR_T) {

                    case 0: /*ISYNC*/

                        break;

                    case 1: /*RSYNC*/

                        break;

                    case 2: /*ESYNC*/

                        break;

                    case 3: /*DSYNC*/

                        break;

                    case 8: /*EXCW*/

                        HAS_OPTION(XTENSA_OPTION_EXCEPTION);

                        break;

                    case 12: /*MEMW*/

                        break;

                    case 13: /*EXTW*/

                        break;

                    case 15: /*NOP*/

                        break;

                    default: /*reserved*/

                        RESERVED();

                        break;

                    }

                    break;

                case 3: /*RFEIx*/

                    switch (RRR_T) {

                    case 0: /*RFETx*/

                        HAS_OPTION(XTENSA_OPTION_EXCEPTION);

                        switch (RRR_S) {

                        case 0: /*RFEx*/

                            gen_check_privilege(dc);

                            tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);

                            gen_helper_check_interrupts(cpu_env);

                            gen_jump(dc, cpu_SR[EPC1]);

                            break;

                        case 1: /*RFUEx*/

                            RESERVED();

                            break;

                        case 2: /*RFDEx*/

                            gen_check_privilege(dc);

                            gen_jump(dc, cpu_SR[

                                    dc->config->ndepc ? DEPC : EPC1]);

                            break;

                        case 4: /*RFWOw*/

                        case 5: /*RFWUw*/

                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                            gen_check_privilege(dc);

                            {

                                TCGv_i32 tmp = tcg_const_i32(1);

                                tcg_gen_andi_i32(

                                        cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);

                                tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);

                                if (RRR_S == 4) {

                                    tcg_gen_andc_i32(cpu_SR[WINDOW_START],

                                            cpu_SR[WINDOW_START], tmp);

                                } else {

                                    tcg_gen_or_i32(cpu_SR[WINDOW_START],

                                            cpu_SR[WINDOW_START], tmp);

                                }

                                gen_helper_restore_owb(cpu_env);

                                gen_helper_check_interrupts(cpu_env);

                                gen_jump(dc, cpu_SR[EPC1]);

                                tcg_temp_free(tmp);

                            }

                            break;

                        default: /*reserved*/

                            RESERVED();

                            break;

                        }

                        break;

                    case 1: /*RFIx*/

                        HAS_OPTION(XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT);

                        if (RRR_S >= 2 && RRR_S <= dc->config->nlevel) {

                            gen_check_privilege(dc);

                            tcg_gen_mov_i32(cpu_SR[PS],

                                    cpu_SR[EPS2 + RRR_S - 2]);

                            gen_helper_check_interrupts(cpu_env);

                            gen_jump(dc, cpu_SR[EPC1 + RRR_S - 1]);

                        } else {

                            qemu_log("RFI %d is illegal\n", RRR_S);

                            gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);

                        }

                        break;

                    case 2: /*RFME*/

                        TBD();

                        break;

                    default: /*reserved*/

                        RESERVED();

                        break;

                    }

                    break;

                case 4: /*BREAKx*/

                    HAS_OPTION(XTENSA_OPTION_DEBUG);

                    if (dc->debug) {

                        gen_debug_exception(dc, DEBUGCAUSE_BI);

                    }

                    break;

                case 5: /*SYSCALLx*/

                    HAS_OPTION(XTENSA_OPTION_EXCEPTION);

                    switch (RRR_S) {

                    case 0: /*SYSCALLx*/

                        gen_exception_cause(dc, SYSCALL_CAUSE);

                        break;

                    case 1: /*SIMCALL*/

                        if (semihosting_enabled) {

                            gen_check_privilege(dc);

                            gen_helper_simcall(cpu_env);

                        } else {

                            qemu_log("SIMCALL but semihosting is disabled\n");

                            gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);

                        }

                        break;

                    default:

                        RESERVED();

                        break;

                    }

                    break;

                case 6: /*RSILx*/

                    HAS_OPTION(XTENSA_OPTION_INTERRUPT);

                    gen_check_privilege(dc);

                    gen_window_check1(dc, RRR_T);

                    tcg_gen_mov_i32(cpu_R[RRR_T], cpu_SR[PS]);

                    tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL);

                    tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], RRR_S);

                    gen_helper_check_interrupts(cpu_env);

                    gen_jumpi_check_loop_end(dc, 0);

                    break;

                case 7: /*WAITIx*/

                    HAS_OPTION(XTENSA_OPTION_INTERRUPT);

                    gen_check_privilege(dc);

                    gen_waiti(dc, RRR_S);

                    break;

                case 8: /*ANY4p*/

                case 9: /*ALL4p*/

                case 10: /*ANY8p*/

                case 11: /*ALL8p*/

                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);

                    {

                        const unsigned shift = (RRR_R & 2) ? 8 : 4;

                        TCGv_i32 mask = tcg_const_i32(

                                ((1 << shift) - 1) << RRR_S);

                        TCGv_i32 tmp = tcg_temp_new_i32();

                        tcg_gen_and_i32(tmp, cpu_SR[BR], mask);

                        if (RRR_R & 1) { /*ALL*/

                            tcg_gen_addi_i32(tmp, tmp, 1 << RRR_S);

                        } else { /*ANY*/

                            tcg_gen_add_i32(tmp, tmp, mask);

                        }

                        tcg_gen_shri_i32(tmp, tmp, RRR_S + shift);

                        tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR],

                                tmp, RRR_T, 1);

                        tcg_temp_free(mask);

                        tcg_temp_free(tmp);

                    }

                    break;

                default: /*reserved*/

                    RESERVED();

                    break;

                }

                break;

            case 1: /*AND*/

                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);

                tcg_gen_and_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);

                break;

            case 2: /*OR*/

                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);

                tcg_gen_or_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);

                break;

            case 3: /*XOR*/

                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);

                tcg_gen_xor_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);

                break;

            case 4: /*ST1*/

                switch (RRR_R) {

                case 0: /*SSR*/

                    gen_window_check1(dc, RRR_S);

                    gen_right_shift_sar(dc, cpu_R[RRR_S]);

                    break;

                case 1: /*SSL*/

                    gen_window_check1(dc, RRR_S);

                    gen_left_shift_sar(dc, cpu_R[RRR_S]);

                    break;

                case 2: /*SSA8L*/

                    gen_window_check1(dc, RRR_S);

                    {

                        TCGv_i32 tmp = tcg_temp_new_i32();

                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);

                        gen_right_shift_sar(dc, tmp);

                        tcg_temp_free(tmp);

                    }

                    break;

                case 3: /*SSA8B*/

                    gen_window_check1(dc, RRR_S);

                    {

                        TCGv_i32 tmp = tcg_temp_new_i32();

                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);

                        gen_left_shift_sar(dc, tmp);

                        tcg_temp_free(tmp);

                    }

                    break;

                case 4: /*SSAI*/

                    {

                        TCGv_i32 tmp = tcg_const_i32(

                                RRR_S | ((RRR_T & 1) << 4));

                        gen_right_shift_sar(dc, tmp);

                        tcg_temp_free(tmp);

                    }

                    break;

                case 6: /*RER*/

                    TBD();

                    break;

                case 7: /*WER*/

                    TBD();

                    break;

                case 8: /*ROTWw*/

                    HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                    gen_check_privilege(dc);

                    {

                        TCGv_i32 tmp = tcg_const_i32(

                                RRR_T | ((RRR_T & 8) ? 0xfffffff0 : 0));

                        gen_helper_rotw(cpu_env, tmp);

                        tcg_temp_free(tmp);

                        reset_used_window(dc);

                    }

                    break;

                case 14: /*NSAu*/

                    HAS_OPTION(XTENSA_OPTION_MISC_OP_NSA);

                    gen_window_check2(dc, RRR_S, RRR_T);

                    gen_helper_nsa(cpu_R[RRR_T], cpu_R[RRR_S]);

                    break;

                case 15: /*NSAUu*/

                    HAS_OPTION(XTENSA_OPTION_MISC_OP_NSA);

                    gen_window_check2(dc, RRR_S, RRR_T);

                    gen_helper_nsau(cpu_R[RRR_T], cpu_R[RRR_S]);

                    break;

                default: /*reserved*/

                    RESERVED();

                    break;

                }

                break;

            case 5: /*TLB*/

                HAS_OPTION_BITS(

                        XTENSA_OPTION_BIT(XTENSA_OPTION_MMU) |

                        XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |

                        XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION));

                gen_check_privilege(dc);

                gen_window_check2(dc, RRR_S, RRR_T);

                {

                    TCGv_i32 dtlb = tcg_const_i32((RRR_R & 8) != 0);

                    switch (RRR_R & 7) {

                    case 3: /*RITLB0*/ /*RDTLB0*/

                        gen_helper_rtlb0(cpu_R[RRR_T],

                                cpu_env, cpu_R[RRR_S], dtlb);

                        break;

                    case 4: /*IITLB*/ /*IDTLB*/

                        gen_helper_itlb(cpu_env, cpu_R[RRR_S], dtlb);

                        /* This could change memory mapping, so exit tb */

                        gen_jumpi_check_loop_end(dc, -1);

                        break;

                    case 5: /*PITLB*/ /*PDTLB*/

                        tcg_gen_movi_i32(cpu_pc, dc->pc);

                        gen_helper_ptlb(cpu_R[RRR_T],

                                cpu_env, cpu_R[RRR_S], dtlb);

                        break;

                    case 6: /*WITLB*/ /*WDTLB*/

                        gen_helper_wtlb(

                                cpu_env, cpu_R[RRR_T], cpu_R[RRR_S], dtlb);

                        /* This could change memory mapping, so exit tb */

                        gen_jumpi_check_loop_end(dc, -1);

                        break;

                    case 7: /*RITLB1*/ /*RDTLB1*/

                        gen_helper_rtlb1(cpu_R[RRR_T],

                                cpu_env, cpu_R[RRR_S], dtlb);

                        break;

                    default:

                        tcg_temp_free(dtlb);

                        RESERVED();

                        break;

                    }

                    tcg_temp_free(dtlb);

                }

                break;

            case 6: /*RT0*/

                gen_window_check2(dc, RRR_R, RRR_T);

                switch (RRR_S) {

                case 0: /*NEG*/

                    tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);

                    break;

                case 1: /*ABS*/

                    {

                        int label = gen_new_label();

                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);

                        tcg_gen_brcondi_i32(

                                TCG_COND_GE, cpu_R[RRR_R], 0, label);

                        tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);

                        gen_set_label(label);

                    }

                    break;

                default: /*reserved*/

                    RESERVED();

                    break;

                }

                break;

            case 7: /*reserved*/

                RESERVED();

                break;

            case 8: /*ADD*/

                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);

                tcg_gen_add_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);

                break;

            case 9: /*ADD**/

            case 10:

            case 11:

                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);

                {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 8);

                    tcg_gen_add_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);

                    tcg_temp_free(tmp);

                }

                break;

            case 12: /*SUB*/

                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);

                tcg_gen_sub_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);

                break;

            case 13: /*SUB**/

            case 14:

            case 15:

                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);

                {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 12);

                    tcg_gen_sub_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);

                    tcg_temp_free(tmp);

                }

                break;

            }

            break;

        case 1: /*RST1*/

            switch (OP2) {

            case 0: /*SLLI*/

            case 1:

                gen_window_check2(dc, RRR_R, RRR_S);

                tcg_gen_shli_i32(cpu_R[RRR_R], cpu_R[RRR_S],

                        32 - (RRR_T | ((OP2 & 1) << 4)));

                break;

            case 2: /*SRAI*/

            case 3:

                gen_window_check2(dc, RRR_R, RRR_T);

                tcg_gen_sari_i32(cpu_R[RRR_R], cpu_R[RRR_T],

                        RRR_S | ((OP2 & 1) << 4));

                break;

            case 4: /*SRLI*/

                gen_window_check2(dc, RRR_R, RRR_T);

                tcg_gen_shri_i32(cpu_R[RRR_R], cpu_R[RRR_T], RRR_S);

                break;

            case 6: /*XSR*/

                {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    if (RSR_SR >= 64) {

                        gen_check_privilege(dc);

                    }

                    gen_window_check1(dc, RRR_T);

                    tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);

                    gen_rsr(dc, cpu_R[RRR_T], RSR_SR);

                    gen_wsr(dc, RSR_SR, tmp);

                    tcg_temp_free(tmp);

                    if (!sregnames[RSR_SR]) {

                        TBD();

                    }

                }

                break;

                /*

                 * Note: 64 bit ops are used here solely because SAR values

                 * have range 0..63

                 */

#define gen_shift_reg(cmd, reg) do { \

                    TCGv_i64 tmp = tcg_temp_new_i64(); \

                    tcg_gen_extu_i32_i64(tmp, reg); \

                    tcg_gen_##cmd##_i64(v, v, tmp); \

                    tcg_gen_trunc_i64_i32(cpu_R[RRR_R], v); \

                    tcg_temp_free_i64(v); \

                    tcg_temp_free_i64(tmp); \

                } while (0)

#define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])

            case 8: /*SRC*/

                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);

                {

                    TCGv_i64 v = tcg_temp_new_i64();

                    tcg_gen_concat_i32_i64(v, cpu_R[RRR_T], cpu_R[RRR_S]);

                    gen_shift(shr);

                }

                break;

            case 9: /*SRL*/

                gen_window_check2(dc, RRR_R, RRR_T);

                if (dc->sar_5bit) {

                    tcg_gen_shr_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);

                } else {

                    TCGv_i64 v = tcg_temp_new_i64();

                    tcg_gen_extu_i32_i64(v, cpu_R[RRR_T]);

                    gen_shift(shr);

                }

                break;

            case 10: /*SLL*/

                gen_window_check2(dc, RRR_R, RRR_S);

                if (dc->sar_m32_5bit) {

                    tcg_gen_shl_i32(cpu_R[RRR_R], cpu_R[RRR_S], dc->sar_m32);

                } else {

                    TCGv_i64 v = tcg_temp_new_i64();

                    TCGv_i32 s = tcg_const_i32(32);

                    tcg_gen_sub_i32(s, s, cpu_SR[SAR]);

                    tcg_gen_andi_i32(s, s, 0x3f);

                    tcg_gen_extu_i32_i64(v, cpu_R[RRR_S]);

                    gen_shift_reg(shl, s);

                    tcg_temp_free(s);

                }

                break;

            case 11: /*SRA*/

                gen_window_check2(dc, RRR_R, RRR_T);

                if (dc->sar_5bit) {

                    tcg_gen_sar_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);

                } else {

                    TCGv_i64 v = tcg_temp_new_i64();

                    tcg_gen_ext_i32_i64(v, cpu_R[RRR_T]);

                    gen_shift(sar);

                }

                break;

#undef gen_shift

#undef gen_shift_reg

            case 12: /*MUL16U*/

                HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);

                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);

                {

                    TCGv_i32 v1 = tcg_temp_new_i32();

                    TCGv_i32 v2 = tcg_temp_new_i32();

                    tcg_gen_ext16u_i32(v1, cpu_R[RRR_S]);

                    tcg_gen_ext16u_i32(v2, cpu_R[RRR_T]);

                    tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);

                    tcg_temp_free(v2);

                    tcg_temp_free(v1);

                }

                break;

            case 13: /*MUL16S*/

                HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);

                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);

                {

                    TCGv_i32 v1 = tcg_temp_new_i32();

                    TCGv_i32 v2 = tcg_temp_new_i32();

                    tcg_gen_ext16s_i32(v1, cpu_R[RRR_S]);

                    tcg_gen_ext16s_i32(v2, cpu_R[RRR_T]);

                    tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);

                    tcg_temp_free(v2);

                    tcg_temp_free(v1);

                }

                break;

            default: /*reserved*/

                RESERVED();

                break;

            }

            break;

        case 2: /*RST2*/

            if (OP2 >= 8) {

                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);

            }

            if (OP2 >= 12) {

                HAS_OPTION(XTENSA_OPTION_32_BIT_IDIV);

                int label = gen_new_label();

                tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0, label);

                gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE);

                gen_set_label(label);

            }

            switch (OP2) {

#define BOOLEAN_LOGIC(fn, r, s, t) \

                do { \

                    HAS_OPTION(XTENSA_OPTION_BOOLEAN); \

                    TCGv_i32 tmp1 = tcg_temp_new_i32(); \

                    TCGv_i32 tmp2 = tcg_temp_new_i32(); \

                    \

                    tcg_gen_shri_i32(tmp1, cpu_SR[BR], s); \

                    tcg_gen_shri_i32(tmp2, cpu_SR[BR], t); \

                    tcg_gen_##fn##_i32(tmp1, tmp1, tmp2); \

                    tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR], tmp1, r, 1); \

                    tcg_temp_free(tmp1); \

                    tcg_temp_free(tmp2); \

                } while (0)

            case 0: /*ANDBp*/

                BOOLEAN_LOGIC(and, RRR_R, RRR_S, RRR_T);

                break;

            case 1: /*ANDBCp*/

                BOOLEAN_LOGIC(andc, RRR_R, RRR_S, RRR_T);

                break;

            case 2: /*ORBp*/

                BOOLEAN_LOGIC(or, RRR_R, RRR_S, RRR_T);

                break;

            case 3: /*ORBCp*/

                BOOLEAN_LOGIC(orc, RRR_R, RRR_S, RRR_T);

                break;

            case 4: /*XORBp*/

                BOOLEAN_LOGIC(xor, RRR_R, RRR_S, RRR_T);

                break;

#undef BOOLEAN_LOGIC

            case 8: /*MULLi*/

                HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL);

                tcg_gen_mul_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);

                break;

            case 10: /*MULUHi*/

            case 11: /*MULSHi*/

                HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL_HIGH);

                {

                    TCGv_i64 r = tcg_temp_new_i64();

                    TCGv_i64 s = tcg_temp_new_i64();

                    TCGv_i64 t = tcg_temp_new_i64();

                    if (OP2 == 10) {

                        tcg_gen_extu_i32_i64(s, cpu_R[RRR_S]);

                        tcg_gen_extu_i32_i64(t, cpu_R[RRR_T]);

                    } else {

                        tcg_gen_ext_i32_i64(s, cpu_R[RRR_S]);

                        tcg_gen_ext_i32_i64(t, cpu_R[RRR_T]);

                    }

                    tcg_gen_mul_i64(r, s, t);

                    tcg_gen_shri_i64(r, r, 32);

                    tcg_gen_trunc_i64_i32(cpu_R[RRR_R], r);

                    tcg_temp_free_i64(r);

                    tcg_temp_free_i64(s);

                    tcg_temp_free_i64(t);

                }

                break;

            case 12: /*QUOUi*/

                tcg_gen_divu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);

                break;

            case 13: /*QUOSi*/

            case 15: /*REMSi*/

                {

                    int label1 = gen_new_label();

                    int label2 = gen_new_label();

                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_S], 0x80000000,

                            label1);

                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0xffffffff,

                            label1);

                    tcg_gen_movi_i32(cpu_R[RRR_R],

                            OP2 == 13 ? 0x80000000 : 0);

                    tcg_gen_br(label2);

                    gen_set_label(label1);

                    if (OP2 == 13) {

                        tcg_gen_div_i32(cpu_R[RRR_R],

                                cpu_R[RRR_S], cpu_R[RRR_T]);

                    } else {

                        tcg_gen_rem_i32(cpu_R[RRR_R],

                                cpu_R[RRR_S], cpu_R[RRR_T]);

                    }

                    gen_set_label(label2);

                }

                break;

            case 14: /*REMUi*/

                tcg_gen_remu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);

                break;

            default: /*reserved*/

                RESERVED();

                break;

            }

            break;

        case 3: /*RST3*/

            switch (OP2) {

            case 0: /*RSR*/

                if (RSR_SR >= 64) {

                    gen_check_privilege(dc);

                }

                gen_window_check1(dc, RRR_T);

                gen_rsr(dc, cpu_R[RRR_T], RSR_SR);

                if (!sregnames[RSR_SR]) {

                    TBD();

                }

                break;

            case 1: /*WSR*/

                if (RSR_SR >= 64) {

                    gen_check_privilege(dc);

                }

                gen_window_check1(dc, RRR_T);

                gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);

                if (!sregnames[RSR_SR]) {

                    TBD();

                }

                break;

            case 2: /*SEXTu*/

                HAS_OPTION(XTENSA_OPTION_MISC_OP_SEXT);

                gen_window_check2(dc, RRR_R, RRR_S);

                {

                    int shift = 24 - RRR_T;

                    if (shift == 24) {

                        tcg_gen_ext8s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);

                    } else if (shift == 16) {

                        tcg_gen_ext16s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);

                    } else {

                        TCGv_i32 tmp = tcg_temp_new_i32();

                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], shift);

                        tcg_gen_sari_i32(cpu_R[RRR_R], tmp, shift);

                        tcg_temp_free(tmp);

                    }

                }

                break;

            case 3: /*CLAMPSu*/

                HAS_OPTION(XTENSA_OPTION_MISC_OP_CLAMPS);

                gen_window_check2(dc, RRR_R, RRR_S);

                {

                    TCGv_i32 tmp1 = tcg_temp_new_i32();

                    TCGv_i32 tmp2 = tcg_temp_new_i32();

                    int label = gen_new_label();

                    tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 24 - RRR_T);

                    tcg_gen_xor_i32(tmp2, tmp1, cpu_R[RRR_S]);

                    tcg_gen_andi_i32(tmp2, tmp2, 0xffffffff << (RRR_T + 7));

                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);

                    tcg_gen_brcondi_i32(TCG_COND_EQ, tmp2, 0, label);

                    tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 31);

                    tcg_gen_xori_i32(cpu_R[RRR_R], tmp1,

                            0xffffffff >> (25 - RRR_T));

                    gen_set_label(label);

                    tcg_temp_free(tmp1);

                    tcg_temp_free(tmp2);

                }

                break;

            case 4: /*MINu*/

            case 5: /*MAXu*/

            case 6: /*MINUu*/

            case 7: /*MAXUu*/

                HAS_OPTION(XTENSA_OPTION_MISC_OP_MINMAX);

                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);

                {

                    static const TCGCond cond[] = {

                        TCG_COND_LE,

                        TCG_COND_GE,

                        TCG_COND_LEU,

                        TCG_COND_GEU

                    };

                    int label = gen_new_label();

                    if (RRR_R != RRR_T) {

                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);

                        tcg_gen_brcond_i32(cond[OP2 - 4],

                                cpu_R[RRR_S], cpu_R[RRR_T], label);

                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);

                    } else {

                        tcg_gen_brcond_i32(cond[OP2 - 4],

                                cpu_R[RRR_T], cpu_R[RRR_S], label);

                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);

                    }

                    gen_set_label(label);

                }

                break;

            case 8: /*MOVEQZ*/

            case 9: /*MOVNEZ*/

            case 10: /*MOVLTZ*/

            case 11: /*MOVGEZ*/

                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);

                {

                    static const TCGCond cond[] = {

                        TCG_COND_NE,

                        TCG_COND_EQ,

                        TCG_COND_GE,

                        TCG_COND_LT

                    };

                    int label = gen_new_label();

                    tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);

                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);

                    gen_set_label(label);

                }

                break;

            case 12: /*MOVFp*/

            case 13: /*MOVTp*/

                HAS_OPTION(XTENSA_OPTION_BOOLEAN);

                gen_window_check2(dc, RRR_R, RRR_S);

                {

                    int label = gen_new_label();

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRR_T);

                    tcg_gen_brcondi_i32(

                            OP2 & 1 ? TCG_COND_EQ : TCG_COND_NE,

                            tmp, 0, label);

                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);

                    gen_set_label(label);

                    tcg_temp_free(tmp);

                }

                break;

            case 14: /*RUR*/

                gen_window_check1(dc, RRR_R);

                {

                    int st = (RRR_S << 4) + RRR_T;

                    if (uregnames[st]) {

                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);

                    } else {

                        qemu_log("RUR %d not implemented, ", st);

                        TBD();

                    }

                }

                break;

            case 15: /*WUR*/

                gen_window_check1(dc, RRR_T);

                if (uregnames[RSR_SR]) {

                    gen_wur(RSR_SR, cpu_R[RRR_T]);

                } else {

                    qemu_log("WUR %d not implemented, ", RSR_SR);

                    TBD();

                }

                break;

            }

            break;

        case 4: /*EXTUI*/

        case 5:

            gen_window_check2(dc, RRR_R, RRR_T);

            {

                int shiftimm = RRR_S | ((OP1 & 1) << 4);

                int maskimm = (1 << (OP2 + 1)) - 1;

                TCGv_i32 tmp = tcg_temp_new_i32();

                tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);

                tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);

                tcg_temp_free(tmp);

            }

            break;

        case 6: /*CUST0*/

            RESERVED();

            break;

        case 7: /*CUST1*/

            RESERVED();

            break;

        case 8: /*LSCXp*/

            switch (OP2) {

            case 0: /*LSXf*/

            case 1: /*LSXUf*/

            case 4: /*SSXf*/

            case 5: /*SSXUf*/

                HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);

                gen_window_check2(dc, RRR_S, RRR_T);

                gen_check_cpenable(dc, 0);

                {

                    TCGv_i32 addr = tcg_temp_new_i32();

                    tcg_gen_add_i32(addr, cpu_R[RRR_S], cpu_R[RRR_T]);

                    gen_load_store_alignment(dc, 2, addr, false);

                    if (OP2 & 0x4) {

                        tcg_gen_qemu_st32(cpu_FR[RRR_R], addr, dc->cring);

                    } else {

                        tcg_gen_qemu_ld32u(cpu_FR[RRR_R], addr, dc->cring);

                    }

                    if (OP2 & 0x1) {

                        tcg_gen_mov_i32(cpu_R[RRR_S], addr);

                    }

                    tcg_temp_free(addr);

                }

                break;

            default: /*reserved*/

                RESERVED();

                break;

            }

            break;

        case 9: /*LSC4*/

            gen_window_check2(dc, RRR_S, RRR_T);

            switch (OP2) {

            case 0: /*L32E*/

                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                gen_check_privilege(dc);

                {

                    TCGv_i32 addr = tcg_temp_new_i32();

                    tcg_gen_addi_i32(addr, cpu_R[RRR_S],

                            (0xffffffc0 | (RRR_R << 2)));

                    tcg_gen_qemu_ld32u(cpu_R[RRR_T], addr, dc->ring);

                    tcg_temp_free(addr);

                }

                break;

            case 4: /*S32E*/

                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                gen_check_privilege(dc);

                {

                    TCGv_i32 addr = tcg_temp_new_i32();

                    tcg_gen_addi_i32(addr, cpu_R[RRR_S],

                            (0xffffffc0 | (RRR_R << 2)));

                    tcg_gen_qemu_st32(cpu_R[RRR_T], addr, dc->ring);

                    tcg_temp_free(addr);

                }

                break;

            default:

                RESERVED();

                break;

            }

            break;

        case 10: /*FP0*/

            HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);

            switch (OP2) {

            case 0: /*ADD.Sf*/

                gen_check_cpenable(dc, 0);

                gen_helper_add_s(cpu_FR[RRR_R], cpu_env,

                        cpu_FR[RRR_S], cpu_FR[RRR_T]);

                break;

            case 1: /*SUB.Sf*/

                gen_check_cpenable(dc, 0);

                gen_helper_sub_s(cpu_FR[RRR_R], cpu_env,

                        cpu_FR[RRR_S], cpu_FR[RRR_T]);

                break;

            case 2: /*MUL.Sf*/

                gen_check_cpenable(dc, 0);

                gen_helper_mul_s(cpu_FR[RRR_R], cpu_env,

                        cpu_FR[RRR_S], cpu_FR[RRR_T]);

                break;

            case 4: /*MADD.Sf*/

                gen_check_cpenable(dc, 0);

                gen_helper_madd_s(cpu_FR[RRR_R], cpu_env,

                        cpu_FR[RRR_R], cpu_FR[RRR_S], cpu_FR[RRR_T]);

                break;

            case 5: /*MSUB.Sf*/

                gen_check_cpenable(dc, 0);

                gen_helper_msub_s(cpu_FR[RRR_R], cpu_env,

                        cpu_FR[RRR_R], cpu_FR[RRR_S], cpu_FR[RRR_T]);

                break;

            case 8: /*ROUND.Sf*/

            case 9: /*TRUNC.Sf*/

            case 10: /*FLOOR.Sf*/

            case 11: /*CEIL.Sf*/

            case 14: /*UTRUNC.Sf*/

                gen_window_check1(dc, RRR_R);

                gen_check_cpenable(dc, 0);

                {

                    static const unsigned rounding_mode_const[] = {

                        float_round_nearest_even,

                        float_round_to_zero,

                        float_round_down,

                        float_round_up,

                        [6] = float_round_to_zero,

                    };

                    TCGv_i32 rounding_mode = tcg_const_i32(

                            rounding_mode_const[OP2 & 7]);

                    TCGv_i32 scale = tcg_const_i32(RRR_T);

                    if (OP2 == 14) {

                        gen_helper_ftoui(cpu_R[RRR_R], cpu_FR[RRR_S],

                                rounding_mode, scale);

                    } else {

                        gen_helper_ftoi(cpu_R[RRR_R], cpu_FR[RRR_S],

                                rounding_mode, scale);

                    }

                    tcg_temp_free(rounding_mode);

                    tcg_temp_free(scale);

                }

                break;

            case 12: /*FLOAT.Sf*/

            case 13: /*UFLOAT.Sf*/

                gen_window_check1(dc, RRR_S);

                gen_check_cpenable(dc, 0);

                {

                    TCGv_i32 scale = tcg_const_i32(-RRR_T);

                    if (OP2 == 13) {

                        gen_helper_uitof(cpu_FR[RRR_R], cpu_env,

                                cpu_R[RRR_S], scale);

                    } else {

                        gen_helper_itof(cpu_FR[RRR_R], cpu_env,

                                cpu_R[RRR_S], scale);

                    }

                    tcg_temp_free(scale);

                }

                break;

            case 15: /*FP1OP*/

                switch (RRR_T) {

                case 0: /*MOV.Sf*/

                    gen_check_cpenable(dc, 0);

                    tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]);

                    break;

                case 1: /*ABS.Sf*/

                    gen_check_cpenable(dc, 0);

                    gen_helper_abs_s(cpu_FR[RRR_R], cpu_FR[RRR_S]);

                    break;

                case 4: /*RFRf*/

                    gen_window_check1(dc, RRR_R);

                    gen_check_cpenable(dc, 0);

                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_FR[RRR_S]);

                    break;

                case 5: /*WFRf*/

                    gen_window_check1(dc, RRR_S);

                    gen_check_cpenable(dc, 0);

                    tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_R[RRR_S]);

                    break;

                case 6: /*NEG.Sf*/

                    gen_check_cpenable(dc, 0);

                    gen_helper_neg_s(cpu_FR[RRR_R], cpu_FR[RRR_S]);

                    break;

                default: /*reserved*/

                    RESERVED();

                    break;

                }

                break;

            default: /*reserved*/

                RESERVED();

                break;

            }

            break;

        case 11: /*FP1*/

            HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);

#define gen_compare(rel, br, a, b) \

    do { \

        TCGv_i32 bit = tcg_const_i32(1 << br); \

        \

        gen_check_cpenable(dc, 0); \

        gen_helper_##rel(cpu_env, bit, cpu_FR[a], cpu_FR[b]); \

        tcg_temp_free(bit); \

    } while (0)

            switch (OP2) {

            case 1: /*UN.Sf*/

                gen_compare(un_s, RRR_R, RRR_S, RRR_T);

                break;

            case 2: /*OEQ.Sf*/

                gen_compare(oeq_s, RRR_R, RRR_S, RRR_T);

                break;

            case 3: /*UEQ.Sf*/

                gen_compare(ueq_s, RRR_R, RRR_S, RRR_T);

                break;

            case 4: /*OLT.Sf*/

                gen_compare(olt_s, RRR_R, RRR_S, RRR_T);

                break;

            case 5: /*ULT.Sf*/

                gen_compare(ult_s, RRR_R, RRR_S, RRR_T);

                break;

            case 6: /*OLE.Sf*/

                gen_compare(ole_s, RRR_R, RRR_S, RRR_T);

                break;

            case 7: /*ULE.Sf*/

                gen_compare(ule_s, RRR_R, RRR_S, RRR_T);

                break;

#undef gen_compare

            case 8: /*MOVEQZ.Sf*/

            case 9: /*MOVNEZ.Sf*/

            case 10: /*MOVLTZ.Sf*/

            case 11: /*MOVGEZ.Sf*/

                gen_window_check1(dc, RRR_T);

                gen_check_cpenable(dc, 0);

                {

                    static const TCGCond cond[] = {

                        TCG_COND_NE,

                        TCG_COND_EQ,

                        TCG_COND_GE,

                        TCG_COND_LT

                    };

                    int label = gen_new_label();

                    tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);

                    tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]);

                    gen_set_label(label);

                }

                break;

            case 12: /*MOVF.Sf*/

            case 13: /*MOVT.Sf*/

                HAS_OPTION(XTENSA_OPTION_BOOLEAN);

                gen_check_cpenable(dc, 0);

                {

                    int label = gen_new_label();

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRR_T);

                    tcg_gen_brcondi_i32(

                            OP2 & 1 ? TCG_COND_EQ : TCG_COND_NE,

                            tmp, 0, label);

                    tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]);

                    gen_set_label(label);

                    tcg_temp_free(tmp);

                }

                break;

            default: /*reserved*/

                RESERVED();

                break;

            }

            break;

        default: /*reserved*/

            RESERVED();

            break;

        }

        break;

    case 1: /*L32R*/

        gen_window_check1(dc, RRR_T);

        {

            TCGv_i32 tmp = tcg_const_i32(

                    ((dc->tb->flags & XTENSA_TBFLAG_LITBASE) ?

                     0 : ((dc->pc + 3) & ~3)) +

                    (0xfffc0000 | (RI16_IMM16 << 2)));

            if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {

                tcg_gen_add_i32(tmp, tmp, dc->litbase);

            }

            tcg_gen_qemu_ld32u(cpu_R[RRR_T], tmp, dc->cring);

            tcg_temp_free(tmp);

        }

        break;

    case 2: /*LSAI*/

#define gen_load_store(type, shift) do { \

            TCGv_i32 addr = tcg_temp_new_i32(); \

            gen_window_check2(dc, RRI8_S, RRI8_T); \

            tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \

            if (shift) { \

                gen_load_store_alignment(dc, shift, addr, false); \

            } \

            tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \

            tcg_temp_free(addr); \

        } while (0)

        switch (RRI8_R) {

        case 0: /*L8UI*/

            gen_load_store(ld8u, 0);

            break;

        case 1: /*L16UI*/

            gen_load_store(ld16u, 1);

            break;

        case 2: /*L32I*/

            gen_load_store(ld32u, 2);

            break;

        case 4: /*S8I*/

            gen_load_store(st8, 0);

            break;

        case 5: /*S16I*/

            gen_load_store(st16, 1);

            break;

        case 6: /*S32I*/

            gen_load_store(st32, 2);

            break;

        case 7: /*CACHEc*/

            if (RRI8_T < 8) {

                HAS_OPTION(XTENSA_OPTION_DCACHE);

            }

            switch (RRI8_T) {

            case 0: /*DPFRc*/

                break;

            case 1: /*DPFWc*/

                break;

            case 2: /*DPFROc*/

                break;

            case 3: /*DPFWOc*/

                break;

            case 4: /*DHWBc*/

                break;

            case 5: /*DHWBIc*/

                break;

            case 6: /*DHIc*/

                break;

            case 7: /*DIIc*/

                break;

            case 8: /*DCEc*/

                switch (OP1) {

                case 0: /*DPFLl*/

                    HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);

                    break;

                case 2: /*DHUl*/

                    HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);

                    break;

                case 3: /*DIUl*/

                    HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);

                    break;

                case 4: /*DIWBc*/

                    HAS_OPTION(XTENSA_OPTION_DCACHE);

                    break;

                case 5: /*DIWBIc*/

                    HAS_OPTION(XTENSA_OPTION_DCACHE);

                    break;

                default: /*reserved*/

                    RESERVED();

                    break;

                }

                break;

            case 12: /*IPFc*/

                HAS_OPTION(XTENSA_OPTION_ICACHE);

                break;

            case 13: /*ICEc*/

                switch (OP1) {

                case 0: /*IPFLl*/

                    HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);

                    break;

                case 2: /*IHUl*/

                    HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);

                    break;

                case 3: /*IIUl*/

                    HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);

                    break;

                default: /*reserved*/

                    RESERVED();

                    break;

                }

                break;

            case 14: /*IHIc*/

                HAS_OPTION(XTENSA_OPTION_ICACHE);

                break;

            case 15: /*IIIc*/

                HAS_OPTION(XTENSA_OPTION_ICACHE);

                break;

            default: /*reserved*/

                RESERVED();

                break;

            }

            break;

        case 9: /*L16SI*/

            gen_load_store(ld16s, 1);

            break;

#undef gen_load_store

        case 10: /*MOVI*/

            gen_window_check1(dc, RRI8_T);

            tcg_gen_movi_i32(cpu_R[RRI8_T],

                    RRI8_IMM8 | (RRI8_S << 8) |

                    ((RRI8_S & 0x8) ? 0xfffff000 : 0));

            break;

#define gen_load_store_no_hw_align(type) do { \

            TCGv_i32 addr = tcg_temp_local_new_i32(); \

            gen_window_check2(dc, RRI8_S, RRI8_T); \

            tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2); \

            gen_load_store_alignment(dc, 2, addr, true); \

            tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \

            tcg_temp_free(addr); \

        } while (0)

        case 11: /*L32AIy*/

            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);

            gen_load_store_no_hw_align(ld32u); /*TODO acquire?*/

            break;

        case 12: /*ADDI*/

            gen_window_check2(dc, RRI8_S, RRI8_T);

            tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE);

            break;

        case 13: /*ADDMI*/

            gen_window_check2(dc, RRI8_S, RRI8_T);

            tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE << 8);

            break;

        case 14: /*S32C1Iy*/

            HAS_OPTION(XTENSA_OPTION_CONDITIONAL_STORE);

            gen_window_check2(dc, RRI8_S, RRI8_T);

            {

                int label = gen_new_label();

                TCGv_i32 tmp = tcg_temp_local_new_i32();

                TCGv_i32 addr = tcg_temp_local_new_i32();

                TCGv_i32 tpc;

                tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]);

                tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);

                gen_load_store_alignment(dc, 2, addr, true);

                gen_advance_ccount(dc);

                tpc = tcg_const_i32(dc->pc);

                gen_helper_check_atomctl(cpu_env, tpc, addr);

                tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, dc->cring);

                tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T],

                        cpu_SR[SCOMPARE1], label);

                tcg_gen_qemu_st32(tmp, addr, dc->cring);

                gen_set_label(label);

                tcg_temp_free(tpc);

                tcg_temp_free(addr);

                tcg_temp_free(tmp);

            }

            break;

        case 15: /*S32RIy*/

            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);

            gen_load_store_no_hw_align(st32); /*TODO release?*/

            break;

#undef gen_load_store_no_hw_align

        default: /*reserved*/

            RESERVED();

            break;

        }

        break;

    case 3: /*LSCIp*/

        switch (RRI8_R) {

        case 0: /*LSIf*/

        case 4: /*SSIf*/

        case 8: /*LSIUf*/

        case 12: /*SSIUf*/

            HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);

            gen_window_check1(dc, RRI8_S);

            gen_check_cpenable(dc, 0);

            {

                TCGv_i32 addr = tcg_temp_new_i32();

                tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);

                gen_load_store_alignment(dc, 2, addr, false);

                if (RRI8_R & 0x4) {

                    tcg_gen_qemu_st32(cpu_FR[RRI8_T], addr, dc->cring);

                } else {

                    tcg_gen_qemu_ld32u(cpu_FR[RRI8_T], addr, dc->cring);

                }

                if (RRI8_R & 0x8) {

                    tcg_gen_mov_i32(cpu_R[RRI8_S], addr);

                }

                tcg_temp_free(addr);

            }

            break;

        default: /*reserved*/

            RESERVED();

            break;

        }

        break;

    case 4: /*MAC16d*/

        HAS_OPTION(XTENSA_OPTION_MAC16);

        {

            enum {

                MAC16_UMUL = 0x0,

                MAC16_MUL  = 0x4,

                MAC16_MULA = 0x8,

                MAC16_MULS = 0xc,

                MAC16_NONE = 0xf,

            } op = OP1 & 0xc;

            bool is_m1_sr = (OP2 & 0x3) == 2;

            bool is_m2_sr = (OP2 & 0xc) == 0;

            uint32_t ld_offset = 0;

            if (OP2 > 9) {

                RESERVED();

            }

            switch (OP2 & 2) {

            case 0: /*MACI?/MACC?*/

                is_m1_sr = true;

                ld_offset = (OP2 & 1) ? -4 : 4;

                if (OP2 >= 8) { /*MACI/MACC*/

                    if (OP1 == 0) { /*LDINC/LDDEC*/

                        op = MAC16_NONE;

                    } else {

                        RESERVED();

                    }

                } else if (op != MAC16_MULA) { /*MULA.*.*.LDINC/LDDEC*/

                    RESERVED();

                }

                break;

            case 2: /*MACD?/MACA?*/

                if (op == MAC16_UMUL && OP2 != 7) { /*UMUL only in MACAA*/

                    RESERVED();

                }

                break;

            }

            if (op != MAC16_NONE) {

                if (!is_m1_sr) {

                    gen_window_check1(dc, RRR_S);

                }

                if (!is_m2_sr) {

                    gen_window_check1(dc, RRR_T);

                }

            }

            {

                TCGv_i32 vaddr = tcg_temp_new_i32();

                TCGv_i32 mem32 = tcg_temp_new_i32();

                if (ld_offset) {

                    gen_window_check1(dc, RRR_S);

                    tcg_gen_addi_i32(vaddr, cpu_R[RRR_S], ld_offset);

                    gen_load_store_alignment(dc, 2, vaddr, false);

                    tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring);

                }

                if (op != MAC16_NONE) {

                    TCGv_i32 m1 = gen_mac16_m(

                            is_m1_sr ? cpu_SR[MR + RRR_X] : cpu_R[RRR_S],

                            OP1 & 1, op == MAC16_UMUL);

                    TCGv_i32 m2 = gen_mac16_m(

                            is_m2_sr ? cpu_SR[MR + 2 + RRR_Y] : cpu_R[RRR_T],

                            OP1 & 2, op == MAC16_UMUL);

                    if (op == MAC16_MUL || op == MAC16_UMUL) {

                        tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2);

                        if (op == MAC16_UMUL) {

                            tcg_gen_movi_i32(cpu_SR[ACCHI], 0);

                        } else {

                            tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31);

                        }

                    } else {

                        TCGv_i32 res = tcg_temp_new_i32();

                        TCGv_i64 res64 = tcg_temp_new_i64();

                        TCGv_i64 tmp = tcg_temp_new_i64();

                        tcg_gen_mul_i32(res, m1, m2);

                        tcg_gen_ext_i32_i64(res64, res);

                        tcg_gen_concat_i32_i64(tmp,

                                cpu_SR[ACCLO], cpu_SR[ACCHI]);

                        if (op == MAC16_MULA) {

                            tcg_gen_add_i64(tmp, tmp, res64);

                        } else {

                            tcg_gen_sub_i64(tmp, tmp, res64);

                        }

                        tcg_gen_trunc_i64_i32(cpu_SR[ACCLO], tmp);

                        tcg_gen_shri_i64(tmp, tmp, 32);

                        tcg_gen_trunc_i64_i32(cpu_SR[ACCHI], tmp);

                        tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);

                        tcg_temp_free(res);

                        tcg_temp_free_i64(res64);

                        tcg_temp_free_i64(tmp);

                    }

                    tcg_temp_free(m1);

                    tcg_temp_free(m2);

                }

                if (ld_offset) {

                    tcg_gen_mov_i32(cpu_R[RRR_S], vaddr);

                    tcg_gen_mov_i32(cpu_SR[MR + RRR_W], mem32);

                }

                tcg_temp_free(vaddr);

                tcg_temp_free(mem32);

            }

        }

        break;

    case 5: /*CALLN*/

        switch (CALL_N) {

        case 0: /*CALL0*/

            tcg_gen_movi_i32(cpu_R[0], dc->next_pc);

            gen_jumpi(dc, (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);

            break;

        case 1: /*CALL4w*/

        case 2: /*CALL8w*/

        case 3: /*CALL12w*/

            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

            gen_window_check1(dc, CALL_N << 2);

            gen_callwi(dc, CALL_N,

                    (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);

            break;

        }

        break;

    case 6: /*SI*/

        switch (CALL_N) {

        case 0: /*J*/

            gen_jumpi(dc, dc->pc + 4 + CALL_OFFSET_SE, 0);

            break;

        case 1: /*BZ*/

            gen_window_check1(dc, BRI12_S);

            {

                static const TCGCond cond[] = {

                    TCG_COND_EQ, /*BEQZ*/

                    TCG_COND_NE, /*BNEZ*/

                    TCG_COND_LT, /*BLTZ*/

                    TCG_COND_GE, /*BGEZ*/

                };

                gen_brcondi(dc, cond[BRI12_M & 3], cpu_R[BRI12_S], 0,

                        4 + BRI12_IMM12_SE);

            }

            break;

        case 2: /*BI0*/

            gen_window_check1(dc, BRI8_S);

            {

                static const TCGCond cond[] = {

                    TCG_COND_EQ, /*BEQI*/

                    TCG_COND_NE, /*BNEI*/

                    TCG_COND_LT, /*BLTI*/

                    TCG_COND_GE, /*BGEI*/

                };

                gen_brcondi(dc, cond[BRI8_M & 3],

                        cpu_R[BRI8_S], B4CONST[BRI8_R], 4 + BRI8_IMM8_SE);

            }

            break;

        case 3: /*BI1*/

            switch (BRI8_M) {

            case 0: /*ENTRYw*/

                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                {

                    TCGv_i32 pc = tcg_const_i32(dc->pc);

                    TCGv_i32 s = tcg_const_i32(BRI12_S);

                    TCGv_i32 imm = tcg_const_i32(BRI12_IMM12);

                    gen_advance_ccount(dc);

                    gen_helper_entry(cpu_env, pc, s, imm);

                    tcg_temp_free(imm);

                    tcg_temp_free(s);

                    tcg_temp_free(pc);

                    reset_used_window(dc);

                }

                break;

            case 1: /*B1*/

                switch (BRI8_R) {

                case 0: /*BFp*/

                case 1: /*BTp*/

                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);

                    {

                        TCGv_i32 tmp = tcg_temp_new_i32();

                        tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRI8_S);

                        gen_brcondi(dc,

                                BRI8_R == 1 ? TCG_COND_NE : TCG_COND_EQ,

                                tmp, 0, 4 + RRI8_IMM8_SE);

                        tcg_temp_free(tmp);

                    }

                    break;

                case 8: /*LOOP*/

                case 9: /*LOOPNEZ*/

                case 10: /*LOOPGTZ*/

                    HAS_OPTION(XTENSA_OPTION_LOOP);

                    gen_window_check1(dc, RRI8_S);

                    {

                        uint32_t lend = dc->pc + RRI8_IMM8 + 4;

                        TCGv_i32 tmp = tcg_const_i32(lend);

                        tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[RRI8_S], 1);

                        tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc);

                        gen_helper_wsr_lend(cpu_env, tmp);

                        tcg_temp_free(tmp);

                        if (BRI8_R > 8) {

                            int label = gen_new_label();

                            tcg_gen_brcondi_i32(

                                    BRI8_R == 9 ? TCG_COND_NE : TCG_COND_GT,

                                    cpu_R[RRI8_S], 0, label);

                            gen_jumpi(dc, lend, 1);

                            gen_set_label(label);

                        }

                        gen_jumpi(dc, dc->next_pc, 0);

                    }

                    break;

                default: /*reserved*/

                    RESERVED();

                    break;

                }

                break;

            case 2: /*BLTUI*/

            case 3: /*BGEUI*/

                gen_window_check1(dc, BRI8_S);

                gen_brcondi(dc, BRI8_M == 2 ? TCG_COND_LTU : TCG_COND_GEU,

                        cpu_R[BRI8_S], B4CONSTU[BRI8_R], 4 + BRI8_IMM8_SE);

                break;

            }

            break;

        }

        break;

    case 7: /*B*/

        {

            TCGCond eq_ne = (RRI8_R & 8) ? TCG_COND_NE : TCG_COND_EQ;

            switch (RRI8_R & 7) {

            case 0: /*BNONE*/ /*BANY*/

                gen_window_check2(dc, RRI8_S, RRI8_T);

                {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);

                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);

                    tcg_temp_free(tmp);

                }

                break;

            case 1: /*BEQ*/ /*BNE*/

            case 2: /*BLT*/ /*BGE*/

            case 3: /*BLTU*/ /*BGEU*/

                gen_window_check2(dc, RRI8_S, RRI8_T);

                {

                    static const TCGCond cond[] = {

                        [1] = TCG_COND_EQ,

                        [2] = TCG_COND_LT,

                        [3] = TCG_COND_LTU,

                        [9] = TCG_COND_NE,

                        [10] = TCG_COND_GE,

                        [11] = TCG_COND_GEU,

                    };

                    gen_brcond(dc, cond[RRI8_R], cpu_R[RRI8_S], cpu_R[RRI8_T],

                            4 + RRI8_IMM8_SE);

                }

                break;

            case 4: /*BALL*/ /*BNALL*/

                gen_window_check2(dc, RRI8_S, RRI8_T);

                {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);

                    gen_brcond(dc, eq_ne, tmp, cpu_R[RRI8_T],

                            4 + RRI8_IMM8_SE);

                    tcg_temp_free(tmp);

                }

                break;

            case 5: /*BBC*/ /*BBS*/

                gen_window_check2(dc, RRI8_S, RRI8_T);

                {

#ifdef TARGET_WORDS_BIGENDIAN

                    TCGv_i32 bit = tcg_const_i32(0x80000000);

#else

                    TCGv_i32 bit = tcg_const_i32(0x00000001);

#endif

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_andi_i32(tmp, cpu_R[RRI8_T], 0x1f);

#ifdef TARGET_WORDS_BIGENDIAN

                    tcg_gen_shr_i32(bit, bit, tmp);

#else

                    tcg_gen_shl_i32(bit, bit, tmp);

#endif

                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], bit);

                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);

                    tcg_temp_free(tmp);

                    tcg_temp_free(bit);

                }

                break;

            case 6: /*BBCI*/ /*BBSI*/

            case 7:

                gen_window_check1(dc, RRI8_S);

                {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_andi_i32(tmp, cpu_R[RRI8_S],

#ifdef TARGET_WORDS_BIGENDIAN

                            0x80000000 >> (((RRI8_R & 1) << 4) | RRI8_T));

#else

                            0x00000001 << (((RRI8_R & 1) << 4) | RRI8_T));

#endif

                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);

                    tcg_temp_free(tmp);

                }

                break;

            }

        }

        break;

#define gen_narrow_load_store(type) do { \

            TCGv_i32 addr = tcg_temp_new_i32(); \

            gen_window_check2(dc, RRRN_S, RRRN_T); \

            tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \

            gen_load_store_alignment(dc, 2, addr, false); \

            tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, dc->cring); \

            tcg_temp_free(addr); \

        } while (0)

    case 8: /*L32I.Nn*/

        gen_narrow_load_store(ld32u);

        break;

    case 9: /*S32I.Nn*/

        gen_narrow_load_store(st32);

        break;

#undef gen_narrow_load_store

    case 10: /*ADD.Nn*/

        gen_window_check3(dc, RRRN_R, RRRN_S, RRRN_T);

        tcg_gen_add_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], cpu_R[RRRN_T]);

        break;

    case 11: /*ADDI.Nn*/

        gen_window_check2(dc, RRRN_R, RRRN_S);

        tcg_gen_addi_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], RRRN_T ? RRRN_T : -1);

        break;

    case 12: /*ST2n*/

        gen_window_check1(dc, RRRN_S);

        if (RRRN_T < 8) { /*MOVI.Nn*/

            tcg_gen_movi_i32(cpu_R[RRRN_S],

                    RRRN_R | (RRRN_T << 4) |

                    ((RRRN_T & 6) == 6 ? 0xffffff80 : 0));

        } else { /*BEQZ.Nn*/ /*BNEZ.Nn*/

            TCGCond eq_ne = (RRRN_T & 4) ? TCG_COND_NE : TCG_COND_EQ;

            gen_brcondi(dc, eq_ne, cpu_R[RRRN_S], 0,

                    4 + (RRRN_R | ((RRRN_T & 3) << 4)));

        }

        break;

    case 13: /*ST3n*/

        switch (RRRN_R) {

        case 0: /*MOV.Nn*/

            gen_window_check2(dc, RRRN_S, RRRN_T);

            tcg_gen_mov_i32(cpu_R[RRRN_T], cpu_R[RRRN_S]);

            break;

        case 15: /*S3*/

            switch (RRRN_T) {

            case 0: /*RET.Nn*/

                gen_jump(dc, cpu_R[0]);

                break;

            case 1: /*RETW.Nn*/

                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                {

                    TCGv_i32 tmp = tcg_const_i32(dc->pc);

                    gen_advance_ccount(dc);

                    gen_helper_retw(tmp, cpu_env, tmp);

                    gen_jump(dc, tmp);

                    tcg_temp_free(tmp);

                }

                break;

            case 2: /*BREAK.Nn*/

                HAS_OPTION(XTENSA_OPTION_DEBUG);

                if (dc->debug) {

                    gen_debug_exception(dc, DEBUGCAUSE_BN);

                }

                break;

            case 3: /*NOP.Nn*/

                break;

            case 6: /*ILL.Nn*/

                gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);

                break;

            default: /*reserved*/

                RESERVED();

                break;

            }

            break;

        default: /*reserved*/

            RESERVED();

            break;

        }

        break;

    default: /*reserved*/

        RESERVED();

        break;

    }

    if (dc->is_jmp == DISAS_NEXT) {

        gen_check_loop_end(dc, 0);

    }

    dc->pc = dc->next_pc;

    return;

invalid_opcode:

    qemu_log("INVALID(pc = %08x)\n", dc->pc);

    gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);

#undef HAS_OPTION

}


static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0,

                                            int nPbW, int nPbH,

                                            int log2_cb_size,

                                            int singleMCLFlag, int part_idx,

                                            int merge_idx,

                                            struct MvField mergecandlist[])

{

    HEVCLocalContext *lc   = &s->HEVClc;

    RefPicList *refPicList = s->ref->refPicList;

    MvField *tab_mvf       = s->ref->tab_mvf;

    const int min_pu_width = s->sps->min_pu_width;

    const int cand_bottom_left = lc->na.cand_bottom_left;

    const int cand_left        = lc->na.cand_left;

    const int cand_up_left     = lc->na.cand_up_left;

    const int cand_up          = lc->na.cand_up;

    const int cand_up_right    = lc->na.cand_up_right_sap;

    const int xA1    = x0 - 1;

    const int yA1    = y0 + nPbH - 1;

    const int xA1_pu = xA1 >> s->sps->log2_min_pu_size;

    const int yA1_pu = yA1 >> s->sps->log2_min_pu_size;

    const int xB1    = x0 + nPbW - 1;

    const int yB1    = y0 - 1;

    const int xB1_pu = xB1 >> s->sps->log2_min_pu_size;

    const int yB1_pu = yB1 >> s->sps->log2_min_pu_size;

    const int xB0    = x0 + nPbW;

    const int yB0    = y0 - 1;

    const int xB0_pu = xB0 >> s->sps->log2_min_pu_size;

    const int yB0_pu = yB0 >> s->sps->log2_min_pu_size;

    const int xA0    = x0 - 1;

    const int yA0    = y0 + nPbH;

    const int xA0_pu = xA0 >> s->sps->log2_min_pu_size;

    const int yA0_pu = yA0 >> s->sps->log2_min_pu_size;

    const int xB2    = x0 - 1;

    const int yB2    = y0 - 1;

    const int xB2_pu = xB2 >> s->sps->log2_min_pu_size;

    const int yB2_pu = yB2 >> s->sps->log2_min_pu_size;

    const int nb_refs = (s->sh.slice_type == P_SLICE) ?

                        s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]);

    int check_MER   = 1;

    int check_MER_1 = 1;

    int zero_idx = 0;

    int nb_merge_cand = 0;

    int nb_orig_merge_cand = 0;

    int is_available_a0;

    int is_available_a1;

    int is_available_b0;

    int is_available_b1;

    int is_available_b2;

    int check_B0;

    int check_A0;

    //first left spatial merge candidate

    is_available_a1 = AVAILABLE(cand_left, A1);

    if (!singleMCLFlag && part_idx == 1 &&

        (lc->cu.part_mode == PART_Nx2N ||

         lc->cu.part_mode == PART_nLx2N ||

         lc->cu.part_mode == PART_nRx2N) ||

        isDiffMER(s, xA1, yA1, x0, y0)) {

        is_available_a1 = 0;

    }

    if (is_available_a1) {

        mergecandlist[0] = TAB_MVF_PU(A1);

        if (merge_idx == 0)

            return;

        nb_merge_cand++;

    }

    // above spatial merge candidate

    is_available_b1 = AVAILABLE(cand_up, B1);

    if (!singleMCLFlag && part_idx == 1 &&

        (lc->cu.part_mode == PART_2NxN ||

         lc->cu.part_mode == PART_2NxnU ||

         lc->cu.part_mode == PART_2NxnD) ||

        isDiffMER(s, xB1, yB1, x0, y0)) {

        is_available_b1 = 0;

    }

    if (is_available_a1 && is_available_b1)

        check_MER = !COMPARE_MV_REFIDX(B1, A1);

    if (is_available_b1 && check_MER)

        mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B1);

    // above right spatial merge candidate

    check_MER = 1;

    check_B0  = PRED_BLOCK_AVAILABLE(B0);

    is_available_b0 = check_B0 && AVAILABLE(cand_up_right, B0);

    if (isDiffMER(s, xB0, yB0, x0, y0))

        is_available_b0 = 0;

    if (is_available_b1 && is_available_b0)

        check_MER = !COMPARE_MV_REFIDX(B0, B1);

    if (is_available_b0 && check_MER) {

        mergecandlist[nb_merge_cand] = TAB_MVF_PU(B0);

        if (merge_idx == nb_merge_cand)

            return;

        nb_merge_cand++;

    }

    // left bottom spatial merge candidate

    check_MER = 1;

    check_A0  = PRED_BLOCK_AVAILABLE(A0);

    is_available_a0 = check_A0 && AVAILABLE(cand_bottom_left, A0);

    if (isDiffMER(s, xA0, yA0, x0, y0))

        is_available_a0 = 0;

    if (is_available_a1 && is_available_a0)

        check_MER = !COMPARE_MV_REFIDX(A0, A1);

    if (is_available_a0 && check_MER) {

        mergecandlist[nb_merge_cand] = TAB_MVF_PU(A0);

        if (merge_idx == nb_merge_cand)

            return;

        nb_merge_cand++;

    }

    // above left spatial merge candidate

    check_MER = 1;

    is_available_b2 = AVAILABLE(cand_up_left, B2);

    if (isDiffMER(s, xB2, yB2, x0, y0))

        is_available_b2 = 0;

    if (is_available_a1 && is_available_b2)

        check_MER = !COMPARE_MV_REFIDX(B2, A1);

    if (is_available_b1 && is_available_b2)

        check_MER_1 = !COMPARE_MV_REFIDX(B2, B1);

    if (is_available_b2 && check_MER && check_MER_1 && nb_merge_cand != 4) {

        mergecandlist[nb_merge_cand] = TAB_MVF_PU(B2);

        if (merge_idx == nb_merge_cand)

            return;

        nb_merge_cand++;

    }

    // temporal motion vector candidate

    if (s->sh.slice_temporal_mvp_enabled_flag &&

        nb_merge_cand < s->sh.max_num_merge_cand) {

        Mv mv_l0_col, mv_l1_col;

        int available_l0 = temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,

                                                       0, &mv_l0_col, 0);

        int available_l1 = (s->sh.slice_type == B_SLICE) ?

                           temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,

                                                       0, &mv_l1_col, 1) : 0;

        if (available_l0 || available_l1) {

            mergecandlist[nb_merge_cand].is_intra     = 0;

            mergecandlist[nb_merge_cand].pred_flag[0] = available_l0;

            mergecandlist[nb_merge_cand].pred_flag[1] = available_l1;

            AV_ZERO16(mergecandlist[nb_merge_cand].ref_idx);

            mergecandlist[nb_merge_cand].mv[0]      = mv_l0_col;

            mergecandlist[nb_merge_cand].mv[1]      = mv_l1_col;

            if (merge_idx == nb_merge_cand)

                return;

            nb_merge_cand++;

        }

    }

    nb_orig_merge_cand = nb_merge_cand;

    // combined bi-predictive merge candidates  (applies for B slices)

    if (s->sh.slice_type == B_SLICE && nb_orig_merge_cand > 1 &&

        nb_orig_merge_cand < s->sh.max_num_merge_cand) {

        int comb_idx;

        for (comb_idx = 0; nb_merge_cand < s->sh.max_num_merge_cand &&

                           comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) {

            int l0_cand_idx = l0_l1_cand_idx[comb_idx][0];

            int l1_cand_idx = l0_l1_cand_idx[comb_idx][1];

            MvField l0_cand = mergecandlist[l0_cand_idx];

            MvField l1_cand = mergecandlist[l1_cand_idx];

            if (l0_cand.pred_flag[0] && l1_cand.pred_flag[1] &&

                (refPicList[0].list[l0_cand.ref_idx[0]] !=

                 refPicList[1].list[l1_cand.ref_idx[1]] ||

                 AV_RN32A(&l0_cand.mv[0]) != AV_RN32A(&l1_cand.mv[1]))) {

                mergecandlist[nb_merge_cand].ref_idx[0]   = l0_cand.ref_idx[0];

                mergecandlist[nb_merge_cand].ref_idx[1]   = l1_cand.ref_idx[1];

                mergecandlist[nb_merge_cand].pred_flag[0] = 1;

                mergecandlist[nb_merge_cand].pred_flag[1] = 1;

                AV_COPY32(&mergecandlist[nb_merge_cand].mv[0], &l0_cand.mv[0]);

                AV_COPY32(&mergecandlist[nb_merge_cand].mv[1], &l1_cand.mv[1]);

                mergecandlist[nb_merge_cand].is_intra     = 0;

                if (merge_idx == nb_merge_cand)

                    return;

                nb_merge_cand++;

            }

        }

    }

    // append Zero motion vector candidates

    while (nb_merge_cand < s->sh.max_num_merge_cand) {

        mergecandlist[nb_merge_cand].pred_flag[0] = 1;

        mergecandlist[nb_merge_cand].pred_flag[1] = s->sh.slice_type == B_SLICE;

        AV_ZERO32(mergecandlist[nb_merge_cand].mv + 0);

        AV_ZERO32(mergecandlist[nb_merge_cand].mv + 1);

        mergecandlist[nb_merge_cand].is_intra     = 0;

        mergecandlist[nb_merge_cand].ref_idx[0]   = zero_idx < nb_refs ? zero_idx : 0;

        mergecandlist[nb_merge_cand].ref_idx[1]   = zero_idx < nb_refs ? zero_idx : 0;

        if (merge_idx == nb_merge_cand)

            return;

        nb_merge_cand++;

        zero_idx++;

    }

}


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

                                ptrdiff_t stride)

{

    avc_luma_midh_qrt_and_aver_dst_4w_msa(src - (2 * stride) - 2,

                                          stride, dst, stride, 4, 0);

}


static void decode_postinit(H264Context *h, int setup_finished)

{

    const SPS *sps = h->ps.sps;

    H264Picture *out = h->cur_pic_ptr;

    H264Picture *cur = h->cur_pic_ptr;

    int i, pics, out_of_order, out_idx;

    int invalid = 0, cnt = 0;

    h->cur_pic_ptr->f->pict_type = h->pict_type;

    if (h->next_output_pic)

        return;

    if (cur->field_poc[0] == INT_MAX || cur->field_poc[1] == INT_MAX) {

        /* FIXME: if we have two PAFF fields in one packet, we can't start

         * the next thread here. If we have one field per packet, we can.

         * The check in decode_nal_units() is not good enough to find this

         * yet, so we assume the worst for now. */

        // if (setup_finished)

        //    ff_thread_finish_setup(h->avctx);

        return;

    }

    cur->f->interlaced_frame = 0;

    cur->f->repeat_pict      = 0;

    /* Signal interlacing information externally. */

    /* Prioritize picture timing SEI information over used

     * decoding process if it exists. */

    if (sps->pic_struct_present_flag) {

        H264SEIPictureTiming *pt = &h->sei.picture_timing;

        switch (pt->pic_struct) {

        case SEI_PIC_STRUCT_FRAME:

            break;

        case SEI_PIC_STRUCT_TOP_FIELD:

        case SEI_PIC_STRUCT_BOTTOM_FIELD:

            cur->f->interlaced_frame = 1;

            break;

        case SEI_PIC_STRUCT_TOP_BOTTOM:

        case SEI_PIC_STRUCT_BOTTOM_TOP:

            if (FIELD_OR_MBAFF_PICTURE(h))

                cur->f->interlaced_frame = 1;

            else

                // try to flag soft telecine progressive

                cur->f->interlaced_frame = h->prev_interlaced_frame;

            break;

        case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:

        case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:

            /* Signal the possibility of telecined film externally

             * (pic_struct 5,6). From these hints, let the applications

             * decide if they apply deinterlacing. */

            cur->f->repeat_pict = 1;

            break;

        case SEI_PIC_STRUCT_FRAME_DOUBLING:

            cur->f->repeat_pict = 2;

            break;

        case SEI_PIC_STRUCT_FRAME_TRIPLING:

            cur->f->repeat_pict = 4;

            break;

        }

        if ((pt->ct_type & 3) &&

            pt->pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP)

            cur->f->interlaced_frame = (pt->ct_type & (1 << 1)) != 0;

    } else {

        /* Derive interlacing flag from used decoding process. */

        cur->f->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h);

    }

    h->prev_interlaced_frame = cur->f->interlaced_frame;

    if (cur->field_poc[0] != cur->field_poc[1]) {

        /* Derive top_field_first from field pocs. */

        cur->f->top_field_first = cur->field_poc[0] < cur->field_poc[1];

    } else {

        if (cur->f->interlaced_frame || sps->pic_struct_present_flag) {

            /* Use picture timing SEI information. Even if it is a

             * information of a past frame, better than nothing. */

            if (h->sei.picture_timing.pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM ||

                h->sei.picture_timing.pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP)

                cur->f->top_field_first = 1;

            else

                cur->f->top_field_first = 0;

        } else {

            /* Most likely progressive */

            cur->f->top_field_first = 0;

        }

    }

    if (h->sei.frame_packing.present &&

        h->sei.frame_packing.arrangement_type >= 0 &&

        h->sei.frame_packing.arrangement_type <= 6 &&

        h->sei.frame_packing.content_interpretation_type > 0 &&

        h->sei.frame_packing.content_interpretation_type < 3) {

        H264SEIFramePacking *fp = &h->sei.frame_packing;

        AVStereo3D *stereo = av_stereo3d_create_side_data(cur->f);

        if (!stereo)

            return;

        switch (fp->arrangement_type) {

        case 0:

            stereo->type = AV_STEREO3D_CHECKERBOARD;

            break;

        case 1:

            stereo->type = AV_STEREO3D_COLUMNS;

            break;

        case 2:

            stereo->type = AV_STEREO3D_LINES;

            break;

        case 3:

            if (fp->quincunx_subsampling)

                stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;

            else

                stereo->type = AV_STEREO3D_SIDEBYSIDE;

            break;

        case 4:

            stereo->type = AV_STEREO3D_TOPBOTTOM;

            break;

        case 5:

            stereo->type = AV_STEREO3D_FRAMESEQUENCE;

            break;

        case 6:

            stereo->type = AV_STEREO3D_2D;

            break;

        }

        if (fp->content_interpretation_type == 2)

            stereo->flags = AV_STEREO3D_FLAG_INVERT;

    }

    if (h->sei.display_orientation.present &&

        (h->sei.display_orientation.anticlockwise_rotation ||

         h->sei.display_orientation.hflip ||

         h->sei.display_orientation.vflip)) {

        H264SEIDisplayOrientation *o = &h->sei.display_orientation;

        double angle = o->anticlockwise_rotation * 360 / (double) (1 << 16);

        AVFrameSideData *rotation = av_frame_new_side_data(cur->f,

                                                           AV_FRAME_DATA_DISPLAYMATRIX,

                                                           sizeof(int32_t) * 9);

        if (!rotation)

            return;

        av_display_rotation_set((int32_t *)rotation->data, angle);

        av_display_matrix_flip((int32_t *)rotation->data,

                               o->hflip, o->vflip);

    }

    if (h->sei.afd.present) {

        AVFrameSideData *sd = av_frame_new_side_data(cur->f, AV_FRAME_DATA_AFD,

                                                     sizeof(uint8_t));

        if (!sd)

            return;

        *sd->data = h->sei.afd.active_format_description;

        h->sei.afd.present = 0;

    }

    if (h->sei.a53_caption.a53_caption) {

        H264SEIA53Caption *a53 = &h->sei.a53_caption;

        AVFrameSideData *sd = av_frame_new_side_data(cur->f,

                                                     AV_FRAME_DATA_A53_CC,

                                                     a53->a53_caption_size);

        if (!sd)

            return;

        memcpy(sd->data, a53->a53_caption, a53->a53_caption_size);

        av_freep(&a53->a53_caption);

        a53->a53_caption_size = 0;

    }

    // FIXME do something with unavailable reference frames

    /* Sort B-frames into display order */

    if (sps->bitstream_restriction_flag ||

        h->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {

        h->avctx->has_b_frames = FFMAX(h->avctx->has_b_frames, sps->num_reorder_frames);

    }

    h->low_delay = !h->avctx->has_b_frames;

    pics = 0;

    while (h->delayed_pic[pics])

        pics++;

    assert(pics <= MAX_DELAYED_PIC_COUNT);

    h->delayed_pic[pics++] = cur;

    if (cur->reference == 0)

        cur->reference = DELAYED_PIC_REF;

    /* Frame reordering. This code takes pictures from coding order and sorts

     * them by their incremental POC value into display order. It supports POC

     * gaps, MMCO reset codes and random resets.

     * A "display group" can start either with a IDR frame (f.key_frame = 1),

     * and/or can be closed down with a MMCO reset code. In sequences where

     * there is no delay, we can't detect that (since the frame was already

     * output to the user), so we also set h->mmco_reset to detect the MMCO

     * reset code.

     * FIXME: if we detect insufficient delays (as per h->avctx->has_b_frames),

     * we increase the delay between input and output. All frames affected by

     * the lag (e.g. those that should have been output before another frame

     * that we already returned to the user) will be dropped. This is a bug

     * that we will fix later. */

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

        cnt     += out->poc < h->last_pocs[i];

        invalid += out->poc == INT_MIN;

    }

    if (!h->mmco_reset && !cur->f->key_frame &&

        cnt + invalid == MAX_DELAYED_PIC_COUNT && cnt > 0) {

        h->mmco_reset = 2;

        if (pics > 1)

            h->delayed_pic[pics - 2]->mmco_reset = 2;

    }

    if (h->mmco_reset || cur->f->key_frame) {

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

            h->last_pocs[i] = INT_MIN;

        cnt     = 0;

        invalid = MAX_DELAYED_PIC_COUNT;

    }

    out     = h->delayed_pic[0];

    out_idx = 0;

    for (i = 1; i < MAX_DELAYED_PIC_COUNT &&

                h->delayed_pic[i] &&

                !h->delayed_pic[i - 1]->mmco_reset &&

                !h->delayed_pic[i]->f->key_frame;

         i++)

        if (h->delayed_pic[i]->poc < out->poc) {

            out     = h->delayed_pic[i];

            out_idx = i;

        }

    if (h->avctx->has_b_frames == 0 &&

        (h->delayed_pic[0]->f->key_frame || h->mmco_reset))

        h->next_outputed_poc = INT_MIN;

    out_of_order = !out->f->key_frame && !h->mmco_reset &&

                   (out->poc < h->next_outputed_poc);

    if (sps->bitstream_restriction_flag &&

        h->avctx->has_b_frames >= sps->num_reorder_frames) {

    } else if (out_of_order && pics - 1 == h->avctx->has_b_frames &&

               h->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT) {

        if (invalid + cnt < MAX_DELAYED_PIC_COUNT) {

            h->avctx->has_b_frames = FFMAX(h->avctx->has_b_frames, cnt);

        }

        h->low_delay = 0;

    } else if (h->low_delay &&

               ((h->next_outputed_poc != INT_MIN &&

                 out->poc > h->next_outputed_poc + 2) ||

                cur->f->pict_type == AV_PICTURE_TYPE_B)) {

        h->low_delay = 0;

        h->avctx->has_b_frames++;

    }

    if (pics > h->avctx->has_b_frames) {

        out->reference &= ~DELAYED_PIC_REF;

        for (i = out_idx; h->delayed_pic[i]; i++)

            h->delayed_pic[i] = h->delayed_pic[i + 1];

    }

    memmove(h->last_pocs, &h->last_pocs[1],

            sizeof(*h->last_pocs) * (MAX_DELAYED_PIC_COUNT - 1));

    h->last_pocs[MAX_DELAYED_PIC_COUNT - 1] = cur->poc;

    if (!out_of_order && pics > h->avctx->has_b_frames) {

        h->next_output_pic = out;

        if (out->mmco_reset) {

            if (out_idx > 0) {

                h->next_outputed_poc                    = out->poc;

                h->delayed_pic[out_idx - 1]->mmco_reset = out->mmco_reset;

            } else {

                h->next_outputed_poc = INT_MIN;

            }

        } else {

            if (out_idx == 0 && pics > 1 && h->delayed_pic[0]->f->key_frame) {

                h->next_outputed_poc = INT_MIN;

            } else {

                h->next_outputed_poc = out->poc;

            }

        }

        h->mmco_reset = 0;

    } else {

        av_log(h->avctx, AV_LOG_DEBUG, "no picture\n");

    }

    if (h->next_output_pic) {

        if (h->next_output_pic->recovered) {

            // We have reached an recovery point and all frames after it in

            // display order are "recovered".

            h->frame_recovered |= FRAME_RECOVERED_SEI;

        }

        h->next_output_pic->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_SEI);

    }

    if (setup_finished && !h->avctx->hwaccel) {

        ff_thread_finish_setup(h->avctx);

        if (h->avctx->active_thread_type & FF_THREAD_FRAME)

            h->setup_finished = 1;

    }

}


static int g2m_load_cursor(AVCodecContext *avctx, G2MContext *c,

                           GetByteContext *gb)

{

    int i, j, k;

    uint8_t *dst;

    uint32_t bits;

    uint32_t cur_size, cursor_w, cursor_h, cursor_stride;

    uint32_t cursor_hot_x, cursor_hot_y;

    int cursor_fmt;

    uint8_t *tmp;

    cur_size      = bytestream2_get_be32(gb);

    cursor_w      = bytestream2_get_byte(gb);

    cursor_h      = bytestream2_get_byte(gb);

    cursor_hot_x  = bytestream2_get_byte(gb);

    cursor_hot_y  = bytestream2_get_byte(gb);

    cursor_fmt    = bytestream2_get_byte(gb);

    cursor_stride = FFALIGN(cursor_w, c->cursor_fmt==1 ? 32 : 1) * 4;

    if (cursor_w < 1 || cursor_w > 256 ||

        cursor_h < 1 || cursor_h > 256) {

        av_log(avctx, AV_LOG_ERROR, "Invalid cursor dimensions %dx%d\n",

               cursor_w, cursor_h);

        return AVERROR_INVALIDDATA;

    }

    if (cursor_hot_x > cursor_w || cursor_hot_y > cursor_h) {

        av_log(avctx, AV_LOG_WARNING, "Invalid hotspot position %d,%d\n",

               cursor_hot_x, cursor_hot_y);

        cursor_hot_x = FFMIN(cursor_hot_x, cursor_w - 1);

        cursor_hot_y = FFMIN(cursor_hot_y, cursor_h - 1);

    }

    if (cur_size - 9 > bytestream2_get_bytes_left(gb) ||

        c->cursor_w * c->cursor_h / 4 > cur_size) {

        av_log(avctx, AV_LOG_ERROR, "Invalid cursor data size %d/%d\n",

               cur_size, bytestream2_get_bytes_left(gb));

        return AVERROR_INVALIDDATA;

    }

    if (cursor_fmt != 1 && cursor_fmt != 32) {

        avpriv_report_missing_feature(avctx, "Cursor format %d",

                                      cursor_fmt);

        return AVERROR_PATCHWELCOME;

    }

    tmp = av_realloc(c->cursor, cursor_stride * cursor_h);

    if (!tmp) {

        av_log(avctx, AV_LOG_ERROR, "Cannot allocate cursor buffer\n");

        return AVERROR(ENOMEM);

    }

    c->cursor        = tmp;

    c->cursor_w      = cursor_w;

    c->cursor_h      = cursor_h;

    c->cursor_hot_x  = cursor_hot_x;

    c->cursor_hot_y  = cursor_hot_y;

    c->cursor_fmt    = cursor_fmt;

    c->cursor_stride = cursor_stride;

    dst = c->cursor;

    switch (c->cursor_fmt) {

    case 1: // old monochrome

        for (j = 0; j < c->cursor_h; j++) {

            for (i = 0; i < c->cursor_w; i += 32) {

                bits = bytestream2_get_be32(gb);

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

                    dst[0] = !!(bits & 0x80000000);

                    dst += 4;

                    bits <<= 1;

                }

            }

        }

        dst = c->cursor;

        for (j = 0; j < c->cursor_h; j++) {

            for (i = 0; i < c->cursor_w; i += 32) {

                bits = bytestream2_get_be32(gb);

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

                    int mask_bit = !!(bits & 0x80000000);

                    switch (dst[0] * 2 + mask_bit) {

                    case 0:

                        dst[0] = 0xFF; dst[1] = 0x00;

                        dst[2] = 0x00; dst[3] = 0x00;

                        break;

                    case 1:

                        dst[0] = 0xFF; dst[1] = 0xFF;

                        dst[2] = 0xFF; dst[3] = 0xFF;

                        break;

                    default:

                        dst[0] = 0x00; dst[1] = 0x00;

                        dst[2] = 0x00; dst[3] = 0x00;

                    }

                    dst += 4;

                    bits <<= 1;

                }

            }

        }

        break;

    case 32: // full colour

        /* skip monochrome version of the cursor and decode RGBA instead */

        bytestream2_skip(gb, c->cursor_h * (FFALIGN(c->cursor_w, 32) >> 3));

        for (j = 0; j < c->cursor_h; j++) {

            for (i = 0; i < c->cursor_w; i++) {

                int val = bytestream2_get_be32(gb);

                *dst++ = val >>  0;

                *dst++ = val >>  8;

                *dst++ = val >> 16;

                *dst++ = val >> 24;

            }

        }

        break;

    default:

        return AVERROR_PATCHWELCOME;

    }

    return 0;

}


static int has_duration(AVFormatContext *ic)

{

    int i;

    AVStream *st;

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

        st = ic->streams[i];

        if (st->duration != AV_NOPTS_VALUE)

            return 1;

    }

    if (ic->duration)

        return 1;

    return 0;

}


void virt_acpi_setup(VirtGuestInfo *guest_info)

{

    AcpiBuildTables tables;

    AcpiBuildState *build_state;

    if (!guest_info->fw_cfg) {

        trace_virt_acpi_setup();

        return;

    }

    if (!acpi_enabled) {

        trace_virt_acpi_setup();

        return;

    }

    build_state = g_malloc0(sizeof *build_state);

    build_state->guest_info = guest_info;

    acpi_build_tables_init(&tables);

    virt_acpi_build(build_state->guest_info, &tables);

    /* Now expose it all to Guest */

    build_state->table_mr = acpi_add_rom_blob(build_state, tables.table_data,

                                               ACPI_BUILD_TABLE_FILE,

                                               ACPI_BUILD_TABLE_MAX_SIZE);

    assert(build_state->table_mr != NULL);

    build_state->linker_mr =

        acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);

    fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,

                    tables.tcpalog->data, acpi_data_len(tables.tcpalog));

    build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp,

                                              ACPI_BUILD_RSDP_FILE, 0);

    qemu_register_reset(virt_acpi_build_reset, build_state);

    virt_acpi_build_reset(build_state);

    vmstate_register(NULL, 0, &vmstate_virt_acpi_build, build_state);

    /* Cleanup tables but don't free the memory: we track it

     * in build_state.

     */

    acpi_build_tables_cleanup(&tables, false);

}


void test_fenv(void)

{

    struct __attribute__((packed)) {

        uint16_t fpuc;

        uint16_t dummy1;

        uint16_t fpus;

        uint16_t dummy2;

        uint16_t fptag;

        uint16_t dummy3;

        uint32_t ignored[4];

        long double fpregs[8];

    } float_env32;

    struct __attribute__((packed)) {

        uint16_t fpuc;

        uint16_t fpus;

        uint16_t fptag;

        uint16_t ignored[4];

        long double fpregs[8];

    } float_env16;

    double dtab[8];

    double rtab[8];

    int i;

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

        dtab[i] = i + 1;

    TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv");

    TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor");

    TEST_ENV(&float_env32, "fnstenv", "fldenv");

    TEST_ENV(&float_env32, "fnsave", "frstor");

    /* test for ffree */

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

        asm volatile ("fldl %0" : : "m" (dtab[i]));

    asm volatile("ffree %st(2)");

    asm volatile ("fnstenv %0\n" : : "m" (float_env32));

    asm volatile ("fninit");

    printf("fptag=%04x\n", float_env32.fptag);

}


static void migrate_params_apply(MigrateSetParameters *params)

{

    MigrationState *s = migrate_get_current();

    /* TODO use QAPI_CLONE() instead of duplicating it inline */

    if (params->has_compress_level) {

        s->parameters.compress_level = params->compress_level;

    }

    if (params->has_compress_threads) {

        s->parameters.compress_threads = params->compress_threads;

    }

    if (params->has_decompress_threads) {

        s->parameters.decompress_threads = params->decompress_threads;

    }

    if (params->has_cpu_throttle_initial) {

        s->parameters.cpu_throttle_initial = params->cpu_throttle_initial;

    }

    if (params->has_cpu_throttle_increment) {

        s->parameters.cpu_throttle_increment = params->cpu_throttle_increment;

    }

    if (params->has_tls_creds) {

        g_free(s->parameters.tls_creds);

        s->parameters.tls_creds = g_strdup(params->tls_creds);

    }

    if (params->has_tls_hostname) {

        g_free(s->parameters.tls_hostname);

        s->parameters.tls_hostname = g_strdup(params->tls_hostname);

    }

    if (params->has_max_bandwidth) {

        s->parameters.max_bandwidth = params->max_bandwidth;

        if (s->to_dst_file) {

            qemu_file_set_rate_limit(s->to_dst_file,

                                s->parameters.max_bandwidth / XFER_LIMIT_RATIO);

        }

    }

    if (params->has_downtime_limit) {

        s->parameters.downtime_limit = params->downtime_limit;

    }

    if (params->has_x_checkpoint_delay) {

        s->parameters.x_checkpoint_delay = params->x_checkpoint_delay;

        if (migration_in_colo_state()) {

            colo_checkpoint_notify(s);

        }

    }

    if (params->has_block_incremental) {

        s->parameters.block_incremental = params->block_incremental;

    }

}


void helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1)

{

    env->CP0_Wired = arg1 % env->tlb->nb_tlb;

}


static int multiwrite_req_compare(const void *a, const void *b)

{

    const BlockRequest *req1 = a, *req2 = b;

    /*

     * Note that we can't simply subtract req2->sector from req1->sector

     * here as that could overflow the return value.

     */

    if (req1->sector > req2->sector) {

        return 1;

    } else if (req1->sector < req2->sector) {

        return -1;

    } else {

        return 0;

    }

}