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

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
                     17:  * License along with this library; if not, write to the Free Software
                     18:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     19:  */
                     20: #include <stdarg.h>
                     21: #include <stdlib.h>
                     22: #include <stdio.h>
                     23: #include <string.h>
                     24: #include <inttypes.h>
                     25: #include <assert.h>
                     26: 
                     27: #define DEBUG_DISAS
                     28: #define SH4_DEBUG_DISAS
                     29: //#define SH4_SINGLE_STEP
                     30: 
                     31: #include "cpu.h"
                     32: #include "exec-all.h"
                     33: #include "disas.h"
                     34: 
                     35: enum {
                     36: #define DEF(s, n, copy_size) INDEX_op_ ## s,
                     37: #include "opc.h"
                     38: #undef DEF
                     39:     NB_OPS,
                     40: };
                     41: 
                     42: #ifdef USE_DIRECT_JUMP
                     43: #define TBPARAM(x)
                     44: #else
                     45: #define TBPARAM(x) ((long)(x))
                     46: #endif
                     47: 
                     48: static uint16_t *gen_opc_ptr;
                     49: static uint32_t *gen_opparam_ptr;
                     50: 
                     51: #include "gen-op.h"
                     52: 
                     53: typedef struct DisasContext {
                     54:     struct TranslationBlock *tb;
                     55:     target_ulong pc;
                     56:     uint32_t sr;
1.1.1.2   root       57:     uint32_t fpscr;
1.1       root       58:     uint16_t opcode;
                     59:     uint32_t flags;
1.1.1.3 ! root       60:     int bstate;
1.1       root       61:     int memidx;
                     62:     uint32_t delayed_pc;
                     63:     int singlestep_enabled;
                     64: } DisasContext;
                     65: 
1.1.1.3 ! root       66: enum {
        !            67:     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
        !            68:                       * exception condition
        !            69:                       */
        !            70:     BS_STOP     = 1, /* We want to stop translation for any reason */
        !            71:     BS_BRANCH   = 2, /* We reached a branch condition     */
        !            72:     BS_EXCP     = 3, /* We reached an exception condition */
        !            73: };
        !            74: 
1.1       root       75: #ifdef CONFIG_USER_ONLY
                     76: 
1.1.1.2   root       77: #define GEN_OP_LD(width, reg) \
                     78:   void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
                     79:     gen_op_ld##width##_T0_##reg##_raw(); \
1.1       root       80:   }
1.1.1.2   root       81: #define GEN_OP_ST(width, reg) \
                     82:   void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
                     83:     gen_op_st##width##_##reg##_T1_raw(); \
1.1       root       84:   }
                     85: 
                     86: #else
                     87: 
1.1.1.2   root       88: #define GEN_OP_LD(width, reg) \
                     89:   void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
                     90:     if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
                     91:     else gen_op_ld##width##_T0_##reg##_user();\
1.1       root       92:   }
1.1.1.2   root       93: #define GEN_OP_ST(width, reg) \
                     94:   void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
                     95:     if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
                     96:     else gen_op_st##width##_##reg##_T1_user();\
1.1       root       97:   }
                     98: 
                     99: #endif
                    100: 
1.1.1.2   root      101: GEN_OP_LD(ub, T0)
                    102: GEN_OP_LD(b, T0)
                    103: GEN_OP_ST(b, T0)
                    104: GEN_OP_LD(uw, T0)
                    105: GEN_OP_LD(w, T0)
                    106: GEN_OP_ST(w, T0)
                    107: GEN_OP_LD(l, T0)
                    108: GEN_OP_ST(l, T0)
                    109: GEN_OP_LD(fl, FT0)
                    110: GEN_OP_ST(fl, FT0)
                    111: GEN_OP_LD(fq, DT0)
                    112: GEN_OP_ST(fq, DT0)
1.1       root      113: 
                    114: void cpu_dump_state(CPUState * env, FILE * f,
                    115:                    int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
                    116:                    int flags)
                    117: {
                    118:     int i;
1.1.1.2   root      119:     cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
                    120:                env->pc, env->sr, env->pr, env->fpscr);
1.1       root      121:     for (i = 0; i < 24; i += 4) {
                    122:        cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
                    123:                    i, env->gregs[i], i + 1, env->gregs[i + 1],
                    124:                    i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
                    125:     }
                    126:     if (env->flags & DELAY_SLOT) {
                    127:        cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
                    128:                    env->delayed_pc);
                    129:     } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
                    130:        cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
                    131:                    env->delayed_pc);
                    132:     }
                    133: }
                    134: 
                    135: void cpu_sh4_reset(CPUSH4State * env)
                    136: {
1.1.1.2   root      137: #if defined(CONFIG_USER_ONLY)
1.1.1.3 ! root      138:     env->sr = SR_FD;            /* FD - kernel does lazy fpu context switch */
1.1.1.2   root      139: #else
1.1       root      140:     env->sr = 0x700000F0;      /* MD, RB, BL, I3-I0 */
1.1.1.2   root      141: #endif
1.1       root      142:     env->vbr = 0;
                    143:     env->pc = 0xA0000000;
1.1.1.3 ! root      144: #if defined(CONFIG_USER_ONLY)
        !           145:     env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
        !           146:     set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
        !           147: #else
        !           148:     env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
        !           149:     set_float_rounding_mode(float_round_to_zero, &env->fp_status);
        !           150: #endif
1.1       root      151:     env->mmucr = 0;
                    152: }
                    153: 
1.1.1.3 ! root      154: CPUSH4State *cpu_sh4_init(const char *cpu_model)
1.1       root      155: {
                    156:     CPUSH4State *env;
                    157: 
                    158:     env = qemu_mallocz(sizeof(CPUSH4State));
                    159:     if (!env)
                    160:        return NULL;
                    161:     cpu_exec_init(env);
                    162:     cpu_sh4_reset(env);
                    163:     tlb_flush(env, 1);
                    164:     return env;
                    165: }
                    166: 
                    167: static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
                    168: {
                    169:     TranslationBlock *tb;
                    170:     tb = ctx->tb;
                    171: 
                    172:     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
                    173:        !ctx->singlestep_enabled) {
                    174:        /* Use a direct jump if in same page and singlestep not enabled */
                    175:        if (n == 0)
                    176:            gen_op_goto_tb0(TBPARAM(tb));
                    177:        else
                    178:            gen_op_goto_tb1(TBPARAM(tb));
                    179:        gen_op_movl_imm_T0((long) tb + n);
                    180:     } else {
                    181:        gen_op_movl_imm_T0(0);
                    182:     }
                    183:     gen_op_movl_imm_PC(dest);
                    184:     if (ctx->singlestep_enabled)
                    185:        gen_op_debug();
                    186:     gen_op_exit_tb();
                    187: }
                    188: 
                    189: static void gen_jump(DisasContext * ctx)
                    190: {
                    191:     if (ctx->delayed_pc == (uint32_t) - 1) {
                    192:        /* Target is not statically known, it comes necessarily from a
                    193:           delayed jump as immediate jump are conditinal jumps */
                    194:        gen_op_movl_delayed_pc_PC();
                    195:        gen_op_movl_imm_T0(0);
                    196:        if (ctx->singlestep_enabled)
                    197:            gen_op_debug();
                    198:        gen_op_exit_tb();
                    199:     } else {
                    200:        gen_goto_tb(ctx, 0, ctx->delayed_pc);
                    201:     }
                    202: }
                    203: 
                    204: /* Immediate conditional jump (bt or bf) */
                    205: static void gen_conditional_jump(DisasContext * ctx,
                    206:                                 target_ulong ift, target_ulong ifnott)
                    207: {
                    208:     int l1;
                    209: 
                    210:     l1 = gen_new_label();
                    211:     gen_op_jT(l1);
                    212:     gen_goto_tb(ctx, 0, ifnott);
                    213:     gen_set_label(l1);
                    214:     gen_goto_tb(ctx, 1, ift);
                    215: }
                    216: 
                    217: /* Delayed conditional jump (bt or bf) */
                    218: static void gen_delayed_conditional_jump(DisasContext * ctx)
                    219: {
                    220:     int l1;
                    221: 
                    222:     l1 = gen_new_label();
1.1.1.2   root      223:     gen_op_jdelayed(l1);
1.1.1.3 ! root      224:     gen_goto_tb(ctx, 1, ctx->pc + 2);
1.1       root      225:     gen_set_label(l1);
1.1.1.2   root      226:     gen_jump(ctx);
1.1       root      227: }
                    228: 
                    229: #define B3_0 (ctx->opcode & 0xf)
                    230: #define B6_4 ((ctx->opcode >> 4) & 0x7)
                    231: #define B7_4 ((ctx->opcode >> 4) & 0xf)
                    232: #define B7_0 (ctx->opcode & 0xff)
                    233: #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
                    234: #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
                    235:   (ctx->opcode & 0xfff))
                    236: #define B11_8 ((ctx->opcode >> 8) & 0xf)
                    237: #define B15_12 ((ctx->opcode >> 12) & 0xf)
                    238: 
                    239: #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
                    240:                (x) + 16 : (x))
                    241: 
                    242: #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
                    243:                ? (x) + 16 : (x))
                    244: 
1.1.1.2   root      245: #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
1.1.1.3 ! root      246: #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
1.1.1.2   root      247: #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
1.1.1.3 ! root      248: #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
1.1.1.2   root      249: 
1.1       root      250: #define CHECK_NOT_DELAY_SLOT \
                    251:   if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
1.1.1.3 ! root      252:   {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
1.1       root      253:    return;}
                    254: 
1.1.1.3 ! root      255: void _decode_opc(DisasContext * ctx)
1.1       root      256: {
                    257: #if 0
                    258:     fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
                    259: #endif
                    260:     switch (ctx->opcode) {
                    261:     case 0x0019:               /* div0u */
                    262:        gen_op_div0u();
                    263:        return;
                    264:     case 0x000b:               /* rts */
                    265:        CHECK_NOT_DELAY_SLOT gen_op_rts();
                    266:        ctx->flags |= DELAY_SLOT;
                    267:        ctx->delayed_pc = (uint32_t) - 1;
                    268:        return;
                    269:     case 0x0028:               /* clrmac */
                    270:        gen_op_clrmac();
                    271:        return;
                    272:     case 0x0048:               /* clrs */
                    273:        gen_op_clrs();
                    274:        return;
                    275:     case 0x0008:               /* clrt */
                    276:        gen_op_clrt();
                    277:        return;
                    278:     case 0x0038:               /* ldtlb */
                    279:        assert(0);              /* XXXXX */
                    280:        return;
1.1.1.3 ! root      281:     case 0x002b:               /* rte */
1.1       root      282:        CHECK_NOT_DELAY_SLOT gen_op_rte();
                    283:        ctx->flags |= DELAY_SLOT;
                    284:        ctx->delayed_pc = (uint32_t) - 1;
                    285:        return;
                    286:     case 0x0058:               /* sets */
                    287:        gen_op_sets();
                    288:        return;
                    289:     case 0x0018:               /* sett */
                    290:        gen_op_sett();
                    291:        return;
                    292:     case 0xfbfb:               /* frchg */
1.1.1.2   root      293:        gen_op_frchg();
1.1.1.3 ! root      294:        ctx->bstate = BS_STOP;
1.1       root      295:        return;
                    296:     case 0xf3fb:               /* fschg */
1.1.1.2   root      297:        gen_op_fschg();
1.1.1.3 ! root      298:        ctx->bstate = BS_STOP;
1.1       root      299:        return;
                    300:     case 0x0009:               /* nop */
                    301:        return;
                    302:     case 0x001b:               /* sleep */
                    303:        assert(0);              /* XXXXX */
                    304:        return;
                    305:     }
                    306: 
                    307:     switch (ctx->opcode & 0xf000) {
                    308:     case 0x1000:               /* mov.l Rm,@(disp,Rn) */
                    309:        gen_op_movl_rN_T0(REG(B7_4));
                    310:        gen_op_movl_rN_T1(REG(B11_8));
                    311:        gen_op_addl_imm_T1(B3_0 * 4);
                    312:        gen_op_stl_T0_T1(ctx);
                    313:        return;
                    314:     case 0x5000:               /* mov.l @(disp,Rm),Rn */
                    315:        gen_op_movl_rN_T0(REG(B7_4));
                    316:        gen_op_addl_imm_T0(B3_0 * 4);
                    317:        gen_op_ldl_T0_T0(ctx);
                    318:        gen_op_movl_T0_rN(REG(B11_8));
                    319:        return;
                    320:     case 0xe000:               /* mov.l #imm,Rn */
                    321:        gen_op_movl_imm_rN(B7_0s, REG(B11_8));
                    322:        return;
                    323:     case 0x9000:               /* mov.w @(disp,PC),Rn */
                    324:        gen_op_movl_imm_T0(ctx->pc + 4 + B7_0 * 2);
                    325:        gen_op_ldw_T0_T0(ctx);
                    326:        gen_op_movl_T0_rN(REG(B11_8));
                    327:        return;
                    328:     case 0xd000:               /* mov.l @(disp,PC),Rn */
                    329:        gen_op_movl_imm_T0((ctx->pc + 4 + B7_0 * 4) & ~3);
                    330:        gen_op_ldl_T0_T0(ctx);
                    331:        gen_op_movl_T0_rN(REG(B11_8));
                    332:        return;
                    333:     case 0x7000:               /* add.l #imm,Rn */
                    334:        gen_op_add_imm_rN(B7_0s, REG(B11_8));
                    335:        return;
                    336:     case 0xa000:               /* bra disp */
                    337:        CHECK_NOT_DELAY_SLOT
                    338:            gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
                    339:        ctx->flags |= DELAY_SLOT;
                    340:        return;
                    341:     case 0xb000:               /* bsr disp */
                    342:        CHECK_NOT_DELAY_SLOT
                    343:            gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
                    344:                       ctx->pc + 4 + B11_0s * 2);
                    345:        ctx->flags |= DELAY_SLOT;
                    346:        return;
                    347:     }
                    348: 
                    349:     switch (ctx->opcode & 0xf00f) {
                    350:     case 0x6003:               /* mov Rm,Rn */
                    351:        gen_op_movl_rN_T0(REG(B7_4));
                    352:        gen_op_movl_T0_rN(REG(B11_8));
                    353:        return;
                    354:     case 0x2000:               /* mov.b Rm,@Rn */
                    355:        gen_op_movl_rN_T0(REG(B7_4));
                    356:        gen_op_movl_rN_T1(REG(B11_8));
                    357:        gen_op_stb_T0_T1(ctx);
                    358:        return;
                    359:     case 0x2001:               /* mov.w Rm,@Rn */
                    360:        gen_op_movl_rN_T0(REG(B7_4));
                    361:        gen_op_movl_rN_T1(REG(B11_8));
                    362:        gen_op_stw_T0_T1(ctx);
                    363:        return;
                    364:     case 0x2002:               /* mov.l Rm,@Rn */
                    365:        gen_op_movl_rN_T0(REG(B7_4));
                    366:        gen_op_movl_rN_T1(REG(B11_8));
                    367:        gen_op_stl_T0_T1(ctx);
                    368:        return;
                    369:     case 0x6000:               /* mov.b @Rm,Rn */
                    370:        gen_op_movl_rN_T0(REG(B7_4));
                    371:        gen_op_ldb_T0_T0(ctx);
                    372:        gen_op_movl_T0_rN(REG(B11_8));
                    373:        return;
                    374:     case 0x6001:               /* mov.w @Rm,Rn */
                    375:        gen_op_movl_rN_T0(REG(B7_4));
                    376:        gen_op_ldw_T0_T0(ctx);
                    377:        gen_op_movl_T0_rN(REG(B11_8));
                    378:        return;
                    379:     case 0x6002:               /* mov.l @Rm,Rn */
                    380:        gen_op_movl_rN_T0(REG(B7_4));
                    381:        gen_op_ldl_T0_T0(ctx);
                    382:        gen_op_movl_T0_rN(REG(B11_8));
                    383:        return;
                    384:     case 0x2004:               /* mov.b Rm,@-Rn */
                    385:        gen_op_dec1_rN(REG(B11_8));
                    386:        gen_op_movl_rN_T0(REG(B7_4));
                    387:        gen_op_movl_rN_T1(REG(B11_8));
                    388:        gen_op_stb_T0_T1(ctx);
                    389:        return;
                    390:     case 0x2005:               /* mov.w Rm,@-Rn */
                    391:        gen_op_dec2_rN(REG(B11_8));
                    392:        gen_op_movl_rN_T0(REG(B7_4));
                    393:        gen_op_movl_rN_T1(REG(B11_8));
                    394:        gen_op_stw_T0_T1(ctx);
                    395:        return;
                    396:     case 0x2006:               /* mov.l Rm,@-Rn */
                    397:        gen_op_dec4_rN(REG(B11_8));
                    398:        gen_op_movl_rN_T0(REG(B7_4));
                    399:        gen_op_movl_rN_T1(REG(B11_8));
                    400:        gen_op_stl_T0_T1(ctx);
                    401:        return;
1.1.1.2   root      402:     case 0x6004:               /* mov.b @Rm+,Rn */
1.1       root      403:        gen_op_movl_rN_T0(REG(B7_4));
                    404:        gen_op_ldb_T0_T0(ctx);
                    405:        gen_op_movl_T0_rN(REG(B11_8));
                    406:        gen_op_inc1_rN(REG(B7_4));
                    407:        return;
                    408:     case 0x6005:               /* mov.w @Rm+,Rn */
                    409:        gen_op_movl_rN_T0(REG(B7_4));
                    410:        gen_op_ldw_T0_T0(ctx);
                    411:        gen_op_movl_T0_rN(REG(B11_8));
                    412:        gen_op_inc2_rN(REG(B7_4));
                    413:        return;
                    414:     case 0x6006:               /* mov.l @Rm+,Rn */
                    415:        gen_op_movl_rN_T0(REG(B7_4));
                    416:        gen_op_ldl_T0_T0(ctx);
                    417:        gen_op_movl_T0_rN(REG(B11_8));
                    418:        gen_op_inc4_rN(REG(B7_4));
                    419:        return;
                    420:     case 0x0004:               /* mov.b Rm,@(R0,Rn) */
                    421:        gen_op_movl_rN_T0(REG(B7_4));
                    422:        gen_op_movl_rN_T1(REG(B11_8));
                    423:        gen_op_add_rN_T1(REG(0));
                    424:        gen_op_stb_T0_T1(ctx);
                    425:        return;
                    426:     case 0x0005:               /* mov.w Rm,@(R0,Rn) */
                    427:        gen_op_movl_rN_T0(REG(B7_4));
                    428:        gen_op_movl_rN_T1(REG(B11_8));
                    429:        gen_op_add_rN_T1(REG(0));
                    430:        gen_op_stw_T0_T1(ctx);
                    431:        return;
                    432:     case 0x0006:               /* mov.l Rm,@(R0,Rn) */
                    433:        gen_op_movl_rN_T0(REG(B7_4));
                    434:        gen_op_movl_rN_T1(REG(B11_8));
                    435:        gen_op_add_rN_T1(REG(0));
                    436:        gen_op_stl_T0_T1(ctx);
                    437:        return;
                    438:     case 0x000c:               /* mov.b @(R0,Rm),Rn */
                    439:        gen_op_movl_rN_T0(REG(B7_4));
                    440:        gen_op_add_rN_T0(REG(0));
                    441:        gen_op_ldb_T0_T0(ctx);
                    442:        gen_op_movl_T0_rN(REG(B11_8));
                    443:        return;
                    444:     case 0x000d:               /* mov.w @(R0,Rm),Rn */
                    445:        gen_op_movl_rN_T0(REG(B7_4));
                    446:        gen_op_add_rN_T0(REG(0));
                    447:        gen_op_ldw_T0_T0(ctx);
                    448:        gen_op_movl_T0_rN(REG(B11_8));
                    449:        return;
                    450:     case 0x000e:               /* mov.l @(R0,Rm),Rn */
                    451:        gen_op_movl_rN_T0(REG(B7_4));
                    452:        gen_op_add_rN_T0(REG(0));
                    453:        gen_op_ldl_T0_T0(ctx);
                    454:        gen_op_movl_T0_rN(REG(B11_8));
                    455:        return;
                    456:     case 0x6008:               /* swap.b Rm,Rn */
                    457:        gen_op_movl_rN_T0(REG(B7_4));
                    458:        gen_op_swapb_T0();
                    459:        gen_op_movl_T0_rN(REG(B11_8));
                    460:        return;
                    461:     case 0x6009:               /* swap.w Rm,Rn */
                    462:        gen_op_movl_rN_T0(REG(B7_4));
                    463:        gen_op_swapw_T0();
                    464:        gen_op_movl_T0_rN(REG(B11_8));
                    465:        return;
                    466:     case 0x200d:               /* xtrct Rm,Rn */
                    467:        gen_op_movl_rN_T0(REG(B7_4));
                    468:        gen_op_movl_rN_T1(REG(B11_8));
                    469:        gen_op_xtrct_T0_T1();
                    470:        gen_op_movl_T1_rN(REG(B11_8));
                    471:        return;
                    472:     case 0x300c:               /* add Rm,Rn */
                    473:        gen_op_movl_rN_T0(REG(B7_4));
                    474:        gen_op_add_T0_rN(REG(B11_8));
                    475:        return;
                    476:     case 0x300e:               /* addc Rm,Rn */
                    477:        gen_op_movl_rN_T0(REG(B7_4));
                    478:        gen_op_movl_rN_T1(REG(B11_8));
                    479:        gen_op_addc_T0_T1();
                    480:        gen_op_movl_T1_rN(REG(B11_8));
                    481:        return;
                    482:     case 0x300f:               /* addv Rm,Rn */
                    483:        gen_op_movl_rN_T0(REG(B7_4));
                    484:        gen_op_movl_rN_T1(REG(B11_8));
                    485:        gen_op_addv_T0_T1();
                    486:        gen_op_movl_T1_rN(REG(B11_8));
                    487:        return;
                    488:     case 0x2009:               /* and Rm,Rn */
                    489:        gen_op_movl_rN_T0(REG(B7_4));
                    490:        gen_op_and_T0_rN(REG(B11_8));
                    491:        return;
                    492:     case 0x3000:               /* cmp/eq Rm,Rn */
                    493:        gen_op_movl_rN_T0(REG(B7_4));
                    494:        gen_op_movl_rN_T1(REG(B11_8));
                    495:        gen_op_cmp_eq_T0_T1();
                    496:        return;
                    497:     case 0x3003:               /* cmp/ge Rm,Rn */
                    498:        gen_op_movl_rN_T0(REG(B7_4));
                    499:        gen_op_movl_rN_T1(REG(B11_8));
                    500:        gen_op_cmp_ge_T0_T1();
                    501:        return;
                    502:     case 0x3007:               /* cmp/gt Rm,Rn */
                    503:        gen_op_movl_rN_T0(REG(B7_4));
                    504:        gen_op_movl_rN_T1(REG(B11_8));
                    505:        gen_op_cmp_gt_T0_T1();
                    506:        return;
                    507:     case 0x3006:               /* cmp/hi Rm,Rn */
                    508:        gen_op_movl_rN_T0(REG(B7_4));
                    509:        gen_op_movl_rN_T1(REG(B11_8));
                    510:        gen_op_cmp_hi_T0_T1();
                    511:        return;
                    512:     case 0x3002:               /* cmp/hs Rm,Rn */
                    513:        gen_op_movl_rN_T0(REG(B7_4));
                    514:        gen_op_movl_rN_T1(REG(B11_8));
                    515:        gen_op_cmp_hs_T0_T1();
                    516:        return;
                    517:     case 0x200c:               /* cmp/str Rm,Rn */
                    518:        gen_op_movl_rN_T0(REG(B7_4));
                    519:        gen_op_movl_rN_T1(REG(B11_8));
                    520:        gen_op_cmp_str_T0_T1();
                    521:        return;
                    522:     case 0x2007:               /* div0s Rm,Rn */
                    523:        gen_op_movl_rN_T0(REG(B7_4));
                    524:        gen_op_movl_rN_T1(REG(B11_8));
                    525:        gen_op_div0s_T0_T1();
                    526:        gen_op_movl_T1_rN(REG(B11_8));
                    527:        return;
                    528:     case 0x3004:               /* div1 Rm,Rn */
                    529:        gen_op_movl_rN_T0(REG(B7_4));
                    530:        gen_op_movl_rN_T1(REG(B11_8));
                    531:        gen_op_div1_T0_T1();
                    532:        gen_op_movl_T1_rN(REG(B11_8));
                    533:        return;
                    534:     case 0x300d:               /* dmuls.l Rm,Rn */
                    535:        gen_op_movl_rN_T0(REG(B7_4));
                    536:        gen_op_movl_rN_T1(REG(B11_8));
                    537:        gen_op_dmulsl_T0_T1();
                    538:        return;
                    539:     case 0x3005:               /* dmulu.l Rm,Rn */
                    540:        gen_op_movl_rN_T0(REG(B7_4));
                    541:        gen_op_movl_rN_T1(REG(B11_8));
                    542:        gen_op_dmulul_T0_T1();
                    543:        return;
                    544:     case 0x600e:               /* exts.b Rm,Rn */
                    545:        gen_op_movb_rN_T0(REG(B7_4));
                    546:        gen_op_movl_T0_rN(REG(B11_8));
                    547:        return;
                    548:     case 0x600f:               /* exts.w Rm,Rn */
                    549:        gen_op_movw_rN_T0(REG(B7_4));
                    550:        gen_op_movl_T0_rN(REG(B11_8));
                    551:        return;
                    552:     case 0x600c:               /* extu.b Rm,Rn */
                    553:        gen_op_movub_rN_T0(REG(B7_4));
                    554:        gen_op_movl_T0_rN(REG(B11_8));
                    555:        return;
                    556:     case 0x600d:               /* extu.w Rm,Rn */
                    557:        gen_op_movuw_rN_T0(REG(B7_4));
                    558:        gen_op_movl_T0_rN(REG(B11_8));
                    559:        return;
                    560:     case 0x000f:               /* mac.l @Rm+,@Rn- */
                    561:        gen_op_movl_rN_T0(REG(B11_8));
                    562:        gen_op_ldl_T0_T0(ctx);
                    563:        gen_op_movl_T0_T1();
                    564:        gen_op_movl_rN_T1(REG(B7_4));
                    565:        gen_op_ldl_T0_T0(ctx);
                    566:        gen_op_macl_T0_T1();
                    567:        gen_op_inc4_rN(REG(B7_4));
                    568:        gen_op_inc4_rN(REG(B11_8));
                    569:        return;
                    570:     case 0x400f:               /* mac.w @Rm+,@Rn+ */
                    571:        gen_op_movl_rN_T0(REG(B11_8));
                    572:        gen_op_ldl_T0_T0(ctx);
                    573:        gen_op_movl_T0_T1();
                    574:        gen_op_movl_rN_T1(REG(B7_4));
                    575:        gen_op_ldl_T0_T0(ctx);
                    576:        gen_op_macw_T0_T1();
                    577:        gen_op_inc2_rN(REG(B7_4));
                    578:        gen_op_inc2_rN(REG(B11_8));
                    579:        return;
                    580:     case 0x0007:               /* mul.l Rm,Rn */
                    581:        gen_op_movl_rN_T0(REG(B7_4));
                    582:        gen_op_movl_rN_T1(REG(B11_8));
                    583:        gen_op_mull_T0_T1();
                    584:        return;
                    585:     case 0x200f:               /* muls.w Rm,Rn */
                    586:        gen_op_movw_rN_T0(REG(B7_4));
                    587:        gen_op_movw_rN_T1(REG(B11_8));
                    588:        gen_op_mulsw_T0_T1();
                    589:        return;
                    590:     case 0x200e:               /* mulu.w Rm,Rn */
                    591:        gen_op_movuw_rN_T0(REG(B7_4));
                    592:        gen_op_movuw_rN_T1(REG(B11_8));
                    593:        gen_op_muluw_T0_T1();
                    594:        return;
                    595:     case 0x600b:               /* neg Rm,Rn */
                    596:        gen_op_movl_rN_T0(REG(B7_4));
                    597:        gen_op_neg_T0();
                    598:        gen_op_movl_T0_rN(REG(B11_8));
                    599:        return;
                    600:     case 0x600a:               /* negc Rm,Rn */
                    601:        gen_op_movl_rN_T0(REG(B7_4));
                    602:        gen_op_negc_T0();
                    603:        gen_op_movl_T0_rN(REG(B11_8));
                    604:        return;
                    605:     case 0x6007:               /* not Rm,Rn */
                    606:        gen_op_movl_rN_T0(REG(B7_4));
                    607:        gen_op_not_T0();
                    608:        gen_op_movl_T0_rN(REG(B11_8));
                    609:        return;
                    610:     case 0x200b:               /* or Rm,Rn */
                    611:        gen_op_movl_rN_T0(REG(B7_4));
                    612:        gen_op_or_T0_rN(REG(B11_8));
                    613:        return;
                    614:     case 0x400c:               /* shad Rm,Rn */
                    615:        gen_op_movl_rN_T0(REG(B7_4));
                    616:        gen_op_movl_rN_T1(REG(B11_8));
                    617:        gen_op_shad_T0_T1();
                    618:        gen_op_movl_T1_rN(REG(B11_8));
                    619:        return;
                    620:     case 0x400d:               /* shld Rm,Rn */
                    621:        gen_op_movl_rN_T0(REG(B7_4));
                    622:        gen_op_movl_rN_T1(REG(B11_8));
                    623:        gen_op_shld_T0_T1();
                    624:        gen_op_movl_T1_rN(REG(B11_8));
                    625:        return;
                    626:     case 0x3008:               /* sub Rm,Rn */
                    627:        gen_op_movl_rN_T0(REG(B7_4));
                    628:        gen_op_sub_T0_rN(REG(B11_8));
                    629:        return;
                    630:     case 0x300a:               /* subc Rm,Rn */
                    631:        gen_op_movl_rN_T0(REG(B7_4));
                    632:        gen_op_movl_rN_T1(REG(B11_8));
                    633:        gen_op_subc_T0_T1();
                    634:        gen_op_movl_T1_rN(REG(B11_8));
                    635:        return;
                    636:     case 0x300b:               /* subv Rm,Rn */
                    637:        gen_op_movl_rN_T0(REG(B7_4));
                    638:        gen_op_movl_rN_T1(REG(B11_8));
                    639:        gen_op_subv_T0_T1();
                    640:        gen_op_movl_T1_rN(REG(B11_8));
                    641:        return;
                    642:     case 0x2008:               /* tst Rm,Rn */
                    643:        gen_op_movl_rN_T0(REG(B7_4));
                    644:        gen_op_movl_rN_T1(REG(B11_8));
                    645:        gen_op_tst_T0_T1();
                    646:        return;
                    647:     case 0x200a:               /* xor Rm,Rn */
                    648:        gen_op_movl_rN_T0(REG(B7_4));
                    649:        gen_op_xor_T0_rN(REG(B11_8));
                    650:        return;
1.1.1.3 ! root      651:     case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
        !           652:        if (ctx->fpscr & FPSCR_SZ) {
1.1.1.2   root      653:            if (ctx->opcode & 0x0110)
                    654:                break; /* illegal instruction */
1.1.1.3 ! root      655:            gen_op_fmov_drN_DT0(DREG(B7_4));
        !           656:            gen_op_fmov_DT0_drN(DREG(B11_8));
1.1.1.2   root      657:        } else {
                    658:            gen_op_fmov_frN_FT0(FREG(B7_4));
                    659:            gen_op_fmov_FT0_frN(FREG(B11_8));
                    660:        }
                    661:        return;
1.1.1.3 ! root      662:     case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
        !           663:        if (ctx->fpscr & FPSCR_SZ) {
1.1.1.2   root      664:            if (ctx->opcode & 0x0010)
                    665:                break; /* illegal instruction */
1.1.1.3 ! root      666:            gen_op_fmov_drN_DT0(DREG(B7_4));
1.1.1.2   root      667:            gen_op_movl_rN_T1(REG(B11_8));
                    668:            gen_op_stfq_DT0_T1(ctx);
                    669:        } else {
                    670:            gen_op_fmov_frN_FT0(FREG(B7_4));
                    671:            gen_op_movl_rN_T1(REG(B11_8));
                    672:            gen_op_stfl_FT0_T1(ctx);
                    673:        }
                    674:        return;
1.1.1.3 ! root      675:     case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
        !           676:        if (ctx->fpscr & FPSCR_SZ) {
1.1.1.2   root      677:            if (ctx->opcode & 0x0100)
                    678:                break; /* illegal instruction */
                    679:            gen_op_movl_rN_T0(REG(B7_4));
                    680:            gen_op_ldfq_T0_DT0(ctx);
1.1.1.3 ! root      681:            gen_op_fmov_DT0_drN(DREG(B11_8));
1.1.1.2   root      682:        } else {
                    683:            gen_op_movl_rN_T0(REG(B7_4));
                    684:            gen_op_ldfl_T0_FT0(ctx);
1.1.1.3 ! root      685:            gen_op_fmov_FT0_frN(FREG(B11_8));
1.1.1.2   root      686:        }
                    687:        return;
1.1.1.3 ! root      688:     case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
        !           689:        if (ctx->fpscr & FPSCR_SZ) {
1.1.1.2   root      690:            if (ctx->opcode & 0x0100)
                    691:                break; /* illegal instruction */
                    692:            gen_op_movl_rN_T0(REG(B7_4));
                    693:            gen_op_ldfq_T0_DT0(ctx);
1.1.1.3 ! root      694:            gen_op_fmov_DT0_drN(DREG(B11_8));
1.1.1.2   root      695:            gen_op_inc8_rN(REG(B7_4));
                    696:        } else {
                    697:            gen_op_movl_rN_T0(REG(B7_4));
                    698:            gen_op_ldfl_T0_FT0(ctx);
1.1.1.3 ! root      699:            gen_op_fmov_FT0_frN(FREG(B11_8));
1.1.1.2   root      700:            gen_op_inc4_rN(REG(B7_4));
                    701:        }
                    702:        return;
1.1.1.3 ! root      703:     case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
        !           704:        if (ctx->fpscr & FPSCR_SZ) {
1.1.1.2   root      705:            if (ctx->opcode & 0x0100)
                    706:                break; /* illegal instruction */
                    707:            gen_op_dec8_rN(REG(B11_8));
1.1.1.3 ! root      708:            gen_op_fmov_drN_DT0(DREG(B7_4));
1.1.1.2   root      709:            gen_op_movl_rN_T1(REG(B11_8));
                    710:            gen_op_stfq_DT0_T1(ctx);
                    711:        } else {
                    712:            gen_op_dec4_rN(REG(B11_8));
                    713:            gen_op_fmov_frN_FT0(FREG(B7_4));
                    714:            gen_op_movl_rN_T1(REG(B11_8));
                    715:            gen_op_stfl_FT0_T1(ctx);
                    716:        }
                    717:        return;
1.1.1.3 ! root      718:     case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
        !           719:        if (ctx->fpscr & FPSCR_SZ) {
1.1.1.2   root      720:            if (ctx->opcode & 0x0100)
                    721:                break; /* illegal instruction */
                    722:            gen_op_movl_rN_T0(REG(B7_4));
                    723:            gen_op_add_rN_T0(REG(0));
                    724:            gen_op_ldfq_T0_DT0(ctx);
1.1.1.3 ! root      725:            gen_op_fmov_DT0_drN(DREG(B11_8));
1.1.1.2   root      726:        } else {
                    727:            gen_op_movl_rN_T0(REG(B7_4));
                    728:            gen_op_add_rN_T0(REG(0));
                    729:            gen_op_ldfl_T0_FT0(ctx);
1.1.1.3 ! root      730:            gen_op_fmov_FT0_frN(FREG(B11_8));
1.1.1.2   root      731:        }
                    732:        return;
1.1.1.3 ! root      733:     case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
        !           734:        if (ctx->fpscr & FPSCR_SZ) {
1.1.1.2   root      735:            if (ctx->opcode & 0x0010)
                    736:                break; /* illegal instruction */
1.1.1.3 ! root      737:            gen_op_fmov_drN_DT0(DREG(B7_4));
1.1.1.2   root      738:            gen_op_movl_rN_T1(REG(B11_8));
                    739:            gen_op_add_rN_T1(REG(0));
                    740:            gen_op_stfq_DT0_T1(ctx);
                    741:        } else {
                    742:            gen_op_fmov_frN_FT0(FREG(B7_4));
                    743:            gen_op_movl_rN_T1(REG(B11_8));
                    744:            gen_op_add_rN_T1(REG(0));
                    745:            gen_op_stfl_FT0_T1(ctx);
                    746:        }
                    747:        return;
1.1.1.3 ! root      748:     case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
        !           749:     case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
        !           750:     case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
        !           751:     case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
        !           752:     case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
        !           753:     case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
        !           754:        if (ctx->fpscr & FPSCR_PR) {
        !           755:            if (ctx->opcode & 0x0110)
        !           756:                break; /* illegal instruction */
        !           757:            gen_op_fmov_drN_DT1(DREG(B7_4));
        !           758:            gen_op_fmov_drN_DT0(DREG(B11_8));
        !           759:        }
        !           760:        else {
        !           761:            gen_op_fmov_frN_FT1(FREG(B7_4));
        !           762:            gen_op_fmov_frN_FT0(FREG(B11_8));
        !           763:        }
        !           764: 
        !           765:        switch (ctx->opcode & 0xf00f) {
        !           766:        case 0xf000:            /* fadd Rm,Rn */
        !           767:            ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
        !           768:            break;
        !           769:        case 0xf001:            /* fsub Rm,Rn */
        !           770:            ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
        !           771:            break;
        !           772:        case 0xf002:            /* fmul Rm,Rn */
        !           773:            ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
        !           774:            break;
        !           775:        case 0xf003:            /* fdiv Rm,Rn */
        !           776:            ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
        !           777:            break;
        !           778:        case 0xf004:            /* fcmp/eq Rm,Rn */
        !           779:            return;
        !           780:        case 0xf005:            /* fcmp/gt Rm,Rn */
        !           781:            return;
        !           782:        }
        !           783: 
        !           784:        if (ctx->fpscr & FPSCR_PR) {
        !           785:            gen_op_fmov_DT0_drN(DREG(B11_8));
        !           786:        }
        !           787:        else {
        !           788:            gen_op_fmov_FT0_frN(FREG(B11_8));
        !           789:        }
        !           790:        return;
1.1       root      791:     }
                    792: 
                    793:     switch (ctx->opcode & 0xff00) {
                    794:     case 0xc900:               /* and #imm,R0 */
                    795:        gen_op_and_imm_rN(B7_0, REG(0));
                    796:        return;
                    797:     case 0xcd00:               /* and.b #imm,@(R0+GBR) */
                    798:        gen_op_movl_rN_T0(REG(0));
                    799:        gen_op_addl_GBR_T0();
                    800:        gen_op_movl_T0_T1();
                    801:        gen_op_ldb_T0_T0(ctx);
                    802:        gen_op_and_imm_T0(B7_0);
                    803:        gen_op_stb_T0_T1(ctx);
                    804:        return;
                    805:     case 0x8b00:               /* bf label */
                    806:        CHECK_NOT_DELAY_SLOT
                    807:            gen_conditional_jump(ctx, ctx->pc + 2,
                    808:                                 ctx->pc + 4 + B7_0s * 2);
1.1.1.3 ! root      809:        ctx->bstate = BS_BRANCH;
1.1       root      810:        return;
                    811:     case 0x8f00:               /* bf/s label */
                    812:        CHECK_NOT_DELAY_SLOT
                    813:            gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
                    814:        ctx->flags |= DELAY_SLOT_CONDITIONAL;
                    815:        return;
                    816:     case 0x8900:               /* bt label */
                    817:        CHECK_NOT_DELAY_SLOT
                    818:            gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
                    819:                                 ctx->pc + 2);
1.1.1.3 ! root      820:        ctx->bstate = BS_BRANCH;
1.1       root      821:        return;
                    822:     case 0x8d00:               /* bt/s label */
                    823:        CHECK_NOT_DELAY_SLOT
                    824:            gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
                    825:        ctx->flags |= DELAY_SLOT_CONDITIONAL;
                    826:        return;
                    827:     case 0x8800:               /* cmp/eq #imm,R0 */
                    828:        gen_op_movl_rN_T0(REG(0));
                    829:        gen_op_cmp_eq_imm_T0(B7_0s);
                    830:        return;
                    831:     case 0xc400:               /* mov.b @(disp,GBR),R0 */
                    832:        gen_op_stc_gbr_T0();
                    833:        gen_op_addl_imm_T0(B7_0);
                    834:        gen_op_ldb_T0_T0(ctx);
                    835:        gen_op_movl_T0_rN(REG(0));
                    836:        return;
                    837:     case 0xc500:               /* mov.w @(disp,GBR),R0 */
                    838:        gen_op_stc_gbr_T0();
                    839:        gen_op_addl_imm_T0(B7_0);
                    840:        gen_op_ldw_T0_T0(ctx);
                    841:        gen_op_movl_T0_rN(REG(0));
                    842:        return;
                    843:     case 0xc600:               /* mov.l @(disp,GBR),R0 */
                    844:        gen_op_stc_gbr_T0();
                    845:        gen_op_addl_imm_T0(B7_0);
                    846:        gen_op_ldl_T0_T0(ctx);
                    847:        gen_op_movl_T0_rN(REG(0));
                    848:        return;
                    849:     case 0xc000:               /* mov.b R0,@(disp,GBR) */
                    850:        gen_op_stc_gbr_T0();
                    851:        gen_op_addl_imm_T0(B7_0);
                    852:        gen_op_movl_T0_T1();
                    853:        gen_op_movl_rN_T0(REG(0));
                    854:        gen_op_stb_T0_T1(ctx);
                    855:        return;
                    856:     case 0xc100:               /* mov.w R0,@(disp,GBR) */
                    857:        gen_op_stc_gbr_T0();
                    858:        gen_op_addl_imm_T0(B7_0);
                    859:        gen_op_movl_T0_T1();
                    860:        gen_op_movl_rN_T0(REG(0));
                    861:        gen_op_stw_T0_T1(ctx);
                    862:        return;
                    863:     case 0xc200:               /* mov.l R0,@(disp,GBR) */
                    864:        gen_op_stc_gbr_T0();
                    865:        gen_op_addl_imm_T0(B7_0);
                    866:        gen_op_movl_T0_T1();
                    867:        gen_op_movl_rN_T0(REG(0));
                    868:        gen_op_stl_T0_T1(ctx);
                    869:        return;
                    870:     case 0x8000:               /* mov.b R0,@(disp,Rn) */
                    871:        gen_op_movl_rN_T0(REG(0));
                    872:        gen_op_movl_rN_T1(REG(B7_4));
                    873:        gen_op_addl_imm_T1(B3_0);
                    874:        gen_op_stb_T0_T1(ctx);
                    875:        return;
                    876:     case 0x8100:               /* mov.w R0,@(disp,Rn) */
                    877:        gen_op_movl_rN_T0(REG(0));
                    878:        gen_op_movl_rN_T1(REG(B7_4));
                    879:        gen_op_addl_imm_T1(B3_0 * 2);
                    880:        gen_op_stw_T0_T1(ctx);
                    881:        return;
                    882:     case 0x8400:               /* mov.b @(disp,Rn),R0 */
1.1.1.3 ! root      883:        gen_op_movl_rN_T0(REG(B7_4));
        !           884:        gen_op_addl_imm_T0(B3_0);
        !           885:        gen_op_ldb_T0_T0(ctx);
        !           886:        gen_op_movl_T0_rN(REG(0));
1.1       root      887:        return;
                    888:     case 0x8500:               /* mov.w @(disp,Rn),R0 */
                    889:        gen_op_movl_rN_T0(REG(B7_4));
                    890:        gen_op_addl_imm_T0(B3_0 * 2);
                    891:        gen_op_ldw_T0_T0(ctx);
                    892:        gen_op_movl_T0_rN(REG(0));
                    893:        return;
                    894:     case 0xc700:               /* mova @(disp,PC),R0 */
                    895:        gen_op_movl_imm_rN(((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3,
                    896:                           REG(0));
                    897:        return;
                    898:     case 0xcb00:               /* or #imm,R0 */
                    899:        gen_op_or_imm_rN(B7_0, REG(0));
                    900:        return;
                    901:     case 0xcf00:               /* or.b #imm,@(R0+GBR) */
                    902:        gen_op_movl_rN_T0(REG(0));
                    903:        gen_op_addl_GBR_T0();
                    904:        gen_op_movl_T0_T1();
                    905:        gen_op_ldb_T0_T0(ctx);
                    906:        gen_op_or_imm_T0(B7_0);
                    907:        gen_op_stb_T0_T1(ctx);
                    908:        return;
                    909:     case 0xc300:               /* trapa #imm */
                    910:        CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
                    911:        gen_op_trapa(B7_0);
1.1.1.3 ! root      912:        ctx->bstate = BS_BRANCH;
1.1       root      913:        return;
                    914:     case 0xc800:               /* tst #imm,R0 */
                    915:        gen_op_tst_imm_rN(B7_0, REG(0));
                    916:        return;
                    917:     case 0xcc00:               /* tst #imm,@(R0+GBR) */
                    918:        gen_op_movl_rN_T0(REG(0));
                    919:        gen_op_addl_GBR_T0();
                    920:        gen_op_ldb_T0_T0(ctx);
                    921:        gen_op_tst_imm_T0(B7_0);
                    922:        return;
                    923:     case 0xca00:               /* xor #imm,R0 */
                    924:        gen_op_xor_imm_rN(B7_0, REG(0));
                    925:        return;
                    926:     case 0xce00:               /* xor.b #imm,@(R0+GBR) */
                    927:        gen_op_movl_rN_T0(REG(0));
                    928:        gen_op_addl_GBR_T0();
                    929:        gen_op_movl_T0_T1();
                    930:        gen_op_ldb_T0_T0(ctx);
                    931:        gen_op_xor_imm_T0(B7_0);
                    932:        gen_op_stb_T0_T1(ctx);
                    933:        return;
                    934:     }
                    935: 
                    936:     switch (ctx->opcode & 0xf08f) {
                    937:     case 0x408e:               /* ldc Rm,Rn_BANK */
                    938:        gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
                    939:        return;
                    940:     case 0x4087:               /* ldc.l @Rm+,Rn_BANK */
                    941:        gen_op_movl_rN_T0(REG(B11_8));
                    942:        gen_op_ldl_T0_T0(ctx);
                    943:        gen_op_movl_T0_rN(ALTREG(B6_4));
                    944:        gen_op_inc4_rN(REG(B11_8));
                    945:        return;
                    946:     case 0x0082:               /* stc Rm_BANK,Rn */
                    947:        gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
                    948:        return;
                    949:     case 0x4083:               /* stc.l Rm_BANK,@-Rn */
                    950:        gen_op_dec4_rN(REG(B11_8));
                    951:        gen_op_movl_rN_T1(REG(B11_8));
                    952:        gen_op_movl_rN_T0(ALTREG(B6_4));
                    953:        gen_op_stl_T0_T1(ctx);
                    954:        return;
                    955:     }
                    956: 
                    957:     switch (ctx->opcode & 0xf0ff) {
                    958:     case 0x0023:               /* braf Rn */
                    959:        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
                    960:        gen_op_braf_T0(ctx->pc + 4);
                    961:        ctx->flags |= DELAY_SLOT;
                    962:        ctx->delayed_pc = (uint32_t) - 1;
                    963:        return;
                    964:     case 0x0003:               /* bsrf Rn */
                    965:        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
                    966:        gen_op_bsrf_T0(ctx->pc + 4);
                    967:        ctx->flags |= DELAY_SLOT;
                    968:        ctx->delayed_pc = (uint32_t) - 1;
                    969:        return;
                    970:     case 0x4015:               /* cmp/pl Rn */
                    971:        gen_op_movl_rN_T0(REG(B11_8));
                    972:        gen_op_cmp_pl_T0();
                    973:        return;
                    974:     case 0x4011:               /* cmp/pz Rn */
                    975:        gen_op_movl_rN_T0(REG(B11_8));
                    976:        gen_op_cmp_pz_T0();
                    977:        return;
                    978:     case 0x4010:               /* dt Rn */
                    979:        gen_op_dt_rN(REG(B11_8));
                    980:        return;
                    981:     case 0x402b:               /* jmp @Rn */
                    982:        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
                    983:        gen_op_jmp_T0();
                    984:        ctx->flags |= DELAY_SLOT;
                    985:        ctx->delayed_pc = (uint32_t) - 1;
                    986:        return;
                    987:     case 0x400b:               /* jsr @Rn */
                    988:        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
                    989:        gen_op_jsr_T0(ctx->pc + 4);
                    990:        ctx->flags |= DELAY_SLOT;
                    991:        ctx->delayed_pc = (uint32_t) - 1;
                    992:        return;
                    993: #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald)  \
                    994:   case ldnum:                                                  \
                    995:     gen_op_movl_rN_T0 (REG(B11_8));                            \
                    996:     gen_op_##ldop##_T0_##reg ();                               \
                    997:     extrald                                                    \
                    998:     return;                                                    \
                    999:   case ldpnum:                                                 \
                   1000:     gen_op_movl_rN_T0 (REG(B11_8));                            \
                   1001:     gen_op_ldl_T0_T0 (ctx);                                    \
                   1002:     gen_op_inc4_rN (REG(B11_8));                               \
                   1003:     gen_op_##ldop##_T0_##reg ();                               \
                   1004:     extrald                                                    \
                   1005:     return;                                                    \
                   1006:   case stnum:                                                  \
                   1007:     gen_op_##stop##_##reg##_T0 ();                                     \
                   1008:     gen_op_movl_T0_rN (REG(B11_8));                            \
                   1009:     return;                                                    \
                   1010:   case stpnum:                                                 \
                   1011:     gen_op_##stop##_##reg##_T0 ();                             \
                   1012:     gen_op_dec4_rN (REG(B11_8));                               \
                   1013:     gen_op_movl_rN_T1 (REG(B11_8));                            \
                   1014:     gen_op_stl_T0_T1 (ctx);                                    \
                   1015:     return;
1.1.1.3 ! root     1016:        LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate =
        !          1017:             BS_STOP;)
1.1.1.2   root     1018:        LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
                   1019:        LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
                   1020:        LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
                   1021:        LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
                   1022:        LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
                   1023:        LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
                   1024:        LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
                   1025:        LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1.1.1.3 ! root     1026:        LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
        !          1027:        LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->bstate =
        !          1028:             BS_STOP;)
1.1       root     1029:     case 0x00c3:               /* movca.l R0,@Rm */
                   1030:        gen_op_movl_rN_T0(REG(0));
                   1031:        gen_op_movl_rN_T1(REG(B11_8));
                   1032:        gen_op_stl_T0_T1(ctx);
                   1033:        return;
                   1034:     case 0x0029:               /* movt Rn */
                   1035:        gen_op_movt_rN(REG(B11_8));
                   1036:        return;
                   1037:     case 0x0093:               /* ocbi @Rn */
                   1038:        gen_op_movl_rN_T0(REG(B11_8));
                   1039:        gen_op_ldl_T0_T0(ctx);
                   1040:        return;
                   1041:     case 0x00a2:               /* ocbp @Rn */
                   1042:        gen_op_movl_rN_T0(REG(B11_8));
                   1043:        gen_op_ldl_T0_T0(ctx);
                   1044:        return;
                   1045:     case 0x00b3:               /* ocbwb @Rn */
                   1046:        gen_op_movl_rN_T0(REG(B11_8));
                   1047:        gen_op_ldl_T0_T0(ctx);
                   1048:        return;
                   1049:     case 0x0083:               /* pref @Rn */
                   1050:        return;
                   1051:     case 0x4024:               /* rotcl Rn */
                   1052:        gen_op_rotcl_Rn(REG(B11_8));
                   1053:        return;
                   1054:     case 0x4025:               /* rotcr Rn */
                   1055:        gen_op_rotcr_Rn(REG(B11_8));
                   1056:        return;
                   1057:     case 0x4004:               /* rotl Rn */
                   1058:        gen_op_rotl_Rn(REG(B11_8));
                   1059:        return;
                   1060:     case 0x4005:               /* rotr Rn */
                   1061:        gen_op_rotr_Rn(REG(B11_8));
                   1062:        return;
                   1063:     case 0x4000:               /* shll Rn */
                   1064:     case 0x4020:               /* shal Rn */
                   1065:        gen_op_shal_Rn(REG(B11_8));
                   1066:        return;
                   1067:     case 0x4021:               /* shar Rn */
                   1068:        gen_op_shar_Rn(REG(B11_8));
                   1069:        return;
                   1070:     case 0x4001:               /* shlr Rn */
                   1071:        gen_op_shlr_Rn(REG(B11_8));
                   1072:        return;
                   1073:     case 0x4008:               /* shll2 Rn */
                   1074:        gen_op_shll2_Rn(REG(B11_8));
                   1075:        return;
                   1076:     case 0x4018:               /* shll8 Rn */
                   1077:        gen_op_shll8_Rn(REG(B11_8));
                   1078:        return;
                   1079:     case 0x4028:               /* shll16 Rn */
                   1080:        gen_op_shll16_Rn(REG(B11_8));
                   1081:        return;
                   1082:     case 0x4009:               /* shlr2 Rn */
                   1083:        gen_op_shlr2_Rn(REG(B11_8));
                   1084:        return;
                   1085:     case 0x4019:               /* shlr8 Rn */
                   1086:        gen_op_shlr8_Rn(REG(B11_8));
                   1087:        return;
                   1088:     case 0x4029:               /* shlr16 Rn */
                   1089:        gen_op_shlr16_Rn(REG(B11_8));
                   1090:        return;
                   1091:     case 0x401b:               /* tas.b @Rn */
                   1092:        gen_op_tasb_rN(REG(B11_8));
                   1093:        return;
1.1.1.3 ! root     1094:     case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1.1.1.2   root     1095:        gen_op_movl_fpul_FT0();
                   1096:        gen_op_fmov_FT0_frN(FREG(B11_8));
                   1097:        return;
1.1.1.3 ! root     1098:     case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1.1.1.2   root     1099:        gen_op_fmov_frN_FT0(FREG(B11_8));
                   1100:        gen_op_movl_FT0_fpul();
                   1101:        return;
1.1.1.3 ! root     1102:     case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
        !          1103:        if (ctx->fpscr & FPSCR_PR) {
        !          1104:            if (ctx->opcode & 0x0100)
        !          1105:                break; /* illegal instruction */
        !          1106:            gen_op_float_DT();
        !          1107:            gen_op_fmov_DT0_drN(DREG(B11_8));
        !          1108:        }
        !          1109:        else {
        !          1110:            gen_op_float_FT();
        !          1111:            gen_op_fmov_FT0_frN(FREG(B11_8));
        !          1112:        }
        !          1113:        return;
        !          1114:     case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
        !          1115:        if (ctx->fpscr & FPSCR_PR) {
        !          1116:            if (ctx->opcode & 0x0100)
        !          1117:                break; /* illegal instruction */
        !          1118:            gen_op_fmov_drN_DT0(DREG(B11_8));
        !          1119:            gen_op_ftrc_DT();
        !          1120:        }
        !          1121:        else {
        !          1122:            gen_op_fmov_frN_FT0(FREG(B11_8));
        !          1123:            gen_op_ftrc_FT();
        !          1124:        }
        !          1125:        return;
        !          1126:     case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
        !          1127:        if (!(ctx->fpscr & FPSCR_PR)) {
        !          1128:            gen_op_movl_imm_T0(0);
        !          1129:            gen_op_fmov_T0_frN(FREG(B11_8));
        !          1130:            return;
        !          1131:        }
        !          1132:        break;
        !          1133:     case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
        !          1134:        if (!(ctx->fpscr & FPSCR_PR)) {
        !          1135:            gen_op_movl_imm_T0(0x3f800000);
        !          1136:            gen_op_fmov_T0_frN(FREG(B11_8));
        !          1137:            return;
        !          1138:        }
        !          1139:        break;
1.1       root     1140:     }
                   1141: 
                   1142:     fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
                   1143:            ctx->opcode, ctx->pc);
                   1144:     gen_op_raise_illegal_instruction();
1.1.1.3 ! root     1145:     ctx->bstate = BS_EXCP;
        !          1146: }
        !          1147: 
        !          1148: void decode_opc(DisasContext * ctx)
        !          1149: {
        !          1150:     uint32_t old_flags = ctx->flags;
        !          1151: 
        !          1152:     _decode_opc(ctx);
        !          1153: 
        !          1154:     if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
        !          1155:         if (ctx->flags & DELAY_SLOT_CLEARME) {
        !          1156:             gen_op_store_flags(0);
        !          1157:         }
        !          1158:         ctx->flags = 0;
        !          1159:         ctx->bstate = BS_BRANCH;
        !          1160:         if (old_flags & DELAY_SLOT_CONDITIONAL) {
        !          1161:            gen_delayed_conditional_jump(ctx);
        !          1162:         } else if (old_flags & DELAY_SLOT) {
        !          1163:             gen_jump(ctx);
        !          1164:        }
        !          1165: 
        !          1166:     }
1.1       root     1167: }
                   1168: 
1.1.1.3 ! root     1169: static inline int
        !          1170: gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
        !          1171:                                int search_pc)
1.1       root     1172: {
                   1173:     DisasContext ctx;
                   1174:     target_ulong pc_start;
                   1175:     static uint16_t *gen_opc_end;
1.1.1.2   root     1176:     int i, ii;
1.1       root     1177: 
                   1178:     pc_start = tb->pc;
                   1179:     gen_opc_ptr = gen_opc_buf;
                   1180:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
                   1181:     gen_opparam_ptr = gen_opparam_buf;
                   1182:     ctx.pc = pc_start;
1.1.1.3 ! root     1183:     ctx.flags = (uint32_t)tb->flags;
        !          1184:     ctx.bstate = BS_NONE;
1.1       root     1185:     ctx.sr = env->sr;
1.1.1.2   root     1186:     ctx.fpscr = env->fpscr;
1.1       root     1187:     ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1.1.1.2   root     1188:     /* We don't know if the delayed pc came from a dynamic or static branch,
                   1189:        so assume it is a dynamic branch.  */
1.1.1.3 ! root     1190:     ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1.1       root     1191:     ctx.tb = tb;
                   1192:     ctx.singlestep_enabled = env->singlestep_enabled;
                   1193:     nb_gen_labels = 0;
                   1194: 
                   1195: #ifdef DEBUG_DISAS
                   1196:     if (loglevel & CPU_LOG_TB_CPU) {
                   1197:        fprintf(logfile,
                   1198:                "------------------------------------------------\n");
                   1199:        cpu_dump_state(env, logfile, fprintf, 0);
                   1200:     }
                   1201: #endif
                   1202: 
1.1.1.2   root     1203:     ii = -1;
1.1.1.3 ! root     1204:     while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1.1       root     1205:        if (env->nb_breakpoints > 0) {
                   1206:            for (i = 0; i < env->nb_breakpoints; i++) {
                   1207:                if (ctx.pc == env->breakpoints[i]) {
                   1208:                    /* We have hit a breakpoint - make sure PC is up-to-date */
                   1209:                    gen_op_movl_imm_PC(ctx.pc);
                   1210:                    gen_op_debug();
1.1.1.3 ! root     1211:                    ctx.bstate = BS_EXCP;
1.1       root     1212:                    break;
                   1213:                }
                   1214:            }
                   1215:        }
1.1.1.2   root     1216:         if (search_pc) {
                   1217:             i = gen_opc_ptr - gen_opc_buf;
                   1218:             if (ii < i) {
                   1219:                 ii++;
                   1220:                 while (ii < i)
                   1221:                     gen_opc_instr_start[ii++] = 0;
                   1222:             }
                   1223:             gen_opc_pc[ii] = ctx.pc;
1.1.1.3 ! root     1224:             gen_opc_hflags[ii] = ctx.flags;
1.1.1.2   root     1225:             gen_opc_instr_start[ii] = 1;
                   1226:         }
1.1       root     1227: #if 0
                   1228:        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
                   1229:        fflush(stderr);
                   1230: #endif
                   1231:        ctx.opcode = lduw_code(ctx.pc);
                   1232:        decode_opc(&ctx);
                   1233:        ctx.pc += 2;
                   1234:        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
                   1235:            break;
                   1236:        if (env->singlestep_enabled)
                   1237:            break;
                   1238: #ifdef SH4_SINGLE_STEP
                   1239:        break;
                   1240: #endif
                   1241:     }
                   1242:     if (env->singlestep_enabled) {
1.1.1.3 ! root     1243:         gen_op_debug();
        !          1244:     } else {
        !          1245:        switch (ctx.bstate) {
        !          1246:         case BS_STOP:
        !          1247:             /* gen_op_interrupt_restart(); */
        !          1248:             /* fall through */
        !          1249:         case BS_NONE:
        !          1250:             if (ctx.flags) {
        !          1251:                 gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
        !          1252:            }
        !          1253:             gen_goto_tb(&ctx, 0, ctx.pc);
        !          1254:             break;
        !          1255:         case BS_EXCP:
        !          1256:             /* gen_op_interrupt_restart(); */
        !          1257:             gen_op_movl_imm_T0(0);
        !          1258:             gen_op_exit_tb();
        !          1259:             break;
        !          1260:         case BS_BRANCH:
        !          1261:         default:
        !          1262:             break;
        !          1263:        }
1.1       root     1264:     }
1.1.1.3 ! root     1265: 
1.1       root     1266:     *gen_opc_ptr = INDEX_op_end;
1.1.1.2   root     1267:     if (search_pc) {
                   1268:         i = gen_opc_ptr - gen_opc_buf;
                   1269:         ii++;
                   1270:         while (ii <= i)
                   1271:             gen_opc_instr_start[ii++] = 0;
                   1272:     } else {
                   1273:         tb->size = ctx.pc - pc_start;
                   1274:     }
1.1       root     1275: 
                   1276: #ifdef DEBUG_DISAS
                   1277: #ifdef SH4_DEBUG_DISAS
                   1278:     if (loglevel & CPU_LOG_TB_IN_ASM)
                   1279:        fprintf(logfile, "\n");
                   1280: #endif
                   1281:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                   1282:        fprintf(logfile, "IN:\n");      /* , lookup_symbol(pc_start)); */
                   1283:        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
                   1284:        fprintf(logfile, "\n");
                   1285:     }
                   1286:     if (loglevel & CPU_LOG_TB_OP) {
                   1287:        fprintf(logfile, "OP:\n");
                   1288:        dump_ops(gen_opc_buf, gen_opparam_buf);
                   1289:        fprintf(logfile, "\n");
                   1290:     }
                   1291: #endif
                   1292:     return 0;
                   1293: }
                   1294: 
                   1295: int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
                   1296: {
                   1297:     return gen_intermediate_code_internal(env, tb, 0);
                   1298: }
                   1299: 
                   1300: int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
                   1301: {
                   1302:     return gen_intermediate_code_internal(env, tb, 1);
                   1303: }

unix.superglobalmegacorp.com

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