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

1.1       root        1: /*
                      2:  *  SH4 translation
                      3:  * 
                      4:  *  Copyright (c) 2005 Samuel Tardieu
                      5:  *
                      6:  * This library is free software; you can redistribute it and/or
                      7:  * modify it under the terms of the GNU Lesser General Public
                      8:  * License as published by the Free Software Foundation; either
                      9:  * version 2 of the License, or (at your option) any later version.
                     10:  *
                     11:  * This library is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * Lesser General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU Lesser General Public
                     17:  * License along with this library; if not, 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;
                     57:     uint16_t opcode;
                     58:     uint32_t flags;
                     59:     int memidx;
                     60:     uint32_t delayed_pc;
                     61:     int singlestep_enabled;
                     62: } DisasContext;
                     63: 
                     64: #ifdef CONFIG_USER_ONLY
                     65: 
                     66: #define GEN_OP_LD(width) \
                     67:   void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \
                     68:     gen_op_ld##width##_T0_T0_raw(); \
                     69:   }
                     70: #define GEN_OP_ST(width) \
                     71:   void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \
                     72:     gen_op_st##width##_T0_T1_raw(); \
                     73:   }
                     74: 
                     75: #else
                     76: 
                     77: #define GEN_OP_LD(width) \
                     78:   void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \
                     79:     if (ctx->memidx) gen_op_ld##width##_T0_T0_kernel(); \
                     80:     else gen_op_ld##width##_T0_T0_user();\
                     81:   }
                     82: #define GEN_OP_ST(width) \
                     83:   void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \
                     84:     if (ctx->memidx) gen_op_st##width##_T0_T1_kernel(); \
                     85:     else gen_op_st##width##_T0_T1_user();\
                     86:   }
                     87: 
                     88: #endif
                     89: 
                     90: GEN_OP_LD(ub)
                     91:     GEN_OP_LD(b)
                     92:     GEN_OP_ST(b)
                     93:     GEN_OP_LD(uw)
                     94:     GEN_OP_LD(w)
                     95:     GEN_OP_ST(w)
                     96:     GEN_OP_LD(l)
                     97:     GEN_OP_ST(l)
                     98: 
                     99: void cpu_dump_state(CPUState * env, FILE * f,
                    100:                    int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
                    101:                    int flags)
                    102: {
                    103:     int i;
                    104:     cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x\n",
                    105:                env->pc, env->sr, env->pr);
                    106:     for (i = 0; i < 24; i += 4) {
                    107:        cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
                    108:                    i, env->gregs[i], i + 1, env->gregs[i + 1],
                    109:                    i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
                    110:     }
                    111:     if (env->flags & DELAY_SLOT) {
                    112:        cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
                    113:                    env->delayed_pc);
                    114:     } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
                    115:        cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
                    116:                    env->delayed_pc);
                    117:     }
                    118: }
                    119: 
                    120: void cpu_sh4_reset(CPUSH4State * env)
                    121: {
                    122:     env->sr = 0x700000F0;      /* MD, RB, BL, I3-I0 */
                    123:     env->vbr = 0;
                    124:     env->pc = 0xA0000000;
                    125:     env->fpscr = 0x00040001;
                    126:     env->mmucr = 0;
                    127: }
                    128: 
                    129: CPUSH4State *cpu_sh4_init(void)
                    130: {
                    131:     CPUSH4State *env;
                    132: 
                    133:     env = qemu_mallocz(sizeof(CPUSH4State));
                    134:     if (!env)
                    135:        return NULL;
                    136:     cpu_exec_init(env);
                    137:     cpu_sh4_reset(env);
                    138:     tlb_flush(env, 1);
                    139:     return env;
                    140: }
                    141: 
                    142: #ifdef CONFIG_USER_ONLY
                    143: target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
                    144: {
                    145:     return addr;
                    146: }
                    147: #else
                    148: target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
                    149: {
                    150:     target_ulong physical;
                    151:     int prot;
                    152: 
                    153:     get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0);
                    154:     return physical;
                    155: }
                    156: #endif
                    157: 
                    158: static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
                    159: {
                    160:     TranslationBlock *tb;
                    161:     tb = ctx->tb;
                    162: 
                    163:     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
                    164:        !ctx->singlestep_enabled) {
                    165:        /* Use a direct jump if in same page and singlestep not enabled */
                    166:        if (n == 0)
                    167:            gen_op_goto_tb0(TBPARAM(tb));
                    168:        else
                    169:            gen_op_goto_tb1(TBPARAM(tb));
                    170:        gen_op_movl_imm_T0((long) tb + n);
                    171:     } else {
                    172:        gen_op_movl_imm_T0(0);
                    173:     }
                    174:     gen_op_movl_imm_PC(dest);
                    175:     if (ctx->singlestep_enabled)
                    176:        gen_op_debug();
                    177:     gen_op_exit_tb();
                    178: }
                    179: 
                    180: /* Jump to pc after an exception */
                    181: static void gen_jump_exception(DisasContext * ctx)
                    182: {
                    183:     gen_op_movl_imm_T0(0);
                    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();
                    223:     gen_op_jTT2(l1);
                    224:     gen_goto_tb(ctx, 0, ctx->pc);
                    225:     gen_set_label(l1);
                    226:     gen_goto_tb(ctx, 1, ctx->delayed_pc);
                    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: 
                    245: #define CHECK_NOT_DELAY_SLOT \
                    246:   if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
                    247:   {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \
                    248:    return;}
                    249: 
                    250: void decode_opc(DisasContext * ctx)
                    251: {
                    252: #if 0
                    253:     fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
                    254: #endif
                    255:     switch (ctx->opcode) {
                    256:     case 0x0019:               /* div0u */
                    257:        printf("div0u\n");
                    258:        gen_op_div0u();
                    259:        return;
                    260:     case 0x000b:               /* rts */
                    261:        CHECK_NOT_DELAY_SLOT gen_op_rts();
                    262:        ctx->flags |= DELAY_SLOT;
                    263:        ctx->delayed_pc = (uint32_t) - 1;
                    264:        return;
                    265:     case 0x0028:               /* clrmac */
                    266:        gen_op_clrmac();
                    267:        return;
                    268:     case 0x0048:               /* clrs */
                    269:        gen_op_clrs();
                    270:        return;
                    271:     case 0x0008:               /* clrt */
                    272:        gen_op_clrt();
                    273:        return;
                    274:     case 0x0038:               /* ldtlb */
                    275:        assert(0);              /* XXXXX */
                    276:        return;
                    277:     case 0x004b:               /* rte */
                    278:        CHECK_NOT_DELAY_SLOT gen_op_rte();
                    279:        ctx->flags |= DELAY_SLOT;
                    280:        ctx->delayed_pc = (uint32_t) - 1;
                    281:        return;
                    282:     case 0x0058:               /* sets */
                    283:        gen_op_sets();
                    284:        return;
                    285:     case 0x0018:               /* sett */
                    286:        gen_op_sett();
                    287:        return;
                    288:     case 0xfbfb:               /* frchg */
                    289:        assert(0);              /* XXXXX */
                    290:        return;
                    291:     case 0xf3fb:               /* fschg */
                    292:        assert(0);              /* XXXXX */
                    293:        return;
                    294:     case 0x0009:               /* nop */
                    295:        return;
                    296:     case 0x001b:               /* sleep */
                    297:        assert(0);              /* XXXXX */
                    298:        return;
                    299:     }
                    300: 
                    301:     switch (ctx->opcode & 0xf000) {
                    302:     case 0x1000:               /* mov.l Rm,@(disp,Rn) */
                    303:        gen_op_movl_rN_T0(REG(B7_4));
                    304:        gen_op_movl_rN_T1(REG(B11_8));
                    305:        gen_op_addl_imm_T1(B3_0 * 4);
                    306:        gen_op_stl_T0_T1(ctx);
                    307:        return;
                    308:     case 0x5000:               /* mov.l @(disp,Rm),Rn */
                    309:        gen_op_movl_rN_T0(REG(B7_4));
                    310:        gen_op_addl_imm_T0(B3_0 * 4);
                    311:        gen_op_ldl_T0_T0(ctx);
                    312:        gen_op_movl_T0_rN(REG(B11_8));
                    313:        return;
                    314:     case 0xe000:               /* mov.l #imm,Rn */
                    315:        gen_op_movl_imm_rN(B7_0s, REG(B11_8));
                    316:        return;
                    317:     case 0x9000:               /* mov.w @(disp,PC),Rn */
                    318:        gen_op_movl_imm_T0(ctx->pc + 4 + B7_0 * 2);
                    319:        gen_op_ldw_T0_T0(ctx);
                    320:        gen_op_movl_T0_rN(REG(B11_8));
                    321:        return;
                    322:     case 0xd000:               /* mov.l @(disp,PC),Rn */
                    323:        gen_op_movl_imm_T0((ctx->pc + 4 + B7_0 * 4) & ~3);
                    324:        gen_op_ldl_T0_T0(ctx);
                    325:        gen_op_movl_T0_rN(REG(B11_8));
                    326:        return;
                    327:     case 0x7000:               /* add.l #imm,Rn */
                    328:        gen_op_add_imm_rN(B7_0s, REG(B11_8));
                    329:        return;
                    330:     case 0xa000:               /* bra disp */
                    331:        CHECK_NOT_DELAY_SLOT
                    332:            gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
                    333:        ctx->flags |= DELAY_SLOT;
                    334:        return;
                    335:     case 0xb000:               /* bsr disp */
                    336:        CHECK_NOT_DELAY_SLOT
                    337:            gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
                    338:                       ctx->pc + 4 + B11_0s * 2);
                    339:        ctx->flags |= DELAY_SLOT;
                    340:        return;
                    341:     }
                    342: 
                    343:     switch (ctx->opcode & 0xf00f) {
                    344:     case 0x6003:               /* mov Rm,Rn */
                    345:        gen_op_movl_rN_T0(REG(B7_4));
                    346:        gen_op_movl_T0_rN(REG(B11_8));
                    347:        return;
                    348:     case 0x2000:               /* mov.b Rm,@Rn */
                    349:        gen_op_movl_rN_T0(REG(B7_4));
                    350:        gen_op_movl_rN_T1(REG(B11_8));
                    351:        gen_op_stb_T0_T1(ctx);
                    352:        return;
                    353:     case 0x2001:               /* mov.w Rm,@Rn */
                    354:        gen_op_movl_rN_T0(REG(B7_4));
                    355:        gen_op_movl_rN_T1(REG(B11_8));
                    356:        gen_op_stw_T0_T1(ctx);
                    357:        return;
                    358:     case 0x2002:               /* mov.l Rm,@Rn */
                    359:        gen_op_movl_rN_T0(REG(B7_4));
                    360:        gen_op_movl_rN_T1(REG(B11_8));
                    361:        gen_op_stl_T0_T1(ctx);
                    362:        return;
                    363:     case 0x6000:               /* mov.b @Rm,Rn */
                    364:        gen_op_movl_rN_T0(REG(B7_4));
                    365:        gen_op_ldb_T0_T0(ctx);
                    366:        gen_op_movl_T0_rN(REG(B11_8));
                    367:        return;
                    368:     case 0x6001:               /* mov.w @Rm,Rn */
                    369:        gen_op_movl_rN_T0(REG(B7_4));
                    370:        gen_op_ldw_T0_T0(ctx);
                    371:        gen_op_movl_T0_rN(REG(B11_8));
                    372:        return;
                    373:     case 0x6002:               /* mov.l @Rm,Rn */
                    374:        gen_op_movl_rN_T0(REG(B7_4));
                    375:        gen_op_ldl_T0_T0(ctx);
                    376:        gen_op_movl_T0_rN(REG(B11_8));
                    377:        return;
                    378:     case 0x2004:               /* mov.b Rm,@-Rn */
                    379:        gen_op_dec1_rN(REG(B11_8));
                    380:        gen_op_movl_rN_T0(REG(B7_4));
                    381:        gen_op_movl_rN_T1(REG(B11_8));
                    382:        gen_op_stb_T0_T1(ctx);
                    383:        return;
                    384:     case 0x2005:               /* mov.w Rm,@-Rn */
                    385:        gen_op_dec2_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_stw_T0_T1(ctx);
                    389:        return;
                    390:     case 0x2006:               /* mov.l Rm,@-Rn */
                    391:        gen_op_dec4_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_stl_T0_T1(ctx);
                    395:        return;
                    396:     case 0x6004:               /* mov.l @Rm+,Rn */
                    397:        gen_op_movl_rN_T0(REG(B7_4));
                    398:        gen_op_ldb_T0_T0(ctx);
                    399:        gen_op_movl_T0_rN(REG(B11_8));
                    400:        gen_op_inc1_rN(REG(B7_4));
                    401:        return;
                    402:     case 0x6005:               /* mov.w @Rm+,Rn */
                    403:        gen_op_movl_rN_T0(REG(B7_4));
                    404:        gen_op_ldw_T0_T0(ctx);
                    405:        gen_op_movl_T0_rN(REG(B11_8));
                    406:        gen_op_inc2_rN(REG(B7_4));
                    407:        return;
                    408:     case 0x6006:               /* mov.l @Rm+,Rn */
                    409:        gen_op_movl_rN_T0(REG(B7_4));
                    410:        gen_op_ldl_T0_T0(ctx);
                    411:        gen_op_movl_T0_rN(REG(B11_8));
                    412:        gen_op_inc4_rN(REG(B7_4));
                    413:        return;
                    414:     case 0x0004:               /* mov.b Rm,@(R0,Rn) */
                    415:        gen_op_movl_rN_T0(REG(B7_4));
                    416:        gen_op_movl_rN_T1(REG(B11_8));
                    417:        gen_op_add_rN_T1(REG(0));
                    418:        gen_op_stb_T0_T1(ctx);
                    419:        return;
                    420:     case 0x0005:               /* mov.w 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_stw_T0_T1(ctx);
                    425:        return;
                    426:     case 0x0006:               /* mov.l 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_stl_T0_T1(ctx);
                    431:        return;
                    432:     case 0x000c:               /* mov.b @(R0,Rm),Rn */
                    433:        gen_op_movl_rN_T0(REG(B7_4));
                    434:        gen_op_add_rN_T0(REG(0));
                    435:        gen_op_ldb_T0_T0(ctx);
                    436:        gen_op_movl_T0_rN(REG(B11_8));
                    437:        return;
                    438:     case 0x000d:               /* mov.w @(R0,Rm),Rn */
                    439:        gen_op_movl_rN_T0(REG(B7_4));
                    440:        gen_op_add_rN_T0(REG(0));
                    441:        gen_op_ldw_T0_T0(ctx);
                    442:        gen_op_movl_T0_rN(REG(B11_8));
                    443:        return;
                    444:     case 0x000e:               /* mov.l @(R0,Rm),Rn */
                    445:        gen_op_movl_rN_T0(REG(B7_4));
                    446:        gen_op_add_rN_T0(REG(0));
                    447:        gen_op_ldl_T0_T0(ctx);
                    448:        gen_op_movl_T0_rN(REG(B11_8));
                    449:        return;
                    450:     case 0x6008:               /* swap.b Rm,Rn */
                    451:        gen_op_movl_rN_T0(REG(B7_4));
                    452:        gen_op_swapb_T0();
                    453:        gen_op_movl_T0_rN(REG(B11_8));
                    454:        return;
                    455:     case 0x6009:               /* swap.w Rm,Rn */
                    456:        gen_op_movl_rN_T0(REG(B7_4));
                    457:        gen_op_swapw_T0();
                    458:        gen_op_movl_T0_rN(REG(B11_8));
                    459:        return;
                    460:     case 0x200d:               /* xtrct Rm,Rn */
                    461:        gen_op_movl_rN_T0(REG(B7_4));
                    462:        gen_op_movl_rN_T1(REG(B11_8));
                    463:        gen_op_xtrct_T0_T1();
                    464:        gen_op_movl_T1_rN(REG(B11_8));
                    465:        return;
                    466:     case 0x300c:               /* add Rm,Rn */
                    467:        gen_op_movl_rN_T0(REG(B7_4));
                    468:        gen_op_add_T0_rN(REG(B11_8));
                    469:        return;
                    470:     case 0x300e:               /* addc Rm,Rn */
                    471:        gen_op_movl_rN_T0(REG(B7_4));
                    472:        gen_op_movl_rN_T1(REG(B11_8));
                    473:        gen_op_addc_T0_T1();
                    474:        gen_op_movl_T1_rN(REG(B11_8));
                    475:        return;
                    476:     case 0x300f:               /* addv Rm,Rn */
                    477:        gen_op_movl_rN_T0(REG(B7_4));
                    478:        gen_op_movl_rN_T1(REG(B11_8));
                    479:        gen_op_addv_T0_T1();
                    480:        gen_op_movl_T1_rN(REG(B11_8));
                    481:        return;
                    482:     case 0x2009:               /* and Rm,Rn */
                    483:        gen_op_movl_rN_T0(REG(B7_4));
                    484:        gen_op_and_T0_rN(REG(B11_8));
                    485:        return;
                    486:     case 0x3000:               /* cmp/eq Rm,Rn */
                    487:        gen_op_movl_rN_T0(REG(B7_4));
                    488:        gen_op_movl_rN_T1(REG(B11_8));
                    489:        gen_op_cmp_eq_T0_T1();
                    490:        return;
                    491:     case 0x3003:               /* cmp/ge Rm,Rn */
                    492:        gen_op_movl_rN_T0(REG(B7_4));
                    493:        gen_op_movl_rN_T1(REG(B11_8));
                    494:        gen_op_cmp_ge_T0_T1();
                    495:        return;
                    496:     case 0x3007:               /* cmp/gt Rm,Rn */
                    497:        gen_op_movl_rN_T0(REG(B7_4));
                    498:        gen_op_movl_rN_T1(REG(B11_8));
                    499:        gen_op_cmp_gt_T0_T1();
                    500:        return;
                    501:     case 0x3006:               /* cmp/hi Rm,Rn */
                    502:        gen_op_movl_rN_T0(REG(B7_4));
                    503:        gen_op_movl_rN_T1(REG(B11_8));
                    504:        gen_op_cmp_hi_T0_T1();
                    505:        return;
                    506:     case 0x3002:               /* cmp/hs Rm,Rn */
                    507:        gen_op_movl_rN_T0(REG(B7_4));
                    508:        gen_op_movl_rN_T1(REG(B11_8));
                    509:        gen_op_cmp_hs_T0_T1();
                    510:        return;
                    511:     case 0x200c:               /* cmp/str Rm,Rn */
                    512:        gen_op_movl_rN_T0(REG(B7_4));
                    513:        gen_op_movl_rN_T1(REG(B11_8));
                    514:        gen_op_cmp_str_T0_T1();
                    515:        return;
                    516:     case 0x2007:               /* div0s Rm,Rn */
                    517:        printf("div0s\n");
                    518:        gen_op_movl_rN_T0(REG(B7_4));
                    519:        gen_op_movl_rN_T1(REG(B11_8));
                    520:        gen_op_div0s_T0_T1();
                    521:        gen_op_movl_T1_rN(REG(B11_8));
                    522:        return;
                    523:     case 0x3004:               /* div1 Rm,Rn */
                    524:        gen_op_movl_rN_T0(REG(B7_4));
                    525:        gen_op_movl_rN_T1(REG(B11_8));
                    526:        gen_op_div1_T0_T1();
                    527:        gen_op_movl_T1_rN(REG(B11_8));
                    528:        return;
                    529:     case 0x300d:               /* dmuls.l Rm,Rn */
                    530:        gen_op_movl_rN_T0(REG(B7_4));
                    531:        gen_op_movl_rN_T1(REG(B11_8));
                    532:        gen_op_dmulsl_T0_T1();
                    533:        return;
                    534:     case 0x3005:               /* dmulu.l Rm,Rn */
                    535:        gen_op_movl_rN_T0(REG(B7_4));
                    536:        gen_op_movl_rN_T1(REG(B11_8));
                    537:        gen_op_dmulul_T0_T1();
                    538:        return;
                    539:     case 0x600e:               /* exts.b Rm,Rn */
                    540:        gen_op_movb_rN_T0(REG(B7_4));
                    541:        gen_op_movl_T0_rN(REG(B11_8));
                    542:        return;
                    543:     case 0x600f:               /* exts.w Rm,Rn */
                    544:        gen_op_movw_rN_T0(REG(B7_4));
                    545:        gen_op_movl_T0_rN(REG(B11_8));
                    546:        return;
                    547:     case 0x600c:               /* extu.b Rm,Rn */
                    548:        gen_op_movub_rN_T0(REG(B7_4));
                    549:        gen_op_movl_T0_rN(REG(B11_8));
                    550:        return;
                    551:     case 0x600d:               /* extu.w Rm,Rn */
                    552:        gen_op_movuw_rN_T0(REG(B7_4));
                    553:        gen_op_movl_T0_rN(REG(B11_8));
                    554:        return;
                    555:     case 0x000f:               /* mac.l @Rm+,@Rn- */
                    556:        gen_op_movl_rN_T0(REG(B11_8));
                    557:        gen_op_ldl_T0_T0(ctx);
                    558:        gen_op_movl_T0_T1();
                    559:        gen_op_movl_rN_T1(REG(B7_4));
                    560:        gen_op_ldl_T0_T0(ctx);
                    561:        gen_op_macl_T0_T1();
                    562:        gen_op_inc4_rN(REG(B7_4));
                    563:        gen_op_inc4_rN(REG(B11_8));
                    564:        return;
                    565:     case 0x400f:               /* mac.w @Rm+,@Rn+ */
                    566:        gen_op_movl_rN_T0(REG(B11_8));
                    567:        gen_op_ldl_T0_T0(ctx);
                    568:        gen_op_movl_T0_T1();
                    569:        gen_op_movl_rN_T1(REG(B7_4));
                    570:        gen_op_ldl_T0_T0(ctx);
                    571:        gen_op_macw_T0_T1();
                    572:        gen_op_inc2_rN(REG(B7_4));
                    573:        gen_op_inc2_rN(REG(B11_8));
                    574:        return;
                    575:     case 0x0007:               /* mul.l Rm,Rn */
                    576:        gen_op_movl_rN_T0(REG(B7_4));
                    577:        gen_op_movl_rN_T1(REG(B11_8));
                    578:        gen_op_mull_T0_T1();
                    579:        return;
                    580:     case 0x200f:               /* muls.w Rm,Rn */
                    581:        gen_op_movw_rN_T0(REG(B7_4));
                    582:        gen_op_movw_rN_T1(REG(B11_8));
                    583:        gen_op_mulsw_T0_T1();
                    584:        return;
                    585:     case 0x200e:               /* mulu.w Rm,Rn */
                    586:        gen_op_movuw_rN_T0(REG(B7_4));
                    587:        gen_op_movuw_rN_T1(REG(B11_8));
                    588:        gen_op_muluw_T0_T1();
                    589:        return;
                    590:     case 0x600b:               /* neg Rm,Rn */
                    591:        gen_op_movl_rN_T0(REG(B7_4));
                    592:        gen_op_neg_T0();
                    593:        gen_op_movl_T0_rN(REG(B11_8));
                    594:        return;
                    595:     case 0x600a:               /* negc Rm,Rn */
                    596:        gen_op_movl_rN_T0(REG(B7_4));
                    597:        gen_op_negc_T0();
                    598:        gen_op_movl_T0_rN(REG(B11_8));
                    599:        return;
                    600:     case 0x6007:               /* not Rm,Rn */
                    601:        gen_op_movl_rN_T0(REG(B7_4));
                    602:        gen_op_not_T0();
                    603:        gen_op_movl_T0_rN(REG(B11_8));
                    604:        return;
                    605:     case 0x200b:               /* or Rm,Rn */
                    606:        gen_op_movl_rN_T0(REG(B7_4));
                    607:        gen_op_or_T0_rN(REG(B11_8));
                    608:        return;
                    609:     case 0x400c:               /* shad Rm,Rn */
                    610:        gen_op_movl_rN_T0(REG(B7_4));
                    611:        gen_op_movl_rN_T1(REG(B11_8));
                    612:        gen_op_shad_T0_T1();
                    613:        gen_op_movl_T1_rN(REG(B11_8));
                    614:        return;
                    615:     case 0x400d:               /* shld Rm,Rn */
                    616:        gen_op_movl_rN_T0(REG(B7_4));
                    617:        gen_op_movl_rN_T1(REG(B11_8));
                    618:        gen_op_shld_T0_T1();
                    619:        gen_op_movl_T1_rN(REG(B11_8));
                    620:        return;
                    621:     case 0x3008:               /* sub Rm,Rn */
                    622:        gen_op_movl_rN_T0(REG(B7_4));
                    623:        gen_op_sub_T0_rN(REG(B11_8));
                    624:        return;
                    625:     case 0x300a:               /* subc Rm,Rn */
                    626:        gen_op_movl_rN_T0(REG(B7_4));
                    627:        gen_op_movl_rN_T1(REG(B11_8));
                    628:        gen_op_subc_T0_T1();
                    629:        gen_op_movl_T1_rN(REG(B11_8));
                    630:        return;
                    631:     case 0x300b:               /* subv Rm,Rn */
                    632:        gen_op_movl_rN_T0(REG(B7_4));
                    633:        gen_op_movl_rN_T1(REG(B11_8));
                    634:        gen_op_subv_T0_T1();
                    635:        gen_op_movl_T1_rN(REG(B11_8));
                    636:        return;
                    637:     case 0x2008:               /* tst Rm,Rn */
                    638:        gen_op_movl_rN_T0(REG(B7_4));
                    639:        gen_op_movl_rN_T1(REG(B11_8));
                    640:        gen_op_tst_T0_T1();
                    641:        return;
                    642:     case 0x200a:               /* xor Rm,Rn */
                    643:        gen_op_movl_rN_T0(REG(B7_4));
                    644:        gen_op_xor_T0_rN(REG(B11_8));
                    645:        return;
                    646:     }
                    647: 
                    648:     switch (ctx->opcode & 0xff00) {
                    649:     case 0xc900:               /* and #imm,R0 */
                    650:        gen_op_and_imm_rN(B7_0, REG(0));
                    651:        return;
                    652:     case 0xcd00:               /* and.b #imm,@(R0+GBR) */
                    653:        gen_op_movl_rN_T0(REG(0));
                    654:        gen_op_addl_GBR_T0();
                    655:        gen_op_movl_T0_T1();
                    656:        gen_op_ldb_T0_T0(ctx);
                    657:        gen_op_and_imm_T0(B7_0);
                    658:        gen_op_stb_T0_T1(ctx);
                    659:        return;
                    660:     case 0x8b00:               /* bf label */
                    661:        CHECK_NOT_DELAY_SLOT
                    662:            gen_conditional_jump(ctx, ctx->pc + 2,
                    663:                                 ctx->pc + 4 + B7_0s * 2);
                    664:        ctx->flags |= BRANCH_CONDITIONAL;
                    665:        return;
                    666:     case 0x8f00:               /* bf/s label */
                    667:        CHECK_NOT_DELAY_SLOT
                    668:            gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
                    669:        ctx->flags |= DELAY_SLOT_CONDITIONAL;
                    670:        return;
                    671:     case 0x8900:               /* bt label */
                    672:        CHECK_NOT_DELAY_SLOT
                    673:            gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
                    674:                                 ctx->pc + 2);
                    675:        ctx->flags |= BRANCH_CONDITIONAL;
                    676:        return;
                    677:     case 0x8d00:               /* bt/s label */
                    678:        CHECK_NOT_DELAY_SLOT
                    679:            gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
                    680:        ctx->flags |= DELAY_SLOT_CONDITIONAL;
                    681:        return;
                    682:     case 0x8800:               /* cmp/eq #imm,R0 */
                    683:        gen_op_movl_rN_T0(REG(0));
                    684:        gen_op_cmp_eq_imm_T0(B7_0s);
                    685:        return;
                    686:     case 0xc400:               /* mov.b @(disp,GBR),R0 */
                    687:        gen_op_stc_gbr_T0();
                    688:        gen_op_addl_imm_T0(B7_0);
                    689:        gen_op_ldb_T0_T0(ctx);
                    690:        gen_op_movl_T0_rN(REG(0));
                    691:        return;
                    692:     case 0xc500:               /* mov.w @(disp,GBR),R0 */
                    693:        gen_op_stc_gbr_T0();
                    694:        gen_op_addl_imm_T0(B7_0);
                    695:        gen_op_ldw_T0_T0(ctx);
                    696:        gen_op_movl_T0_rN(REG(0));
                    697:        return;
                    698:     case 0xc600:               /* mov.l @(disp,GBR),R0 */
                    699:        gen_op_stc_gbr_T0();
                    700:        gen_op_addl_imm_T0(B7_0);
                    701:        gen_op_ldl_T0_T0(ctx);
                    702:        gen_op_movl_T0_rN(REG(0));
                    703:        return;
                    704:     case 0xc000:               /* mov.b R0,@(disp,GBR) */
                    705:        gen_op_stc_gbr_T0();
                    706:        gen_op_addl_imm_T0(B7_0);
                    707:        gen_op_movl_T0_T1();
                    708:        gen_op_movl_rN_T0(REG(0));
                    709:        gen_op_stb_T0_T1(ctx);
                    710:        return;
                    711:     case 0xc100:               /* mov.w R0,@(disp,GBR) */
                    712:        gen_op_stc_gbr_T0();
                    713:        gen_op_addl_imm_T0(B7_0);
                    714:        gen_op_movl_T0_T1();
                    715:        gen_op_movl_rN_T0(REG(0));
                    716:        gen_op_stw_T0_T1(ctx);
                    717:        return;
                    718:     case 0xc200:               /* mov.l R0,@(disp,GBR) */
                    719:        gen_op_stc_gbr_T0();
                    720:        gen_op_addl_imm_T0(B7_0);
                    721:        gen_op_movl_T0_T1();
                    722:        gen_op_movl_rN_T0(REG(0));
                    723:        gen_op_stl_T0_T1(ctx);
                    724:        return;
                    725:     case 0x8000:               /* mov.b R0,@(disp,Rn) */
                    726:        gen_op_movl_rN_T0(REG(0));
                    727:        gen_op_movl_rN_T1(REG(B7_4));
                    728:        gen_op_addl_imm_T1(B3_0);
                    729:        gen_op_stb_T0_T1(ctx);
                    730:        return;
                    731:     case 0x8100:               /* mov.w R0,@(disp,Rn) */
                    732:        gen_op_movl_rN_T0(REG(0));
                    733:        gen_op_movl_rN_T1(REG(B7_4));
                    734:        gen_op_addl_imm_T1(B3_0 * 2);
                    735:        gen_op_stw_T0_T1(ctx);
                    736:        return;
                    737:     case 0x8400:               /* mov.b @(disp,Rn),R0 */
                    738:        gen_op_movl_rN_T0(REG(0));
                    739:        gen_op_movl_rN_T1(REG(B7_4));
                    740:        gen_op_addl_imm_T1(B3_0);
                    741:        gen_op_stb_T0_T1(ctx);
                    742:        return;
                    743:     case 0x8500:               /* mov.w @(disp,Rn),R0 */
                    744:        gen_op_movl_rN_T0(REG(B7_4));
                    745:        gen_op_addl_imm_T0(B3_0 * 2);
                    746:        gen_op_ldw_T0_T0(ctx);
                    747:        gen_op_movl_T0_rN(REG(0));
                    748:        return;
                    749:     case 0xc700:               /* mova @(disp,PC),R0 */
                    750:        gen_op_movl_imm_rN(((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3,
                    751:                           REG(0));
                    752:        return;
                    753:     case 0xcb00:               /* or #imm,R0 */
                    754:        gen_op_or_imm_rN(B7_0, REG(0));
                    755:        return;
                    756:     case 0xcf00:               /* or.b #imm,@(R0+GBR) */
                    757:        gen_op_movl_rN_T0(REG(0));
                    758:        gen_op_addl_GBR_T0();
                    759:        gen_op_movl_T0_T1();
                    760:        gen_op_ldb_T0_T0(ctx);
                    761:        gen_op_or_imm_T0(B7_0);
                    762:        gen_op_stb_T0_T1(ctx);
                    763:        return;
                    764:     case 0xc300:               /* trapa #imm */
                    765:        CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
                    766:        gen_op_trapa(B7_0);
                    767:        ctx->flags |= BRANCH;
                    768:        return;
                    769:     case 0xc800:               /* tst #imm,R0 */
                    770:        gen_op_tst_imm_rN(B7_0, REG(0));
                    771:        return;
                    772:     case 0xcc00:               /* tst #imm,@(R0+GBR) */
                    773:        gen_op_movl_rN_T0(REG(0));
                    774:        gen_op_addl_GBR_T0();
                    775:        gen_op_ldb_T0_T0(ctx);
                    776:        gen_op_tst_imm_T0(B7_0);
                    777:        return;
                    778:     case 0xca00:               /* xor #imm,R0 */
                    779:        gen_op_xor_imm_rN(B7_0, REG(0));
                    780:        return;
                    781:     case 0xce00:               /* xor.b #imm,@(R0+GBR) */
                    782:        gen_op_movl_rN_T0(REG(0));
                    783:        gen_op_addl_GBR_T0();
                    784:        gen_op_movl_T0_T1();
                    785:        gen_op_ldb_T0_T0(ctx);
                    786:        gen_op_xor_imm_T0(B7_0);
                    787:        gen_op_stb_T0_T1(ctx);
                    788:        return;
                    789:     }
                    790: 
                    791:     switch (ctx->opcode & 0xf08f) {
                    792:     case 0x408e:               /* ldc Rm,Rn_BANK */
                    793:        gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
                    794:        return;
                    795:     case 0x4087:               /* ldc.l @Rm+,Rn_BANK */
                    796:        gen_op_movl_rN_T0(REG(B11_8));
                    797:        gen_op_ldl_T0_T0(ctx);
                    798:        gen_op_movl_T0_rN(ALTREG(B6_4));
                    799:        gen_op_inc4_rN(REG(B11_8));
                    800:        return;
                    801:     case 0x0082:               /* stc Rm_BANK,Rn */
                    802:        gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
                    803:        return;
                    804:     case 0x4083:               /* stc.l Rm_BANK,@-Rn */
                    805:        gen_op_dec4_rN(REG(B11_8));
                    806:        gen_op_movl_rN_T1(REG(B11_8));
                    807:        gen_op_movl_rN_T0(ALTREG(B6_4));
                    808:        gen_op_stl_T0_T1(ctx);
                    809:        return;
                    810:     }
                    811: 
                    812:     switch (ctx->opcode & 0xf0ff) {
                    813:     case 0x0023:               /* braf Rn */
                    814:        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
                    815:        gen_op_braf_T0(ctx->pc + 4);
                    816:        ctx->flags |= DELAY_SLOT;
                    817:        ctx->delayed_pc = (uint32_t) - 1;
                    818:        return;
                    819:     case 0x0003:               /* bsrf Rn */
                    820:        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
                    821:        gen_op_bsrf_T0(ctx->pc + 4);
                    822:        ctx->flags |= DELAY_SLOT;
                    823:        ctx->delayed_pc = (uint32_t) - 1;
                    824:        return;
                    825:     case 0x4015:               /* cmp/pl Rn */
                    826:        gen_op_movl_rN_T0(REG(B11_8));
                    827:        gen_op_cmp_pl_T0();
                    828:        return;
                    829:     case 0x4011:               /* cmp/pz Rn */
                    830:        gen_op_movl_rN_T0(REG(B11_8));
                    831:        gen_op_cmp_pz_T0();
                    832:        return;
                    833:     case 0x4010:               /* dt Rn */
                    834:        gen_op_dt_rN(REG(B11_8));
                    835:        return;
                    836:     case 0x402b:               /* jmp @Rn */
                    837:        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
                    838:        gen_op_jmp_T0();
                    839:        ctx->flags |= DELAY_SLOT;
                    840:        ctx->delayed_pc = (uint32_t) - 1;
                    841:        return;
                    842:     case 0x400b:               /* jsr @Rn */
                    843:        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
                    844:        gen_op_jsr_T0(ctx->pc + 4);
                    845:        ctx->flags |= DELAY_SLOT;
                    846:        ctx->delayed_pc = (uint32_t) - 1;
                    847:        return;
                    848: #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald)  \
                    849:   case ldnum:                                                  \
                    850:     gen_op_movl_rN_T0 (REG(B11_8));                            \
                    851:     gen_op_##ldop##_T0_##reg ();                               \
                    852:     extrald                                                    \
                    853:     return;                                                    \
                    854:   case ldpnum:                                                 \
                    855:     gen_op_movl_rN_T0 (REG(B11_8));                            \
                    856:     gen_op_ldl_T0_T0 (ctx);                                    \
                    857:     gen_op_inc4_rN (REG(B11_8));                               \
                    858:     gen_op_##ldop##_T0_##reg ();                               \
                    859:     extrald                                                    \
                    860:     return;                                                    \
                    861:   case stnum:                                                  \
                    862:     gen_op_##stop##_##reg##_T0 ();                                     \
                    863:     gen_op_movl_T0_rN (REG(B11_8));                            \
                    864:     return;                                                    \
                    865:   case stpnum:                                                 \
                    866:     gen_op_##stop##_##reg##_T0 ();                             \
                    867:     gen_op_dec4_rN (REG(B11_8));                               \
                    868:     gen_op_movl_rN_T1 (REG(B11_8));                            \
                    869:     gen_op_stl_T0_T1 (ctx);                                    \
                    870:     return;
                    871:        LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |=
                    872:             MODE_CHANGE;
                    873:            )
                    874:            LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
                    875:            LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
                    876:            LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
                    877:            LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
                    878:            LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
                    879:            LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
                    880:            LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
                    881:            LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
                    882:     case 0x00c3:               /* movca.l R0,@Rm */
                    883:        gen_op_movl_rN_T0(REG(0));
                    884:        gen_op_movl_rN_T1(REG(B11_8));
                    885:        gen_op_stl_T0_T1(ctx);
                    886:        return;
                    887:     case 0x0029:               /* movt Rn */
                    888:        gen_op_movt_rN(REG(B11_8));
                    889:        return;
                    890:     case 0x0093:               /* ocbi @Rn */
                    891:        gen_op_movl_rN_T0(REG(B11_8));
                    892:        gen_op_ldl_T0_T0(ctx);
                    893:        return;
                    894:     case 0x00a2:               /* ocbp @Rn */
                    895:        gen_op_movl_rN_T0(REG(B11_8));
                    896:        gen_op_ldl_T0_T0(ctx);
                    897:        return;
                    898:     case 0x00b3:               /* ocbwb @Rn */
                    899:        gen_op_movl_rN_T0(REG(B11_8));
                    900:        gen_op_ldl_T0_T0(ctx);
                    901:        return;
                    902:     case 0x0083:               /* pref @Rn */
                    903:        return;
                    904:     case 0x4024:               /* rotcl Rn */
                    905:        gen_op_rotcl_Rn(REG(B11_8));
                    906:        return;
                    907:     case 0x4025:               /* rotcr Rn */
                    908:        gen_op_rotcr_Rn(REG(B11_8));
                    909:        return;
                    910:     case 0x4004:               /* rotl Rn */
                    911:        gen_op_rotl_Rn(REG(B11_8));
                    912:        return;
                    913:     case 0x4005:               /* rotr Rn */
                    914:        gen_op_rotr_Rn(REG(B11_8));
                    915:        return;
                    916:     case 0x4000:               /* shll Rn */
                    917:     case 0x4020:               /* shal Rn */
                    918:        gen_op_shal_Rn(REG(B11_8));
                    919:        return;
                    920:     case 0x4021:               /* shar Rn */
                    921:        gen_op_shar_Rn(REG(B11_8));
                    922:        return;
                    923:     case 0x4001:               /* shlr Rn */
                    924:        gen_op_shlr_Rn(REG(B11_8));
                    925:        return;
                    926:     case 0x4008:               /* shll2 Rn */
                    927:        gen_op_shll2_Rn(REG(B11_8));
                    928:        return;
                    929:     case 0x4018:               /* shll8 Rn */
                    930:        gen_op_shll8_Rn(REG(B11_8));
                    931:        return;
                    932:     case 0x4028:               /* shll16 Rn */
                    933:        gen_op_shll16_Rn(REG(B11_8));
                    934:        return;
                    935:     case 0x4009:               /* shlr2 Rn */
                    936:        gen_op_shlr2_Rn(REG(B11_8));
                    937:        return;
                    938:     case 0x4019:               /* shlr8 Rn */
                    939:        gen_op_shlr8_Rn(REG(B11_8));
                    940:        return;
                    941:     case 0x4029:               /* shlr16 Rn */
                    942:        gen_op_shlr16_Rn(REG(B11_8));
                    943:        return;
                    944:     case 0x401b:               /* tas.b @Rn */
                    945:        gen_op_tasb_rN(REG(B11_8));
                    946:        return;
                    947:     }
                    948: 
                    949:     fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
                    950:            ctx->opcode, ctx->pc);
                    951:     gen_op_raise_illegal_instruction();
                    952:     ctx->flags |= BRANCH_EXCEPTION;
                    953: }
                    954: 
                    955: int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
                    956:                                   int search_pc)
                    957: {
                    958:     DisasContext ctx;
                    959:     target_ulong pc_start;
                    960:     static uint16_t *gen_opc_end;
                    961:     uint32_t old_flags;
                    962:     int i;
                    963: 
                    964:     pc_start = tb->pc;
                    965:     gen_opc_ptr = gen_opc_buf;
                    966:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
                    967:     gen_opparam_ptr = gen_opparam_buf;
                    968:     ctx.pc = pc_start;
                    969:     ctx.flags = env->flags;
                    970:     old_flags = 0;
                    971:     ctx.sr = env->sr;
                    972:     ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
                    973:     ctx.delayed_pc = env->delayed_pc;
                    974:     ctx.tb = tb;
                    975:     ctx.singlestep_enabled = env->singlestep_enabled;
                    976:     nb_gen_labels = 0;
                    977: 
                    978: #ifdef DEBUG_DISAS
                    979:     if (loglevel & CPU_LOG_TB_CPU) {
                    980:        fprintf(logfile,
                    981:                "------------------------------------------------\n");
                    982:        cpu_dump_state(env, logfile, fprintf, 0);
                    983:     }
                    984: #endif
                    985: 
                    986:     while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 &&
                    987:           (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE |
                    988:                         BRANCH_EXCEPTION)) == 0 &&
                    989:           gen_opc_ptr < gen_opc_end && ctx.sr == env->sr) {
                    990:        old_flags = ctx.flags;
                    991:        if (env->nb_breakpoints > 0) {
                    992:            for (i = 0; i < env->nb_breakpoints; i++) {
                    993:                if (ctx.pc == env->breakpoints[i]) {
                    994:                    /* We have hit a breakpoint - make sure PC is up-to-date */
                    995:                    gen_op_movl_imm_PC(ctx.pc);
                    996:                    gen_op_debug();
                    997:                    ctx.flags |= BRANCH_EXCEPTION;
                    998:                    break;
                    999:                }
                   1000:            }
                   1001:        }
                   1002: #if 0
                   1003:        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
                   1004:        fflush(stderr);
                   1005: #endif
                   1006:        ctx.opcode = lduw_code(ctx.pc);
                   1007:        decode_opc(&ctx);
                   1008:        ctx.pc += 2;
                   1009:        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
                   1010:            break;
                   1011:        if (env->singlestep_enabled)
                   1012:            break;
                   1013: #ifdef SH4_SINGLE_STEP
                   1014:        break;
                   1015: #endif
                   1016:     }
                   1017: 
                   1018:     switch (old_flags & (DELAY_SLOT_CONDITIONAL | DELAY_SLOT)) {
                   1019:     case DELAY_SLOT_CONDITIONAL:
                   1020:        gen_op_clr_delay_slot_conditional();
                   1021:        gen_delayed_conditional_jump(&ctx);
                   1022:        break;
                   1023:     case DELAY_SLOT:
                   1024:        gen_op_clr_delay_slot();
                   1025:        gen_jump(&ctx);
                   1026:        break;
                   1027:     case 0:
                   1028:        if (ctx.flags & BRANCH_EXCEPTION) {
                   1029:            gen_jump_exception(&ctx);
                   1030:        } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) {
                   1031:            gen_goto_tb(&ctx, 0, ctx.pc);
                   1032:        }
                   1033:        break;
                   1034:     default:
                   1035:        /* Both cannot be set at the same time */
                   1036:        assert(0);
                   1037:     }
                   1038: 
                   1039:     if (env->singlestep_enabled) {
                   1040:        gen_op_debug();
                   1041:     }
                   1042:     *gen_opc_ptr = INDEX_op_end;
                   1043:     tb->size = ctx.pc - pc_start;
                   1044: 
                   1045: #ifdef DEBUG_DISAS
                   1046: #ifdef SH4_DEBUG_DISAS
                   1047:     if (loglevel & CPU_LOG_TB_IN_ASM)
                   1048:        fprintf(logfile, "\n");
                   1049: #endif
                   1050:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                   1051:        fprintf(logfile, "IN:\n");      /* , lookup_symbol(pc_start)); */
                   1052:        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
                   1053:        fprintf(logfile, "\n");
                   1054:     }
                   1055:     if (loglevel & CPU_LOG_TB_OP) {
                   1056:        fprintf(logfile, "OP:\n");
                   1057:        dump_ops(gen_opc_buf, gen_opparam_buf);
                   1058:        fprintf(logfile, "\n");
                   1059:     }
                   1060: #endif
                   1061:     return 0;
                   1062: }
                   1063: 
                   1064: int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
                   1065: {
                   1066:     return gen_intermediate_code_internal(env, tb, 0);
                   1067: }
                   1068: 
                   1069: int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
                   1070: {
                   1071:     assert(0);
                   1072:     return gen_intermediate_code_internal(env, tb, 1);
                   1073: }

unix.superglobalmegacorp.com

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