Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ ce62e5ba

History | View | Annotate | Download (34 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
#if defined(CONFIG_USER_ONLY)
128
    env->sr = SR_FD;            /* FD - kernel does lazy fpu context switch */
129
#else
130
    env->sr = 0x700000F0;        /* MD, RB, BL, I3-I0 */
131
#endif
132
    env->vbr = 0;
133
    env->pc = 0xA0000000;
134
#if defined(CONFIG_USER_ONLY)
135
    env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
136
    env->fp_status.float_rounding_mode = float_round_nearest_even; /* ?! */
137
#else
138
    env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
139
    env->fp_status.float_rounding_mode = float_round_to_zero;
140
#endif
141
    env->mmucr = 0;
142
}
143

    
144
CPUSH4State *cpu_sh4_init(void)
145
{
146
    CPUSH4State *env;
147

    
148
    env = qemu_mallocz(sizeof(CPUSH4State));
149
    if (!env)
150
        return NULL;
151
    cpu_exec_init(env);
152
    cpu_sh4_reset(env);
153
    tlb_flush(env, 1);
154
    return env;
155
}
156

    
157
static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
158
{
159
    TranslationBlock *tb;
160
    tb = ctx->tb;
161

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

    
179
/* Jump to pc after an exception */
180
static void gen_jump_exception(DisasContext * ctx)
181
{
182
    gen_op_movl_imm_T0(0);
183
    if (ctx->singlestep_enabled)
184
        gen_op_debug();
185
    gen_op_exit_tb();
186
}
187

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

    
203
/* Immediate conditional jump (bt or bf) */
204
static void gen_conditional_jump(DisasContext * ctx,
205
                                 target_ulong ift, target_ulong ifnott)
206
{
207
    int l1;
208

    
209
    l1 = gen_new_label();
210
    gen_op_jT(l1);
211
    gen_goto_tb(ctx, 0, ifnott);
212
    gen_set_label(l1);
213
    gen_goto_tb(ctx, 1, ift);
214
}
215

    
216
/* Delayed conditional jump (bt or bf) */
217
static void gen_delayed_conditional_jump(DisasContext * ctx)
218
{
219
    int l1;
220

    
221
    l1 = gen_new_label();
222
    gen_op_jdelayed(l1);
223
    gen_goto_tb(ctx, 1, ctx->pc);
224
    gen_set_label(l1);
225
    gen_jump(ctx);
226
}
227

    
228
#define B3_0 (ctx->opcode & 0xf)
229
#define B6_4 ((ctx->opcode >> 4) & 0x7)
230
#define B7_4 ((ctx->opcode >> 4) & 0xf)
231
#define B7_0 (ctx->opcode & 0xff)
232
#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
233
#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
234
  (ctx->opcode & 0xfff))
235
#define B11_8 ((ctx->opcode >> 8) & 0xf)
236
#define B15_12 ((ctx->opcode >> 12) & 0xf)
237

    
238
#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
239
                (x) + 16 : (x))
240

    
241
#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
242
                ? (x) + 16 : (x))
243

    
244
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
245
#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
246
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
247
#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
248

    
249
#define CHECK_NOT_DELAY_SLOT \
250
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
251
  {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \
252
   return;}
253

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

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

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

    
764
        switch (ctx->opcode & 0xf00f) {
765
        case 0xf000:                /* fadd Rm,Rn */
766
            ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
767
            break;
768
        case 0xf001:                /* fsub Rm,Rn */
769
            ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
770
            break;
771
        case 0xf002:                /* fmul Rm,Rn */
772
            ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
773
            break;
774
        case 0xf003:                /* fdiv Rm,Rn */
775
            ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
776
            break;
777
        case 0xf004:                /* fcmp/eq Rm,Rn */
778
            return;
779
        case 0xf005:                /* fcmp/gt Rm,Rn */
780
            return;
781
        }
782

    
783
        if (ctx->fpscr & FPSCR_PR) {
784
            gen_op_fmov_DT0_drN(DREG(B11_8));
785
        }
786
        else {
787
            gen_op_fmov_FT0_frN(FREG(B11_8));
788
        }
789
        return;
790
    }
791

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

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

    
956
    switch (ctx->opcode & 0xf0ff) {
957
    case 0x0023:                /* braf Rn */
958
        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
959
        gen_op_braf_T0(ctx->pc + 4);
960
        ctx->flags |= DELAY_SLOT;
961
        ctx->delayed_pc = (uint32_t) - 1;
962
        return;
963
    case 0x0003:                /* bsrf Rn */
964
        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
965
        gen_op_bsrf_T0(ctx->pc + 4);
966
        ctx->flags |= DELAY_SLOT;
967
        ctx->delayed_pc = (uint32_t) - 1;
968
        return;
969
    case 0x4015:                /* cmp/pl Rn */
970
        gen_op_movl_rN_T0(REG(B11_8));
971
        gen_op_cmp_pl_T0();
972
        return;
973
    case 0x4011:                /* cmp/pz Rn */
974
        gen_op_movl_rN_T0(REG(B11_8));
975
        gen_op_cmp_pz_T0();
976
        return;
977
    case 0x4010:                /* dt Rn */
978
        gen_op_dt_rN(REG(B11_8));
979
        return;
980
    case 0x402b:                /* jmp @Rn */
981
        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
982
        gen_op_jmp_T0();
983
        ctx->flags |= DELAY_SLOT;
984
        ctx->delayed_pc = (uint32_t) - 1;
985
        return;
986
    case 0x400b:                /* jsr @Rn */
987
        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
988
        gen_op_jsr_T0(ctx->pc + 4);
989
        ctx->flags |= DELAY_SLOT;
990
        ctx->delayed_pc = (uint32_t) - 1;
991
        return;
992
#define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald)        \
993
  case ldnum:                                                        \
994
    gen_op_movl_rN_T0 (REG(B11_8));                                \
995
    gen_op_##ldop##_T0_##reg ();                                \
996
    extrald                                                        \
997
    return;                                                        \
998
  case ldpnum:                                                        \
999
    gen_op_movl_rN_T0 (REG(B11_8));                                \
1000
    gen_op_ldl_T0_T0 (ctx);                                        \
1001
    gen_op_inc4_rN (REG(B11_8));                                \
1002
    gen_op_##ldop##_T0_##reg ();                                \
1003
    extrald                                                        \
1004
    return;                                                        \
1005
  case stnum:                                                        \
1006
    gen_op_##stop##_##reg##_T0 ();                                        \
1007
    gen_op_movl_T0_rN (REG(B11_8));                                \
1008
    return;                                                        \
1009
  case stpnum:                                                        \
1010
    gen_op_##stop##_##reg##_T0 ();                                \
1011
    gen_op_dec4_rN (REG(B11_8));                                \
1012
    gen_op_movl_rN_T1 (REG(B11_8));                                \
1013
    gen_op_stl_T0_T1 (ctx);                                        \
1014
    return;
1015
        LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |=
1016
             MODE_CHANGE;)
1017
        LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1018
        LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1019
        LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1020
        LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1021
        LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1022
        LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1023
        LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1024
        LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1025
        LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
1026
        LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->flags |=
1027
             MODE_CHANGE;)
1028
    case 0x00c3:                /* movca.l R0,@Rm */
1029
        gen_op_movl_rN_T0(REG(0));
1030
        gen_op_movl_rN_T1(REG(B11_8));
1031
        gen_op_stl_T0_T1(ctx);
1032
        return;
1033
    case 0x0029:                /* movt Rn */
1034
        gen_op_movt_rN(REG(B11_8));
1035
        return;
1036
    case 0x0093:                /* ocbi @Rn */
1037
        gen_op_movl_rN_T0(REG(B11_8));
1038
        gen_op_ldl_T0_T0(ctx);
1039
        return;
1040
    case 0x00a2:                /* ocbp @Rn */
1041
        gen_op_movl_rN_T0(REG(B11_8));
1042
        gen_op_ldl_T0_T0(ctx);
1043
        return;
1044
    case 0x00b3:                /* ocbwb @Rn */
1045
        gen_op_movl_rN_T0(REG(B11_8));
1046
        gen_op_ldl_T0_T0(ctx);
1047
        return;
1048
    case 0x0083:                /* pref @Rn */
1049
        return;
1050
    case 0x4024:                /* rotcl Rn */
1051
        gen_op_rotcl_Rn(REG(B11_8));
1052
        return;
1053
    case 0x4025:                /* rotcr Rn */
1054
        gen_op_rotcr_Rn(REG(B11_8));
1055
        return;
1056
    case 0x4004:                /* rotl Rn */
1057
        gen_op_rotl_Rn(REG(B11_8));
1058
        return;
1059
    case 0x4005:                /* rotr Rn */
1060
        gen_op_rotr_Rn(REG(B11_8));
1061
        return;
1062
    case 0x4000:                /* shll Rn */
1063
    case 0x4020:                /* shal Rn */
1064
        gen_op_shal_Rn(REG(B11_8));
1065
        return;
1066
    case 0x4021:                /* shar Rn */
1067
        gen_op_shar_Rn(REG(B11_8));
1068
        return;
1069
    case 0x4001:                /* shlr Rn */
1070
        gen_op_shlr_Rn(REG(B11_8));
1071
        return;
1072
    case 0x4008:                /* shll2 Rn */
1073
        gen_op_shll2_Rn(REG(B11_8));
1074
        return;
1075
    case 0x4018:                /* shll8 Rn */
1076
        gen_op_shll8_Rn(REG(B11_8));
1077
        return;
1078
    case 0x4028:                /* shll16 Rn */
1079
        gen_op_shll16_Rn(REG(B11_8));
1080
        return;
1081
    case 0x4009:                /* shlr2 Rn */
1082
        gen_op_shlr2_Rn(REG(B11_8));
1083
        return;
1084
    case 0x4019:                /* shlr8 Rn */
1085
        gen_op_shlr8_Rn(REG(B11_8));
1086
        return;
1087
    case 0x4029:                /* shlr16 Rn */
1088
        gen_op_shlr16_Rn(REG(B11_8));
1089
        return;
1090
    case 0x401b:                /* tas.b @Rn */
1091
        gen_op_tasb_rN(REG(B11_8));
1092
        return;
1093
    case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1094
        gen_op_movl_fpul_FT0();
1095
        gen_op_fmov_FT0_frN(FREG(B11_8));
1096
        return;
1097
    case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1098
        gen_op_fmov_frN_FT0(FREG(B11_8));
1099
        gen_op_movl_FT0_fpul();
1100
        return;
1101
    case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1102
        if (ctx->fpscr & FPSCR_PR) {
1103
            if (ctx->opcode & 0x0100)
1104
                break; /* illegal instruction */
1105
            gen_op_float_DT();
1106
            gen_op_fmov_DT0_drN(DREG(B11_8));
1107
        }
1108
        else {
1109
            gen_op_float_FT();
1110
            gen_op_fmov_FT0_frN(FREG(B11_8));
1111
        }
1112
        return;
1113
    case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1114
        if (ctx->fpscr & FPSCR_PR) {
1115
            if (ctx->opcode & 0x0100)
1116
                break; /* illegal instruction */
1117
            gen_op_fmov_drN_DT0(DREG(B11_8));
1118
            gen_op_ftrc_DT();
1119
        }
1120
        else {
1121
            gen_op_fmov_frN_FT0(FREG(B11_8));
1122
            gen_op_ftrc_FT();
1123
        }
1124
        return;
1125
    case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1126
        if (!(ctx->fpscr & FPSCR_PR)) {
1127
            gen_op_movl_imm_T0(0);
1128
            gen_op_fmov_T0_frN(FREG(B11_8));
1129
            return;
1130
        }
1131
        break;
1132
    case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1133
        if (!(ctx->fpscr & FPSCR_PR)) {
1134
            gen_op_movl_imm_T0(0x3f800000);
1135
            gen_op_fmov_T0_frN(FREG(B11_8));
1136
            return;
1137
        }
1138
        break;
1139
    }
1140

    
1141
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1142
            ctx->opcode, ctx->pc);
1143
    gen_op_raise_illegal_instruction();
1144
    ctx->flags |= BRANCH_EXCEPTION;
1145
}
1146

    
1147
static inline int
1148
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1149
                               int search_pc)
1150
{
1151
    DisasContext ctx;
1152
    target_ulong pc_start;
1153
    static uint16_t *gen_opc_end;
1154
    uint32_t old_flags;
1155
    int i, ii;
1156

    
1157
    pc_start = tb->pc;
1158
    gen_opc_ptr = gen_opc_buf;
1159
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1160
    gen_opparam_ptr = gen_opparam_buf;
1161
    ctx.pc = pc_start;
1162
    ctx.flags = env->flags;
1163
    old_flags = 0;
1164
    ctx.sr = env->sr;
1165
    ctx.fpscr = env->fpscr;
1166
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1167
    /* We don't know if the delayed pc came from a dynamic or static branch,
1168
       so assume it is a dynamic branch.  */
1169
    ctx.delayed_pc = -1;
1170
    ctx.tb = tb;
1171
    ctx.singlestep_enabled = env->singlestep_enabled;
1172
    nb_gen_labels = 0;
1173

    
1174
#ifdef DEBUG_DISAS
1175
    if (loglevel & CPU_LOG_TB_CPU) {
1176
        fprintf(logfile,
1177
                "------------------------------------------------\n");
1178
        cpu_dump_state(env, logfile, fprintf, 0);
1179
    }
1180
#endif
1181

    
1182
    ii = -1;
1183
    while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 &&
1184
           (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE |
1185
                         BRANCH_EXCEPTION)) == 0 &&
1186
           gen_opc_ptr < gen_opc_end && ctx.sr == env->sr) {
1187
        old_flags = ctx.flags;
1188
        if (env->nb_breakpoints > 0) {
1189
            for (i = 0; i < env->nb_breakpoints; i++) {
1190
                if (ctx.pc == env->breakpoints[i]) {
1191
                    /* We have hit a breakpoint - make sure PC is up-to-date */
1192
                    gen_op_movl_imm_PC(ctx.pc);
1193
                    gen_op_debug();
1194
                    ctx.flags |= BRANCH_EXCEPTION;
1195
                    break;
1196
                }
1197
            }
1198
        }
1199
        if (search_pc) {
1200
            i = gen_opc_ptr - gen_opc_buf;
1201
            if (ii < i) {
1202
                ii++;
1203
                while (ii < i)
1204
                    gen_opc_instr_start[ii++] = 0;
1205
            }
1206
            gen_opc_pc[ii] = ctx.pc;
1207
            gen_opc_instr_start[ii] = 1;
1208
        }
1209
#if 0
1210
        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1211
        fflush(stderr);
1212
#endif
1213
        ctx.opcode = lduw_code(ctx.pc);
1214
        decode_opc(&ctx);
1215
        ctx.pc += 2;
1216
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1217
            break;
1218
        if (env->singlestep_enabled)
1219
            break;
1220
#ifdef SH4_SINGLE_STEP
1221
        break;
1222
#endif
1223
    }
1224

    
1225
    if (old_flags & DELAY_SLOT_CONDITIONAL) {
1226
        gen_delayed_conditional_jump(&ctx);
1227
    } else if (old_flags & DELAY_SLOT) {
1228
        gen_op_clr_delay_slot();
1229
        gen_jump(&ctx);
1230
    } else if (ctx.flags & BRANCH_EXCEPTION) {
1231
        gen_jump_exception(&ctx);
1232
    } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) {
1233
        gen_goto_tb(&ctx, 0, ctx.pc);
1234
    }
1235

    
1236
    if (env->singlestep_enabled) {
1237
        gen_op_debug();
1238
    }
1239
    *gen_opc_ptr = INDEX_op_end;
1240
    if (search_pc) {
1241
        i = gen_opc_ptr - gen_opc_buf;
1242
        ii++;
1243
        while (ii <= i)
1244
            gen_opc_instr_start[ii++] = 0;
1245
    } else {
1246
        tb->size = ctx.pc - pc_start;
1247
    }
1248

    
1249
#ifdef DEBUG_DISAS
1250
#ifdef SH4_DEBUG_DISAS
1251
    if (loglevel & CPU_LOG_TB_IN_ASM)
1252
        fprintf(logfile, "\n");
1253
#endif
1254
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1255
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1256
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1257
        fprintf(logfile, "\n");
1258
    }
1259
    if (loglevel & CPU_LOG_TB_OP) {
1260
        fprintf(logfile, "OP:\n");
1261
        dump_ops(gen_opc_buf, gen_opparam_buf);
1262
        fprintf(logfile, "\n");
1263
    }
1264
#endif
1265
    return 0;
1266
}
1267

    
1268
int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1269
{
1270
    return gen_intermediate_code_internal(env, tb, 0);
1271
}
1272

    
1273
int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1274
{
1275
    return gen_intermediate_code_internal(env, tb, 1);
1276
}