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