Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ 833ed386

History | View | Annotate | Download (36.1 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
#include "tcg-op.h"
35
#include "qemu-common.h"
36

    
37
typedef struct DisasContext {
38
    struct TranslationBlock *tb;
39
    target_ulong pc;
40
    uint32_t sr;
41
    uint32_t fpscr;
42
    uint16_t opcode;
43
    uint32_t flags;
44
    int bstate;
45
    int memidx;
46
    uint32_t delayed_pc;
47
    int singlestep_enabled;
48
} DisasContext;
49

    
50
enum {
51
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
52
                      * exception condition
53
                      */
54
    BS_STOP     = 1, /* We want to stop translation for any reason */
55
    BS_BRANCH   = 2, /* We reached a branch condition     */
56
    BS_EXCP     = 3, /* We reached an exception condition */
57
};
58

    
59
static TCGv cpu_env;
60

    
61
#include "gen-icount.h"
62

    
63
static void sh4_translate_init(void)
64
{
65
    static int done_init = 0;
66
    if (done_init)
67
        return;
68
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
69
    done_init = 1;
70
}
71

    
72
#ifdef CONFIG_USER_ONLY
73

    
74
#define GEN_OP_LD(width, reg) \
75
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
76
    gen_op_ld##width##_T0_##reg##_raw(); \
77
  }
78
#define GEN_OP_ST(width, reg) \
79
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
80
    gen_op_st##width##_##reg##_T1_raw(); \
81
  }
82

    
83
#else
84

    
85
#define GEN_OP_LD(width, reg) \
86
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
87
    if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
88
    else gen_op_ld##width##_T0_##reg##_user();\
89
  }
90
#define GEN_OP_ST(width, reg) \
91
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
92
    if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
93
    else gen_op_st##width##_##reg##_T1_user();\
94
  }
95

    
96
#endif
97

    
98
GEN_OP_LD(ub, T0)
99
GEN_OP_LD(b, T0)
100
GEN_OP_ST(b, T0)
101
GEN_OP_LD(uw, T0)
102
GEN_OP_LD(w, T0)
103
GEN_OP_ST(w, T0)
104
GEN_OP_LD(l, T0)
105
GEN_OP_ST(l, T0)
106
GEN_OP_LD(fl, FT0)
107
GEN_OP_ST(fl, FT0)
108
GEN_OP_LD(fq, DT0)
109
GEN_OP_ST(fq, DT0)
110

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

    
132
void cpu_sh4_reset(CPUSH4State * env)
133
{
134
#if defined(CONFIG_USER_ONLY)
135
    env->sr = SR_FD;            /* FD - kernel does lazy fpu context switch */
136
#else
137
    env->sr = 0x700000F0;        /* MD, RB, BL, I3-I0 */
138
#endif
139
    env->vbr = 0;
140
    env->pc = 0xA0000000;
141
#if defined(CONFIG_USER_ONLY)
142
    env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
143
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
144
#else
145
    env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
146
    set_float_rounding_mode(float_round_to_zero, &env->fp_status);
147
#endif
148
    env->mmucr = 0;
149
}
150

    
151
CPUSH4State *cpu_sh4_init(const char *cpu_model)
152
{
153
    CPUSH4State *env;
154

    
155
    env = qemu_mallocz(sizeof(CPUSH4State));
156
    if (!env)
157
        return NULL;
158
    cpu_exec_init(env);
159
    sh4_translate_init();
160
    cpu_sh4_reset(env);
161
    tlb_flush(env, 1);
162
    return env;
163
}
164

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

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

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

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

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

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

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

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

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

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

    
239
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
240
#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
241
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
242
#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
243

    
244
#define CHECK_NOT_DELAY_SLOT \
245
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
246
  {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
247
   return;}
248

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

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

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

    
756
        switch (ctx->opcode & 0xf00f) {
757
        case 0xf000:                /* fadd Rm,Rn */
758
            ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
759
            break;
760
        case 0xf001:                /* fsub Rm,Rn */
761
            ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
762
            break;
763
        case 0xf002:                /* fmul Rm,Rn */
764
            ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
765
            break;
766
        case 0xf003:                /* fdiv Rm,Rn */
767
            ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
768
            break;
769
        case 0xf004:                /* fcmp/eq Rm,Rn */
770
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
771
            return;
772
        case 0xf005:                /* fcmp/gt Rm,Rn */
773
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
774
            return;
775
        }
776

    
777
        if (ctx->fpscr & FPSCR_PR) {
778
            gen_op_fmov_DT0_drN(DREG(B11_8));
779
        }
780
        else {
781
            gen_op_fmov_FT0_frN(FREG(B11_8));
782
        }
783
        return;
784
    }
785

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

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

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

    
1176
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1177
            ctx->opcode, ctx->pc);
1178
    gen_op_raise_illegal_instruction();
1179
    ctx->bstate = BS_EXCP;
1180
}
1181

    
1182
void decode_opc(DisasContext * ctx)
1183
{
1184
    uint32_t old_flags = ctx->flags;
1185

    
1186
    _decode_opc(ctx);
1187

    
1188
    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1189
        if (ctx->flags & DELAY_SLOT_CLEARME) {
1190
            gen_op_store_flags(0);
1191
        }
1192
        ctx->flags = 0;
1193
        ctx->bstate = BS_BRANCH;
1194
        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1195
            gen_delayed_conditional_jump(ctx);
1196
        } else if (old_flags & DELAY_SLOT) {
1197
            gen_jump(ctx);
1198
        }
1199

    
1200
    }
1201
}
1202

    
1203
static inline void
1204
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1205
                               int search_pc)
1206
{
1207
    DisasContext ctx;
1208
    target_ulong pc_start;
1209
    static uint16_t *gen_opc_end;
1210
    int i, ii;
1211
    int num_insns;
1212
    int max_insns;
1213

    
1214
    pc_start = tb->pc;
1215
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1216
    ctx.pc = pc_start;
1217
    ctx.flags = (uint32_t)tb->flags;
1218
    ctx.bstate = BS_NONE;
1219
    ctx.sr = env->sr;
1220
    ctx.fpscr = env->fpscr;
1221
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1222
    /* We don't know if the delayed pc came from a dynamic or static branch,
1223
       so assume it is a dynamic branch.  */
1224
    ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1225
    ctx.tb = tb;
1226
    ctx.singlestep_enabled = env->singlestep_enabled;
1227

    
1228
#ifdef DEBUG_DISAS
1229
    if (loglevel & CPU_LOG_TB_CPU) {
1230
        fprintf(logfile,
1231
                "------------------------------------------------\n");
1232
        cpu_dump_state(env, logfile, fprintf, 0);
1233
    }
1234
#endif
1235

    
1236
    ii = -1;
1237
    num_insns = 0;
1238
    max_insns = tb->cflags & CF_COUNT_MASK;
1239
    if (max_insns == 0)
1240
        max_insns = CF_COUNT_MASK;
1241
    gen_icount_start();
1242
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1243
        if (env->nb_breakpoints > 0) {
1244
            for (i = 0; i < env->nb_breakpoints; i++) {
1245
                if (ctx.pc == env->breakpoints[i]) {
1246
                    /* We have hit a breakpoint - make sure PC is up-to-date */
1247
                    gen_op_movl_imm_PC(ctx.pc);
1248
                    gen_op_debug();
1249
                    ctx.bstate = BS_EXCP;
1250
                    break;
1251
                }
1252
            }
1253
        }
1254
        if (search_pc) {
1255
            i = gen_opc_ptr - gen_opc_buf;
1256
            if (ii < i) {
1257
                ii++;
1258
                while (ii < i)
1259
                    gen_opc_instr_start[ii++] = 0;
1260
            }
1261
            gen_opc_pc[ii] = ctx.pc;
1262
            gen_opc_hflags[ii] = ctx.flags;
1263
            gen_opc_instr_start[ii] = 1;
1264
            gen_opc_icount[ii] = num_insns;
1265
        }
1266
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1267
            gen_io_start();
1268
#if 0
1269
        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1270
        fflush(stderr);
1271
#endif
1272
        ctx.opcode = lduw_code(ctx.pc);
1273
        decode_opc(&ctx);
1274
        num_insns++;
1275
        ctx.pc += 2;
1276
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1277
            break;
1278
        if (env->singlestep_enabled)
1279
            break;
1280
        if (num_insns >= max_insns)
1281
            break;
1282
#ifdef SH4_SINGLE_STEP
1283
        break;
1284
#endif
1285
    }
1286
    if (tb->cflags & CF_LAST_IO)
1287
        gen_io_end();
1288
    if (env->singlestep_enabled) {
1289
        gen_op_debug();
1290
    } else {
1291
        switch (ctx.bstate) {
1292
        case BS_STOP:
1293
            /* gen_op_interrupt_restart(); */
1294
            /* fall through */
1295
        case BS_NONE:
1296
            if (ctx.flags) {
1297
                gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1298
            }
1299
            gen_goto_tb(&ctx, 0, ctx.pc);
1300
            break;
1301
        case BS_EXCP:
1302
            /* gen_op_interrupt_restart(); */
1303
            tcg_gen_exit_tb(0);
1304
            break;
1305
        case BS_BRANCH:
1306
        default:
1307
            break;
1308
        }
1309
    }
1310

    
1311
    gen_icount_end(tb, num_insns);
1312
    *gen_opc_ptr = INDEX_op_end;
1313
    if (search_pc) {
1314
        i = gen_opc_ptr - gen_opc_buf;
1315
        ii++;
1316
        while (ii <= i)
1317
            gen_opc_instr_start[ii++] = 0;
1318
    } else {
1319
        tb->size = ctx.pc - pc_start;
1320
        tb->icount = num_insns;
1321
    }
1322

    
1323
#ifdef DEBUG_DISAS
1324
#ifdef SH4_DEBUG_DISAS
1325
    if (loglevel & CPU_LOG_TB_IN_ASM)
1326
        fprintf(logfile, "\n");
1327
#endif
1328
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1329
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1330
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1331
        fprintf(logfile, "\n");
1332
    }
1333
#endif
1334
}
1335

    
1336
void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1337
{
1338
    gen_intermediate_code_internal(env, tb, 0);
1339
}
1340

    
1341
void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1342
{
1343
    gen_intermediate_code_internal(env, tb, 1);
1344
}
1345

    
1346
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1347
                unsigned long searched_pc, int pc_pos, void *puc)
1348
{
1349
    env->pc = gen_opc_pc[pc_pos];
1350
    env->flags = gen_opc_hflags[pc_pos];
1351
}