Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ c5d6edc3

History | View | Annotate | Download (32 kB)

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
    uint32_t fpscr;
58
    uint16_t opcode;
59
    uint32_t flags;
60
    int memidx;
61
    uint32_t delayed_pc;
62
    int singlestep_enabled;
63
} DisasContext;
64

    
65
#ifdef CONFIG_USER_ONLY
66

    
67
#define GEN_OP_LD(width, reg) \
68
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
69
    gen_op_ld##width##_T0_##reg##_raw(); \
70
  }
71
#define GEN_OP_ST(width, reg) \
72
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
73
    gen_op_st##width##_##reg##_T1_raw(); \
74
  }
75

    
76
#else
77

    
78
#define GEN_OP_LD(width, reg) \
79
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
80
    if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
81
    else gen_op_ld##width##_T0_##reg##_user();\
82
  }
83
#define GEN_OP_ST(width, reg) \
84
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
85
    if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
86
    else gen_op_st##width##_##reg##_T1_user();\
87
  }
88

    
89
#endif
90

    
91
GEN_OP_LD(ub, T0)
92
GEN_OP_LD(b, T0)
93
GEN_OP_ST(b, T0)
94
GEN_OP_LD(uw, T0)
95
GEN_OP_LD(w, T0)
96
GEN_OP_ST(w, T0)
97
GEN_OP_LD(l, T0)
98
GEN_OP_ST(l, T0)
99
GEN_OP_LD(fl, FT0)
100
GEN_OP_ST(fl, FT0)
101
GEN_OP_LD(fq, DT0)
102
GEN_OP_ST(fq, DT0)
103

    
104
void cpu_dump_state(CPUState * env, FILE * f,
105
                    int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
106
                    int flags)
107
{
108
    int i;
109
    cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
110
                env->pc, env->sr, env->pr, env->fpscr);
111
    for (i = 0; i < 24; i += 4) {
112
        cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
113
                    i, env->gregs[i], i + 1, env->gregs[i + 1],
114
                    i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
115
    }
116
    if (env->flags & DELAY_SLOT) {
117
        cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
118
                    env->delayed_pc);
119
    } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
120
        cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
121
                    env->delayed_pc);
122
    }
123
}
124

    
125
void cpu_sh4_reset(CPUSH4State * env)
126
{
127
    env->sr = 0x700000F0;        /* MD, RB, BL, I3-I0 */
128
    env->vbr = 0;
129
    env->pc = 0xA0000000;
130
    env->fpscr = 0x00040001;
131
    env->mmucr = 0;
132
}
133

    
134
CPUSH4State *cpu_sh4_init(void)
135
{
136
    CPUSH4State *env;
137

    
138
    env = qemu_mallocz(sizeof(CPUSH4State));
139
    if (!env)
140
        return NULL;
141
    cpu_exec_init(env);
142
    cpu_sh4_reset(env);
143
    tlb_flush(env, 1);
144
    return env;
145
}
146

    
147
#ifdef CONFIG_USER_ONLY
148
target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
149
{
150
    return addr;
151
}
152
#else
153
target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
154
{
155
    target_ulong physical;
156
    int prot;
157

    
158
    get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0);
159
    return physical;
160
}
161
#endif
162

    
163
static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
164
{
165
    TranslationBlock *tb;
166
    tb = ctx->tb;
167

    
168
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
169
        !ctx->singlestep_enabled) {
170
        /* Use a direct jump if in same page and singlestep not enabled */
171
        if (n == 0)
172
            gen_op_goto_tb0(TBPARAM(tb));
173
        else
174
            gen_op_goto_tb1(TBPARAM(tb));
175
        gen_op_movl_imm_T0((long) tb + n);
176
    } else {
177
        gen_op_movl_imm_T0(0);
178
    }
179
    gen_op_movl_imm_PC(dest);
180
    if (ctx->singlestep_enabled)
181
        gen_op_debug();
182
    gen_op_exit_tb();
183
}
184

    
185
/* Jump to pc after an exception */
186
static void gen_jump_exception(DisasContext * ctx)
187
{
188
    gen_op_movl_imm_T0(0);
189
    if (ctx->singlestep_enabled)
190
        gen_op_debug();
191
    gen_op_exit_tb();
192
}
193

    
194
static void gen_jump(DisasContext * ctx)
195
{
196
    if (ctx->delayed_pc == (uint32_t) - 1) {
197
        /* Target is not statically known, it comes necessarily from a
198
           delayed jump as immediate jump are conditinal jumps */
199
        gen_op_movl_delayed_pc_PC();
200
        gen_op_movl_imm_T0(0);
201
        if (ctx->singlestep_enabled)
202
            gen_op_debug();
203
        gen_op_exit_tb();
204
    } else {
205
        gen_goto_tb(ctx, 0, ctx->delayed_pc);
206
    }
207
}
208

    
209
/* Immediate conditional jump (bt or bf) */
210
static void gen_conditional_jump(DisasContext * ctx,
211
                                 target_ulong ift, target_ulong ifnott)
212
{
213
    int l1;
214

    
215
    l1 = gen_new_label();
216
    gen_op_jT(l1);
217
    gen_goto_tb(ctx, 0, ifnott);
218
    gen_set_label(l1);
219
    gen_goto_tb(ctx, 1, ift);
220
}
221

    
222
/* Delayed conditional jump (bt or bf) */
223
static void gen_delayed_conditional_jump(DisasContext * ctx)
224
{
225
    int l1;
226

    
227
    l1 = gen_new_label();
228
    gen_op_jTT2(l1);
229
    gen_goto_tb(ctx, 0, ctx->pc);
230
    gen_set_label(l1);
231
    gen_goto_tb(ctx, 1, ctx->delayed_pc);
232
}
233

    
234
#define B3_0 (ctx->opcode & 0xf)
235
#define B6_4 ((ctx->opcode >> 4) & 0x7)
236
#define B7_4 ((ctx->opcode >> 4) & 0xf)
237
#define B7_0 (ctx->opcode & 0xff)
238
#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
239
#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
240
  (ctx->opcode & 0xfff))
241
#define B11_8 ((ctx->opcode >> 8) & 0xf)
242
#define B15_12 ((ctx->opcode >> 12) & 0xf)
243

    
244
#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
245
                (x) + 16 : (x))
246

    
247
#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
248
                ? (x) + 16 : (x))
249

    
250
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
251
#define XHACK(x) (((x) & 1 ) << 4 | ((x) & 0xe ) << 1)
252
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
253

    
254
#define CHECK_NOT_DELAY_SLOT \
255
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
256
  {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \
257
   return;}
258

    
259
void decode_opc(DisasContext * ctx)
260
{
261
#if 0
262
    fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
263
#endif
264
    switch (ctx->opcode) {
265
    case 0x0019:                /* div0u */
266
        printf("div0u\n");
267
        gen_op_div0u();
268
        return;
269
    case 0x000b:                /* rts */
270
        CHECK_NOT_DELAY_SLOT gen_op_rts();
271
        ctx->flags |= DELAY_SLOT;
272
        ctx->delayed_pc = (uint32_t) - 1;
273
        return;
274
    case 0x0028:                /* clrmac */
275
        gen_op_clrmac();
276
        return;
277
    case 0x0048:                /* clrs */
278
        gen_op_clrs();
279
        return;
280
    case 0x0008:                /* clrt */
281
        gen_op_clrt();
282
        return;
283
    case 0x0038:                /* ldtlb */
284
        assert(0);                /* XXXXX */
285
        return;
286
    case 0x004b:                /* rte */
287
        CHECK_NOT_DELAY_SLOT gen_op_rte();
288
        ctx->flags |= DELAY_SLOT;
289
        ctx->delayed_pc = (uint32_t) - 1;
290
        return;
291
    case 0x0058:                /* sets */
292
        gen_op_sets();
293
        return;
294
    case 0x0018:                /* sett */
295
        gen_op_sett();
296
        return;
297
    case 0xfbfb:                /* frchg */
298
        gen_op_frchg();
299
        ctx->flags |= MODE_CHANGE;
300
        return;
301
    case 0xf3fb:                /* fschg */
302
        gen_op_fschg();
303
        ctx->flags |= MODE_CHANGE;
304
        return;
305
    case 0x0009:                /* nop */
306
        return;
307
    case 0x001b:                /* sleep */
308
        assert(0);                /* XXXXX */
309
        return;
310
    }
311

    
312
    switch (ctx->opcode & 0xf000) {
313
    case 0x1000:                /* mov.l Rm,@(disp,Rn) */
314
        gen_op_movl_rN_T0(REG(B7_4));
315
        gen_op_movl_rN_T1(REG(B11_8));
316
        gen_op_addl_imm_T1(B3_0 * 4);
317
        gen_op_stl_T0_T1(ctx);
318
        return;
319
    case 0x5000:                /* mov.l @(disp,Rm),Rn */
320
        gen_op_movl_rN_T0(REG(B7_4));
321
        gen_op_addl_imm_T0(B3_0 * 4);
322
        gen_op_ldl_T0_T0(ctx);
323
        gen_op_movl_T0_rN(REG(B11_8));
324
        return;
325
    case 0xe000:                /* mov.l #imm,Rn */
326
        gen_op_movl_imm_rN(B7_0s, REG(B11_8));
327
        return;
328
    case 0x9000:                /* mov.w @(disp,PC),Rn */
329
        gen_op_movl_imm_T0(ctx->pc + 4 + B7_0 * 2);
330
        gen_op_ldw_T0_T0(ctx);
331
        gen_op_movl_T0_rN(REG(B11_8));
332
        return;
333
    case 0xd000:                /* mov.l @(disp,PC),Rn */
334
        gen_op_movl_imm_T0((ctx->pc + 4 + B7_0 * 4) & ~3);
335
        gen_op_ldl_T0_T0(ctx);
336
        gen_op_movl_T0_rN(REG(B11_8));
337
        return;
338
    case 0x7000:                /* add.l #imm,Rn */
339
        gen_op_add_imm_rN(B7_0s, REG(B11_8));
340
        return;
341
    case 0xa000:                /* bra disp */
342
        CHECK_NOT_DELAY_SLOT
343
            gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
344
        ctx->flags |= DELAY_SLOT;
345
        return;
346
    case 0xb000:                /* bsr disp */
347
        CHECK_NOT_DELAY_SLOT
348
            gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
349
                       ctx->pc + 4 + B11_0s * 2);
350
        ctx->flags |= DELAY_SLOT;
351
        return;
352
    }
353

    
354
    switch (ctx->opcode & 0xf00f) {
355
    case 0x6003:                /* mov Rm,Rn */
356
        gen_op_movl_rN_T0(REG(B7_4));
357
        gen_op_movl_T0_rN(REG(B11_8));
358
        return;
359
    case 0x2000:                /* mov.b Rm,@Rn */
360
        gen_op_movl_rN_T0(REG(B7_4));
361
        gen_op_movl_rN_T1(REG(B11_8));
362
        gen_op_stb_T0_T1(ctx);
363
        return;
364
    case 0x2001:                /* mov.w Rm,@Rn */
365
        gen_op_movl_rN_T0(REG(B7_4));
366
        gen_op_movl_rN_T1(REG(B11_8));
367
        gen_op_stw_T0_T1(ctx);
368
        return;
369
    case 0x2002:                /* mov.l Rm,@Rn */
370
        gen_op_movl_rN_T0(REG(B7_4));
371
        gen_op_movl_rN_T1(REG(B11_8));
372
        gen_op_stl_T0_T1(ctx);
373
        return;
374
    case 0x6000:                /* mov.b @Rm,Rn */
375
        gen_op_movl_rN_T0(REG(B7_4));
376
        gen_op_ldb_T0_T0(ctx);
377
        gen_op_movl_T0_rN(REG(B11_8));
378
        return;
379
    case 0x6001:                /* mov.w @Rm,Rn */
380
        gen_op_movl_rN_T0(REG(B7_4));
381
        gen_op_ldw_T0_T0(ctx);
382
        gen_op_movl_T0_rN(REG(B11_8));
383
        return;
384
    case 0x6002:                /* mov.l @Rm,Rn */
385
        gen_op_movl_rN_T0(REG(B7_4));
386
        gen_op_ldl_T0_T0(ctx);
387
        gen_op_movl_T0_rN(REG(B11_8));
388
        return;
389
    case 0x2004:                /* mov.b Rm,@-Rn */
390
        gen_op_dec1_rN(REG(B11_8));
391
        gen_op_movl_rN_T0(REG(B7_4));
392
        gen_op_movl_rN_T1(REG(B11_8));
393
        gen_op_stb_T0_T1(ctx);
394
        return;
395
    case 0x2005:                /* mov.w Rm,@-Rn */
396
        gen_op_dec2_rN(REG(B11_8));
397
        gen_op_movl_rN_T0(REG(B7_4));
398
        gen_op_movl_rN_T1(REG(B11_8));
399
        gen_op_stw_T0_T1(ctx);
400
        return;
401
    case 0x2006:                /* mov.l Rm,@-Rn */
402
        gen_op_dec4_rN(REG(B11_8));
403
        gen_op_movl_rN_T0(REG(B7_4));
404
        gen_op_movl_rN_T1(REG(B11_8));
405
        gen_op_stl_T0_T1(ctx);
406
        return;
407
    case 0x6004:                /* mov.b @Rm+,Rn */
408
        gen_op_movl_rN_T0(REG(B7_4));
409
        gen_op_ldb_T0_T0(ctx);
410
        gen_op_movl_T0_rN(REG(B11_8));
411
        gen_op_inc1_rN(REG(B7_4));
412
        return;
413
    case 0x6005:                /* mov.w @Rm+,Rn */
414
        gen_op_movl_rN_T0(REG(B7_4));
415
        gen_op_ldw_T0_T0(ctx);
416
        gen_op_movl_T0_rN(REG(B11_8));
417
        gen_op_inc2_rN(REG(B7_4));
418
        return;
419
    case 0x6006:                /* mov.l @Rm+,Rn */
420
        gen_op_movl_rN_T0(REG(B7_4));
421
        gen_op_ldl_T0_T0(ctx);
422
        gen_op_movl_T0_rN(REG(B11_8));
423
        gen_op_inc4_rN(REG(B7_4));
424
        return;
425
    case 0x0004:                /* mov.b Rm,@(R0,Rn) */
426
        gen_op_movl_rN_T0(REG(B7_4));
427
        gen_op_movl_rN_T1(REG(B11_8));
428
        gen_op_add_rN_T1(REG(0));
429
        gen_op_stb_T0_T1(ctx);
430
        return;
431
    case 0x0005:                /* mov.w Rm,@(R0,Rn) */
432
        gen_op_movl_rN_T0(REG(B7_4));
433
        gen_op_movl_rN_T1(REG(B11_8));
434
        gen_op_add_rN_T1(REG(0));
435
        gen_op_stw_T0_T1(ctx);
436
        return;
437
    case 0x0006:                /* mov.l Rm,@(R0,Rn) */
438
        gen_op_movl_rN_T0(REG(B7_4));
439
        gen_op_movl_rN_T1(REG(B11_8));
440
        gen_op_add_rN_T1(REG(0));
441
        gen_op_stl_T0_T1(ctx);
442
        return;
443
    case 0x000c:                /* mov.b @(R0,Rm),Rn */
444
        gen_op_movl_rN_T0(REG(B7_4));
445
        gen_op_add_rN_T0(REG(0));
446
        gen_op_ldb_T0_T0(ctx);
447
        gen_op_movl_T0_rN(REG(B11_8));
448
        return;
449
    case 0x000d:                /* mov.w @(R0,Rm),Rn */
450
        gen_op_movl_rN_T0(REG(B7_4));
451
        gen_op_add_rN_T0(REG(0));
452
        gen_op_ldw_T0_T0(ctx);
453
        gen_op_movl_T0_rN(REG(B11_8));
454
        return;
455
    case 0x000e:                /* mov.l @(R0,Rm),Rn */
456
        gen_op_movl_rN_T0(REG(B7_4));
457
        gen_op_add_rN_T0(REG(0));
458
        gen_op_ldl_T0_T0(ctx);
459
        gen_op_movl_T0_rN(REG(B11_8));
460
        return;
461
    case 0x6008:                /* swap.b Rm,Rn */
462
        gen_op_movl_rN_T0(REG(B7_4));
463
        gen_op_swapb_T0();
464
        gen_op_movl_T0_rN(REG(B11_8));
465
        return;
466
    case 0x6009:                /* swap.w Rm,Rn */
467
        gen_op_movl_rN_T0(REG(B7_4));
468
        gen_op_swapw_T0();
469
        gen_op_movl_T0_rN(REG(B11_8));
470
        return;
471
    case 0x200d:                /* xtrct Rm,Rn */
472
        gen_op_movl_rN_T0(REG(B7_4));
473
        gen_op_movl_rN_T1(REG(B11_8));
474
        gen_op_xtrct_T0_T1();
475
        gen_op_movl_T1_rN(REG(B11_8));
476
        return;
477
    case 0x300c:                /* add Rm,Rn */
478
        gen_op_movl_rN_T0(REG(B7_4));
479
        gen_op_add_T0_rN(REG(B11_8));
480
        return;
481
    case 0x300e:                /* addc Rm,Rn */
482
        gen_op_movl_rN_T0(REG(B7_4));
483
        gen_op_movl_rN_T1(REG(B11_8));
484
        gen_op_addc_T0_T1();
485
        gen_op_movl_T1_rN(REG(B11_8));
486
        return;
487
    case 0x300f:                /* addv Rm,Rn */
488
        gen_op_movl_rN_T0(REG(B7_4));
489
        gen_op_movl_rN_T1(REG(B11_8));
490
        gen_op_addv_T0_T1();
491
        gen_op_movl_T1_rN(REG(B11_8));
492
        return;
493
    case 0x2009:                /* and Rm,Rn */
494
        gen_op_movl_rN_T0(REG(B7_4));
495
        gen_op_and_T0_rN(REG(B11_8));
496
        return;
497
    case 0x3000:                /* cmp/eq Rm,Rn */
498
        gen_op_movl_rN_T0(REG(B7_4));
499
        gen_op_movl_rN_T1(REG(B11_8));
500
        gen_op_cmp_eq_T0_T1();
501
        return;
502
    case 0x3003:                /* cmp/ge Rm,Rn */
503
        gen_op_movl_rN_T0(REG(B7_4));
504
        gen_op_movl_rN_T1(REG(B11_8));
505
        gen_op_cmp_ge_T0_T1();
506
        return;
507
    case 0x3007:                /* cmp/gt Rm,Rn */
508
        gen_op_movl_rN_T0(REG(B7_4));
509
        gen_op_movl_rN_T1(REG(B11_8));
510
        gen_op_cmp_gt_T0_T1();
511
        return;
512
    case 0x3006:                /* cmp/hi Rm,Rn */
513
        gen_op_movl_rN_T0(REG(B7_4));
514
        gen_op_movl_rN_T1(REG(B11_8));
515
        gen_op_cmp_hi_T0_T1();
516
        return;
517
    case 0x3002:                /* cmp/hs Rm,Rn */
518
        gen_op_movl_rN_T0(REG(B7_4));
519
        gen_op_movl_rN_T1(REG(B11_8));
520
        gen_op_cmp_hs_T0_T1();
521
        return;
522
    case 0x200c:                /* cmp/str Rm,Rn */
523
        gen_op_movl_rN_T0(REG(B7_4));
524
        gen_op_movl_rN_T1(REG(B11_8));
525
        gen_op_cmp_str_T0_T1();
526
        return;
527
    case 0x2007:                /* div0s Rm,Rn */
528
        printf("div0s\n");
529
        gen_op_movl_rN_T0(REG(B7_4));
530
        gen_op_movl_rN_T1(REG(B11_8));
531
        gen_op_div0s_T0_T1();
532
        gen_op_movl_T1_rN(REG(B11_8));
533
        return;
534
    case 0x3004:                /* div1 Rm,Rn */
535
        gen_op_movl_rN_T0(REG(B7_4));
536
        gen_op_movl_rN_T1(REG(B11_8));
537
        gen_op_div1_T0_T1();
538
        gen_op_movl_T1_rN(REG(B11_8));
539
        return;
540
    case 0x300d:                /* dmuls.l Rm,Rn */
541
        gen_op_movl_rN_T0(REG(B7_4));
542
        gen_op_movl_rN_T1(REG(B11_8));
543
        gen_op_dmulsl_T0_T1();
544
        return;
545
    case 0x3005:                /* dmulu.l Rm,Rn */
546
        gen_op_movl_rN_T0(REG(B7_4));
547
        gen_op_movl_rN_T1(REG(B11_8));
548
        gen_op_dmulul_T0_T1();
549
        return;
550
    case 0x600e:                /* exts.b Rm,Rn */
551
        gen_op_movb_rN_T0(REG(B7_4));
552
        gen_op_movl_T0_rN(REG(B11_8));
553
        return;
554
    case 0x600f:                /* exts.w Rm,Rn */
555
        gen_op_movw_rN_T0(REG(B7_4));
556
        gen_op_movl_T0_rN(REG(B11_8));
557
        return;
558
    case 0x600c:                /* extu.b Rm,Rn */
559
        gen_op_movub_rN_T0(REG(B7_4));
560
        gen_op_movl_T0_rN(REG(B11_8));
561
        return;
562
    case 0x600d:                /* extu.w Rm,Rn */
563
        gen_op_movuw_rN_T0(REG(B7_4));
564
        gen_op_movl_T0_rN(REG(B11_8));
565
        return;
566
    case 0x000f:                /* mac.l @Rm+,@Rn- */
567
        gen_op_movl_rN_T0(REG(B11_8));
568
        gen_op_ldl_T0_T0(ctx);
569
        gen_op_movl_T0_T1();
570
        gen_op_movl_rN_T1(REG(B7_4));
571
        gen_op_ldl_T0_T0(ctx);
572
        gen_op_macl_T0_T1();
573
        gen_op_inc4_rN(REG(B7_4));
574
        gen_op_inc4_rN(REG(B11_8));
575
        return;
576
    case 0x400f:                /* mac.w @Rm+,@Rn+ */
577
        gen_op_movl_rN_T0(REG(B11_8));
578
        gen_op_ldl_T0_T0(ctx);
579
        gen_op_movl_T0_T1();
580
        gen_op_movl_rN_T1(REG(B7_4));
581
        gen_op_ldl_T0_T0(ctx);
582
        gen_op_macw_T0_T1();
583
        gen_op_inc2_rN(REG(B7_4));
584
        gen_op_inc2_rN(REG(B11_8));
585
        return;
586
    case 0x0007:                /* mul.l Rm,Rn */
587
        gen_op_movl_rN_T0(REG(B7_4));
588
        gen_op_movl_rN_T1(REG(B11_8));
589
        gen_op_mull_T0_T1();
590
        return;
591
    case 0x200f:                /* muls.w Rm,Rn */
592
        gen_op_movw_rN_T0(REG(B7_4));
593
        gen_op_movw_rN_T1(REG(B11_8));
594
        gen_op_mulsw_T0_T1();
595
        return;
596
    case 0x200e:                /* mulu.w Rm,Rn */
597
        gen_op_movuw_rN_T0(REG(B7_4));
598
        gen_op_movuw_rN_T1(REG(B11_8));
599
        gen_op_muluw_T0_T1();
600
        return;
601
    case 0x600b:                /* neg Rm,Rn */
602
        gen_op_movl_rN_T0(REG(B7_4));
603
        gen_op_neg_T0();
604
        gen_op_movl_T0_rN(REG(B11_8));
605
        return;
606
    case 0x600a:                /* negc Rm,Rn */
607
        gen_op_movl_rN_T0(REG(B7_4));
608
        gen_op_negc_T0();
609
        gen_op_movl_T0_rN(REG(B11_8));
610
        return;
611
    case 0x6007:                /* not Rm,Rn */
612
        gen_op_movl_rN_T0(REG(B7_4));
613
        gen_op_not_T0();
614
        gen_op_movl_T0_rN(REG(B11_8));
615
        return;
616
    case 0x200b:                /* or Rm,Rn */
617
        gen_op_movl_rN_T0(REG(B7_4));
618
        gen_op_or_T0_rN(REG(B11_8));
619
        return;
620
    case 0x400c:                /* shad Rm,Rn */
621
        gen_op_movl_rN_T0(REG(B7_4));
622
        gen_op_movl_rN_T1(REG(B11_8));
623
        gen_op_shad_T0_T1();
624
        gen_op_movl_T1_rN(REG(B11_8));
625
        return;
626
    case 0x400d:                /* shld Rm,Rn */
627
        gen_op_movl_rN_T0(REG(B7_4));
628
        gen_op_movl_rN_T1(REG(B11_8));
629
        gen_op_shld_T0_T1();
630
        gen_op_movl_T1_rN(REG(B11_8));
631
        return;
632
    case 0x3008:                /* sub Rm,Rn */
633
        gen_op_movl_rN_T0(REG(B7_4));
634
        gen_op_sub_T0_rN(REG(B11_8));
635
        return;
636
    case 0x300a:                /* subc Rm,Rn */
637
        gen_op_movl_rN_T0(REG(B7_4));
638
        gen_op_movl_rN_T1(REG(B11_8));
639
        gen_op_subc_T0_T1();
640
        gen_op_movl_T1_rN(REG(B11_8));
641
        return;
642
    case 0x300b:                /* subv Rm,Rn */
643
        gen_op_movl_rN_T0(REG(B7_4));
644
        gen_op_movl_rN_T1(REG(B11_8));
645
        gen_op_subv_T0_T1();
646
        gen_op_movl_T1_rN(REG(B11_8));
647
        return;
648
    case 0x2008:                /* tst Rm,Rn */
649
        gen_op_movl_rN_T0(REG(B7_4));
650
        gen_op_movl_rN_T1(REG(B11_8));
651
        gen_op_tst_T0_T1();
652
        return;
653
    case 0x200a:                /* xor Rm,Rn */
654
        gen_op_movl_rN_T0(REG(B7_4));
655
        gen_op_xor_T0_rN(REG(B11_8));
656
        return;
657
    case 0xf00c:                /* fmov {F,D,X}Rm,{F,D,X}Rn */
658
        if (ctx->fpscr & FPSCR_PR) {
659
            gen_op_fmov_drN_DT0(XREG(B7_4));
660
            gen_op_fmov_DT0_drN(XREG(B11_8));
661
        } else if (ctx->fpscr & FPSCR_SZ) {
662
            if (ctx->opcode & 0x0110)
663
                break; /* illegal instruction */
664
            gen_op_fmov_drN_DT0(XREG(B7_4));
665
            gen_op_fmov_DT0_drN(XREG(B11_8));
666
        } else {
667
            gen_op_fmov_frN_FT0(FREG(B7_4));
668
            gen_op_fmov_FT0_frN(FREG(B11_8));
669
        }
670
        return;
671
    case 0xf00a:                /* fmov {F,D,X}Rm,@Rn */
672
        if (ctx->fpscr & FPSCR_PR) {
673
            gen_op_fmov_drN_DT0(XREG(B7_4));
674
            gen_op_movl_rN_T1(REG(B11_8));
675
            gen_op_stfq_DT0_T1(ctx);
676
        } else if (ctx->fpscr & FPSCR_SZ) {
677
            if (ctx->opcode & 0x0010)
678
                break; /* illegal instruction */
679
            gen_op_fmov_drN_DT0(XREG(B7_4));
680
            gen_op_movl_rN_T1(REG(B11_8));
681
            gen_op_stfq_DT0_T1(ctx);
682
        } else {
683
            gen_op_fmov_frN_FT0(FREG(B7_4));
684
            gen_op_movl_rN_T1(REG(B11_8));
685
            gen_op_stfl_FT0_T1(ctx);
686
        }
687
        return;
688
    case 0xf008:                /* fmov @Rm,{F,D,X}Rn */
689
        if (ctx->fpscr & FPSCR_PR) {
690
            gen_op_movl_rN_T0(REG(B7_4));
691
            gen_op_ldfq_T0_DT0(ctx);
692
            gen_op_fmov_DT0_drN(XREG(B11_8));
693
        } else if (ctx->fpscr & FPSCR_SZ) {
694
            if (ctx->opcode & 0x0100)
695
                break; /* illegal instruction */
696
            gen_op_movl_rN_T0(REG(B7_4));
697
            gen_op_ldfq_T0_DT0(ctx);
698
            gen_op_fmov_DT0_drN(XREG(B11_8));
699
        } else {
700
            gen_op_movl_rN_T0(REG(B7_4));
701
            gen_op_ldfl_T0_FT0(ctx);
702
            gen_op_fmov_FT0_frN(XREG(B11_8));
703
        }
704
        return;
705
    case 0xf009:                /* fmov @Rm+,{F,D,X}Rn */
706
        if (ctx->fpscr & FPSCR_PR) {
707
            gen_op_movl_rN_T0(REG(B7_4));
708
            gen_op_ldfq_T0_DT0(ctx);
709
            gen_op_fmov_DT0_drN(XREG(B11_8));
710
            gen_op_inc8_rN(REG(B7_4));
711
        } else if (ctx->fpscr & FPSCR_SZ) {
712
            if (ctx->opcode & 0x0100)
713
                break; /* illegal instruction */
714
            gen_op_movl_rN_T0(REG(B7_4));
715
            gen_op_ldfq_T0_DT0(ctx);
716
            gen_op_fmov_DT0_drN(XREG(B11_8));
717
            gen_op_inc8_rN(REG(B7_4));
718
        } else {
719
            gen_op_movl_rN_T0(REG(B7_4));
720
            gen_op_ldfl_T0_FT0(ctx);
721
            gen_op_fmov_FT0_frN(XREG(B11_8));
722
            gen_op_inc4_rN(REG(B7_4));
723
        }
724
        return;
725
    case 0xf00b:                /* fmov {F,D,X}Rm,@-Rn */
726
        if (ctx->fpscr & FPSCR_PR) {
727
            gen_op_dec8_rN(REG(B11_8));
728
            gen_op_fmov_drN_DT0(XREG(B7_4));
729
            gen_op_movl_rN_T1(REG(B11_8));
730
            gen_op_stfq_DT0_T1(ctx);
731
        } else if (ctx->fpscr & FPSCR_SZ) {
732
            if (ctx->opcode & 0x0100)
733
                break; /* illegal instruction */
734
            gen_op_dec8_rN(REG(B11_8));
735
            gen_op_fmov_drN_DT0(XREG(B7_4));
736
            gen_op_movl_rN_T1(REG(B11_8));
737
            gen_op_stfq_DT0_T1(ctx);
738
        } else {
739
            gen_op_dec4_rN(REG(B11_8));
740
            gen_op_fmov_frN_FT0(FREG(B7_4));
741
            gen_op_movl_rN_T1(REG(B11_8));
742
            gen_op_stfl_FT0_T1(ctx);
743
        }
744
        return;
745
    case 0xf006:                /* fmov @(R0,Rm),{F,D,X}Rm */
746
        if (ctx->fpscr & FPSCR_PR) {
747
            gen_op_movl_rN_T0(REG(B7_4));
748
            gen_op_add_rN_T0(REG(0));
749
            gen_op_ldfq_T0_DT0(ctx);
750
            gen_op_fmov_DT0_drN(XREG(B11_8));
751
        } else if (ctx->fpscr & FPSCR_SZ) {
752
            if (ctx->opcode & 0x0100)
753
                break; /* illegal instruction */
754
            gen_op_movl_rN_T0(REG(B7_4));
755
            gen_op_add_rN_T0(REG(0));
756
            gen_op_ldfq_T0_DT0(ctx);
757
            gen_op_fmov_DT0_drN(XREG(B11_8));
758
        } else {
759
            gen_op_movl_rN_T0(REG(B7_4));
760
            gen_op_add_rN_T0(REG(0));
761
            gen_op_ldfl_T0_FT0(ctx);
762
            gen_op_fmov_FT0_frN(XREG(B11_8));
763
        }
764
        return;
765
    case 0xf007:                /* fmov {F,D,X}Rn,@(R0,Rn) */
766
        if (ctx->fpscr & FPSCR_PR) {
767
            gen_op_fmov_drN_DT0(XREG(B7_4));
768
            gen_op_movl_rN_T1(REG(B11_8));
769
            gen_op_add_rN_T1(REG(0));
770
            gen_op_stfq_DT0_T1(ctx);
771
        } else if (ctx->fpscr & FPSCR_SZ) {
772
            if (ctx->opcode & 0x0010)
773
                break; /* illegal instruction */
774
            gen_op_fmov_drN_DT0(XREG(B7_4));
775
            gen_op_movl_rN_T1(REG(B11_8));
776
            gen_op_add_rN_T1(REG(0));
777
            gen_op_stfq_DT0_T1(ctx);
778
        } else {
779
            gen_op_fmov_frN_FT0(FREG(B7_4));
780
            gen_op_movl_rN_T1(REG(B11_8));
781
            gen_op_add_rN_T1(REG(0));
782
            gen_op_stfl_FT0_T1(ctx);
783
        }
784
        return;
785
    }
786

    
787
    switch (ctx->opcode & 0xff00) {
788
    case 0xc900:                /* and #imm,R0 */
789
        gen_op_and_imm_rN(B7_0, REG(0));
790
        return;
791
    case 0xcd00:                /* and.b #imm,@(R0+GBR) */
792
        gen_op_movl_rN_T0(REG(0));
793
        gen_op_addl_GBR_T0();
794
        gen_op_movl_T0_T1();
795
        gen_op_ldb_T0_T0(ctx);
796
        gen_op_and_imm_T0(B7_0);
797
        gen_op_stb_T0_T1(ctx);
798
        return;
799
    case 0x8b00:                /* bf label */
800
        CHECK_NOT_DELAY_SLOT
801
            gen_conditional_jump(ctx, ctx->pc + 2,
802
                                 ctx->pc + 4 + B7_0s * 2);
803
        ctx->flags |= BRANCH_CONDITIONAL;
804
        return;
805
    case 0x8f00:                /* bf/s label */
806
        CHECK_NOT_DELAY_SLOT
807
            gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
808
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
809
        return;
810
    case 0x8900:                /* bt label */
811
        CHECK_NOT_DELAY_SLOT
812
            gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
813
                                 ctx->pc + 2);
814
        ctx->flags |= BRANCH_CONDITIONAL;
815
        return;
816
    case 0x8d00:                /* bt/s label */
817
        CHECK_NOT_DELAY_SLOT
818
            gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
819
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
820
        return;
821
    case 0x8800:                /* cmp/eq #imm,R0 */
822
        gen_op_movl_rN_T0(REG(0));
823
        gen_op_cmp_eq_imm_T0(B7_0s);
824
        return;
825
    case 0xc400:                /* mov.b @(disp,GBR),R0 */
826
        gen_op_stc_gbr_T0();
827
        gen_op_addl_imm_T0(B7_0);
828
        gen_op_ldb_T0_T0(ctx);
829
        gen_op_movl_T0_rN(REG(0));
830
        return;
831
    case 0xc500:                /* mov.w @(disp,GBR),R0 */
832
        gen_op_stc_gbr_T0();
833
        gen_op_addl_imm_T0(B7_0);
834
        gen_op_ldw_T0_T0(ctx);
835
        gen_op_movl_T0_rN(REG(0));
836
        return;
837
    case 0xc600:                /* mov.l @(disp,GBR),R0 */
838
        gen_op_stc_gbr_T0();
839
        gen_op_addl_imm_T0(B7_0);
840
        gen_op_ldl_T0_T0(ctx);
841
        gen_op_movl_T0_rN(REG(0));
842
        return;
843
    case 0xc000:                /* mov.b R0,@(disp,GBR) */
844
        gen_op_stc_gbr_T0();
845
        gen_op_addl_imm_T0(B7_0);
846
        gen_op_movl_T0_T1();
847
        gen_op_movl_rN_T0(REG(0));
848
        gen_op_stb_T0_T1(ctx);
849
        return;
850
    case 0xc100:                /* mov.w R0,@(disp,GBR) */
851
        gen_op_stc_gbr_T0();
852
        gen_op_addl_imm_T0(B7_0);
853
        gen_op_movl_T0_T1();
854
        gen_op_movl_rN_T0(REG(0));
855
        gen_op_stw_T0_T1(ctx);
856
        return;
857
    case 0xc200:                /* mov.l R0,@(disp,GBR) */
858
        gen_op_stc_gbr_T0();
859
        gen_op_addl_imm_T0(B7_0);
860
        gen_op_movl_T0_T1();
861
        gen_op_movl_rN_T0(REG(0));
862
        gen_op_stl_T0_T1(ctx);
863
        return;
864
    case 0x8000:                /* mov.b R0,@(disp,Rn) */
865
        gen_op_movl_rN_T0(REG(0));
866
        gen_op_movl_rN_T1(REG(B7_4));
867
        gen_op_addl_imm_T1(B3_0);
868
        gen_op_stb_T0_T1(ctx);
869
        return;
870
    case 0x8100:                /* mov.w 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 * 2);
874
        gen_op_stw_T0_T1(ctx);
875
        return;
876
    case 0x8400:                /* mov.b @(disp,Rn),R0 */
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);
880
        gen_op_stb_T0_T1(ctx);
881
        return;
882
    case 0x8500:                /* mov.w @(disp,Rn),R0 */
883
        gen_op_movl_rN_T0(REG(B7_4));
884
        gen_op_addl_imm_T0(B3_0 * 2);
885
        gen_op_ldw_T0_T0(ctx);
886
        gen_op_movl_T0_rN(REG(0));
887
        return;
888
    case 0xc700:                /* mova @(disp,PC),R0 */
889
        gen_op_movl_imm_rN(((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3,
890
                           REG(0));
891
        return;
892
    case 0xcb00:                /* or #imm,R0 */
893
        gen_op_or_imm_rN(B7_0, REG(0));
894
        return;
895
    case 0xcf00:                /* or.b #imm,@(R0+GBR) */
896
        gen_op_movl_rN_T0(REG(0));
897
        gen_op_addl_GBR_T0();
898
        gen_op_movl_T0_T1();
899
        gen_op_ldb_T0_T0(ctx);
900
        gen_op_or_imm_T0(B7_0);
901
        gen_op_stb_T0_T1(ctx);
902
        return;
903
    case 0xc300:                /* trapa #imm */
904
        CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
905
        gen_op_trapa(B7_0);
906
        ctx->flags |= BRANCH;
907
        return;
908
    case 0xc800:                /* tst #imm,R0 */
909
        gen_op_tst_imm_rN(B7_0, REG(0));
910
        return;
911
    case 0xcc00:                /* tst #imm,@(R0+GBR) */
912
        gen_op_movl_rN_T0(REG(0));
913
        gen_op_addl_GBR_T0();
914
        gen_op_ldb_T0_T0(ctx);
915
        gen_op_tst_imm_T0(B7_0);
916
        return;
917
    case 0xca00:                /* xor #imm,R0 */
918
        gen_op_xor_imm_rN(B7_0, REG(0));
919
        return;
920
    case 0xce00:                /* xor.b #imm,@(R0+GBR) */
921
        gen_op_movl_rN_T0(REG(0));
922
        gen_op_addl_GBR_T0();
923
        gen_op_movl_T0_T1();
924
        gen_op_ldb_T0_T0(ctx);
925
        gen_op_xor_imm_T0(B7_0);
926
        gen_op_stb_T0_T1(ctx);
927
        return;
928
    }
929

    
930
    switch (ctx->opcode & 0xf08f) {
931
    case 0x408e:                /* ldc Rm,Rn_BANK */
932
        gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
933
        return;
934
    case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
935
        gen_op_movl_rN_T0(REG(B11_8));
936
        gen_op_ldl_T0_T0(ctx);
937
        gen_op_movl_T0_rN(ALTREG(B6_4));
938
        gen_op_inc4_rN(REG(B11_8));
939
        return;
940
    case 0x0082:                /* stc Rm_BANK,Rn */
941
        gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
942
        return;
943
    case 0x4083:                /* stc.l Rm_BANK,@-Rn */
944
        gen_op_dec4_rN(REG(B11_8));
945
        gen_op_movl_rN_T1(REG(B11_8));
946
        gen_op_movl_rN_T0(ALTREG(B6_4));
947
        gen_op_stl_T0_T1(ctx);
948
        return;
949
    }
950

    
951
    switch (ctx->opcode & 0xf0ff) {
952
    case 0x0023:                /* braf Rn */
953
        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
954
        gen_op_braf_T0(ctx->pc + 4);
955
        ctx->flags |= DELAY_SLOT;
956
        ctx->delayed_pc = (uint32_t) - 1;
957
        return;
958
    case 0x0003:                /* bsrf Rn */
959
        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
960
        gen_op_bsrf_T0(ctx->pc + 4);
961
        ctx->flags |= DELAY_SLOT;
962
        ctx->delayed_pc = (uint32_t) - 1;
963
        return;
964
    case 0x4015:                /* cmp/pl Rn */
965
        gen_op_movl_rN_T0(REG(B11_8));
966
        gen_op_cmp_pl_T0();
967
        return;
968
    case 0x4011:                /* cmp/pz Rn */
969
        gen_op_movl_rN_T0(REG(B11_8));
970
        gen_op_cmp_pz_T0();
971
        return;
972
    case 0x4010:                /* dt Rn */
973
        gen_op_dt_rN(REG(B11_8));
974
        return;
975
    case 0x402b:                /* jmp @Rn */
976
        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
977
        gen_op_jmp_T0();
978
        ctx->flags |= DELAY_SLOT;
979
        ctx->delayed_pc = (uint32_t) - 1;
980
        return;
981
    case 0x400b:                /* jsr @Rn */
982
        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
983
        gen_op_jsr_T0(ctx->pc + 4);
984
        ctx->flags |= DELAY_SLOT;
985
        ctx->delayed_pc = (uint32_t) - 1;
986
        return;
987
#define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald)        \
988
  case ldnum:                                                        \
989
    gen_op_movl_rN_T0 (REG(B11_8));                                \
990
    gen_op_##ldop##_T0_##reg ();                                \
991
    extrald                                                        \
992
    return;                                                        \
993
  case ldpnum:                                                        \
994
    gen_op_movl_rN_T0 (REG(B11_8));                                \
995
    gen_op_ldl_T0_T0 (ctx);                                        \
996
    gen_op_inc4_rN (REG(B11_8));                                \
997
    gen_op_##ldop##_T0_##reg ();                                \
998
    extrald                                                        \
999
    return;                                                        \
1000
  case stnum:                                                        \
1001
    gen_op_##stop##_##reg##_T0 ();                                        \
1002
    gen_op_movl_T0_rN (REG(B11_8));                                \
1003
    return;                                                        \
1004
  case stpnum:                                                        \
1005
    gen_op_##stop##_##reg##_T0 ();                                \
1006
    gen_op_dec4_rN (REG(B11_8));                                \
1007
    gen_op_movl_rN_T1 (REG(B11_8));                                \
1008
    gen_op_stl_T0_T1 (ctx);                                        \
1009
    return;
1010
        LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |=
1011
             MODE_CHANGE;)
1012
        LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1013
        LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1014
        LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1015
        LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1016
        LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1017
        LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1018
        LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1019
        LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1020
        LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x0052, sts,)
1021
        LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x0062, sts, ctx->flags |=
1022
             MODE_CHANGE;)
1023
    case 0x00c3:                /* movca.l R0,@Rm */
1024
        gen_op_movl_rN_T0(REG(0));
1025
        gen_op_movl_rN_T1(REG(B11_8));
1026
        gen_op_stl_T0_T1(ctx);
1027
        return;
1028
    case 0x0029:                /* movt Rn */
1029
        gen_op_movt_rN(REG(B11_8));
1030
        return;
1031
    case 0x0093:                /* ocbi @Rn */
1032
        gen_op_movl_rN_T0(REG(B11_8));
1033
        gen_op_ldl_T0_T0(ctx);
1034
        return;
1035
    case 0x00a2:                /* ocbp @Rn */
1036
        gen_op_movl_rN_T0(REG(B11_8));
1037
        gen_op_ldl_T0_T0(ctx);
1038
        return;
1039
    case 0x00b3:                /* ocbwb @Rn */
1040
        gen_op_movl_rN_T0(REG(B11_8));
1041
        gen_op_ldl_T0_T0(ctx);
1042
        return;
1043
    case 0x0083:                /* pref @Rn */
1044
        return;
1045
    case 0x4024:                /* rotcl Rn */
1046
        gen_op_rotcl_Rn(REG(B11_8));
1047
        return;
1048
    case 0x4025:                /* rotcr Rn */
1049
        gen_op_rotcr_Rn(REG(B11_8));
1050
        return;
1051
    case 0x4004:                /* rotl Rn */
1052
        gen_op_rotl_Rn(REG(B11_8));
1053
        return;
1054
    case 0x4005:                /* rotr Rn */
1055
        gen_op_rotr_Rn(REG(B11_8));
1056
        return;
1057
    case 0x4000:                /* shll Rn */
1058
    case 0x4020:                /* shal Rn */
1059
        gen_op_shal_Rn(REG(B11_8));
1060
        return;
1061
    case 0x4021:                /* shar Rn */
1062
        gen_op_shar_Rn(REG(B11_8));
1063
        return;
1064
    case 0x4001:                /* shlr Rn */
1065
        gen_op_shlr_Rn(REG(B11_8));
1066
        return;
1067
    case 0x4008:                /* shll2 Rn */
1068
        gen_op_shll2_Rn(REG(B11_8));
1069
        return;
1070
    case 0x4018:                /* shll8 Rn */
1071
        gen_op_shll8_Rn(REG(B11_8));
1072
        return;
1073
    case 0x4028:                /* shll16 Rn */
1074
        gen_op_shll16_Rn(REG(B11_8));
1075
        return;
1076
    case 0x4009:                /* shlr2 Rn */
1077
        gen_op_shlr2_Rn(REG(B11_8));
1078
        return;
1079
    case 0x4019:                /* shlr8 Rn */
1080
        gen_op_shlr8_Rn(REG(B11_8));
1081
        return;
1082
    case 0x4029:                /* shlr16 Rn */
1083
        gen_op_shlr16_Rn(REG(B11_8));
1084
        return;
1085
    case 0x401b:                /* tas.b @Rn */
1086
        gen_op_tasb_rN(REG(B11_8));
1087
        return;
1088
    case 0xf00d:                /* fsts FPUL,FRn */
1089
        gen_op_movl_fpul_FT0();
1090
        gen_op_fmov_FT0_frN(FREG(B11_8));
1091
        return;
1092
    case 0xf01d:                /* flds FRm.FPUL */
1093
        gen_op_fmov_frN_FT0(FREG(B11_8));
1094
        gen_op_movl_FT0_fpul();
1095
        return;
1096
    }
1097

    
1098
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1099
            ctx->opcode, ctx->pc);
1100
    gen_op_raise_illegal_instruction();
1101
    ctx->flags |= BRANCH_EXCEPTION;
1102
}
1103

    
1104
int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1105
                                   int search_pc)
1106
{
1107
    DisasContext ctx;
1108
    target_ulong pc_start;
1109
    static uint16_t *gen_opc_end;
1110
    uint32_t old_flags;
1111
    int i;
1112

    
1113
    pc_start = tb->pc;
1114
    gen_opc_ptr = gen_opc_buf;
1115
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1116
    gen_opparam_ptr = gen_opparam_buf;
1117
    ctx.pc = pc_start;
1118
    ctx.flags = env->flags;
1119
    old_flags = 0;
1120
    ctx.sr = env->sr;
1121
    ctx.fpscr = env->fpscr;
1122
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1123
    ctx.delayed_pc = env->delayed_pc;
1124
    ctx.tb = tb;
1125
    ctx.singlestep_enabled = env->singlestep_enabled;
1126
    nb_gen_labels = 0;
1127

    
1128
#ifdef DEBUG_DISAS
1129
    if (loglevel & CPU_LOG_TB_CPU) {
1130
        fprintf(logfile,
1131
                "------------------------------------------------\n");
1132
        cpu_dump_state(env, logfile, fprintf, 0);
1133
    }
1134
#endif
1135

    
1136
    while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 &&
1137
           (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE |
1138
                         BRANCH_EXCEPTION)) == 0 &&
1139
           gen_opc_ptr < gen_opc_end && ctx.sr == env->sr) {
1140
        old_flags = ctx.flags;
1141
        if (env->nb_breakpoints > 0) {
1142
            for (i = 0; i < env->nb_breakpoints; i++) {
1143
                if (ctx.pc == env->breakpoints[i]) {
1144
                    /* We have hit a breakpoint - make sure PC is up-to-date */
1145
                    gen_op_movl_imm_PC(ctx.pc);
1146
                    gen_op_debug();
1147
                    ctx.flags |= BRANCH_EXCEPTION;
1148
                    break;
1149
                }
1150
            }
1151
        }
1152
#if 0
1153
        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1154
        fflush(stderr);
1155
#endif
1156
        ctx.opcode = lduw_code(ctx.pc);
1157
        decode_opc(&ctx);
1158
        ctx.pc += 2;
1159
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1160
            break;
1161
        if (env->singlestep_enabled)
1162
            break;
1163
#ifdef SH4_SINGLE_STEP
1164
        break;
1165
#endif
1166
    }
1167

    
1168
    switch (old_flags & (DELAY_SLOT_CONDITIONAL | DELAY_SLOT)) {
1169
    case DELAY_SLOT_CONDITIONAL:
1170
        gen_op_clr_delay_slot_conditional();
1171
        gen_delayed_conditional_jump(&ctx);
1172
        break;
1173
    case DELAY_SLOT:
1174
        gen_op_clr_delay_slot();
1175
        gen_jump(&ctx);
1176
        break;
1177
    case 0:
1178
        if (ctx.flags & BRANCH_EXCEPTION) {
1179
            gen_jump_exception(&ctx);
1180
        } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) {
1181
            gen_goto_tb(&ctx, 0, ctx.pc);
1182
        }
1183
        break;
1184
    default:
1185
        /* Both cannot be set at the same time */
1186
        assert(0);
1187
    }
1188

    
1189
    if (env->singlestep_enabled) {
1190
        gen_op_debug();
1191
    }
1192
    *gen_opc_ptr = INDEX_op_end;
1193
    tb->size = ctx.pc - pc_start;
1194

    
1195
#ifdef DEBUG_DISAS
1196
#ifdef SH4_DEBUG_DISAS
1197
    if (loglevel & CPU_LOG_TB_IN_ASM)
1198
        fprintf(logfile, "\n");
1199
#endif
1200
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1201
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1202
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1203
        fprintf(logfile, "\n");
1204
    }
1205
    if (loglevel & CPU_LOG_TB_OP) {
1206
        fprintf(logfile, "OP:\n");
1207
        dump_ops(gen_opc_buf, gen_opparam_buf);
1208
        fprintf(logfile, "\n");
1209
    }
1210
#endif
1211
    return 0;
1212
}
1213

    
1214
int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1215
{
1216
    return gen_intermediate_code_internal(env, tb, 0);
1217
}
1218

    
1219
int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1220
{
1221
    assert(0);
1222
    return gen_intermediate_code_internal(env, tb, 1);
1223
}