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 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 "cpu.h"
  23#include "disas/disas.h"
  24#include "tcg-op.h"
  25#include "exec/cpu_ldst.h"
  26
  27#include "exec/helper-proto.h"
  28#include "exec/helper-gen.h"
  29
  30#include "trace-tcg.h"
  31
  32
  33typedef struct DisasContext {
  34    struct TranslationBlock *tb;
  35    target_ulong pc;
  36    uint16_t opcode;
  37    uint32_t flags;
  38    int bstate;
  39    int memidx;
  40    uint32_t delayed_pc;
  41    int singlestep_enabled;
  42    uint32_t features;
  43    int has_movcal;
  44} DisasContext;
  45
  46#if defined(CONFIG_USER_ONLY)
  47#define IS_USER(ctx) 1
  48#else
  49#define IS_USER(ctx) (!(ctx->flags & (1u << SR_MD)))
  50#endif
  51
  52enum {
  53    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
  54                      * exception condition
  55                      */
  56    BS_STOP     = 1, /* We want to stop translation for any reason */
  57    BS_BRANCH   = 2, /* We reached a branch condition     */
  58    BS_EXCP     = 3, /* We reached an exception condition */
  59};
  60
  61/* global register indexes */
  62static TCGv_ptr cpu_env;
  63static TCGv cpu_gregs[24];
  64static TCGv cpu_sr, cpu_sr_m, cpu_sr_q, cpu_sr_t;
  65static TCGv cpu_pc, cpu_ssr, cpu_spc, cpu_gbr;
  66static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
  67static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_ldst;
  68static TCGv cpu_fregs[32];
  69
  70/* internal register indexes */
  71static TCGv cpu_flags, cpu_delayed_pc;
  72
  73#include "exec/gen-icount.h"
  74
  75void sh4_translate_init(void)
  76{
  77    int i;
  78    static int done_init = 0;
  79    static const char * const gregnames[24] = {
  80        "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
  81        "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
  82        "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
  83        "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
  84        "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
  85    };
  86    static const char * const fregnames[32] = {
  87         "FPR0_BANK0",  "FPR1_BANK0",  "FPR2_BANK0",  "FPR3_BANK0",
  88         "FPR4_BANK0",  "FPR5_BANK0",  "FPR6_BANK0",  "FPR7_BANK0",
  89         "FPR8_BANK0",  "FPR9_BANK0", "FPR10_BANK0", "FPR11_BANK0",
  90        "FPR12_BANK0", "FPR13_BANK0", "FPR14_BANK0", "FPR15_BANK0",
  91         "FPR0_BANK1",  "FPR1_BANK1",  "FPR2_BANK1",  "FPR3_BANK1",
  92         "FPR4_BANK1",  "FPR5_BANK1",  "FPR6_BANK1",  "FPR7_BANK1",
  93         "FPR8_BANK1",  "FPR9_BANK1", "FPR10_BANK1", "FPR11_BANK1",
  94        "FPR12_BANK1", "FPR13_BANK1", "FPR14_BANK1", "FPR15_BANK1",
  95    };
  96
  97    if (done_init)
  98        return;
  99
 100    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 101
 102    for (i = 0; i < 24; i++)
 103        cpu_gregs[i] = tcg_global_mem_new_i32(TCG_AREG0,
 104                                              offsetof(CPUSH4State, gregs[i]),
 105                                              gregnames[i]);
 106
 107    cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
 108                                    offsetof(CPUSH4State, pc), "PC");
 109    cpu_sr = tcg_global_mem_new_i32(TCG_AREG0,
 110                                    offsetof(CPUSH4State, sr), "SR");
 111    cpu_sr_m = tcg_global_mem_new_i32(TCG_AREG0,
 112                                    offsetof(CPUSH4State, sr_m), "SR_M");
 113    cpu_sr_q = tcg_global_mem_new_i32(TCG_AREG0,
 114                                    offsetof(CPUSH4State, sr_q), "SR_Q");
 115    cpu_sr_t = tcg_global_mem_new_i32(TCG_AREG0,
 116                                    offsetof(CPUSH4State, sr_t), "SR_T");
 117    cpu_ssr = tcg_global_mem_new_i32(TCG_AREG0,
 118                                     offsetof(CPUSH4State, ssr), "SSR");
 119    cpu_spc = tcg_global_mem_new_i32(TCG_AREG0,
 120                                     offsetof(CPUSH4State, spc), "SPC");
 121    cpu_gbr = tcg_global_mem_new_i32(TCG_AREG0,
 122                                     offsetof(CPUSH4State, gbr), "GBR");
 123    cpu_vbr = tcg_global_mem_new_i32(TCG_AREG0,
 124                                     offsetof(CPUSH4State, vbr), "VBR");
 125    cpu_sgr = tcg_global_mem_new_i32(TCG_AREG0,
 126                                     offsetof(CPUSH4State, sgr), "SGR");
 127    cpu_dbr = tcg_global_mem_new_i32(TCG_AREG0,
 128                                     offsetof(CPUSH4State, dbr), "DBR");
 129    cpu_mach = tcg_global_mem_new_i32(TCG_AREG0,
 130                                      offsetof(CPUSH4State, mach), "MACH");
 131    cpu_macl = tcg_global_mem_new_i32(TCG_AREG0,
 132                                      offsetof(CPUSH4State, macl), "MACL");
 133    cpu_pr = tcg_global_mem_new_i32(TCG_AREG0,
 134                                    offsetof(CPUSH4State, pr), "PR");
 135    cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
 136                                       offsetof(CPUSH4State, fpscr), "FPSCR");
 137    cpu_fpul = tcg_global_mem_new_i32(TCG_AREG0,
 138                                      offsetof(CPUSH4State, fpul), "FPUL");
 139
 140    cpu_flags = tcg_global_mem_new_i32(TCG_AREG0,
 141                                       offsetof(CPUSH4State, flags), "_flags_");
 142    cpu_delayed_pc = tcg_global_mem_new_i32(TCG_AREG0,
 143                                            offsetof(CPUSH4State, delayed_pc),
 144                                            "_delayed_pc_");
 145    cpu_ldst = tcg_global_mem_new_i32(TCG_AREG0,
 146                                      offsetof(CPUSH4State, ldst), "_ldst_");
 147
 148    for (i = 0; i < 32; i++)
 149        cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0,
 150                                              offsetof(CPUSH4State, fregs[i]),
 151                                              fregnames[i]);
 152
 153    done_init = 1;
 154}
 155
 156void superh_cpu_dump_state(CPUState *cs, FILE *f,
 157                           fprintf_function cpu_fprintf, int flags)
 158{
 159    SuperHCPU *cpu = SUPERH_CPU(cs);
 160    CPUSH4State *env = &cpu->env;
 161    int i;
 162    cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
 163                env->pc, cpu_read_sr(env), env->pr, env->fpscr);
 164    cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
 165                env->spc, env->ssr, env->gbr, env->vbr);
 166    cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
 167                env->sgr, env->dbr, env->delayed_pc, env->fpul);
 168    for (i = 0; i < 24; i += 4) {
 169        cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
 170                    i, env->gregs[i], i + 1, env->gregs[i + 1],
 171                    i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
 172    }
 173    if (env->flags & DELAY_SLOT) {
 174        cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
 175                    env->delayed_pc);
 176    } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
 177        cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
 178                    env->delayed_pc);
 179    }
 180}
 181
 182static void gen_read_sr(TCGv dst)
 183{
 184    TCGv t0 = tcg_temp_new();
 185    tcg_gen_shli_i32(t0, cpu_sr_q, SR_Q);
 186    tcg_gen_or_i32(dst, dst, t0);
 187    tcg_gen_shli_i32(t0, cpu_sr_m, SR_M);
 188    tcg_gen_or_i32(dst, dst, t0);
 189    tcg_gen_shli_i32(t0, cpu_sr_t, SR_T);
 190    tcg_gen_or_i32(dst, cpu_sr, t0);
 191    tcg_temp_free_i32(t0);
 192}
 193
 194static void gen_write_sr(TCGv src)
 195{
 196    tcg_gen_andi_i32(cpu_sr, src,
 197                     ~((1u << SR_Q) | (1u << SR_M) | (1u << SR_T)));
 198    tcg_gen_shri_i32(cpu_sr_q, src, SR_Q);
 199    tcg_gen_andi_i32(cpu_sr_q, cpu_sr_q, 1);
 200    tcg_gen_shri_i32(cpu_sr_m, src, SR_M);
 201    tcg_gen_andi_i32(cpu_sr_m, cpu_sr_m, 1);
 202    tcg_gen_shri_i32(cpu_sr_t, src, SR_T);
 203    tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
 204}
 205
 206static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
 207{
 208    TranslationBlock *tb;
 209    tb = ctx->tb;
 210
 211    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
 212        !ctx->singlestep_enabled) {
 213        /* Use a direct jump if in same page and singlestep not enabled */
 214        tcg_gen_goto_tb(n);
 215        tcg_gen_movi_i32(cpu_pc, dest);
 216        tcg_gen_exit_tb((uintptr_t)tb + n);
 217    } else {
 218        tcg_gen_movi_i32(cpu_pc, dest);
 219        if (ctx->singlestep_enabled)
 220            gen_helper_debug(cpu_env);
 221        tcg_gen_exit_tb(0);
 222    }
 223}
 224
 225static void gen_jump(DisasContext * ctx)
 226{
 227    if (ctx->delayed_pc == (uint32_t) - 1) {
 228        /* Target is not statically known, it comes necessarily from a
 229           delayed jump as immediate jump are conditinal jumps */
 230        tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
 231        if (ctx->singlestep_enabled)
 232            gen_helper_debug(cpu_env);
 233        tcg_gen_exit_tb(0);
 234    } else {
 235        gen_goto_tb(ctx, 0, ctx->delayed_pc);
 236    }
 237}
 238
 239static inline void gen_branch_slot(uint32_t delayed_pc, int t)
 240{
 241    TCGLabel *label = gen_new_label();
 242    tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
 243    tcg_gen_brcondi_i32(t ? TCG_COND_EQ : TCG_COND_NE, cpu_sr_t, 0, label);
 244    tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
 245    gen_set_label(label);
 246}
 247
 248/* Immediate conditional jump (bt or bf) */
 249static void gen_conditional_jump(DisasContext * ctx,
 250                                 target_ulong ift, target_ulong ifnott)
 251{
 252    TCGLabel *l1 = gen_new_label();
 253    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_sr_t, 0, l1);
 254    gen_goto_tb(ctx, 0, ifnott);
 255    gen_set_label(l1);
 256    gen_goto_tb(ctx, 1, ift);
 257}
 258
 259/* Delayed conditional jump (bt or bf) */
 260static void gen_delayed_conditional_jump(DisasContext * ctx)
 261{
 262    TCGLabel *l1;
 263    TCGv ds;
 264
 265    l1 = gen_new_label();
 266    ds = tcg_temp_new();
 267    tcg_gen_andi_i32(ds, cpu_flags, DELAY_SLOT_TRUE);
 268    tcg_gen_brcondi_i32(TCG_COND_NE, ds, 0, l1);
 269    gen_goto_tb(ctx, 1, ctx->pc + 2);
 270    gen_set_label(l1);
 271    tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
 272    gen_jump(ctx);
 273}
 274
 275static inline void gen_store_flags(uint32_t flags)
 276{
 277    tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
 278    tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
 279}
 280
 281static inline void gen_load_fpr64(TCGv_i64 t, int reg)
 282{
 283    tcg_gen_concat_i32_i64(t, cpu_fregs[reg + 1], cpu_fregs[reg]);
 284}
 285
 286static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
 287{
 288    TCGv_i32 tmp = tcg_temp_new_i32();
 289    tcg_gen_extrl_i64_i32(tmp, t);
 290    tcg_gen_mov_i32(cpu_fregs[reg + 1], tmp);
 291    tcg_gen_shri_i64(t, t, 32);
 292    tcg_gen_extrl_i64_i32(tmp, t);
 293    tcg_gen_mov_i32(cpu_fregs[reg], tmp);
 294    tcg_temp_free_i32(tmp);
 295}
 296
 297#define B3_0 (ctx->opcode & 0xf)
 298#define B6_4 ((ctx->opcode >> 4) & 0x7)
 299#define B7_4 ((ctx->opcode >> 4) & 0xf)
 300#define B7_0 (ctx->opcode & 0xff)
 301#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
 302#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
 303  (ctx->opcode & 0xfff))
 304#define B11_8 ((ctx->opcode >> 8) & 0xf)
 305#define B15_12 ((ctx->opcode >> 12) & 0xf)
 306
 307#define REG(x) ((x) < 8 && (ctx->flags & (1u << SR_MD))\
 308                        && (ctx->flags & (1u << SR_RB))\
 309                ? (cpu_gregs[x + 16]) : (cpu_gregs[x]))
 310
 311#define ALTREG(x) ((x) < 8 && (!(ctx->flags & (1u << SR_MD))\
 312                               || !(ctx->flags & (1u << SR_RB)))\
 313                ? (cpu_gregs[x + 16]) : (cpu_gregs[x]))
 314
 315#define FREG(x) (ctx->flags & FPSCR_FR ? (x) ^ 0x10 : (x))
 316#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
 317#define XREG(x) (ctx->flags & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
 318#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
 319
 320#define CHECK_NOT_DELAY_SLOT \
 321  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))     \
 322  {                                                           \
 323      tcg_gen_movi_i32(cpu_pc, ctx->pc);                      \
 324      gen_helper_raise_slot_illegal_instruction(cpu_env);     \
 325      ctx->bstate = BS_BRANCH;                                \
 326      return;                                                 \
 327  }
 328
 329#define CHECK_PRIVILEGED                                        \
 330  if (IS_USER(ctx)) {                                           \
 331      tcg_gen_movi_i32(cpu_pc, ctx->pc);                        \
 332      if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
 333          gen_helper_raise_slot_illegal_instruction(cpu_env);   \
 334      } else {                                                  \
 335          gen_helper_raise_illegal_instruction(cpu_env);        \
 336      }                                                         \
 337      ctx->bstate = BS_BRANCH;                                  \
 338      return;                                                   \
 339  }
 340
 341#define CHECK_FPU_ENABLED                                       \
 342  if (ctx->flags & (1u << SR_FD)) {                             \
 343      tcg_gen_movi_i32(cpu_pc, ctx->pc);                        \
 344      if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
 345          gen_helper_raise_slot_fpu_disable(cpu_env);           \
 346      } else {                                                  \
 347          gen_helper_raise_fpu_disable(cpu_env);                \
 348      }                                                         \
 349      ctx->bstate = BS_BRANCH;                                  \
 350      return;                                                   \
 351  }
 352
 353static void _decode_opc(DisasContext * ctx)
 354{
 355    /* This code tries to make movcal emulation sufficiently
 356       accurate for Linux purposes.  This instruction writes
 357       memory, and prior to that, always allocates a cache line.
 358       It is used in two contexts:
 359       - in memcpy, where data is copied in blocks, the first write
 360       of to a block uses movca.l for performance.
 361       - in arch/sh/mm/cache-sh4.c, movcal.l + ocbi combination is used
 362       to flush the cache. Here, the data written by movcal.l is never
 363       written to memory, and the data written is just bogus.
 364
 365       To simulate this, we simulate movcal.l, we store the value to memory,
 366       but we also remember the previous content. If we see ocbi, we check
 367       if movcal.l for that address was done previously. If so, the write should
 368       not have hit the memory, so we restore the previous content.
 369       When we see an instruction that is neither movca.l
 370       nor ocbi, the previous content is discarded.
 371
 372       To optimize, we only try to flush stores when we're at the start of
 373       TB, or if we already saw movca.l in this TB and did not flush stores
 374       yet.  */
 375    if (ctx->has_movcal)
 376        {
 377          int opcode = ctx->opcode & 0xf0ff;
 378          if (opcode != 0x0093 /* ocbi */
 379              && opcode != 0x00c3 /* movca.l */)
 380              {
 381                  gen_helper_discard_movcal_backup(cpu_env);
 382                  ctx->has_movcal = 0;
 383              }
 384        }
 385
 386#if 0
 387    fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
 388#endif
 389
 390    switch (ctx->opcode) {
 391    case 0x0019:                /* div0u */
 392        tcg_gen_movi_i32(cpu_sr_m, 0);
 393        tcg_gen_movi_i32(cpu_sr_q, 0);
 394        tcg_gen_movi_i32(cpu_sr_t, 0);
 395        return;
 396    case 0x000b:                /* rts */
 397        CHECK_NOT_DELAY_SLOT
 398        tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
 399        ctx->flags |= DELAY_SLOT;
 400        ctx->delayed_pc = (uint32_t) - 1;
 401        return;
 402    case 0x0028:                /* clrmac */
 403        tcg_gen_movi_i32(cpu_mach, 0);
 404        tcg_gen_movi_i32(cpu_macl, 0);
 405        return;
 406    case 0x0048:                /* clrs */
 407        tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(1u << SR_S));
 408        return;
 409    case 0x0008:                /* clrt */
 410        tcg_gen_movi_i32(cpu_sr_t, 0);
 411        return;
 412    case 0x0038:                /* ldtlb */
 413        CHECK_PRIVILEGED
 414        gen_helper_ldtlb(cpu_env);
 415        return;
 416    case 0x002b:                /* rte */
 417        CHECK_PRIVILEGED
 418        CHECK_NOT_DELAY_SLOT
 419        gen_write_sr(cpu_ssr);
 420        tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
 421        ctx->flags |= DELAY_SLOT;
 422        ctx->delayed_pc = (uint32_t) - 1;
 423        return;
 424    case 0x0058:                /* sets */
 425        tcg_gen_ori_i32(cpu_sr, cpu_sr, (1u << SR_S));
 426        return;
 427    case 0x0018:                /* sett */
 428        tcg_gen_movi_i32(cpu_sr_t, 1);
 429        return;
 430    case 0xfbfd:                /* frchg */
 431        tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
 432        ctx->bstate = BS_STOP;
 433        return;
 434    case 0xf3fd:                /* fschg */
 435        tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
 436        ctx->bstate = BS_STOP;
 437        return;
 438    case 0x0009:                /* nop */
 439        return;
 440    case 0x001b:                /* sleep */
 441        CHECK_PRIVILEGED
 442        tcg_gen_movi_i32(cpu_pc, ctx->pc + 2);
 443        gen_helper_sleep(cpu_env);
 444        return;
 445    }
 446
 447    switch (ctx->opcode & 0xf000) {
 448    case 0x1000:                /* mov.l Rm,@(disp,Rn) */
 449        {
 450            TCGv addr = tcg_temp_new();
 451            tcg_gen_addi_i32(addr, REG(B11_8), B3_0 * 4);
 452            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
 453            tcg_temp_free(addr);
 454        }
 455        return;
 456    case 0x5000:                /* mov.l @(disp,Rm),Rn */
 457        {
 458            TCGv addr = tcg_temp_new();
 459            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 4);
 460            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
 461            tcg_temp_free(addr);
 462        }
 463        return;
 464    case 0xe000:                /* mov #imm,Rn */
 465        tcg_gen_movi_i32(REG(B11_8), B7_0s);
 466        return;
 467    case 0x9000:                /* mov.w @(disp,PC),Rn */
 468        {
 469            TCGv addr = tcg_const_i32(ctx->pc + 4 + B7_0 * 2);
 470            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESW);
 471            tcg_temp_free(addr);
 472        }
 473        return;
 474    case 0xd000:                /* mov.l @(disp,PC),Rn */
 475        {
 476            TCGv addr = tcg_const_i32((ctx->pc + 4 + B7_0 * 4) & ~3);
 477            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
 478            tcg_temp_free(addr);
 479        }
 480        return;
 481    case 0x7000:                /* add #imm,Rn */
 482        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);
 483        return;
 484    case 0xa000:                /* bra disp */
 485        CHECK_NOT_DELAY_SLOT
 486        ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
 487        tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
 488        ctx->flags |= DELAY_SLOT;
 489        return;
 490    case 0xb000:                /* bsr disp */
 491        CHECK_NOT_DELAY_SLOT
 492        tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
 493        ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
 494        tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
 495        ctx->flags |= DELAY_SLOT;
 496        return;
 497    }
 498
 499    switch (ctx->opcode & 0xf00f) {
 500    case 0x6003:                /* mov Rm,Rn */
 501        tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
 502        return;
 503    case 0x2000:                /* mov.b Rm,@Rn */
 504        tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_UB);
 505        return;
 506    case 0x2001:                /* mov.w Rm,@Rn */
 507        tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_TEUW);
 508        return;
 509    case 0x2002:                /* mov.l Rm,@Rn */
 510        tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_TEUL);
 511        return;
 512    case 0x6000:                /* mov.b @Rm,Rn */
 513        tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_SB);
 514        return;
 515    case 0x6001:                /* mov.w @Rm,Rn */
 516        tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESW);
 517        return;
 518    case 0x6002:                /* mov.l @Rm,Rn */
 519        tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESL);
 520        return;
 521    case 0x2004:                /* mov.b Rm,@-Rn */
 522        {
 523            TCGv addr = tcg_temp_new();
 524            tcg_gen_subi_i32(addr, REG(B11_8), 1);
 525            /* might cause re-execution */
 526            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_UB);
 527            tcg_gen_mov_i32(REG(B11_8), addr);                  /* modify register status */
 528            tcg_temp_free(addr);
 529        }
 530        return;
 531    case 0x2005:                /* mov.w Rm,@-Rn */
 532        {
 533            TCGv addr = tcg_temp_new();
 534            tcg_gen_subi_i32(addr, REG(B11_8), 2);
 535            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUW);
 536            tcg_gen_mov_i32(REG(B11_8), addr);
 537            tcg_temp_free(addr);
 538        }
 539        return;
 540    case 0x2006:                /* mov.l Rm,@-Rn */
 541        {
 542            TCGv addr = tcg_temp_new();
 543            tcg_gen_subi_i32(addr, REG(B11_8), 4);
 544            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
 545            tcg_gen_mov_i32(REG(B11_8), addr);
 546        }
 547        return;
 548    case 0x6004:                /* mov.b @Rm+,Rn */
 549        tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_SB);
 550        if ( B11_8 != B7_4 )
 551                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 1);
 552        return;
 553    case 0x6005:                /* mov.w @Rm+,Rn */
 554        tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESW);
 555        if ( B11_8 != B7_4 )
 556                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
 557        return;
 558    case 0x6006:                /* mov.l @Rm+,Rn */
 559        tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESL);
 560        if ( B11_8 != B7_4 )
 561                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
 562        return;
 563    case 0x0004:                /* mov.b Rm,@(R0,Rn) */
 564        {
 565            TCGv addr = tcg_temp_new();
 566            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
 567            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_UB);
 568            tcg_temp_free(addr);
 569        }
 570        return;
 571    case 0x0005:                /* mov.w Rm,@(R0,Rn) */
 572        {
 573            TCGv addr = tcg_temp_new();
 574            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
 575            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUW);
 576            tcg_temp_free(addr);
 577        }
 578        return;
 579    case 0x0006:                /* mov.l Rm,@(R0,Rn) */
 580        {
 581            TCGv addr = tcg_temp_new();
 582            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
 583            tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
 584            tcg_temp_free(addr);
 585        }
 586        return;
 587    case 0x000c:                /* mov.b @(R0,Rm),Rn */
 588        {
 589            TCGv addr = tcg_temp_new();
 590            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
 591            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_SB);
 592            tcg_temp_free(addr);
 593        }
 594        return;
 595    case 0x000d:                /* mov.w @(R0,Rm),Rn */
 596        {
 597            TCGv addr = tcg_temp_new();
 598            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
 599            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESW);
 600            tcg_temp_free(addr);
 601        }
 602        return;
 603    case 0x000e:                /* mov.l @(R0,Rm),Rn */
 604        {
 605            TCGv addr = tcg_temp_new();
 606            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
 607            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
 608            tcg_temp_free(addr);
 609        }
 610        return;
 611    case 0x6008:                /* swap.b Rm,Rn */
 612        {
 613            TCGv low = tcg_temp_new();;
 614            tcg_gen_ext16u_i32(low, REG(B7_4));
 615            tcg_gen_bswap16_i32(low, low);
 616            tcg_gen_deposit_i32(REG(B11_8), REG(B7_4), low, 0, 16);
 617            tcg_temp_free(low);
 618        }
 619        return;
 620    case 0x6009:                /* swap.w Rm,Rn */
 621        tcg_gen_rotli_i32(REG(B11_8), REG(B7_4), 16);
 622        return;
 623    case 0x200d:                /* xtrct Rm,Rn */
 624        {
 625            TCGv high, low;
 626            high = tcg_temp_new();
 627            tcg_gen_shli_i32(high, REG(B7_4), 16);
 628            low = tcg_temp_new();
 629            tcg_gen_shri_i32(low, REG(B11_8), 16);
 630            tcg_gen_or_i32(REG(B11_8), high, low);
 631            tcg_temp_free(low);
 632            tcg_temp_free(high);
 633        }
 634        return;
 635    case 0x300c:                /* add Rm,Rn */
 636        tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));
 637        return;
 638    case 0x300e:                /* addc Rm,Rn */
 639        {
 640            TCGv t0, t1;
 641            t0 = tcg_const_tl(0);
 642            t1 = tcg_temp_new();
 643            tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0);
 644            tcg_gen_add2_i32(REG(B11_8), cpu_sr_t,
 645                             REG(B11_8), t0, t1, cpu_sr_t);
 646            tcg_temp_free(t0);
 647            tcg_temp_free(t1);
 648        }
 649        return;
 650    case 0x300f:                /* addv Rm,Rn */
 651        {
 652            TCGv t0, t1, t2;
 653            t0 = tcg_temp_new();
 654            tcg_gen_add_i32(t0, REG(B7_4), REG(B11_8));
 655            t1 = tcg_temp_new();
 656            tcg_gen_xor_i32(t1, t0, REG(B11_8));
 657            t2 = tcg_temp_new();
 658            tcg_gen_xor_i32(t2, REG(B7_4), REG(B11_8));
 659            tcg_gen_andc_i32(cpu_sr_t, t1, t2);
 660            tcg_temp_free(t2);
 661            tcg_gen_shri_i32(cpu_sr_t, cpu_sr_t, 31);
 662            tcg_temp_free(t1);
 663            tcg_gen_mov_i32(REG(B7_4), t0);
 664            tcg_temp_free(t0);
 665        }
 666        return;
 667    case 0x2009:                /* and Rm,Rn */
 668        tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
 669        return;
 670    case 0x3000:                /* cmp/eq Rm,Rn */
 671        tcg_gen_setcond_i32(TCG_COND_EQ, cpu_sr_t, REG(B11_8), REG(B7_4));
 672        return;
 673    case 0x3003:                /* cmp/ge Rm,Rn */
 674        tcg_gen_setcond_i32(TCG_COND_GE, cpu_sr_t, REG(B11_8), REG(B7_4));
 675        return;
 676    case 0x3007:                /* cmp/gt Rm,Rn */
 677        tcg_gen_setcond_i32(TCG_COND_GT, cpu_sr_t, REG(B11_8), REG(B7_4));
 678        return;
 679    case 0x3006:                /* cmp/hi Rm,Rn */
 680        tcg_gen_setcond_i32(TCG_COND_GTU, cpu_sr_t, REG(B11_8), REG(B7_4));
 681        return;
 682    case 0x3002:                /* cmp/hs Rm,Rn */
 683        tcg_gen_setcond_i32(TCG_COND_GEU, cpu_sr_t, REG(B11_8), REG(B7_4));
 684        return;
 685    case 0x200c:                /* cmp/str Rm,Rn */
 686        {
 687            TCGv cmp1 = tcg_temp_new();
 688            TCGv cmp2 = tcg_temp_new();
 689            tcg_gen_xor_i32(cmp2, REG(B7_4), REG(B11_8));
 690            tcg_gen_subi_i32(cmp1, cmp2, 0x01010101);
 691            tcg_gen_andc_i32(cmp1, cmp1, cmp2);
 692            tcg_gen_andi_i32(cmp1, cmp1, 0x80808080);
 693            tcg_gen_setcondi_i32(TCG_COND_NE, cpu_sr_t, cmp1, 0);
 694            tcg_temp_free(cmp2);
 695            tcg_temp_free(cmp1);
 696        }
 697        return;
 698    case 0x2007:                /* div0s Rm,Rn */
 699        tcg_gen_shri_i32(cpu_sr_q, REG(B11_8), 31);         /* SR_Q */
 700        tcg_gen_shri_i32(cpu_sr_m, REG(B7_4), 31);          /* SR_M */
 701        tcg_gen_xor_i32(cpu_sr_t, cpu_sr_q, cpu_sr_m);      /* SR_T */
 702        return;
 703    case 0x3004:                /* div1 Rm,Rn */
 704        {
 705            TCGv t0 = tcg_temp_new();
 706            TCGv t1 = tcg_temp_new();
 707            TCGv t2 = tcg_temp_new();
 708            TCGv zero = tcg_const_i32(0);
 709
 710            /* shift left arg1, saving the bit being pushed out and inserting
 711               T on the right */
 712            tcg_gen_shri_i32(t0, REG(B11_8), 31);
 713            tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
 714            tcg_gen_or_i32(REG(B11_8), REG(B11_8), cpu_sr_t);
 715
 716            /* Add or subtract arg0 from arg1 depending if Q == M. To avoid
 717               using 64-bit temps, we compute arg0's high part from q ^ m, so
 718               that it is 0x00000000 when adding the value or 0xffffffff when
 719               subtracting it. */
 720            tcg_gen_xor_i32(t1, cpu_sr_q, cpu_sr_m);
 721            tcg_gen_subi_i32(t1, t1, 1);
 722            tcg_gen_neg_i32(t2, REG(B7_4));
 723            tcg_gen_movcond_i32(TCG_COND_EQ, t2, t1, zero, REG(B7_4), t2);
 724            tcg_gen_add2_i32(REG(B11_8), t1, REG(B11_8), zero, t2, t1);
 725
 726            /* compute T and Q depending on carry */
 727            tcg_gen_andi_i32(t1, t1, 1);
 728            tcg_gen_xor_i32(t1, t1, t0);
 729            tcg_gen_xori_i32(cpu_sr_t, t1, 1);
 730            tcg_gen_xor_i32(cpu_sr_q, cpu_sr_m, t1);
 731
 732            tcg_temp_free(zero);
 733            tcg_temp_free(t2);
 734            tcg_temp_free(t1);
 735            tcg_temp_free(t0);
 736        }
 737        return;
 738    case 0x300d:                /* dmuls.l Rm,Rn */
 739        tcg_gen_muls2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
 740        return;
 741    case 0x3005:                /* dmulu.l Rm,Rn */
 742        tcg_gen_mulu2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
 743        return;
 744    case 0x600e:                /* exts.b Rm,Rn */
 745        tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));
 746        return;
 747    case 0x600f:                /* exts.w Rm,Rn */
 748        tcg_gen_ext16s_i32(REG(B11_8), REG(B7_4));
 749        return;
 750    case 0x600c:                /* extu.b Rm,Rn */
 751        tcg_gen_ext8u_i32(REG(B11_8), REG(B7_4));
 752        return;
 753    case 0x600d:                /* extu.w Rm,Rn */
 754        tcg_gen_ext16u_i32(REG(B11_8), REG(B7_4));
 755        return;
 756    case 0x000f:                /* mac.l @Rm+,@Rn+ */
 757        {
 758            TCGv arg0, arg1;
 759            arg0 = tcg_temp_new();
 760            tcg_gen_qemu_ld_i32(arg0, REG(B7_4), ctx->memidx, MO_TESL);
 761            arg1 = tcg_temp_new();
 762            tcg_gen_qemu_ld_i32(arg1, REG(B11_8), ctx->memidx, MO_TESL);
 763            gen_helper_macl(cpu_env, arg0, arg1);
 764            tcg_temp_free(arg1);
 765            tcg_temp_free(arg0);
 766            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
 767            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
 768        }
 769        return;
 770    case 0x400f:                /* mac.w @Rm+,@Rn+ */
 771        {
 772            TCGv arg0, arg1;
 773            arg0 = tcg_temp_new();
 774            tcg_gen_qemu_ld_i32(arg0, REG(B7_4), ctx->memidx, MO_TESL);
 775            arg1 = tcg_temp_new();
 776            tcg_gen_qemu_ld_i32(arg1, REG(B11_8), ctx->memidx, MO_TESL);
 777            gen_helper_macw(cpu_env, arg0, arg1);
 778            tcg_temp_free(arg1);
 779            tcg_temp_free(arg0);
 780            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);
 781            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
 782        }
 783        return;
 784    case 0x0007:                /* mul.l Rm,Rn */
 785        tcg_gen_mul_i32(cpu_macl, REG(B7_4), REG(B11_8));
 786        return;
 787    case 0x200f:                /* muls.w Rm,Rn */
 788        {
 789            TCGv arg0, arg1;
 790            arg0 = tcg_temp_new();
 791            tcg_gen_ext16s_i32(arg0, REG(B7_4));
 792            arg1 = tcg_temp_new();
 793            tcg_gen_ext16s_i32(arg1, REG(B11_8));
 794            tcg_gen_mul_i32(cpu_macl, arg0, arg1);
 795            tcg_temp_free(arg1);
 796            tcg_temp_free(arg0);
 797        }
 798        return;
 799    case 0x200e:                /* mulu.w Rm,Rn */
 800        {
 801            TCGv arg0, arg1;
 802            arg0 = tcg_temp_new();
 803            tcg_gen_ext16u_i32(arg0, REG(B7_4));
 804            arg1 = tcg_temp_new();
 805            tcg_gen_ext16u_i32(arg1, REG(B11_8));
 806            tcg_gen_mul_i32(cpu_macl, arg0, arg1);
 807            tcg_temp_free(arg1);
 808            tcg_temp_free(arg0);
 809        }
 810        return;
 811    case 0x600b:                /* neg Rm,Rn */
 812        tcg_gen_neg_i32(REG(B11_8), REG(B7_4));
 813        return;
 814    case 0x600a:                /* negc Rm,Rn */
 815        {
 816            TCGv t0 = tcg_const_i32(0);
 817            tcg_gen_add2_i32(REG(B11_8), cpu_sr_t,
 818                             REG(B7_4), t0, cpu_sr_t, t0);
 819            tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t,
 820                             t0, t0, REG(B11_8), cpu_sr_t);
 821            tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
 822            tcg_temp_free(t0);
 823        }
 824        return;
 825    case 0x6007:                /* not Rm,Rn */
 826        tcg_gen_not_i32(REG(B11_8), REG(B7_4));
 827        return;
 828    case 0x200b:                /* or Rm,Rn */
 829        tcg_gen_or_i32(REG(B11_8), REG(B11_8), REG(B7_4));
 830        return;
 831    case 0x400c:                /* shad Rm,Rn */
 832        {
 833            TCGv t0 = tcg_temp_new();
 834            TCGv t1 = tcg_temp_new();
 835            TCGv t2 = tcg_temp_new();
 836
 837            tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
 838
 839            /* positive case: shift to the left */
 840            tcg_gen_shl_i32(t1, REG(B11_8), t0);
 841
 842            /* negative case: shift to the right in two steps to
 843               correctly handle the -32 case */
 844            tcg_gen_xori_i32(t0, t0, 0x1f);
 845            tcg_gen_sar_i32(t2, REG(B11_8), t0);
 846            tcg_gen_sari_i32(t2, t2, 1);
 847
 848            /* select between the two cases */
 849            tcg_gen_movi_i32(t0, 0);
 850            tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
 851
 852            tcg_temp_free(t0);
 853            tcg_temp_free(t1);
 854            tcg_temp_free(t2);
 855        }
 856        return;
 857    case 0x400d:                /* shld Rm,Rn */
 858        {
 859            TCGv t0 = tcg_temp_new();
 860            TCGv t1 = tcg_temp_new();
 861            TCGv t2 = tcg_temp_new();
 862
 863            tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
 864
 865            /* positive case: shift to the left */
 866            tcg_gen_shl_i32(t1, REG(B11_8), t0);
 867
 868            /* negative case: shift to the right in two steps to
 869               correctly handle the -32 case */
 870            tcg_gen_xori_i32(t0, t0, 0x1f);
 871            tcg_gen_shr_i32(t2, REG(B11_8), t0);
 872            tcg_gen_shri_i32(t2, t2, 1);
 873
 874            /* select between the two cases */
 875            tcg_gen_movi_i32(t0, 0);
 876            tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
 877
 878            tcg_temp_free(t0);
 879            tcg_temp_free(t1);
 880            tcg_temp_free(t2);
 881        }
 882        return;
 883    case 0x3008:                /* sub Rm,Rn */
 884        tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));
 885        return;
 886    case 0x300a:                /* subc Rm,Rn */
 887        {
 888            TCGv t0, t1;
 889            t0 = tcg_const_tl(0);
 890            t1 = tcg_temp_new();
 891            tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0);
 892            tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t,
 893                             REG(B11_8), t0, t1, cpu_sr_t);
 894            tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
 895            tcg_temp_free(t0);
 896            tcg_temp_free(t1);
 897        }
 898        return;
 899    case 0x300b:                /* subv Rm,Rn */
 900        {
 901            TCGv t0, t1, t2;
 902            t0 = tcg_temp_new();
 903            tcg_gen_sub_i32(t0, REG(B11_8), REG(B7_4));
 904            t1 = tcg_temp_new();
 905            tcg_gen_xor_i32(t1, t0, REG(B7_4));
 906            t2 = tcg_temp_new();
 907            tcg_gen_xor_i32(t2, REG(B11_8), REG(B7_4));
 908            tcg_gen_and_i32(t1, t1, t2);
 909            tcg_temp_free(t2);
 910            tcg_gen_shri_i32(cpu_sr_t, t1, 31);
 911            tcg_temp_free(t1);
 912            tcg_gen_mov_i32(REG(B11_8), t0);
 913            tcg_temp_free(t0);
 914        }
 915        return;
 916    case 0x2008:                /* tst Rm,Rn */
 917        {
 918            TCGv val = tcg_temp_new();
 919            tcg_gen_and_i32(val, REG(B7_4), REG(B11_8));
 920            tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
 921            tcg_temp_free(val);
 922        }
 923        return;
 924    case 0x200a:                /* xor Rm,Rn */
 925        tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));
 926        return;
 927    case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
 928        CHECK_FPU_ENABLED
 929        if (ctx->flags & FPSCR_SZ) {
 930            TCGv_i64 fp = tcg_temp_new_i64();
 931            gen_load_fpr64(fp, XREG(B7_4));
 932            gen_store_fpr64(fp, XREG(B11_8));
 933            tcg_temp_free_i64(fp);
 934        } else {
 935            tcg_gen_mov_i32(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
 936        }
 937        return;
 938    case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
 939        CHECK_FPU_ENABLED
 940        if (ctx->flags & FPSCR_SZ) {
 941            TCGv addr_hi = tcg_temp_new();
 942            int fr = XREG(B7_4);
 943            tcg_gen_addi_i32(addr_hi, REG(B11_8), 4);
 944            tcg_gen_qemu_st_i32(cpu_fregs[fr], REG(B11_8),
 945                                ctx->memidx, MO_TEUL);
 946            tcg_gen_qemu_st_i32(cpu_fregs[fr+1], addr_hi,
 947                                ctx->memidx, MO_TEUL);
 948            tcg_temp_free(addr_hi);
 949        } else {
 950            tcg_gen_qemu_st_i32(cpu_fregs[FREG(B7_4)], REG(B11_8),
 951                                ctx->memidx, MO_TEUL);
 952        }
 953        return;
 954    case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
 955        CHECK_FPU_ENABLED
 956        if (ctx->flags & FPSCR_SZ) {
 957            TCGv addr_hi = tcg_temp_new();
 958            int fr = XREG(B11_8);
 959            tcg_gen_addi_i32(addr_hi, REG(B7_4), 4);
 960            tcg_gen_qemu_ld_i32(cpu_fregs[fr], REG(B7_4), ctx->memidx, MO_TEUL);
 961            tcg_gen_qemu_ld_i32(cpu_fregs[fr+1], addr_hi, ctx->memidx, MO_TEUL);
 962            tcg_temp_free(addr_hi);
 963        } else {
 964            tcg_gen_qemu_ld_i32(cpu_fregs[FREG(B11_8)], REG(B7_4),
 965                                ctx->memidx, MO_TEUL);
 966        }
 967        return;
 968    case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
 969        CHECK_FPU_ENABLED
 970        if (ctx->flags & FPSCR_SZ) {
 971            TCGv addr_hi = tcg_temp_new();
 972            int fr = XREG(B11_8);
 973            tcg_gen_addi_i32(addr_hi, REG(B7_4), 4);
 974            tcg_gen_qemu_ld_i32(cpu_fregs[fr], REG(B7_4), ctx->memidx, MO_TEUL);
 975            tcg_gen_qemu_ld_i32(cpu_fregs[fr+1], addr_hi, ctx->memidx, MO_TEUL);
 976            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 8);
 977            tcg_temp_free(addr_hi);
 978        } else {
 979            tcg_gen_qemu_ld_i32(cpu_fregs[FREG(B11_8)], REG(B7_4),
 980                                ctx->memidx, MO_TEUL);
 981            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
 982        }
 983        return;
 984    case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
 985        CHECK_FPU_ENABLED
 986        TCGv addr = tcg_temp_new_i32();
 987        tcg_gen_subi_i32(addr, REG(B11_8), 4);
 988        if (ctx->flags & FPSCR_SZ) {
 989            int fr = XREG(B7_4);
 990            tcg_gen_qemu_st_i32(cpu_fregs[fr+1], addr, ctx->memidx, MO_TEUL);
 991            tcg_gen_subi_i32(addr, addr, 4);
 992            tcg_gen_qemu_st_i32(cpu_fregs[fr], addr, ctx->memidx, MO_TEUL);
 993        } else {
 994            tcg_gen_qemu_st_i32(cpu_fregs[FREG(B7_4)], addr,
 995                                ctx->memidx, MO_TEUL);
 996        }
 997        tcg_gen_mov_i32(REG(B11_8), addr);
 998        tcg_temp_free(addr);
 999        return;
1000    case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
1001        CHECK_FPU_ENABLED
1002        {
1003            TCGv addr = tcg_temp_new_i32();
1004            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
1005            if (ctx->flags & FPSCR_SZ) {
1006                int fr = XREG(B11_8);
1007                tcg_gen_qemu_ld_i32(cpu_fregs[fr], addr,
1008                                    ctx->memidx, MO_TEUL);
1009                tcg_gen_addi_i32(addr, addr, 4);
1010                tcg_gen_qemu_ld_i32(cpu_fregs[fr+1], addr,
1011                                    ctx->memidx, MO_TEUL);
1012            } else {
1013                tcg_gen_qemu_ld_i32(cpu_fregs[FREG(B11_8)], addr,
1014                                    ctx->memidx, MO_TEUL);
1015            }
1016            tcg_temp_free(addr);
1017        }
1018        return;
1019    case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
1020        CHECK_FPU_ENABLED
1021        {
1022            TCGv addr = tcg_temp_new();
1023            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
1024            if (ctx->flags & FPSCR_SZ) {
1025                int fr = XREG(B7_4);
1026                tcg_gen_qemu_ld_i32(cpu_fregs[fr], addr,
1027                                    ctx->memidx, MO_TEUL);
1028                tcg_gen_addi_i32(addr, addr, 4);
1029                tcg_gen_qemu_ld_i32(cpu_fregs[fr+1], addr,
1030                                    ctx->memidx, MO_TEUL);
1031            } else {
1032                tcg_gen_qemu_st_i32(cpu_fregs[FREG(B7_4)], addr,
1033                                    ctx->memidx, MO_TEUL);
1034            }
1035            tcg_temp_free(addr);
1036        }
1037        return;
1038    case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1039    case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1040    case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1041    case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1042    case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1043    case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1044        {
1045            CHECK_FPU_ENABLED
1046            if (ctx->flags & FPSCR_PR) {
1047                TCGv_i64 fp0, fp1;
1048
1049                if (ctx->opcode & 0x0110)
1050                    break; /* illegal instruction */
1051                fp0 = tcg_temp_new_i64();
1052                fp1 = tcg_temp_new_i64();
1053                gen_load_fpr64(fp0, DREG(B11_8));
1054                gen_load_fpr64(fp1, DREG(B7_4));
1055                switch (ctx->opcode & 0xf00f) {
1056                case 0xf000:            /* fadd Rm,Rn */
1057                    gen_helper_fadd_DT(fp0, cpu_env, fp0, fp1);
1058                    break;
1059                case 0xf001:            /* fsub Rm,Rn */
1060                    gen_helper_fsub_DT(fp0, cpu_env, fp0, fp1);
1061                    break;
1062                case 0xf002:            /* fmul Rm,Rn */
1063                    gen_helper_fmul_DT(fp0, cpu_env, fp0, fp1);
1064                    break;
1065                case 0xf003:            /* fdiv Rm,Rn */
1066                    gen_helper_fdiv_DT(fp0, cpu_env, fp0, fp1);
1067                    break;
1068                case 0xf004:            /* fcmp/eq Rm,Rn */
1069                    gen_helper_fcmp_eq_DT(cpu_env, fp0, fp1);
1070                    return;
1071                case 0xf005:            /* fcmp/gt Rm,Rn */
1072                    gen_helper_fcmp_gt_DT(cpu_env, fp0, fp1);
1073                    return;
1074                }
1075                gen_store_fpr64(fp0, DREG(B11_8));
1076                tcg_temp_free_i64(fp0);
1077                tcg_temp_free_i64(fp1);
1078            } else {
1079                switch (ctx->opcode & 0xf00f) {
1080                case 0xf000:            /* fadd Rm,Rn */
1081                    gen_helper_fadd_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1082                                       cpu_fregs[FREG(B11_8)],
1083                                       cpu_fregs[FREG(B7_4)]);
1084                    break;
1085                case 0xf001:            /* fsub Rm,Rn */
1086                    gen_helper_fsub_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1087                                       cpu_fregs[FREG(B11_8)],
1088                                       cpu_fregs[FREG(B7_4)]);
1089                    break;
1090                case 0xf002:            /* fmul Rm,Rn */
1091                    gen_helper_fmul_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1092                                       cpu_fregs[FREG(B11_8)],
1093                                       cpu_fregs[FREG(B7_4)]);
1094                    break;
1095                case 0xf003:            /* fdiv Rm,Rn */
1096                    gen_helper_fdiv_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1097                                       cpu_fregs[FREG(B11_8)],
1098                                       cpu_fregs[FREG(B7_4)]);
1099                    break;
1100                case 0xf004:            /* fcmp/eq Rm,Rn */
1101                    gen_helper_fcmp_eq_FT(cpu_env, cpu_fregs[FREG(B11_8)],
1102                                          cpu_fregs[FREG(B7_4)]);
1103                    return;
1104                case 0xf005:            /* fcmp/gt Rm,Rn */
1105                    gen_helper_fcmp_gt_FT(cpu_env, cpu_fregs[FREG(B11_8)],
1106                                          cpu_fregs[FREG(B7_4)]);
1107                    return;
1108                }
1109            }
1110        }
1111        return;
1112    case 0xf00e: /* fmac FR0,RM,Rn */
1113        {
1114            CHECK_FPU_ENABLED
1115            if (ctx->flags & FPSCR_PR) {
1116                break; /* illegal instruction */
1117            } else {
1118                gen_helper_fmac_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1119                                   cpu_fregs[FREG(0)], cpu_fregs[FREG(B7_4)],
1120                                   cpu_fregs[FREG(B11_8)]);
1121                return;
1122            }
1123        }
1124    }
1125
1126    switch (ctx->opcode & 0xff00) {
1127    case 0xc900:                /* and #imm,R0 */
1128        tcg_gen_andi_i32(REG(0), REG(0), B7_0);
1129        return;
1130    case 0xcd00:                /* and.b #imm,@(R0,GBR) */
1131        {
1132            TCGv addr, val;
1133            addr = tcg_temp_new();
1134            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1135            val = tcg_temp_new();
1136            tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1137            tcg_gen_andi_i32(val, val, B7_0);
1138            tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1139            tcg_temp_free(val);
1140            tcg_temp_free(addr);
1141        }
1142        return;
1143    case 0x8b00:                /* bf label */
1144        CHECK_NOT_DELAY_SLOT
1145            gen_conditional_jump(ctx, ctx->pc + 2,
1146                                 ctx->pc + 4 + B7_0s * 2);
1147        ctx->bstate = BS_BRANCH;
1148        return;
1149    case 0x8f00:                /* bf/s label */
1150        CHECK_NOT_DELAY_SLOT
1151        gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);
1152        ctx->flags |= DELAY_SLOT_CONDITIONAL;
1153        return;
1154    case 0x8900:                /* bt label */
1155        CHECK_NOT_DELAY_SLOT
1156            gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
1157                                 ctx->pc + 2);
1158        ctx->bstate = BS_BRANCH;
1159        return;
1160    case 0x8d00:                /* bt/s label */
1161        CHECK_NOT_DELAY_SLOT
1162        gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);
1163        ctx->flags |= DELAY_SLOT_CONDITIONAL;
1164        return;
1165    case 0x8800:                /* cmp/eq #imm,R0 */
1166        tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, REG(0), B7_0s);
1167        return;
1168    case 0xc400:                /* mov.b @(disp,GBR),R0 */
1169        {
1170            TCGv addr = tcg_temp_new();
1171            tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1172            tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_SB);
1173            tcg_temp_free(addr);
1174        }
1175        return;
1176    case 0xc500:                /* mov.w @(disp,GBR),R0 */
1177        {
1178            TCGv addr = tcg_temp_new();
1179            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1180            tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESW);
1181            tcg_temp_free(addr);
1182        }
1183        return;
1184    case 0xc600:                /* mov.l @(disp,GBR),R0 */
1185        {
1186            TCGv addr = tcg_temp_new();
1187            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1188            tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESL);
1189            tcg_temp_free(addr);
1190        }
1191        return;
1192    case 0xc000:                /* mov.b R0,@(disp,GBR) */
1193        {
1194            TCGv addr = tcg_temp_new();
1195            tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1196            tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_UB);
1197            tcg_temp_free(addr);
1198        }
1199        return;
1200    case 0xc100:                /* mov.w R0,@(disp,GBR) */
1201        {
1202            TCGv addr = tcg_temp_new();
1203            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1204            tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUW);
1205            tcg_temp_free(addr);
1206        }
1207        return;
1208    case 0xc200:                /* mov.l R0,@(disp,GBR) */
1209        {
1210            TCGv addr = tcg_temp_new();
1211            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1212            tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUL);
1213            tcg_temp_free(addr);
1214        }
1215        return;
1216    case 0x8000:                /* mov.b R0,@(disp,Rn) */
1217        {
1218            TCGv addr = tcg_temp_new();
1219            tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1220            tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_UB);
1221            tcg_temp_free(addr);
1222        }
1223        return;
1224    case 0x8100:                /* mov.w R0,@(disp,Rn) */
1225        {
1226            TCGv addr = tcg_temp_new();
1227            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1228            tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUW);
1229            tcg_temp_free(addr);
1230        }
1231        return;
1232    case 0x8400:                /* mov.b @(disp,Rn),R0 */
1233        {
1234            TCGv addr = tcg_temp_new();
1235            tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1236            tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_SB);
1237            tcg_temp_free(addr);
1238        }
1239        return;
1240    case 0x8500:                /* mov.w @(disp,Rn),R0 */
1241        {
1242            TCGv addr = tcg_temp_new();
1243            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1244            tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESW);
1245            tcg_temp_free(addr);
1246        }
1247        return;
1248    case 0xc700:                /* mova @(disp,PC),R0 */
1249        tcg_gen_movi_i32(REG(0), ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
1250        return;
1251    case 0xcb00:                /* or #imm,R0 */
1252        tcg_gen_ori_i32(REG(0), REG(0), B7_0);
1253        return;
1254    case 0xcf00:                /* or.b #imm,@(R0,GBR) */
1255        {
1256            TCGv addr, val;
1257            addr = tcg_temp_new();
1258            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1259            val = tcg_temp_new();
1260            tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1261            tcg_gen_ori_i32(val, val, B7_0);
1262            tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1263            tcg_temp_free(val);
1264            tcg_temp_free(addr);
1265        }
1266        return;
1267    case 0xc300:                /* trapa #imm */
1268        {
1269            TCGv imm;
1270            CHECK_NOT_DELAY_SLOT
1271            tcg_gen_movi_i32(cpu_pc, ctx->pc);
1272            imm = tcg_const_i32(B7_0);
1273            gen_helper_trapa(cpu_env, imm);
1274            tcg_temp_free(imm);
1275            ctx->bstate = BS_BRANCH;
1276        }
1277        return;
1278    case 0xc800:                /* tst #imm,R0 */
1279        {
1280            TCGv val = tcg_temp_new();
1281            tcg_gen_andi_i32(val, REG(0), B7_0);
1282            tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1283            tcg_temp_free(val);
1284        }
1285        return;
1286    case 0xcc00:                /* tst.b #imm,@(R0,GBR) */
1287        {
1288            TCGv val = tcg_temp_new();
1289            tcg_gen_add_i32(val, REG(0), cpu_gbr);
1290            tcg_gen_qemu_ld_i32(val, val, ctx->memidx, MO_UB);
1291            tcg_gen_andi_i32(val, val, B7_0);
1292            tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1293            tcg_temp_free(val);
1294        }
1295        return;
1296    case 0xca00:                /* xor #imm,R0 */
1297        tcg_gen_xori_i32(REG(0), REG(0), B7_0);
1298        return;
1299    case 0xce00:                /* xor.b #imm,@(R0,GBR) */
1300        {
1301            TCGv addr, val;
1302            addr = tcg_temp_new();
1303            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1304            val = tcg_temp_new();
1305            tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1306            tcg_gen_xori_i32(val, val, B7_0);
1307            tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1308            tcg_temp_free(val);
1309            tcg_temp_free(addr);
1310        }
1311        return;
1312    }
1313
1314    switch (ctx->opcode & 0xf08f) {
1315    case 0x408e:                /* ldc Rm,Rn_BANK */
1316        CHECK_PRIVILEGED
1317        tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
1318        return;
1319    case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
1320        CHECK_PRIVILEGED
1321        tcg_gen_qemu_ld_i32(ALTREG(B6_4), REG(B11_8), ctx->memidx, MO_TESL);
1322        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1323        return;
1324    case 0x0082:                /* stc Rm_BANK,Rn */
1325        CHECK_PRIVILEGED
1326        tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
1327        return;
1328    case 0x4083:                /* stc.l Rm_BANK,@-Rn */
1329        CHECK_PRIVILEGED
1330        {
1331            TCGv addr = tcg_temp_new();
1332            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1333            tcg_gen_qemu_st_i32(ALTREG(B6_4), addr, ctx->memidx, MO_TEUL);
1334            tcg_gen_mov_i32(REG(B11_8), addr);
1335            tcg_temp_free(addr);
1336        }
1337        return;
1338    }
1339
1340    switch (ctx->opcode & 0xf0ff) {
1341    case 0x0023:                /* braf Rn */
1342        CHECK_NOT_DELAY_SLOT
1343        tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->pc + 4);
1344        ctx->flags |= DELAY_SLOT;
1345        ctx->delayed_pc = (uint32_t) - 1;
1346        return;
1347    case 0x0003:                /* bsrf Rn */
1348        CHECK_NOT_DELAY_SLOT
1349        tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1350        tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);
1351        ctx->flags |= DELAY_SLOT;
1352        ctx->delayed_pc = (uint32_t) - 1;
1353        return;
1354    case 0x4015:                /* cmp/pl Rn */
1355        tcg_gen_setcondi_i32(TCG_COND_GT, cpu_sr_t, REG(B11_8), 0);
1356        return;
1357    case 0x4011:                /* cmp/pz Rn */
1358        tcg_gen_setcondi_i32(TCG_COND_GE, cpu_sr_t, REG(B11_8), 0);
1359        return;
1360    case 0x4010:                /* dt Rn */
1361        tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);
1362        tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, REG(B11_8), 0);
1363        return;
1364    case 0x402b:                /* jmp @Rn */
1365        CHECK_NOT_DELAY_SLOT
1366        tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1367        ctx->flags |= DELAY_SLOT;
1368        ctx->delayed_pc = (uint32_t) - 1;
1369        return;
1370    case 0x400b:                /* jsr @Rn */
1371        CHECK_NOT_DELAY_SLOT
1372        tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1373        tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1374        ctx->flags |= DELAY_SLOT;
1375        ctx->delayed_pc = (uint32_t) - 1;
1376        return;
1377    case 0x400e:                /* ldc Rm,SR */
1378        CHECK_PRIVILEGED
1379        {
1380            TCGv val = tcg_temp_new();
1381            tcg_gen_andi_i32(val, REG(B11_8), 0x700083f3);
1382            gen_write_sr(val);
1383            tcg_temp_free(val);
1384            ctx->bstate = BS_STOP;
1385        }
1386        return;
1387    case 0x4007:                /* ldc.l @Rm+,SR */
1388        CHECK_PRIVILEGED
1389        {
1390            TCGv val = tcg_temp_new();
1391            tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_TESL);
1392            tcg_gen_andi_i32(val, val, 0x700083f3);
1393            gen_write_sr(val);
1394            tcg_temp_free(val);
1395            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1396            ctx->bstate = BS_STOP;
1397        }
1398        return;
1399    case 0x0002:                /* stc SR,Rn */
1400        CHECK_PRIVILEGED
1401        gen_read_sr(REG(B11_8));
1402        return;
1403    case 0x4003:                /* stc SR,@-Rn */
1404        CHECK_PRIVILEGED
1405        {
1406            TCGv addr = tcg_temp_new();
1407            TCGv val = tcg_temp_new();
1408            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1409            gen_read_sr(val);
1410            tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_TEUL);
1411            tcg_gen_mov_i32(REG(B11_8), addr);
1412            tcg_temp_free(val);
1413            tcg_temp_free(addr);
1414        }
1415        return;
1416#define LD(reg,ldnum,ldpnum,prechk)             \
1417  case ldnum:                                                   \
1418    prechk                                                      \
1419    tcg_gen_mov_i32 (cpu_##reg, REG(B11_8));                    \
1420    return;                                                     \
1421  case ldpnum:                                                  \
1422    prechk                                                      \
1423    tcg_gen_qemu_ld_i32(cpu_##reg, REG(B11_8), ctx->memidx, MO_TESL); \
1424    tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);                \
1425    return;
1426#define ST(reg,stnum,stpnum,prechk)             \
1427  case stnum:                                                   \
1428    prechk                                                      \
1429    tcg_gen_mov_i32 (REG(B11_8), cpu_##reg);                    \
1430    return;                                                     \
1431  case stpnum:                                                  \
1432    prechk                                                      \
1433    {                                                           \
1434        TCGv addr = tcg_temp_new();                             \
1435        tcg_gen_subi_i32(addr, REG(B11_8), 4);                  \
1436        tcg_gen_qemu_st_i32(cpu_##reg, addr, ctx->memidx, MO_TEUL); \
1437        tcg_gen_mov_i32(REG(B11_8), addr);                      \
1438        tcg_temp_free(addr);                                    \
1439    }                                                           \
1440    return;
1441#define LDST(reg,ldnum,ldpnum,stnum,stpnum,prechk)              \
1442        LD(reg,ldnum,ldpnum,prechk)                             \
1443        ST(reg,stnum,stpnum,prechk)
1444        LDST(gbr,  0x401e, 0x4017, 0x0012, 0x4013, {})
1445        LDST(vbr,  0x402e, 0x4027, 0x0022, 0x4023, CHECK_PRIVILEGED)
1446        LDST(ssr,  0x403e, 0x4037, 0x0032, 0x4033, CHECK_PRIVILEGED)
1447        LDST(spc,  0x404e, 0x4047, 0x0042, 0x4043, CHECK_PRIVILEGED)
1448        ST(sgr,  0x003a, 0x4032, CHECK_PRIVILEGED)
1449        LD(sgr,  0x403a, 0x4036, CHECK_PRIVILEGED if (!(ctx->features & SH_FEATURE_SH4A)) break;)
1450        LDST(dbr,  0x40fa, 0x40f6, 0x00fa, 0x40f2, CHECK_PRIVILEGED)
1451        LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002, {})
1452        LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012, {})
1453        LDST(pr,   0x402a, 0x4026, 0x002a, 0x4022, {})
1454        LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052, {CHECK_FPU_ENABLED})
1455    case 0x406a:                /* lds Rm,FPSCR */
1456        CHECK_FPU_ENABLED
1457        gen_helper_ld_fpscr(cpu_env, REG(B11_8));
1458        ctx->bstate = BS_STOP;
1459        return;
1460    case 0x4066:                /* lds.l @Rm+,FPSCR */
1461        CHECK_FPU_ENABLED
1462        {
1463            TCGv addr = tcg_temp_new();
1464            tcg_gen_qemu_ld_i32(addr, REG(B11_8), ctx->memidx, MO_TESL);
1465            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1466            gen_helper_ld_fpscr(cpu_env, addr);
1467            tcg_temp_free(addr);
1468            ctx->bstate = BS_STOP;
1469        }
1470        return;
1471    case 0x006a:                /* sts FPSCR,Rn */
1472        CHECK_FPU_ENABLED
1473        tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);
1474        return;
1475    case 0x4062:                /* sts FPSCR,@-Rn */
1476        CHECK_FPU_ENABLED
1477        {
1478            TCGv addr, val;
1479            val = tcg_temp_new();
1480            tcg_gen_andi_i32(val, cpu_fpscr, 0x003fffff);
1481            addr = tcg_temp_new();
1482            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1483            tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_TEUL);
1484            tcg_gen_mov_i32(REG(B11_8), addr);
1485            tcg_temp_free(addr);
1486            tcg_temp_free(val);
1487        }
1488        return;
1489    case 0x00c3:                /* movca.l R0,@Rm */
1490        {
1491            TCGv val = tcg_temp_new();
1492            tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_TEUL);
1493            gen_helper_movcal(cpu_env, REG(B11_8), val);
1494            tcg_gen_qemu_st_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1495        }
1496        ctx->has_movcal = 1;
1497        return;
1498    case 0x40a9:
1499        /* MOVUA.L @Rm,R0 (Rm) -> R0
1500           Load non-boundary-aligned data */
1501        tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1502        return;
1503    case 0x40e9:
1504        /* MOVUA.L @Rm+,R0   (Rm) -> R0, Rm + 4 -> Rm
1505           Load non-boundary-aligned data */
1506        tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1507        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1508        return;
1509    case 0x0029:                /* movt Rn */
1510        tcg_gen_mov_i32(REG(B11_8), cpu_sr_t);
1511        return;
1512    case 0x0073:
1513        /* MOVCO.L
1514               LDST -> T
1515               If (T == 1) R0 -> (Rn)
1516               0 -> LDST
1517        */
1518        if (ctx->features & SH_FEATURE_SH4A) {
1519            TCGLabel *label = gen_new_label();
1520            tcg_gen_mov_i32(cpu_sr_t, cpu_ldst);
1521            tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ldst, 0, label);
1522            tcg_gen_qemu_st_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1523            gen_set_label(label);
1524            tcg_gen_movi_i32(cpu_ldst, 0);
1525            return;
1526        } else
1527            break;
1528    case 0x0063:
1529        /* MOVLI.L @Rm,R0
1530               1 -> LDST
1531               (Rm) -> R0
1532               When interrupt/exception
1533               occurred 0 -> LDST
1534        */
1535        if (ctx->features & SH_FEATURE_SH4A) {
1536            tcg_gen_movi_i32(cpu_ldst, 0);
1537            tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TESL);
1538            tcg_gen_movi_i32(cpu_ldst, 1);
1539            return;
1540        } else
1541            break;
1542    case 0x0093:                /* ocbi @Rn */
1543        {
1544            gen_helper_ocbi(cpu_env, REG(B11_8));
1545        }
1546        return;
1547    case 0x00a3:                /* ocbp @Rn */
1548    case 0x00b3:                /* ocbwb @Rn */
1549        /* These instructions are supposed to do nothing in case of
1550           a cache miss. Given that we only partially emulate caches
1551           it is safe to simply ignore them. */
1552        return;
1553    case 0x0083:                /* pref @Rn */
1554        return;
1555    case 0x00d3:                /* prefi @Rn */
1556        if (ctx->features & SH_FEATURE_SH4A)
1557            return;
1558        else
1559            break;
1560    case 0x00e3:                /* icbi @Rn */
1561        if (ctx->features & SH_FEATURE_SH4A)
1562            return;
1563        else
1564            break;
1565    case 0x00ab:                /* synco */
1566        if (ctx->features & SH_FEATURE_SH4A)
1567            return;
1568        else
1569            break;
1570    case 0x4024:                /* rotcl Rn */
1571        {
1572            TCGv tmp = tcg_temp_new();
1573            tcg_gen_mov_i32(tmp, cpu_sr_t);
1574            tcg_gen_shri_i32(cpu_sr_t, REG(B11_8), 31);
1575            tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1576            tcg_gen_or_i32(REG(B11_8), REG(B11_8), tmp);
1577            tcg_temp_free(tmp);
1578        }
1579        return;
1580    case 0x4025:                /* rotcr Rn */
1581        {
1582            TCGv tmp = tcg_temp_new();
1583            tcg_gen_shli_i32(tmp, cpu_sr_t, 31);
1584            tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1585            tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1586            tcg_gen_or_i32(REG(B11_8), REG(B11_8), tmp);
1587            tcg_temp_free(tmp);
1588        }
1589        return;
1590    case 0x4004:                /* rotl Rn */
1591        tcg_gen_rotli_i32(REG(B11_8), REG(B11_8), 1);
1592        tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 0);
1593        return;
1594    case 0x4005:                /* rotr Rn */
1595        tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 0);
1596        tcg_gen_rotri_i32(REG(B11_8), REG(B11_8), 1);
1597        return;
1598    case 0x4000:                /* shll Rn */
1599    case 0x4020:                /* shal Rn */
1600        tcg_gen_shri_i32(cpu_sr_t, REG(B11_8), 31);
1601        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1602        return;
1603    case 0x4021:                /* shar Rn */
1604        tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1605        tcg_gen_sari_i32(REG(B11_8), REG(B11_8), 1);
1606        return;
1607    case 0x4001:                /* shlr Rn */
1608        tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1609        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1610        return;
1611    case 0x4008:                /* shll2 Rn */
1612        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 2);
1613        return;
1614    case 0x4018:                /* shll8 Rn */
1615        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 8);
1616        return;
1617    case 0x4028:                /* shll16 Rn */
1618        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 16);
1619        return;
1620    case 0x4009:                /* shlr2 Rn */
1621        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 2);
1622        return;
1623    case 0x4019:                /* shlr8 Rn */
1624        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 8);
1625        return;
1626    case 0x4029:                /* shlr16 Rn */
1627        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16);
1628        return;
1629    case 0x401b:                /* tas.b @Rn */
1630        {
1631            TCGv addr, val;
1632            addr = tcg_temp_local_new();
1633            tcg_gen_mov_i32(addr, REG(B11_8));
1634            val = tcg_temp_local_new();
1635            tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1636            tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1637            tcg_gen_ori_i32(val, val, 0x80);
1638            tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1639            tcg_temp_free(val);
1640            tcg_temp_free(addr);
1641        }
1642        return;
1643    case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1644        CHECK_FPU_ENABLED
1645        tcg_gen_mov_i32(cpu_fregs[FREG(B11_8)], cpu_fpul);
1646        return;
1647    case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1648        CHECK_FPU_ENABLED
1649        tcg_gen_mov_i32(cpu_fpul, cpu_fregs[FREG(B11_8)]);
1650        return;
1651    case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1652        CHECK_FPU_ENABLED
1653        if (ctx->flags & FPSCR_PR) {
1654            TCGv_i64 fp;
1655            if (ctx->opcode & 0x0100)
1656                break; /* illegal instruction */
1657            fp = tcg_temp_new_i64();
1658            gen_helper_float_DT(fp, cpu_env, cpu_fpul);
1659            gen_store_fpr64(fp, DREG(B11_8));
1660            tcg_temp_free_i64(fp);
1661        }
1662        else {
1663            gen_helper_float_FT(cpu_fregs[FREG(B11_8)], cpu_env, cpu_fpul);
1664        }
1665        return;
1666    case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1667        CHECK_FPU_ENABLED
1668        if (ctx->flags & FPSCR_PR) {
1669            TCGv_i64 fp;
1670            if (ctx->opcode & 0x0100)
1671                break; /* illegal instruction */
1672            fp = tcg_temp_new_i64();
1673            gen_load_fpr64(fp, DREG(B11_8));
1674            gen_helper_ftrc_DT(cpu_fpul, cpu_env, fp);
1675            tcg_temp_free_i64(fp);
1676        }
1677        else {
1678            gen_helper_ftrc_FT(cpu_fpul, cpu_env, cpu_fregs[FREG(B11_8)]);
1679        }
1680        return;
1681    case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1682        CHECK_FPU_ENABLED
1683        {
1684            gen_helper_fneg_T(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
1685        }
1686        return;
1687    case 0xf05d: /* fabs FRn/DRn */
1688        CHECK_FPU_ENABLED
1689        if (ctx->flags & FPSCR_PR) {
1690            if (ctx->opcode & 0x0100)
1691                break; /* illegal instruction */
1692            TCGv_i64 fp = tcg_temp_new_i64();
1693            gen_load_fpr64(fp, DREG(B11_8));
1694            gen_helper_fabs_DT(fp, fp);
1695            gen_store_fpr64(fp, DREG(B11_8));
1696            tcg_temp_free_i64(fp);
1697        } else {
1698            gen_helper_fabs_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
1699        }
1700        return;
1701    case 0xf06d: /* fsqrt FRn */
1702        CHECK_FPU_ENABLED
1703        if (ctx->flags & FPSCR_PR) {
1704            if (ctx->opcode & 0x0100)
1705                break; /* illegal instruction */
1706            TCGv_i64 fp = tcg_temp_new_i64();
1707            gen_load_fpr64(fp, DREG(B11_8));
1708            gen_helper_fsqrt_DT(fp, cpu_env, fp);
1709            gen_store_fpr64(fp, DREG(B11_8));
1710            tcg_temp_free_i64(fp);
1711        } else {
1712            gen_helper_fsqrt_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1713                                cpu_fregs[FREG(B11_8)]);
1714        }
1715        return;
1716    case 0xf07d: /* fsrra FRn */
1717        CHECK_FPU_ENABLED
1718        break;
1719    case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1720        CHECK_FPU_ENABLED
1721        if (!(ctx->flags & FPSCR_PR)) {
1722            tcg_gen_movi_i32(cpu_fregs[FREG(B11_8)], 0);
1723        }
1724        return;
1725    case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1726        CHECK_FPU_ENABLED
1727        if (!(ctx->flags & FPSCR_PR)) {
1728            tcg_gen_movi_i32(cpu_fregs[FREG(B11_8)], 0x3f800000);
1729        }
1730        return;
1731    case 0xf0ad: /* fcnvsd FPUL,DRn */
1732        CHECK_FPU_ENABLED
1733        {
1734            TCGv_i64 fp = tcg_temp_new_i64();
1735            gen_helper_fcnvsd_FT_DT(fp, cpu_env, cpu_fpul);
1736            gen_store_fpr64(fp, DREG(B11_8));
1737            tcg_temp_free_i64(fp);
1738        }
1739        return;
1740    case 0xf0bd: /* fcnvds DRn,FPUL */
1741        CHECK_FPU_ENABLED
1742        {
1743            TCGv_i64 fp = tcg_temp_new_i64();
1744            gen_load_fpr64(fp, DREG(B11_8));
1745            gen_helper_fcnvds_DT_FT(cpu_fpul, cpu_env, fp);
1746            tcg_temp_free_i64(fp);
1747        }
1748        return;
1749    case 0xf0ed: /* fipr FVm,FVn */
1750        CHECK_FPU_ENABLED
1751        if ((ctx->flags & FPSCR_PR) == 0) {
1752            TCGv m, n;
1753            m = tcg_const_i32((ctx->opcode >> 8) & 3);
1754            n = tcg_const_i32((ctx->opcode >> 10) & 3);
1755            gen_helper_fipr(cpu_env, m, n);
1756            tcg_temp_free(m);
1757            tcg_temp_free(n);
1758            return;
1759        }
1760        break;
1761    case 0xf0fd: /* ftrv XMTRX,FVn */
1762        CHECK_FPU_ENABLED
1763        if ((ctx->opcode & 0x0300) == 0x0100 &&
1764            (ctx->flags & FPSCR_PR) == 0) {
1765            TCGv n;
1766            n = tcg_const_i32((ctx->opcode >> 10) & 3);
1767            gen_helper_ftrv(cpu_env, n);
1768            tcg_temp_free(n);
1769            return;
1770        }
1771        break;
1772    }
1773#if 0
1774    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1775            ctx->opcode, ctx->pc);
1776    fflush(stderr);
1777#endif
1778    tcg_gen_movi_i32(cpu_pc, ctx->pc);
1779    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1780        gen_helper_raise_slot_illegal_instruction(cpu_env);
1781    } else {
1782        gen_helper_raise_illegal_instruction(cpu_env);
1783    }
1784    ctx->bstate = BS_BRANCH;
1785}
1786
1787static void decode_opc(DisasContext * ctx)
1788{
1789    uint32_t old_flags = ctx->flags;
1790
1791    _decode_opc(ctx);
1792
1793    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1794        if (ctx->flags & DELAY_SLOT_CLEARME) {
1795            gen_store_flags(0);
1796        } else {
1797            /* go out of the delay slot */
1798            uint32_t new_flags = ctx->flags;
1799            new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1800            gen_store_flags(new_flags);
1801        }
1802        ctx->flags = 0;
1803        ctx->bstate = BS_BRANCH;
1804        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1805            gen_delayed_conditional_jump(ctx);
1806        } else if (old_flags & DELAY_SLOT) {
1807            gen_jump(ctx);
1808        }
1809
1810    }
1811
1812    /* go into a delay slot */
1813    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1814        gen_store_flags(ctx->flags);
1815}
1816
1817void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
1818{
1819    SuperHCPU *cpu = sh_env_get_cpu(env);
1820    CPUState *cs = CPU(cpu);
1821    DisasContext ctx;
1822    target_ulong pc_start;
1823    int num_insns;
1824    int max_insns;
1825
1826    pc_start = tb->pc;
1827    ctx.pc = pc_start;
1828    ctx.flags = (uint32_t)tb->flags;
1829    ctx.bstate = BS_NONE;
1830    ctx.memidx = (ctx.flags & (1u << SR_MD)) == 0 ? 1 : 0;
1831    /* We don't know if the delayed pc came from a dynamic or static branch,
1832       so assume it is a dynamic branch.  */
1833    ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1834    ctx.tb = tb;
1835    ctx.singlestep_enabled = cs->singlestep_enabled;
1836    ctx.features = env->features;
1837    ctx.has_movcal = (ctx.flags & TB_FLAG_PENDING_MOVCA);
1838
1839    num_insns = 0;
1840    max_insns = tb->cflags & CF_COUNT_MASK;
1841    if (max_insns == 0) {
1842        max_insns = CF_COUNT_MASK;
1843    }
1844    if (max_insns > TCG_MAX_INSNS) {
1845        max_insns = TCG_MAX_INSNS;
1846    }
1847
1848    gen_tb_start(tb);
1849    while (ctx.bstate == BS_NONE && !tcg_op_buf_full()) {
1850        tcg_gen_insn_start(ctx.pc, ctx.flags);
1851        num_insns++;
1852
1853        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
1854            /* We have hit a breakpoint - make sure PC is up-to-date */
1855            tcg_gen_movi_i32(cpu_pc, ctx.pc);
1856            gen_helper_debug(cpu_env);
1857            ctx.bstate = BS_BRANCH;
1858            /* The address covered by the breakpoint must be included in
1859               [tb->pc, tb->pc + tb->size) in order to for it to be
1860               properly cleared -- thus we increment the PC here so that
1861               the logic setting tb->size below does the right thing.  */
1862            ctx.pc += 2;
1863            break;
1864        }
1865
1866        if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
1867            gen_io_start();
1868        }
1869
1870        ctx.opcode = cpu_lduw_code(env, ctx.pc);
1871        decode_opc(&ctx);
1872        ctx.pc += 2;
1873        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1874            break;
1875        if (cs->singlestep_enabled) {
1876            break;
1877        }
1878        if (num_insns >= max_insns)
1879            break;
1880        if (singlestep)
1881            break;
1882    }
1883    if (tb->cflags & CF_LAST_IO)
1884        gen_io_end();
1885    if (cs->singlestep_enabled) {
1886        tcg_gen_movi_i32(cpu_pc, ctx.pc);
1887        gen_helper_debug(cpu_env);
1888    } else {
1889        switch (ctx.bstate) {
1890        case BS_STOP:
1891            /* gen_op_interrupt_restart(); */
1892            /* fall through */
1893        case BS_NONE:
1894            if (ctx.flags) {
1895                gen_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1896            }
1897            gen_goto_tb(&ctx, 0, ctx.pc);
1898            break;
1899        case BS_EXCP:
1900            /* gen_op_interrupt_restart(); */
1901            tcg_gen_exit_tb(0);
1902            break;
1903        case BS_BRANCH:
1904        default:
1905            break;
1906        }
1907    }
1908
1909    gen_tb_end(tb, num_insns);
1910
1911    tb->size = ctx.pc - pc_start;
1912    tb->icount = num_insns;
1913
1914#ifdef DEBUG_DISAS
1915    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1916        qemu_log("IN:\n");      /* , lookup_symbol(pc_start)); */
1917        log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
1918        qemu_log("\n");
1919    }
1920#endif
1921}
1922
1923void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb,
1924                          target_ulong *data)
1925{
1926    env->pc = data[0];
1927    env->flags = data[1];
1928}
1929