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