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