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