Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ 274a9e70

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

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

    
781
        if (ctx->fpscr & FPSCR_PR) {
782
            gen_op_fmov_DT0_drN(DREG(B11_8));
783
        }
784
        else {
785
            gen_op_fmov_FT0_frN(FREG(B11_8));
786
        }
787
        return;
788
    }
789

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

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

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

    
1180
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1181
            ctx->opcode, ctx->pc);
1182
    gen_op_raise_illegal_instruction();
1183
    ctx->bstate = BS_EXCP;
1184
}
1185

    
1186
void decode_opc(DisasContext * ctx)
1187
{
1188
    uint32_t old_flags = ctx->flags;
1189

    
1190
    _decode_opc(ctx);
1191

    
1192
    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1193
        if (ctx->flags & DELAY_SLOT_CLEARME) {
1194
            gen_op_store_flags(0);
1195
        } else {
1196
            /* go out of the delay slot */
1197
            uint32_t new_flags = ctx->flags;
1198
            new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1199
            gen_op_store_flags(new_flags);
1200
        }
1201
        ctx->flags = 0;
1202
        ctx->bstate = BS_BRANCH;
1203
        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1204
            gen_delayed_conditional_jump(ctx);
1205
        } else if (old_flags & DELAY_SLOT) {
1206
            gen_jump(ctx);
1207
        }
1208

    
1209
    }
1210

    
1211
    /* go into a delay slot */
1212
    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1213
        gen_op_store_flags(ctx->flags);
1214
}
1215

    
1216
static inline void
1217
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1218
                               int search_pc)
1219
{
1220
    DisasContext ctx;
1221
    target_ulong pc_start;
1222
    static uint16_t *gen_opc_end;
1223
    int i, ii;
1224
    int num_insns;
1225
    int max_insns;
1226

    
1227
    pc_start = tb->pc;
1228
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1229
    ctx.pc = pc_start;
1230
    ctx.flags = (uint32_t)tb->flags;
1231
    ctx.bstate = BS_NONE;
1232
    ctx.sr = env->sr;
1233
    ctx.fpscr = env->fpscr;
1234
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1235
    /* We don't know if the delayed pc came from a dynamic or static branch,
1236
       so assume it is a dynamic branch.  */
1237
    ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1238
    ctx.tb = tb;
1239
    ctx.singlestep_enabled = env->singlestep_enabled;
1240

    
1241
#ifdef DEBUG_DISAS
1242
    if (loglevel & CPU_LOG_TB_CPU) {
1243
        fprintf(logfile,
1244
                "------------------------------------------------\n");
1245
        cpu_dump_state(env, logfile, fprintf, 0);
1246
    }
1247
#endif
1248

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

    
1324
    gen_icount_end(tb, num_insns);
1325
    *gen_opc_ptr = INDEX_op_end;
1326
    if (search_pc) {
1327
        i = gen_opc_ptr - gen_opc_buf;
1328
        ii++;
1329
        while (ii <= i)
1330
            gen_opc_instr_start[ii++] = 0;
1331
    } else {
1332
        tb->size = ctx.pc - pc_start;
1333
        tb->icount = num_insns;
1334
    }
1335

    
1336
#ifdef DEBUG_DISAS
1337
#ifdef SH4_DEBUG_DISAS
1338
    if (loglevel & CPU_LOG_TB_IN_ASM)
1339
        fprintf(logfile, "\n");
1340
#endif
1341
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1342
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1343
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1344
        fprintf(logfile, "\n");
1345
    }
1346
#endif
1347
}
1348

    
1349
void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1350
{
1351
    gen_intermediate_code_internal(env, tb, 0);
1352
}
1353

    
1354
void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1355
{
1356
    gen_intermediate_code_internal(env, tb, 1);
1357
}
1358

    
1359
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1360
                unsigned long searched_pc, int pc_pos, void *puc)
1361
{
1362
    env->pc = gen_opc_pc[pc_pos];
1363
    env->flags = gen_opc_hflags[pc_pos];
1364
}