cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

translate_v10.c.inc (43553B)


      1/*
      2 *  CRISv10 emulation for qemu: main translation routines.
      3 *
      4 *  Copyright (c) 2010 AXIS Communications AB
      5 *  Written by Edgar E. Iglesias.
      6 *
      7 * This library is free software; you can redistribute it and/or
      8 * modify it under the terms of the GNU Lesser General Public
      9 * License as published by the Free Software Foundation; either
     10 * version 2.1 of the License, or (at your option) any later version.
     11 *
     12 * This library is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15 * Lesser General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU Lesser General Public
     18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     19 */
     20
     21#include "qemu/osdep.h"
     22#include "crisv10-decode.h"
     23
     24static const char * const regnames_v10[] =
     25{
     26    "$r0", "$r1", "$r2", "$r3",
     27    "$r4", "$r5", "$r6", "$r7",
     28    "$r8", "$r9", "$r10", "$r11",
     29    "$r12", "$r13", "$sp", "$pc",
     30};
     31
     32static const char * const pregnames_v10[] =
     33{
     34    "$bz", "$vr", "$p2", "$p3",
     35    "$wz", "$ccr", "$p6-prefix", "$mof",
     36    "$dz", "$ibr", "$irp", "$srp",
     37    "$bar", "$dccr", "$brp", "$usp",
     38};
     39
     40/* We need this table to handle preg-moves with implicit width.  */
     41static const int preg_sizes_v10[] = {
     42    1, /* bz.  */
     43    1, /* vr.  */
     44    1, /* pid. */
     45    1, /* srs. */
     46    2, /* wz.  */
     47    2, 2, 4,
     48    4, 4, 4, 4,
     49    4, 4, 4, 4,
     50};
     51
     52static inline int dec10_size(unsigned int size)
     53{
     54    size++;
     55    if (size == 3)
     56        size++;
     57    return size;
     58}
     59
     60static inline void cris_illegal_insn(DisasContext *dc)
     61{
     62    qemu_log_mask(LOG_GUEST_ERROR, "illegal insn at pc=%x\n", dc->pc);
     63    t_gen_raise_exception(EXCP_BREAK);
     64    dc->base.is_jmp = DISAS_NORETURN;
     65}
     66
     67static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val,
     68                       unsigned int size, int mem_index)
     69{
     70    TCGLabel *l1 = gen_new_label();
     71    TCGv taddr = tcg_temp_local_new();
     72    TCGv tval = tcg_temp_local_new();
     73    TCGv t1 = tcg_temp_local_new();
     74    dc->postinc = 0;
     75    cris_evaluate_flags(dc);
     76
     77    tcg_gen_mov_tl(taddr, addr);
     78    tcg_gen_mov_tl(tval, val);
     79
     80    /* Store only if F flag isn't set */
     81    tcg_gen_andi_tl(t1, cpu_PR[PR_CCS], F_FLAG_V10);
     82    tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
     83    if (size == 1) {
     84        tcg_gen_qemu_st8(tval, taddr, mem_index);
     85    } else if (size == 2) {
     86        tcg_gen_qemu_st16(tval, taddr, mem_index);
     87    } else {
     88        tcg_gen_qemu_st32(tval, taddr, mem_index);
     89    }
     90    gen_set_label(l1);
     91    tcg_gen_shri_tl(t1, t1, 1);  /* shift F to P position */
     92    tcg_gen_or_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], t1); /*P=F*/
     93    tcg_temp_free(t1);
     94    tcg_temp_free(tval);
     95    tcg_temp_free(taddr);
     96}
     97
     98static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val,
     99                       unsigned int size)
    100{
    101    int mem_index = cpu_mmu_index(&dc->cpu->env, false);
    102
    103    /* If we get a fault on a delayslot we must keep the jmp state in
    104       the cpu-state to be able to re-execute the jmp.  */
    105    if (dc->delayed_branch == 1) {
    106        cris_store_direct_jmp(dc);
    107    }
    108
    109    /* Conditional writes. */
    110    if (dc->flags_x) {
    111        gen_store_v10_conditional(dc, addr, val, size, mem_index);
    112        return;
    113    }
    114
    115    if (size == 1) {
    116        tcg_gen_qemu_st8(val, addr, mem_index);
    117    } else if (size == 2) {
    118        tcg_gen_qemu_st16(val, addr, mem_index);
    119    } else {
    120        tcg_gen_qemu_st32(val, addr, mem_index);
    121    }
    122}
    123
    124
    125/* Prefix flag and register are used to handle the more complex
    126   addressing modes.  */
    127static void cris_set_prefix(DisasContext *dc)
    128{
    129    dc->clear_prefix = 0;
    130    dc->tb_flags |= PFIX_FLAG;
    131    tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], PFIX_FLAG);
    132
    133    /* prefix insns don't clear the x flag.  */
    134    dc->clear_x = 0;
    135    cris_lock_irq(dc);
    136}
    137
    138static void crisv10_prepare_memaddr(DisasContext *dc,
    139                                    TCGv addr, unsigned int size)
    140{
    141    if (dc->tb_flags & PFIX_FLAG) {
    142        tcg_gen_mov_tl(addr, cpu_PR[PR_PREFIX]);
    143    } else {
    144        tcg_gen_mov_tl(addr, cpu_R[dc->src]);
    145    }
    146}
    147
    148static unsigned int crisv10_post_memaddr(DisasContext *dc, unsigned int size)
    149{
    150    unsigned int insn_len = 0;
    151
    152    if (dc->tb_flags & PFIX_FLAG) {
    153        if (dc->mode == CRISV10_MODE_AUTOINC) {
    154            tcg_gen_mov_tl(cpu_R[dc->src], cpu_PR[PR_PREFIX]);
    155        }
    156    } else {
    157        if (dc->mode == CRISV10_MODE_AUTOINC) {
    158            if (dc->src == 15) {
    159                insn_len += size & ~1;
    160            } else {
    161                tcg_gen_addi_tl(cpu_R[dc->src], cpu_R[dc->src], size);
    162            }
    163        }
    164    }
    165    return insn_len;
    166}
    167
    168static int dec10_prep_move_m(CPUCRISState *env, DisasContext *dc,
    169                             int s_ext, int memsize, TCGv dst)
    170{
    171    unsigned int rs;
    172    uint32_t imm;
    173    int is_imm;
    174    int insn_len = 0;
    175
    176    rs = dc->src;
    177    is_imm = rs == 15 && !(dc->tb_flags & PFIX_FLAG);
    178    LOG_DIS("rs=%d rd=%d is_imm=%d mode=%d pfix=%d\n",
    179             rs, dc->dst, is_imm, dc->mode, dc->tb_flags & PFIX_FLAG);
    180
    181    /* Load [$rs] onto T1.  */
    182    if (is_imm) {
    183        if (memsize != 4) {
    184            if (s_ext) {
    185                if (memsize == 1)
    186                    imm = cpu_ldsb_code(env, dc->pc + 2);
    187                else
    188                    imm = cpu_ldsw_code(env, dc->pc + 2);
    189            } else {
    190                if (memsize == 1)
    191                    imm = cpu_ldub_code(env, dc->pc + 2);
    192                else
    193                    imm = cpu_lduw_code(env, dc->pc + 2);
    194            }
    195        } else
    196            imm = cpu_ldl_code(env, dc->pc + 2);
    197
    198        tcg_gen_movi_tl(dst, imm);
    199
    200        if (dc->mode == CRISV10_MODE_AUTOINC) {
    201            insn_len += memsize;
    202            if (memsize == 1)
    203                insn_len++;
    204            tcg_gen_addi_tl(cpu_R[15], cpu_R[15], insn_len);
    205        }
    206    } else {
    207        TCGv addr;
    208
    209        addr = tcg_temp_new();
    210        cris_flush_cc_state(dc);
    211        crisv10_prepare_memaddr(dc, addr, memsize);
    212        gen_load(dc, dst, addr, memsize, 0);
    213        if (s_ext)
    214            t_gen_sext(dst, dst, memsize);
    215        else
    216            t_gen_zext(dst, dst, memsize);
    217        insn_len += crisv10_post_memaddr(dc, memsize);
    218        tcg_temp_free(addr);
    219    }
    220
    221    if (dc->mode == CRISV10_MODE_INDIRECT && (dc->tb_flags & PFIX_FLAG)) {
    222        dc->dst = dc->src;
    223    }
    224    return insn_len;
    225}
    226
    227static unsigned int dec10_quick_imm(DisasContext *dc)
    228{
    229    int32_t imm, simm;
    230    int op;
    231    TCGv c;
    232
    233    /* sign extend.  */
    234    imm = dc->ir & ((1 << 6) - 1);
    235    simm = (int8_t) (imm << 2);
    236    simm >>= 2;
    237    switch (dc->opcode) {
    238        case CRISV10_QIMM_BDAP_R0:
    239        case CRISV10_QIMM_BDAP_R1:
    240        case CRISV10_QIMM_BDAP_R2:
    241        case CRISV10_QIMM_BDAP_R3:
    242            simm = (int8_t)dc->ir;
    243            LOG_DIS("bdap %d $r%d\n", simm, dc->dst);
    244            LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n",
    245                     dc->pc, dc->mode, dc->opcode, dc->src, dc->dst);
    246            cris_set_prefix(dc);
    247            if (dc->dst == 15) {
    248                tcg_gen_movi_tl(cpu_PR[PR_PREFIX], dc->pc + 2 + simm);
    249            } else {
    250                tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm);
    251            }
    252            break;
    253
    254        case CRISV10_QIMM_MOVEQ:
    255            LOG_DIS("moveq %d, $r%d\n", simm, dc->dst);
    256
    257            cris_cc_mask(dc, CC_MASK_NZVC);
    258            c = tcg_const_tl(simm);
    259            cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst],
    260                     cpu_R[dc->dst], c, 4);
    261            tcg_temp_free(c);
    262            break;
    263        case CRISV10_QIMM_CMPQ:
    264            LOG_DIS("cmpq %d, $r%d\n", simm, dc->dst);
    265
    266            cris_cc_mask(dc, CC_MASK_NZVC);
    267            c = tcg_const_tl(simm);
    268            cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst],
    269                     cpu_R[dc->dst], c, 4);
    270            tcg_temp_free(c);
    271            break;
    272        case CRISV10_QIMM_ADDQ:
    273            LOG_DIS("addq %d, $r%d\n", imm, dc->dst);
    274
    275            cris_cc_mask(dc, CC_MASK_NZVC);
    276            c = tcg_const_tl(imm);
    277            cris_alu(dc, CC_OP_ADD, cpu_R[dc->dst],
    278                     cpu_R[dc->dst], c, 4);
    279            tcg_temp_free(c);
    280            break;
    281        case CRISV10_QIMM_ANDQ:
    282            LOG_DIS("andq %d, $r%d\n", simm, dc->dst);
    283
    284            cris_cc_mask(dc, CC_MASK_NZVC);
    285            c = tcg_const_tl(simm);
    286            cris_alu(dc, CC_OP_AND, cpu_R[dc->dst],
    287                     cpu_R[dc->dst], c, 4);
    288            tcg_temp_free(c);
    289            break;
    290        case CRISV10_QIMM_ASHQ:
    291            LOG_DIS("ashq %d, $r%d\n", simm, dc->dst);
    292
    293            cris_cc_mask(dc, CC_MASK_NZVC);
    294            op = imm & (1 << 5);
    295            imm &= 0x1f;
    296            c = tcg_const_tl(imm);
    297            if (op) {
    298                cris_alu(dc, CC_OP_ASR, cpu_R[dc->dst],
    299                          cpu_R[dc->dst], c, 4);
    300            } else {
    301                /* BTST */
    302                cris_update_cc_op(dc, CC_OP_FLAGS, 4);
    303                gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->dst],
    304                           c, cpu_PR[PR_CCS]);
    305            }
    306            tcg_temp_free(c);
    307            break;
    308        case CRISV10_QIMM_LSHQ:
    309            LOG_DIS("lshq %d, $r%d\n", simm, dc->dst);
    310
    311            op = CC_OP_LSL;
    312            if (imm & (1 << 5)) {
    313                op = CC_OP_LSR; 
    314            }
    315            imm &= 0x1f;
    316            cris_cc_mask(dc, CC_MASK_NZVC);
    317            c = tcg_const_tl(imm);
    318            cris_alu(dc, op, cpu_R[dc->dst],
    319                     cpu_R[dc->dst], c, 4);
    320            tcg_temp_free(c);
    321            break;
    322        case CRISV10_QIMM_SUBQ:
    323            LOG_DIS("subq %d, $r%d\n", imm, dc->dst);
    324
    325            cris_cc_mask(dc, CC_MASK_NZVC);
    326            c = tcg_const_tl(imm);
    327            cris_alu(dc, CC_OP_SUB, cpu_R[dc->dst],
    328                     cpu_R[dc->dst], c, 4);
    329            tcg_temp_free(c);
    330            break;
    331        case CRISV10_QIMM_ORQ:
    332            LOG_DIS("andq %d, $r%d\n", simm, dc->dst);
    333
    334            cris_cc_mask(dc, CC_MASK_NZVC);
    335            c = tcg_const_tl(simm);
    336            cris_alu(dc, CC_OP_OR, cpu_R[dc->dst],
    337                     cpu_R[dc->dst], c, 4);
    338            tcg_temp_free(c);
    339            break;
    340
    341        case CRISV10_QIMM_BCC_R0:
    342        case CRISV10_QIMM_BCC_R1:
    343        case CRISV10_QIMM_BCC_R2:
    344        case CRISV10_QIMM_BCC_R3:
    345            imm = dc->ir & 0xff;
    346            /* bit 0 is a sign bit.  */
    347            if (imm & 1) {
    348                imm |= 0xffffff00;   /* sign extend.  */
    349                imm &= ~1;           /* get rid of the sign bit.  */
    350            }
    351            imm += 2;
    352            LOG_DIS("b%s %d\n", cc_name(dc->cond), imm);
    353
    354            cris_cc_mask(dc, 0);
    355            cris_prepare_cc_branch(dc, imm, dc->cond); 
    356            break;
    357
    358        default:
    359            LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n",
    360                     dc->pc, dc->mode, dc->opcode, dc->src, dc->dst);
    361            cpu_abort(CPU(dc->cpu), "Unhandled quickimm\n");
    362            break;
    363    }
    364    return 2;
    365}
    366
    367static unsigned int dec10_setclrf(DisasContext *dc)
    368{
    369    uint32_t flags;
    370    unsigned int set = ~dc->opcode & 1;
    371
    372    flags = EXTRACT_FIELD(dc->ir, 0, 3)
    373            | (EXTRACT_FIELD(dc->ir, 12, 15) << 4);
    374    LOG_DIS("%s set=%d flags=%x\n", __func__, set, flags);
    375
    376
    377    if (flags & X_FLAG) {
    378        if (set)
    379            dc->flags_x = X_FLAG;
    380        else
    381            dc->flags_x = 0;
    382    }
    383
    384    cris_evaluate_flags (dc);
    385    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
    386    cris_update_cc_x(dc);
    387    tcg_gen_movi_tl(cc_op, dc->cc_op);
    388
    389    if (set) {
    390        tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
    391    } else {
    392        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS],
    393                        ~(flags|F_FLAG_V10|P_FLAG_V10));
    394    }
    395
    396    dc->flags_uptodate = 1;
    397    dc->clear_x = 0;
    398    cris_lock_irq(dc);
    399    return 2;
    400}
    401
    402static inline void dec10_reg_prep_sext(DisasContext *dc, int size, int sext,
    403                                       TCGv dd, TCGv ds, TCGv sd, TCGv ss)
    404{
    405    if (sext) {
    406        t_gen_sext(dd, sd, size);
    407        t_gen_sext(ds, ss, size);
    408    } else {
    409        t_gen_zext(dd, sd, size);
    410        t_gen_zext(ds, ss, size);
    411    }
    412}
    413
    414static void dec10_reg_alu(DisasContext *dc, int op, int size, int sext)
    415{
    416    TCGv t[2];
    417
    418    t[0] = tcg_temp_new();
    419    t[1] = tcg_temp_new();
    420    dec10_reg_prep_sext(dc, size, sext,
    421                        t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]);
    422
    423    if (op == CC_OP_LSL || op == CC_OP_LSR || op == CC_OP_ASR) {
    424        tcg_gen_andi_tl(t[1], t[1], 63);
    425    }
    426
    427    assert(dc->dst != 15);
    428    cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], size);
    429    tcg_temp_free(t[0]);
    430    tcg_temp_free(t[1]);
    431}
    432
    433static void dec10_reg_bound(DisasContext *dc, int size)
    434{
    435    TCGv t;
    436
    437    t = tcg_temp_local_new();
    438    t_gen_zext(t, cpu_R[dc->src], size);
    439    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
    440    tcg_temp_free(t);
    441}
    442
    443static void dec10_reg_mul(DisasContext *dc, int size, int sext)
    444{
    445    int op = sext ? CC_OP_MULS : CC_OP_MULU;
    446    TCGv t[2];
    447
    448    t[0] = tcg_temp_new();
    449    t[1] = tcg_temp_new();
    450    dec10_reg_prep_sext(dc, size, sext,
    451                        t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]);
    452
    453    cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], 4);
    454
    455    tcg_temp_free(t[0]);
    456    tcg_temp_free(t[1]);
    457}
    458
    459
    460static void dec10_reg_movs(DisasContext *dc)
    461{
    462    int size = (dc->size & 1) + 1;
    463    TCGv t;
    464
    465    LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst);
    466    cris_cc_mask(dc, CC_MASK_NZVC);
    467
    468    t = tcg_temp_new();
    469    if (dc->ir & 32)
    470        t_gen_sext(t, cpu_R[dc->src], size);
    471    else
    472        t_gen_zext(t, cpu_R[dc->src], size);
    473
    474    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
    475    tcg_temp_free(t);
    476}
    477
    478static void dec10_reg_alux(DisasContext *dc, int op)
    479{
    480    int size = (dc->size & 1) + 1;
    481    TCGv t;
    482
    483    LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst);
    484    cris_cc_mask(dc, CC_MASK_NZVC);
    485
    486    t = tcg_temp_new();
    487    if (dc->ir & 32)
    488        t_gen_sext(t, cpu_R[dc->src], size);
    489    else
    490        t_gen_zext(t, cpu_R[dc->src], size);
    491
    492    cris_alu(dc, op, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
    493    tcg_temp_free(t);
    494}
    495
    496static void dec10_reg_mov_pr(DisasContext *dc)
    497{
    498    LOG_DIS("move p%d r%d sz=%d\n", dc->dst, dc->src, preg_sizes_v10[dc->dst]);
    499    cris_lock_irq(dc);
    500    if (dc->src == 15) {
    501        tcg_gen_mov_tl(env_btarget, cpu_PR[dc->dst]);
    502        cris_prepare_jmp(dc, JMP_INDIRECT);
    503        return;
    504    }
    505    if (dc->dst == PR_CCS) {
    506        cris_evaluate_flags(dc); 
    507    }
    508    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src],
    509                 cpu_R[dc->src], cpu_PR[dc->dst], preg_sizes_v10[dc->dst]);
    510}
    511
    512static void dec10_reg_abs(DisasContext *dc)
    513{
    514    TCGv t0;
    515
    516    LOG_DIS("abs $r%u, $r%u\n", dc->src, dc->dst);
    517
    518    assert(dc->dst != 15);
    519    t0 = tcg_temp_new();
    520    tcg_gen_sari_tl(t0, cpu_R[dc->src], 31);
    521    tcg_gen_xor_tl(cpu_R[dc->dst], cpu_R[dc->src], t0);
    522    tcg_gen_sub_tl(t0, cpu_R[dc->dst], t0);
    523
    524    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t0, 4);
    525    tcg_temp_free(t0);
    526}
    527
    528static void dec10_reg_swap(DisasContext *dc)
    529{
    530    TCGv t0;
    531
    532    LOG_DIS("not $r%d, $r%d\n", dc->src, dc->dst);
    533
    534    cris_cc_mask(dc, CC_MASK_NZVC);
    535    t0 = tcg_temp_new();
    536    tcg_gen_mov_tl(t0, cpu_R[dc->src]);
    537    if (dc->dst & 8)
    538        tcg_gen_not_tl(t0, t0);
    539    if (dc->dst & 4)
    540        t_gen_swapw(t0, t0);
    541    if (dc->dst & 2)
    542        t_gen_swapb(t0, t0);
    543    if (dc->dst & 1)
    544        t_gen_swapr(t0, t0);
    545    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src], cpu_R[dc->src], t0, 4);
    546    tcg_temp_free(t0);
    547}
    548
    549static void dec10_reg_scc(DisasContext *dc)
    550{
    551    int cond = dc->dst;
    552
    553    LOG_DIS("s%s $r%u\n", cc_name(cond), dc->src);
    554
    555    gen_tst_cc(dc, cpu_R[dc->src], cond);
    556    tcg_gen_setcondi_tl(TCG_COND_NE, cpu_R[dc->src], cpu_R[dc->src], 0);
    557
    558    cris_cc_mask(dc, 0);
    559}
    560
    561static unsigned int dec10_reg(DisasContext *dc)
    562{
    563    TCGv t;
    564    unsigned int insn_len = 2;
    565    unsigned int size = dec10_size(dc->size);
    566    unsigned int tmp;
    567
    568    if (dc->size != 3) {
    569        switch (dc->opcode) {
    570            case CRISV10_REG_MOVE_R:
    571                LOG_DIS("move.%d $r%d, $r%d\n", dc->size, dc->src, dc->dst);
    572                cris_cc_mask(dc, CC_MASK_NZVC);
    573                dec10_reg_alu(dc, CC_OP_MOVE, size, 0);
    574                if (dc->dst == 15) {
    575                    tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
    576                    cris_prepare_jmp(dc, JMP_INDIRECT);
    577                    dc->delayed_branch = 1;
    578                }
    579                break;
    580            case CRISV10_REG_MOVX:
    581                cris_cc_mask(dc, CC_MASK_NZVC);
    582                dec10_reg_movs(dc);
    583                break;
    584            case CRISV10_REG_ADDX:
    585                cris_cc_mask(dc, CC_MASK_NZVC);
    586                dec10_reg_alux(dc, CC_OP_ADD);
    587                break;
    588            case CRISV10_REG_SUBX:
    589                cris_cc_mask(dc, CC_MASK_NZVC);
    590                dec10_reg_alux(dc, CC_OP_SUB);
    591                break;
    592            case CRISV10_REG_ADD:
    593                LOG_DIS("add $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    594                cris_cc_mask(dc, CC_MASK_NZVC);
    595                dec10_reg_alu(dc, CC_OP_ADD, size, 0);
    596                break;
    597            case CRISV10_REG_SUB:
    598                LOG_DIS("sub $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    599                cris_cc_mask(dc, CC_MASK_NZVC);
    600                dec10_reg_alu(dc, CC_OP_SUB, size, 0);
    601                break;
    602            case CRISV10_REG_CMP:
    603                LOG_DIS("cmp $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    604                cris_cc_mask(dc, CC_MASK_NZVC);
    605                dec10_reg_alu(dc, CC_OP_CMP, size, 0);
    606                break;
    607            case CRISV10_REG_BOUND:
    608                LOG_DIS("bound $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    609                cris_cc_mask(dc, CC_MASK_NZVC);
    610                dec10_reg_bound(dc, size);
    611                break;
    612            case CRISV10_REG_AND:
    613                LOG_DIS("and $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    614                cris_cc_mask(dc, CC_MASK_NZVC);
    615                dec10_reg_alu(dc, CC_OP_AND, size, 0);
    616                break;
    617            case CRISV10_REG_ADDI:
    618                if (dc->src == 15) {
    619                    /* nop.  */
    620                    return 2;
    621                }
    622                t = tcg_temp_new();
    623                LOG_DIS("addi r%d r%d size=%d\n", dc->src, dc->dst, dc->size);
    624                tcg_gen_shli_tl(t, cpu_R[dc->dst], dc->size & 3);
    625                tcg_gen_add_tl(cpu_R[dc->src], cpu_R[dc->src], t);
    626                tcg_temp_free(t);
    627                break;
    628            case CRISV10_REG_LSL:
    629                LOG_DIS("lsl $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    630                cris_cc_mask(dc, CC_MASK_NZVC);
    631                dec10_reg_alu(dc, CC_OP_LSL, size, 0);
    632                break;
    633            case CRISV10_REG_LSR:
    634                LOG_DIS("lsr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    635                cris_cc_mask(dc, CC_MASK_NZVC);
    636                dec10_reg_alu(dc, CC_OP_LSR, size, 0);
    637                break;
    638            case CRISV10_REG_ASR:
    639                LOG_DIS("asr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    640                cris_cc_mask(dc, CC_MASK_NZVC);
    641                dec10_reg_alu(dc, CC_OP_ASR, size, 1);
    642                break;
    643            case CRISV10_REG_OR:
    644                LOG_DIS("or $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    645                cris_cc_mask(dc, CC_MASK_NZVC);
    646                dec10_reg_alu(dc, CC_OP_OR, size, 0);
    647                break;
    648            case CRISV10_REG_NEG:
    649                LOG_DIS("neg $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    650                cris_cc_mask(dc, CC_MASK_NZVC);
    651                dec10_reg_alu(dc, CC_OP_NEG, size, 0);
    652                break;
    653            case CRISV10_REG_BIAP:
    654                LOG_DIS("BIAP pc=%x reg %d r%d r%d size=%d\n", dc->pc,
    655                         dc->opcode, dc->src, dc->dst, size);
    656                switch (size) {
    657                    case 4: tmp = 2; break;
    658                    case 2: tmp = 1; break;
    659                    case 1: tmp = 0; break;
    660                    default:
    661                        cpu_abort(CPU(dc->cpu), "Unhandled BIAP");
    662                        break;
    663                }
    664
    665                t = tcg_temp_new();
    666                tcg_gen_shli_tl(t, cpu_R[dc->dst], tmp);
    667                if (dc->src == 15) {
    668                    tcg_gen_addi_tl(cpu_PR[PR_PREFIX], t, ((dc->pc +2)| 1) + 1);
    669                } else {
    670                    tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_R[dc->src], t);
    671                }
    672                tcg_temp_free(t);
    673                cris_set_prefix(dc);
    674                break;
    675
    676            default:
    677                LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc,
    678                         dc->opcode, dc->src, dc->dst);
    679                cpu_abort(CPU(dc->cpu), "Unhandled opcode");
    680                break;
    681        }
    682    } else {
    683        switch (dc->opcode) {
    684            case CRISV10_REG_MOVX:
    685                cris_cc_mask(dc, CC_MASK_NZVC);
    686                dec10_reg_movs(dc);
    687                break;
    688            case CRISV10_REG_ADDX:
    689                cris_cc_mask(dc, CC_MASK_NZVC);
    690                dec10_reg_alux(dc, CC_OP_ADD);
    691                break;
    692            case CRISV10_REG_SUBX:
    693                cris_cc_mask(dc, CC_MASK_NZVC);
    694                dec10_reg_alux(dc, CC_OP_SUB);
    695                break;
    696            case CRISV10_REG_MOVE_SPR_R:
    697                cris_evaluate_flags(dc);
    698                cris_cc_mask(dc, 0);
    699                dec10_reg_mov_pr(dc);
    700                break;
    701            case CRISV10_REG_MOVE_R_SPR:
    702                LOG_DIS("move r%d p%d\n", dc->src, dc->dst);
    703                cris_evaluate_flags(dc);
    704                if (dc->src != 11) /* fast for srp.  */
    705                    dc->cpustate_changed = 1;
    706                t_gen_mov_preg_TN(dc, dc->dst, cpu_R[dc->src]);
    707                break;
    708            case CRISV10_REG_SETF:
    709            case CRISV10_REG_CLEARF:
    710                dec10_setclrf(dc);
    711                break;
    712            case CRISV10_REG_SWAP:
    713                dec10_reg_swap(dc);
    714                break;
    715            case CRISV10_REG_ABS:
    716                cris_cc_mask(dc, CC_MASK_NZVC);
    717                dec10_reg_abs(dc);
    718                break;
    719            case CRISV10_REG_LZ:
    720                LOG_DIS("lz $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    721                cris_cc_mask(dc, CC_MASK_NZVC);
    722                dec10_reg_alu(dc, CC_OP_LZ, 4, 0);
    723                break;
    724            case CRISV10_REG_XOR:
    725                LOG_DIS("xor $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    726                cris_cc_mask(dc, CC_MASK_NZVC);
    727                dec10_reg_alu(dc, CC_OP_XOR, 4, 0);
    728                break;
    729            case CRISV10_REG_BTST:
    730                LOG_DIS("btst $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    731                cris_cc_mask(dc, CC_MASK_NZVC);
    732                cris_update_cc_op(dc, CC_OP_FLAGS, 4);
    733                gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->dst],
    734                           cpu_R[dc->src], cpu_PR[PR_CCS]);
    735                break;
    736            case CRISV10_REG_DSTEP:
    737                LOG_DIS("dstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    738                cris_cc_mask(dc, CC_MASK_NZVC);
    739                cris_alu(dc, CC_OP_DSTEP, cpu_R[dc->dst],
    740                            cpu_R[dc->dst], cpu_R[dc->src], 4);
    741                break;
    742            case CRISV10_REG_MSTEP:
    743                LOG_DIS("mstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
    744                cris_evaluate_flags(dc);
    745                cris_cc_mask(dc, CC_MASK_NZVC);
    746                cris_alu(dc, CC_OP_MSTEP, cpu_R[dc->dst],
    747                            cpu_R[dc->dst], cpu_R[dc->src], 4);
    748                break;
    749            case CRISV10_REG_SCC:
    750                dec10_reg_scc(dc);
    751                break;
    752            default:
    753                LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc,
    754                         dc->opcode, dc->src, dc->dst);
    755                cpu_abort(CPU(dc->cpu), "Unhandled opcode");
    756                break;
    757        }
    758    }
    759    return insn_len;
    760}
    761
    762static unsigned int dec10_ind_move_m_r(CPUCRISState *env, DisasContext *dc,
    763                                       unsigned int size)
    764{
    765    unsigned int insn_len = 2;
    766    TCGv t;
    767
    768    LOG_DIS("%s: move.%d [$r%d], $r%d\n", __func__,
    769             size, dc->src, dc->dst);
    770
    771    cris_cc_mask(dc, CC_MASK_NZVC);
    772    t = tcg_temp_new();
    773    insn_len += dec10_prep_move_m(env, dc, 0, size, t);
    774    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, size);
    775    if (dc->dst == 15) {
    776        tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
    777        cris_prepare_jmp(dc, JMP_INDIRECT);
    778        dc->delayed_branch = 1;
    779    }
    780
    781    tcg_temp_free(t);
    782    return insn_len;
    783}
    784
    785static unsigned int dec10_ind_move_r_m(DisasContext *dc, unsigned int size)
    786{
    787    unsigned int insn_len = 2;
    788    TCGv addr;
    789
    790    LOG_DIS("move.%d $r%d, [$r%d]\n", dc->size, dc->src, dc->dst);
    791    addr = tcg_temp_new();
    792    crisv10_prepare_memaddr(dc, addr, size);
    793    gen_store_v10(dc, addr, cpu_R[dc->dst], size);
    794    insn_len += crisv10_post_memaddr(dc, size);
    795    tcg_temp_free(addr);
    796
    797    return insn_len;
    798}
    799
    800static unsigned int dec10_ind_move_m_pr(CPUCRISState *env, DisasContext *dc)
    801{
    802    unsigned int insn_len = 2, rd = dc->dst;
    803    TCGv t, addr;
    804
    805    LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src);
    806    cris_lock_irq(dc);
    807
    808    addr = tcg_temp_new();
    809    t = tcg_temp_new();
    810    insn_len += dec10_prep_move_m(env, dc, 0, 4, t);
    811    if (rd == 15) {
    812        tcg_gen_mov_tl(env_btarget, t);
    813        cris_prepare_jmp(dc, JMP_INDIRECT);
    814        dc->delayed_branch = 1;
    815    } else {
    816        tcg_gen_mov_tl(cpu_PR[rd], t);
    817        dc->cpustate_changed = 1;
    818    }
    819    tcg_temp_free(addr);
    820    tcg_temp_free(t);
    821    return insn_len;
    822}
    823
    824static unsigned int dec10_ind_move_pr_m(DisasContext *dc)
    825{
    826    unsigned int insn_len = 2, size = preg_sizes_v10[dc->dst];
    827    TCGv addr, t0;
    828
    829    LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src);
    830
    831    addr = tcg_temp_new();
    832    crisv10_prepare_memaddr(dc, addr, size);
    833    if (dc->dst == PR_CCS) {
    834        t0 = tcg_temp_new();
    835        cris_evaluate_flags(dc);
    836        tcg_gen_andi_tl(t0, cpu_PR[PR_CCS], ~PFIX_FLAG);
    837        gen_store_v10(dc, addr, t0, size);
    838        tcg_temp_free(t0);
    839    } else {
    840        gen_store_v10(dc, addr, cpu_PR[dc->dst], size);
    841    }
    842    insn_len += crisv10_post_memaddr(dc, size);
    843    tcg_temp_free(addr);
    844    cris_lock_irq(dc);
    845
    846    return insn_len;
    847}
    848
    849static void dec10_movem_r_m(DisasContext *dc)
    850{
    851    int i, pfix = dc->tb_flags & PFIX_FLAG;
    852    TCGv addr, t0;
    853
    854    LOG_DIS("%s r%d, [r%d] pi=%d ir=%x\n", __func__,
    855              dc->dst, dc->src, dc->postinc, dc->ir);
    856
    857    addr = tcg_temp_new();
    858    t0 = tcg_temp_new();
    859    crisv10_prepare_memaddr(dc, addr, 4);
    860    tcg_gen_mov_tl(t0, addr);
    861    for (i = dc->dst; i >= 0; i--) {
    862        if ((pfix && dc->mode == CRISV10_MODE_AUTOINC) && dc->src == i) {
    863            gen_store_v10(dc, addr, t0, 4);
    864        } else {
    865            gen_store_v10(dc, addr, cpu_R[i], 4);
    866        }
    867        tcg_gen_addi_tl(addr, addr, 4);
    868    }
    869
    870    if (pfix && dc->mode == CRISV10_MODE_AUTOINC) {
    871        tcg_gen_mov_tl(cpu_R[dc->src], t0);
    872    }
    873
    874    if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) {
    875        tcg_gen_mov_tl(cpu_R[dc->src], addr);
    876    }
    877    tcg_temp_free(addr);
    878    tcg_temp_free(t0);
    879}
    880
    881static void dec10_movem_m_r(DisasContext *dc)
    882{
    883    int i, pfix = dc->tb_flags & PFIX_FLAG;
    884    TCGv addr, t0;
    885
    886    LOG_DIS("%s [r%d], r%d pi=%d ir=%x\n", __func__,
    887              dc->src, dc->dst, dc->postinc, dc->ir);
    888
    889    addr = tcg_temp_new();
    890    t0 = tcg_temp_new();
    891    crisv10_prepare_memaddr(dc, addr, 4);
    892    tcg_gen_mov_tl(t0, addr);
    893    for (i = dc->dst; i >= 0; i--) {
    894        gen_load(dc, cpu_R[i], addr, 4, 0);
    895        tcg_gen_addi_tl(addr, addr, 4);
    896    }
    897
    898    if (pfix && dc->mode == CRISV10_MODE_AUTOINC) {
    899        tcg_gen_mov_tl(cpu_R[dc->src], t0);
    900    }
    901
    902    if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) {
    903        tcg_gen_mov_tl(cpu_R[dc->src], addr);
    904    }
    905    tcg_temp_free(addr);
    906    tcg_temp_free(t0);
    907}
    908
    909static int dec10_ind_alu(CPUCRISState *env, DisasContext *dc,
    910                         int op, unsigned int size)
    911{
    912    int insn_len = 0;
    913    int rd = dc->dst;
    914    TCGv t[2];
    915
    916    cris_alu_m_alloc_temps(t);
    917    insn_len += dec10_prep_move_m(env, dc, 0, size, t[0]);
    918    cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t[0], size);
    919    if (dc->dst == 15) {
    920        tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
    921        cris_prepare_jmp(dc, JMP_INDIRECT);
    922        dc->delayed_branch = 1;
    923        return insn_len;
    924    }
    925
    926    cris_alu_m_free_temps(t);
    927
    928    return insn_len;
    929}
    930
    931static int dec10_ind_bound(CPUCRISState *env, DisasContext *dc,
    932                           unsigned int size)
    933{
    934    int insn_len = 0;
    935    int rd = dc->dst;
    936    TCGv t;
    937
    938    t = tcg_temp_local_new();
    939    insn_len += dec10_prep_move_m(env, dc, 0, size, t);
    940    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[rd], t, 4);
    941    if (dc->dst == 15) {
    942        tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
    943        cris_prepare_jmp(dc, JMP_INDIRECT);
    944        dc->delayed_branch = 1;
    945    }
    946
    947    tcg_temp_free(t);
    948    return insn_len;
    949}
    950
    951static int dec10_alux_m(CPUCRISState *env, DisasContext *dc, int op)
    952{
    953    unsigned int size = (dc->size & 1) ? 2 : 1;
    954    unsigned int sx = !!(dc->size & 2);
    955    int insn_len = 2;
    956    int rd = dc->dst;
    957    TCGv t;
    958
    959    LOG_DIS("addx size=%d sx=%d op=%d %d\n", size, sx, dc->src, dc->dst);
    960
    961    t = tcg_temp_new();
    962
    963    cris_cc_mask(dc, CC_MASK_NZVC);
    964    insn_len += dec10_prep_move_m(env, dc, sx, size, t);
    965    cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t, 4);
    966    if (dc->dst == 15) {
    967        tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
    968        cris_prepare_jmp(dc, JMP_INDIRECT);
    969        dc->delayed_branch = 1;
    970    }
    971
    972    tcg_temp_free(t);
    973    return insn_len;
    974}
    975
    976static int dec10_dip(CPUCRISState *env, DisasContext *dc)
    977{
    978    int insn_len = 2;
    979    uint32_t imm;
    980
    981    LOG_DIS("dip pc=%x opcode=%d r%d r%d\n",
    982              dc->pc, dc->opcode, dc->src, dc->dst);
    983    if (dc->src == 15) {
    984        imm = cpu_ldl_code(env, dc->pc + 2);
    985        tcg_gen_movi_tl(cpu_PR[PR_PREFIX], imm);
    986        if (dc->postinc)
    987            insn_len += 4;
    988        tcg_gen_addi_tl(cpu_R[15], cpu_R[15], insn_len - 2);
    989    } else {
    990        gen_load(dc, cpu_PR[PR_PREFIX], cpu_R[dc->src], 4, 0);
    991        if (dc->postinc)
    992            tcg_gen_addi_tl(cpu_R[dc->src], cpu_R[dc->src], 4);
    993    }
    994
    995    cris_set_prefix(dc);
    996    return insn_len;
    997}
    998
    999static int dec10_bdap_m(CPUCRISState *env, DisasContext *dc, int size)
   1000{
   1001    int insn_len = 2;
   1002    int rd = dc->dst;
   1003
   1004    LOG_DIS("bdap_m pc=%x opcode=%d r%d r%d sz=%d\n",
   1005              dc->pc, dc->opcode, dc->src, dc->dst, size);
   1006
   1007    assert(dc->dst != 15);
   1008#if 0
   1009    /* 8bit embedded offset?  */
   1010    if (!dc->postinc && (dc->ir & (1 << 11))) {
   1011        int simm = dc->ir & 0xff;
   1012
   1013        /* cpu_abort(CPU(dc->cpu), "Unhandled opcode"); */
   1014        /* sign extended.  */
   1015        simm = (int8_t)simm;
   1016
   1017        tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm);
   1018
   1019        cris_set_prefix(dc);
   1020        return insn_len;
   1021    }
   1022#endif
   1023    /* Now the rest of the modes are truly indirect.  */
   1024    insn_len += dec10_prep_move_m(env, dc, 1, size, cpu_PR[PR_PREFIX]);
   1025    tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_PR[PR_PREFIX], cpu_R[rd]);
   1026    cris_set_prefix(dc);
   1027    return insn_len;
   1028}
   1029
   1030static unsigned int dec10_ind(CPUCRISState *env, DisasContext *dc)
   1031{
   1032    unsigned int insn_len = 2;
   1033    unsigned int size = dec10_size(dc->size);
   1034    uint32_t imm;
   1035    int32_t simm;
   1036    TCGv t[2], c;
   1037
   1038    if (dc->size != 3) {
   1039        switch (dc->opcode) {
   1040            case CRISV10_IND_MOVE_M_R:
   1041                return dec10_ind_move_m_r(env, dc, size);
   1042            case CRISV10_IND_MOVE_R_M:
   1043                return dec10_ind_move_r_m(dc, size);
   1044            case CRISV10_IND_CMP:
   1045                LOG_DIS("cmp size=%d op=%d %d\n",  size, dc->src, dc->dst);
   1046                cris_cc_mask(dc, CC_MASK_NZVC);
   1047                insn_len += dec10_ind_alu(env, dc, CC_OP_CMP, size);
   1048                break;
   1049            case CRISV10_IND_TEST:
   1050                LOG_DIS("test size=%d op=%d %d\n",  size, dc->src, dc->dst);
   1051
   1052                cris_evaluate_flags(dc);
   1053                cris_cc_mask(dc, CC_MASK_NZVC);
   1054                cris_alu_m_alloc_temps(t);
   1055                insn_len += dec10_prep_move_m(env, dc, 0, size, t[0]);
   1056                tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
   1057                c = tcg_const_tl(0);
   1058                cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst],
   1059                         t[0], c, size);
   1060                tcg_temp_free(c);
   1061                cris_alu_m_free_temps(t);
   1062                break;
   1063            case CRISV10_IND_ADD:
   1064                LOG_DIS("add size=%d op=%d %d\n",  size, dc->src, dc->dst);
   1065                cris_cc_mask(dc, CC_MASK_NZVC);
   1066                insn_len += dec10_ind_alu(env, dc, CC_OP_ADD, size);
   1067                break;
   1068            case CRISV10_IND_SUB:
   1069                LOG_DIS("sub size=%d op=%d %d\n",  size, dc->src, dc->dst);
   1070                cris_cc_mask(dc, CC_MASK_NZVC);
   1071                insn_len += dec10_ind_alu(env, dc, CC_OP_SUB, size);
   1072                break;
   1073            case CRISV10_IND_BOUND:
   1074                LOG_DIS("bound size=%d op=%d %d\n",  size, dc->src, dc->dst);
   1075                cris_cc_mask(dc, CC_MASK_NZVC);
   1076                insn_len += dec10_ind_bound(env, dc, size);
   1077                break;
   1078            case CRISV10_IND_AND:
   1079                LOG_DIS("and size=%d op=%d %d\n",  size, dc->src, dc->dst);
   1080                cris_cc_mask(dc, CC_MASK_NZVC);
   1081                insn_len += dec10_ind_alu(env, dc, CC_OP_AND, size);
   1082                break;
   1083            case CRISV10_IND_OR:
   1084                LOG_DIS("or size=%d op=%d %d\n",  size, dc->src, dc->dst);
   1085                cris_cc_mask(dc, CC_MASK_NZVC);
   1086                insn_len += dec10_ind_alu(env, dc, CC_OP_OR, size);
   1087                break;
   1088            case CRISV10_IND_MOVX:
   1089                insn_len = dec10_alux_m(env, dc, CC_OP_MOVE);
   1090                break;
   1091            case CRISV10_IND_ADDX:
   1092                insn_len = dec10_alux_m(env, dc, CC_OP_ADD);
   1093                break;
   1094            case CRISV10_IND_SUBX:
   1095                insn_len = dec10_alux_m(env, dc, CC_OP_SUB);
   1096                break;
   1097            case CRISV10_IND_CMPX:
   1098                insn_len = dec10_alux_m(env, dc, CC_OP_CMP);
   1099                break;
   1100            case CRISV10_IND_MUL:
   1101                /* This is a reg insn coded in the mem indir space.  */
   1102                LOG_DIS("mul pc=%x opcode=%d\n", dc->pc, dc->opcode);
   1103                cris_cc_mask(dc, CC_MASK_NZVC);
   1104                dec10_reg_mul(dc, size, dc->ir & (1 << 10));
   1105                break;
   1106            case CRISV10_IND_BDAP_M:
   1107                insn_len = dec10_bdap_m(env, dc, size);
   1108                break;
   1109            default:
   1110            /*
   1111             * ADDC for v17:
   1112             *
   1113             * Instruction format: ADDC [Rs],Rd
   1114             *
   1115             *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+
   1116             *  |Destination(Rd)| 1   0   0   1   1   0   1   0 |   Source(Rs)|
   1117             *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+--+--+
   1118             *
   1119             * Instruction format: ADDC [Rs+],Rd
   1120             *
   1121             *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+
   1122             *  |Destination(Rd)| 1   1   0   1   1   0   1   0 |   Source(Rs)|
   1123             *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+
   1124             */
   1125                if (dc->opcode == CRISV17_IND_ADDC && dc->size == 2 &&
   1126                    env->pregs[PR_VR] == 17) {
   1127                    LOG_DIS("addc op=%d %d\n",  dc->src, dc->dst);
   1128                    cris_cc_mask(dc, CC_MASK_NZVC);
   1129                    insn_len += dec10_ind_alu(env, dc, CC_OP_ADDC, size);
   1130                    break;
   1131                }
   1132
   1133                LOG_DIS("pc=%x var-ind.%d %d r%d r%d\n",
   1134                          dc->pc, size, dc->opcode, dc->src, dc->dst);
   1135                cpu_abort(CPU(dc->cpu), "Unhandled opcode");
   1136                break;
   1137        }
   1138        return insn_len;
   1139    }
   1140
   1141    switch (dc->opcode) {
   1142        case CRISV10_IND_MOVE_M_SPR:
   1143            insn_len = dec10_ind_move_m_pr(env, dc);
   1144            break;
   1145        case CRISV10_IND_MOVE_SPR_M:
   1146            insn_len = dec10_ind_move_pr_m(dc);
   1147            break;
   1148        case CRISV10_IND_JUMP_M:
   1149            if (dc->src == 15) {
   1150                LOG_DIS("jump.%d %d r%d r%d direct\n", size,
   1151                         dc->opcode, dc->src, dc->dst);
   1152                imm = cpu_ldl_code(env, dc->pc + 2);
   1153                if (dc->mode == CRISV10_MODE_AUTOINC)
   1154                    insn_len += size;
   1155
   1156                c = tcg_const_tl(dc->pc + insn_len);
   1157                t_gen_mov_preg_TN(dc, dc->dst, c);
   1158                tcg_temp_free(c);
   1159                dc->jmp_pc = imm;
   1160                cris_prepare_jmp(dc, JMP_DIRECT);
   1161                dc->delayed_branch--; /* v10 has no dslot here.  */
   1162            } else {
   1163                if (dc->dst == 14) {
   1164                    LOG_DIS("break %d\n", dc->src);
   1165                    cris_evaluate_flags(dc);
   1166                    tcg_gen_movi_tl(env_pc, dc->pc + 2);
   1167                    c = tcg_const_tl(dc->src + 2);
   1168                    t_gen_mov_env_TN(trap_vector, c);
   1169                    tcg_temp_free(c);
   1170                    t_gen_raise_exception(EXCP_BREAK);
   1171                    dc->base.is_jmp = DISAS_NORETURN;
   1172                    return insn_len;
   1173                }
   1174                LOG_DIS("%d: jump.%d %d r%d r%d\n", __LINE__, size,
   1175                         dc->opcode, dc->src, dc->dst);
   1176                t[0] = tcg_temp_new();
   1177                c = tcg_const_tl(dc->pc + insn_len);
   1178                t_gen_mov_preg_TN(dc, dc->dst, c);
   1179                tcg_temp_free(c);
   1180                crisv10_prepare_memaddr(dc, t[0], size);
   1181                gen_load(dc, env_btarget, t[0], 4, 0);
   1182                insn_len += crisv10_post_memaddr(dc, size);
   1183                cris_prepare_jmp(dc, JMP_INDIRECT);
   1184                dc->delayed_branch--; /* v10 has no dslot here.  */
   1185                tcg_temp_free(t[0]);
   1186            }
   1187            break;
   1188
   1189        case CRISV10_IND_MOVEM_R_M:
   1190            LOG_DIS("movem_r_m pc=%x opcode=%d r%d r%d\n",
   1191                        dc->pc, dc->opcode, dc->dst, dc->src);
   1192            dec10_movem_r_m(dc);
   1193            break;
   1194        case CRISV10_IND_MOVEM_M_R:
   1195            LOG_DIS("movem_m_r pc=%x opcode=%d\n", dc->pc, dc->opcode);
   1196            dec10_movem_m_r(dc);
   1197            break;
   1198        case CRISV10_IND_JUMP_R:
   1199            LOG_DIS("jmp pc=%x opcode=%d r%d r%d\n",
   1200                        dc->pc, dc->opcode, dc->dst, dc->src);
   1201            tcg_gen_mov_tl(env_btarget, cpu_R[dc->src]);
   1202            c = tcg_const_tl(dc->pc + insn_len);
   1203            t_gen_mov_preg_TN(dc, dc->dst, c);
   1204            tcg_temp_free(c);
   1205            cris_prepare_jmp(dc, JMP_INDIRECT);
   1206            dc->delayed_branch--; /* v10 has no dslot here.  */
   1207            break;
   1208        case CRISV10_IND_MOVX:
   1209            insn_len = dec10_alux_m(env, dc, CC_OP_MOVE);
   1210            break;
   1211        case CRISV10_IND_ADDX:
   1212            insn_len = dec10_alux_m(env, dc, CC_OP_ADD);
   1213            break;
   1214        case CRISV10_IND_SUBX:
   1215            insn_len = dec10_alux_m(env, dc, CC_OP_SUB);
   1216            break;
   1217        case CRISV10_IND_CMPX:
   1218            insn_len = dec10_alux_m(env, dc, CC_OP_CMP);
   1219            break;
   1220        case CRISV10_IND_DIP:
   1221            insn_len = dec10_dip(env, dc);
   1222            break;
   1223        case CRISV10_IND_BCC_M:
   1224
   1225            cris_cc_mask(dc, 0);
   1226            simm = cpu_ldsw_code(env, dc->pc + 2);
   1227            simm += 4;
   1228
   1229            LOG_DIS("bcc_m: b%s %x\n", cc_name(dc->cond), dc->pc + simm);
   1230            cris_prepare_cc_branch(dc, simm, dc->cond);
   1231            insn_len = 4;
   1232            break;
   1233        default:
   1234            LOG_DIS("ERROR pc=%x opcode=%d\n", dc->pc, dc->opcode);
   1235            cpu_abort(CPU(dc->cpu), "Unhandled opcode");
   1236            break;
   1237    }
   1238
   1239    return insn_len;
   1240}
   1241
   1242static unsigned int crisv10_decoder(CPUCRISState *env, DisasContext *dc)
   1243{
   1244    unsigned int insn_len = 2;
   1245
   1246    /* Load a halfword onto the instruction register.  */
   1247    dc->ir = cpu_lduw_code(env, dc->pc);
   1248
   1249    /* Now decode it.  */
   1250    dc->opcode   = EXTRACT_FIELD(dc->ir, 6, 9);
   1251    dc->mode     = EXTRACT_FIELD(dc->ir, 10, 11);
   1252    dc->src      = EXTRACT_FIELD(dc->ir, 0, 3);
   1253    dc->size     = EXTRACT_FIELD(dc->ir, 4, 5);
   1254    dc->cond = dc->dst = EXTRACT_FIELD(dc->ir, 12, 15);
   1255    dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
   1256
   1257    dc->clear_prefix = 1;
   1258
   1259    /* FIXME: What if this insn insn't 2 in length??  */
   1260    if (dc->src == 15 || dc->dst == 15)
   1261        tcg_gen_movi_tl(cpu_R[15], dc->pc + 2);
   1262
   1263    switch (dc->mode) {
   1264        case CRISV10_MODE_QIMMEDIATE:
   1265            insn_len = dec10_quick_imm(dc);
   1266            break;
   1267        case CRISV10_MODE_REG:
   1268            insn_len = dec10_reg(dc);
   1269            break;
   1270        case CRISV10_MODE_AUTOINC:
   1271        case CRISV10_MODE_INDIRECT:
   1272            insn_len = dec10_ind(env, dc);
   1273            break;
   1274    }
   1275
   1276    if (dc->clear_prefix && dc->tb_flags & PFIX_FLAG) {
   1277        dc->tb_flags &= ~PFIX_FLAG;
   1278        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~PFIX_FLAG);
   1279        if (dc->tb_flags != dc->base.tb->flags) {
   1280            dc->cpustate_changed = 1;
   1281        }
   1282    }
   1283
   1284    /* CRISv10 locks out interrupts on dslots.  */
   1285    if (dc->delayed_branch == 2) {
   1286        cris_lock_irq(dc);
   1287    }
   1288    return insn_len;
   1289}
   1290
   1291void cris_initialize_crisv10_tcg(void)
   1292{
   1293    int i;
   1294
   1295    cc_x = tcg_global_mem_new(cpu_env,
   1296                              offsetof(CPUCRISState, cc_x), "cc_x");
   1297    cc_src = tcg_global_mem_new(cpu_env,
   1298                                offsetof(CPUCRISState, cc_src), "cc_src");
   1299    cc_dest = tcg_global_mem_new(cpu_env,
   1300                                 offsetof(CPUCRISState, cc_dest),
   1301                                 "cc_dest");
   1302    cc_result = tcg_global_mem_new(cpu_env,
   1303                                   offsetof(CPUCRISState, cc_result),
   1304                                   "cc_result");
   1305    cc_op = tcg_global_mem_new(cpu_env,
   1306                               offsetof(CPUCRISState, cc_op), "cc_op");
   1307    cc_size = tcg_global_mem_new(cpu_env,
   1308                                 offsetof(CPUCRISState, cc_size),
   1309                                 "cc_size");
   1310    cc_mask = tcg_global_mem_new(cpu_env,
   1311                                 offsetof(CPUCRISState, cc_mask),
   1312                                 "cc_mask");
   1313
   1314    env_pc = tcg_global_mem_new(cpu_env,
   1315                                offsetof(CPUCRISState, pc),
   1316                                "pc");
   1317    env_btarget = tcg_global_mem_new(cpu_env,
   1318                                     offsetof(CPUCRISState, btarget),
   1319                                     "btarget");
   1320    env_btaken = tcg_global_mem_new(cpu_env,
   1321                                    offsetof(CPUCRISState, btaken),
   1322                                    "btaken");
   1323    for (i = 0; i < 16; i++) {
   1324        cpu_R[i] = tcg_global_mem_new(cpu_env,
   1325                                      offsetof(CPUCRISState, regs[i]),
   1326                                      regnames_v10[i]);
   1327    }
   1328    for (i = 0; i < 16; i++) {
   1329        cpu_PR[i] = tcg_global_mem_new(cpu_env,
   1330                                       offsetof(CPUCRISState, pregs[i]),
   1331                                       pregnames_v10[i]);
   1332    }
   1333}