Annotation of qemu/target-sh4/translate.c, revision 1.1.1.8

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.