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.c (91865B)


      1/*
      2 *  CRIS emulation for qemu: main translation routines.
      3 *
      4 *  Copyright (c) 2008 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/*
     22 * FIXME:
     23 * The condition code translation is in need of attention.
     24 */
     25
     26#include "qemu/osdep.h"
     27#include "cpu.h"
     28#include "disas/disas.h"
     29#include "exec/exec-all.h"
     30#include "tcg/tcg-op.h"
     31#include "exec/helper-proto.h"
     32#include "mmu.h"
     33#include "exec/cpu_ldst.h"
     34#include "exec/translator.h"
     35#include "crisv32-decode.h"
     36#include "qemu/qemu-print.h"
     37
     38#include "exec/helper-gen.h"
     39
     40#include "exec/log.h"
     41
     42
     43#define DISAS_CRIS 0
     44#if DISAS_CRIS
     45#  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
     46#else
     47#  define LOG_DIS(...) do { } while (0)
     48#endif
     49
     50#define D(x)
     51#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
     52#define BUG_ON(x) ({if (x) BUG();})
     53
     54/*
     55 * Target-specific is_jmp field values
     56 */
     57/* Only pc was modified dynamically */
     58#define DISAS_JUMP          DISAS_TARGET_0
     59/* Cpu state was modified dynamically, including pc */
     60#define DISAS_UPDATE        DISAS_TARGET_1
     61/* Cpu state was modified dynamically, excluding pc -- use npc */
     62#define DISAS_UPDATE_NEXT   DISAS_TARGET_2
     63/* PC update for delayed branch, see cpustate_changed otherwise */
     64#define DISAS_DBRANCH       DISAS_TARGET_3
     65
     66/* Used by the decoder.  */
     67#define EXTRACT_FIELD(src, start, end) \
     68            (((src) >> start) & ((1 << (end - start + 1)) - 1))
     69
     70#define CC_MASK_NZ 0xc
     71#define CC_MASK_NZV 0xe
     72#define CC_MASK_NZVC 0xf
     73#define CC_MASK_RNZV 0x10e
     74
     75static TCGv cpu_R[16];
     76static TCGv cpu_PR[16];
     77static TCGv cc_x;
     78static TCGv cc_src;
     79static TCGv cc_dest;
     80static TCGv cc_result;
     81static TCGv cc_op;
     82static TCGv cc_size;
     83static TCGv cc_mask;
     84
     85static TCGv env_btaken;
     86static TCGv env_btarget;
     87static TCGv env_pc;
     88
     89#include "exec/gen-icount.h"
     90
     91/* This is the state at translation time.  */
     92typedef struct DisasContext {
     93    DisasContextBase base;
     94
     95    CRISCPU *cpu;
     96    target_ulong pc, ppc;
     97
     98    /* Decoder.  */
     99        unsigned int (*decoder)(CPUCRISState *env, struct DisasContext *dc);
    100    uint32_t ir;
    101    uint32_t opcode;
    102    unsigned int op1;
    103    unsigned int op2;
    104    unsigned int zsize, zzsize;
    105    unsigned int mode;
    106    unsigned int postinc;
    107
    108    unsigned int size;
    109    unsigned int src;
    110    unsigned int dst;
    111    unsigned int cond;
    112
    113    int update_cc;
    114    int cc_op;
    115    int cc_size;
    116    uint32_t cc_mask;
    117
    118    int cc_size_uptodate; /* -1 invalid or last written value.  */
    119
    120    int cc_x_uptodate;  /* 1 - ccs, 2 - known | X_FLAG. 0 not up-to-date.  */
    121    int flags_uptodate; /* Whether or not $ccs is up-to-date.  */
    122    int flags_x;
    123
    124    int clear_x; /* Clear x after this insn?  */
    125    int clear_prefix; /* Clear prefix after this insn?  */
    126    int clear_locked_irq; /* Clear the irq lockout.  */
    127    int cpustate_changed;
    128    unsigned int tb_flags; /* tb dependent flags.  */
    129
    130#define JMP_NOJMP     0
    131#define JMP_DIRECT    1
    132#define JMP_DIRECT_CC 2
    133#define JMP_INDIRECT  3
    134    int jmp; /* 0=nojmp, 1=direct, 2=indirect.  */
    135    uint32_t jmp_pc;
    136
    137    int delayed_branch;
    138} DisasContext;
    139
    140static void gen_BUG(DisasContext *dc, const char *file, int line)
    141{
    142    cpu_abort(CPU(dc->cpu), "%s:%d pc=%x\n", file, line, dc->pc);
    143}
    144
    145static const char * const regnames_v32[] =
    146{
    147    "$r0", "$r1", "$r2", "$r3",
    148    "$r4", "$r5", "$r6", "$r7",
    149    "$r8", "$r9", "$r10", "$r11",
    150    "$r12", "$r13", "$sp", "$acr",
    151};
    152
    153static const char * const pregnames_v32[] =
    154{
    155    "$bz", "$vr", "$pid", "$srs",
    156    "$wz", "$exs", "$eda", "$mof",
    157    "$dz", "$ebp", "$erp", "$srp",
    158    "$nrp", "$ccs", "$usp", "$spc",
    159};
    160
    161/* We need this table to handle preg-moves with implicit width.  */
    162static const int preg_sizes[] = {
    163    1, /* bz.  */
    164    1, /* vr.  */
    165    4, /* pid.  */
    166    1, /* srs.  */
    167    2, /* wz.  */
    168    4, 4, 4,
    169    4, 4, 4, 4,
    170    4, 4, 4, 4,
    171};
    172
    173#define t_gen_mov_TN_env(tn, member) \
    174    tcg_gen_ld_tl(tn, cpu_env, offsetof(CPUCRISState, member))
    175#define t_gen_mov_env_TN(member, tn) \
    176    tcg_gen_st_tl(tn, cpu_env, offsetof(CPUCRISState, member))
    177#define t_gen_movi_env_TN(member, c) \
    178    do { \
    179        TCGv tc = tcg_const_tl(c); \
    180        t_gen_mov_env_TN(member, tc); \
    181        tcg_temp_free(tc); \
    182    } while (0)
    183
    184static inline void t_gen_mov_TN_preg(TCGv tn, int r)
    185{
    186    assert(r >= 0 && r <= 15);
    187    if (r == PR_BZ || r == PR_WZ || r == PR_DZ) {
    188        tcg_gen_movi_tl(tn, 0);
    189    } else if (r == PR_VR) {
    190        tcg_gen_movi_tl(tn, 32);
    191    } else {
    192        tcg_gen_mov_tl(tn, cpu_PR[r]);
    193    }
    194}
    195static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
    196{
    197    assert(r >= 0 && r <= 15);
    198    if (r == PR_BZ || r == PR_WZ || r == PR_DZ) {
    199        return;
    200    } else if (r == PR_SRS) {
    201        tcg_gen_andi_tl(cpu_PR[r], tn, 3);
    202    } else {
    203        if (r == PR_PID) {
    204            gen_helper_tlb_flush_pid(cpu_env, tn);
    205        }
    206        if (dc->tb_flags & S_FLAG && r == PR_SPC) {
    207            gen_helper_spc_write(cpu_env, tn);
    208        } else if (r == PR_CCS) {
    209            dc->cpustate_changed = 1;
    210        }
    211        tcg_gen_mov_tl(cpu_PR[r], tn);
    212    }
    213}
    214
    215/* Sign extend at translation time.  */
    216static int sign_extend(unsigned int val, unsigned int width)
    217{
    218    int sval;
    219
    220    /* LSL.  */
    221    val <<= 31 - width;
    222    sval = val;
    223    /* ASR.  */
    224    sval >>= 31 - width;
    225    return sval;
    226}
    227
    228static int cris_fetch(CPUCRISState *env, DisasContext *dc, uint32_t addr,
    229              unsigned int size, unsigned int sign)
    230{
    231    int r;
    232
    233    switch (size) {
    234    case 4:
    235    {
    236        r = cpu_ldl_code(env, addr);
    237        break;
    238    }
    239    case 2:
    240    {
    241        if (sign) {
    242            r = cpu_ldsw_code(env, addr);
    243        } else {
    244            r = cpu_lduw_code(env, addr);
    245        }
    246        break;
    247    }
    248    case 1:
    249    {
    250        if (sign) {
    251            r = cpu_ldsb_code(env, addr);
    252        } else {
    253            r = cpu_ldub_code(env, addr);
    254        }
    255        break;
    256    }
    257    default:
    258        cpu_abort(CPU(dc->cpu), "Invalid fetch size %d\n", size);
    259        break;
    260    }
    261    return r;
    262}
    263
    264static void cris_lock_irq(DisasContext *dc)
    265{
    266    dc->clear_locked_irq = 0;
    267    t_gen_movi_env_TN(locked_irq, 1);
    268}
    269
    270static inline void t_gen_raise_exception(uint32_t index)
    271{
    272        TCGv_i32 tmp = tcg_const_i32(index);
    273        gen_helper_raise_exception(cpu_env, tmp);
    274        tcg_temp_free_i32(tmp);
    275}
    276
    277static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
    278{
    279    TCGv t0, t_31;
    280
    281    t0 = tcg_temp_new();
    282    t_31 = tcg_const_tl(31);
    283    tcg_gen_shl_tl(d, a, b);
    284
    285    tcg_gen_sub_tl(t0, t_31, b);
    286    tcg_gen_sar_tl(t0, t0, t_31);
    287    tcg_gen_and_tl(t0, t0, d);
    288    tcg_gen_xor_tl(d, d, t0);
    289    tcg_temp_free(t0);
    290    tcg_temp_free(t_31);
    291}
    292
    293static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
    294{
    295    TCGv t0, t_31;
    296
    297    t0 = tcg_temp_new();
    298    t_31 = tcg_temp_new();
    299    tcg_gen_shr_tl(d, a, b);
    300
    301    tcg_gen_movi_tl(t_31, 31);
    302    tcg_gen_sub_tl(t0, t_31, b);
    303    tcg_gen_sar_tl(t0, t0, t_31);
    304    tcg_gen_and_tl(t0, t0, d);
    305    tcg_gen_xor_tl(d, d, t0);
    306    tcg_temp_free(t0);
    307    tcg_temp_free(t_31);
    308}
    309
    310static void t_gen_asr(TCGv d, TCGv a, TCGv b)
    311{
    312    TCGv t0, t_31;
    313
    314    t0 = tcg_temp_new();
    315    t_31 = tcg_temp_new();
    316    tcg_gen_sar_tl(d, a, b);
    317
    318    tcg_gen_movi_tl(t_31, 31);
    319    tcg_gen_sub_tl(t0, t_31, b);
    320    tcg_gen_sar_tl(t0, t0, t_31);
    321    tcg_gen_or_tl(d, d, t0);
    322    tcg_temp_free(t0);
    323    tcg_temp_free(t_31);
    324}
    325
    326static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
    327{
    328    TCGv t = tcg_temp_new();
    329
    330    /*
    331     * d <<= 1
    332     * if (d >= s)
    333     *    d -= s;
    334     */
    335    tcg_gen_shli_tl(d, a, 1);
    336    tcg_gen_sub_tl(t, d, b);
    337    tcg_gen_movcond_tl(TCG_COND_GEU, d, d, b, t, d);
    338    tcg_temp_free(t);
    339}
    340
    341static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
    342{
    343    TCGv t;
    344
    345    /*
    346     * d <<= 1
    347     * if (n)
    348     *    d += s;
    349     */
    350    t = tcg_temp_new();
    351    tcg_gen_shli_tl(d, a, 1);
    352    tcg_gen_shli_tl(t, ccs, 31 - 3);
    353    tcg_gen_sari_tl(t, t, 31);
    354    tcg_gen_and_tl(t, t, b);
    355    tcg_gen_add_tl(d, d, t);
    356    tcg_temp_free(t);
    357}
    358
    359/* Extended arithmetics on CRIS.  */
    360static inline void t_gen_add_flag(TCGv d, int flag)
    361{
    362    TCGv c;
    363
    364    c = tcg_temp_new();
    365    t_gen_mov_TN_preg(c, PR_CCS);
    366    /* Propagate carry into d.  */
    367    tcg_gen_andi_tl(c, c, 1 << flag);
    368    if (flag) {
    369        tcg_gen_shri_tl(c, c, flag);
    370    }
    371    tcg_gen_add_tl(d, d, c);
    372    tcg_temp_free(c);
    373}
    374
    375static inline void t_gen_addx_carry(DisasContext *dc, TCGv d)
    376{
    377    if (dc->flags_x) {
    378        TCGv c = tcg_temp_new();
    379
    380        t_gen_mov_TN_preg(c, PR_CCS);
    381        /* C flag is already at bit 0.  */
    382        tcg_gen_andi_tl(c, c, C_FLAG);
    383        tcg_gen_add_tl(d, d, c);
    384        tcg_temp_free(c);
    385    }
    386}
    387
    388static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)
    389{
    390    if (dc->flags_x) {
    391        TCGv c = tcg_temp_new();
    392
    393        t_gen_mov_TN_preg(c, PR_CCS);
    394        /* C flag is already at bit 0.  */
    395        tcg_gen_andi_tl(c, c, C_FLAG);
    396        tcg_gen_sub_tl(d, d, c);
    397        tcg_temp_free(c);
    398    }
    399}
    400
    401/* Swap the two bytes within each half word of the s operand.
    402   T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff)  */
    403static inline void t_gen_swapb(TCGv d, TCGv s)
    404{
    405    TCGv t, org_s;
    406
    407    t = tcg_temp_new();
    408    org_s = tcg_temp_new();
    409
    410    /* d and s may refer to the same object.  */
    411    tcg_gen_mov_tl(org_s, s);
    412    tcg_gen_shli_tl(t, org_s, 8);
    413    tcg_gen_andi_tl(d, t, 0xff00ff00);
    414    tcg_gen_shri_tl(t, org_s, 8);
    415    tcg_gen_andi_tl(t, t, 0x00ff00ff);
    416    tcg_gen_or_tl(d, d, t);
    417    tcg_temp_free(t);
    418    tcg_temp_free(org_s);
    419}
    420
    421/* Swap the halfwords of the s operand.  */
    422static inline void t_gen_swapw(TCGv d, TCGv s)
    423{
    424    TCGv t;
    425    /* d and s refer the same object.  */
    426    t = tcg_temp_new();
    427    tcg_gen_mov_tl(t, s);
    428    tcg_gen_shli_tl(d, t, 16);
    429    tcg_gen_shri_tl(t, t, 16);
    430    tcg_gen_or_tl(d, d, t);
    431    tcg_temp_free(t);
    432}
    433
    434/* Reverse the within each byte.
    435   T0 = (((T0 << 7) & 0x80808080) |
    436   ((T0 << 5) & 0x40404040) |
    437   ((T0 << 3) & 0x20202020) |
    438   ((T0 << 1) & 0x10101010) |
    439   ((T0 >> 1) & 0x08080808) |
    440   ((T0 >> 3) & 0x04040404) |
    441   ((T0 >> 5) & 0x02020202) |
    442   ((T0 >> 7) & 0x01010101));
    443 */
    444static void t_gen_swapr(TCGv d, TCGv s)
    445{
    446    static const struct {
    447        int shift; /* LSL when positive, LSR when negative.  */
    448        uint32_t mask;
    449    } bitrev[] = {
    450        {7, 0x80808080},
    451        {5, 0x40404040},
    452        {3, 0x20202020},
    453        {1, 0x10101010},
    454        {-1, 0x08080808},
    455        {-3, 0x04040404},
    456        {-5, 0x02020202},
    457        {-7, 0x01010101}
    458    };
    459    int i;
    460    TCGv t, org_s;
    461
    462    /* d and s refer the same object.  */
    463    t = tcg_temp_new();
    464    org_s = tcg_temp_new();
    465    tcg_gen_mov_tl(org_s, s);
    466
    467    tcg_gen_shli_tl(t, org_s,  bitrev[0].shift);
    468    tcg_gen_andi_tl(d, t,  bitrev[0].mask);
    469    for (i = 1; i < ARRAY_SIZE(bitrev); i++) {
    470        if (bitrev[i].shift >= 0) {
    471            tcg_gen_shli_tl(t, org_s,  bitrev[i].shift);
    472        } else {
    473            tcg_gen_shri_tl(t, org_s,  -bitrev[i].shift);
    474        }
    475        tcg_gen_andi_tl(t, t,  bitrev[i].mask);
    476        tcg_gen_or_tl(d, d, t);
    477    }
    478    tcg_temp_free(t);
    479    tcg_temp_free(org_s);
    480}
    481
    482static bool use_goto_tb(DisasContext *dc, target_ulong dest)
    483{
    484    return translator_use_goto_tb(&dc->base, dest);
    485}
    486
    487static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
    488{
    489    if (use_goto_tb(dc, dest)) {
    490        tcg_gen_goto_tb(n);
    491        tcg_gen_movi_tl(env_pc, dest);
    492        tcg_gen_exit_tb(dc->base.tb, n);
    493    } else {
    494        tcg_gen_movi_tl(env_pc, dest);
    495        tcg_gen_lookup_and_goto_ptr();
    496    }
    497}
    498
    499static inline void cris_clear_x_flag(DisasContext *dc)
    500{
    501    if (dc->flags_x) {
    502        dc->flags_uptodate = 0;
    503    }
    504    dc->flags_x = 0;
    505}
    506
    507static void cris_flush_cc_state(DisasContext *dc)
    508{
    509    if (dc->cc_size_uptodate != dc->cc_size) {
    510        tcg_gen_movi_tl(cc_size, dc->cc_size);
    511        dc->cc_size_uptodate = dc->cc_size;
    512    }
    513    tcg_gen_movi_tl(cc_op, dc->cc_op);
    514    tcg_gen_movi_tl(cc_mask, dc->cc_mask);
    515}
    516
    517static void cris_evaluate_flags(DisasContext *dc)
    518{
    519    if (dc->flags_uptodate) {
    520        return;
    521    }
    522
    523    cris_flush_cc_state(dc);
    524
    525    switch (dc->cc_op) {
    526    case CC_OP_MCP:
    527        gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS], cpu_env,
    528                cpu_PR[PR_CCS], cc_src,
    529                cc_dest, cc_result);
    530        break;
    531    case CC_OP_MULS:
    532        gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS], cpu_env,
    533                cpu_PR[PR_CCS], cc_result,
    534                cpu_PR[PR_MOF]);
    535        break;
    536    case CC_OP_MULU:
    537        gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS], cpu_env,
    538                cpu_PR[PR_CCS], cc_result,
    539                cpu_PR[PR_MOF]);
    540        break;
    541    case CC_OP_MOVE:
    542    case CC_OP_AND:
    543    case CC_OP_OR:
    544    case CC_OP_XOR:
    545    case CC_OP_ASR:
    546    case CC_OP_LSR:
    547    case CC_OP_LSL:
    548        switch (dc->cc_size) {
    549        case 4:
    550            gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
    551                    cpu_env, cpu_PR[PR_CCS], cc_result);
    552            break;
    553        case 2:
    554            gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
    555                    cpu_env, cpu_PR[PR_CCS], cc_result);
    556            break;
    557        default:
    558            gen_helper_evaluate_flags(cpu_env);
    559            break;
    560        }
    561        break;
    562    case CC_OP_FLAGS:
    563        /* live.  */
    564        break;
    565    case CC_OP_SUB:
    566    case CC_OP_CMP:
    567        if (dc->cc_size == 4) {
    568            gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS], cpu_env,
    569                    cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
    570        } else {
    571            gen_helper_evaluate_flags(cpu_env);
    572        }
    573
    574        break;
    575    default:
    576        switch (dc->cc_size) {
    577        case 4:
    578            gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS], cpu_env,
    579                    cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
    580            break;
    581        default:
    582            gen_helper_evaluate_flags(cpu_env);
    583            break;
    584        }
    585        break;
    586    }
    587
    588    if (dc->flags_x) {
    589        tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], X_FLAG);
    590    } else if (dc->cc_op == CC_OP_FLAGS) {
    591        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~X_FLAG);
    592    }
    593    dc->flags_uptodate = 1;
    594}
    595
    596static void cris_cc_mask(DisasContext *dc, unsigned int mask)
    597{
    598    uint32_t ovl;
    599
    600    if (!mask) {
    601        dc->update_cc = 0;
    602        return;
    603    }
    604
    605    /* Check if we need to evaluate the condition codes due to
    606       CC overlaying.  */
    607    ovl = (dc->cc_mask ^ mask) & ~mask;
    608    if (ovl) {
    609        /* TODO: optimize this case. It trigs all the time.  */
    610        cris_evaluate_flags(dc);
    611    }
    612    dc->cc_mask = mask;
    613    dc->update_cc = 1;
    614}
    615
    616static void cris_update_cc_op(DisasContext *dc, int op, int size)
    617{
    618    dc->cc_op = op;
    619    dc->cc_size = size;
    620    dc->flags_uptodate = 0;
    621}
    622
    623static inline void cris_update_cc_x(DisasContext *dc)
    624{
    625    /* Save the x flag state at the time of the cc snapshot.  */
    626    if (dc->cc_x_uptodate == (2 | dc->flags_x)) {
    627        return;
    628    }
    629    tcg_gen_movi_tl(cc_x, dc->flags_x);
    630    dc->cc_x_uptodate = 2 | dc->flags_x;
    631}
    632
    633/* Update cc prior to executing ALU op. Needs source operands untouched.  */
    634static void cris_pre_alu_update_cc(DisasContext *dc, int op, 
    635                   TCGv dst, TCGv src, int size)
    636{
    637    if (dc->update_cc) {
    638        cris_update_cc_op(dc, op, size);
    639        tcg_gen_mov_tl(cc_src, src);
    640
    641        if (op != CC_OP_MOVE
    642            && op != CC_OP_AND
    643            && op != CC_OP_OR
    644            && op != CC_OP_XOR
    645            && op != CC_OP_ASR
    646            && op != CC_OP_LSR
    647            && op != CC_OP_LSL) {
    648            tcg_gen_mov_tl(cc_dest, dst);
    649        }
    650
    651        cris_update_cc_x(dc);
    652    }
    653}
    654
    655/* Update cc after executing ALU op. needs the result.  */
    656static inline void cris_update_result(DisasContext *dc, TCGv res)
    657{
    658    if (dc->update_cc) {
    659        tcg_gen_mov_tl(cc_result, res);
    660    }
    661}
    662
    663/* Returns one if the write back stage should execute.  */
    664static void cris_alu_op_exec(DisasContext *dc, int op, 
    665                   TCGv dst, TCGv a, TCGv b, int size)
    666{
    667    /* Emit the ALU insns.  */
    668    switch (op) {
    669    case CC_OP_ADD:
    670        tcg_gen_add_tl(dst, a, b);
    671        /* Extended arithmetics.  */
    672        t_gen_addx_carry(dc, dst);
    673        break;
    674    case CC_OP_ADDC:
    675        tcg_gen_add_tl(dst, a, b);
    676        t_gen_add_flag(dst, 0); /* C_FLAG.  */
    677        break;
    678    case CC_OP_MCP:
    679        tcg_gen_add_tl(dst, a, b);
    680        t_gen_add_flag(dst, 8); /* R_FLAG.  */
    681        break;
    682    case CC_OP_SUB:
    683        tcg_gen_sub_tl(dst, a, b);
    684        /* Extended arithmetics.  */
    685        t_gen_subx_carry(dc, dst);
    686        break;
    687    case CC_OP_MOVE:
    688        tcg_gen_mov_tl(dst, b);
    689        break;
    690    case CC_OP_OR:
    691        tcg_gen_or_tl(dst, a, b);
    692        break;
    693    case CC_OP_AND:
    694        tcg_gen_and_tl(dst, a, b);
    695        break;
    696    case CC_OP_XOR:
    697        tcg_gen_xor_tl(dst, a, b);
    698        break;
    699    case CC_OP_LSL:
    700        t_gen_lsl(dst, a, b);
    701        break;
    702    case CC_OP_LSR:
    703        t_gen_lsr(dst, a, b);
    704        break;
    705    case CC_OP_ASR:
    706        t_gen_asr(dst, a, b);
    707        break;
    708    case CC_OP_NEG:
    709        tcg_gen_neg_tl(dst, b);
    710        /* Extended arithmetics.  */
    711        t_gen_subx_carry(dc, dst);
    712        break;
    713    case CC_OP_LZ:
    714        tcg_gen_clzi_tl(dst, b, TARGET_LONG_BITS);
    715        break;
    716    case CC_OP_MULS:
    717        tcg_gen_muls2_tl(dst, cpu_PR[PR_MOF], a, b);
    718        break;
    719    case CC_OP_MULU:
    720        tcg_gen_mulu2_tl(dst, cpu_PR[PR_MOF], a, b);
    721        break;
    722    case CC_OP_DSTEP:
    723        t_gen_cris_dstep(dst, a, b);
    724        break;
    725    case CC_OP_MSTEP:
    726        t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]);
    727        break;
    728    case CC_OP_BOUND:
    729        tcg_gen_movcond_tl(TCG_COND_LEU, dst, a, b, a, b);
    730        break;
    731    case CC_OP_CMP:
    732        tcg_gen_sub_tl(dst, a, b);
    733        /* Extended arithmetics.  */
    734        t_gen_subx_carry(dc, dst);
    735        break;
    736    default:
    737        qemu_log_mask(LOG_GUEST_ERROR, "illegal ALU op.\n");
    738        BUG();
    739        break;
    740    }
    741
    742    if (size == 1) {
    743        tcg_gen_andi_tl(dst, dst, 0xff);
    744    } else if (size == 2) {
    745        tcg_gen_andi_tl(dst, dst, 0xffff);
    746    }
    747}
    748
    749static void cris_alu(DisasContext *dc, int op,
    750                   TCGv d, TCGv op_a, TCGv op_b, int size)
    751{
    752    TCGv tmp;
    753    int writeback;
    754
    755    writeback = 1;
    756
    757    if (op == CC_OP_CMP) {
    758        tmp = tcg_temp_new();
    759        writeback = 0;
    760    } else if (size == 4) {
    761        tmp = d;
    762        writeback = 0;
    763    } else {
    764        tmp = tcg_temp_new();
    765    }
    766
    767
    768    cris_pre_alu_update_cc(dc, op, op_a, op_b, size);
    769    cris_alu_op_exec(dc, op, tmp, op_a, op_b, size);
    770    cris_update_result(dc, tmp);
    771
    772    /* Writeback.  */
    773    if (writeback) {
    774        if (size == 1) {
    775            tcg_gen_andi_tl(d, d, ~0xff);
    776        } else {
    777            tcg_gen_andi_tl(d, d, ~0xffff);
    778        }
    779        tcg_gen_or_tl(d, d, tmp);
    780    }
    781    if (tmp != d) {
    782        tcg_temp_free(tmp);
    783    }
    784}
    785
    786static int arith_cc(DisasContext *dc)
    787{
    788    if (dc->update_cc) {
    789        switch (dc->cc_op) {
    790        case CC_OP_ADDC: return 1;
    791        case CC_OP_ADD: return 1;
    792        case CC_OP_SUB: return 1;
    793        case CC_OP_DSTEP: return 1;
    794        case CC_OP_LSL: return 1;
    795        case CC_OP_LSR: return 1;
    796        case CC_OP_ASR: return 1;
    797        case CC_OP_CMP: return 1;
    798        case CC_OP_NEG: return 1;
    799        case CC_OP_OR: return 1;
    800        case CC_OP_AND: return 1;
    801        case CC_OP_XOR: return 1;
    802        case CC_OP_MULU: return 1;
    803        case CC_OP_MULS: return 1;
    804        default:
    805            return 0;
    806        }
    807    }
    808    return 0;
    809}
    810
    811static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
    812{
    813    int arith_opt, move_opt;
    814
    815    /* TODO: optimize more condition codes.  */
    816
    817    /*
    818     * If the flags are live, we've gotta look into the bits of CCS.
    819     * Otherwise, if we just did an arithmetic operation we try to
    820     * evaluate the condition code faster.
    821     *
    822     * When this function is done, T0 should be non-zero if the condition
    823     * code is true.
    824     */
    825    arith_opt = arith_cc(dc) && !dc->flags_uptodate;
    826    move_opt = (dc->cc_op == CC_OP_MOVE);
    827    switch (cond) {
    828    case CC_EQ:
    829        if ((arith_opt || move_opt)
    830                && dc->cc_x_uptodate != (2 | X_FLAG)) {
    831            tcg_gen_setcondi_tl(TCG_COND_EQ, cc, cc_result, 0);
    832        } else {
    833            cris_evaluate_flags(dc);
    834            tcg_gen_andi_tl(cc,
    835                    cpu_PR[PR_CCS], Z_FLAG);
    836        }
    837        break;
    838    case CC_NE:
    839        if ((arith_opt || move_opt)
    840                && dc->cc_x_uptodate != (2 | X_FLAG)) {
    841            tcg_gen_mov_tl(cc, cc_result);
    842        } else {
    843            cris_evaluate_flags(dc);
    844            tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
    845                    Z_FLAG);
    846            tcg_gen_andi_tl(cc, cc, Z_FLAG);
    847        }
    848        break;
    849    case CC_CS:
    850        cris_evaluate_flags(dc);
    851        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], C_FLAG);
    852        break;
    853    case CC_CC:
    854        cris_evaluate_flags(dc);
    855        tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], C_FLAG);
    856        tcg_gen_andi_tl(cc, cc, C_FLAG);
    857        break;
    858    case CC_VS:
    859        cris_evaluate_flags(dc);
    860        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], V_FLAG);
    861        break;
    862    case CC_VC:
    863        cris_evaluate_flags(dc);
    864        tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
    865                V_FLAG);
    866        tcg_gen_andi_tl(cc, cc, V_FLAG);
    867        break;
    868    case CC_PL:
    869        if (arith_opt || move_opt) {
    870            int bits = 31;
    871
    872            if (dc->cc_size == 1) {
    873                bits = 7;
    874            } else if (dc->cc_size == 2) {
    875                bits = 15;
    876            }
    877
    878            tcg_gen_shri_tl(cc, cc_result, bits);
    879            tcg_gen_xori_tl(cc, cc, 1);
    880        } else {
    881            cris_evaluate_flags(dc);
    882            tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
    883                    N_FLAG);
    884            tcg_gen_andi_tl(cc, cc, N_FLAG);
    885        }
    886        break;
    887    case CC_MI:
    888        if (arith_opt || move_opt) {
    889            int bits = 31;
    890
    891            if (dc->cc_size == 1) {
    892                bits = 7;
    893            } else if (dc->cc_size == 2) {
    894                bits = 15;
    895            }
    896
    897            tcg_gen_shri_tl(cc, cc_result, bits);
    898            tcg_gen_andi_tl(cc, cc, 1);
    899        } else {
    900            cris_evaluate_flags(dc);
    901            tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
    902                    N_FLAG);
    903        }
    904        break;
    905    case CC_LS:
    906        cris_evaluate_flags(dc);
    907        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
    908                C_FLAG | Z_FLAG);
    909        break;
    910    case CC_HI:
    911        cris_evaluate_flags(dc);
    912        {
    913            TCGv tmp;
    914
    915            tmp = tcg_temp_new();
    916            tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
    917                    C_FLAG | Z_FLAG);
    918            /* Overlay the C flag on top of the Z.  */
    919            tcg_gen_shli_tl(cc, tmp, 2);
    920            tcg_gen_and_tl(cc, tmp, cc);
    921            tcg_gen_andi_tl(cc, cc, Z_FLAG);
    922
    923            tcg_temp_free(tmp);
    924        }
    925        break;
    926    case CC_GE:
    927        cris_evaluate_flags(dc);
    928        /* Overlay the V flag on top of the N.  */
    929        tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
    930        tcg_gen_xor_tl(cc,
    931                cpu_PR[PR_CCS], cc);
    932        tcg_gen_andi_tl(cc, cc, N_FLAG);
    933        tcg_gen_xori_tl(cc, cc, N_FLAG);
    934        break;
    935    case CC_LT:
    936        cris_evaluate_flags(dc);
    937        /* Overlay the V flag on top of the N.  */
    938        tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
    939        tcg_gen_xor_tl(cc,
    940                cpu_PR[PR_CCS], cc);
    941        tcg_gen_andi_tl(cc, cc, N_FLAG);
    942        break;
    943    case CC_GT:
    944        cris_evaluate_flags(dc);
    945        {
    946            TCGv n, z;
    947
    948            n = tcg_temp_new();
    949            z = tcg_temp_new();
    950
    951            /* To avoid a shift we overlay everything on
    952                   the V flag.  */
    953            tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
    954            tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
    955            /* invert Z.  */
    956            tcg_gen_xori_tl(z, z, 2);
    957
    958            tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
    959            tcg_gen_xori_tl(n, n, 2);
    960            tcg_gen_and_tl(cc, z, n);
    961            tcg_gen_andi_tl(cc, cc, 2);
    962
    963            tcg_temp_free(n);
    964            tcg_temp_free(z);
    965        }
    966        break;
    967    case CC_LE:
    968        cris_evaluate_flags(dc);
    969        {
    970            TCGv n, z;
    971
    972            n = tcg_temp_new();
    973            z = tcg_temp_new();
    974
    975            /* To avoid a shift we overlay everything on
    976                   the V flag.  */
    977            tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
    978            tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
    979
    980            tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
    981            tcg_gen_or_tl(cc, z, n);
    982            tcg_gen_andi_tl(cc, cc, 2);
    983
    984            tcg_temp_free(n);
    985            tcg_temp_free(z);
    986        }
    987        break;
    988    case CC_P:
    989        cris_evaluate_flags(dc);
    990        tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], P_FLAG);
    991        break;
    992    case CC_A:
    993        tcg_gen_movi_tl(cc, 1);
    994        break;
    995    default:
    996        BUG();
    997        break;
    998    };
    999}
   1000
   1001static void cris_store_direct_jmp(DisasContext *dc)
   1002{
   1003    /* Store the direct jmp state into the cpu-state.  */
   1004    if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
   1005        if (dc->jmp == JMP_DIRECT) {
   1006            tcg_gen_movi_tl(env_btaken, 1);
   1007        }
   1008        tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
   1009        dc->jmp = JMP_INDIRECT;
   1010    }
   1011}
   1012
   1013static void cris_prepare_cc_branch (DisasContext *dc, 
   1014                    int offset, int cond)
   1015{
   1016    /* This helps us re-schedule the micro-code to insns in delay-slots
   1017       before the actual jump.  */
   1018    dc->delayed_branch = 2;
   1019    dc->jmp = JMP_DIRECT_CC;
   1020    dc->jmp_pc = dc->pc + offset;
   1021
   1022    gen_tst_cc(dc, env_btaken, cond);
   1023    tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
   1024}
   1025
   1026
   1027/* jumps, when the dest is in a live reg for example. Direct should be set
   1028   when the dest addr is constant to allow tb chaining.  */
   1029static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
   1030{
   1031    /* This helps us re-schedule the micro-code to insns in delay-slots
   1032       before the actual jump.  */
   1033    dc->delayed_branch = 2;
   1034    dc->jmp = type;
   1035    if (type == JMP_INDIRECT) {
   1036        tcg_gen_movi_tl(env_btaken, 1);
   1037    }
   1038}
   1039
   1040static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
   1041{
   1042    int mem_index = cpu_mmu_index(&dc->cpu->env, false);
   1043
   1044    /* If we get a fault on a delayslot we must keep the jmp state in
   1045       the cpu-state to be able to re-execute the jmp.  */
   1046    if (dc->delayed_branch == 1) {
   1047        cris_store_direct_jmp(dc);
   1048    }
   1049
   1050    tcg_gen_qemu_ld_i64(dst, addr, mem_index, MO_TEQ);
   1051}
   1052
   1053static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, 
   1054             unsigned int size, int sign)
   1055{
   1056    int mem_index = cpu_mmu_index(&dc->cpu->env, false);
   1057
   1058    /* If we get a fault on a delayslot we must keep the jmp state in
   1059       the cpu-state to be able to re-execute the jmp.  */
   1060    if (dc->delayed_branch == 1) {
   1061        cris_store_direct_jmp(dc);
   1062    }
   1063
   1064    tcg_gen_qemu_ld_tl(dst, addr, mem_index,
   1065                       MO_TE + ctz32(size) + (sign ? MO_SIGN : 0));
   1066}
   1067
   1068static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
   1069               unsigned int size)
   1070{
   1071    int mem_index = cpu_mmu_index(&dc->cpu->env, false);
   1072
   1073    /* If we get a fault on a delayslot we must keep the jmp state in
   1074       the cpu-state to be able to re-execute the jmp.  */
   1075    if (dc->delayed_branch == 1) {
   1076        cris_store_direct_jmp(dc);
   1077    }
   1078
   1079
   1080    /* Conditional writes. We only support the kind were X and P are known
   1081       at translation time.  */
   1082    if (dc->flags_x && (dc->tb_flags & P_FLAG)) {
   1083        dc->postinc = 0;
   1084        cris_evaluate_flags(dc);
   1085        tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
   1086        return;
   1087    }
   1088
   1089    tcg_gen_qemu_st_tl(val, addr, mem_index, MO_TE + ctz32(size));
   1090
   1091    if (dc->flags_x) {
   1092        cris_evaluate_flags(dc);
   1093        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
   1094    }
   1095}
   1096
   1097static inline void t_gen_sext(TCGv d, TCGv s, int size)
   1098{
   1099    if (size == 1) {
   1100        tcg_gen_ext8s_i32(d, s);
   1101    } else if (size == 2) {
   1102        tcg_gen_ext16s_i32(d, s);
   1103    } else {
   1104        tcg_gen_mov_tl(d, s);
   1105    }
   1106}
   1107
   1108static inline void t_gen_zext(TCGv d, TCGv s, int size)
   1109{
   1110    if (size == 1) {
   1111        tcg_gen_ext8u_i32(d, s);
   1112    } else if (size == 2) {
   1113        tcg_gen_ext16u_i32(d, s);
   1114    } else {
   1115        tcg_gen_mov_tl(d, s);
   1116    }
   1117}
   1118
   1119#if DISAS_CRIS
   1120static char memsize_char(int size)
   1121{
   1122    switch (size) {
   1123    case 1: return 'b';
   1124    case 2: return 'w';
   1125    case 4: return 'd';
   1126    default:
   1127        return 'x';
   1128    }
   1129}
   1130#endif
   1131
   1132static inline unsigned int memsize_z(DisasContext *dc)
   1133{
   1134    return dc->zsize + 1;
   1135}
   1136
   1137static inline unsigned int memsize_zz(DisasContext *dc)
   1138{
   1139    switch (dc->zzsize) {
   1140    case 0: return 1;
   1141    case 1: return 2;
   1142    default:
   1143        return 4;
   1144    }
   1145}
   1146
   1147static inline void do_postinc (DisasContext *dc, int size)
   1148{
   1149    if (dc->postinc) {
   1150        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
   1151    }
   1152}
   1153
   1154static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
   1155                   int size, int s_ext, TCGv dst)
   1156{
   1157    if (s_ext) {
   1158        t_gen_sext(dst, cpu_R[rs], size);
   1159    } else {
   1160        t_gen_zext(dst, cpu_R[rs], size);
   1161    }
   1162}
   1163
   1164/* Prepare T0 and T1 for a register alu operation.
   1165   s_ext decides if the operand1 should be sign-extended or zero-extended when
   1166   needed.  */
   1167static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
   1168              int size, int s_ext, TCGv dst, TCGv src)
   1169{
   1170    dec_prep_move_r(dc, rs, rd, size, s_ext, src);
   1171
   1172    if (s_ext) {
   1173        t_gen_sext(dst, cpu_R[rd], size);
   1174    } else {
   1175        t_gen_zext(dst, cpu_R[rd], size);
   1176    }
   1177}
   1178
   1179static int dec_prep_move_m(CPUCRISState *env, DisasContext *dc,
   1180                           int s_ext, int memsize, TCGv dst)
   1181{
   1182    unsigned int rs;
   1183    uint32_t imm;
   1184    int is_imm;
   1185    int insn_len = 2;
   1186
   1187    rs = dc->op1;
   1188    is_imm = rs == 15 && dc->postinc;
   1189
   1190    /* Load [$rs] onto T1.  */
   1191    if (is_imm) {
   1192        insn_len = 2 + memsize;
   1193        if (memsize == 1) {
   1194            insn_len++;
   1195        }
   1196
   1197        imm = cris_fetch(env, dc, dc->pc + 2, memsize, s_ext);
   1198        tcg_gen_movi_tl(dst, imm);
   1199        dc->postinc = 0;
   1200    } else {
   1201        cris_flush_cc_state(dc);
   1202        gen_load(dc, dst, cpu_R[rs], memsize, 0);
   1203        if (s_ext) {
   1204            t_gen_sext(dst, dst, memsize);
   1205        } else {
   1206            t_gen_zext(dst, dst, memsize);
   1207        }
   1208    }
   1209    return insn_len;
   1210}
   1211
   1212/* Prepare T0 and T1 for a memory + alu operation.
   1213   s_ext decides if the operand1 should be sign-extended or zero-extended when
   1214   needed.  */
   1215static int dec_prep_alu_m(CPUCRISState *env, DisasContext *dc,
   1216                          int s_ext, int memsize, TCGv dst, TCGv src)
   1217{
   1218    int insn_len;
   1219
   1220    insn_len = dec_prep_move_m(env, dc, s_ext, memsize, src);
   1221    tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
   1222    return insn_len;
   1223}
   1224
   1225#if DISAS_CRIS
   1226static const char *cc_name(int cc)
   1227{
   1228    static const char * const cc_names[16] = {
   1229        "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
   1230        "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
   1231    };
   1232    assert(cc < 16);
   1233    return cc_names[cc];
   1234}
   1235#endif
   1236
   1237/* Start of insn decoders.  */
   1238
   1239static int dec_bccq(CPUCRISState *env, DisasContext *dc)
   1240{
   1241    int32_t offset;
   1242    int sign;
   1243    uint32_t cond = dc->op2;
   1244
   1245    offset = EXTRACT_FIELD(dc->ir, 1, 7);
   1246    sign = EXTRACT_FIELD(dc->ir, 0, 0);
   1247
   1248    offset *= 2;
   1249    offset |= sign << 8;
   1250    offset = sign_extend(offset, 8);
   1251
   1252    LOG_DIS("b%s %x\n", cc_name(cond), dc->pc + offset);
   1253
   1254    /* op2 holds the condition-code.  */
   1255    cris_cc_mask(dc, 0);
   1256    cris_prepare_cc_branch(dc, offset, cond);
   1257    return 2;
   1258}
   1259static int dec_addoq(CPUCRISState *env, DisasContext *dc)
   1260{
   1261    int32_t imm;
   1262
   1263    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
   1264    imm = sign_extend(dc->op1, 7);
   1265
   1266    LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
   1267    cris_cc_mask(dc, 0);
   1268    /* Fetch register operand,  */
   1269    tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
   1270
   1271    return 2;
   1272}
   1273static int dec_addq(CPUCRISState *env, DisasContext *dc)
   1274{
   1275    TCGv c;
   1276    LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
   1277
   1278    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
   1279
   1280    cris_cc_mask(dc, CC_MASK_NZVC);
   1281
   1282    c = tcg_const_tl(dc->op1);
   1283    cris_alu(dc, CC_OP_ADD,
   1284            cpu_R[dc->op2], cpu_R[dc->op2], c, 4);
   1285    tcg_temp_free(c);
   1286    return 2;
   1287}
   1288static int dec_moveq(CPUCRISState *env, DisasContext *dc)
   1289{
   1290    uint32_t imm;
   1291
   1292    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
   1293    imm = sign_extend(dc->op1, 5);
   1294    LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
   1295
   1296    tcg_gen_movi_tl(cpu_R[dc->op2], imm);
   1297    return 2;
   1298}
   1299static int dec_subq(CPUCRISState *env, DisasContext *dc)
   1300{
   1301    TCGv c;
   1302    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
   1303
   1304    LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2);
   1305
   1306    cris_cc_mask(dc, CC_MASK_NZVC);
   1307    c = tcg_const_tl(dc->op1);
   1308    cris_alu(dc, CC_OP_SUB,
   1309            cpu_R[dc->op2], cpu_R[dc->op2], c, 4);
   1310    tcg_temp_free(c);
   1311    return 2;
   1312}
   1313static int dec_cmpq(CPUCRISState *env, DisasContext *dc)
   1314{
   1315    uint32_t imm;
   1316    TCGv c;
   1317    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
   1318    imm = sign_extend(dc->op1, 5);
   1319
   1320    LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
   1321    cris_cc_mask(dc, CC_MASK_NZVC);
   1322
   1323    c = tcg_const_tl(imm);
   1324    cris_alu(dc, CC_OP_CMP,
   1325            cpu_R[dc->op2], cpu_R[dc->op2], c, 4);
   1326    tcg_temp_free(c);
   1327    return 2;
   1328}
   1329static int dec_andq(CPUCRISState *env, DisasContext *dc)
   1330{
   1331    uint32_t imm;
   1332    TCGv c;
   1333    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
   1334    imm = sign_extend(dc->op1, 5);
   1335
   1336    LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
   1337    cris_cc_mask(dc, CC_MASK_NZ);
   1338
   1339    c = tcg_const_tl(imm);
   1340    cris_alu(dc, CC_OP_AND,
   1341            cpu_R[dc->op2], cpu_R[dc->op2], c, 4);
   1342    tcg_temp_free(c);
   1343    return 2;
   1344}
   1345static int dec_orq(CPUCRISState *env, DisasContext *dc)
   1346{
   1347    uint32_t imm;
   1348    TCGv c;
   1349    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
   1350    imm = sign_extend(dc->op1, 5);
   1351    LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
   1352    cris_cc_mask(dc, CC_MASK_NZ);
   1353
   1354    c = tcg_const_tl(imm);
   1355    cris_alu(dc, CC_OP_OR,
   1356            cpu_R[dc->op2], cpu_R[dc->op2], c, 4);
   1357    tcg_temp_free(c);
   1358    return 2;
   1359}
   1360static int dec_btstq(CPUCRISState *env, DisasContext *dc)
   1361{
   1362    TCGv c;
   1363    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
   1364    LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
   1365
   1366    cris_cc_mask(dc, CC_MASK_NZ);
   1367    c = tcg_const_tl(dc->op1);
   1368    cris_evaluate_flags(dc);
   1369    gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
   1370            c, cpu_PR[PR_CCS]);
   1371    tcg_temp_free(c);
   1372    cris_alu(dc, CC_OP_MOVE,
   1373         cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
   1374    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
   1375    dc->flags_uptodate = 1;
   1376    return 2;
   1377}
   1378static int dec_asrq(CPUCRISState *env, DisasContext *dc)
   1379{
   1380    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
   1381    LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
   1382    cris_cc_mask(dc, CC_MASK_NZ);
   1383
   1384    tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
   1385    cris_alu(dc, CC_OP_MOVE,
   1386            cpu_R[dc->op2],
   1387            cpu_R[dc->op2], cpu_R[dc->op2], 4);
   1388    return 2;
   1389}
   1390static int dec_lslq(CPUCRISState *env, DisasContext *dc)
   1391{
   1392    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
   1393    LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
   1394
   1395    cris_cc_mask(dc, CC_MASK_NZ);
   1396
   1397    tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
   1398
   1399    cris_alu(dc, CC_OP_MOVE,
   1400            cpu_R[dc->op2],
   1401            cpu_R[dc->op2], cpu_R[dc->op2], 4);
   1402    return 2;
   1403}
   1404static int dec_lsrq(CPUCRISState *env, DisasContext *dc)
   1405{
   1406    dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
   1407    LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
   1408
   1409    cris_cc_mask(dc, CC_MASK_NZ);
   1410
   1411    tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
   1412    cris_alu(dc, CC_OP_MOVE,
   1413            cpu_R[dc->op2],
   1414            cpu_R[dc->op2], cpu_R[dc->op2], 4);
   1415    return 2;
   1416}
   1417
   1418static int dec_move_r(CPUCRISState *env, DisasContext *dc)
   1419{
   1420    int size = memsize_zz(dc);
   1421
   1422    LOG_DIS("move.%c $r%u, $r%u\n",
   1423            memsize_char(size), dc->op1, dc->op2);
   1424
   1425    cris_cc_mask(dc, CC_MASK_NZ);
   1426    if (size == 4) {
   1427        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
   1428        cris_cc_mask(dc, CC_MASK_NZ);
   1429        cris_update_cc_op(dc, CC_OP_MOVE, 4);
   1430        cris_update_cc_x(dc);
   1431        cris_update_result(dc, cpu_R[dc->op2]);
   1432    } else {
   1433        TCGv t0;
   1434
   1435        t0 = tcg_temp_new();
   1436        dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
   1437        cris_alu(dc, CC_OP_MOVE,
   1438             cpu_R[dc->op2],
   1439             cpu_R[dc->op2], t0, size);
   1440        tcg_temp_free(t0);
   1441    }
   1442    return 2;
   1443}
   1444
   1445static int dec_scc_r(CPUCRISState *env, DisasContext *dc)
   1446{
   1447    int cond = dc->op2;
   1448
   1449    LOG_DIS("s%s $r%u\n",
   1450            cc_name(cond), dc->op1);
   1451
   1452    gen_tst_cc(dc, cpu_R[dc->op1], cond);
   1453    tcg_gen_setcondi_tl(TCG_COND_NE, cpu_R[dc->op1], cpu_R[dc->op1], 0);
   1454
   1455    cris_cc_mask(dc, 0);
   1456    return 2;
   1457}
   1458
   1459static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
   1460{
   1461    if (size == 4) {
   1462        t[0] = cpu_R[dc->op2];
   1463        t[1] = cpu_R[dc->op1];
   1464    } else {
   1465        t[0] = tcg_temp_new();
   1466        t[1] = tcg_temp_new();
   1467    }
   1468}
   1469
   1470static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
   1471{
   1472    if (size != 4) {
   1473        tcg_temp_free(t[0]);
   1474        tcg_temp_free(t[1]);
   1475    }
   1476}
   1477
   1478static int dec_and_r(CPUCRISState *env, DisasContext *dc)
   1479{
   1480    TCGv t[2];
   1481    int size = memsize_zz(dc);
   1482
   1483    LOG_DIS("and.%c $r%u, $r%u\n",
   1484            memsize_char(size), dc->op1, dc->op2);
   1485
   1486    cris_cc_mask(dc, CC_MASK_NZ);
   1487
   1488    cris_alu_alloc_temps(dc, size, t);
   1489    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
   1490    cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
   1491    cris_alu_free_temps(dc, size, t);
   1492    return 2;
   1493}
   1494
   1495static int dec_lz_r(CPUCRISState *env, DisasContext *dc)
   1496{
   1497    TCGv t0;
   1498    LOG_DIS("lz $r%u, $r%u\n",
   1499            dc->op1, dc->op2);
   1500    cris_cc_mask(dc, CC_MASK_NZ);
   1501    t0 = tcg_temp_new();
   1502    dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
   1503    cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
   1504    tcg_temp_free(t0);
   1505    return 2;
   1506}
   1507
   1508static int dec_lsl_r(CPUCRISState *env, DisasContext *dc)
   1509{
   1510    TCGv t[2];
   1511    int size = memsize_zz(dc);
   1512
   1513    LOG_DIS("lsl.%c $r%u, $r%u\n",
   1514            memsize_char(size), dc->op1, dc->op2);
   1515
   1516    cris_cc_mask(dc, CC_MASK_NZ);
   1517    cris_alu_alloc_temps(dc, size, t);
   1518    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
   1519    tcg_gen_andi_tl(t[1], t[1], 63);
   1520    cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
   1521    cris_alu_free_temps(dc, size, t);
   1522    return 2;
   1523}
   1524
   1525static int dec_lsr_r(CPUCRISState *env, DisasContext *dc)
   1526{
   1527    TCGv t[2];
   1528    int size = memsize_zz(dc);
   1529
   1530    LOG_DIS("lsr.%c $r%u, $r%u\n",
   1531            memsize_char(size), dc->op1, dc->op2);
   1532
   1533    cris_cc_mask(dc, CC_MASK_NZ);
   1534    cris_alu_alloc_temps(dc, size, t);
   1535    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
   1536    tcg_gen_andi_tl(t[1], t[1], 63);
   1537    cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
   1538    cris_alu_free_temps(dc, size, t);
   1539    return 2;
   1540}
   1541
   1542static int dec_asr_r(CPUCRISState *env, DisasContext *dc)
   1543{
   1544    TCGv t[2];
   1545    int size = memsize_zz(dc);
   1546
   1547    LOG_DIS("asr.%c $r%u, $r%u\n",
   1548            memsize_char(size), dc->op1, dc->op2);
   1549
   1550    cris_cc_mask(dc, CC_MASK_NZ);
   1551    cris_alu_alloc_temps(dc, size, t);
   1552    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
   1553    tcg_gen_andi_tl(t[1], t[1], 63);
   1554    cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
   1555    cris_alu_free_temps(dc, size, t);
   1556    return 2;
   1557}
   1558
   1559static int dec_muls_r(CPUCRISState *env, DisasContext *dc)
   1560{
   1561    TCGv t[2];
   1562    int size = memsize_zz(dc);
   1563
   1564    LOG_DIS("muls.%c $r%u, $r%u\n",
   1565            memsize_char(size), dc->op1, dc->op2);
   1566    cris_cc_mask(dc, CC_MASK_NZV);
   1567    cris_alu_alloc_temps(dc, size, t);
   1568    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
   1569
   1570    cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
   1571    cris_alu_free_temps(dc, size, t);
   1572    return 2;
   1573}
   1574
   1575static int dec_mulu_r(CPUCRISState *env, DisasContext *dc)
   1576{
   1577    TCGv t[2];
   1578    int size = memsize_zz(dc);
   1579
   1580    LOG_DIS("mulu.%c $r%u, $r%u\n",
   1581            memsize_char(size), dc->op1, dc->op2);
   1582    cris_cc_mask(dc, CC_MASK_NZV);
   1583    cris_alu_alloc_temps(dc, size, t);
   1584    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
   1585
   1586    cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
   1587    cris_alu_free_temps(dc, size, t);
   1588    return 2;
   1589}
   1590
   1591
   1592static int dec_dstep_r(CPUCRISState *env, DisasContext *dc)
   1593{
   1594    LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
   1595    cris_cc_mask(dc, CC_MASK_NZ);
   1596    cris_alu(dc, CC_OP_DSTEP,
   1597            cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
   1598    return 2;
   1599}
   1600
   1601static int dec_xor_r(CPUCRISState *env, DisasContext *dc)
   1602{
   1603    TCGv t[2];
   1604    int size = memsize_zz(dc);
   1605    LOG_DIS("xor.%c $r%u, $r%u\n",
   1606            memsize_char(size), dc->op1, dc->op2);
   1607    BUG_ON(size != 4); /* xor is dword.  */
   1608    cris_cc_mask(dc, CC_MASK_NZ);
   1609    cris_alu_alloc_temps(dc, size, t);
   1610    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
   1611
   1612    cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
   1613    cris_alu_free_temps(dc, size, t);
   1614    return 2;
   1615}
   1616
   1617static int dec_bound_r(CPUCRISState *env, DisasContext *dc)
   1618{
   1619    TCGv l0;
   1620    int size = memsize_zz(dc);
   1621    LOG_DIS("bound.%c $r%u, $r%u\n",
   1622            memsize_char(size), dc->op1, dc->op2);
   1623    cris_cc_mask(dc, CC_MASK_NZ);
   1624    l0 = tcg_temp_local_new();
   1625    dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
   1626    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
   1627    tcg_temp_free(l0);
   1628    return 2;
   1629}
   1630
   1631static int dec_cmp_r(CPUCRISState *env, DisasContext *dc)
   1632{
   1633    TCGv t[2];
   1634    int size = memsize_zz(dc);
   1635    LOG_DIS("cmp.%c $r%u, $r%u\n",
   1636            memsize_char(size), dc->op1, dc->op2);
   1637    cris_cc_mask(dc, CC_MASK_NZVC);
   1638    cris_alu_alloc_temps(dc, size, t);
   1639    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
   1640
   1641    cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
   1642    cris_alu_free_temps(dc, size, t);
   1643    return 2;
   1644}
   1645
   1646static int dec_abs_r(CPUCRISState *env, DisasContext *dc)
   1647{
   1648    LOG_DIS("abs $r%u, $r%u\n",
   1649            dc->op1, dc->op2);
   1650    cris_cc_mask(dc, CC_MASK_NZ);
   1651
   1652    tcg_gen_abs_tl(cpu_R[dc->op2], cpu_R[dc->op1]);
   1653    cris_alu(dc, CC_OP_MOVE,
   1654            cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
   1655    return 2;
   1656}
   1657
   1658static int dec_add_r(CPUCRISState *env, DisasContext *dc)
   1659{
   1660    TCGv t[2];
   1661    int size = memsize_zz(dc);
   1662    LOG_DIS("add.%c $r%u, $r%u\n",
   1663            memsize_char(size), dc->op1, dc->op2);
   1664    cris_cc_mask(dc, CC_MASK_NZVC);
   1665    cris_alu_alloc_temps(dc, size, t);
   1666    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
   1667
   1668    cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
   1669    cris_alu_free_temps(dc, size, t);
   1670    return 2;
   1671}
   1672
   1673static int dec_addc_r(CPUCRISState *env, DisasContext *dc)
   1674{
   1675    LOG_DIS("addc $r%u, $r%u\n",
   1676            dc->op1, dc->op2);
   1677    cris_evaluate_flags(dc);
   1678
   1679    /* Set for this insn.  */
   1680    dc->flags_x = X_FLAG;
   1681
   1682    cris_cc_mask(dc, CC_MASK_NZVC);
   1683    cris_alu(dc, CC_OP_ADDC,
   1684         cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
   1685    return 2;
   1686}
   1687
   1688static int dec_mcp_r(CPUCRISState *env, DisasContext *dc)
   1689{
   1690    LOG_DIS("mcp $p%u, $r%u\n",
   1691             dc->op2, dc->op1);
   1692    cris_evaluate_flags(dc);
   1693    cris_cc_mask(dc, CC_MASK_RNZV);
   1694    cris_alu(dc, CC_OP_MCP,
   1695            cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
   1696    return 2;
   1697}
   1698
   1699#if DISAS_CRIS
   1700static char * swapmode_name(int mode, char *modename) {
   1701    int i = 0;
   1702    if (mode & 8) {
   1703        modename[i++] = 'n';
   1704    }
   1705    if (mode & 4) {
   1706        modename[i++] = 'w';
   1707    }
   1708    if (mode & 2) {
   1709        modename[i++] = 'b';
   1710    }
   1711    if (mode & 1) {
   1712        modename[i++] = 'r';
   1713    }
   1714    modename[i++] = 0;
   1715    return modename;
   1716}
   1717#endif
   1718
   1719static int dec_swap_r(CPUCRISState *env, DisasContext *dc)
   1720{
   1721    TCGv t0;
   1722#if DISAS_CRIS
   1723    char modename[4];
   1724#endif
   1725    LOG_DIS("swap%s $r%u\n",
   1726             swapmode_name(dc->op2, modename), dc->op1);
   1727
   1728    cris_cc_mask(dc, CC_MASK_NZ);
   1729    t0 = tcg_temp_new();
   1730    tcg_gen_mov_tl(t0, cpu_R[dc->op1]);
   1731    if (dc->op2 & 8) {
   1732        tcg_gen_not_tl(t0, t0);
   1733    }
   1734    if (dc->op2 & 4) {
   1735        t_gen_swapw(t0, t0);
   1736    }
   1737    if (dc->op2 & 2) {
   1738        t_gen_swapb(t0, t0);
   1739    }
   1740    if (dc->op2 & 1) {
   1741        t_gen_swapr(t0, t0);
   1742    }
   1743    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
   1744    tcg_temp_free(t0);
   1745    return 2;
   1746}
   1747
   1748static int dec_or_r(CPUCRISState *env, DisasContext *dc)
   1749{
   1750    TCGv t[2];
   1751    int size = memsize_zz(dc);
   1752    LOG_DIS("or.%c $r%u, $r%u\n",
   1753            memsize_char(size), dc->op1, dc->op2);
   1754    cris_cc_mask(dc, CC_MASK_NZ);
   1755    cris_alu_alloc_temps(dc, size, t);
   1756    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
   1757    cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
   1758    cris_alu_free_temps(dc, size, t);
   1759    return 2;
   1760}
   1761
   1762static int dec_addi_r(CPUCRISState *env, DisasContext *dc)
   1763{
   1764    TCGv t0;
   1765    LOG_DIS("addi.%c $r%u, $r%u\n",
   1766            memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
   1767    cris_cc_mask(dc, 0);
   1768    t0 = tcg_temp_new();
   1769    tcg_gen_shli_tl(t0, cpu_R[dc->op2], dc->zzsize);
   1770    tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
   1771    tcg_temp_free(t0);
   1772    return 2;
   1773}
   1774
   1775static int dec_addi_acr(CPUCRISState *env, DisasContext *dc)
   1776{
   1777    TCGv t0;
   1778    LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
   1779          memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
   1780    cris_cc_mask(dc, 0);
   1781    t0 = tcg_temp_new();
   1782    tcg_gen_shli_tl(t0, cpu_R[dc->op2], dc->zzsize);
   1783    tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
   1784    tcg_temp_free(t0);
   1785    return 2;
   1786}
   1787
   1788static int dec_neg_r(CPUCRISState *env, DisasContext *dc)
   1789{
   1790    TCGv t[2];
   1791    int size = memsize_zz(dc);
   1792    LOG_DIS("neg.%c $r%u, $r%u\n",
   1793            memsize_char(size), dc->op1, dc->op2);
   1794    cris_cc_mask(dc, CC_MASK_NZVC);
   1795    cris_alu_alloc_temps(dc, size, t);
   1796    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
   1797
   1798    cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
   1799    cris_alu_free_temps(dc, size, t);
   1800    return 2;
   1801}
   1802
   1803static int dec_btst_r(CPUCRISState *env, DisasContext *dc)
   1804{
   1805    LOG_DIS("btst $r%u, $r%u\n",
   1806            dc->op1, dc->op2);
   1807    cris_cc_mask(dc, CC_MASK_NZ);
   1808    cris_evaluate_flags(dc);
   1809        gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
   1810            cpu_R[dc->op1], cpu_PR[PR_CCS]);
   1811    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
   1812         cpu_R[dc->op2], cpu_R[dc->op2], 4);
   1813    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
   1814    dc->flags_uptodate = 1;
   1815    return 2;
   1816}
   1817
   1818static int dec_sub_r(CPUCRISState *env, DisasContext *dc)
   1819{
   1820    TCGv t[2];
   1821    int size = memsize_zz(dc);
   1822    LOG_DIS("sub.%c $r%u, $r%u\n",
   1823            memsize_char(size), dc->op1, dc->op2);
   1824    cris_cc_mask(dc, CC_MASK_NZVC);
   1825    cris_alu_alloc_temps(dc, size, t);
   1826    dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
   1827    cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
   1828    cris_alu_free_temps(dc, size, t);
   1829    return 2;
   1830}
   1831
   1832/* Zero extension. From size to dword.  */
   1833static int dec_movu_r(CPUCRISState *env, DisasContext *dc)
   1834{
   1835    TCGv t0;
   1836    int size = memsize_z(dc);
   1837    LOG_DIS("movu.%c $r%u, $r%u\n",
   1838            memsize_char(size),
   1839            dc->op1, dc->op2);
   1840
   1841    cris_cc_mask(dc, CC_MASK_NZ);
   1842    t0 = tcg_temp_new();
   1843    dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
   1844    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
   1845    tcg_temp_free(t0);
   1846    return 2;
   1847}
   1848
   1849/* Sign extension. From size to dword.  */
   1850static int dec_movs_r(CPUCRISState *env, DisasContext *dc)
   1851{
   1852    TCGv t0;
   1853    int size = memsize_z(dc);
   1854    LOG_DIS("movs.%c $r%u, $r%u\n",
   1855            memsize_char(size),
   1856            dc->op1, dc->op2);
   1857
   1858    cris_cc_mask(dc, CC_MASK_NZ);
   1859    t0 = tcg_temp_new();
   1860    /* Size can only be qi or hi.  */
   1861    t_gen_sext(t0, cpu_R[dc->op1], size);
   1862    cris_alu(dc, CC_OP_MOVE,
   1863            cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
   1864    tcg_temp_free(t0);
   1865    return 2;
   1866}
   1867
   1868/* zero extension. From size to dword.  */
   1869static int dec_addu_r(CPUCRISState *env, DisasContext *dc)
   1870{
   1871    TCGv t0;
   1872    int size = memsize_z(dc);
   1873    LOG_DIS("addu.%c $r%u, $r%u\n",
   1874            memsize_char(size),
   1875            dc->op1, dc->op2);
   1876
   1877    cris_cc_mask(dc, CC_MASK_NZVC);
   1878    t0 = tcg_temp_new();
   1879    /* Size can only be qi or hi.  */
   1880    t_gen_zext(t0, cpu_R[dc->op1], size);
   1881    cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
   1882    tcg_temp_free(t0);
   1883    return 2;
   1884}
   1885
   1886/* Sign extension. From size to dword.  */
   1887static int dec_adds_r(CPUCRISState *env, DisasContext *dc)
   1888{
   1889    TCGv t0;
   1890    int size = memsize_z(dc);
   1891    LOG_DIS("adds.%c $r%u, $r%u\n",
   1892            memsize_char(size),
   1893            dc->op1, dc->op2);
   1894
   1895    cris_cc_mask(dc, CC_MASK_NZVC);
   1896    t0 = tcg_temp_new();
   1897    /* Size can only be qi or hi.  */
   1898    t_gen_sext(t0, cpu_R[dc->op1], size);
   1899    cris_alu(dc, CC_OP_ADD,
   1900            cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
   1901    tcg_temp_free(t0);
   1902    return 2;
   1903}
   1904
   1905/* Zero extension. From size to dword.  */
   1906static int dec_subu_r(CPUCRISState *env, DisasContext *dc)
   1907{
   1908    TCGv t0;
   1909    int size = memsize_z(dc);
   1910    LOG_DIS("subu.%c $r%u, $r%u\n",
   1911            memsize_char(size),
   1912            dc->op1, dc->op2);
   1913
   1914    cris_cc_mask(dc, CC_MASK_NZVC);
   1915    t0 = tcg_temp_new();
   1916    /* Size can only be qi or hi.  */
   1917    t_gen_zext(t0, cpu_R[dc->op1], size);
   1918    cris_alu(dc, CC_OP_SUB,
   1919            cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
   1920    tcg_temp_free(t0);
   1921    return 2;
   1922}
   1923
   1924/* Sign extension. From size to dword.  */
   1925static int dec_subs_r(CPUCRISState *env, DisasContext *dc)
   1926{
   1927    TCGv t0;
   1928    int size = memsize_z(dc);
   1929    LOG_DIS("subs.%c $r%u, $r%u\n",
   1930            memsize_char(size),
   1931            dc->op1, dc->op2);
   1932
   1933    cris_cc_mask(dc, CC_MASK_NZVC);
   1934    t0 = tcg_temp_new();
   1935    /* Size can only be qi or hi.  */
   1936    t_gen_sext(t0, cpu_R[dc->op1], size);
   1937    cris_alu(dc, CC_OP_SUB,
   1938            cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
   1939    tcg_temp_free(t0);
   1940    return 2;
   1941}
   1942
   1943static int dec_setclrf(CPUCRISState *env, DisasContext *dc)
   1944{
   1945    uint32_t flags;
   1946    int set = (~dc->opcode >> 2) & 1;
   1947
   1948
   1949    flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
   1950        | EXTRACT_FIELD(dc->ir, 0, 3);
   1951    if (set && flags == 0) {
   1952        LOG_DIS("nop\n");
   1953        return 2;
   1954    } else if (!set && (flags & 0x20)) {
   1955        LOG_DIS("di\n");
   1956    } else {
   1957        LOG_DIS("%sf %x\n", set ? "set" : "clr", flags);
   1958    }
   1959
   1960    /* User space is not allowed to touch these. Silently ignore.  */
   1961    if (dc->tb_flags & U_FLAG) {
   1962        flags &= ~(S_FLAG | I_FLAG | U_FLAG);
   1963    }
   1964
   1965    if (flags & X_FLAG) {
   1966        if (set) {
   1967            dc->flags_x = X_FLAG;
   1968        } else {
   1969            dc->flags_x = 0;
   1970        }
   1971    }
   1972
   1973    /* Break the TB if any of the SPI flag changes.  */
   1974    if (flags & (P_FLAG | S_FLAG)) {
   1975        tcg_gen_movi_tl(env_pc, dc->pc + 2);
   1976        dc->base.is_jmp = DISAS_UPDATE;
   1977        dc->cpustate_changed = 1;
   1978    }
   1979
   1980    /* For the I flag, only act on posedge.  */
   1981    if ((flags & I_FLAG)) {
   1982        tcg_gen_movi_tl(env_pc, dc->pc + 2);
   1983        dc->base.is_jmp = DISAS_UPDATE;
   1984        dc->cpustate_changed = 1;
   1985    }
   1986
   1987
   1988    /* Simply decode the flags.  */
   1989    cris_evaluate_flags(dc);
   1990    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
   1991    cris_update_cc_x(dc);
   1992    tcg_gen_movi_tl(cc_op, dc->cc_op);
   1993
   1994    if (set) {
   1995        if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
   1996            /* Enter user mode.  */
   1997            t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
   1998            tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
   1999            dc->cpustate_changed = 1;
   2000        }
   2001        tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
   2002    } else {
   2003        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
   2004    }
   2005
   2006    dc->flags_uptodate = 1;
   2007    dc->clear_x = 0;
   2008    return 2;
   2009}
   2010
   2011static int dec_move_rs(CPUCRISState *env, DisasContext *dc)
   2012{
   2013    TCGv c2, c1;
   2014    LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
   2015    c1 = tcg_const_tl(dc->op1);
   2016    c2 = tcg_const_tl(dc->op2);
   2017    cris_cc_mask(dc, 0);
   2018    gen_helper_movl_sreg_reg(cpu_env, c2, c1);
   2019    tcg_temp_free(c1);
   2020    tcg_temp_free(c2);
   2021    return 2;
   2022}
   2023static int dec_move_sr(CPUCRISState *env, DisasContext *dc)
   2024{
   2025    TCGv c2, c1;
   2026    LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
   2027    c1 = tcg_const_tl(dc->op1);
   2028    c2 = tcg_const_tl(dc->op2);
   2029    cris_cc_mask(dc, 0);
   2030    gen_helper_movl_reg_sreg(cpu_env, c1, c2);
   2031    tcg_temp_free(c1);
   2032    tcg_temp_free(c2);
   2033    return 2;
   2034}
   2035
   2036static int dec_move_rp(CPUCRISState *env, DisasContext *dc)
   2037{
   2038    TCGv t[2];
   2039    LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
   2040    cris_cc_mask(dc, 0);
   2041
   2042    t[0] = tcg_temp_new();
   2043    if (dc->op2 == PR_CCS) {
   2044        cris_evaluate_flags(dc);
   2045        tcg_gen_mov_tl(t[0], cpu_R[dc->op1]);
   2046        if (dc->tb_flags & U_FLAG) {
   2047            t[1] = tcg_temp_new();
   2048            /* User space is not allowed to touch all flags.  */
   2049            tcg_gen_andi_tl(t[0], t[0], 0x39f);
   2050            tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
   2051            tcg_gen_or_tl(t[0], t[1], t[0]);
   2052            tcg_temp_free(t[1]);
   2053        }
   2054    } else {
   2055        tcg_gen_mov_tl(t[0], cpu_R[dc->op1]);
   2056    }
   2057
   2058    t_gen_mov_preg_TN(dc, dc->op2, t[0]);
   2059    if (dc->op2 == PR_CCS) {
   2060        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
   2061        dc->flags_uptodate = 1;
   2062    }
   2063    tcg_temp_free(t[0]);
   2064    return 2;
   2065}
   2066static int dec_move_pr(CPUCRISState *env, DisasContext *dc)
   2067{
   2068    TCGv t0;
   2069    LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
   2070    cris_cc_mask(dc, 0);
   2071
   2072    if (dc->op2 == PR_CCS) {
   2073        cris_evaluate_flags(dc);
   2074    }
   2075
   2076    if (dc->op2 == PR_DZ) {
   2077        tcg_gen_movi_tl(cpu_R[dc->op1], 0);
   2078    } else {
   2079        t0 = tcg_temp_new();
   2080        t_gen_mov_TN_preg(t0, dc->op2);
   2081        cris_alu(dc, CC_OP_MOVE,
   2082                cpu_R[dc->op1], cpu_R[dc->op1], t0,
   2083                preg_sizes[dc->op2]);
   2084        tcg_temp_free(t0);
   2085    }
   2086    return 2;
   2087}
   2088
   2089static int dec_move_mr(CPUCRISState *env, DisasContext *dc)
   2090{
   2091    int memsize = memsize_zz(dc);
   2092    int insn_len;
   2093    LOG_DIS("move.%c [$r%u%s, $r%u\n",
   2094            memsize_char(memsize),
   2095            dc->op1, dc->postinc ? "+]" : "]",
   2096                    dc->op2);
   2097
   2098    if (memsize == 4) {
   2099        insn_len = dec_prep_move_m(env, dc, 0, 4, cpu_R[dc->op2]);
   2100        cris_cc_mask(dc, CC_MASK_NZ);
   2101        cris_update_cc_op(dc, CC_OP_MOVE, 4);
   2102        cris_update_cc_x(dc);
   2103        cris_update_result(dc, cpu_R[dc->op2]);
   2104    } else {
   2105        TCGv t0;
   2106
   2107        t0 = tcg_temp_new();
   2108        insn_len = dec_prep_move_m(env, dc, 0, memsize, t0);
   2109        cris_cc_mask(dc, CC_MASK_NZ);
   2110        cris_alu(dc, CC_OP_MOVE,
   2111                cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
   2112        tcg_temp_free(t0);
   2113    }
   2114    do_postinc(dc, memsize);
   2115    return insn_len;
   2116}
   2117
   2118static inline void cris_alu_m_alloc_temps(TCGv *t)
   2119{
   2120    t[0] = tcg_temp_new();
   2121    t[1] = tcg_temp_new();
   2122}
   2123
   2124static inline void cris_alu_m_free_temps(TCGv *t)
   2125{
   2126    tcg_temp_free(t[0]);
   2127    tcg_temp_free(t[1]);
   2128}
   2129
   2130static int dec_movs_m(CPUCRISState *env, DisasContext *dc)
   2131{
   2132    TCGv t[2];
   2133    int memsize = memsize_z(dc);
   2134    int insn_len;
   2135    LOG_DIS("movs.%c [$r%u%s, $r%u\n",
   2136            memsize_char(memsize),
   2137            dc->op1, dc->postinc ? "+]" : "]",
   2138            dc->op2);
   2139
   2140    cris_alu_m_alloc_temps(t);
   2141    /* sign extend.  */
   2142        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
   2143    cris_cc_mask(dc, CC_MASK_NZ);
   2144    cris_alu(dc, CC_OP_MOVE,
   2145            cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
   2146    do_postinc(dc, memsize);
   2147    cris_alu_m_free_temps(t);
   2148    return insn_len;
   2149}
   2150
   2151static int dec_addu_m(CPUCRISState *env, DisasContext *dc)
   2152{
   2153    TCGv t[2];
   2154    int memsize = memsize_z(dc);
   2155    int insn_len;
   2156    LOG_DIS("addu.%c [$r%u%s, $r%u\n",
   2157            memsize_char(memsize),
   2158            dc->op1, dc->postinc ? "+]" : "]",
   2159            dc->op2);
   2160
   2161    cris_alu_m_alloc_temps(t);
   2162    /* sign extend.  */
   2163        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
   2164    cris_cc_mask(dc, CC_MASK_NZVC);
   2165    cris_alu(dc, CC_OP_ADD,
   2166            cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
   2167    do_postinc(dc, memsize);
   2168    cris_alu_m_free_temps(t);
   2169    return insn_len;
   2170}
   2171
   2172static int dec_adds_m(CPUCRISState *env, DisasContext *dc)
   2173{
   2174    TCGv t[2];
   2175    int memsize = memsize_z(dc);
   2176    int insn_len;
   2177    LOG_DIS("adds.%c [$r%u%s, $r%u\n",
   2178            memsize_char(memsize),
   2179            dc->op1, dc->postinc ? "+]" : "]",
   2180            dc->op2);
   2181
   2182    cris_alu_m_alloc_temps(t);
   2183    /* sign extend.  */
   2184        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
   2185    cris_cc_mask(dc, CC_MASK_NZVC);
   2186    cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
   2187    do_postinc(dc, memsize);
   2188    cris_alu_m_free_temps(t);
   2189    return insn_len;
   2190}
   2191
   2192static int dec_subu_m(CPUCRISState *env, DisasContext *dc)
   2193{
   2194    TCGv t[2];
   2195    int memsize = memsize_z(dc);
   2196    int insn_len;
   2197    LOG_DIS("subu.%c [$r%u%s, $r%u\n",
   2198            memsize_char(memsize),
   2199            dc->op1, dc->postinc ? "+]" : "]",
   2200            dc->op2);
   2201
   2202    cris_alu_m_alloc_temps(t);
   2203    /* sign extend.  */
   2204        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
   2205    cris_cc_mask(dc, CC_MASK_NZVC);
   2206    cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
   2207    do_postinc(dc, memsize);
   2208    cris_alu_m_free_temps(t);
   2209    return insn_len;
   2210}
   2211
   2212static int dec_subs_m(CPUCRISState *env, DisasContext *dc)
   2213{
   2214    TCGv t[2];
   2215    int memsize = memsize_z(dc);
   2216    int insn_len;
   2217    LOG_DIS("subs.%c [$r%u%s, $r%u\n",
   2218            memsize_char(memsize),
   2219            dc->op1, dc->postinc ? "+]" : "]",
   2220            dc->op2);
   2221
   2222    cris_alu_m_alloc_temps(t);
   2223    /* sign extend.  */
   2224        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
   2225    cris_cc_mask(dc, CC_MASK_NZVC);
   2226    cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
   2227    do_postinc(dc, memsize);
   2228    cris_alu_m_free_temps(t);
   2229    return insn_len;
   2230}
   2231
   2232static int dec_movu_m(CPUCRISState *env, DisasContext *dc)
   2233{
   2234    TCGv t[2];
   2235    int memsize = memsize_z(dc);
   2236    int insn_len;
   2237
   2238    LOG_DIS("movu.%c [$r%u%s, $r%u\n",
   2239            memsize_char(memsize),
   2240            dc->op1, dc->postinc ? "+]" : "]",
   2241            dc->op2);
   2242
   2243    cris_alu_m_alloc_temps(t);
   2244        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
   2245    cris_cc_mask(dc, CC_MASK_NZ);
   2246    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
   2247    do_postinc(dc, memsize);
   2248    cris_alu_m_free_temps(t);
   2249    return insn_len;
   2250}
   2251
   2252static int dec_cmpu_m(CPUCRISState *env, DisasContext *dc)
   2253{
   2254    TCGv t[2];
   2255    int memsize = memsize_z(dc);
   2256    int insn_len;
   2257    LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
   2258            memsize_char(memsize),
   2259            dc->op1, dc->postinc ? "+]" : "]",
   2260            dc->op2);
   2261
   2262    cris_alu_m_alloc_temps(t);
   2263        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
   2264    cris_cc_mask(dc, CC_MASK_NZVC);
   2265    cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
   2266    do_postinc(dc, memsize);
   2267    cris_alu_m_free_temps(t);
   2268    return insn_len;
   2269}
   2270
   2271static int dec_cmps_m(CPUCRISState *env, DisasContext *dc)
   2272{
   2273    TCGv t[2];
   2274    int memsize = memsize_z(dc);
   2275    int insn_len;
   2276    LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
   2277            memsize_char(memsize),
   2278            dc->op1, dc->postinc ? "+]" : "]",
   2279            dc->op2);
   2280
   2281    cris_alu_m_alloc_temps(t);
   2282        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
   2283    cris_cc_mask(dc, CC_MASK_NZVC);
   2284    cris_alu(dc, CC_OP_CMP,
   2285            cpu_R[dc->op2], cpu_R[dc->op2], t[1],
   2286            memsize_zz(dc));
   2287    do_postinc(dc, memsize);
   2288    cris_alu_m_free_temps(t);
   2289    return insn_len;
   2290}
   2291
   2292static int dec_cmp_m(CPUCRISState *env, DisasContext *dc)
   2293{
   2294    TCGv t[2];
   2295    int memsize = memsize_zz(dc);
   2296    int insn_len;
   2297    LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
   2298            memsize_char(memsize),
   2299            dc->op1, dc->postinc ? "+]" : "]",
   2300            dc->op2);
   2301
   2302    cris_alu_m_alloc_temps(t);
   2303        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
   2304    cris_cc_mask(dc, CC_MASK_NZVC);
   2305    cris_alu(dc, CC_OP_CMP,
   2306            cpu_R[dc->op2], cpu_R[dc->op2], t[1],
   2307            memsize_zz(dc));
   2308    do_postinc(dc, memsize);
   2309    cris_alu_m_free_temps(t);
   2310    return insn_len;
   2311}
   2312
   2313static int dec_test_m(CPUCRISState *env, DisasContext *dc)
   2314{
   2315    TCGv t[2], c;
   2316    int memsize = memsize_zz(dc);
   2317    int insn_len;
   2318    LOG_DIS("test.%c [$r%u%s] op2=%x\n",
   2319            memsize_char(memsize),
   2320            dc->op1, dc->postinc ? "+]" : "]",
   2321            dc->op2);
   2322
   2323    cris_evaluate_flags(dc);
   2324
   2325    cris_alu_m_alloc_temps(t);
   2326        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
   2327    cris_cc_mask(dc, CC_MASK_NZ);
   2328    tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
   2329
   2330    c = tcg_const_tl(0);
   2331    cris_alu(dc, CC_OP_CMP,
   2332         cpu_R[dc->op2], t[1], c, memsize_zz(dc));
   2333    tcg_temp_free(c);
   2334    do_postinc(dc, memsize);
   2335    cris_alu_m_free_temps(t);
   2336    return insn_len;
   2337}
   2338
   2339static int dec_and_m(CPUCRISState *env, DisasContext *dc)
   2340{
   2341    TCGv t[2];
   2342    int memsize = memsize_zz(dc);
   2343    int insn_len;
   2344    LOG_DIS("and.%c [$r%u%s, $r%u\n",
   2345            memsize_char(memsize),
   2346            dc->op1, dc->postinc ? "+]" : "]",
   2347            dc->op2);
   2348
   2349    cris_alu_m_alloc_temps(t);
   2350        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
   2351    cris_cc_mask(dc, CC_MASK_NZ);
   2352    cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
   2353    do_postinc(dc, memsize);
   2354    cris_alu_m_free_temps(t);
   2355    return insn_len;
   2356}
   2357
   2358static int dec_add_m(CPUCRISState *env, DisasContext *dc)
   2359{
   2360    TCGv t[2];
   2361    int memsize = memsize_zz(dc);
   2362    int insn_len;
   2363    LOG_DIS("add.%c [$r%u%s, $r%u\n",
   2364            memsize_char(memsize),
   2365            dc->op1, dc->postinc ? "+]" : "]",
   2366            dc->op2);
   2367
   2368    cris_alu_m_alloc_temps(t);
   2369        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
   2370    cris_cc_mask(dc, CC_MASK_NZVC);
   2371    cris_alu(dc, CC_OP_ADD,
   2372         cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
   2373    do_postinc(dc, memsize);
   2374    cris_alu_m_free_temps(t);
   2375    return insn_len;
   2376}
   2377
   2378static int dec_addo_m(CPUCRISState *env, DisasContext *dc)
   2379{
   2380    TCGv t[2];
   2381    int memsize = memsize_zz(dc);
   2382    int insn_len;
   2383    LOG_DIS("add.%c [$r%u%s, $r%u\n",
   2384            memsize_char(memsize),
   2385            dc->op1, dc->postinc ? "+]" : "]",
   2386            dc->op2);
   2387
   2388    cris_alu_m_alloc_temps(t);
   2389        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
   2390    cris_cc_mask(dc, 0);
   2391    cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
   2392    do_postinc(dc, memsize);
   2393    cris_alu_m_free_temps(t);
   2394    return insn_len;
   2395}
   2396
   2397static int dec_bound_m(CPUCRISState *env, DisasContext *dc)
   2398{
   2399    TCGv l[2];
   2400    int memsize = memsize_zz(dc);
   2401    int insn_len;
   2402    LOG_DIS("bound.%c [$r%u%s, $r%u\n",
   2403            memsize_char(memsize),
   2404            dc->op1, dc->postinc ? "+]" : "]",
   2405            dc->op2);
   2406
   2407    l[0] = tcg_temp_local_new();
   2408    l[1] = tcg_temp_local_new();
   2409        insn_len = dec_prep_alu_m(env, dc, 0, memsize, l[0], l[1]);
   2410    cris_cc_mask(dc, CC_MASK_NZ);
   2411    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
   2412    do_postinc(dc, memsize);
   2413    tcg_temp_free(l[0]);
   2414    tcg_temp_free(l[1]);
   2415    return insn_len;
   2416}
   2417
   2418static int dec_addc_mr(CPUCRISState *env, DisasContext *dc)
   2419{
   2420    TCGv t[2];
   2421    int insn_len = 2;
   2422    LOG_DIS("addc [$r%u%s, $r%u\n",
   2423            dc->op1, dc->postinc ? "+]" : "]",
   2424            dc->op2);
   2425
   2426    cris_evaluate_flags(dc);
   2427
   2428    /* Set for this insn.  */
   2429    dc->flags_x = X_FLAG;
   2430
   2431    cris_alu_m_alloc_temps(t);
   2432        insn_len = dec_prep_alu_m(env, dc, 0, 4, t[0], t[1]);
   2433    cris_cc_mask(dc, CC_MASK_NZVC);
   2434    cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
   2435    do_postinc(dc, 4);
   2436    cris_alu_m_free_temps(t);
   2437    return insn_len;
   2438}
   2439
   2440static int dec_sub_m(CPUCRISState *env, DisasContext *dc)
   2441{
   2442    TCGv t[2];
   2443    int memsize = memsize_zz(dc);
   2444    int insn_len;
   2445    LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
   2446            memsize_char(memsize),
   2447            dc->op1, dc->postinc ? "+]" : "]",
   2448            dc->op2, dc->ir, dc->zzsize);
   2449
   2450    cris_alu_m_alloc_temps(t);
   2451        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
   2452    cris_cc_mask(dc, CC_MASK_NZVC);
   2453    cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
   2454    do_postinc(dc, memsize);
   2455    cris_alu_m_free_temps(t);
   2456    return insn_len;
   2457}
   2458
   2459static int dec_or_m(CPUCRISState *env, DisasContext *dc)
   2460{
   2461    TCGv t[2];
   2462    int memsize = memsize_zz(dc);
   2463    int insn_len;
   2464    LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
   2465            memsize_char(memsize),
   2466            dc->op1, dc->postinc ? "+]" : "]",
   2467            dc->op2, dc->pc);
   2468
   2469    cris_alu_m_alloc_temps(t);
   2470        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
   2471    cris_cc_mask(dc, CC_MASK_NZ);
   2472    cris_alu(dc, CC_OP_OR,
   2473            cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
   2474    do_postinc(dc, memsize);
   2475    cris_alu_m_free_temps(t);
   2476    return insn_len;
   2477}
   2478
   2479static int dec_move_mp(CPUCRISState *env, DisasContext *dc)
   2480{
   2481    TCGv t[2];
   2482    int memsize = memsize_zz(dc);
   2483    int insn_len = 2;
   2484
   2485    LOG_DIS("move.%c [$r%u%s, $p%u\n",
   2486            memsize_char(memsize),
   2487            dc->op1,
   2488            dc->postinc ? "+]" : "]",
   2489            dc->op2);
   2490
   2491    cris_alu_m_alloc_temps(t);
   2492        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
   2493    cris_cc_mask(dc, 0);
   2494    if (dc->op2 == PR_CCS) {
   2495        cris_evaluate_flags(dc);
   2496        if (dc->tb_flags & U_FLAG) {
   2497            /* User space is not allowed to touch all flags.  */
   2498            tcg_gen_andi_tl(t[1], t[1], 0x39f);
   2499            tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
   2500            tcg_gen_or_tl(t[1], t[0], t[1]);
   2501        }
   2502    }
   2503
   2504    t_gen_mov_preg_TN(dc, dc->op2, t[1]);
   2505
   2506    do_postinc(dc, memsize);
   2507    cris_alu_m_free_temps(t);
   2508    return insn_len;
   2509}
   2510
   2511static int dec_move_pm(CPUCRISState *env, DisasContext *dc)
   2512{
   2513    TCGv t0;
   2514    int memsize;
   2515
   2516    memsize = preg_sizes[dc->op2];
   2517
   2518    LOG_DIS("move.%c $p%u, [$r%u%s\n",
   2519            memsize_char(memsize),
   2520            dc->op2, dc->op1, dc->postinc ? "+]" : "]");
   2521
   2522    /* prepare store. Address in T0, value in T1.  */
   2523    if (dc->op2 == PR_CCS) {
   2524        cris_evaluate_flags(dc);
   2525    }
   2526    t0 = tcg_temp_new();
   2527    t_gen_mov_TN_preg(t0, dc->op2);
   2528    cris_flush_cc_state(dc);
   2529    gen_store(dc, cpu_R[dc->op1], t0, memsize);
   2530    tcg_temp_free(t0);
   2531
   2532    cris_cc_mask(dc, 0);
   2533    if (dc->postinc) {
   2534        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
   2535    }
   2536    return 2;
   2537}
   2538
   2539static int dec_movem_mr(CPUCRISState *env, DisasContext *dc)
   2540{
   2541    TCGv_i64 tmp[16];
   2542    TCGv tmp32;
   2543    TCGv addr;
   2544    int i;
   2545    int nr = dc->op2 + 1;
   2546
   2547    LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
   2548            dc->postinc ? "+]" : "]", dc->op2);
   2549
   2550    addr = tcg_temp_new();
   2551    /* There are probably better ways of doing this.  */
   2552    cris_flush_cc_state(dc);
   2553    for (i = 0; i < (nr >> 1); i++) {
   2554        tmp[i] = tcg_temp_new_i64();
   2555        tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
   2556        gen_load64(dc, tmp[i], addr);
   2557    }
   2558    if (nr & 1) {
   2559        tmp32 = tcg_temp_new_i32();
   2560        tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
   2561        gen_load(dc, tmp32, addr, 4, 0);
   2562    } else {
   2563        tmp32 = NULL;
   2564    }
   2565    tcg_temp_free(addr);
   2566
   2567    for (i = 0; i < (nr >> 1); i++) {
   2568        tcg_gen_extrl_i64_i32(cpu_R[i * 2], tmp[i]);
   2569        tcg_gen_shri_i64(tmp[i], tmp[i], 32);
   2570        tcg_gen_extrl_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
   2571        tcg_temp_free_i64(tmp[i]);
   2572    }
   2573    if (nr & 1) {
   2574        tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
   2575        tcg_temp_free(tmp32);
   2576    }
   2577
   2578    /* writeback the updated pointer value.  */
   2579    if (dc->postinc) {
   2580        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
   2581    }
   2582
   2583    /* gen_load might want to evaluate the previous insns flags.  */
   2584    cris_cc_mask(dc, 0);
   2585    return 2;
   2586}
   2587
   2588static int dec_movem_rm(CPUCRISState *env, DisasContext *dc)
   2589{
   2590    TCGv tmp;
   2591    TCGv addr;
   2592    int i;
   2593
   2594    LOG_DIS("movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
   2595            dc->postinc ? "+]" : "]");
   2596
   2597    cris_flush_cc_state(dc);
   2598
   2599    tmp = tcg_temp_new();
   2600    addr = tcg_temp_new();
   2601    tcg_gen_movi_tl(tmp, 4);
   2602    tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
   2603    for (i = 0; i <= dc->op2; i++) {
   2604        /* Displace addr.  */
   2605        /* Perform the store.  */
   2606        gen_store(dc, addr, cpu_R[i], 4);
   2607        tcg_gen_add_tl(addr, addr, tmp);
   2608    }
   2609    if (dc->postinc) {
   2610        tcg_gen_mov_tl(cpu_R[dc->op1], addr);
   2611    }
   2612    cris_cc_mask(dc, 0);
   2613    tcg_temp_free(tmp);
   2614    tcg_temp_free(addr);
   2615    return 2;
   2616}
   2617
   2618static int dec_move_rm(CPUCRISState *env, DisasContext *dc)
   2619{
   2620    int memsize;
   2621
   2622    memsize = memsize_zz(dc);
   2623
   2624    LOG_DIS("move.%c $r%u, [$r%u]\n",
   2625            memsize_char(memsize), dc->op2, dc->op1);
   2626
   2627    /* prepare store.  */
   2628    cris_flush_cc_state(dc);
   2629    gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
   2630
   2631    if (dc->postinc) {
   2632        tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
   2633    }
   2634    cris_cc_mask(dc, 0);
   2635    return 2;
   2636}
   2637
   2638static int dec_lapcq(CPUCRISState *env, DisasContext *dc)
   2639{
   2640    LOG_DIS("lapcq %x, $r%u\n",
   2641            dc->pc + dc->op1*2, dc->op2);
   2642    cris_cc_mask(dc, 0);
   2643    tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
   2644    return 2;
   2645}
   2646
   2647static int dec_lapc_im(CPUCRISState *env, DisasContext *dc)
   2648{
   2649    unsigned int rd;
   2650    int32_t imm;
   2651    int32_t pc;
   2652
   2653    rd = dc->op2;
   2654
   2655    cris_cc_mask(dc, 0);
   2656    imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
   2657    LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
   2658
   2659    pc = dc->pc;
   2660    pc += imm;
   2661    tcg_gen_movi_tl(cpu_R[rd], pc);
   2662    return 6;
   2663}
   2664
   2665/* Jump to special reg.  */
   2666static int dec_jump_p(CPUCRISState *env, DisasContext *dc)
   2667{
   2668    LOG_DIS("jump $p%u\n", dc->op2);
   2669
   2670    if (dc->op2 == PR_CCS) {
   2671        cris_evaluate_flags(dc);
   2672    }
   2673    t_gen_mov_TN_preg(env_btarget, dc->op2);
   2674    /* rete will often have low bit set to indicate delayslot.  */
   2675    tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
   2676    cris_cc_mask(dc, 0);
   2677    cris_prepare_jmp(dc, JMP_INDIRECT);
   2678    return 2;
   2679}
   2680
   2681/* Jump and save.  */
   2682static int dec_jas_r(CPUCRISState *env, DisasContext *dc)
   2683{
   2684    TCGv c;
   2685    LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
   2686    cris_cc_mask(dc, 0);
   2687    /* Store the return address in Pd.  */
   2688    tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
   2689    if (dc->op2 > 15) {
   2690        abort();
   2691    }
   2692    c = tcg_const_tl(dc->pc + 4);
   2693    t_gen_mov_preg_TN(dc, dc->op2, c);
   2694    tcg_temp_free(c);
   2695
   2696    cris_prepare_jmp(dc, JMP_INDIRECT);
   2697    return 2;
   2698}
   2699
   2700static int dec_jas_im(CPUCRISState *env, DisasContext *dc)
   2701{
   2702    uint32_t imm;
   2703    TCGv c;
   2704
   2705    imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
   2706
   2707    LOG_DIS("jas 0x%x\n", imm);
   2708    cris_cc_mask(dc, 0);
   2709    c = tcg_const_tl(dc->pc + 8);
   2710    /* Store the return address in Pd.  */
   2711    t_gen_mov_preg_TN(dc, dc->op2, c);
   2712    tcg_temp_free(c);
   2713
   2714    dc->jmp_pc = imm;
   2715    cris_prepare_jmp(dc, JMP_DIRECT);
   2716    return 6;
   2717}
   2718
   2719static int dec_jasc_im(CPUCRISState *env, DisasContext *dc)
   2720{
   2721    uint32_t imm;
   2722    TCGv c;
   2723
   2724    imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
   2725
   2726    LOG_DIS("jasc 0x%x\n", imm);
   2727    cris_cc_mask(dc, 0);
   2728    c = tcg_const_tl(dc->pc + 8 + 4);
   2729    /* Store the return address in Pd.  */
   2730    t_gen_mov_preg_TN(dc, dc->op2, c);
   2731    tcg_temp_free(c);
   2732
   2733    dc->jmp_pc = imm;
   2734    cris_prepare_jmp(dc, JMP_DIRECT);
   2735    return 6;
   2736}
   2737
   2738static int dec_jasc_r(CPUCRISState *env, DisasContext *dc)
   2739{
   2740    TCGv c;
   2741    LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
   2742    cris_cc_mask(dc, 0);
   2743    /* Store the return address in Pd.  */
   2744    tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
   2745    c = tcg_const_tl(dc->pc + 4 + 4);
   2746    t_gen_mov_preg_TN(dc, dc->op2, c);
   2747    tcg_temp_free(c);
   2748    cris_prepare_jmp(dc, JMP_INDIRECT);
   2749    return 2;
   2750}
   2751
   2752static int dec_bcc_im(CPUCRISState *env, DisasContext *dc)
   2753{
   2754    int32_t offset;
   2755    uint32_t cond = dc->op2;
   2756
   2757    offset = cris_fetch(env, dc, dc->pc + 2, 2, 1);
   2758
   2759    LOG_DIS("b%s %d pc=%x dst=%x\n",
   2760            cc_name(cond), offset,
   2761            dc->pc, dc->pc + offset);
   2762
   2763    cris_cc_mask(dc, 0);
   2764    /* op2 holds the condition-code.  */
   2765    cris_prepare_cc_branch(dc, offset, cond);
   2766    return 4;
   2767}
   2768
   2769static int dec_bas_im(CPUCRISState *env, DisasContext *dc)
   2770{
   2771    int32_t simm;
   2772    TCGv c;
   2773
   2774    simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
   2775
   2776    LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
   2777    cris_cc_mask(dc, 0);
   2778    c = tcg_const_tl(dc->pc + 8);
   2779    /* Store the return address in Pd.  */
   2780    t_gen_mov_preg_TN(dc, dc->op2, c);
   2781    tcg_temp_free(c);
   2782
   2783    dc->jmp_pc = dc->pc + simm;
   2784    cris_prepare_jmp(dc, JMP_DIRECT);
   2785    return 6;
   2786}
   2787
   2788static int dec_basc_im(CPUCRISState *env, DisasContext *dc)
   2789{
   2790    int32_t simm;
   2791    TCGv c;
   2792    simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
   2793
   2794    LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
   2795    cris_cc_mask(dc, 0);
   2796    c = tcg_const_tl(dc->pc + 12);
   2797    /* Store the return address in Pd.  */
   2798    t_gen_mov_preg_TN(dc, dc->op2, c);
   2799    tcg_temp_free(c);
   2800
   2801    dc->jmp_pc = dc->pc + simm;
   2802    cris_prepare_jmp(dc, JMP_DIRECT);
   2803    return 6;
   2804}
   2805
   2806static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
   2807{
   2808    cris_cc_mask(dc, 0);
   2809
   2810    if (dc->op2 == 15) {
   2811        tcg_gen_st_i32(tcg_const_i32(1), cpu_env,
   2812                       -offsetof(CRISCPU, env) + offsetof(CPUState, halted));
   2813        tcg_gen_movi_tl(env_pc, dc->pc + 2);
   2814        t_gen_raise_exception(EXCP_HLT);
   2815        dc->base.is_jmp = DISAS_NORETURN;
   2816        return 2;
   2817    }
   2818
   2819    switch (dc->op2 & 7) {
   2820    case 2:
   2821        /* rfe.  */
   2822        LOG_DIS("rfe\n");
   2823        cris_evaluate_flags(dc);
   2824        gen_helper_rfe(cpu_env);
   2825        dc->base.is_jmp = DISAS_UPDATE;
   2826        dc->cpustate_changed = true;
   2827        break;
   2828    case 5:
   2829        /* rfn.  */
   2830        LOG_DIS("rfn\n");
   2831        cris_evaluate_flags(dc);
   2832        gen_helper_rfn(cpu_env);
   2833        dc->base.is_jmp = DISAS_UPDATE;
   2834        dc->cpustate_changed = true;
   2835        break;
   2836    case 6:
   2837        LOG_DIS("break %d\n", dc->op1);
   2838        cris_evaluate_flags(dc);
   2839        /* break.  */
   2840        tcg_gen_movi_tl(env_pc, dc->pc + 2);
   2841
   2842        /* Breaks start at 16 in the exception vector.  */
   2843        t_gen_movi_env_TN(trap_vector, dc->op1 + 16);
   2844        t_gen_raise_exception(EXCP_BREAK);
   2845        dc->base.is_jmp = DISAS_NORETURN;
   2846        break;
   2847    default:
   2848        printf("op2=%x\n", dc->op2);
   2849        BUG();
   2850        break;
   2851
   2852    }
   2853    return 2;
   2854}
   2855
   2856static int dec_ftag_fidx_d_m(CPUCRISState *env, DisasContext *dc)
   2857{
   2858    return 2;
   2859}
   2860
   2861static int dec_ftag_fidx_i_m(CPUCRISState *env, DisasContext *dc)
   2862{
   2863    return 2;
   2864}
   2865
   2866static int dec_null(CPUCRISState *env, DisasContext *dc)
   2867{
   2868    printf("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
   2869        dc->pc, dc->opcode, dc->op1, dc->op2);
   2870    fflush(NULL);
   2871    BUG();
   2872    return 2;
   2873}
   2874
   2875static const struct decoder_info {
   2876    struct {
   2877        uint32_t bits;
   2878        uint32_t mask;
   2879    };
   2880    int (*dec)(CPUCRISState *env, DisasContext *dc);
   2881} decinfo[] = {
   2882    /* Order matters here.  */
   2883    {DEC_MOVEQ, dec_moveq},
   2884    {DEC_BTSTQ, dec_btstq},
   2885    {DEC_CMPQ, dec_cmpq},
   2886    {DEC_ADDOQ, dec_addoq},
   2887    {DEC_ADDQ, dec_addq},
   2888    {DEC_SUBQ, dec_subq},
   2889    {DEC_ANDQ, dec_andq},
   2890    {DEC_ORQ, dec_orq},
   2891    {DEC_ASRQ, dec_asrq},
   2892    {DEC_LSLQ, dec_lslq},
   2893    {DEC_LSRQ, dec_lsrq},
   2894    {DEC_BCCQ, dec_bccq},
   2895
   2896    {DEC_BCC_IM, dec_bcc_im},
   2897    {DEC_JAS_IM, dec_jas_im},
   2898    {DEC_JAS_R, dec_jas_r},
   2899    {DEC_JASC_IM, dec_jasc_im},
   2900    {DEC_JASC_R, dec_jasc_r},
   2901    {DEC_BAS_IM, dec_bas_im},
   2902    {DEC_BASC_IM, dec_basc_im},
   2903    {DEC_JUMP_P, dec_jump_p},
   2904    {DEC_LAPC_IM, dec_lapc_im},
   2905    {DEC_LAPCQ, dec_lapcq},
   2906
   2907    {DEC_RFE_ETC, dec_rfe_etc},
   2908    {DEC_ADDC_MR, dec_addc_mr},
   2909
   2910    {DEC_MOVE_MP, dec_move_mp},
   2911    {DEC_MOVE_PM, dec_move_pm},
   2912    {DEC_MOVEM_MR, dec_movem_mr},
   2913    {DEC_MOVEM_RM, dec_movem_rm},
   2914    {DEC_MOVE_PR, dec_move_pr},
   2915    {DEC_SCC_R, dec_scc_r},
   2916    {DEC_SETF, dec_setclrf},
   2917    {DEC_CLEARF, dec_setclrf},
   2918
   2919    {DEC_MOVE_SR, dec_move_sr},
   2920    {DEC_MOVE_RP, dec_move_rp},
   2921    {DEC_SWAP_R, dec_swap_r},
   2922    {DEC_ABS_R, dec_abs_r},
   2923    {DEC_LZ_R, dec_lz_r},
   2924    {DEC_MOVE_RS, dec_move_rs},
   2925    {DEC_BTST_R, dec_btst_r},
   2926    {DEC_ADDC_R, dec_addc_r},
   2927
   2928    {DEC_DSTEP_R, dec_dstep_r},
   2929    {DEC_XOR_R, dec_xor_r},
   2930    {DEC_MCP_R, dec_mcp_r},
   2931    {DEC_CMP_R, dec_cmp_r},
   2932
   2933    {DEC_ADDI_R, dec_addi_r},
   2934    {DEC_ADDI_ACR, dec_addi_acr},
   2935
   2936    {DEC_ADD_R, dec_add_r},
   2937    {DEC_SUB_R, dec_sub_r},
   2938
   2939    {DEC_ADDU_R, dec_addu_r},
   2940    {DEC_ADDS_R, dec_adds_r},
   2941    {DEC_SUBU_R, dec_subu_r},
   2942    {DEC_SUBS_R, dec_subs_r},
   2943    {DEC_LSL_R, dec_lsl_r},
   2944
   2945    {DEC_AND_R, dec_and_r},
   2946    {DEC_OR_R, dec_or_r},
   2947    {DEC_BOUND_R, dec_bound_r},
   2948    {DEC_ASR_R, dec_asr_r},
   2949    {DEC_LSR_R, dec_lsr_r},
   2950
   2951    {DEC_MOVU_R, dec_movu_r},
   2952    {DEC_MOVS_R, dec_movs_r},
   2953    {DEC_NEG_R, dec_neg_r},
   2954    {DEC_MOVE_R, dec_move_r},
   2955
   2956    {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
   2957    {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
   2958
   2959    {DEC_MULS_R, dec_muls_r},
   2960    {DEC_MULU_R, dec_mulu_r},
   2961
   2962    {DEC_ADDU_M, dec_addu_m},
   2963    {DEC_ADDS_M, dec_adds_m},
   2964    {DEC_SUBU_M, dec_subu_m},
   2965    {DEC_SUBS_M, dec_subs_m},
   2966
   2967    {DEC_CMPU_M, dec_cmpu_m},
   2968    {DEC_CMPS_M, dec_cmps_m},
   2969    {DEC_MOVU_M, dec_movu_m},
   2970    {DEC_MOVS_M, dec_movs_m},
   2971
   2972    {DEC_CMP_M, dec_cmp_m},
   2973    {DEC_ADDO_M, dec_addo_m},
   2974    {DEC_BOUND_M, dec_bound_m},
   2975    {DEC_ADD_M, dec_add_m},
   2976    {DEC_SUB_M, dec_sub_m},
   2977    {DEC_AND_M, dec_and_m},
   2978    {DEC_OR_M, dec_or_m},
   2979    {DEC_MOVE_RM, dec_move_rm},
   2980    {DEC_TEST_M, dec_test_m},
   2981    {DEC_MOVE_MR, dec_move_mr},
   2982
   2983    {{0, 0}, dec_null}
   2984};
   2985
   2986static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
   2987{
   2988    int insn_len = 2;
   2989    int i;
   2990
   2991    /* Load a halfword onto the instruction register.  */
   2992        dc->ir = cris_fetch(env, dc, dc->pc, 2, 0);
   2993
   2994    /* Now decode it.  */
   2995    dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
   2996    dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
   2997    dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
   2998    dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
   2999    dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
   3000    dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);
   3001
   3002    /* Large switch for all insns.  */
   3003    for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
   3004        if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
   3005            insn_len = decinfo[i].dec(env, dc);
   3006            break;
   3007        }
   3008    }
   3009
   3010#if !defined(CONFIG_USER_ONLY)
   3011    /* Single-stepping ?  */
   3012    if (dc->tb_flags & S_FLAG) {
   3013        TCGLabel *l1 = gen_new_label();
   3014        tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1);
   3015        /* We treat SPC as a break with an odd trap vector.  */
   3016        cris_evaluate_flags(dc);
   3017        t_gen_movi_env_TN(trap_vector, 3);
   3018        tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
   3019        tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len);
   3020        t_gen_raise_exception(EXCP_BREAK);
   3021        gen_set_label(l1);
   3022    }
   3023#endif
   3024    return insn_len;
   3025}
   3026
   3027#include "translate_v10.c.inc"
   3028
   3029/*
   3030 * Delay slots on QEMU/CRIS.
   3031 *
   3032 * If an exception hits on a delayslot, the core will let ERP (the Exception
   3033 * Return Pointer) point to the branch (the previous) insn and set the lsb to
   3034 * to give SW a hint that the exception actually hit on the dslot.
   3035 *
   3036 * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by
   3037 * the core and any jmp to an odd addresses will mask off that lsb. It is 
   3038 * simply there to let sw know there was an exception on a dslot.
   3039 *
   3040 * When the software returns from an exception, the branch will re-execute.
   3041 * On QEMU care needs to be taken when a branch+delayslot sequence is broken
   3042 * and the branch and delayslot don't share pages.
   3043 *
   3044 * The TB contaning the branch insn will set up env->btarget and evaluate 
   3045 * env->btaken. When the translation loop exits we will note that the branch 
   3046 * sequence is broken and let env->dslot be the size of the branch insn (those
   3047 * vary in length).
   3048 *
   3049 * The TB contaning the delayslot will have the PC of its real insn (i.e no lsb
   3050 * set). It will also expect to have env->dslot setup with the size of the 
   3051 * delay slot so that env->pc - env->dslot point to the branch insn. This TB 
   3052 * will execute the dslot and take the branch, either to btarget or just one 
   3053 * insn ahead.
   3054 *
   3055 * When exceptions occur, we check for env->dslot in do_interrupt to detect 
   3056 * broken branch sequences and setup $erp accordingly (i.e let it point to the
   3057 * branch and set lsb). Then env->dslot gets cleared so that the exception 
   3058 * handler can enter. When returning from exceptions (jump $erp) the lsb gets
   3059 * masked off and we will reexecute the branch insn.
   3060 *
   3061 */
   3062
   3063static void cris_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
   3064{
   3065    DisasContext *dc = container_of(dcbase, DisasContext, base);
   3066    CPUCRISState *env = cs->env_ptr;
   3067    uint32_t tb_flags = dc->base.tb->flags;
   3068    uint32_t pc_start;
   3069
   3070    if (env->pregs[PR_VR] == 32) {
   3071        dc->decoder = crisv32_decoder;
   3072        dc->clear_locked_irq = 0;
   3073    } else {
   3074        dc->decoder = crisv10_decoder;
   3075        dc->clear_locked_irq = 1;
   3076    }
   3077
   3078    /*
   3079     * Odd PC indicates that branch is rexecuting due to exception in the
   3080     * delayslot, like in real hw.
   3081     */
   3082    pc_start = dc->base.pc_first & ~1;
   3083    dc->base.pc_first = pc_start;
   3084    dc->base.pc_next = pc_start;
   3085
   3086    dc->cpu = env_archcpu(env);
   3087    dc->ppc = pc_start;
   3088    dc->pc = pc_start;
   3089    dc->flags_uptodate = 1;
   3090    dc->flags_x = tb_flags & X_FLAG;
   3091    dc->cc_x_uptodate = 0;
   3092    dc->cc_mask = 0;
   3093    dc->update_cc = 0;
   3094    dc->clear_prefix = 0;
   3095    dc->cpustate_changed = 0;
   3096
   3097    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
   3098    dc->cc_size_uptodate = -1;
   3099
   3100    /* Decode TB flags.  */
   3101    dc->tb_flags = tb_flags & (S_FLAG | P_FLAG | U_FLAG | X_FLAG | PFIX_FLAG);
   3102    dc->delayed_branch = !!(tb_flags & 7);
   3103    if (dc->delayed_branch) {
   3104        dc->jmp = JMP_INDIRECT;
   3105    } else {
   3106        dc->jmp = JMP_NOJMP;
   3107    }
   3108}
   3109
   3110static void cris_tr_tb_start(DisasContextBase *db, CPUState *cpu)
   3111{
   3112}
   3113
   3114static void cris_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
   3115{
   3116    DisasContext *dc = container_of(dcbase, DisasContext, base);
   3117
   3118    tcg_gen_insn_start(dc->delayed_branch == 1 ? dc->ppc | 1 : dc->pc);
   3119}
   3120
   3121static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
   3122{
   3123    DisasContext *dc = container_of(dcbase, DisasContext, base);
   3124    CPUCRISState *env = cs->env_ptr;
   3125    unsigned int insn_len;
   3126
   3127    /* Pretty disas.  */
   3128    LOG_DIS("%8.8x:\t", dc->pc);
   3129
   3130    dc->clear_x = 1;
   3131
   3132    insn_len = dc->decoder(env, dc);
   3133    dc->ppc = dc->pc;
   3134    dc->pc += insn_len;
   3135    dc->base.pc_next += insn_len;
   3136
   3137    if (dc->base.is_jmp == DISAS_NORETURN) {
   3138        return;
   3139    }
   3140
   3141    if (dc->clear_x) {
   3142        cris_clear_x_flag(dc);
   3143    }
   3144
   3145    /*
   3146     * All branches are delayed branches, handled immediately below.
   3147     * We don't expect to see odd combinations of exit conditions.
   3148     */
   3149    assert(dc->base.is_jmp == DISAS_NEXT || dc->cpustate_changed);
   3150
   3151    if (dc->delayed_branch && --dc->delayed_branch == 0) {
   3152        dc->base.is_jmp = DISAS_DBRANCH;
   3153        return;
   3154    }
   3155
   3156    if (dc->base.is_jmp != DISAS_NEXT) {
   3157        return;
   3158    }
   3159
   3160    /* Force an update if the per-tb cpu state has changed.  */
   3161    if (dc->cpustate_changed) {
   3162        dc->base.is_jmp = DISAS_UPDATE_NEXT;
   3163        return;
   3164    }
   3165
   3166    /*
   3167     * FIXME: Only the first insn in the TB should cross a page boundary.
   3168     * If we can detect the length of the next insn easily, we should.
   3169     * In the meantime, simply stop when we do cross.
   3170     */
   3171    if ((dc->pc ^ dc->base.pc_first) & TARGET_PAGE_MASK) {
   3172        dc->base.is_jmp = DISAS_TOO_MANY;
   3173    }
   3174}
   3175
   3176static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
   3177{
   3178    DisasContext *dc = container_of(dcbase, DisasContext, base);
   3179    DisasJumpType is_jmp = dc->base.is_jmp;
   3180    target_ulong npc = dc->pc;
   3181
   3182    if (is_jmp == DISAS_NORETURN) {
   3183        /* If we have a broken branch+delayslot sequence, it's too late. */
   3184        assert(dc->delayed_branch != 1);
   3185        return;
   3186    }
   3187
   3188    if (dc->clear_locked_irq) {
   3189        t_gen_movi_env_TN(locked_irq, 0);
   3190    }
   3191
   3192    /* Broken branch+delayslot sequence.  */
   3193    if (dc->delayed_branch == 1) {
   3194        /* Set env->dslot to the size of the branch insn.  */
   3195        t_gen_movi_env_TN(dslot, dc->pc - dc->ppc);
   3196        cris_store_direct_jmp(dc);
   3197    }
   3198
   3199    cris_evaluate_flags(dc);
   3200
   3201    /* Evaluate delayed branch destination and fold to another is_jmp case. */
   3202    if (is_jmp == DISAS_DBRANCH) {
   3203        if (dc->base.tb->flags & 7) {
   3204            t_gen_movi_env_TN(dslot, 0);
   3205        }
   3206
   3207        switch (dc->jmp) {
   3208        case JMP_DIRECT:
   3209            npc = dc->jmp_pc;
   3210            is_jmp = dc->cpustate_changed ? DISAS_UPDATE_NEXT : DISAS_TOO_MANY;
   3211            break;
   3212
   3213        case JMP_DIRECT_CC:
   3214            /*
   3215             * Use a conditional branch if either taken or not-taken path
   3216             * can use goto_tb.  If neither can, then treat it as indirect.
   3217             */
   3218            if (likely(!dc->cpustate_changed)
   3219                && (use_goto_tb(dc, dc->jmp_pc) || use_goto_tb(dc, npc))) {
   3220                TCGLabel *not_taken = gen_new_label();
   3221
   3222                tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, not_taken);
   3223                gen_goto_tb(dc, 1, dc->jmp_pc);
   3224                gen_set_label(not_taken);
   3225
   3226                /* not-taken case handled below. */
   3227                is_jmp = DISAS_TOO_MANY;
   3228                break;
   3229            }
   3230            tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
   3231            /* fall through */
   3232
   3233        case JMP_INDIRECT:
   3234            tcg_gen_movcond_tl(TCG_COND_NE, env_pc,
   3235                               env_btaken, tcg_constant_tl(0),
   3236                               env_btarget, tcg_constant_tl(npc));
   3237            is_jmp = dc->cpustate_changed ? DISAS_UPDATE : DISAS_JUMP;
   3238
   3239            /*
   3240             * We have now consumed btaken and btarget.  Hint to the
   3241             * tcg compiler that the writeback to env may be dropped.
   3242             */
   3243            tcg_gen_discard_tl(env_btaken);
   3244            tcg_gen_discard_tl(env_btarget);
   3245            break;
   3246
   3247        default:
   3248            g_assert_not_reached();
   3249        }
   3250    }
   3251
   3252    if (unlikely(dc->base.singlestep_enabled)) {
   3253        switch (is_jmp) {
   3254        case DISAS_TOO_MANY:
   3255        case DISAS_UPDATE_NEXT:
   3256            tcg_gen_movi_tl(env_pc, npc);
   3257            /* fall through */
   3258        case DISAS_JUMP:
   3259        case DISAS_UPDATE:
   3260            t_gen_raise_exception(EXCP_DEBUG);
   3261            return;
   3262        default:
   3263            break;
   3264        }
   3265        g_assert_not_reached();
   3266    }
   3267
   3268    switch (is_jmp) {
   3269    case DISAS_TOO_MANY:
   3270        gen_goto_tb(dc, 0, npc);
   3271        break;
   3272    case DISAS_UPDATE_NEXT:
   3273        tcg_gen_movi_tl(env_pc, npc);
   3274        /* fall through */
   3275    case DISAS_JUMP:
   3276        tcg_gen_lookup_and_goto_ptr();
   3277        break;
   3278    case DISAS_UPDATE:
   3279        /* Indicate that interupts must be re-evaluated before the next TB. */
   3280        tcg_gen_exit_tb(NULL, 0);
   3281        break;
   3282    default:
   3283        g_assert_not_reached();
   3284    }
   3285}
   3286
   3287static void cris_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
   3288{
   3289    if (!DISAS_CRIS) {
   3290        qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
   3291        log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
   3292    }
   3293}
   3294
   3295static const TranslatorOps cris_tr_ops = {
   3296    .init_disas_context = cris_tr_init_disas_context,
   3297    .tb_start           = cris_tr_tb_start,
   3298    .insn_start         = cris_tr_insn_start,
   3299    .translate_insn     = cris_tr_translate_insn,
   3300    .tb_stop            = cris_tr_tb_stop,
   3301    .disas_log          = cris_tr_disas_log,
   3302};
   3303
   3304void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
   3305{
   3306    DisasContext dc;
   3307    translator_loop(&cris_tr_ops, &dc.base, cs, tb, max_insns);
   3308}
   3309
   3310void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags)
   3311{
   3312    CRISCPU *cpu = CRIS_CPU(cs);
   3313    CPUCRISState *env = &cpu->env;
   3314    const char * const *regnames;
   3315    const char * const *pregnames;
   3316    int i;
   3317
   3318    if (!env) {
   3319        return;
   3320    }
   3321    if (env->pregs[PR_VR] < 32) {
   3322        pregnames = pregnames_v10;
   3323        regnames = regnames_v10;
   3324    } else {
   3325        pregnames = pregnames_v32;
   3326        regnames = regnames_v32;
   3327    }
   3328
   3329    qemu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
   3330                 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
   3331                 env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
   3332                 env->cc_op,
   3333                 env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
   3334
   3335
   3336    for (i = 0; i < 16; i++) {
   3337        qemu_fprintf(f, "%s=%8.8x ", regnames[i], env->regs[i]);
   3338        if ((i + 1) % 4 == 0) {
   3339            qemu_fprintf(f, "\n");
   3340        }
   3341    }
   3342    qemu_fprintf(f, "\nspecial regs:\n");
   3343    for (i = 0; i < 16; i++) {
   3344        qemu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
   3345        if ((i + 1) % 4 == 0) {
   3346            qemu_fprintf(f, "\n");
   3347        }
   3348    }
   3349    if (env->pregs[PR_VR] >= 32) {
   3350        uint32_t srs = env->pregs[PR_SRS];
   3351        qemu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
   3352        if (srs < ARRAY_SIZE(env->sregs)) {
   3353            for (i = 0; i < 16; i++) {
   3354                qemu_fprintf(f, "s%2.2d=%8.8x ",
   3355                             i, env->sregs[srs][i]);
   3356                if ((i + 1) % 4 == 0) {
   3357                    qemu_fprintf(f, "\n");
   3358                }
   3359            }
   3360        }
   3361    }
   3362    qemu_fprintf(f, "\n\n");
   3363
   3364}
   3365
   3366void cris_initialize_tcg(void)
   3367{
   3368    int i;
   3369
   3370    cc_x = tcg_global_mem_new(cpu_env,
   3371                              offsetof(CPUCRISState, cc_x), "cc_x");
   3372    cc_src = tcg_global_mem_new(cpu_env,
   3373                                offsetof(CPUCRISState, cc_src), "cc_src");
   3374    cc_dest = tcg_global_mem_new(cpu_env,
   3375                                 offsetof(CPUCRISState, cc_dest),
   3376                                 "cc_dest");
   3377    cc_result = tcg_global_mem_new(cpu_env,
   3378                                   offsetof(CPUCRISState, cc_result),
   3379                                   "cc_result");
   3380    cc_op = tcg_global_mem_new(cpu_env,
   3381                               offsetof(CPUCRISState, cc_op), "cc_op");
   3382    cc_size = tcg_global_mem_new(cpu_env,
   3383                                 offsetof(CPUCRISState, cc_size),
   3384                                 "cc_size");
   3385    cc_mask = tcg_global_mem_new(cpu_env,
   3386                                 offsetof(CPUCRISState, cc_mask),
   3387                                 "cc_mask");
   3388
   3389    env_pc = tcg_global_mem_new(cpu_env,
   3390                                offsetof(CPUCRISState, pc),
   3391                                "pc");
   3392    env_btarget = tcg_global_mem_new(cpu_env,
   3393                                     offsetof(CPUCRISState, btarget),
   3394                                     "btarget");
   3395    env_btaken = tcg_global_mem_new(cpu_env,
   3396                                    offsetof(CPUCRISState, btaken),
   3397                                    "btaken");
   3398    for (i = 0; i < 16; i++) {
   3399        cpu_R[i] = tcg_global_mem_new(cpu_env,
   3400                                      offsetof(CPUCRISState, regs[i]),
   3401                                      regnames_v32[i]);
   3402    }
   3403    for (i = 0; i < 16; i++) {
   3404        cpu_PR[i] = tcg_global_mem_new(cpu_env,
   3405                                       offsetof(CPUCRISState, pregs[i]),
   3406                                       pregnames_v32[i]);
   3407    }
   3408}
   3409
   3410void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb,
   3411                          target_ulong *data)
   3412{
   3413    env->pc = data[0];
   3414}