Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ 6858571c

History | View | Annotate | Download (37.4 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, cpu_T[2];
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
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
70
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
71
    done_init = 1;
72
}
73

    
74
#ifdef CONFIG_USER_ONLY
75

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

    
85
#else
86

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

    
98
#endif
99

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

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

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

    
157
CPUSH4State *cpu_sh4_init(const char *cpu_model)
158
{
159
    CPUSH4State *env;
160

    
161
    env = qemu_mallocz(sizeof(CPUSH4State));
162
    if (!env)
163
        return NULL;
164
    cpu_exec_init(env);
165
    sh4_translate_init();
166
    cpu_sh4_reset(env);
167
    tlb_flush(env, 1);
168
    return env;
169
}
170

    
171
static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
172
{
173
    TranslationBlock *tb;
174
    tb = ctx->tb;
175

    
176
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
177
        !ctx->singlestep_enabled) {
178
        /* Use a direct jump if in same page and singlestep not enabled */
179
        tcg_gen_goto_tb(n);
180
        gen_op_movl_imm_PC(dest);
181
        tcg_gen_exit_tb((long) tb + n);
182
    } else {
183
        gen_op_movl_imm_PC(dest);
184
        if (ctx->singlestep_enabled)
185
            gen_op_debug();
186
        tcg_gen_exit_tb(0);
187
    }
188
}
189

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

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

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

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

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

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

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

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

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

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

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

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

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

    
772
        switch (ctx->opcode & 0xf00f) {
773
        case 0xf000:                /* fadd Rm,Rn */
774
            ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
775
            break;
776
        case 0xf001:                /* fsub Rm,Rn */
777
            ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
778
            break;
779
        case 0xf002:                /* fmul Rm,Rn */
780
            ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
781
            break;
782
        case 0xf003:                /* fdiv Rm,Rn */
783
            ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
784
            break;
785
        case 0xf004:                /* fcmp/eq Rm,Rn */
786
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
787
            return;
788
        case 0xf005:                /* fcmp/gt Rm,Rn */
789
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
790
            return;
791
        }
792

    
793
        if (ctx->fpscr & FPSCR_PR) {
794
            gen_op_fmov_DT0_drN(DREG(B11_8));
795
        }
796
        else {
797
            gen_op_fmov_FT0_frN(FREG(B11_8));
798
        }
799
        return;
800
    }
801

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

    
945
    switch (ctx->opcode & 0xf08f) {
946
    case 0x408e:                /* ldc Rm,Rn_BANK */
947
        gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
948
        return;
949
    case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
950
        gen_op_movl_rN_T0(REG(B11_8));
951
        gen_op_ldl_T0_T0(ctx);
952
        gen_op_movl_T0_rN(ALTREG(B6_4));
953
        gen_op_inc4_rN(REG(B11_8));
954
        return;
955
    case 0x0082:                /* stc Rm_BANK,Rn */
956
        gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
957
        return;
958
    case 0x4083:                /* stc.l Rm_BANK,@-Rn */
959
        gen_op_dec4_rN(REG(B11_8));
960
        gen_op_movl_rN_T1(REG(B11_8));
961
        gen_op_movl_rN_T0(ALTREG(B6_4));
962
        gen_op_inc4_rN(REG(B11_8));
963
        gen_op_stl_T0_T1(ctx);
964
        gen_op_dec4_rN(REG(B11_8));
965
        return;
966
    }
967

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

    
1201
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1202
            ctx->opcode, ctx->pc);
1203
    gen_op_raise_illegal_instruction();
1204
    ctx->bstate = BS_EXCP;
1205
}
1206

    
1207
void decode_opc(DisasContext * ctx)
1208
{
1209
    uint32_t old_flags = ctx->flags;
1210

    
1211
    _decode_opc(ctx);
1212

    
1213
    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1214
        if (ctx->flags & DELAY_SLOT_CLEARME) {
1215
            gen_op_store_flags(0);
1216
        } else {
1217
            /* go out of the delay slot */
1218
            uint32_t new_flags = ctx->flags;
1219
            new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1220
            gen_op_store_flags(new_flags);
1221
        }
1222
        ctx->flags = 0;
1223
        ctx->bstate = BS_BRANCH;
1224
        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1225
            gen_delayed_conditional_jump(ctx);
1226
        } else if (old_flags & DELAY_SLOT) {
1227
            gen_jump(ctx);
1228
        }
1229

    
1230
    }
1231

    
1232
    /* go into a delay slot */
1233
    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1234
        gen_op_store_flags(ctx->flags);
1235
}
1236

    
1237
static inline void
1238
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1239
                               int search_pc)
1240
{
1241
    DisasContext ctx;
1242
    target_ulong pc_start;
1243
    static uint16_t *gen_opc_end;
1244
    int i, ii;
1245
    int num_insns;
1246
    int max_insns;
1247

    
1248
    pc_start = tb->pc;
1249
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1250
    ctx.pc = pc_start;
1251
    ctx.flags = (uint32_t)tb->flags;
1252
    ctx.bstate = BS_NONE;
1253
    ctx.sr = env->sr;
1254
    ctx.fpscr = env->fpscr;
1255
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1256
    /* We don't know if the delayed pc came from a dynamic or static branch,
1257
       so assume it is a dynamic branch.  */
1258
    ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1259
    ctx.tb = tb;
1260
    ctx.singlestep_enabled = env->singlestep_enabled;
1261

    
1262
#ifdef DEBUG_DISAS
1263
    if (loglevel & CPU_LOG_TB_CPU) {
1264
        fprintf(logfile,
1265
                "------------------------------------------------\n");
1266
        cpu_dump_state(env, logfile, fprintf, 0);
1267
    }
1268
#endif
1269

    
1270
    ii = -1;
1271
    num_insns = 0;
1272
    max_insns = tb->cflags & CF_COUNT_MASK;
1273
    if (max_insns == 0)
1274
        max_insns = CF_COUNT_MASK;
1275
    gen_icount_start();
1276
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1277
        if (env->nb_breakpoints > 0) {
1278
            for (i = 0; i < env->nb_breakpoints; i++) {
1279
                if (ctx.pc == env->breakpoints[i]) {
1280
                    /* We have hit a breakpoint - make sure PC is up-to-date */
1281
                    gen_op_movl_imm_PC(ctx.pc);
1282
                    gen_op_debug();
1283
                    ctx.bstate = BS_EXCP;
1284
                    break;
1285
                }
1286
            }
1287
        }
1288
        if (search_pc) {
1289
            i = gen_opc_ptr - gen_opc_buf;
1290
            if (ii < i) {
1291
                ii++;
1292
                while (ii < i)
1293
                    gen_opc_instr_start[ii++] = 0;
1294
            }
1295
            gen_opc_pc[ii] = ctx.pc;
1296
            gen_opc_hflags[ii] = ctx.flags;
1297
            gen_opc_instr_start[ii] = 1;
1298
            gen_opc_icount[ii] = num_insns;
1299
        }
1300
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1301
            gen_io_start();
1302
#if 0
1303
        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1304
        fflush(stderr);
1305
#endif
1306
        ctx.opcode = lduw_code(ctx.pc);
1307
        decode_opc(&ctx);
1308
        num_insns++;
1309
        ctx.pc += 2;
1310
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1311
            break;
1312
        if (env->singlestep_enabled)
1313
            break;
1314
        if (num_insns >= max_insns)
1315
            break;
1316
#ifdef SH4_SINGLE_STEP
1317
        break;
1318
#endif
1319
    }
1320
    if (tb->cflags & CF_LAST_IO)
1321
        gen_io_end();
1322
    if (env->singlestep_enabled) {
1323
        gen_op_debug();
1324
    } else {
1325
        switch (ctx.bstate) {
1326
        case BS_STOP:
1327
            /* gen_op_interrupt_restart(); */
1328
            /* fall through */
1329
        case BS_NONE:
1330
            if (ctx.flags) {
1331
                gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1332
            }
1333
            gen_goto_tb(&ctx, 0, ctx.pc);
1334
            break;
1335
        case BS_EXCP:
1336
            /* gen_op_interrupt_restart(); */
1337
            tcg_gen_exit_tb(0);
1338
            break;
1339
        case BS_BRANCH:
1340
        default:
1341
            break;
1342
        }
1343
    }
1344

    
1345
    gen_icount_end(tb, num_insns);
1346
    *gen_opc_ptr = INDEX_op_end;
1347
    if (search_pc) {
1348
        i = gen_opc_ptr - gen_opc_buf;
1349
        ii++;
1350
        while (ii <= i)
1351
            gen_opc_instr_start[ii++] = 0;
1352
    } else {
1353
        tb->size = ctx.pc - pc_start;
1354
        tb->icount = num_insns;
1355
    }
1356

    
1357
#ifdef DEBUG_DISAS
1358
#ifdef SH4_DEBUG_DISAS
1359
    if (loglevel & CPU_LOG_TB_IN_ASM)
1360
        fprintf(logfile, "\n");
1361
#endif
1362
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1363
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1364
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1365
        fprintf(logfile, "\n");
1366
    }
1367
#endif
1368
}
1369

    
1370
void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1371
{
1372
    gen_intermediate_code_internal(env, tb, 0);
1373
}
1374

    
1375
void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1376
{
1377
    gen_intermediate_code_internal(env, tb, 1);
1378
}
1379

    
1380
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1381
                unsigned long searched_pc, int pc_pos, void *puc)
1382
{
1383
    env->pc = gen_opc_pc[pc_pos];
1384
    env->flags = gen_opc_hflags[pc_pos];
1385
}