static void disas_thumb_insn(CPUState *env, DisasContext *s)

{

    uint32_t val, insn, op, rm, rn, rd, shift, cond;

    int32_t offset;

    int i;

    TCGv tmp;

    TCGv tmp2;

    TCGv addr;



    if (s->condexec_mask) {

        cond = s->condexec_cond;

        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */

          s->condlabel = gen_new_label();

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

          s->condjmp = 1;

        }

    }



    insn = lduw_code(s->pc);

    s->pc += 2;



    switch (insn >> 12) {

    case 0: case 1:



        rd = insn & 7;

        op = (insn >> 11) & 3;

        if (op == 3) {

            /* add/subtract */

            rn = (insn >> 3) & 7;

            tmp = load_reg(s, rn);

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

                /* immediate */

                tmp2 = new_tmp();

                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);

            } else {

                /* reg */

                rm = (insn >> 6) & 7;

                tmp2 = load_reg(s, rm);

            }

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

                if (s->condexec_mask)

                    tcg_gen_sub_i32(tmp, tmp, tmp2);

                else

                    gen_helper_sub_cc(tmp, tmp, tmp2);

            } else {

                if (s->condexec_mask)

                    tcg_gen_add_i32(tmp, tmp, tmp2);

                else

                    gen_helper_add_cc(tmp, tmp, tmp2);

            }

            dead_tmp(tmp2);

            store_reg(s, rd, tmp);

        } else {

            /* shift immediate */

            rm = (insn >> 3) & 7;

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

            tmp = load_reg(s, rm);

            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            store_reg(s, rd, tmp);

        }

        break;

    case 2: case 3:

        /* arithmetic large immediate */

        op = (insn >> 11) & 3;

        rd = (insn >> 8) & 0x7;

        if (op == 0) { /* mov */

            tmp = new_tmp();

            tcg_gen_movi_i32(tmp, insn & 0xff);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            store_reg(s, rd, tmp);

        } else {

            tmp = load_reg(s, rd);

            tmp2 = new_tmp();

            tcg_gen_movi_i32(tmp2, insn & 0xff);

            switch (op) {

            case 1: /* cmp */

                gen_helper_sub_cc(tmp, tmp, tmp2);

                dead_tmp(tmp);

                dead_tmp(tmp2);

                break;

            case 2: /* add */

                if (s->condexec_mask)

                    tcg_gen_add_i32(tmp, tmp, tmp2);

                else

                    gen_helper_add_cc(tmp, tmp, tmp2);

                dead_tmp(tmp2);

                store_reg(s, rd, tmp);

                break;

            case 3: /* sub */

                if (s->condexec_mask)

                    tcg_gen_sub_i32(tmp, tmp, tmp2);

                else

                    gen_helper_sub_cc(tmp, tmp, tmp2);

                dead_tmp(tmp2);

                store_reg(s, rd, tmp);

                break;

            }

        }

        break;

    case 4:

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

            rd = (insn >> 8) & 7;

            /* load pc-relative.  Bit 1 of PC is ignored.  */

            val = s->pc + 2 + ((insn & 0xff) * 4);

            val &= ~(uint32_t)2;

            addr = new_tmp();

            tcg_gen_movi_i32(addr, val);

            tmp = gen_ld32(addr, IS_USER(s));

            dead_tmp(addr);

            store_reg(s, rd, tmp);

            break;

        }

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

            /* data processing extended or blx */

            rd = (insn & 7) | ((insn >> 4) & 8);

            rm = (insn >> 3) & 0xf;

            op = (insn >> 8) & 3;

            switch (op) {

            case 0: /* add */

                tmp = load_reg(s, rd);

                tmp2 = load_reg(s, rm);

                tcg_gen_add_i32(tmp, tmp, tmp2);

                dead_tmp(tmp2);

                store_reg(s, rd, tmp);

                break;

            case 1: /* cmp */

                tmp = load_reg(s, rd);

                tmp2 = load_reg(s, rm);

                gen_helper_sub_cc(tmp, tmp, tmp2);

                dead_tmp(tmp2);

                dead_tmp(tmp);

                break;

            case 2: /* mov/cpy */

                tmp = load_reg(s, rm);

                store_reg(s, rd, tmp);

                break;

            case 3:/* branch [and link] exchange thumb register */

                tmp = load_reg(s, rm);

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

                    val = (uint32_t)s->pc | 1;

                    tmp2 = new_tmp();

                    tcg_gen_movi_i32(tmp2, val);

                    store_reg(s, 14, tmp2);

                }

                gen_bx(s, tmp);

                break;

            }

            break;

        }



        /* data processing register */

        rd = insn & 7;

        rm = (insn >> 3) & 7;

        op = (insn >> 6) & 0xf;

        if (op == 2 || op == 3 || op == 4 || op == 7) {

            /* the shift/rotate ops want the operands backwards */

            val = rm;

            rm = rd;

            rd = val;

            val = 1;

        } else {

            val = 0;

        }



        if (op == 9) { /* neg */

            tmp = new_tmp();

            tcg_gen_movi_i32(tmp, 0);

        } else if (op != 0xf) { /* mvn doesn't read its first operand */

            tmp = load_reg(s, rd);

        } else {

            TCGV_UNUSED(tmp);

        }



        tmp2 = load_reg(s, rm);

        switch (op) {

        case 0x0: /* and */

            tcg_gen_and_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0x1: /* eor */

            tcg_gen_xor_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0x2: /* lsl */

            if (s->condexec_mask) {

                gen_helper_shl(tmp2, tmp2, tmp);

            } else {

                gen_helper_shl_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x3: /* lsr */

            if (s->condexec_mask) {

                gen_helper_shr(tmp2, tmp2, tmp);

            } else {

                gen_helper_shr_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x4: /* asr */

            if (s->condexec_mask) {

                gen_helper_sar(tmp2, tmp2, tmp);

            } else {

                gen_helper_sar_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x5: /* adc */

            if (s->condexec_mask)

                gen_adc(tmp, tmp2);

            else

                gen_helper_adc_cc(tmp, tmp, tmp2);

            break;

        case 0x6: /* sbc */

            if (s->condexec_mask)

                gen_sub_carry(tmp, tmp, tmp2);

            else

                gen_helper_sbc_cc(tmp, tmp, tmp2);

            break;

        case 0x7: /* ror */

            if (s->condexec_mask) {

                tcg_gen_andi_i32(tmp, tmp, 0x1f);

                tcg_gen_rotr_i32(tmp2, tmp2, tmp);

            } else {

                gen_helper_ror_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x8: /* tst */

            tcg_gen_and_i32(tmp, tmp, tmp2);

            gen_logic_CC(tmp);

            rd = 16;

            break;

        case 0x9: /* neg */

            if (s->condexec_mask)

                tcg_gen_neg_i32(tmp, tmp2);

            else

                gen_helper_sub_cc(tmp, tmp, tmp2);

            break;

        case 0xa: /* cmp */

            gen_helper_sub_cc(tmp, tmp, tmp2);

            rd = 16;

            break;

        case 0xb: /* cmn */

            gen_helper_add_cc(tmp, tmp, tmp2);

            rd = 16;

            break;

        case 0xc: /* orr */

            tcg_gen_or_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xd: /* mul */

            tcg_gen_mul_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xe: /* bic */

            tcg_gen_andc_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xf: /* mvn */

            tcg_gen_not_i32(tmp2, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp2);

            val = 1;

            rm = rd;

            break;

        }

        if (rd != 16) {

            if (val) {

                store_reg(s, rm, tmp2);

                if (op != 0xf)

                    dead_tmp(tmp);

            } else {

                store_reg(s, rd, tmp);

                dead_tmp(tmp2);

            }

        } else {

            dead_tmp(tmp);

            dead_tmp(tmp2);

        }

        break;



    case 5:

        /* load/store register offset.  */

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        rm = (insn >> 6) & 7;

        op = (insn >> 9) & 7;

        addr = load_reg(s, rn);

        tmp = load_reg(s, rm);

        tcg_gen_add_i32(addr, addr, tmp);

        dead_tmp(tmp);



        if (op < 3) /* store */

            tmp = load_reg(s, rd);



        switch (op) {

        case 0: /* str */

            gen_st32(tmp, addr, IS_USER(s));

            break;

        case 1: /* strh */

            gen_st16(tmp, addr, IS_USER(s));

            break;

        case 2: /* strb */

            gen_st8(tmp, addr, IS_USER(s));

            break;

        case 3: /* ldrsb */

            tmp = gen_ld8s(addr, IS_USER(s));

            break;

        case 4: /* ldr */

            tmp = gen_ld32(addr, IS_USER(s));

            break;

        case 5: /* ldrh */

            tmp = gen_ld16u(addr, IS_USER(s));

            break;

        case 6: /* ldrb */

            tmp = gen_ld8u(addr, IS_USER(s));

            break;

        case 7: /* ldrsh */

            tmp = gen_ld16s(addr, IS_USER(s));

            break;

        }

        if (op >= 3) /* load */

            store_reg(s, rd, tmp);

        dead_tmp(addr);

        break;



    case 6:

        /* load/store word immediate offset */

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(s, rn);

        val = (insn >> 4) & 0x7c;

        tcg_gen_addi_i32(addr, addr, val);



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

            /* load */

            tmp = gen_ld32(addr, IS_USER(s));

            store_reg(s, rd, tmp);

        } else {

            /* store */

            tmp = load_reg(s, rd);

            gen_st32(tmp, addr, IS_USER(s));

        }

        dead_tmp(addr);

        break;



    case 7:

        /* load/store byte immediate offset */

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(s, rn);

        val = (insn >> 6) & 0x1f;

        tcg_gen_addi_i32(addr, addr, val);



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

            /* load */

            tmp = gen_ld8u(addr, IS_USER(s));

            store_reg(s, rd, tmp);

        } else {

            /* store */

            tmp = load_reg(s, rd);

            gen_st8(tmp, addr, IS_USER(s));

        }

        dead_tmp(addr);

        break;



    case 8:

        /* load/store halfword immediate offset */

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(s, rn);

        val = (insn >> 5) & 0x3e;

        tcg_gen_addi_i32(addr, addr, val);



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

            /* load */

            tmp = gen_ld16u(addr, IS_USER(s));

            store_reg(s, rd, tmp);

        } else {

            /* store */

            tmp = load_reg(s, rd);

            gen_st16(tmp, addr, IS_USER(s));

        }

        dead_tmp(addr);

        break;



    case 9:

        /* load/store from stack */

        rd = (insn >> 8) & 7;

        addr = load_reg(s, 13);

        val = (insn & 0xff) * 4;

        tcg_gen_addi_i32(addr, addr, val);



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

            /* load */

            tmp = gen_ld32(addr, IS_USER(s));

            store_reg(s, rd, tmp);

        } else {

            /* store */

            tmp = load_reg(s, rd);

            gen_st32(tmp, addr, IS_USER(s));

        }

        dead_tmp(addr);

        break;



    case 10:

        /* add to high reg */

        rd = (insn >> 8) & 7;

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

            /* SP */

            tmp = load_reg(s, 13);

        } else {

            /* PC. bit 1 is ignored.  */

            tmp = new_tmp();

            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);

        }

        val = (insn & 0xff) * 4;

        tcg_gen_addi_i32(tmp, tmp, val);

        store_reg(s, rd, tmp);

        break;



    case 11:

        /* misc */

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

        switch (op) {

        case 0:

            /* adjust stack pointer */

            tmp = load_reg(s, 13);

            val = (insn & 0x7f) * 4;

            if (insn & (1 << 7))

                val = -(int32_t)val;

            tcg_gen_addi_i32(tmp, tmp, val);

            store_reg(s, 13, tmp);

            break;



        case 2: /* sign/zero extend.  */

            ARCH(6);

            rd = insn & 7;

            rm = (insn >> 3) & 7;

            tmp = load_reg(s, rm);

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

            case 0: gen_sxth(tmp); break;

            case 1: gen_sxtb(tmp); break;

            case 2: gen_uxth(tmp); break;

            case 3: gen_uxtb(tmp); break;

            }

            store_reg(s, rd, tmp);

            break;

        case 4: case 5: case 0xc: case 0xd:

            /* push/pop */

            addr = load_reg(s, 13);

            if (insn & (1 << 8))

                offset = 4;

            else

                offset = 0;

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

                if (insn & (1 << i))

                    offset += 4;

            }

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

                tcg_gen_addi_i32(addr, addr, -offset);

            }

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

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

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

                        /* pop */

                        tmp = gen_ld32(addr, IS_USER(s));

                        store_reg(s, i, tmp);

                    } else {

                        /* push */

                        tmp = load_reg(s, i);

                        gen_st32(tmp, addr, IS_USER(s));

                    }

                    /* advance to the next address.  */

                    tcg_gen_addi_i32(addr, addr, 4);

                }

            }

            TCGV_UNUSED(tmp);

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

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

                    /* pop pc */

                    tmp = gen_ld32(addr, IS_USER(s));

                    /* don't set the pc until the rest of the instruction

                       has completed */

                } else {

                    /* push lr */

                    tmp = load_reg(s, 14);

                    gen_st32(tmp, addr, IS_USER(s));

                }

                tcg_gen_addi_i32(addr, addr, 4);

            }

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

                tcg_gen_addi_i32(addr, addr, -offset);

            }

            /* write back the new stack pointer */

            store_reg(s, 13, addr);

            /* set the new PC value */

            if ((insn & 0x0900) == 0x0900)

                gen_bx(s, tmp);

            break;



        case 1: case 3: case 9: case 11: /* czb */

            rm = insn & 7;

            tmp = load_reg(s, rm);

            s->condlabel = gen_new_label();

            s->condjmp = 1;

            if (insn & (1 << 11))

                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);

            else

                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);

            dead_tmp(tmp);

            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;

            val = (uint32_t)s->pc + 2;

            val += offset;

            gen_jmp(s, val);

            break;



        case 15: /* IT, nop-hint.  */

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

                gen_nop_hint(s, (insn >> 4) & 0xf);

                break;

            }

            /* If Then.  */

            s->condexec_cond = (insn >> 4) & 0xe;

            s->condexec_mask = insn & 0x1f;

            /* No actual code generated for this insn, just setup state.  */

            break;



        case 0xe: /* bkpt */

            gen_exception_insn(s, 2, EXCP_BKPT);

            break;



        case 0xa: /* rev */

            ARCH(6);

            rn = (insn >> 3) & 0x7;

            rd = insn & 0x7;

            tmp = load_reg(s, rn);

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

            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;

            case 1: gen_rev16(tmp); break;

            case 3: gen_revsh(tmp); break;

            default: goto illegal_op;

            }

            store_reg(s, rd, tmp);

            break;



        case 6: /* cps */

            ARCH(6);

            if (IS_USER(s))

                break;

            if (IS_M(env)) {

                tmp = tcg_const_i32((insn & (1 << 4)) != 0);

                /* PRIMASK */

                if (insn & 1) {

                    addr = tcg_const_i32(16);

                    gen_helper_v7m_msr(cpu_env, addr, tmp);

                    tcg_temp_free_i32(addr);

                }

                /* FAULTMASK */

                if (insn & 2) {

                    addr = tcg_const_i32(17);

                    gen_helper_v7m_msr(cpu_env, addr, tmp);

                    tcg_temp_free_i32(addr);

                }

                tcg_temp_free_i32(tmp);

                gen_lookup_tb(s);

            } else {

                if (insn & (1 << 4))

                    shift = CPSR_A | CPSR_I | CPSR_F;

                else

                    shift = 0;

                gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);

            }

            break;



        default:

            goto undef;

        }

        break;



    case 12:

        /* load/store multiple */

        rn = (insn >> 8) & 0x7;

        addr = load_reg(s, rn);

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

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

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

                    /* load */

                    tmp = gen_ld32(addr, IS_USER(s));

                    store_reg(s, i, tmp);

                } else {

                    /* store */

                    tmp = load_reg(s, i);

                    gen_st32(tmp, addr, IS_USER(s));

                }

                /* advance to the next address */

                tcg_gen_addi_i32(addr, addr, 4);

            }

        }

        /* Base register writeback.  */

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

            store_reg(s, rn, addr);

        } else {

            dead_tmp(addr);

        }

        break;



    case 13:

        /* conditional branch or swi */

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

        if (cond == 0xe)

            goto undef;



        if (cond == 0xf) {

            /* swi */

            gen_set_pc_im(s->pc);

            s->is_jmp = DISAS_SWI;

            break;

        }

        /* generate a conditional jump to next instruction */

        s->condlabel = gen_new_label();

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

        s->condjmp = 1;



        /* jump to the offset */

        val = (uint32_t)s->pc + 2;

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

        val += offset << 1;

        gen_jmp(s, val);

        break;



    case 14:

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

            if (disas_thumb2_insn(env, s, insn))

              goto undef32;

            break;

        }

        /* unconditional branch */

        val = (uint32_t)s->pc;

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

        val += (offset << 1) + 2;

        gen_jmp(s, val);

        break;



    case 15:

        if (disas_thumb2_insn(env, s, insn))

            goto undef32;

        break;

    }

    return;

undef32:

    gen_exception_insn(s, 4, EXCP_UDEF);

    return;

illegal_op:

undef:

    gen_exception_insn(s, 2, EXCP_UDEF);

}

static void disas_thumb_insn(CPUState *env, DisasContext *s)

{

    uint32_t val, insn, op, rm, rn, rd, shift, cond;

    int32_t offset;

    int i;

    TCGv tmp;

    TCGv tmp2;

    TCGv addr;



    if (s->condexec_mask) {

        cond = s->condexec_cond;

        if (cond != 0x0e) {     

          s->condlabel = gen_new_label();

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

          s->condjmp = 1;

        }

    }



    insn = lduw_code(s->pc);

    s->pc += 2;



    switch (insn >> 12) {

    case 0: case 1:



        rd = insn & 7;

        op = (insn >> 11) & 3;

        if (op == 3) {

            

            rn = (insn >> 3) & 7;

            tmp = load_reg(s, rn);

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

                

                tmp2 = new_tmp();

                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);

            } else {

                

                rm = (insn >> 6) & 7;

                tmp2 = load_reg(s, rm);

            }

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

                if (s->condexec_mask)

                    tcg_gen_sub_i32(tmp, tmp, tmp2);

                else

                    gen_helper_sub_cc(tmp, tmp, tmp2);

            } else {

                if (s->condexec_mask)

                    tcg_gen_add_i32(tmp, tmp, tmp2);

                else

                    gen_helper_add_cc(tmp, tmp, tmp2);

            }

            dead_tmp(tmp2);

            store_reg(s, rd, tmp);

        } else {

            

            rm = (insn >> 3) & 7;

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

            tmp = load_reg(s, rm);

            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            store_reg(s, rd, tmp);

        }

        break;

    case 2: case 3:

        

        op = (insn >> 11) & 3;

        rd = (insn >> 8) & 0x7;

        if (op == 0) { 

            tmp = new_tmp();

            tcg_gen_movi_i32(tmp, insn & 0xff);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            store_reg(s, rd, tmp);

        } else {

            tmp = load_reg(s, rd);

            tmp2 = new_tmp();

            tcg_gen_movi_i32(tmp2, insn & 0xff);

            switch (op) {

            case 1: 

                gen_helper_sub_cc(tmp, tmp, tmp2);

                dead_tmp(tmp);

                dead_tmp(tmp2);

                break;

            case 2: 

                if (s->condexec_mask)

                    tcg_gen_add_i32(tmp, tmp, tmp2);

                else

                    gen_helper_add_cc(tmp, tmp, tmp2);

                dead_tmp(tmp2);

                store_reg(s, rd, tmp);

                break;

            case 3: 

                if (s->condexec_mask)

                    tcg_gen_sub_i32(tmp, tmp, tmp2);

                else

                    gen_helper_sub_cc(tmp, tmp, tmp2);

                dead_tmp(tmp2);

                store_reg(s, rd, tmp);

                break;

            }

        }

        break;

    case 4:

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

            rd = (insn >> 8) & 7;

            

            val = s->pc + 2 + ((insn & 0xff) * 4);

            val &= ~(uint32_t)2;

            addr = new_tmp();

            tcg_gen_movi_i32(addr, val);

            tmp = gen_ld32(addr, IS_USER(s));

            dead_tmp(addr);

            store_reg(s, rd, tmp);

            break;

        }

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

            

            rd = (insn & 7) | ((insn >> 4) & 8);

            rm = (insn >> 3) & 0xf;

            op = (insn >> 8) & 3;

            switch (op) {

            case 0: 

                tmp = load_reg(s, rd);

                tmp2 = load_reg(s, rm);

                tcg_gen_add_i32(tmp, tmp, tmp2);

                dead_tmp(tmp2);

                store_reg(s, rd, tmp);

                break;

            case 1: 

                tmp = load_reg(s, rd);

                tmp2 = load_reg(s, rm);

                gen_helper_sub_cc(tmp, tmp, tmp2);

                dead_tmp(tmp2);

                dead_tmp(tmp);

                break;

            case 2: 

                tmp = load_reg(s, rm);

                store_reg(s, rd, tmp);

                break;

            case 3:

                tmp = load_reg(s, rm);

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

                    val = (uint32_t)s->pc | 1;

                    tmp2 = new_tmp();

                    tcg_gen_movi_i32(tmp2, val);

                    store_reg(s, 14, tmp2);

                }

                gen_bx(s, tmp);

                break;

            }

            break;

        }



        

        rd = insn & 7;

        rm = (insn >> 3) & 7;

        op = (insn >> 6) & 0xf;

        if (op == 2 || op == 3 || op == 4 || op == 7) {

            

            val = rm;

            rm = rd;

            rd = val;

            val = 1;

        } else {

            val = 0;

        }



        if (op == 9) { 

            tmp = new_tmp();

            tcg_gen_movi_i32(tmp, 0);

        } else if (op != 0xf) { 

            tmp = load_reg(s, rd);

        } else {

            TCGV_UNUSED(tmp);

        }



        tmp2 = load_reg(s, rm);

        switch (op) {

        case 0x0: 

            tcg_gen_and_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0x1: 

            tcg_gen_xor_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0x2: 

            if (s->condexec_mask) {

                gen_helper_shl(tmp2, tmp2, tmp);

            } else {

                gen_helper_shl_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x3: 

            if (s->condexec_mask) {

                gen_helper_shr(tmp2, tmp2, tmp);

            } else {

                gen_helper_shr_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x4: 

            if (s->condexec_mask) {

                gen_helper_sar(tmp2, tmp2, tmp);

            } else {

                gen_helper_sar_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x5: 

            if (s->condexec_mask)

                gen_adc(tmp, tmp2);

            else

                gen_helper_adc_cc(tmp, tmp, tmp2);

            break;

        case 0x6: 

            if (s->condexec_mask)

                gen_sub_carry(tmp, tmp, tmp2);

            else

                gen_helper_sbc_cc(tmp, tmp, tmp2);

            break;

        case 0x7: 

            if (s->condexec_mask) {

                tcg_gen_andi_i32(tmp, tmp, 0x1f);

                tcg_gen_rotr_i32(tmp2, tmp2, tmp);

            } else {

                gen_helper_ror_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x8: 

            tcg_gen_and_i32(tmp, tmp, tmp2);

            gen_logic_CC(tmp);

            rd = 16;

            break;

        case 0x9: 

            if (s->condexec_mask)

                tcg_gen_neg_i32(tmp, tmp2);

            else

                gen_helper_sub_cc(tmp, tmp, tmp2);

            break;

        case 0xa: 

            gen_helper_sub_cc(tmp, tmp, tmp2);

            rd = 16;

            break;

        case 0xb: 

            gen_helper_add_cc(tmp, tmp, tmp2);

            rd = 16;

            break;

        case 0xc: 

            tcg_gen_or_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xd: 

            tcg_gen_mul_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xe: 

            tcg_gen_andc_i32(tmp, tmp, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xf: 

            tcg_gen_not_i32(tmp2, tmp2);

            if (!s->condexec_mask)

                gen_logic_CC(tmp2);

            val = 1;

            rm = rd;

            break;

        }

        if (rd != 16) {

            if (val) {

                store_reg(s, rm, tmp2);

                if (op != 0xf)

                    dead_tmp(tmp);

            } else {

                store_reg(s, rd, tmp);

                dead_tmp(tmp2);

            }

        } else {

            dead_tmp(tmp);

            dead_tmp(tmp2);

        }

        break;



    case 5:

        

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        rm = (insn >> 6) & 7;

        op = (insn >> 9) & 7;

        addr = load_reg(s, rn);

        tmp = load_reg(s, rm);

        tcg_gen_add_i32(addr, addr, tmp);

        dead_tmp(tmp);



        if (op < 3) 

            tmp = load_reg(s, rd);



        switch (op) {

        case 0: 

            gen_st32(tmp, addr, IS_USER(s));

            break;

        case 1: 

            gen_st16(tmp, addr, IS_USER(s));

            break;

        case 2: 

            gen_st8(tmp, addr, IS_USER(s));

            break;

        case 3: 

            tmp = gen_ld8s(addr, IS_USER(s));

            break;

        case 4: 

            tmp = gen_ld32(addr, IS_USER(s));

            break;

        case 5: 

            tmp = gen_ld16u(addr, IS_USER(s));

            break;

        case 6: 

            tmp = gen_ld8u(addr, IS_USER(s));

            break;

        case 7: 

            tmp = gen_ld16s(addr, IS_USER(s));

            break;

        }

        if (op >= 3) 

            store_reg(s, rd, tmp);

        dead_tmp(addr);

        break;



    case 6:

        

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(s, rn);

        val = (insn >> 4) & 0x7c;

        tcg_gen_addi_i32(addr, addr, val);



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

            

            tmp = gen_ld32(addr, IS_USER(s));

            store_reg(s, rd, tmp);

        } else {

            

            tmp = load_reg(s, rd);

            gen_st32(tmp, addr, IS_USER(s));

        }

        dead_tmp(addr);

        break;



    case 7:

        

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(s, rn);

        val = (insn >> 6) & 0x1f;

        tcg_gen_addi_i32(addr, addr, val);



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

            

            tmp = gen_ld8u(addr, IS_USER(s));

            store_reg(s, rd, tmp);

        } else {

            

            tmp = load_reg(s, rd);

            gen_st8(tmp, addr, IS_USER(s));

        }

        dead_tmp(addr);

        break;



    case 8:

        

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(s, rn);

        val = (insn >> 5) & 0x3e;

        tcg_gen_addi_i32(addr, addr, val);



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

            

            tmp = gen_ld16u(addr, IS_USER(s));

            store_reg(s, rd, tmp);

        } else {

            

            tmp = load_reg(s, rd);

            gen_st16(tmp, addr, IS_USER(s));

        }

        dead_tmp(addr);

        break;



    case 9:

        

        rd = (insn >> 8) & 7;

        addr = load_reg(s, 13);

        val = (insn & 0xff) * 4;

        tcg_gen_addi_i32(addr, addr, val);



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

            

            tmp = gen_ld32(addr, IS_USER(s));

            store_reg(s, rd, tmp);

        } else {

            

            tmp = load_reg(s, rd);

            gen_st32(tmp, addr, IS_USER(s));

        }

        dead_tmp(addr);

        break;



    case 10:

        

        rd = (insn >> 8) & 7;

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

            

            tmp = load_reg(s, 13);

        } else {

            

            tmp = new_tmp();

            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);

        }

        val = (insn & 0xff) * 4;

        tcg_gen_addi_i32(tmp, tmp, val);

        store_reg(s, rd, tmp);

        break;



    case 11:

        

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

        switch (op) {

        case 0:

            

            tmp = load_reg(s, 13);

            val = (insn & 0x7f) * 4;

            if (insn & (1 << 7))

                val = -(int32_t)val;

            tcg_gen_addi_i32(tmp, tmp, val);

            store_reg(s, 13, tmp);

            break;



        case 2: 

            ARCH(6);

            rd = insn & 7;

            rm = (insn >> 3) & 7;

            tmp = load_reg(s, rm);

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

            case 0: gen_sxth(tmp); break;

            case 1: gen_sxtb(tmp); break;

            case 2: gen_uxth(tmp); break;

            case 3: gen_uxtb(tmp); break;

            }

            store_reg(s, rd, tmp);

            break;

        case 4: case 5: case 0xc: case 0xd:

            

            addr = load_reg(s, 13);

            if (insn & (1 << 8))

                offset = 4;

            else

                offset = 0;

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

                if (insn & (1 << i))

                    offset += 4;

            }

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

                tcg_gen_addi_i32(addr, addr, -offset);

            }

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

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

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

                        

                        tmp = gen_ld32(addr, IS_USER(s));

                        store_reg(s, i, tmp);

                    } else {

                        

                        tmp = load_reg(s, i);

                        gen_st32(tmp, addr, IS_USER(s));

                    }

                    

                    tcg_gen_addi_i32(addr, addr, 4);

                }

            }

            TCGV_UNUSED(tmp);

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

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

                    

                    tmp = gen_ld32(addr, IS_USER(s));

                    



                } else {

                    

                    tmp = load_reg(s, 14);

                    gen_st32(tmp, addr, IS_USER(s));

                }

                tcg_gen_addi_i32(addr, addr, 4);

            }

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

                tcg_gen_addi_i32(addr, addr, -offset);

            }

            

            store_reg(s, 13, addr);

            

            if ((insn & 0x0900) == 0x0900)

                gen_bx(s, tmp);

            break;



        case 1: case 3: case 9: case 11: 

            rm = insn & 7;

            tmp = load_reg(s, rm);

            s->condlabel = gen_new_label();

            s->condjmp = 1;

            if (insn & (1 << 11))

                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);

            else

                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);

            dead_tmp(tmp);

            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;

            val = (uint32_t)s->pc + 2;

            val += offset;

            gen_jmp(s, val);

            break;



        case 15: 

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

                gen_nop_hint(s, (insn >> 4) & 0xf);

                break;

            }

            

            s->condexec_cond = (insn >> 4) & 0xe;

            s->condexec_mask = insn & 0x1f;

            

            break;



        case 0xe: 

            gen_exception_insn(s, 2, EXCP_BKPT);

            break;



        case 0xa: 

            ARCH(6);

            rn = (insn >> 3) & 0x7;

            rd = insn & 0x7;

            tmp = load_reg(s, rn);

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

            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;

            case 1: gen_rev16(tmp); break;

            case 3: gen_revsh(tmp); break;

            default: goto illegal_op;

            }

            store_reg(s, rd, tmp);

            break;



        case 6: 

            ARCH(6);

            if (IS_USER(s))

                break;

            if (IS_M(env)) {

                tmp = tcg_const_i32((insn & (1 << 4)) != 0);

                

                if (insn & 1) {

                    addr = tcg_const_i32(16);

                    gen_helper_v7m_msr(cpu_env, addr, tmp);

                    tcg_temp_free_i32(addr);

                }

                

                if (insn & 2) {

                    addr = tcg_const_i32(17);

                    gen_helper_v7m_msr(cpu_env, addr, tmp);

                    tcg_temp_free_i32(addr);

                }

                tcg_temp_free_i32(tmp);

                gen_lookup_tb(s);

            } else {

                if (insn & (1 << 4))

                    shift = CPSR_A | CPSR_I | CPSR_F;

                else

                    shift = 0;

                gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);

            }

            break;



        default:

            goto undef;

        }

        break;



    case 12:

        

        rn = (insn >> 8) & 0x7;

        addr = load_reg(s, rn);

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

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

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

                    

                    tmp = gen_ld32(addr, IS_USER(s));

                    store_reg(s, i, tmp);

                } else {

                    

                    tmp = load_reg(s, i);

                    gen_st32(tmp, addr, IS_USER(s));

                }

                

                tcg_gen_addi_i32(addr, addr, 4);

            }

        }

        

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

            store_reg(s, rn, addr);

        } else {

            dead_tmp(addr);

        }

        break;



    case 13:

        

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

        if (cond == 0xe)

            goto undef;



        if (cond == 0xf) {

            

            gen_set_pc_im(s->pc);

            s->is_jmp = DISAS_SWI;

            break;

        }

        

        s->condlabel = gen_new_label();

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

        s->condjmp = 1;



        

        val = (uint32_t)s->pc + 2;

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

        val += offset << 1;

        gen_jmp(s, val);

        break;



    case 14:

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

            if (disas_thumb2_insn(env, s, insn))

              goto undef32;

            break;

        }

        

        val = (uint32_t)s->pc;

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

        val += (offset << 1) + 2;

        gen_jmp(s, val);

        break;



    case 15:

        if (disas_thumb2_insn(env, s, insn))

            goto undef32;

        break;

    }

    return;

undef32:

    gen_exception_insn(s, 4, EXCP_UDEF);

    return;

illegal_op:

undef:

    gen_exception_insn(s, 2, EXCP_UDEF);

}

            dead_tmp(tmp);         dead_tmp(tmp);         dead_tmp(tmp);         dead_tmp(tmp);         dead_tmp(tmp);         dead_tmp(tmp);             dead_tmp(tmp);             dead_tmp(addr);                     dead_tmp(tmp);         dead_tmp(addr);             dead_tmp(tmp2);         dead_tmp(tmp);         dead_tmp(tmp);         dead_tmp(tmp);         dead_tmp(tmp);         dead_tmp(tmp);         dead_tmp(tmp);             dead_tmp(tmp);         dead_tmp(tmp);             dead_tmp(tmp);         dead_tmp(tmp);             dead_tmp(tmp);         dead_tmp(tmp);                 dead_tmp(tmp);                 dead_tmp(tmp);                 dead_tmp(tmp);         dead_tmp(tmp);             dead_tmp(tmp2);             dead_tmp(tmp);         dead_tmp(tmp);         dead_tmp(tmp);         dead_tmp(tmp);             dead_tmp(tmp);             dead_tmp(tmp);         dead_tmp(tmp);                 tmp2 = new_tmp();             dead_tmp(tmp2);             dead_tmp(tmp2);                 dead_tmp(tmp2);                     tmp2 = new_tmp();                     tmp2 = new_tmp();                     dead_tmp(tmp);                     dead_tmp(tmp);                 dead_tmp(tmp);                 dead_tmp(tmp);                     tmp2 = new_tmp();                 dead_tmp(tmp);             dead_tmp(tmp);         dead_tmp(tmp);             addr = new_tmp();             tmp = new_tmp();             tmp2 = new_tmp();             dead_tmp(tmp2);                 dead_tmp(tmp2);                     dead_tmp(tmp);             tmp2 = new_tmp();             dead_tmp(tmp);             dead_tmp(tmp);             dead_tmp(tmp);             dead_tmp(tmp);             dead_tmp(tmp2);                 dead_tmp(tmp2);                     dead_tmp(tmp);             tmp2 = new_tmp();             tmp2 = new_tmp();                     dead_tmp(tmp);                     dead_tmp(tmp);             dead_tmp(tmp2);             dead_tmp(tmp2);                 dead_tmp(tmp);             dead_tmp(tmp2);                 dead_tmp(tmp2);                 dead_tmp(tmp2);                 dead_tmp(tmp2);                 dead_tmp(tmp2);                 dead_tmp(tmp2);                 dead_tmp(tmp2);                 dead_tmp(tmp2);                 dead_tmp(tmp);                 tmp2 = new_tmp();                 dead_tmp(tmp2);                     dead_tmp(tmp);             addr = new_tmp();                     dead_tmp(tmp);             dead_tmp(addr);                 tmp2 = new_tmp();             dead_tmp(tmp2);             tmp = new_tmp();             tmp2 = new_tmp();                 dead_tmp(tmp);                 dead_tmp(tmp2);                 dead_tmp(tmp2);                 dead_tmp(tmp2);             addr = new_tmp();             dead_tmp(addr);                 dead_tmp(tmp2);                 dead_tmp(tmp2);                 dead_tmp(tmp);                     tmp2 = new_tmp();             tmp = new_tmp();                     dead_tmp(tmp);                 dead_tmp(tmp2);             dead_tmp(tmp);             dead_tmp(tmp2);         dead_tmp(tmp);         dead_tmp(addr);         dead_tmp(addr);         dead_tmp(addr);         dead_tmp(addr);         dead_tmp(addr);             tmp = new_tmp();             dead_tmp(tmp);             dead_tmp(addr);
static void FUNC_0(CPUState *VAR_0, DisasContext *VAR_1)

{

    uint32_t val, insn, op, rm, rn, rd, shift, cond;

    int32_t offset;

    int VAR_2;

    TCGv tmp;

    TCGv tmp2;

    TCGv addr;



    if (VAR_1->condexec_mask) {

        cond = VAR_1->condexec_cond;

        if (cond != 0x0e) {     

          VAR_1->condlabel = gen_new_label();

          gen_test_cc(cond ^ 1, VAR_1->condlabel);

          VAR_1->condjmp = 1;

        }

    }



    insn = lduw_code(VAR_1->pc);

    VAR_1->pc += 2;



    switch (insn >> 12) {

    case 0: case 1:



        rd = insn & 7;

        op = (insn >> 11) & 3;

        if (op == 3) {

            

            rn = (insn >> 3) & 7;

            tmp = load_reg(VAR_1, rn);

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

                

                tmp2 = new_tmp();

                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);

            } else {

                

                rm = (insn >> 6) & 7;

                tmp2 = load_reg(VAR_1, rm);

            }

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

                if (VAR_1->condexec_mask)

                    tcg_gen_sub_i32(tmp, tmp, tmp2);

                else

                    gen_helper_sub_cc(tmp, tmp, tmp2);

            } else {

                if (VAR_1->condexec_mask)

                    tcg_gen_add_i32(tmp, tmp, tmp2);

                else

                    gen_helper_add_cc(tmp, tmp, tmp2);

            }

            dead_tmp(tmp2);

            store_reg(VAR_1, rd, tmp);

        } else {

            

            rm = (insn >> 3) & 7;

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

            tmp = load_reg(VAR_1, rm);

            gen_arm_shift_im(tmp, op, shift, VAR_1->condexec_mask == 0);

            if (!VAR_1->condexec_mask)

                gen_logic_CC(tmp);

            store_reg(VAR_1, rd, tmp);

        }

        break;

    case 2: case 3:

        

        op = (insn >> 11) & 3;

        rd = (insn >> 8) & 0x7;

        if (op == 0) { 

            tmp = new_tmp();

            tcg_gen_movi_i32(tmp, insn & 0xff);

            if (!VAR_1->condexec_mask)

                gen_logic_CC(tmp);

            store_reg(VAR_1, rd, tmp);

        } else {

            tmp = load_reg(VAR_1, rd);

            tmp2 = new_tmp();

            tcg_gen_movi_i32(tmp2, insn & 0xff);

            switch (op) {

            case 1: 

                gen_helper_sub_cc(tmp, tmp, tmp2);

                dead_tmp(tmp);

                dead_tmp(tmp2);

                break;

            case 2: 

                if (VAR_1->condexec_mask)

                    tcg_gen_add_i32(tmp, tmp, tmp2);

                else

                    gen_helper_add_cc(tmp, tmp, tmp2);

                dead_tmp(tmp2);

                store_reg(VAR_1, rd, tmp);

                break;

            case 3: 

                if (VAR_1->condexec_mask)

                    tcg_gen_sub_i32(tmp, tmp, tmp2);

                else

                    gen_helper_sub_cc(tmp, tmp, tmp2);

                dead_tmp(tmp2);

                store_reg(VAR_1, rd, tmp);

                break;

            }

        }

        break;

    case 4:

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

            rd = (insn >> 8) & 7;

            

            val = VAR_1->pc + 2 + ((insn & 0xff) * 4);

            val &= ~(uint32_t)2;

            addr = new_tmp();

            tcg_gen_movi_i32(addr, val);

            tmp = gen_ld32(addr, IS_USER(VAR_1));

            dead_tmp(addr);

            store_reg(VAR_1, rd, tmp);

            break;

        }

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

            

            rd = (insn & 7) | ((insn >> 4) & 8);

            rm = (insn >> 3) & 0xf;

            op = (insn >> 8) & 3;

            switch (op) {

            case 0: 

                tmp = load_reg(VAR_1, rd);

                tmp2 = load_reg(VAR_1, rm);

                tcg_gen_add_i32(tmp, tmp, tmp2);

                dead_tmp(tmp2);

                store_reg(VAR_1, rd, tmp);

                break;

            case 1: 

                tmp = load_reg(VAR_1, rd);

                tmp2 = load_reg(VAR_1, rm);

                gen_helper_sub_cc(tmp, tmp, tmp2);

                dead_tmp(tmp2);

                dead_tmp(tmp);

                break;

            case 2: 

                tmp = load_reg(VAR_1, rm);

                store_reg(VAR_1, rd, tmp);

                break;

            case 3:

                tmp = load_reg(VAR_1, rm);

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

                    val = (uint32_t)VAR_1->pc | 1;

                    tmp2 = new_tmp();

                    tcg_gen_movi_i32(tmp2, val);

                    store_reg(VAR_1, 14, tmp2);

                }

                gen_bx(VAR_1, tmp);

                break;

            }

            break;

        }



        

        rd = insn & 7;

        rm = (insn >> 3) & 7;

        op = (insn >> 6) & 0xf;

        if (op == 2 || op == 3 || op == 4 || op == 7) {

            

            val = rm;

            rm = rd;

            rd = val;

            val = 1;

        } else {

            val = 0;

        }



        if (op == 9) { 

            tmp = new_tmp();

            tcg_gen_movi_i32(tmp, 0);

        } else if (op != 0xf) { 

            tmp = load_reg(VAR_1, rd);

        } else {

            TCGV_UNUSED(tmp);

        }



        tmp2 = load_reg(VAR_1, rm);

        switch (op) {

        case 0x0: 

            tcg_gen_and_i32(tmp, tmp, tmp2);

            if (!VAR_1->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0x1: 

            tcg_gen_xor_i32(tmp, tmp, tmp2);

            if (!VAR_1->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0x2: 

            if (VAR_1->condexec_mask) {

                gen_helper_shl(tmp2, tmp2, tmp);

            } else {

                gen_helper_shl_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x3: 

            if (VAR_1->condexec_mask) {

                gen_helper_shr(tmp2, tmp2, tmp);

            } else {

                gen_helper_shr_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x4: 

            if (VAR_1->condexec_mask) {

                gen_helper_sar(tmp2, tmp2, tmp);

            } else {

                gen_helper_sar_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x5: 

            if (VAR_1->condexec_mask)

                gen_adc(tmp, tmp2);

            else

                gen_helper_adc_cc(tmp, tmp, tmp2);

            break;

        case 0x6: 

            if (VAR_1->condexec_mask)

                gen_sub_carry(tmp, tmp, tmp2);

            else

                gen_helper_sbc_cc(tmp, tmp, tmp2);

            break;

        case 0x7: 

            if (VAR_1->condexec_mask) {

                tcg_gen_andi_i32(tmp, tmp, 0x1f);

                tcg_gen_rotr_i32(tmp2, tmp2, tmp);

            } else {

                gen_helper_ror_cc(tmp2, tmp2, tmp);

                gen_logic_CC(tmp2);

            }

            break;

        case 0x8: 

            tcg_gen_and_i32(tmp, tmp, tmp2);

            gen_logic_CC(tmp);

            rd = 16;

            break;

        case 0x9: 

            if (VAR_1->condexec_mask)

                tcg_gen_neg_i32(tmp, tmp2);

            else

                gen_helper_sub_cc(tmp, tmp, tmp2);

            break;

        case 0xa: 

            gen_helper_sub_cc(tmp, tmp, tmp2);

            rd = 16;

            break;

        case 0xb: 

            gen_helper_add_cc(tmp, tmp, tmp2);

            rd = 16;

            break;

        case 0xc: 

            tcg_gen_or_i32(tmp, tmp, tmp2);

            if (!VAR_1->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xd: 

            tcg_gen_mul_i32(tmp, tmp, tmp2);

            if (!VAR_1->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xe: 

            tcg_gen_andc_i32(tmp, tmp, tmp2);

            if (!VAR_1->condexec_mask)

                gen_logic_CC(tmp);

            break;

        case 0xf: 

            tcg_gen_not_i32(tmp2, tmp2);

            if (!VAR_1->condexec_mask)

                gen_logic_CC(tmp2);

            val = 1;

            rm = rd;

            break;

        }

        if (rd != 16) {

            if (val) {

                store_reg(VAR_1, rm, tmp2);

                if (op != 0xf)

                    dead_tmp(tmp);

            } else {

                store_reg(VAR_1, rd, tmp);

                dead_tmp(tmp2);

            }

        } else {

            dead_tmp(tmp);

            dead_tmp(tmp2);

        }

        break;



    case 5:

        

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        rm = (insn >> 6) & 7;

        op = (insn >> 9) & 7;

        addr = load_reg(VAR_1, rn);

        tmp = load_reg(VAR_1, rm);

        tcg_gen_add_i32(addr, addr, tmp);

        dead_tmp(tmp);



        if (op < 3) 

            tmp = load_reg(VAR_1, rd);



        switch (op) {

        case 0: 

            gen_st32(tmp, addr, IS_USER(VAR_1));

            break;

        case 1: 

            gen_st16(tmp, addr, IS_USER(VAR_1));

            break;

        case 2: 

            gen_st8(tmp, addr, IS_USER(VAR_1));

            break;

        case 3: 

            tmp = gen_ld8s(addr, IS_USER(VAR_1));

            break;

        case 4: 

            tmp = gen_ld32(addr, IS_USER(VAR_1));

            break;

        case 5: 

            tmp = gen_ld16u(addr, IS_USER(VAR_1));

            break;

        case 6: 

            tmp = gen_ld8u(addr, IS_USER(VAR_1));

            break;

        case 7: 

            tmp = gen_ld16s(addr, IS_USER(VAR_1));

            break;

        }

        if (op >= 3) 

            store_reg(VAR_1, rd, tmp);

        dead_tmp(addr);

        break;



    case 6:

        

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(VAR_1, rn);

        val = (insn >> 4) & 0x7c;

        tcg_gen_addi_i32(addr, addr, val);



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

            

            tmp = gen_ld32(addr, IS_USER(VAR_1));

            store_reg(VAR_1, rd, tmp);

        } else {

            

            tmp = load_reg(VAR_1, rd);

            gen_st32(tmp, addr, IS_USER(VAR_1));

        }

        dead_tmp(addr);

        break;



    case 7:

        

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(VAR_1, rn);

        val = (insn >> 6) & 0x1f;

        tcg_gen_addi_i32(addr, addr, val);



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

            

            tmp = gen_ld8u(addr, IS_USER(VAR_1));

            store_reg(VAR_1, rd, tmp);

        } else {

            

            tmp = load_reg(VAR_1, rd);

            gen_st8(tmp, addr, IS_USER(VAR_1));

        }

        dead_tmp(addr);

        break;



    case 8:

        

        rd = insn & 7;

        rn = (insn >> 3) & 7;

        addr = load_reg(VAR_1, rn);

        val = (insn >> 5) & 0x3e;

        tcg_gen_addi_i32(addr, addr, val);



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

            

            tmp = gen_ld16u(addr, IS_USER(VAR_1));

            store_reg(VAR_1, rd, tmp);

        } else {

            

            tmp = load_reg(VAR_1, rd);

            gen_st16(tmp, addr, IS_USER(VAR_1));

        }

        dead_tmp(addr);

        break;



    case 9:

        

        rd = (insn >> 8) & 7;

        addr = load_reg(VAR_1, 13);

        val = (insn & 0xff) * 4;

        tcg_gen_addi_i32(addr, addr, val);



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

            

            tmp = gen_ld32(addr, IS_USER(VAR_1));

            store_reg(VAR_1, rd, tmp);

        } else {

            

            tmp = load_reg(VAR_1, rd);

            gen_st32(tmp, addr, IS_USER(VAR_1));

        }

        dead_tmp(addr);

        break;



    case 10:

        

        rd = (insn >> 8) & 7;

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

            

            tmp = load_reg(VAR_1, 13);

        } else {

            

            tmp = new_tmp();

            tcg_gen_movi_i32(tmp, (VAR_1->pc + 2) & ~(uint32_t)2);

        }

        val = (insn & 0xff) * 4;

        tcg_gen_addi_i32(tmp, tmp, val);

        store_reg(VAR_1, rd, tmp);

        break;



    case 11:

        

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

        switch (op) {

        case 0:

            

            tmp = load_reg(VAR_1, 13);

            val = (insn & 0x7f) * 4;

            if (insn & (1 << 7))

                val = -(int32_t)val;

            tcg_gen_addi_i32(tmp, tmp, val);

            store_reg(VAR_1, 13, tmp);

            break;



        case 2: 

            ARCH(6);

            rd = insn & 7;

            rm = (insn >> 3) & 7;

            tmp = load_reg(VAR_1, rm);

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

            case 0: gen_sxth(tmp); break;

            case 1: gen_sxtb(tmp); break;

            case 2: gen_uxth(tmp); break;

            case 3: gen_uxtb(tmp); break;

            }

            store_reg(VAR_1, rd, tmp);

            break;

        case 4: case 5: case 0xc: case 0xd:

            

            addr = load_reg(VAR_1, 13);

            if (insn & (1 << 8))

                offset = 4;

            else

                offset = 0;

            for (VAR_2 = 0; VAR_2 < 8; VAR_2++) {

                if (insn & (1 << VAR_2))

                    offset += 4;

            }

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

                tcg_gen_addi_i32(addr, addr, -offset);

            }

            for (VAR_2 = 0; VAR_2 < 8; VAR_2++) {

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

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

                        

                        tmp = gen_ld32(addr, IS_USER(VAR_1));

                        store_reg(VAR_1, VAR_2, tmp);

                    } else {

                        

                        tmp = load_reg(VAR_1, VAR_2);

                        gen_st32(tmp, addr, IS_USER(VAR_1));

                    }

                    

                    tcg_gen_addi_i32(addr, addr, 4);

                }

            }

            TCGV_UNUSED(tmp);

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

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

                    

                    tmp = gen_ld32(addr, IS_USER(VAR_1));

                    



                } else {

                    

                    tmp = load_reg(VAR_1, 14);

                    gen_st32(tmp, addr, IS_USER(VAR_1));

                }

                tcg_gen_addi_i32(addr, addr, 4);

            }

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

                tcg_gen_addi_i32(addr, addr, -offset);

            }

            

            store_reg(VAR_1, 13, addr);

            

            if ((insn & 0x0900) == 0x0900)

                gen_bx(VAR_1, tmp);

            break;



        case 1: case 3: case 9: case 11: 

            rm = insn & 7;

            tmp = load_reg(VAR_1, rm);

            VAR_1->condlabel = gen_new_label();

            VAR_1->condjmp = 1;

            if (insn & (1 << 11))

                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, VAR_1->condlabel);

            else

                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, VAR_1->condlabel);

            dead_tmp(tmp);

            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;

            val = (uint32_t)VAR_1->pc + 2;

            val += offset;

            gen_jmp(VAR_1, val);

            break;



        case 15: 

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

                gen_nop_hint(VAR_1, (insn >> 4) & 0xf);

                break;

            }

            

            VAR_1->condexec_cond = (insn >> 4) & 0xe;

            VAR_1->condexec_mask = insn & 0x1f;

            

            break;



        case 0xe: 

            gen_exception_insn(VAR_1, 2, EXCP_BKPT);

            break;



        case 0xa: 

            ARCH(6);

            rn = (insn >> 3) & 0x7;

            rd = insn & 0x7;

            tmp = load_reg(VAR_1, rn);

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

            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;

            case 1: gen_rev16(tmp); break;

            case 3: gen_revsh(tmp); break;

            default: goto illegal_op;

            }

            store_reg(VAR_1, rd, tmp);

            break;



        case 6: 

            ARCH(6);

            if (IS_USER(VAR_1))

                break;

            if (IS_M(VAR_0)) {

                tmp = tcg_const_i32((insn & (1 << 4)) != 0);

                

                if (insn & 1) {

                    addr = tcg_const_i32(16);

                    gen_helper_v7m_msr(cpu_env, addr, tmp);

                    tcg_temp_free_i32(addr);

                }

                

                if (insn & 2) {

                    addr = tcg_const_i32(17);

                    gen_helper_v7m_msr(cpu_env, addr, tmp);

                    tcg_temp_free_i32(addr);

                }

                tcg_temp_free_i32(tmp);

                gen_lookup_tb(VAR_1);

            } else {

                if (insn & (1 << 4))

                    shift = CPSR_A | CPSR_I | CPSR_F;

                else

                    shift = 0;

                gen_set_psr_im(VAR_1, ((insn & 7) << 6), 0, shift);

            }

            break;



        default:

            goto undef;

        }

        break;



    case 12:

        

        rn = (insn >> 8) & 0x7;

        addr = load_reg(VAR_1, rn);

        for (VAR_2 = 0; VAR_2 < 8; VAR_2++) {

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

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

                    

                    tmp = gen_ld32(addr, IS_USER(VAR_1));

                    store_reg(VAR_1, VAR_2, tmp);

                } else {

                    

                    tmp = load_reg(VAR_1, VAR_2);

                    gen_st32(tmp, addr, IS_USER(VAR_1));

                }

                

                tcg_gen_addi_i32(addr, addr, 4);

            }

        }

        

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

            store_reg(VAR_1, rn, addr);

        } else {

            dead_tmp(addr);

        }

        break;



    case 13:

        

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

        if (cond == 0xe)

            goto undef;



        if (cond == 0xf) {

            

            gen_set_pc_im(VAR_1->pc);

            VAR_1->is_jmp = DISAS_SWI;

            break;

        }

        

        VAR_1->condlabel = gen_new_label();

        gen_test_cc(cond ^ 1, VAR_1->condlabel);

        VAR_1->condjmp = 1;



        

        val = (uint32_t)VAR_1->pc + 2;

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

        val += offset << 1;

        gen_jmp(VAR_1, val);

        break;



    case 14:

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

            if (disas_thumb2_insn(VAR_0, VAR_1, insn))

              goto undef32;

            break;

        }

        

        val = (uint32_t)VAR_1->pc;

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

        val += (offset << 1) + 2;

        gen_jmp(VAR_1, val);

        break;



    case 15:

        if (disas_thumb2_insn(VAR_0, VAR_1, insn))

            goto undef32;

        break;

    }

    return;

undef32:

    gen_exception_insn(VAR_1, 4, EXCP_UDEF);

    return;

illegal_op:

undef:

    gen_exception_insn(VAR_1, 2, EXCP_UDEF);

}

static void FUNC_0(CPUState *VAR_0, DisasContext *VAR_1)
{ uint32_t val, insn, op, rm, rn, rd, shift, cond; int32_t offset; int VAR_2; TCGv tmp; TCGv tmp2; TCGv addr; if (VAR_1->condexec_mask) { cond = VAR_1->condexec_cond; if (cond != 0x0e) { VAR_1->condlabel = gen_new_label(); gen_test_cc(cond ^ 1, VAR_1->condlabel); VAR_1->condjmp = 1; } } insn = lduw_code(VAR_1->pc); VAR_1->pc += 2; switch (insn >> 12) { case 0: case 1:
rd = insn & 7; op = (insn >> 11) & 3; if (op == 3) { rn = (insn >> 3) & 7; tmp = load_reg(VAR_1, rn); if (insn & (1 << 10)) { tmp2 = new_tmp(); tcg_gen_movi_i32(tmp2, (insn >> 6) & 7); } else { rm = (insn >> 6) & 7; tmp2 = load_reg(VAR_1, rm); } if (insn & (1 << 9)) { if (VAR_1->condexec_mask)
tcg_gen_sub_i32(tmp, tmp, tmp2); else
gen_helper_sub_cc(tmp, tmp, tmp2); } else { if (VAR_1->condexec_mask)
tcg_gen_add_i32(tmp, tmp, tmp2); else
gen_helper_add_cc(tmp, tmp, tmp2); } dead_tmp(tmp2); store_reg(VAR_1, rd, tmp); } else { rm = (insn >> 3) & 7; shift = (insn >> 6) & 0x1f; tmp = load_reg(VAR_1, rm); gen_arm_shift_im(tmp, op, shift, VAR_1->condexec_mask == 0); if (!VAR_1->condexec_mask)
gen_logic_CC(tmp); store_reg(VAR_1, rd, tmp); } break; case 2: case 3:
op = (insn >> 11) & 3; rd = (insn >> 8) & 0x7; if (op == 0) { tmp = new_tmp(); tcg_gen_movi_i32(tmp, insn & 0xff); if (!VAR_1->condexec_mask)
gen_logic_CC(tmp); store_reg(VAR_1, rd, tmp); } else { tmp = load_reg(VAR_1, rd); tmp2 = new_tmp(); tcg_gen_movi_i32(tmp2, insn & 0xff); switch (op) { case 1:
gen_helper_sub_cc(tmp, tmp, tmp2); dead_tmp(tmp); dead_tmp(tmp2); break; case 2:
if (VAR_1->condexec_mask)
tcg_gen_add_i32(tmp, tmp, tmp2); else
gen_helper_add_cc(tmp, tmp, tmp2); dead_tmp(tmp2); store_reg(VAR_1, rd, tmp); break; case 3:
if (VAR_1->condexec_mask)
tcg_gen_sub_i32(tmp, tmp, tmp2); else
gen_helper_sub_cc(tmp, tmp, tmp2); dead_tmp(tmp2); store_reg(VAR_1, rd, tmp); break; } } break; case 4:
if (insn & (1 << 11)) { rd = (insn >> 8) & 7; val = VAR_1->pc + 2 + ((insn & 0xff) * 4); val &= ~(uint32_t)2; addr = new_tmp(); tcg_gen_movi_i32(addr, val); tmp = gen_ld32(addr, IS_USER(VAR_1)); dead_tmp(addr); store_reg(VAR_1, rd, tmp); break; } if (insn & (1 << 10)) { rd = (insn & 7) | ((insn >> 4) & 8); rm = (insn >> 3) & 0xf; op = (insn >> 8) & 3; switch (op) { case 0:
tmp = load_reg(VAR_1, rd); tmp2 = load_reg(VAR_1, rm); tcg_gen_add_i32(tmp, tmp, tmp2); dead_tmp(tmp2); store_reg(VAR_1, rd, tmp); break; case 1:
tmp = load_reg(VAR_1, rd); tmp2 = load_reg(VAR_1, rm); gen_helper_sub_cc(tmp, tmp, tmp2); dead_tmp(tmp2); dead_tmp(tmp); break; case 2:
tmp = load_reg(VAR_1, rm); store_reg(VAR_1, rd, tmp); break; case 3:
tmp = load_reg(VAR_1, rm); if (insn & (1 << 7)) { val = (uint32_t)VAR_1->pc | 1; tmp2 = new_tmp(); tcg_gen_movi_i32(tmp2, val); store_reg(VAR_1, 14, tmp2); } gen_bx(VAR_1, tmp); break; } break; } rd = insn & 7; rm = (insn >> 3) & 7; op = (insn >> 6) & 0xf; if (op == 2 || op == 3 || op == 4 || op == 7) { val = rm; rm = rd; rd = val; val = 1; } else { val = 0; } if (op == 9) { tmp = new_tmp(); tcg_gen_movi_i32(tmp, 0); } else if (op != 0xf) { tmp = load_reg(VAR_1, rd); } else { TCGV_UNUSED(tmp); } tmp2 = load_reg(VAR_1, rm); switch (op) { case 0x0:
tcg_gen_and_i32(tmp, tmp, tmp2); if (!VAR_1->condexec_mask)
gen_logic_CC(tmp); break; case 0x1:
tcg_gen_xor_i32(tmp, tmp, tmp2); if (!VAR_1->condexec_mask)
gen_logic_CC(tmp); break; case 0x2:
if (VAR_1->condexec_mask) { gen_helper_shl(tmp2, tmp2, tmp); } else { gen_helper_shl_cc(tmp2, tmp2, tmp); gen_logic_CC(tmp2); } break; case 0x3:
if (VAR_1->condexec_mask) { gen_helper_shr(tmp2, tmp2, tmp); } else { gen_helper_shr_cc(tmp2, tmp2, tmp); gen_logic_CC(tmp2); } break; case 0x4:
if (VAR_1->condexec_mask) { gen_helper_sar(tmp2, tmp2, tmp); } else { gen_helper_sar_cc(tmp2, tmp2, tmp); gen_logic_CC(tmp2); } break; case 0x5:
if (VAR_1->condexec_mask)
gen_adc(tmp, tmp2); else
gen_helper_adc_cc(tmp, tmp, tmp2); break; case 0x6:
if (VAR_1->condexec_mask)
gen_sub_carry(tmp, tmp, tmp2); else
gen_helper_sbc_cc(tmp, tmp, tmp2); break; case 0x7:
if (VAR_1->condexec_mask) { tcg_gen_andi_i32(tmp, tmp, 0x1f); tcg_gen_rotr_i32(tmp2, tmp2, tmp); } else { gen_helper_ror_cc(tmp2, tmp2, tmp); gen_logic_CC(tmp2); } break; case 0x8:
tcg_gen_and_i32(tmp, tmp, tmp2); gen_logic_CC(tmp); rd = 16; break; case 0x9:
if (VAR_1->condexec_mask)
tcg_gen_neg_i32(tmp, tmp2); else
gen_helper_sub_cc(tmp, tmp, tmp2); break; case 0xa:
gen_helper_sub_cc(tmp, tmp, tmp2); rd = 16; break; case 0xb:
gen_helper_add_cc(tmp, tmp, tmp2); rd = 16; break; case 0xc:
tcg_gen_or_i32(tmp, tmp, tmp2); if (!VAR_1->condexec_mask)
gen_logic_CC(tmp); break; case 0xd:
tcg_gen_mul_i32(tmp, tmp, tmp2); if (!VAR_1->condexec_mask)
gen_logic_CC(tmp); break; case 0xe:
tcg_gen_andc_i32(tmp, tmp, tmp2); if (!VAR_1->condexec_mask)
gen_logic_CC(tmp); break; case 0xf:
tcg_gen_not_i32(tmp2, tmp2); if (!VAR_1->condexec_mask)
gen_logic_CC(tmp2); val = 1; rm = rd; break; } if (rd != 16) { if (val) { store_reg(VAR_1, rm, tmp2); if (op != 0xf)
dead_tmp(tmp); } else { store_reg(VAR_1, rd, tmp); dead_tmp(tmp2); } } else { dead_tmp(tmp); dead_tmp(tmp2); } break; case 5:
rd = insn & 7; rn = (insn >> 3) & 7; rm = (insn >> 6) & 7; op = (insn >> 9) & 7; addr = load_reg(VAR_1, rn); tmp = load_reg(VAR_1, rm); tcg_gen_add_i32(addr, addr, tmp); dead_tmp(tmp); if (op < 3)
tmp = load_reg(VAR_1, rd); switch (op) { case 0:
gen_st32(tmp, addr, IS_USER(VAR_1)); break; case 1:
gen_st16(tmp, addr, IS_USER(VAR_1)); break; case 2:
gen_st8(tmp, addr, IS_USER(VAR_1)); break; case 3:
tmp = gen_ld8s(addr, IS_USER(VAR_1)); break; case 4:
tmp = gen_ld32(addr, IS_USER(VAR_1)); break; case 5:
tmp = gen_ld16u(addr, IS_USER(VAR_1)); break; case 6:
tmp = gen_ld8u(addr, IS_USER(VAR_1)); break; case 7:
tmp = gen_ld16s(addr, IS_USER(VAR_1)); break; } if (op >= 3)
store_reg(VAR_1, rd, tmp); dead_tmp(addr); break; case 6:
rd = insn & 7; rn = (insn >> 3) & 7; addr = load_reg(VAR_1, rn); val = (insn >> 4) & 0x7c; tcg_gen_addi_i32(addr, addr, val); if (insn & (1 << 11)) { tmp = gen_ld32(addr, IS_USER(VAR_1)); store_reg(VAR_1, rd, tmp); } else { tmp = load_reg(VAR_1, rd); gen_st32(tmp, addr, IS_USER(VAR_1)); } dead_tmp(addr); break; case 7:
rd = insn & 7; rn = (insn >> 3) & 7; addr = load_reg(VAR_1, rn); val = (insn >> 6) & 0x1f; tcg_gen_addi_i32(addr, addr, val); if (insn & (1 << 11)) { tmp = gen_ld8u(addr, IS_USER(VAR_1)); store_reg(VAR_1, rd, tmp); } else { tmp = load_reg(VAR_1, rd); gen_st8(tmp, addr, IS_USER(VAR_1)); } dead_tmp(addr); break; case 8:
rd = insn & 7; rn = (insn >> 3) & 7; addr = load_reg(VAR_1, rn); val = (insn >> 5) & 0x3e; tcg_gen_addi_i32(addr, addr, val); if (insn & (1 << 11)) { tmp = gen_ld16u(addr, IS_USER(VAR_1)); store_reg(VAR_1, rd, tmp); } else { tmp = load_reg(VAR_1, rd); gen_st16(tmp, addr, IS_USER(VAR_1)); } dead_tmp(addr); break; case 9:
rd = (insn >> 8) & 7; addr = load_reg(VAR_1, 13); val = (insn & 0xff) * 4; tcg_gen_addi_i32(addr, addr, val); if (insn & (1 << 11)) { tmp = gen_ld32(addr, IS_USER(VAR_1)); store_reg(VAR_1, rd, tmp); } else { tmp = load_reg(VAR_1, rd); gen_st32(tmp, addr, IS_USER(VAR_1)); } dead_tmp(addr); break; case 10:
rd = (insn >> 8) & 7; if (insn & (1 << 11)) { tmp = load_reg(VAR_1, 13); } else { tmp = new_tmp(); tcg_gen_movi_i32(tmp, (VAR_1->pc + 2) & ~(uint32_t)2); } val = (insn & 0xff) * 4; tcg_gen_addi_i32(tmp, tmp, val); store_reg(VAR_1, rd, tmp); break; case 11:
op = (insn >> 8) & 0xf; switch (op) { case 0:
tmp = load_reg(VAR_1, 13); val = (insn & 0x7f) * 4; if (insn & (1 << 7))
val = -(int32_t)val; tcg_gen_addi_i32(tmp, tmp, val); store_reg(VAR_1, 13, tmp); break; case 2:
ARCH(6); rd = insn & 7; rm = (insn >> 3) & 7; tmp = load_reg(VAR_1, rm); switch ((insn >> 6) & 3) { case 0: gen_sxth(tmp); break; case 1: gen_sxtb(tmp); break; case 2: gen_uxth(tmp); break; case 3: gen_uxtb(tmp); break; } store_reg(VAR_1, rd, tmp); break; case 4: case 5: case 0xc: case 0xd:
addr = load_reg(VAR_1, 13); if (insn & (1 << 8))
offset = 4; else
offset = 0; for (VAR_2 = 0; VAR_2 < 8; VAR_2++) { if (insn & (1 << VAR_2))
offset += 4; } if ((insn & (1 << 11)) == 0) { tcg_gen_addi_i32(addr, addr, -offset); } for (VAR_2 = 0; VAR_2 < 8; VAR_2++) { if (insn & (1 << VAR_2)) { if (insn & (1 << 11)) { tmp = gen_ld32(addr, IS_USER(VAR_1)); store_reg(VAR_1, VAR_2, tmp); } else { tmp = load_reg(VAR_1, VAR_2); gen_st32(tmp, addr, IS_USER(VAR_1)); } tcg_gen_addi_i32(addr, addr, 4); } } TCGV_UNUSED(tmp); if (insn & (1 << 8)) { if (insn & (1 << 11)) { tmp = gen_ld32(addr, IS_USER(VAR_1)); } else { tmp = load_reg(VAR_1, 14); gen_st32(tmp, addr, IS_USER(VAR_1)); } tcg_gen_addi_i32(addr, addr, 4); } if ((insn & (1 << 11)) == 0) { tcg_gen_addi_i32(addr, addr, -offset); } store_reg(VAR_1, 13, addr); if ((insn & 0x0900) == 0x0900)
gen_bx(VAR_1, tmp); break; case 1: case 3: case 9: case 11:
rm = insn & 7; tmp = load_reg(VAR_1, rm); VAR_1->condlabel = gen_new_label(); VAR_1->condjmp = 1; if (insn & (1 << 11))
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, VAR_1->condlabel); else
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, VAR_1->condlabel); dead_tmp(tmp); offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3; val = (uint32_t)VAR_1->pc + 2; val += offset; gen_jmp(VAR_1, val); break; case 15:
if ((insn & 0xf) == 0) { gen_nop_hint(VAR_1, (insn >> 4) & 0xf); break; } VAR_1->condexec_cond = (insn >> 4) & 0xe; VAR_1->condexec_mask = insn & 0x1f; break; case 0xe:
gen_exception_insn(VAR_1, 2, EXCP_BKPT); break; case 0xa:
ARCH(6); rn = (insn >> 3) & 0x7; rd = insn & 0x7; tmp = load_reg(VAR_1, rn); switch ((insn >> 6) & 3) { case 0: tcg_gen_bswap32_i32(tmp, tmp); break; case 1: gen_rev16(tmp); break; case 3: gen_revsh(tmp); break; default: goto illegal_op; } store_reg(VAR_1, rd, tmp); break; case 6:
ARCH(6); if (IS_USER(VAR_1))
break; if (IS_M(VAR_0)) { tmp = tcg_const_i32((insn & (1 << 4)) != 0); if (insn & 1) { addr = tcg_const_i32(16); gen_helper_v7m_msr(cpu_env, addr, tmp); tcg_temp_free_i32(addr); } if (insn & 2) { addr = tcg_const_i32(17); gen_helper_v7m_msr(cpu_env, addr, tmp); tcg_temp_free_i32(addr); } tcg_temp_free_i32(tmp); gen_lookup_tb(VAR_1); } else { if (insn & (1 << 4))
shift = CPSR_A | CPSR_I | CPSR_F; else
shift = 0; gen_set_psr_im(VAR_1, ((insn & 7) << 6), 0, shift); } break; default:
goto undef; } break; case 12:
rn = (insn >> 8) & 0x7; addr = load_reg(VAR_1, rn); for (VAR_2 = 0; VAR_2 < 8; VAR_2++) { if (insn & (1 << VAR_2)) { if (insn & (1 << 11)) { tmp = gen_ld32(addr, IS_USER(VAR_1)); store_reg(VAR_1, VAR_2, tmp); } else { tmp = load_reg(VAR_1, VAR_2); gen_st32(tmp, addr, IS_USER(VAR_1)); } tcg_gen_addi_i32(addr, addr, 4); } } if ((insn & (1 << rn)) == 0) { store_reg(VAR_1, rn, addr); } else { dead_tmp(addr); } break; case 13:
cond = (insn >> 8) & 0xf; if (cond == 0xe)
goto undef; if (cond == 0xf) { gen_set_pc_im(VAR_1->pc); VAR_1->is_jmp = DISAS_SWI; break; } VAR_1->condlabel = gen_new_label(); gen_test_cc(cond ^ 1, VAR_1->condlabel); VAR_1->condjmp = 1; val = (uint32_t)VAR_1->pc + 2; offset = ((int32_t)insn << 24) >> 24; val += offset << 1; gen_jmp(VAR_1, val); break; case 14:
if (insn & (1 << 11)) { if (disas_thumb2_insn(VAR_0, VAR_1, insn))
goto undef32; break; } val = (uint32_t)VAR_1->pc; offset = ((int32_t)insn << 21) >> 21; val += (offset << 1) + 2; gen_jmp(VAR_1, val); break; case 15:
if (disas_thumb2_insn(VAR_0, VAR_1, insn))
goto undef32; break; } return; undef32:
gen_exception_insn(VAR_1, 4, EXCP_UDEF); return; illegal_op:
undef:
gen_exception_insn(VAR_1, 2, EXCP_UDEF); }