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