Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ 7da76bce

History | View | Annotate | Download (37.2 kB)

1
/*
2
 *  SH4 translation
3
 *
4
 *  Copyright (c) 2005 Samuel Tardieu
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
#include <stdarg.h>
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <string.h>
24
#include <inttypes.h>
25
#include <assert.h>
26

    
27
#define DEBUG_DISAS
28
#define SH4_DEBUG_DISAS
29
//#define SH4_SINGLE_STEP
30

    
31
#include "cpu.h"
32
#include "exec-all.h"
33
#include "disas.h"
34
#include "tcg-op.h"
35
#include "qemu-common.h"
36

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

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

    
59
static TCGv cpu_env;
60

    
61
#include "gen-icount.h"
62

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

    
72
#ifdef CONFIG_USER_ONLY
73

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

    
83
#else
84

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

    
96
#endif
97

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

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

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

    
155
CPUSH4State *cpu_sh4_init(const char *cpu_model)
156
{
157
    CPUSH4State *env;
158

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1194
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1195
            ctx->opcode, ctx->pc);
1196
    gen_op_raise_illegal_instruction();
1197
    ctx->bstate = BS_EXCP;
1198
}
1199

    
1200
void decode_opc(DisasContext * ctx)
1201
{
1202
    uint32_t old_flags = ctx->flags;
1203

    
1204
    _decode_opc(ctx);
1205

    
1206
    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1207
        if (ctx->flags & DELAY_SLOT_CLEARME) {
1208
            gen_op_store_flags(0);
1209
        } else {
1210
            /* go out of the delay slot */
1211
            uint32_t new_flags = ctx->flags;
1212
            new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1213
            gen_op_store_flags(new_flags);
1214
        }
1215
        ctx->flags = 0;
1216
        ctx->bstate = BS_BRANCH;
1217
        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1218
            gen_delayed_conditional_jump(ctx);
1219
        } else if (old_flags & DELAY_SLOT) {
1220
            gen_jump(ctx);
1221
        }
1222

    
1223
    }
1224

    
1225
    /* go into a delay slot */
1226
    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1227
        gen_op_store_flags(ctx->flags);
1228
}
1229

    
1230
static inline void
1231
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1232
                               int search_pc)
1233
{
1234
    DisasContext ctx;
1235
    target_ulong pc_start;
1236
    static uint16_t *gen_opc_end;
1237
    int i, ii;
1238
    int num_insns;
1239
    int max_insns;
1240

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

    
1255
#ifdef DEBUG_DISAS
1256
    if (loglevel & CPU_LOG_TB_CPU) {
1257
        fprintf(logfile,
1258
                "------------------------------------------------\n");
1259
        cpu_dump_state(env, logfile, fprintf, 0);
1260
    }
1261
#endif
1262

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

    
1338
    gen_icount_end(tb, num_insns);
1339
    *gen_opc_ptr = INDEX_op_end;
1340
    if (search_pc) {
1341
        i = gen_opc_ptr - gen_opc_buf;
1342
        ii++;
1343
        while (ii <= i)
1344
            gen_opc_instr_start[ii++] = 0;
1345
    } else {
1346
        tb->size = ctx.pc - pc_start;
1347
        tb->icount = num_insns;
1348
    }
1349

    
1350
#ifdef DEBUG_DISAS
1351
#ifdef SH4_DEBUG_DISAS
1352
    if (loglevel & CPU_LOG_TB_IN_ASM)
1353
        fprintf(logfile, "\n");
1354
#endif
1355
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1356
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1357
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1358
        fprintf(logfile, "\n");
1359
    }
1360
#endif
1361
}
1362

    
1363
void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1364
{
1365
    gen_intermediate_code_internal(env, tb, 0);
1366
}
1367

    
1368
void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1369
{
1370
    gen_intermediate_code_internal(env, tb, 1);
1371
}
1372

    
1373
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1374
                unsigned long searched_pc, int pc_pos, void *puc)
1375
{
1376
    env->pc = gen_opc_pc[pc_pos];
1377
    env->flags = gen_opc_hflags[pc_pos];
1378
}