Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ b2437bf2

History | View | Annotate | Download (36 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()
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
        assert(0);                /* XXXXX */
302
        return;
303
    }
304

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

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

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

    
772
        if (ctx->fpscr & FPSCR_PR) {
773
            gen_op_fmov_DT0_drN(DREG(B11_8));
774
        }
775
        else {
776
            gen_op_fmov_FT0_frN(FREG(B11_8));
777
        }
778
        return;
779
    }
780

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

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

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

    
1171
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1172
            ctx->opcode, ctx->pc);
1173
    gen_op_raise_illegal_instruction();
1174
    ctx->bstate = BS_EXCP;
1175
}
1176

    
1177
void decode_opc(DisasContext * ctx)
1178
{
1179
    uint32_t old_flags = ctx->flags;
1180

    
1181
    _decode_opc(ctx);
1182

    
1183
    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1184
        if (ctx->flags & DELAY_SLOT_CLEARME) {
1185
            gen_op_store_flags(0);
1186
        }
1187
        ctx->flags = 0;
1188
        ctx->bstate = BS_BRANCH;
1189
        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1190
            gen_delayed_conditional_jump(ctx);
1191
        } else if (old_flags & DELAY_SLOT) {
1192
            gen_jump(ctx);
1193
        }
1194

    
1195
    }
1196
}
1197

    
1198
static inline int
1199
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1200
                               int search_pc)
1201
{
1202
    DisasContext ctx;
1203
    target_ulong pc_start;
1204
    static uint16_t *gen_opc_end;
1205
    int i, ii;
1206
    int num_insns;
1207
    int max_insns;
1208

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

    
1223
#ifdef DEBUG_DISAS
1224
    if (loglevel & CPU_LOG_TB_CPU) {
1225
        fprintf(logfile,
1226
                "------------------------------------------------\n");
1227
        cpu_dump_state(env, logfile, fprintf, 0);
1228
    }
1229
#endif
1230

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

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

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

    
1332
int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1333
{
1334
    return gen_intermediate_code_internal(env, tb, 0);
1335
}
1336

    
1337
int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1338
{
1339
    return gen_intermediate_code_internal(env, tb, 1);
1340
}
1341

    
1342
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1343
                unsigned long searched_pc, int pc_pos, void *puc)
1344
{
1345
    env->pc = gen_opc_pc[pc_pos];
1346
    env->flags = gen_opc_hflags[pc_pos];
1347
}