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