qemu/target/sh4/translate.c
<<
>>
Prefs
   1/*
   2 *  SH4 translation
   3 *
   4 *  Copyright (c) 2005 Samuel Tardieu
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2.1 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#define DEBUG_DISAS
  21
  22#include "qemu/osdep.h"
  23#include "cpu.h"
  24#include "disas/disas.h"
  25#include "exec/exec-all.h"
  26#include "tcg/tcg-op.h"
  27#include "exec/cpu_ldst.h"
  28#include "exec/helper-proto.h"
  29#include "exec/helper-gen.h"
  30#include "exec/translator.h"
  31#include "exec/log.h"
  32#include "qemu/qemu-print.h"
  33
  34
  35typedef struct DisasContext {
  36    DisasContextBase base;
  37
  38    uint32_t tbflags;  /* should stay unmodified during the TB translation */
  39    uint32_t envflags; /* should stay in sync with env->flags using TCG ops */
  40    int memidx;
  41    int gbank;
  42    int fbank;
  43    uint32_t delayed_pc;
  44    uint32_t features;
  45
  46    uint16_t opcode;
  47
  48    bool has_movcal;
  49} DisasContext;
  50
  51#if defined(CONFIG_USER_ONLY)
  52#define IS_USER(ctx) 1
  53#define UNALIGN(C)   (ctx->tbflags & TB_FLAG_UNALIGN ? MO_UNALN : MO_ALIGN)
  54#else
  55#define IS_USER(ctx) (!(ctx->tbflags & (1u << SR_MD)))
  56#define UNALIGN(C)   0
  57#endif
  58
  59/* Target-specific values for ctx->base.is_jmp.  */
  60/* We want to exit back to the cpu loop for some reason.
  61   Usually this is to recognize interrupts immediately.  */
  62#define DISAS_STOP    DISAS_TARGET_0
  63
  64/* global register indexes */
  65static TCGv cpu_gregs[32];
  66static TCGv cpu_sr, cpu_sr_m, cpu_sr_q, cpu_sr_t;
  67static TCGv cpu_pc, cpu_ssr, cpu_spc, cpu_gbr;
  68static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
  69static TCGv cpu_pr, cpu_fpscr, cpu_fpul;
  70static TCGv cpu_lock_addr, cpu_lock_value;
  71static TCGv cpu_fregs[32];
  72
  73/* internal register indexes */
  74static TCGv cpu_flags, cpu_delayed_pc, cpu_delayed_cond;
  75
  76#include "exec/gen-icount.h"
  77
  78void sh4_translate_init(void)
  79{
  80    int i;
  81    static const char * const gregnames[24] = {
  82        "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
  83        "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
  84        "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
  85        "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
  86        "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
  87    };
  88    static const char * const fregnames[32] = {
  89         "FPR0_BANK0",  "FPR1_BANK0",  "FPR2_BANK0",  "FPR3_BANK0",
  90         "FPR4_BANK0",  "FPR5_BANK0",  "FPR6_BANK0",  "FPR7_BANK0",
  91         "FPR8_BANK0",  "FPR9_BANK0", "FPR10_BANK0", "FPR11_BANK0",
  92        "FPR12_BANK0", "FPR13_BANK0", "FPR14_BANK0", "FPR15_BANK0",
  93         "FPR0_BANK1",  "FPR1_BANK1",  "FPR2_BANK1",  "FPR3_BANK1",
  94         "FPR4_BANK1",  "FPR5_BANK1",  "FPR6_BANK1",  "FPR7_BANK1",
  95         "FPR8_BANK1",  "FPR9_BANK1", "FPR10_BANK1", "FPR11_BANK1",
  96        "FPR12_BANK1", "FPR13_BANK1", "FPR14_BANK1", "FPR15_BANK1",
  97    };
  98
  99    for (i = 0; i < 24; i++) {
 100        cpu_gregs[i] = tcg_global_mem_new_i32(cpu_env,
 101                                              offsetof(CPUSH4State, gregs[i]),
 102                                              gregnames[i]);
 103    }
 104    memcpy(cpu_gregs + 24, cpu_gregs + 8, 8 * sizeof(TCGv));
 105
 106    cpu_pc = tcg_global_mem_new_i32(cpu_env,
 107                                    offsetof(CPUSH4State, pc), "PC");
 108    cpu_sr = tcg_global_mem_new_i32(cpu_env,
 109                                    offsetof(CPUSH4State, sr), "SR");
 110    cpu_sr_m = tcg_global_mem_new_i32(cpu_env,
 111                                      offsetof(CPUSH4State, sr_m), "SR_M");
 112    cpu_sr_q = tcg_global_mem_new_i32(cpu_env,
 113                                      offsetof(CPUSH4State, sr_q), "SR_Q");
 114    cpu_sr_t = tcg_global_mem_new_i32(cpu_env,
 115                                      offsetof(CPUSH4State, sr_t), "SR_T");
 116    cpu_ssr = tcg_global_mem_new_i32(cpu_env,
 117                                     offsetof(CPUSH4State, ssr), "SSR");
 118    cpu_spc = tcg_global_mem_new_i32(cpu_env,
 119                                     offsetof(CPUSH4State, spc), "SPC");
 120    cpu_gbr = tcg_global_mem_new_i32(cpu_env,
 121                                     offsetof(CPUSH4State, gbr), "GBR");
 122    cpu_vbr = tcg_global_mem_new_i32(cpu_env,
 123                                     offsetof(CPUSH4State, vbr), "VBR");
 124    cpu_sgr = tcg_global_mem_new_i32(cpu_env,
 125                                     offsetof(CPUSH4State, sgr), "SGR");
 126    cpu_dbr = tcg_global_mem_new_i32(cpu_env,
 127                                     offsetof(CPUSH4State, dbr), "DBR");
 128    cpu_mach = tcg_global_mem_new_i32(cpu_env,
 129                                      offsetof(CPUSH4State, mach), "MACH");
 130    cpu_macl = tcg_global_mem_new_i32(cpu_env,
 131                                      offsetof(CPUSH4State, macl), "MACL");
 132    cpu_pr = tcg_global_mem_new_i32(cpu_env,
 133                                    offsetof(CPUSH4State, pr), "PR");
 134    cpu_fpscr = tcg_global_mem_new_i32(cpu_env,
 135                                       offsetof(CPUSH4State, fpscr), "FPSCR");
 136    cpu_fpul = tcg_global_mem_new_i32(cpu_env,
 137                                      offsetof(CPUSH4State, fpul), "FPUL");
 138
 139    cpu_flags = tcg_global_mem_new_i32(cpu_env,
 140                                       offsetof(CPUSH4State, flags), "_flags_");
 141    cpu_delayed_pc = tcg_global_mem_new_i32(cpu_env,
 142                                            offsetof(CPUSH4State, delayed_pc),
 143                                            "_delayed_pc_");
 144    cpu_delayed_cond = tcg_global_mem_new_i32(cpu_env,
 145                                              offsetof(CPUSH4State,
 146                                                       delayed_cond),
 147                                              "_delayed_cond_");
 148    cpu_lock_addr = tcg_global_mem_new_i32(cpu_env,
 149                                           offsetof(CPUSH4State, lock_addr),
 150                                           "_lock_addr_");
 151    cpu_lock_value = tcg_global_mem_new_i32(cpu_env,
 152                                            offsetof(CPUSH4State, lock_value),
 153                                            "_lock_value_");
 154
 155    for (i = 0; i < 32; i++)
 156        cpu_fregs[i] = tcg_global_mem_new_i32(cpu_env,
 157                                              offsetof(CPUSH4State, fregs[i]),
 158                                              fregnames[i]);
 159}
 160
 161void superh_cpu_dump_state(CPUState *cs, FILE *f, int flags)
 162{
 163    SuperHCPU *cpu = SUPERH_CPU(cs);
 164    CPUSH4State *env = &cpu->env;
 165    int i;
 166
 167    qemu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
 168                 env->pc, cpu_read_sr(env), env->pr, env->fpscr);
 169    qemu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
 170                 env->spc, env->ssr, env->gbr, env->vbr);
 171    qemu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
 172                 env->sgr, env->dbr, env->delayed_pc, env->fpul);
 173    for (i = 0; i < 24; i += 4) {
 174        qemu_printf("r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
 175                    i, env->gregs[i], i + 1, env->gregs[i + 1],
 176                    i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
 177    }
 178    if (env->flags & DELAY_SLOT) {
 179        qemu_printf("in delay slot (delayed_pc=0x%08x)\n",
 180                    env->delayed_pc);
 181    } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
 182        qemu_printf("in conditional delay slot (delayed_pc=0x%08x)\n",
 183                    env->delayed_pc);
 184    } else if (env->flags & DELAY_SLOT_RTE) {
 185        qemu_fprintf(f, "in rte delay slot (delayed_pc=0x%08x)\n",
 186                     env->delayed_pc);
 187    }
 188}
 189
 190static void gen_read_sr(TCGv dst)
 191{
 192    TCGv t0 = tcg_temp_new();
 193    tcg_gen_shli_i32(t0, cpu_sr_q, SR_Q);
 194    tcg_gen_or_i32(dst, dst, t0);
 195    tcg_gen_shli_i32(t0, cpu_sr_m, SR_M);
 196    tcg_gen_or_i32(dst, dst, t0);
 197    tcg_gen_shli_i32(t0, cpu_sr_t, SR_T);
 198    tcg_gen_or_i32(dst, cpu_sr, t0);
 199    tcg_temp_free_i32(t0);
 200}
 201
 202static void gen_write_sr(TCGv src)
 203{
 204    tcg_gen_andi_i32(cpu_sr, src,
 205                     ~((1u << SR_Q) | (1u << SR_M) | (1u << SR_T)));
 206    tcg_gen_extract_i32(cpu_sr_q, src, SR_Q, 1);
 207    tcg_gen_extract_i32(cpu_sr_m, src, SR_M, 1);
 208    tcg_gen_extract_i32(cpu_sr_t, src, SR_T, 1);
 209}
 210
 211static inline void gen_save_cpu_state(DisasContext *ctx, bool save_pc)
 212{
 213    if (save_pc) {
 214        tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next);
 215    }
 216    if (ctx->delayed_pc != (uint32_t) -1) {
 217        tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
 218    }
 219    if ((ctx->tbflags & TB_FLAG_ENVFLAGS_MASK) != ctx->envflags) {
 220        tcg_gen_movi_i32(cpu_flags, ctx->envflags);
 221    }
 222}
 223
 224static inline bool use_exit_tb(DisasContext *ctx)
 225{
 226    return (ctx->tbflags & GUSA_EXCLUSIVE) != 0;
 227}
 228
 229static bool use_goto_tb(DisasContext *ctx, target_ulong dest)
 230{
 231    if (use_exit_tb(ctx)) {
 232        return false;
 233    }
 234    return translator_use_goto_tb(&ctx->base, dest);
 235}
 236
 237static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
 238{
 239    if (use_goto_tb(ctx, dest)) {
 240        tcg_gen_goto_tb(n);
 241        tcg_gen_movi_i32(cpu_pc, dest);
 242        tcg_gen_exit_tb(ctx->base.tb, n);
 243    } else {
 244        tcg_gen_movi_i32(cpu_pc, dest);
 245        if (use_exit_tb(ctx)) {
 246            tcg_gen_exit_tb(NULL, 0);
 247        } else {
 248            tcg_gen_lookup_and_goto_ptr();
 249        }
 250    }
 251    ctx->base.is_jmp = DISAS_NORETURN;
 252}
 253
 254static void gen_jump(DisasContext * ctx)
 255{
 256    if (ctx->delayed_pc == -1) {
 257        /* Target is not statically known, it comes necessarily from a
 258           delayed jump as immediate jump are conditinal jumps */
 259        tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
 260        tcg_gen_discard_i32(cpu_delayed_pc);
 261        if (use_exit_tb(ctx)) {
 262            tcg_gen_exit_tb(NULL, 0);
 263        } else {
 264            tcg_gen_lookup_and_goto_ptr();
 265        }
 266        ctx->base.is_jmp = DISAS_NORETURN;
 267    } else {
 268        gen_goto_tb(ctx, 0, ctx->delayed_pc);
 269    }
 270}
 271
 272/* Immediate conditional jump (bt or bf) */
 273static void gen_conditional_jump(DisasContext *ctx, target_ulong dest,
 274                                 bool jump_if_true)
 275{
 276    TCGLabel *l1 = gen_new_label();
 277    TCGCond cond_not_taken = jump_if_true ? TCG_COND_EQ : TCG_COND_NE;
 278
 279    if (ctx->tbflags & GUSA_EXCLUSIVE) {
 280        /* When in an exclusive region, we must continue to the end.
 281           Therefore, exit the region on a taken branch, but otherwise
 282           fall through to the next instruction.  */
 283        tcg_gen_brcondi_i32(cond_not_taken, cpu_sr_t, 0, l1);
 284        tcg_gen_movi_i32(cpu_flags, ctx->envflags & ~GUSA_MASK);
 285        /* Note that this won't actually use a goto_tb opcode because we
 286           disallow it in use_goto_tb, but it handles exit + singlestep.  */
 287        gen_goto_tb(ctx, 0, dest);
 288        gen_set_label(l1);
 289        ctx->base.is_jmp = DISAS_NEXT;
 290        return;
 291    }
 292
 293    gen_save_cpu_state(ctx, false);
 294    tcg_gen_brcondi_i32(cond_not_taken, cpu_sr_t, 0, l1);
 295    gen_goto_tb(ctx, 0, dest);
 296    gen_set_label(l1);
 297    gen_goto_tb(ctx, 1, ctx->base.pc_next + 2);
 298    ctx->base.is_jmp = DISAS_NORETURN;
 299}
 300
 301/* Delayed conditional jump (bt or bf) */
 302static void gen_delayed_conditional_jump(DisasContext * ctx)
 303{
 304    TCGLabel *l1 = gen_new_label();
 305    TCGv ds = tcg_temp_new();
 306
 307    tcg_gen_mov_i32(ds, cpu_delayed_cond);
 308    tcg_gen_discard_i32(cpu_delayed_cond);
 309
 310    if (ctx->tbflags & GUSA_EXCLUSIVE) {
 311        /* When in an exclusive region, we must continue to the end.
 312           Therefore, exit the region on a taken branch, but otherwise
 313           fall through to the next instruction.  */
 314        tcg_gen_brcondi_i32(TCG_COND_EQ, ds, 0, l1);
 315
 316        /* Leave the gUSA region.  */
 317        tcg_gen_movi_i32(cpu_flags, ctx->envflags & ~GUSA_MASK);
 318        gen_jump(ctx);
 319
 320        gen_set_label(l1);
 321        ctx->base.is_jmp = DISAS_NEXT;
 322        return;
 323    }
 324
 325    tcg_gen_brcondi_i32(TCG_COND_NE, ds, 0, l1);
 326    gen_goto_tb(ctx, 1, ctx->base.pc_next + 2);
 327    gen_set_label(l1);
 328    gen_jump(ctx);
 329}
 330
 331static inline void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
 332{
 333    /* We have already signaled illegal instruction for odd Dr.  */
 334    tcg_debug_assert((reg & 1) == 0);
 335    reg ^= ctx->fbank;
 336    tcg_gen_concat_i32_i64(t, cpu_fregs[reg + 1], cpu_fregs[reg]);
 337}
 338
 339static inline void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
 340{
 341    /* We have already signaled illegal instruction for odd Dr.  */
 342    tcg_debug_assert((reg & 1) == 0);
 343    reg ^= ctx->fbank;
 344    tcg_gen_extr_i64_i32(cpu_fregs[reg + 1], cpu_fregs[reg], t);
 345}
 346
 347#define B3_0 (ctx->opcode & 0xf)
 348#define B6_4 ((ctx->opcode >> 4) & 0x7)
 349#define B7_4 ((ctx->opcode >> 4) & 0xf)
 350#define B7_0 (ctx->opcode & 0xff)
 351#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
 352#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
 353  (ctx->opcode & 0xfff))
 354#define B11_8 ((ctx->opcode >> 8) & 0xf)
 355#define B15_12 ((ctx->opcode >> 12) & 0xf)
 356
 357#define REG(x)     cpu_gregs[(x) ^ ctx->gbank]
 358#define ALTREG(x)  cpu_gregs[(x) ^ ctx->gbank ^ 0x10]
 359#define FREG(x)    cpu_fregs[(x) ^ ctx->fbank]
 360
 361#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
 362
 363#define CHECK_NOT_DELAY_SLOT \
 364    if (ctx->envflags & DELAY_SLOT_MASK) {  \
 365        goto do_illegal_slot;               \
 366    }
 367
 368#define CHECK_PRIVILEGED \
 369    if (IS_USER(ctx)) {                     \
 370        goto do_illegal;                    \
 371    }
 372
 373#define CHECK_FPU_ENABLED \
 374    if (ctx->tbflags & (1u << SR_FD)) {     \
 375        goto do_fpu_disabled;               \
 376    }
 377
 378#define CHECK_FPSCR_PR_0 \
 379    if (ctx->tbflags & FPSCR_PR) {          \
 380        goto do_illegal;                    \
 381    }
 382
 383#define CHECK_FPSCR_PR_1 \
 384    if (!(ctx->tbflags & FPSCR_PR)) {       \
 385        goto do_illegal;                    \
 386    }
 387
 388#define CHECK_SH4A \
 389    if (!(ctx->features & SH_FEATURE_SH4A)) { \
 390        goto do_illegal;                      \
 391    }
 392
 393static void _decode_opc(DisasContext * ctx)
 394{
 395    /* This code tries to make movcal emulation sufficiently
 396       accurate for Linux purposes.  This instruction writes
 397       memory, and prior to that, always allocates a cache line.
 398       It is used in two contexts:
 399       - in memcpy, where data is copied in blocks, the first write
 400       of to a block uses movca.l for performance.
 401       - in arch/sh/mm/cache-sh4.c, movcal.l + ocbi combination is used
 402       to flush the cache. Here, the data written by movcal.l is never
 403       written to memory, and the data written is just bogus.
 404
 405       To simulate this, we simulate movcal.l, we store the value to memory,
 406       but we also remember the previous content. If we see ocbi, we check
 407       if movcal.l for that address was done previously. If so, the write should
 408       not have hit the memory, so we restore the previous content.
 409       When we see an instruction that is neither movca.l
 410       nor ocbi, the previous content is discarded.
 411
 412       To optimize, we only try to flush stores when we're at the start of
 413       TB, or if we already saw movca.l in this TB and did not flush stores
 414       yet.  */
 415    if (ctx->has_movcal)
 416        {
 417          int opcode = ctx->opcode & 0xf0ff;
 418          if (opcode != 0x0093 /* ocbi */
 419              && opcode != 0x00c3 /* movca.l */)
 420              {
 421                  gen_helper_discard_movcal_backup(cpu_env);
 422                  ctx->has_movcal = 0;
 423              }
 424        }
 425
 426#if 0
 427    fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
 428#endif
 429
 430    switch (ctx->opcode) {
 431    case 0x0019:                /* div0u */
 432        tcg_gen_movi_i32(cpu_sr_m, 0);
 433        tcg_gen_movi_i32(cpu_sr_q, 0);
 434        tcg_gen_movi_i32(cpu_sr_t, 0);
 435        return;
 436    case 0x000b:                /* rts */
 437        CHECK_NOT_DELAY_SLOT
 438        tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
 439        ctx->envflags |= DELAY_SLOT;
 440        ctx->delayed_pc = (uint32_t) - 1;
 441        return;
 442    case 0x0028:                /* clrmac */
 443        tcg_gen_movi_i32(cpu_mach, 0);
 444        tcg_gen_movi_i32(cpu_macl, 0);
 445        return;
 446    case 0x0048:                /* clrs */
 447        tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(1u << SR_S));
 448        return;
 449    case 0x0008:                /* clrt */
 450        tcg_gen_movi_i32(cpu_sr_t, 0);
 451        return;
 452    case 0x0038:                /* ldtlb */
 453        CHECK_PRIVILEGED
 454        gen_helper_ldtlb(cpu_env);
 455        return;
 456    case 0x002b:                /* rte */
 457        CHECK_PRIVILEGED
 458        CHECK_NOT_DELAY_SLOT
 459        gen_write_sr(cpu_ssr);
 460        tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
 461        ctx->envflags |= DELAY_SLOT_RTE;
 462        ctx->delayed_pc = (uint32_t) - 1;
 463        ctx->base.is_jmp = DISAS_STOP;
 464        return;
 465    case 0x0058:                /* sets */
 466        tcg_gen_ori_i32(cpu_sr, cpu_sr, (1u << SR_S));
 467        return;
 468    case 0x0018:                /* sett */
 469        tcg_gen_movi_i32(cpu_sr_t, 1);
 470        return;
 471    case 0xfbfd:                /* frchg */
 472        CHECK_FPSCR_PR_0
 473        tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
 474        ctx->base.is_jmp = DISAS_STOP;
 475        return;
 476    case 0xf3fd:                /* fschg */
 477        CHECK_FPSCR_PR_0
 478        tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
 479        ctx->base.is_jmp = DISAS_STOP;
 480        return;
 481    case 0xf7fd:                /* fpchg */
 482        CHECK_SH4A
 483        tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_PR);
 484        ctx->base.is_jmp = DISAS_STOP;
 485        return;
 486    case 0x0009:                /* nop */
 487        return;
 488    case 0x001b:                /* sleep */
 489        CHECK_PRIVILEGED
 490        tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next + 2);
 491        gen_helper_sleep(cpu_env);
 492        return;
 493    }
 494
 495    switch (ctx->opcode & 0xf000) {
 496    case 0x1000:                /* mov.l Rm,@(disp,Rn) */
 497        {
 498            TCGv addr = tcg_temp_new();
 499            tcg_gen_addi_i32(addr, REG(B11_8), B3_0 * 4);
 500            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx,
 501                                MO_TEUL | UNALIGN(ctx));
 502            tcg_temp_free(addr);
 503        }
 504        return;
 505    case 0x5000:                /* mov.l @(disp,Rm),Rn */
 506        {
 507            TCGv addr = tcg_temp_new();
 508            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 4);
 509            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx,
 510                                MO_TESL | UNALIGN(ctx));
 511            tcg_temp_free(addr);
 512        }
 513        return;
 514    case 0xe000:                /* mov #imm,Rn */
 515#ifdef CONFIG_USER_ONLY
 516        /* Detect the start of a gUSA region.  If so, update envflags
 517           and end the TB.  This will allow us to see the end of the
 518           region (stored in R0) in the next TB.  */
 519        if (B11_8 == 15 && B7_0s < 0 &&
 520            (tb_cflags(ctx->base.tb) & CF_PARALLEL)) {
 521            ctx->envflags = deposit32(ctx->envflags, GUSA_SHIFT, 8, B7_0s);
 522            ctx->base.is_jmp = DISAS_STOP;
 523        }
 524#endif
 525        tcg_gen_movi_i32(REG(B11_8), B7_0s);
 526        return;
 527    case 0x9000:                /* mov.w @(disp,PC),Rn */
 528        {
 529            TCGv addr = tcg_const_i32(ctx->base.pc_next + 4 + B7_0 * 2);
 530            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESW);
 531            tcg_temp_free(addr);
 532        }
 533        return;
 534    case 0xd000:                /* mov.l @(disp,PC),Rn */
 535        {
 536            TCGv addr = tcg_const_i32((ctx->base.pc_next + 4 + B7_0 * 4) & ~3);
 537            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
 538            tcg_temp_free(addr);
 539        }
 540        return;
 541    case 0x7000:                /* add #imm,Rn */
 542        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);
 543        return;
 544    case 0xa000:                /* bra disp */
 545        CHECK_NOT_DELAY_SLOT
 546        ctx->delayed_pc = ctx->base.pc_next + 4 + B11_0s * 2;
 547        ctx->envflags |= DELAY_SLOT;
 548        return;
 549    case 0xb000:                /* bsr disp */
 550        CHECK_NOT_DELAY_SLOT
 551        tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 4);
 552        ctx->delayed_pc = ctx->base.pc_next + 4 + B11_0s * 2;
 553        ctx->envflags |= DELAY_SLOT;
 554        return;
 555    }
 556
 557    switch (ctx->opcode & 0xf00f) {
 558    case 0x6003:                /* mov Rm,Rn */
 559        tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
 560        return;
 561    case 0x2000:                /* mov.b Rm,@Rn */
 562        tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_UB);
 563        return;
 564    case 0x2001:                /* mov.w Rm,@Rn */
 565        tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx,
 566                            MO_TEUW | UNALIGN(ctx));
 567        return;
 568    case 0x2002:                /* mov.l Rm,@Rn */
 569        tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx,
 570                            MO_TEUL | UNALIGN(ctx));
 571        return;
 572    case 0x6000:                /* mov.b @Rm,Rn */
 573        tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_SB);
 574        return;
 575    case 0x6001:                /* mov.w @Rm,Rn */
 576        tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx,
 577                            MO_TESW | UNALIGN(ctx));
 578        return;
 579    case 0x6002:                /* mov.l @Rm,Rn */
 580        tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx,
 581                            MO_TESL | UNALIGN(ctx));
 582        return;
 583    case 0x2004:                /* mov.b Rm,@-Rn */
 584        {
 585            TCGv addr = tcg_temp_new();
 586            tcg_gen_subi_i32(addr, REG(B11_8), 1);
 587            /* might cause re-execution */
 588            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_UB);
 589            tcg_gen_mov_i32(REG(B11_8), addr);                  /* modify register status */
 590            tcg_temp_free(addr);
 591        }
 592        return;
 593    case 0x2005:                /* mov.w Rm,@-Rn */
 594        {
 595            TCGv addr = tcg_temp_new();
 596            tcg_gen_subi_i32(addr, REG(B11_8), 2);
 597            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx,
 598                                MO_TEUW | UNALIGN(ctx));
 599            tcg_gen_mov_i32(REG(B11_8), addr);
 600            tcg_temp_free(addr);
 601        }
 602        return;
 603    case 0x2006:                /* mov.l Rm,@-Rn */
 604        {
 605            TCGv addr = tcg_temp_new();
 606            tcg_gen_subi_i32(addr, REG(B11_8), 4);
 607            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx,
 608                                MO_TEUL | UNALIGN(ctx));
 609            tcg_gen_mov_i32(REG(B11_8), addr);
 610        tcg_temp_free(addr);
 611        }
 612        return;
 613    case 0x6004:                /* mov.b @Rm+,Rn */
 614        tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_SB);
 615        if ( B11_8 != B7_4 )
 616                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 1);
 617        return;
 618    case 0x6005:                /* mov.w @Rm+,Rn */
 619        tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx,
 620                            MO_TESW | UNALIGN(ctx));
 621        if ( B11_8 != B7_4 )
 622                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
 623        return;
 624    case 0x6006:                /* mov.l @Rm+,Rn */
 625        tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx,
 626                            MO_TESL | UNALIGN(ctx));
 627        if ( B11_8 != B7_4 )
 628                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
 629        return;
 630    case 0x0004:                /* mov.b Rm,@(R0,Rn) */
 631        {
 632            TCGv addr = tcg_temp_new();
 633            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
 634            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_UB);
 635            tcg_temp_free(addr);
 636        }
 637        return;
 638    case 0x0005:                /* mov.w Rm,@(R0,Rn) */
 639        {
 640            TCGv addr = tcg_temp_new();
 641            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
 642            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx,
 643                                MO_TEUW | UNALIGN(ctx));
 644            tcg_temp_free(addr);
 645        }
 646        return;
 647    case 0x0006:                /* mov.l Rm,@(R0,Rn) */
 648        {
 649            TCGv addr = tcg_temp_new();
 650            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
 651            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx,
 652                                MO_TEUL | UNALIGN(ctx));
 653            tcg_temp_free(addr);
 654        }
 655        return;
 656    case 0x000c:                /* mov.b @(R0,Rm),Rn */
 657        {
 658            TCGv addr = tcg_temp_new();
 659            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
 660            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_SB);
 661            tcg_temp_free(addr);
 662        }
 663        return;
 664    case 0x000d:                /* mov.w @(R0,Rm),Rn */
 665        {
 666            TCGv addr = tcg_temp_new();
 667            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
 668            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx,
 669                                MO_TESW | UNALIGN(ctx));
 670            tcg_temp_free(addr);
 671        }
 672        return;
 673    case 0x000e:                /* mov.l @(R0,Rm),Rn */
 674        {
 675            TCGv addr = tcg_temp_new();
 676            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
 677            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx,
 678                                MO_TESL | UNALIGN(ctx));
 679            tcg_temp_free(addr);
 680        }
 681        return;
 682    case 0x6008:                /* swap.b Rm,Rn */
 683        {
 684            TCGv low = tcg_temp_new();
 685            tcg_gen_bswap16_i32(low, REG(B7_4), 0);
 686            tcg_gen_deposit_i32(REG(B11_8), REG(B7_4), low, 0, 16);
 687            tcg_temp_free(low);
 688        }
 689        return;
 690    case 0x6009:                /* swap.w Rm,Rn */
 691        tcg_gen_rotli_i32(REG(B11_8), REG(B7_4), 16);
 692        return;
 693    case 0x200d:                /* xtrct Rm,Rn */
 694        {
 695            TCGv high, low;
 696            high = tcg_temp_new();
 697            tcg_gen_shli_i32(high, REG(B7_4), 16);
 698            low = tcg_temp_new();
 699            tcg_gen_shri_i32(low, REG(B11_8), 16);
 700            tcg_gen_or_i32(REG(B11_8), high, low);
 701            tcg_temp_free(low);
 702            tcg_temp_free(high);
 703        }
 704        return;
 705    case 0x300c:                /* add Rm,Rn */
 706        tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));
 707        return;
 708    case 0x300e:                /* addc Rm,Rn */
 709        {
 710            TCGv t0, t1;
 711            t0 = tcg_const_tl(0);
 712            t1 = tcg_temp_new();
 713            tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0);
 714            tcg_gen_add2_i32(REG(B11_8), cpu_sr_t,
 715                             REG(B11_8), t0, t1, cpu_sr_t);
 716            tcg_temp_free(t0);
 717            tcg_temp_free(t1);
 718        }
 719        return;
 720    case 0x300f:                /* addv Rm,Rn */
 721        {
 722            TCGv t0, t1, t2;
 723            t0 = tcg_temp_new();
 724            tcg_gen_add_i32(t0, REG(B7_4), REG(B11_8));
 725            t1 = tcg_temp_new();
 726            tcg_gen_xor_i32(t1, t0, REG(B11_8));
 727            t2 = tcg_temp_new();
 728            tcg_gen_xor_i32(t2, REG(B7_4), REG(B11_8));
 729            tcg_gen_andc_i32(cpu_sr_t, t1, t2);
 730            tcg_temp_free(t2);
 731            tcg_gen_shri_i32(cpu_sr_t, cpu_sr_t, 31);
 732            tcg_temp_free(t1);
 733            tcg_gen_mov_i32(REG(B7_4), t0);
 734            tcg_temp_free(t0);
 735        }
 736        return;
 737    case 0x2009:                /* and Rm,Rn */
 738        tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
 739        return;
 740    case 0x3000:                /* cmp/eq Rm,Rn */
 741        tcg_gen_setcond_i32(TCG_COND_EQ, cpu_sr_t, REG(B11_8), REG(B7_4));
 742        return;
 743    case 0x3003:                /* cmp/ge Rm,Rn */
 744        tcg_gen_setcond_i32(TCG_COND_GE, cpu_sr_t, REG(B11_8), REG(B7_4));
 745        return;
 746    case 0x3007:                /* cmp/gt Rm,Rn */
 747        tcg_gen_setcond_i32(TCG_COND_GT, cpu_sr_t, REG(B11_8), REG(B7_4));
 748        return;
 749    case 0x3006:                /* cmp/hi Rm,Rn */
 750        tcg_gen_setcond_i32(TCG_COND_GTU, cpu_sr_t, REG(B11_8), REG(B7_4));
 751        return;
 752    case 0x3002:                /* cmp/hs Rm,Rn */
 753        tcg_gen_setcond_i32(TCG_COND_GEU, cpu_sr_t, REG(B11_8), REG(B7_4));
 754        return;
 755    case 0x200c:                /* cmp/str Rm,Rn */
 756        {
 757            TCGv cmp1 = tcg_temp_new();
 758            TCGv cmp2 = tcg_temp_new();
 759            tcg_gen_xor_i32(cmp2, REG(B7_4), REG(B11_8));
 760            tcg_gen_subi_i32(cmp1, cmp2, 0x01010101);
 761            tcg_gen_andc_i32(cmp1, cmp1, cmp2);
 762            tcg_gen_andi_i32(cmp1, cmp1, 0x80808080);
 763            tcg_gen_setcondi_i32(TCG_COND_NE, cpu_sr_t, cmp1, 0);
 764            tcg_temp_free(cmp2);
 765            tcg_temp_free(cmp1);
 766        }
 767        return;
 768    case 0x2007:                /* div0s Rm,Rn */
 769        tcg_gen_shri_i32(cpu_sr_q, REG(B11_8), 31);         /* SR_Q */
 770        tcg_gen_shri_i32(cpu_sr_m, REG(B7_4), 31);          /* SR_M */
 771        tcg_gen_xor_i32(cpu_sr_t, cpu_sr_q, cpu_sr_m);      /* SR_T */
 772        return;
 773    case 0x3004:                /* div1 Rm,Rn */
 774        {
 775            TCGv t0 = tcg_temp_new();
 776            TCGv t1 = tcg_temp_new();
 777            TCGv t2 = tcg_temp_new();
 778            TCGv zero = tcg_const_i32(0);
 779
 780            /* shift left arg1, saving the bit being pushed out and inserting
 781               T on the right */
 782            tcg_gen_shri_i32(t0, REG(B11_8), 31);
 783            tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
 784            tcg_gen_or_i32(REG(B11_8), REG(B11_8), cpu_sr_t);
 785
 786            /* Add or subtract arg0 from arg1 depending if Q == M. To avoid
 787               using 64-bit temps, we compute arg0's high part from q ^ m, so
 788               that it is 0x00000000 when adding the value or 0xffffffff when
 789               subtracting it. */
 790            tcg_gen_xor_i32(t1, cpu_sr_q, cpu_sr_m);
 791            tcg_gen_subi_i32(t1, t1, 1);
 792            tcg_gen_neg_i32(t2, REG(B7_4));
 793            tcg_gen_movcond_i32(TCG_COND_EQ, t2, t1, zero, REG(B7_4), t2);
 794            tcg_gen_add2_i32(REG(B11_8), t1, REG(B11_8), zero, t2, t1);
 795
 796            /* compute T and Q depending on carry */
 797            tcg_gen_andi_i32(t1, t1, 1);
 798            tcg_gen_xor_i32(t1, t1, t0);
 799            tcg_gen_xori_i32(cpu_sr_t, t1, 1);
 800            tcg_gen_xor_i32(cpu_sr_q, cpu_sr_m, t1);
 801
 802            tcg_temp_free(zero);
 803            tcg_temp_free(t2);
 804            tcg_temp_free(t1);
 805            tcg_temp_free(t0);
 806        }
 807        return;
 808    case 0x300d:                /* dmuls.l Rm,Rn */
 809        tcg_gen_muls2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
 810        return;
 811    case 0x3005:                /* dmulu.l Rm,Rn */
 812        tcg_gen_mulu2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
 813        return;
 814    case 0x600e:                /* exts.b Rm,Rn */
 815        tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));
 816        return;
 817    case 0x600f:                /* exts.w Rm,Rn */
 818        tcg_gen_ext16s_i32(REG(B11_8), REG(B7_4));
 819        return;
 820    case 0x600c:                /* extu.b Rm,Rn */
 821        tcg_gen_ext8u_i32(REG(B11_8), REG(B7_4));
 822        return;
 823    case 0x600d:                /* extu.w Rm,Rn */
 824        tcg_gen_ext16u_i32(REG(B11_8), REG(B7_4));
 825        return;
 826    case 0x000f:                /* mac.l @Rm+,@Rn+ */
 827        {
 828            TCGv arg0, arg1;
 829            arg0 = tcg_temp_new();
 830            tcg_gen_qemu_ld_i32(arg0, REG(B7_4), ctx->memidx, MO_TESL);
 831            arg1 = tcg_temp_new();
 832            tcg_gen_qemu_ld_i32(arg1, REG(B11_8), ctx->memidx, MO_TESL);
 833            gen_helper_macl(cpu_env, arg0, arg1);
 834            tcg_temp_free(arg1);
 835            tcg_temp_free(arg0);
 836            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
 837            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
 838        }
 839        return;
 840    case 0x400f:                /* mac.w @Rm+,@Rn+ */
 841        {
 842            TCGv arg0, arg1;
 843            arg0 = tcg_temp_new();
 844            tcg_gen_qemu_ld_i32(arg0, REG(B7_4), ctx->memidx, MO_TESL);
 845            arg1 = tcg_temp_new();
 846            tcg_gen_qemu_ld_i32(arg1, REG(B11_8), ctx->memidx, MO_TESL);
 847            gen_helper_macw(cpu_env, arg0, arg1);
 848            tcg_temp_free(arg1);
 849            tcg_temp_free(arg0);
 850            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);
 851            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
 852        }
 853        return;
 854    case 0x0007:                /* mul.l Rm,Rn */
 855        tcg_gen_mul_i32(cpu_macl, REG(B7_4), REG(B11_8));
 856        return;
 857    case 0x200f:                /* muls.w Rm,Rn */
 858        {
 859            TCGv arg0, arg1;
 860            arg0 = tcg_temp_new();
 861            tcg_gen_ext16s_i32(arg0, REG(B7_4));
 862            arg1 = tcg_temp_new();
 863            tcg_gen_ext16s_i32(arg1, REG(B11_8));
 864            tcg_gen_mul_i32(cpu_macl, arg0, arg1);
 865            tcg_temp_free(arg1);
 866            tcg_temp_free(arg0);
 867        }
 868        return;
 869    case 0x200e:                /* mulu.w Rm,Rn */
 870        {
 871            TCGv arg0, arg1;
 872            arg0 = tcg_temp_new();
 873            tcg_gen_ext16u_i32(arg0, REG(B7_4));
 874            arg1 = tcg_temp_new();
 875            tcg_gen_ext16u_i32(arg1, REG(B11_8));
 876            tcg_gen_mul_i32(cpu_macl, arg0, arg1);
 877            tcg_temp_free(arg1);
 878            tcg_temp_free(arg0);
 879        }
 880        return;
 881    case 0x600b:                /* neg Rm,Rn */
 882        tcg_gen_neg_i32(REG(B11_8), REG(B7_4));
 883        return;
 884    case 0x600a:                /* negc Rm,Rn */
 885        {
 886            TCGv t0 = tcg_const_i32(0);
 887            tcg_gen_add2_i32(REG(B11_8), cpu_sr_t,
 888                             REG(B7_4), t0, cpu_sr_t, t0);
 889            tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t,
 890                             t0, t0, REG(B11_8), cpu_sr_t);
 891            tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
 892            tcg_temp_free(t0);
 893        }
 894        return;
 895    case 0x6007:                /* not Rm,Rn */
 896        tcg_gen_not_i32(REG(B11_8), REG(B7_4));
 897        return;
 898    case 0x200b:                /* or Rm,Rn */
 899        tcg_gen_or_i32(REG(B11_8), REG(B11_8), REG(B7_4));
 900        return;
 901    case 0x400c:                /* shad Rm,Rn */
 902        {
 903            TCGv t0 = tcg_temp_new();
 904            TCGv t1 = tcg_temp_new();
 905            TCGv t2 = tcg_temp_new();
 906
 907            tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
 908
 909            /* positive case: shift to the left */
 910            tcg_gen_shl_i32(t1, REG(B11_8), t0);
 911
 912            /* negative case: shift to the right in two steps to
 913               correctly handle the -32 case */
 914            tcg_gen_xori_i32(t0, t0, 0x1f);
 915            tcg_gen_sar_i32(t2, REG(B11_8), t0);
 916            tcg_gen_sari_i32(t2, t2, 1);
 917
 918            /* select between the two cases */
 919            tcg_gen_movi_i32(t0, 0);
 920            tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
 921
 922            tcg_temp_free(t0);
 923            tcg_temp_free(t1);
 924            tcg_temp_free(t2);
 925        }
 926        return;
 927    case 0x400d:                /* shld Rm,Rn */
 928        {
 929            TCGv t0 = tcg_temp_new();
 930            TCGv t1 = tcg_temp_new();
 931            TCGv t2 = tcg_temp_new();
 932
 933            tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
 934
 935            /* positive case: shift to the left */
 936            tcg_gen_shl_i32(t1, REG(B11_8), t0);
 937
 938            /* negative case: shift to the right in two steps to
 939               correctly handle the -32 case */
 940            tcg_gen_xori_i32(t0, t0, 0x1f);
 941            tcg_gen_shr_i32(t2, REG(B11_8), t0);
 942            tcg_gen_shri_i32(t2, t2, 1);
 943
 944            /* select between the two cases */
 945            tcg_gen_movi_i32(t0, 0);
 946            tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
 947
 948            tcg_temp_free(t0);
 949            tcg_temp_free(t1);
 950            tcg_temp_free(t2);
 951        }
 952        return;
 953    case 0x3008:                /* sub Rm,Rn */
 954        tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));
 955        return;
 956    case 0x300a:                /* subc Rm,Rn */
 957        {
 958            TCGv t0, t1;
 959            t0 = tcg_const_tl(0);
 960            t1 = tcg_temp_new();
 961            tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0);
 962            tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t,
 963                             REG(B11_8), t0, t1, cpu_sr_t);
 964            tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
 965            tcg_temp_free(t0);
 966            tcg_temp_free(t1);
 967        }
 968        return;
 969    case 0x300b:                /* subv Rm,Rn */
 970        {
 971            TCGv t0, t1, t2;
 972            t0 = tcg_temp_new();
 973            tcg_gen_sub_i32(t0, REG(B11_8), REG(B7_4));
 974            t1 = tcg_temp_new();
 975            tcg_gen_xor_i32(t1, t0, REG(B7_4));
 976            t2 = tcg_temp_new();
 977            tcg_gen_xor_i32(t2, REG(B11_8), REG(B7_4));
 978            tcg_gen_and_i32(t1, t1, t2);
 979            tcg_temp_free(t2);
 980            tcg_gen_shri_i32(cpu_sr_t, t1, 31);
 981            tcg_temp_free(t1);
 982            tcg_gen_mov_i32(REG(B11_8), t0);
 983            tcg_temp_free(t0);
 984        }
 985        return;
 986    case 0x2008:                /* tst Rm,Rn */
 987        {
 988            TCGv val = tcg_temp_new();
 989            tcg_gen_and_i32(val, REG(B7_4), REG(B11_8));
 990            tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
 991            tcg_temp_free(val);
 992        }
 993        return;
 994    case 0x200a:                /* xor Rm,Rn */
 995        tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));
 996        return;
 997    case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
 998        CHECK_FPU_ENABLED
 999        if (ctx->tbflags & FPSCR_SZ) {
1000            int xsrc = XHACK(B7_4);
1001            int xdst = XHACK(B11_8);
1002            tcg_gen_mov_i32(FREG(xdst), FREG(xsrc));
1003            tcg_gen_mov_i32(FREG(xdst + 1), FREG(xsrc + 1));
1004        } else {
1005            tcg_gen_mov_i32(FREG(B11_8), FREG(B7_4));
1006        }
1007        return;
1008    case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
1009        CHECK_FPU_ENABLED
1010        if (ctx->tbflags & FPSCR_SZ) {
1011            TCGv_i64 fp = tcg_temp_new_i64();
1012            gen_load_fpr64(ctx, fp, XHACK(B7_4));
1013            tcg_gen_qemu_st_i64(fp, REG(B11_8), ctx->memidx, MO_TEUQ);
1014            tcg_temp_free_i64(fp);
1015        } else {
1016            tcg_gen_qemu_st_i32(FREG(B7_4), REG(B11_8), ctx->memidx, MO_TEUL);
1017        }
1018        return;
1019    case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
1020        CHECK_FPU_ENABLED
1021        if (ctx->tbflags & FPSCR_SZ) {
1022            TCGv_i64 fp = tcg_temp_new_i64();
1023            tcg_gen_qemu_ld_i64(fp, REG(B7_4), ctx->memidx, MO_TEUQ);
1024            gen_store_fpr64(ctx, fp, XHACK(B11_8));
1025            tcg_temp_free_i64(fp);
1026        } else {
1027            tcg_gen_qemu_ld_i32(FREG(B11_8), REG(B7_4), ctx->memidx, MO_TEUL);
1028        }
1029        return;
1030    case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
1031        CHECK_FPU_ENABLED
1032        if (ctx->tbflags & FPSCR_SZ) {
1033            TCGv_i64 fp = tcg_temp_new_i64();
1034            tcg_gen_qemu_ld_i64(fp, REG(B7_4), ctx->memidx, MO_TEUQ);
1035            gen_store_fpr64(ctx, fp, XHACK(B11_8));
1036            tcg_temp_free_i64(fp);
1037            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 8);
1038        } else {
1039            tcg_gen_qemu_ld_i32(FREG(B11_8), REG(B7_4), ctx->memidx, MO_TEUL);
1040            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
1041        }
1042        return;
1043    case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
1044        CHECK_FPU_ENABLED
1045        {
1046            TCGv addr = tcg_temp_new_i32();
1047            if (ctx->tbflags & FPSCR_SZ) {
1048                TCGv_i64 fp = tcg_temp_new_i64();
1049                gen_load_fpr64(ctx, fp, XHACK(B7_4));
1050                tcg_gen_subi_i32(addr, REG(B11_8), 8);
1051                tcg_gen_qemu_st_i64(fp, addr, ctx->memidx, MO_TEUQ);
1052                tcg_temp_free_i64(fp);
1053            } else {
1054                tcg_gen_subi_i32(addr, REG(B11_8), 4);
1055                tcg_gen_qemu_st_i32(FREG(B7_4), addr, ctx->memidx, MO_TEUL);
1056            }
1057            tcg_gen_mov_i32(REG(B11_8), addr);
1058            tcg_temp_free(addr);
1059        }
1060        return;
1061    case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
1062        CHECK_FPU_ENABLED
1063        {
1064            TCGv addr = tcg_temp_new_i32();
1065            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
1066            if (ctx->tbflags & FPSCR_SZ) {
1067                TCGv_i64 fp = tcg_temp_new_i64();
1068                tcg_gen_qemu_ld_i64(fp, addr, ctx->memidx, MO_TEUQ);
1069                gen_store_fpr64(ctx, fp, XHACK(B11_8));
1070                tcg_temp_free_i64(fp);
1071            } else {
1072                tcg_gen_qemu_ld_i32(FREG(B11_8), addr, ctx->memidx, MO_TEUL);
1073            }
1074            tcg_temp_free(addr);
1075        }
1076        return;
1077    case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
1078        CHECK_FPU_ENABLED
1079        {
1080            TCGv addr = tcg_temp_new();
1081            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
1082            if (ctx->tbflags & FPSCR_SZ) {
1083                TCGv_i64 fp = tcg_temp_new_i64();
1084                gen_load_fpr64(ctx, fp, XHACK(B7_4));
1085                tcg_gen_qemu_st_i64(fp, addr, ctx->memidx, MO_TEUQ);
1086                tcg_temp_free_i64(fp);
1087            } else {
1088                tcg_gen_qemu_st_i32(FREG(B7_4), addr, ctx->memidx, MO_TEUL);
1089            }
1090            tcg_temp_free(addr);
1091        }
1092        return;
1093    case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1094    case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1095    case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1096    case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1097    case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1098    case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1099        {
1100            CHECK_FPU_ENABLED
1101            if (ctx->tbflags & FPSCR_PR) {
1102                TCGv_i64 fp0, fp1;
1103
1104                if (ctx->opcode & 0x0110) {
1105                    goto do_illegal;
1106                }
1107                fp0 = tcg_temp_new_i64();
1108                fp1 = tcg_temp_new_i64();
1109                gen_load_fpr64(ctx, fp0, B11_8);
1110                gen_load_fpr64(ctx, fp1, B7_4);
1111                switch (ctx->opcode & 0xf00f) {
1112                case 0xf000:            /* fadd Rm,Rn */
1113                    gen_helper_fadd_DT(fp0, cpu_env, fp0, fp1);
1114                    break;
1115                case 0xf001:            /* fsub Rm,Rn */
1116                    gen_helper_fsub_DT(fp0, cpu_env, fp0, fp1);
1117                    break;
1118                case 0xf002:            /* fmul Rm,Rn */
1119                    gen_helper_fmul_DT(fp0, cpu_env, fp0, fp1);
1120                    break;
1121                case 0xf003:            /* fdiv Rm,Rn */
1122                    gen_helper_fdiv_DT(fp0, cpu_env, fp0, fp1);
1123                    break;
1124                case 0xf004:            /* fcmp/eq Rm,Rn */
1125                    gen_helper_fcmp_eq_DT(cpu_sr_t, cpu_env, fp0, fp1);
1126                    return;
1127                case 0xf005:            /* fcmp/gt Rm,Rn */
1128                    gen_helper_fcmp_gt_DT(cpu_sr_t, cpu_env, fp0, fp1);
1129                    return;
1130                }
1131                gen_store_fpr64(ctx, fp0, B11_8);
1132                tcg_temp_free_i64(fp0);
1133                tcg_temp_free_i64(fp1);
1134            } else {
1135                switch (ctx->opcode & 0xf00f) {
1136                case 0xf000:            /* fadd Rm,Rn */
1137                    gen_helper_fadd_FT(FREG(B11_8), cpu_env,
1138                                       FREG(B11_8), FREG(B7_4));
1139                    break;
1140                case 0xf001:            /* fsub Rm,Rn */
1141                    gen_helper_fsub_FT(FREG(B11_8), cpu_env,
1142                                       FREG(B11_8), FREG(B7_4));
1143                    break;
1144                case 0xf002:            /* fmul Rm,Rn */
1145                    gen_helper_fmul_FT(FREG(B11_8), cpu_env,
1146                                       FREG(B11_8), FREG(B7_4));
1147                    break;
1148                case 0xf003:            /* fdiv Rm,Rn */
1149                    gen_helper_fdiv_FT(FREG(B11_8), cpu_env,
1150                                       FREG(B11_8), FREG(B7_4));
1151                    break;
1152                case 0xf004:            /* fcmp/eq Rm,Rn */
1153                    gen_helper_fcmp_eq_FT(cpu_sr_t, cpu_env,
1154                                          FREG(B11_8), FREG(B7_4));
1155                    return;
1156                case 0xf005:            /* fcmp/gt Rm,Rn */
1157                    gen_helper_fcmp_gt_FT(cpu_sr_t, cpu_env,
1158                                          FREG(B11_8), FREG(B7_4));
1159                    return;
1160                }
1161            }
1162        }
1163        return;
1164    case 0xf00e: /* fmac FR0,RM,Rn */
1165        CHECK_FPU_ENABLED
1166        CHECK_FPSCR_PR_0
1167        gen_helper_fmac_FT(FREG(B11_8), cpu_env,
1168                           FREG(0), FREG(B7_4), FREG(B11_8));
1169        return;
1170    }
1171
1172    switch (ctx->opcode & 0xff00) {
1173    case 0xc900:                /* and #imm,R0 */
1174        tcg_gen_andi_i32(REG(0), REG(0), B7_0);
1175        return;
1176    case 0xcd00:                /* and.b #imm,@(R0,GBR) */
1177        {
1178            TCGv addr, val;
1179            addr = tcg_temp_new();
1180            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1181            val = tcg_temp_new();
1182            tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1183            tcg_gen_andi_i32(val, val, B7_0);
1184            tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1185            tcg_temp_free(val);
1186            tcg_temp_free(addr);
1187        }
1188        return;
1189    case 0x8b00:                /* bf label */
1190        CHECK_NOT_DELAY_SLOT
1191        gen_conditional_jump(ctx, ctx->base.pc_next + 4 + B7_0s * 2, false);
1192        return;
1193    case 0x8f00:                /* bf/s label */
1194        CHECK_NOT_DELAY_SLOT
1195        tcg_gen_xori_i32(cpu_delayed_cond, cpu_sr_t, 1);
1196        ctx->delayed_pc = ctx->base.pc_next + 4 + B7_0s * 2;
1197        ctx->envflags |= DELAY_SLOT_CONDITIONAL;
1198        return;
1199    case 0x8900:                /* bt label */
1200        CHECK_NOT_DELAY_SLOT
1201        gen_conditional_jump(ctx, ctx->base.pc_next + 4 + B7_0s * 2, true);
1202        return;
1203    case 0x8d00:                /* bt/s label */
1204        CHECK_NOT_DELAY_SLOT
1205        tcg_gen_mov_i32(cpu_delayed_cond, cpu_sr_t);
1206        ctx->delayed_pc = ctx->base.pc_next + 4 + B7_0s * 2;
1207        ctx->envflags |= DELAY_SLOT_CONDITIONAL;
1208        return;
1209    case 0x8800:                /* cmp/eq #imm,R0 */
1210        tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, REG(0), B7_0s);
1211        return;
1212    case 0xc400:                /* mov.b @(disp,GBR),R0 */
1213        {
1214            TCGv addr = tcg_temp_new();
1215            tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1216            tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_SB);
1217            tcg_temp_free(addr);
1218        }
1219        return;
1220    case 0xc500:                /* mov.w @(disp,GBR),R0 */
1221        {
1222            TCGv addr = tcg_temp_new();
1223            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1224            tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESW);
1225            tcg_temp_free(addr);
1226        }
1227        return;
1228    case 0xc600:                /* mov.l @(disp,GBR),R0 */
1229        {
1230            TCGv addr = tcg_temp_new();
1231            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1232            tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESL);
1233            tcg_temp_free(addr);
1234        }
1235        return;
1236    case 0xc000:                /* mov.b R0,@(disp,GBR) */
1237        {
1238            TCGv addr = tcg_temp_new();
1239            tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1240            tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_UB);
1241            tcg_temp_free(addr);
1242        }
1243        return;
1244    case 0xc100:                /* mov.w R0,@(disp,GBR) */
1245        {
1246            TCGv addr = tcg_temp_new();
1247            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1248            tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUW);
1249            tcg_temp_free(addr);
1250        }
1251        return;
1252    case 0xc200:                /* mov.l R0,@(disp,GBR) */
1253        {
1254            TCGv addr = tcg_temp_new();
1255            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1256            tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUL);
1257            tcg_temp_free(addr);
1258        }
1259        return;
1260    case 0x8000:                /* mov.b R0,@(disp,Rn) */
1261        {
1262            TCGv addr = tcg_temp_new();
1263            tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1264            tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_UB);
1265            tcg_temp_free(addr);
1266        }
1267        return;
1268    case 0x8100:                /* mov.w R0,@(disp,Rn) */
1269        {
1270            TCGv addr = tcg_temp_new();
1271            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1272            tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx,
1273                                MO_TEUW | UNALIGN(ctx));
1274            tcg_temp_free(addr);
1275        }
1276        return;
1277    case 0x8400:                /* mov.b @(disp,Rn),R0 */
1278        {
1279            TCGv addr = tcg_temp_new();
1280            tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1281            tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_SB);
1282            tcg_temp_free(addr);
1283        }
1284        return;
1285    case 0x8500:                /* mov.w @(disp,Rn),R0 */
1286        {
1287            TCGv addr = tcg_temp_new();
1288            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1289            tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx,
1290                                MO_TESW | UNALIGN(ctx));
1291            tcg_temp_free(addr);
1292        }
1293        return;
1294    case 0xc700:                /* mova @(disp,PC),R0 */
1295        tcg_gen_movi_i32(REG(0), ((ctx->base.pc_next & 0xfffffffc) +
1296                                  4 + B7_0 * 4) & ~3);
1297        return;
1298    case 0xcb00:                /* or #imm,R0 */
1299        tcg_gen_ori_i32(REG(0), REG(0), B7_0);
1300        return;
1301    case 0xcf00:                /* or.b #imm,@(R0,GBR) */
1302        {
1303            TCGv addr, val;
1304            addr = tcg_temp_new();
1305            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1306            val = tcg_temp_new();
1307            tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1308            tcg_gen_ori_i32(val, val, B7_0);
1309            tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1310            tcg_temp_free(val);
1311            tcg_temp_free(addr);
1312        }
1313        return;
1314    case 0xc300:                /* trapa #imm */
1315        {
1316            TCGv imm;
1317            CHECK_NOT_DELAY_SLOT
1318            gen_save_cpu_state(ctx, true);
1319            imm = tcg_const_i32(B7_0);
1320            gen_helper_trapa(cpu_env, imm);
1321            tcg_temp_free(imm);
1322            ctx->base.is_jmp = DISAS_NORETURN;
1323        }
1324        return;
1325    case 0xc800:                /* tst #imm,R0 */
1326        {
1327            TCGv val = tcg_temp_new();
1328            tcg_gen_andi_i32(val, REG(0), B7_0);
1329            tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1330            tcg_temp_free(val);
1331        }
1332        return;
1333    case 0xcc00:                /* tst.b #imm,@(R0,GBR) */
1334        {
1335            TCGv val = tcg_temp_new();
1336            tcg_gen_add_i32(val, REG(0), cpu_gbr);
1337            tcg_gen_qemu_ld_i32(val, val, ctx->memidx, MO_UB);
1338            tcg_gen_andi_i32(val, val, B7_0);
1339            tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1340            tcg_temp_free(val);
1341        }
1342        return;
1343    case 0xca00:                /* xor #imm,R0 */
1344        tcg_gen_xori_i32(REG(0), REG(0), B7_0);
1345        return;
1346    case 0xce00:                /* xor.b #imm,@(R0,GBR) */
1347        {
1348            TCGv addr, val;
1349            addr = tcg_temp_new();
1350            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1351            val = tcg_temp_new();
1352            tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1353            tcg_gen_xori_i32(val, val, B7_0);
1354            tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1355            tcg_temp_free(val);
1356            tcg_temp_free(addr);
1357        }
1358        return;
1359    }
1360
1361    switch (ctx->opcode & 0xf08f) {
1362    case 0x408e:                /* ldc Rm,Rn_BANK */
1363        CHECK_PRIVILEGED
1364        tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
1365        return;
1366    case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
1367        CHECK_PRIVILEGED
1368        tcg_gen_qemu_ld_i32(ALTREG(B6_4), REG(B11_8), ctx->memidx, MO_TESL);
1369        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1370        return;
1371    case 0x0082:                /* stc Rm_BANK,Rn */
1372        CHECK_PRIVILEGED
1373        tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
1374        return;
1375    case 0x4083:                /* stc.l Rm_BANK,@-Rn */
1376        CHECK_PRIVILEGED
1377        {
1378            TCGv addr = tcg_temp_new();
1379            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1380            tcg_gen_qemu_st_i32(ALTREG(B6_4), addr, ctx->memidx, MO_TEUL);
1381            tcg_gen_mov_i32(REG(B11_8), addr);
1382            tcg_temp_free(addr);
1383        }
1384        return;
1385    }
1386
1387    switch (ctx->opcode & 0xf0ff) {
1388    case 0x0023:                /* braf Rn */
1389        CHECK_NOT_DELAY_SLOT
1390        tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->base.pc_next + 4);
1391        ctx->envflags |= DELAY_SLOT;
1392        ctx->delayed_pc = (uint32_t) - 1;
1393        return;
1394    case 0x0003:                /* bsrf Rn */
1395        CHECK_NOT_DELAY_SLOT
1396        tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 4);
1397        tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);
1398        ctx->envflags |= DELAY_SLOT;
1399        ctx->delayed_pc = (uint32_t) - 1;
1400        return;
1401    case 0x4015:                /* cmp/pl Rn */
1402        tcg_gen_setcondi_i32(TCG_COND_GT, cpu_sr_t, REG(B11_8), 0);
1403        return;
1404    case 0x4011:                /* cmp/pz Rn */
1405        tcg_gen_setcondi_i32(TCG_COND_GE, cpu_sr_t, REG(B11_8), 0);
1406        return;
1407    case 0x4010:                /* dt Rn */
1408        tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);
1409        tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, REG(B11_8), 0);
1410        return;
1411    case 0x402b:                /* jmp @Rn */
1412        CHECK_NOT_DELAY_SLOT
1413        tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1414        ctx->envflags |= DELAY_SLOT;
1415        ctx->delayed_pc = (uint32_t) - 1;
1416        return;
1417    case 0x400b:                /* jsr @Rn */
1418        CHECK_NOT_DELAY_SLOT
1419        tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 4);
1420        tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1421        ctx->envflags |= DELAY_SLOT;
1422        ctx->delayed_pc = (uint32_t) - 1;
1423        return;
1424    case 0x400e:                /* ldc Rm,SR */
1425        CHECK_PRIVILEGED
1426        {
1427            TCGv val = tcg_temp_new();
1428            tcg_gen_andi_i32(val, REG(B11_8), 0x700083f3);
1429            gen_write_sr(val);
1430            tcg_temp_free(val);
1431            ctx->base.is_jmp = DISAS_STOP;
1432        }
1433        return;
1434    case 0x4007:                /* ldc.l @Rm+,SR */
1435        CHECK_PRIVILEGED
1436        {
1437            TCGv val = tcg_temp_new();
1438            tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_TESL);
1439            tcg_gen_andi_i32(val, val, 0x700083f3);
1440            gen_write_sr(val);
1441            tcg_temp_free(val);
1442            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1443            ctx->base.is_jmp = DISAS_STOP;
1444        }
1445        return;
1446    case 0x0002:                /* stc SR,Rn */
1447        CHECK_PRIVILEGED
1448        gen_read_sr(REG(B11_8));
1449        return;
1450    case 0x4003:                /* stc SR,@-Rn */
1451        CHECK_PRIVILEGED
1452        {
1453            TCGv addr = tcg_temp_new();
1454            TCGv val = tcg_temp_new();
1455            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1456            gen_read_sr(val);
1457            tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_TEUL);
1458            tcg_gen_mov_i32(REG(B11_8), addr);
1459            tcg_temp_free(val);
1460            tcg_temp_free(addr);
1461        }
1462        return;
1463#define LD(reg,ldnum,ldpnum,prechk)             \
1464  case ldnum:                                                   \
1465    prechk                                                      \
1466    tcg_gen_mov_i32 (cpu_##reg, REG(B11_8));                    \
1467    return;                                                     \
1468  case ldpnum:                                                  \
1469    prechk                                                      \
1470    tcg_gen_qemu_ld_i32(cpu_##reg, REG(B11_8), ctx->memidx, MO_TESL); \
1471    tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);                \
1472    return;
1473#define ST(reg,stnum,stpnum,prechk)             \
1474  case stnum:                                                   \
1475    prechk                                                      \
1476    tcg_gen_mov_i32 (REG(B11_8), cpu_##reg);                    \
1477    return;                                                     \
1478  case stpnum:                                                  \
1479    prechk                                                      \
1480    {                                                           \
1481        TCGv addr = tcg_temp_new();                             \
1482        tcg_gen_subi_i32(addr, REG(B11_8), 4);                  \
1483        tcg_gen_qemu_st_i32(cpu_##reg, addr, ctx->memidx, MO_TEUL); \
1484        tcg_gen_mov_i32(REG(B11_8), addr);                      \
1485        tcg_temp_free(addr);                                    \
1486    }                                                           \
1487    return;
1488#define LDST(reg,ldnum,ldpnum,stnum,stpnum,prechk)              \
1489        LD(reg,ldnum,ldpnum,prechk)                             \
1490        ST(reg,stnum,stpnum,prechk)
1491        LDST(gbr,  0x401e, 0x4017, 0x0012, 0x4013, {})
1492        LDST(vbr,  0x402e, 0x4027, 0x0022, 0x4023, CHECK_PRIVILEGED)
1493        LDST(ssr,  0x403e, 0x4037, 0x0032, 0x4033, CHECK_PRIVILEGED)
1494        LDST(spc,  0x404e, 0x4047, 0x0042, 0x4043, CHECK_PRIVILEGED)
1495        ST(sgr,  0x003a, 0x4032, CHECK_PRIVILEGED)
1496        LD(sgr,  0x403a, 0x4036, CHECK_PRIVILEGED CHECK_SH4A)
1497        LDST(dbr,  0x40fa, 0x40f6, 0x00fa, 0x40f2, CHECK_PRIVILEGED)
1498        LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002, {})
1499        LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012, {})
1500        LDST(pr,   0x402a, 0x4026, 0x002a, 0x4022, {})
1501        LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052, {CHECK_FPU_ENABLED})
1502    case 0x406a:                /* lds Rm,FPSCR */
1503        CHECK_FPU_ENABLED
1504        gen_helper_ld_fpscr(cpu_env, REG(B11_8));
1505        ctx->base.is_jmp = DISAS_STOP;
1506        return;
1507    case 0x4066:                /* lds.l @Rm+,FPSCR */
1508        CHECK_FPU_ENABLED
1509        {
1510            TCGv addr = tcg_temp_new();
1511            tcg_gen_qemu_ld_i32(addr, REG(B11_8), ctx->memidx, MO_TESL);
1512            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1513            gen_helper_ld_fpscr(cpu_env, addr);
1514            tcg_temp_free(addr);
1515            ctx->base.is_jmp = DISAS_STOP;
1516        }
1517        return;
1518    case 0x006a:                /* sts FPSCR,Rn */
1519        CHECK_FPU_ENABLED
1520        tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);
1521        return;
1522    case 0x4062:                /* sts FPSCR,@-Rn */
1523        CHECK_FPU_ENABLED
1524        {
1525            TCGv addr, val;
1526            val = tcg_temp_new();
1527            tcg_gen_andi_i32(val, cpu_fpscr, 0x003fffff);
1528            addr = tcg_temp_new();
1529            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1530            tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_TEUL);
1531            tcg_gen_mov_i32(REG(B11_8), addr);
1532            tcg_temp_free(addr);
1533            tcg_temp_free(val);
1534        }
1535        return;
1536    case 0x00c3:                /* movca.l R0,@Rm */
1537        {
1538            TCGv val = tcg_temp_new();
1539            tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_TEUL);
1540            gen_helper_movcal(cpu_env, REG(B11_8), val);
1541            tcg_gen_qemu_st_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1542            tcg_temp_free(val);
1543        }
1544        ctx->has_movcal = 1;
1545        return;
1546    case 0x40a9:                /* movua.l @Rm,R0 */
1547        CHECK_SH4A
1548        /* Load non-boundary-aligned data */
1549        tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx,
1550                            MO_TEUL | MO_UNALN);
1551        return;
1552    case 0x40e9:                /* movua.l @Rm+,R0 */
1553        CHECK_SH4A
1554        /* Load non-boundary-aligned data */
1555        tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx,
1556                            MO_TEUL | MO_UNALN);
1557        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1558        return;
1559    case 0x0029:                /* movt Rn */
1560        tcg_gen_mov_i32(REG(B11_8), cpu_sr_t);
1561        return;
1562    case 0x0073:
1563        /* MOVCO.L
1564         *     LDST -> T
1565         *     If (T == 1) R0 -> (Rn)
1566         *     0 -> LDST
1567         *
1568         * The above description doesn't work in a parallel context.
1569         * Since we currently support no smp boards, this implies user-mode.
1570         * But we can still support the official mechanism while user-mode
1571         * is single-threaded.  */
1572        CHECK_SH4A
1573        {
1574            TCGLabel *fail = gen_new_label();
1575            TCGLabel *done = gen_new_label();
1576
1577            if ((tb_cflags(ctx->base.tb) & CF_PARALLEL)) {
1578                TCGv tmp;
1579
1580                tcg_gen_brcond_i32(TCG_COND_NE, REG(B11_8),
1581                                   cpu_lock_addr, fail);
1582                tmp = tcg_temp_new();
1583                tcg_gen_atomic_cmpxchg_i32(tmp, REG(B11_8), cpu_lock_value,
1584                                           REG(0), ctx->memidx, MO_TEUL);
1585                tcg_gen_setcond_i32(TCG_COND_EQ, cpu_sr_t, tmp, cpu_lock_value);
1586                tcg_temp_free(tmp);
1587            } else {
1588                tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_lock_addr, -1, fail);
1589                tcg_gen_qemu_st_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1590                tcg_gen_movi_i32(cpu_sr_t, 1);
1591            }
1592            tcg_gen_br(done);
1593
1594            gen_set_label(fail);
1595            tcg_gen_movi_i32(cpu_sr_t, 0);
1596
1597            gen_set_label(done);
1598            tcg_gen_movi_i32(cpu_lock_addr, -1);
1599        }
1600        return;
1601    case 0x0063:
1602        /* MOVLI.L @Rm,R0
1603         *     1 -> LDST
1604         *     (Rm) -> R0
1605         *     When interrupt/exception
1606         *     occurred 0 -> LDST
1607         *
1608         * In a parallel context, we must also save the loaded value
1609         * for use with the cmpxchg that we'll use with movco.l.  */
1610        CHECK_SH4A
1611        if ((tb_cflags(ctx->base.tb) & CF_PARALLEL)) {
1612            TCGv tmp = tcg_temp_new();
1613            tcg_gen_mov_i32(tmp, REG(B11_8));
1614            tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TESL);
1615            tcg_gen_mov_i32(cpu_lock_value, REG(0));
1616            tcg_gen_mov_i32(cpu_lock_addr, tmp);
1617            tcg_temp_free(tmp);
1618        } else {
1619            tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TESL);
1620            tcg_gen_movi_i32(cpu_lock_addr, 0);
1621        }
1622        return;
1623    case 0x0093:                /* ocbi @Rn */
1624        {
1625            gen_helper_ocbi(cpu_env, REG(B11_8));
1626        }
1627        return;
1628    case 0x00a3:                /* ocbp @Rn */
1629    case 0x00b3:                /* ocbwb @Rn */
1630        /* These instructions are supposed to do nothing in case of
1631           a cache miss. Given that we only partially emulate caches
1632           it is safe to simply ignore them. */
1633        return;
1634    case 0x0083:                /* pref @Rn */
1635        return;
1636    case 0x00d3:                /* prefi @Rn */
1637        CHECK_SH4A
1638        return;
1639    case 0x00e3:                /* icbi @Rn */
1640        CHECK_SH4A
1641        return;
1642    case 0x00ab:                /* synco */
1643        CHECK_SH4A
1644        tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
1645        return;
1646    case 0x4024:                /* rotcl Rn */
1647        {
1648            TCGv tmp = tcg_temp_new();
1649            tcg_gen_mov_i32(tmp, cpu_sr_t);
1650            tcg_gen_shri_i32(cpu_sr_t, REG(B11_8), 31);
1651            tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1652            tcg_gen_or_i32(REG(B11_8), REG(B11_8), tmp);
1653            tcg_temp_free(tmp);
1654        }
1655        return;
1656    case 0x4025:                /* rotcr Rn */
1657        {
1658            TCGv tmp = tcg_temp_new();
1659            tcg_gen_shli_i32(tmp, cpu_sr_t, 31);
1660            tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1661            tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1662            tcg_gen_or_i32(REG(B11_8), REG(B11_8), tmp);
1663            tcg_temp_free(tmp);
1664        }
1665        return;
1666    case 0x4004:                /* rotl Rn */
1667        tcg_gen_rotli_i32(REG(B11_8), REG(B11_8), 1);
1668        tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 0);
1669        return;
1670    case 0x4005:                /* rotr Rn */
1671        tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 0);
1672        tcg_gen_rotri_i32(REG(B11_8), REG(B11_8), 1);
1673        return;
1674    case 0x4000:                /* shll Rn */
1675    case 0x4020:                /* shal Rn */
1676        tcg_gen_shri_i32(cpu_sr_t, REG(B11_8), 31);
1677        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1678        return;
1679    case 0x4021:                /* shar Rn */
1680        tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1681        tcg_gen_sari_i32(REG(B11_8), REG(B11_8), 1);
1682        return;
1683    case 0x4001:                /* shlr Rn */
1684        tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1685        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1686        return;
1687    case 0x4008:                /* shll2 Rn */
1688        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 2);
1689        return;
1690    case 0x4018:                /* shll8 Rn */
1691        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 8);
1692        return;
1693    case 0x4028:                /* shll16 Rn */
1694        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 16);
1695        return;
1696    case 0x4009:                /* shlr2 Rn */
1697        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 2);
1698        return;
1699    case 0x4019:                /* shlr8 Rn */
1700        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 8);
1701        return;
1702    case 0x4029:                /* shlr16 Rn */
1703        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16);
1704        return;
1705    case 0x401b:                /* tas.b @Rn */
1706        {
1707            TCGv val = tcg_const_i32(0x80);
1708            tcg_gen_atomic_fetch_or_i32(val, REG(B11_8), val,
1709                                        ctx->memidx, MO_UB);
1710            tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1711            tcg_temp_free(val);
1712        }
1713        return;
1714    case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1715        CHECK_FPU_ENABLED
1716        tcg_gen_mov_i32(FREG(B11_8), cpu_fpul);
1717        return;
1718    case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1719        CHECK_FPU_ENABLED
1720        tcg_gen_mov_i32(cpu_fpul, FREG(B11_8));
1721        return;
1722    case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1723        CHECK_FPU_ENABLED
1724        if (ctx->tbflags & FPSCR_PR) {
1725            TCGv_i64 fp;
1726            if (ctx->opcode & 0x0100) {
1727                goto do_illegal;
1728            }
1729            fp = tcg_temp_new_i64();
1730            gen_helper_float_DT(fp, cpu_env, cpu_fpul);
1731            gen_store_fpr64(ctx, fp, B11_8);
1732            tcg_temp_free_i64(fp);
1733        }
1734        else {
1735            gen_helper_float_FT(FREG(B11_8), cpu_env, cpu_fpul);
1736        }
1737        return;
1738    case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1739        CHECK_FPU_ENABLED
1740        if (ctx->tbflags & FPSCR_PR) {
1741            TCGv_i64 fp;
1742            if (ctx->opcode & 0x0100) {
1743                goto do_illegal;
1744            }
1745            fp = tcg_temp_new_i64();
1746            gen_load_fpr64(ctx, fp, B11_8);
1747            gen_helper_ftrc_DT(cpu_fpul, cpu_env, fp);
1748            tcg_temp_free_i64(fp);
1749        }
1750        else {
1751            gen_helper_ftrc_FT(cpu_fpul, cpu_env, FREG(B11_8));
1752        }
1753        return;
1754    case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1755        CHECK_FPU_ENABLED
1756        tcg_gen_xori_i32(FREG(B11_8), FREG(B11_8), 0x80000000);
1757        return;
1758    case 0xf05d: /* fabs FRn/DRn - FPCSR: Nothing */
1759        CHECK_FPU_ENABLED
1760        tcg_gen_andi_i32(FREG(B11_8), FREG(B11_8), 0x7fffffff);
1761        return;
1762    case 0xf06d: /* fsqrt FRn */
1763        CHECK_FPU_ENABLED
1764        if (ctx->tbflags & FPSCR_PR) {
1765            if (ctx->opcode & 0x0100) {
1766                goto do_illegal;
1767            }
1768            TCGv_i64 fp = tcg_temp_new_i64();
1769            gen_load_fpr64(ctx, fp, B11_8);
1770            gen_helper_fsqrt_DT(fp, cpu_env, fp);
1771            gen_store_fpr64(ctx, fp, B11_8);
1772            tcg_temp_free_i64(fp);
1773        } else {
1774            gen_helper_fsqrt_FT(FREG(B11_8), cpu_env, FREG(B11_8));
1775        }
1776        return;
1777    case 0xf07d: /* fsrra FRn */
1778        CHECK_FPU_ENABLED
1779        CHECK_FPSCR_PR_0
1780        gen_helper_fsrra_FT(FREG(B11_8), cpu_env, FREG(B11_8));
1781        break;
1782    case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1783        CHECK_FPU_ENABLED
1784        CHECK_FPSCR_PR_0
1785        tcg_gen_movi_i32(FREG(B11_8), 0);
1786        return;
1787    case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1788        CHECK_FPU_ENABLED
1789        CHECK_FPSCR_PR_0
1790        tcg_gen_movi_i32(FREG(B11_8), 0x3f800000);
1791        return;
1792    case 0xf0ad: /* fcnvsd FPUL,DRn */
1793        CHECK_FPU_ENABLED
1794        {
1795            TCGv_i64 fp = tcg_temp_new_i64();
1796            gen_helper_fcnvsd_FT_DT(fp, cpu_env, cpu_fpul);
1797            gen_store_fpr64(ctx, fp, B11_8);
1798            tcg_temp_free_i64(fp);
1799        }
1800        return;
1801    case 0xf0bd: /* fcnvds DRn,FPUL */
1802        CHECK_FPU_ENABLED
1803        {
1804            TCGv_i64 fp = tcg_temp_new_i64();
1805            gen_load_fpr64(ctx, fp, B11_8);
1806            gen_helper_fcnvds_DT_FT(cpu_fpul, cpu_env, fp);
1807            tcg_temp_free_i64(fp);
1808        }
1809        return;
1810    case 0xf0ed: /* fipr FVm,FVn */
1811        CHECK_FPU_ENABLED
1812        CHECK_FPSCR_PR_1
1813        {
1814            TCGv m = tcg_const_i32((ctx->opcode >> 8) & 3);
1815            TCGv n = tcg_const_i32((ctx->opcode >> 10) & 3);
1816            gen_helper_fipr(cpu_env, m, n);
1817            tcg_temp_free(m);
1818            tcg_temp_free(n);
1819            return;
1820        }
1821        break;
1822    case 0xf0fd: /* ftrv XMTRX,FVn */
1823        CHECK_FPU_ENABLED
1824        CHECK_FPSCR_PR_1
1825        {
1826            if ((ctx->opcode & 0x0300) != 0x0100) {
1827                goto do_illegal;
1828            }
1829            TCGv n = tcg_const_i32((ctx->opcode >> 10) & 3);
1830            gen_helper_ftrv(cpu_env, n);
1831            tcg_temp_free(n);
1832            return;
1833        }
1834        break;
1835    }
1836#if 0
1837    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1838            ctx->opcode, ctx->base.pc_next);
1839    fflush(stderr);
1840#endif
1841 do_illegal:
1842    if (ctx->envflags & DELAY_SLOT_MASK) {
1843 do_illegal_slot:
1844        gen_save_cpu_state(ctx, true);
1845        gen_helper_raise_slot_illegal_instruction(cpu_env);
1846    } else {
1847        gen_save_cpu_state(ctx, true);
1848        gen_helper_raise_illegal_instruction(cpu_env);
1849    }
1850    ctx->base.is_jmp = DISAS_NORETURN;
1851    return;
1852
1853 do_fpu_disabled:
1854    gen_save_cpu_state(ctx, true);
1855    if (ctx->envflags & DELAY_SLOT_MASK) {
1856        gen_helper_raise_slot_fpu_disable(cpu_env);
1857    } else {
1858        gen_helper_raise_fpu_disable(cpu_env);
1859    }
1860    ctx->base.is_jmp = DISAS_NORETURN;
1861    return;
1862}
1863
1864static void decode_opc(DisasContext * ctx)
1865{
1866    uint32_t old_flags = ctx->envflags;
1867
1868    _decode_opc(ctx);
1869
1870    if (old_flags & DELAY_SLOT_MASK) {
1871        /* go out of the delay slot */
1872        ctx->envflags &= ~DELAY_SLOT_MASK;
1873
1874        /* When in an exclusive region, we must continue to the end
1875           for conditional branches.  */
1876        if (ctx->tbflags & GUSA_EXCLUSIVE
1877            && old_flags & DELAY_SLOT_CONDITIONAL) {
1878            gen_delayed_conditional_jump(ctx);
1879            return;
1880        }
1881        /* Otherwise this is probably an invalid gUSA region.
1882           Drop the GUSA bits so the next TB doesn't see them.  */
1883        ctx->envflags &= ~GUSA_MASK;
1884
1885        tcg_gen_movi_i32(cpu_flags, ctx->envflags);
1886        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1887            gen_delayed_conditional_jump(ctx);
1888        } else {
1889            gen_jump(ctx);
1890        }
1891    }
1892}
1893
1894#ifdef CONFIG_USER_ONLY
1895/* For uniprocessors, SH4 uses optimistic restartable atomic sequences.
1896   Upon an interrupt, a real kernel would simply notice magic values in
1897   the registers and reset the PC to the start of the sequence.
1898
1899   For QEMU, we cannot do this in quite the same way.  Instead, we notice
1900   the normal start of such a sequence (mov #-x,r15).  While we can handle
1901   any sequence via cpu_exec_step_atomic, we can recognize the "normal"
1902   sequences and transform them into atomic operations as seen by the host.
1903*/
1904static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
1905{
1906    uint16_t insns[5];
1907    int ld_adr, ld_dst, ld_mop;
1908    int op_dst, op_src, op_opc;
1909    int mv_src, mt_dst, st_src, st_mop;
1910    TCGv op_arg;
1911    uint32_t pc = ctx->base.pc_next;
1912    uint32_t pc_end = ctx->base.tb->cs_base;
1913    int max_insns = (pc_end - pc) / 2;
1914    int i;
1915
1916    /* The state machine below will consume only a few insns.
1917       If there are more than that in a region, fail now.  */
1918    if (max_insns > ARRAY_SIZE(insns)) {
1919        goto fail;
1920    }
1921
1922    /* Read all of the insns for the region.  */
1923    for (i = 0; i < max_insns; ++i) {
1924        insns[i] = translator_lduw(env, &ctx->base, pc + i * 2);
1925    }
1926
1927    ld_adr = ld_dst = ld_mop = -1;
1928    mv_src = -1;
1929    op_dst = op_src = op_opc = -1;
1930    mt_dst = -1;
1931    st_src = st_mop = -1;
1932    op_arg = NULL;
1933    i = 0;
1934
1935#define NEXT_INSN \
1936    do { if (i >= max_insns) goto fail; ctx->opcode = insns[i++]; } while (0)
1937
1938    /*
1939     * Expect a load to begin the region.
1940     */
1941    NEXT_INSN;
1942    switch (ctx->opcode & 0xf00f) {
1943    case 0x6000: /* mov.b @Rm,Rn */
1944        ld_mop = MO_SB;
1945        break;
1946    case 0x6001: /* mov.w @Rm,Rn */
1947        ld_mop = MO_TESW;
1948        break;
1949    case 0x6002: /* mov.l @Rm,Rn */
1950        ld_mop = MO_TESL;
1951        break;
1952    default:
1953        goto fail;
1954    }
1955    ld_adr = B7_4;
1956    ld_dst = B11_8;
1957    if (ld_adr == ld_dst) {
1958        goto fail;
1959    }
1960    /* Unless we see a mov, any two-operand operation must use ld_dst.  */
1961    op_dst = ld_dst;
1962
1963    /*
1964     * Expect an optional register move.
1965     */
1966    NEXT_INSN;
1967    switch (ctx->opcode & 0xf00f) {
1968    case 0x6003: /* mov Rm,Rn */
1969        /*
1970         * Here we want to recognize ld_dst being saved for later consumption,
1971         * or for another input register being copied so that ld_dst need not
1972         * be clobbered during the operation.
1973         */
1974        op_dst = B11_8;
1975        mv_src = B7_4;
1976        if (op_dst == ld_dst) {
1977            /* Overwriting the load output.  */
1978            goto fail;
1979        }
1980        if (mv_src != ld_dst) {
1981            /* Copying a new input; constrain op_src to match the load.  */
1982            op_src = ld_dst;
1983        }
1984        break;
1985
1986    default:
1987        /* Put back and re-examine as operation.  */
1988        --i;
1989    }
1990
1991    /*
1992     * Expect the operation.
1993     */
1994    NEXT_INSN;
1995    switch (ctx->opcode & 0xf00f) {
1996    case 0x300c: /* add Rm,Rn */
1997        op_opc = INDEX_op_add_i32;
1998        goto do_reg_op;
1999    case 0x2009: /* and Rm,Rn */
2000        op_opc = INDEX_op_and_i32;
2001        goto do_reg_op;
2002    case 0x200a: /* xor Rm,Rn */
2003        op_opc = INDEX_op_xor_i32;
2004        goto do_reg_op;
2005    case 0x200b: /* or Rm,Rn */
2006        op_opc = INDEX_op_or_i32;
2007    do_reg_op:
2008        /* The operation register should be as expected, and the
2009           other input cannot depend on the load.  */
2010        if (op_dst != B11_8) {
2011            goto fail;
2012        }
2013        if (op_src < 0) {
2014            /* Unconstrainted input.  */
2015            op_src = B7_4;
2016        } else if (op_src == B7_4) {
2017            /* Constrained input matched load.  All operations are
2018               commutative; "swap" them by "moving" the load output
2019               to the (implicit) first argument and the move source
2020               to the (explicit) second argument.  */
2021            op_src = mv_src;
2022        } else {
2023            goto fail;
2024        }
2025        op_arg = REG(op_src);
2026        break;
2027
2028    case 0x6007: /* not Rm,Rn */
2029        if (ld_dst != B7_4 || mv_src >= 0) {
2030            goto fail;
2031        }
2032        op_dst = B11_8;
2033        op_opc = INDEX_op_xor_i32;
2034        op_arg = tcg_const_i32(-1);
2035        break;
2036
2037    case 0x7000 ... 0x700f: /* add #imm,Rn */
2038        if (op_dst != B11_8 || mv_src >= 0) {
2039            goto fail;
2040        }
2041        op_opc = INDEX_op_add_i32;
2042        op_arg = tcg_const_i32(B7_0s);
2043        break;
2044
2045    case 0x3000: /* cmp/eq Rm,Rn */
2046        /* Looking for the middle of a compare-and-swap sequence,
2047           beginning with the compare.  Operands can be either order,
2048           but with only one overlapping the load.  */
2049        if ((ld_dst == B11_8) + (ld_dst == B7_4) != 1 || mv_src >= 0) {
2050            goto fail;
2051        }
2052        op_opc = INDEX_op_setcond_i32;  /* placeholder */
2053        op_src = (ld_dst == B11_8 ? B7_4 : B11_8);
2054        op_arg = REG(op_src);
2055
2056        NEXT_INSN;
2057        switch (ctx->opcode & 0xff00) {
2058        case 0x8b00: /* bf label */
2059        case 0x8f00: /* bf/s label */
2060            if (pc + (i + 1 + B7_0s) * 2 != pc_end) {
2061                goto fail;
2062            }
2063            if ((ctx->opcode & 0xff00) == 0x8b00) { /* bf label */
2064                break;
2065            }
2066            /* We're looking to unconditionally modify Rn with the
2067               result of the comparison, within the delay slot of
2068               the branch.  This is used by older gcc.  */
2069            NEXT_INSN;
2070            if ((ctx->opcode & 0xf0ff) == 0x0029) { /* movt Rn */
2071                mt_dst = B11_8;
2072            } else {
2073                goto fail;
2074            }
2075            break;
2076
2077        default:
2078            goto fail;
2079        }
2080        break;
2081
2082    case 0x2008: /* tst Rm,Rn */
2083        /* Looking for a compare-and-swap against zero.  */
2084        if (ld_dst != B11_8 || ld_dst != B7_4 || mv_src >= 0) {
2085            goto fail;
2086        }
2087        op_opc = INDEX_op_setcond_i32;
2088        op_arg = tcg_const_i32(0);
2089
2090        NEXT_INSN;
2091        if ((ctx->opcode & 0xff00) != 0x8900 /* bt label */
2092            || pc + (i + 1 + B7_0s) * 2 != pc_end) {
2093            goto fail;
2094        }
2095        break;
2096
2097    default:
2098        /* Put back and re-examine as store.  */
2099        --i;
2100    }
2101
2102    /*
2103     * Expect the store.
2104     */
2105    /* The store must be the last insn.  */
2106    if (i != max_insns - 1) {
2107        goto fail;
2108    }
2109    NEXT_INSN;
2110    switch (ctx->opcode & 0xf00f) {
2111    case 0x2000: /* mov.b Rm,@Rn */
2112        st_mop = MO_UB;
2113        break;
2114    case 0x2001: /* mov.w Rm,@Rn */
2115        st_mop = MO_UW;
2116        break;
2117    case 0x2002: /* mov.l Rm,@Rn */
2118        st_mop = MO_UL;
2119        break;
2120    default:
2121        goto fail;
2122    }
2123    /* The store must match the load.  */
2124    if (ld_adr != B11_8 || st_mop != (ld_mop & MO_SIZE)) {
2125        goto fail;
2126    }
2127    st_src = B7_4;
2128
2129#undef NEXT_INSN
2130
2131    /*
2132     * Emit the operation.
2133     */
2134    switch (op_opc) {
2135    case -1:
2136        /* No operation found.  Look for exchange pattern.  */
2137        if (st_src == ld_dst || mv_src >= 0) {
2138            goto fail;
2139        }
2140        tcg_gen_atomic_xchg_i32(REG(ld_dst), REG(ld_adr), REG(st_src),
2141                                ctx->memidx, ld_mop);
2142        break;
2143
2144    case INDEX_op_add_i32:
2145        if (op_dst != st_src) {
2146            goto fail;
2147        }
2148        if (op_dst == ld_dst && st_mop == MO_UL) {
2149            tcg_gen_atomic_add_fetch_i32(REG(ld_dst), REG(ld_adr),
2150                                         op_arg, ctx->memidx, ld_mop);
2151        } else {
2152            tcg_gen_atomic_fetch_add_i32(REG(ld_dst), REG(ld_adr),
2153                                         op_arg, ctx->memidx, ld_mop);
2154            if (op_dst != ld_dst) {
2155                /* Note that mop sizes < 4 cannot use add_fetch
2156                   because it won't carry into the higher bits.  */
2157                tcg_gen_add_i32(REG(op_dst), REG(ld_dst), op_arg);
2158            }
2159        }
2160        break;
2161
2162    case INDEX_op_and_i32:
2163        if (op_dst != st_src) {
2164            goto fail;
2165        }
2166        if (op_dst == ld_dst) {
2167            tcg_gen_atomic_and_fetch_i32(REG(ld_dst), REG(ld_adr),
2168                                         op_arg, ctx->memidx, ld_mop);
2169        } else {
2170            tcg_gen_atomic_fetch_and_i32(REG(ld_dst), REG(ld_adr),
2171                                         op_arg, ctx->memidx, ld_mop);
2172            tcg_gen_and_i32(REG(op_dst), REG(ld_dst), op_arg);
2173        }
2174        break;
2175
2176    case INDEX_op_or_i32:
2177        if (op_dst != st_src) {
2178            goto fail;
2179        }
2180        if (op_dst == ld_dst) {
2181            tcg_gen_atomic_or_fetch_i32(REG(ld_dst), REG(ld_adr),
2182                                        op_arg, ctx->memidx, ld_mop);
2183        } else {
2184            tcg_gen_atomic_fetch_or_i32(REG(ld_dst), REG(ld_adr),
2185                                        op_arg, ctx->memidx, ld_mop);
2186            tcg_gen_or_i32(REG(op_dst), REG(ld_dst), op_arg);
2187        }
2188        break;
2189
2190    case INDEX_op_xor_i32:
2191        if (op_dst != st_src) {
2192            goto fail;
2193        }
2194        if (op_dst == ld_dst) {
2195            tcg_gen_atomic_xor_fetch_i32(REG(ld_dst), REG(ld_adr),
2196                                         op_arg, ctx->memidx, ld_mop);
2197        } else {
2198            tcg_gen_atomic_fetch_xor_i32(REG(ld_dst), REG(ld_adr),
2199                                         op_arg, ctx->memidx, ld_mop);
2200            tcg_gen_xor_i32(REG(op_dst), REG(ld_dst), op_arg);
2201        }
2202        break;
2203
2204    case INDEX_op_setcond_i32:
2205        if (st_src == ld_dst) {
2206            goto fail;
2207        }
2208        tcg_gen_atomic_cmpxchg_i32(REG(ld_dst), REG(ld_adr), op_arg,
2209                                   REG(st_src), ctx->memidx, ld_mop);
2210        tcg_gen_setcond_i32(TCG_COND_EQ, cpu_sr_t, REG(ld_dst), op_arg);
2211        if (mt_dst >= 0) {
2212            tcg_gen_mov_i32(REG(mt_dst), cpu_sr_t);
2213        }
2214        break;
2215
2216    default:
2217        g_assert_not_reached();
2218    }
2219
2220    /* If op_src is not a valid register, then op_arg was a constant.  */
2221    if (op_src < 0 && op_arg) {
2222        tcg_temp_free_i32(op_arg);
2223    }
2224
2225    /* The entire region has been translated.  */
2226    ctx->envflags &= ~GUSA_MASK;
2227    ctx->base.pc_next = pc_end;
2228    ctx->base.num_insns += max_insns - 1;
2229    return;
2230
2231 fail:
2232    qemu_log_mask(LOG_UNIMP, "Unrecognized gUSA sequence %08x-%08x\n",
2233                  pc, pc_end);
2234
2235    /* Restart with the EXCLUSIVE bit set, within a TB run via
2236       cpu_exec_step_atomic holding the exclusive lock.  */
2237    ctx->envflags |= GUSA_EXCLUSIVE;
2238    gen_save_cpu_state(ctx, false);
2239    gen_helper_exclusive(cpu_env);
2240    ctx->base.is_jmp = DISAS_NORETURN;
2241
2242    /* We're not executing an instruction, but we must report one for the
2243       purposes of accounting within the TB.  We might as well report the
2244       entire region consumed via ctx->base.pc_next so that it's immediately
2245       available in the disassembly dump.  */
2246    ctx->base.pc_next = pc_end;
2247    ctx->base.num_insns += max_insns - 1;
2248}
2249#endif
2250
2251static void sh4_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
2252{
2253    DisasContext *ctx = container_of(dcbase, DisasContext, base);
2254    CPUSH4State *env = cs->env_ptr;
2255    uint32_t tbflags;
2256    int bound;
2257
2258    ctx->tbflags = tbflags = ctx->base.tb->flags;
2259    ctx->envflags = tbflags & TB_FLAG_ENVFLAGS_MASK;
2260    ctx->memidx = (tbflags & (1u << SR_MD)) == 0 ? 1 : 0;
2261    /* We don't know if the delayed pc came from a dynamic or static branch,
2262       so assume it is a dynamic branch.  */
2263    ctx->delayed_pc = -1; /* use delayed pc from env pointer */
2264    ctx->features = env->features;
2265    ctx->has_movcal = (tbflags & TB_FLAG_PENDING_MOVCA);
2266    ctx->gbank = ((tbflags & (1 << SR_MD)) &&
2267                  (tbflags & (1 << SR_RB))) * 0x10;
2268    ctx->fbank = tbflags & FPSCR_FR ? 0x10 : 0;
2269
2270    if (tbflags & GUSA_MASK) {
2271        uint32_t pc = ctx->base.pc_next;
2272        uint32_t pc_end = ctx->base.tb->cs_base;
2273        int backup = sextract32(ctx->tbflags, GUSA_SHIFT, 8);
2274        int max_insns = (pc_end - pc) / 2;
2275
2276        if (pc != pc_end + backup || max_insns < 2) {
2277            /* This is a malformed gUSA region.  Don't do anything special,
2278               since the interpreter is likely to get confused.  */
2279            ctx->envflags &= ~GUSA_MASK;
2280        } else if (tbflags & GUSA_EXCLUSIVE) {
2281            /* Regardless of single-stepping or the end of the page,
2282               we must complete execution of the gUSA region while
2283               holding the exclusive lock.  */
2284            ctx->base.max_insns = max_insns;
2285            return;
2286        }
2287    }
2288
2289    /* Since the ISA is fixed-width, we can bound by the number
2290       of instructions remaining on the page.  */
2291    bound = -(ctx->base.pc_next | TARGET_PAGE_MASK) / 2;
2292    ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
2293}
2294
2295static void sh4_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
2296{
2297}
2298
2299static void sh4_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
2300{
2301    DisasContext *ctx = container_of(dcbase, DisasContext, base);
2302
2303    tcg_gen_insn_start(ctx->base.pc_next, ctx->envflags);
2304}
2305
2306static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
2307{
2308    CPUSH4State *env = cs->env_ptr;
2309    DisasContext *ctx = container_of(dcbase, DisasContext, base);
2310
2311#ifdef CONFIG_USER_ONLY
2312    if (unlikely(ctx->envflags & GUSA_MASK)
2313        && !(ctx->envflags & GUSA_EXCLUSIVE)) {
2314        /* We're in an gUSA region, and we have not already fallen
2315           back on using an exclusive region.  Attempt to parse the
2316           region into a single supported atomic operation.  Failure
2317           is handled within the parser by raising an exception to
2318           retry using an exclusive region.  */
2319        decode_gusa(ctx, env);
2320        return;
2321    }
2322#endif
2323
2324    ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
2325    decode_opc(ctx);
2326    ctx->base.pc_next += 2;
2327}
2328
2329static void sh4_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
2330{
2331    DisasContext *ctx = container_of(dcbase, DisasContext, base);
2332
2333    if (ctx->tbflags & GUSA_EXCLUSIVE) {
2334        /* Ending the region of exclusivity.  Clear the bits.  */
2335        ctx->envflags &= ~GUSA_MASK;
2336    }
2337
2338    switch (ctx->base.is_jmp) {
2339    case DISAS_STOP:
2340        gen_save_cpu_state(ctx, true);
2341        tcg_gen_exit_tb(NULL, 0);
2342        break;
2343    case DISAS_NEXT:
2344    case DISAS_TOO_MANY:
2345        gen_save_cpu_state(ctx, false);
2346        gen_goto_tb(ctx, 0, ctx->base.pc_next);
2347        break;
2348    case DISAS_NORETURN:
2349        break;
2350    default:
2351        g_assert_not_reached();
2352    }
2353}
2354
2355static void sh4_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
2356{
2357    qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
2358    log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
2359}
2360
2361static const TranslatorOps sh4_tr_ops = {
2362    .init_disas_context = sh4_tr_init_disas_context,
2363    .tb_start           = sh4_tr_tb_start,
2364    .insn_start         = sh4_tr_insn_start,
2365    .translate_insn     = sh4_tr_translate_insn,
2366    .tb_stop            = sh4_tr_tb_stop,
2367    .disas_log          = sh4_tr_disas_log,
2368};
2369
2370void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
2371{
2372    DisasContext ctx;
2373
2374    translator_loop(&sh4_tr_ops, &ctx.base, cs, tb, max_insns);
2375}
2376
2377void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb,
2378                          target_ulong *data)
2379{
2380    env->pc = data[0];
2381    env->flags = data[1];
2382    /* Theoretically delayed_pc should also be restored. In practice the
2383       branch instruction is re-executed after exception, so the delayed
2384       branch target will be recomputed. */
2385}
2386