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