Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ d2856f1a

History | View | Annotate | Download (35.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
#ifdef CONFIG_USER_ONLY
60

    
61
#define GEN_OP_LD(width, reg) \
62
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
63
    gen_op_ld##width##_T0_##reg##_raw(); \
64
  }
65
#define GEN_OP_ST(width, reg) \
66
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
67
    gen_op_st##width##_##reg##_T1_raw(); \
68
  }
69

    
70
#else
71

    
72
#define GEN_OP_LD(width, reg) \
73
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
74
    if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
75
    else gen_op_ld##width##_T0_##reg##_user();\
76
  }
77
#define GEN_OP_ST(width, reg) \
78
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
79
    if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
80
    else gen_op_st##width##_##reg##_T1_user();\
81
  }
82

    
83
#endif
84

    
85
GEN_OP_LD(ub, T0)
86
GEN_OP_LD(b, T0)
87
GEN_OP_ST(b, T0)
88
GEN_OP_LD(uw, T0)
89
GEN_OP_LD(w, T0)
90
GEN_OP_ST(w, T0)
91
GEN_OP_LD(l, T0)
92
GEN_OP_ST(l, T0)
93
GEN_OP_LD(fl, FT0)
94
GEN_OP_ST(fl, FT0)
95
GEN_OP_LD(fq, DT0)
96
GEN_OP_ST(fq, DT0)
97

    
98
void cpu_dump_state(CPUState * env, FILE * f,
99
                    int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
100
                    int flags)
101
{
102
    int i;
103
    cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
104
                env->pc, env->sr, env->pr, env->fpscr);
105
    for (i = 0; i < 24; i += 4) {
106
        cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
107
                    i, env->gregs[i], i + 1, env->gregs[i + 1],
108
                    i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
109
    }
110
    if (env->flags & DELAY_SLOT) {
111
        cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
112
                    env->delayed_pc);
113
    } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
114
        cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
115
                    env->delayed_pc);
116
    }
117
}
118

    
119
void cpu_sh4_reset(CPUSH4State * env)
120
{
121
#if defined(CONFIG_USER_ONLY)
122
    env->sr = SR_FD;            /* FD - kernel does lazy fpu context switch */
123
#else
124
    env->sr = 0x700000F0;        /* MD, RB, BL, I3-I0 */
125
#endif
126
    env->vbr = 0;
127
    env->pc = 0xA0000000;
128
#if defined(CONFIG_USER_ONLY)
129
    env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
130
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
131
#else
132
    env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
133
    set_float_rounding_mode(float_round_to_zero, &env->fp_status);
134
#endif
135
    env->mmucr = 0;
136
}
137

    
138
CPUSH4State *cpu_sh4_init(const char *cpu_model)
139
{
140
    CPUSH4State *env;
141

    
142
    env = qemu_mallocz(sizeof(CPUSH4State));
143
    if (!env)
144
        return NULL;
145
    cpu_exec_init(env);
146
    cpu_sh4_reset(env);
147
    tlb_flush(env, 1);
148
    return env;
149
}
150

    
151
static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
152
{
153
    TranslationBlock *tb;
154
    tb = ctx->tb;
155

    
156
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
157
        !ctx->singlestep_enabled) {
158
        /* Use a direct jump if in same page and singlestep not enabled */
159
        tcg_gen_goto_tb(n);
160
        gen_op_movl_imm_PC(dest);
161
        tcg_gen_exit_tb((long) tb + n);
162
    } else {
163
        gen_op_movl_imm_PC(dest);
164
        if (ctx->singlestep_enabled)
165
            gen_op_debug();
166
        tcg_gen_exit_tb(0);
167
    }
168
}
169

    
170
static void gen_jump(DisasContext * ctx)
171
{
172
    if (ctx->delayed_pc == (uint32_t) - 1) {
173
        /* Target is not statically known, it comes necessarily from a
174
           delayed jump as immediate jump are conditinal jumps */
175
        gen_op_movl_delayed_pc_PC();
176
        if (ctx->singlestep_enabled)
177
            gen_op_debug();
178
        tcg_gen_exit_tb(0);
179
    } else {
180
        gen_goto_tb(ctx, 0, ctx->delayed_pc);
181
    }
182
}
183

    
184
/* Immediate conditional jump (bt or bf) */
185
static void gen_conditional_jump(DisasContext * ctx,
186
                                 target_ulong ift, target_ulong ifnott)
187
{
188
    int l1;
189

    
190
    l1 = gen_new_label();
191
    gen_op_jT(l1);
192
    gen_goto_tb(ctx, 0, ifnott);
193
    gen_set_label(l1);
194
    gen_goto_tb(ctx, 1, ift);
195
}
196

    
197
/* Delayed conditional jump (bt or bf) */
198
static void gen_delayed_conditional_jump(DisasContext * ctx)
199
{
200
    int l1;
201

    
202
    l1 = gen_new_label();
203
    gen_op_jdelayed(l1);
204
    gen_goto_tb(ctx, 1, ctx->pc + 2);
205
    gen_set_label(l1);
206
    gen_jump(ctx);
207
}
208

    
209
#define B3_0 (ctx->opcode & 0xf)
210
#define B6_4 ((ctx->opcode >> 4) & 0x7)
211
#define B7_4 ((ctx->opcode >> 4) & 0xf)
212
#define B7_0 (ctx->opcode & 0xff)
213
#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
214
#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
215
  (ctx->opcode & 0xfff))
216
#define B11_8 ((ctx->opcode >> 8) & 0xf)
217
#define B15_12 ((ctx->opcode >> 12) & 0xf)
218

    
219
#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
220
                (x) + 16 : (x))
221

    
222
#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
223
                ? (x) + 16 : (x))
224

    
225
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
226
#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
227
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
228
#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
229

    
230
#define CHECK_NOT_DELAY_SLOT \
231
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
232
  {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
233
   return;}
234

    
235
void _decode_opc(DisasContext * ctx)
236
{
237
#if 0
238
    fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
239
#endif
240
    switch (ctx->opcode) {
241
    case 0x0019:                /* div0u */
242
        gen_op_div0u();
243
        return;
244
    case 0x000b:                /* rts */
245
        CHECK_NOT_DELAY_SLOT gen_op_rts();
246
        ctx->flags |= DELAY_SLOT;
247
        ctx->delayed_pc = (uint32_t) - 1;
248
        return;
249
    case 0x0028:                /* clrmac */
250
        gen_op_clrmac();
251
        return;
252
    case 0x0048:                /* clrs */
253
        gen_op_clrs();
254
        return;
255
    case 0x0008:                /* clrt */
256
        gen_op_clrt();
257
        return;
258
    case 0x0038:                /* ldtlb */
259
        assert(0);                /* XXXXX */
260
        return;
261
    case 0x002b:                /* rte */
262
        CHECK_NOT_DELAY_SLOT gen_op_rte();
263
        ctx->flags |= DELAY_SLOT;
264
        ctx->delayed_pc = (uint32_t) - 1;
265
        return;
266
    case 0x0058:                /* sets */
267
        gen_op_sets();
268
        return;
269
    case 0x0018:                /* sett */
270
        gen_op_sett();
271
        return;
272
    case 0xfbfd:                /* frchg */
273
        gen_op_frchg();
274
        ctx->bstate = BS_STOP;
275
        return;
276
    case 0xf3fd:                /* fschg */
277
        gen_op_fschg();
278
        ctx->bstate = BS_STOP;
279
        return;
280
    case 0x0009:                /* nop */
281
        return;
282
    case 0x001b:                /* sleep */
283
        assert(0);                /* XXXXX */
284
        return;
285
    }
286

    
287
    switch (ctx->opcode & 0xf000) {
288
    case 0x1000:                /* mov.l Rm,@(disp,Rn) */
289
        gen_op_movl_rN_T0(REG(B7_4));
290
        gen_op_movl_rN_T1(REG(B11_8));
291
        gen_op_addl_imm_T1(B3_0 * 4);
292
        gen_op_stl_T0_T1(ctx);
293
        return;
294
    case 0x5000:                /* mov.l @(disp,Rm),Rn */
295
        gen_op_movl_rN_T0(REG(B7_4));
296
        gen_op_addl_imm_T0(B3_0 * 4);
297
        gen_op_ldl_T0_T0(ctx);
298
        gen_op_movl_T0_rN(REG(B11_8));
299
        return;
300
    case 0xe000:                /* mov #imm,Rn */
301
        gen_op_movl_imm_rN(B7_0s, REG(B11_8));
302
        return;
303
    case 0x9000:                /* mov.w @(disp,PC),Rn */
304
        gen_op_movl_imm_T0(ctx->pc + 4 + B7_0 * 2);
305
        gen_op_ldw_T0_T0(ctx);
306
        gen_op_movl_T0_rN(REG(B11_8));
307
        return;
308
    case 0xd000:                /* mov.l @(disp,PC),Rn */
309
        gen_op_movl_imm_T0((ctx->pc + 4 + B7_0 * 4) & ~3);
310
        gen_op_ldl_T0_T0(ctx);
311
        gen_op_movl_T0_rN(REG(B11_8));
312
        return;
313
    case 0x7000:                /* add #imm,Rn */
314
        gen_op_add_imm_rN(B7_0s, REG(B11_8));
315
        return;
316
    case 0xa000:                /* bra disp */
317
        CHECK_NOT_DELAY_SLOT
318
            gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
319
        ctx->flags |= DELAY_SLOT;
320
        return;
321
    case 0xb000:                /* bsr disp */
322
        CHECK_NOT_DELAY_SLOT
323
            gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
324
                       ctx->pc + 4 + B11_0s * 2);
325
        ctx->flags |= DELAY_SLOT;
326
        return;
327
    }
328

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

    
733
        switch (ctx->opcode & 0xf00f) {
734
        case 0xf000:                /* fadd Rm,Rn */
735
            ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
736
            break;
737
        case 0xf001:                /* fsub Rm,Rn */
738
            ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
739
            break;
740
        case 0xf002:                /* fmul Rm,Rn */
741
            ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
742
            break;
743
        case 0xf003:                /* fdiv Rm,Rn */
744
            ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
745
            break;
746
        case 0xf004:                /* fcmp/eq Rm,Rn */
747
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
748
            return;
749
        case 0xf005:                /* fcmp/gt Rm,Rn */
750
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
751
            return;
752
        }
753

    
754
        if (ctx->fpscr & FPSCR_PR) {
755
            gen_op_fmov_DT0_drN(DREG(B11_8));
756
        }
757
        else {
758
            gen_op_fmov_FT0_frN(FREG(B11_8));
759
        }
760
        return;
761
    }
762

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

    
906
    switch (ctx->opcode & 0xf08f) {
907
    case 0x408e:                /* ldc Rm,Rn_BANK */
908
        gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
909
        return;
910
    case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
911
        gen_op_movl_rN_T0(REG(B11_8));
912
        gen_op_ldl_T0_T0(ctx);
913
        gen_op_movl_T0_rN(ALTREG(B6_4));
914
        gen_op_inc4_rN(REG(B11_8));
915
        return;
916
    case 0x0082:                /* stc Rm_BANK,Rn */
917
        gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
918
        return;
919
    case 0x4083:                /* stc.l Rm_BANK,@-Rn */
920
        gen_op_dec4_rN(REG(B11_8));
921
        gen_op_movl_rN_T1(REG(B11_8));
922
        gen_op_movl_rN_T0(ALTREG(B6_4));
923
        gen_op_stl_T0_T1(ctx);
924
        return;
925
    }
926

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

    
1153
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1154
            ctx->opcode, ctx->pc);
1155
    gen_op_raise_illegal_instruction();
1156
    ctx->bstate = BS_EXCP;
1157
}
1158

    
1159
void decode_opc(DisasContext * ctx)
1160
{
1161
    uint32_t old_flags = ctx->flags;
1162

    
1163
    _decode_opc(ctx);
1164

    
1165
    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1166
        if (ctx->flags & DELAY_SLOT_CLEARME) {
1167
            gen_op_store_flags(0);
1168
        }
1169
        ctx->flags = 0;
1170
        ctx->bstate = BS_BRANCH;
1171
        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1172
            gen_delayed_conditional_jump(ctx);
1173
        } else if (old_flags & DELAY_SLOT) {
1174
            gen_jump(ctx);
1175
        }
1176

    
1177
    }
1178
}
1179

    
1180
static inline int
1181
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1182
                               int search_pc)
1183
{
1184
    DisasContext ctx;
1185
    target_ulong pc_start;
1186
    static uint16_t *gen_opc_end;
1187
    int i, ii;
1188

    
1189
    pc_start = tb->pc;
1190
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1191
    ctx.pc = pc_start;
1192
    ctx.flags = (uint32_t)tb->flags;
1193
    ctx.bstate = BS_NONE;
1194
    ctx.sr = env->sr;
1195
    ctx.fpscr = env->fpscr;
1196
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1197
    /* We don't know if the delayed pc came from a dynamic or static branch,
1198
       so assume it is a dynamic branch.  */
1199
    ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1200
    ctx.tb = tb;
1201
    ctx.singlestep_enabled = env->singlestep_enabled;
1202

    
1203
#ifdef DEBUG_DISAS
1204
    if (loglevel & CPU_LOG_TB_CPU) {
1205
        fprintf(logfile,
1206
                "------------------------------------------------\n");
1207
        cpu_dump_state(env, logfile, fprintf, 0);
1208
    }
1209
#endif
1210

    
1211
    ii = -1;
1212
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1213
        if (env->nb_breakpoints > 0) {
1214
            for (i = 0; i < env->nb_breakpoints; i++) {
1215
                if (ctx.pc == env->breakpoints[i]) {
1216
                    /* We have hit a breakpoint - make sure PC is up-to-date */
1217
                    gen_op_movl_imm_PC(ctx.pc);
1218
                    gen_op_debug();
1219
                    ctx.bstate = BS_EXCP;
1220
                    break;
1221
                }
1222
            }
1223
        }
1224
        if (search_pc) {
1225
            i = gen_opc_ptr - gen_opc_buf;
1226
            if (ii < i) {
1227
                ii++;
1228
                while (ii < i)
1229
                    gen_opc_instr_start[ii++] = 0;
1230
            }
1231
            gen_opc_pc[ii] = ctx.pc;
1232
            gen_opc_hflags[ii] = ctx.flags;
1233
            gen_opc_instr_start[ii] = 1;
1234
        }
1235
#if 0
1236
        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1237
        fflush(stderr);
1238
#endif
1239
        ctx.opcode = lduw_code(ctx.pc);
1240
        decode_opc(&ctx);
1241
        ctx.pc += 2;
1242
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1243
            break;
1244
        if (env->singlestep_enabled)
1245
            break;
1246
#ifdef SH4_SINGLE_STEP
1247
        break;
1248
#endif
1249
    }
1250
    if (env->singlestep_enabled) {
1251
        gen_op_debug();
1252
    } else {
1253
        switch (ctx.bstate) {
1254
        case BS_STOP:
1255
            /* gen_op_interrupt_restart(); */
1256
            /* fall through */
1257
        case BS_NONE:
1258
            if (ctx.flags) {
1259
                gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1260
            }
1261
            gen_goto_tb(&ctx, 0, ctx.pc);
1262
            break;
1263
        case BS_EXCP:
1264
            /* gen_op_interrupt_restart(); */
1265
            tcg_gen_exit_tb(0);
1266
            break;
1267
        case BS_BRANCH:
1268
        default:
1269
            break;
1270
        }
1271
    }
1272

    
1273
    *gen_opc_ptr = INDEX_op_end;
1274
    if (search_pc) {
1275
        i = gen_opc_ptr - gen_opc_buf;
1276
        ii++;
1277
        while (ii <= i)
1278
            gen_opc_instr_start[ii++] = 0;
1279
    } else {
1280
        tb->size = ctx.pc - pc_start;
1281
    }
1282

    
1283
#ifdef DEBUG_DISAS
1284
#ifdef SH4_DEBUG_DISAS
1285
    if (loglevel & CPU_LOG_TB_IN_ASM)
1286
        fprintf(logfile, "\n");
1287
#endif
1288
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1289
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1290
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1291
        fprintf(logfile, "\n");
1292
    }
1293
#endif
1294
    return 0;
1295
}
1296

    
1297
int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1298
{
1299
    return gen_intermediate_code_internal(env, tb, 0);
1300
}
1301

    
1302
int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1303
{
1304
    return gen_intermediate_code_internal(env, tb, 1);
1305
}
1306

    
1307
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1308
                unsigned long searched_pc, int pc_pos, void *puc)
1309
{
1310
    env->pc = gen_opc_pc[pc_pos];
1311
    env->flags = gen_opc_hflags[pc_pos];
1312
}