qemu/target/cris/translate.c
<<
>>
Prefs
   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    switch (is_jmp) {
3253    case DISAS_TOO_MANY:
3254        gen_goto_tb(dc, 0, npc);
3255        break;
3256    case DISAS_UPDATE_NEXT:
3257        tcg_gen_movi_tl(env_pc, npc);
3258        /* fall through */
3259    case DISAS_JUMP:
3260        tcg_gen_lookup_and_goto_ptr();
3261        break;
3262    case DISAS_UPDATE:
3263        /* Indicate that interupts must be re-evaluated before the next TB. */
3264        tcg_gen_exit_tb(NULL, 0);
3265        break;
3266    default:
3267        g_assert_not_reached();
3268    }
3269}
3270
3271static void cris_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
3272{
3273    if (!DISAS_CRIS) {
3274        qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
3275        log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
3276    }
3277}
3278
3279static const TranslatorOps cris_tr_ops = {
3280    .init_disas_context = cris_tr_init_disas_context,
3281    .tb_start           = cris_tr_tb_start,
3282    .insn_start         = cris_tr_insn_start,
3283    .translate_insn     = cris_tr_translate_insn,
3284    .tb_stop            = cris_tr_tb_stop,
3285    .disas_log          = cris_tr_disas_log,
3286};
3287
3288void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
3289{
3290    DisasContext dc;
3291    translator_loop(&cris_tr_ops, &dc.base, cs, tb, max_insns);
3292}
3293
3294void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags)
3295{
3296    CRISCPU *cpu = CRIS_CPU(cs);
3297    CPUCRISState *env = &cpu->env;
3298    const char * const *regnames;
3299    const char * const *pregnames;
3300    int i;
3301
3302    if (!env) {
3303        return;
3304    }
3305    if (env->pregs[PR_VR] < 32) {
3306        pregnames = pregnames_v10;
3307        regnames = regnames_v10;
3308    } else {
3309        pregnames = pregnames_v32;
3310        regnames = regnames_v32;
3311    }
3312
3313    qemu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
3314                 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
3315                 env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
3316                 env->cc_op,
3317                 env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
3318
3319
3320    for (i = 0; i < 16; i++) {
3321        qemu_fprintf(f, "%s=%8.8x ", regnames[i], env->regs[i]);
3322        if ((i + 1) % 4 == 0) {
3323            qemu_fprintf(f, "\n");
3324        }
3325    }
3326    qemu_fprintf(f, "\nspecial regs:\n");
3327    for (i = 0; i < 16; i++) {
3328        qemu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
3329        if ((i + 1) % 4 == 0) {
3330            qemu_fprintf(f, "\n");
3331        }
3332    }
3333    if (env->pregs[PR_VR] >= 32) {
3334        uint32_t srs = env->pregs[PR_SRS];
3335        qemu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
3336        if (srs < ARRAY_SIZE(env->sregs)) {
3337            for (i = 0; i < 16; i++) {
3338                qemu_fprintf(f, "s%2.2d=%8.8x ",
3339                             i, env->sregs[srs][i]);
3340                if ((i + 1) % 4 == 0) {
3341                    qemu_fprintf(f, "\n");
3342                }
3343            }
3344        }
3345    }
3346    qemu_fprintf(f, "\n\n");
3347
3348}
3349
3350void cris_initialize_tcg(void)
3351{
3352    int i;
3353
3354    cc_x = tcg_global_mem_new(cpu_env,
3355                              offsetof(CPUCRISState, cc_x), "cc_x");
3356    cc_src = tcg_global_mem_new(cpu_env,
3357                                offsetof(CPUCRISState, cc_src), "cc_src");
3358    cc_dest = tcg_global_mem_new(cpu_env,
3359                                 offsetof(CPUCRISState, cc_dest),
3360                                 "cc_dest");
3361    cc_result = tcg_global_mem_new(cpu_env,
3362                                   offsetof(CPUCRISState, cc_result),
3363                                   "cc_result");
3364    cc_op = tcg_global_mem_new(cpu_env,
3365                               offsetof(CPUCRISState, cc_op), "cc_op");
3366    cc_size = tcg_global_mem_new(cpu_env,
3367                                 offsetof(CPUCRISState, cc_size),
3368                                 "cc_size");
3369    cc_mask = tcg_global_mem_new(cpu_env,
3370                                 offsetof(CPUCRISState, cc_mask),
3371                                 "cc_mask");
3372
3373    env_pc = tcg_global_mem_new(cpu_env,
3374                                offsetof(CPUCRISState, pc),
3375                                "pc");
3376    env_btarget = tcg_global_mem_new(cpu_env,
3377                                     offsetof(CPUCRISState, btarget),
3378                                     "btarget");
3379    env_btaken = tcg_global_mem_new(cpu_env,
3380                                    offsetof(CPUCRISState, btaken),
3381                                    "btaken");
3382    for (i = 0; i < 16; i++) {
3383        cpu_R[i] = tcg_global_mem_new(cpu_env,
3384                                      offsetof(CPUCRISState, regs[i]),
3385                                      regnames_v32[i]);
3386    }
3387    for (i = 0; i < 16; i++) {
3388        cpu_PR[i] = tcg_global_mem_new(cpu_env,
3389                                       offsetof(CPUCRISState, pregs[i]),
3390                                       pregnames_v32[i]);
3391    }
3392}
3393
3394void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb,
3395                          target_ulong *data)
3396{
3397    env->pc = data[0];
3398}
3399