Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ 820e00f2

History | View | Annotate | Download (32.2 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 = 0x00000000;
129
#else
130
    env->sr = 0x700000F0;        /* MD, RB, BL, I3-I0 */
131
#endif
132
    env->vbr = 0;
133
    env->pc = 0xA0000000;
134
    env->fpscr = 0x00040001;
135
    env->mmucr = 0;
136
}
137

    
138
CPUSH4State *cpu_sh4_init(void)
139
{
140
    CPUSH4State *env;
141

    
142
    env = qemu_mallocz(sizeof(CPUSH4State));
143
    if (!env)
144
        return NULL;
145
    cpu_exec_init(env);
146
    cpu_sh4_reset(env);
147
    tlb_flush(env, 1);
148
    return env;
149
}
150

    
151
static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
152
{
153
    TranslationBlock *tb;
154
    tb = ctx->tb;
155

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

    
173
/* Jump to pc after an exception */
174
static void gen_jump_exception(DisasContext * ctx)
175
{
176
    gen_op_movl_imm_T0(0);
177
    if (ctx->singlestep_enabled)
178
        gen_op_debug();
179
    gen_op_exit_tb();
180
}
181

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

    
197
/* Immediate conditional jump (bt or bf) */
198
static void gen_conditional_jump(DisasContext * ctx,
199
                                 target_ulong ift, target_ulong ifnott)
200
{
201
    int l1;
202

    
203
    l1 = gen_new_label();
204
    gen_op_jT(l1);
205
    gen_goto_tb(ctx, 0, ifnott);
206
    gen_set_label(l1);
207
    gen_goto_tb(ctx, 1, ift);
208
}
209

    
210
/* Delayed conditional jump (bt or bf) */
211
static void gen_delayed_conditional_jump(DisasContext * ctx)
212
{
213
    int l1;
214

    
215
    l1 = gen_new_label();
216
    gen_op_jdelayed(l1);
217
    gen_goto_tb(ctx, 1, ctx->pc);
218
    gen_set_label(l1);
219
    gen_jump(ctx);
220
}
221

    
222
#define B3_0 (ctx->opcode & 0xf)
223
#define B6_4 ((ctx->opcode >> 4) & 0x7)
224
#define B7_4 ((ctx->opcode >> 4) & 0xf)
225
#define B7_0 (ctx->opcode & 0xff)
226
#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
227
#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
228
  (ctx->opcode & 0xfff))
229
#define B11_8 ((ctx->opcode >> 8) & 0xf)
230
#define B15_12 ((ctx->opcode >> 12) & 0xf)
231

    
232
#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
233
                (x) + 16 : (x))
234

    
235
#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
236
                ? (x) + 16 : (x))
237

    
238
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
239
#define XHACK(x) (((x) & 1 ) << 4 | ((x) & 0xe ) << 1)
240
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
241

    
242
#define CHECK_NOT_DELAY_SLOT \
243
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
244
  {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \
245
   return;}
246

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

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

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

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

    
916
    switch (ctx->opcode & 0xf08f) {
917
    case 0x408e:                /* ldc Rm,Rn_BANK */
918
        gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
919
        return;
920
    case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
921
        gen_op_movl_rN_T0(REG(B11_8));
922
        gen_op_ldl_T0_T0(ctx);
923
        gen_op_movl_T0_rN(ALTREG(B6_4));
924
        gen_op_inc4_rN(REG(B11_8));
925
        return;
926
    case 0x0082:                /* stc Rm_BANK,Rn */
927
        gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
928
        return;
929
    case 0x4083:                /* stc.l Rm_BANK,@-Rn */
930
        gen_op_dec4_rN(REG(B11_8));
931
        gen_op_movl_rN_T1(REG(B11_8));
932
        gen_op_movl_rN_T0(ALTREG(B6_4));
933
        gen_op_stl_T0_T1(ctx);
934
        return;
935
    }
936

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

    
1084
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1085
            ctx->opcode, ctx->pc);
1086
    gen_op_raise_illegal_instruction();
1087
    ctx->flags |= BRANCH_EXCEPTION;
1088
}
1089

    
1090
static inline int
1091
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1092
                               int search_pc)
1093
{
1094
    DisasContext ctx;
1095
    target_ulong pc_start;
1096
    static uint16_t *gen_opc_end;
1097
    uint32_t old_flags;
1098
    int i, ii;
1099

    
1100
    pc_start = tb->pc;
1101
    gen_opc_ptr = gen_opc_buf;
1102
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1103
    gen_opparam_ptr = gen_opparam_buf;
1104
    ctx.pc = pc_start;
1105
    ctx.flags = env->flags;
1106
    old_flags = 0;
1107
    ctx.sr = env->sr;
1108
    ctx.fpscr = env->fpscr;
1109
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1110
    /* We don't know if the delayed pc came from a dynamic or static branch,
1111
       so assume it is a dynamic branch.  */
1112
    ctx.delayed_pc = -1;
1113
    ctx.tb = tb;
1114
    ctx.singlestep_enabled = env->singlestep_enabled;
1115
    nb_gen_labels = 0;
1116

    
1117
#ifdef DEBUG_DISAS
1118
    if (loglevel & CPU_LOG_TB_CPU) {
1119
        fprintf(logfile,
1120
                "------------------------------------------------\n");
1121
        cpu_dump_state(env, logfile, fprintf, 0);
1122
    }
1123
#endif
1124

    
1125
    ii = -1;
1126
    while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 &&
1127
           (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE |
1128
                         BRANCH_EXCEPTION)) == 0 &&
1129
           gen_opc_ptr < gen_opc_end && ctx.sr == env->sr) {
1130
        old_flags = ctx.flags;
1131
        if (env->nb_breakpoints > 0) {
1132
            for (i = 0; i < env->nb_breakpoints; i++) {
1133
                if (ctx.pc == env->breakpoints[i]) {
1134
                    /* We have hit a breakpoint - make sure PC is up-to-date */
1135
                    gen_op_movl_imm_PC(ctx.pc);
1136
                    gen_op_debug();
1137
                    ctx.flags |= BRANCH_EXCEPTION;
1138
                    break;
1139
                }
1140
            }
1141
        }
1142
        if (search_pc) {
1143
            i = gen_opc_ptr - gen_opc_buf;
1144
            if (ii < i) {
1145
                ii++;
1146
                while (ii < i)
1147
                    gen_opc_instr_start[ii++] = 0;
1148
            }
1149
            gen_opc_pc[ii] = ctx.pc;
1150
            gen_opc_instr_start[ii] = 1;
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
    if (old_flags & DELAY_SLOT_CONDITIONAL) {
1169
        gen_delayed_conditional_jump(&ctx);
1170
    } else if (old_flags & DELAY_SLOT) {
1171
        gen_op_clr_delay_slot();
1172
        gen_jump(&ctx);
1173
    } else if (ctx.flags & BRANCH_EXCEPTION) {
1174
        gen_jump_exception(&ctx);
1175
    } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) {
1176
        gen_goto_tb(&ctx, 0, ctx.pc);
1177
    }
1178

    
1179
    if (env->singlestep_enabled) {
1180
        gen_op_debug();
1181
    }
1182
    *gen_opc_ptr = INDEX_op_end;
1183
    if (search_pc) {
1184
        i = gen_opc_ptr - gen_opc_buf;
1185
        ii++;
1186
        while (ii <= i)
1187
            gen_opc_instr_start[ii++] = 0;
1188
        tb->size = 0;
1189
    } else {
1190
        tb->size = ctx.pc - pc_start;
1191
    }
1192

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

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

    
1217
int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1218
{
1219
    return gen_intermediate_code_internal(env, tb, 1);
1220
}