Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ ccc9cc5b

History | View | Annotate | Download (37.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 "helper.h"
35
#include "tcg-op.h"
36
#include "qemu-common.h"
37

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

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

    
60
static TCGv cpu_env, cpu_T[2];
61

    
62
#include "gen-icount.h"
63

    
64
static void sh4_translate_init(void)
65
{
66
    static int done_init = 0;
67
    if (done_init)
68
        return;
69
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
70
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
71
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
72

    
73
    /* register helpers */
74
#undef DEF_HELPER
75
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
76
#include "helper.h"
77

    
78
    done_init = 1;
79
}
80

    
81
#ifdef CONFIG_USER_ONLY
82

    
83
#define GEN_OP_LD(width, reg) \
84
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
85
    gen_op_ld##width##_T0_##reg##_raw(); \
86
  }
87
#define GEN_OP_ST(width, reg) \
88
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
89
    gen_op_st##width##_##reg##_T1_raw(); \
90
  }
91

    
92
#else
93

    
94
#define GEN_OP_LD(width, reg) \
95
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
96
    if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
97
    else gen_op_ld##width##_T0_##reg##_user();\
98
  }
99
#define GEN_OP_ST(width, reg) \
100
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
101
    if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
102
    else gen_op_st##width##_##reg##_T1_user();\
103
  }
104

    
105
#endif
106

    
107
GEN_OP_LD(ub, T0)
108
GEN_OP_LD(b, T0)
109
GEN_OP_ST(b, T0)
110
GEN_OP_LD(uw, T0)
111
GEN_OP_LD(w, T0)
112
GEN_OP_ST(w, T0)
113
GEN_OP_LD(l, T0)
114
GEN_OP_ST(l, T0)
115
GEN_OP_LD(fl, FT0)
116
GEN_OP_ST(fl, FT0)
117
GEN_OP_LD(fq, DT0)
118
GEN_OP_ST(fq, DT0)
119

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

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

    
164
CPUSH4State *cpu_sh4_init(const char *cpu_model)
165
{
166
    CPUSH4State *env;
167

    
168
    env = qemu_mallocz(sizeof(CPUSH4State));
169
    if (!env)
170
        return NULL;
171
    cpu_exec_init(env);
172
    sh4_translate_init();
173
    cpu_sh4_reset(env);
174
    tlb_flush(env, 1);
175
    return env;
176
}
177

    
178
static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
179
{
180
    TranslationBlock *tb;
181
    tb = ctx->tb;
182

    
183
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
184
        !ctx->singlestep_enabled) {
185
        /* Use a direct jump if in same page and singlestep not enabled */
186
        tcg_gen_goto_tb(n);
187
        gen_op_movl_imm_PC(dest);
188
        tcg_gen_exit_tb((long) tb + n);
189
    } else {
190
        gen_op_movl_imm_PC(dest);
191
        if (ctx->singlestep_enabled)
192
            gen_op_debug();
193
        tcg_gen_exit_tb(0);
194
    }
195
}
196

    
197
static void gen_jump(DisasContext * ctx)
198
{
199
    if (ctx->delayed_pc == (uint32_t) - 1) {
200
        /* Target is not statically known, it comes necessarily from a
201
           delayed jump as immediate jump are conditinal jumps */
202
        gen_op_movl_delayed_pc_PC();
203
        if (ctx->singlestep_enabled)
204
            gen_op_debug();
205
        tcg_gen_exit_tb(0);
206
    } else {
207
        gen_goto_tb(ctx, 0, ctx->delayed_pc);
208
    }
209
}
210

    
211
/* Immediate conditional jump (bt or bf) */
212
static void gen_conditional_jump(DisasContext * ctx,
213
                                 target_ulong ift, target_ulong ifnott)
214
{
215
    int l1;
216

    
217
    l1 = gen_new_label();
218
    gen_op_jT(l1);
219
    gen_goto_tb(ctx, 0, ifnott);
220
    gen_set_label(l1);
221
    gen_goto_tb(ctx, 1, ift);
222
}
223

    
224
/* Delayed conditional jump (bt or bf) */
225
static void gen_delayed_conditional_jump(DisasContext * ctx)
226
{
227
    int l1;
228

    
229
    l1 = gen_new_label();
230
    gen_op_jdelayed(l1);
231
    gen_goto_tb(ctx, 1, ctx->pc + 2);
232
    gen_set_label(l1);
233
    gen_jump(ctx);
234
}
235

    
236
#define B3_0 (ctx->opcode & 0xf)
237
#define B6_4 ((ctx->opcode >> 4) & 0x7)
238
#define B7_4 ((ctx->opcode >> 4) & 0xf)
239
#define B7_0 (ctx->opcode & 0xff)
240
#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
241
#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
242
  (ctx->opcode & 0xfff))
243
#define B11_8 ((ctx->opcode >> 8) & 0xf)
244
#define B15_12 ((ctx->opcode >> 12) & 0xf)
245

    
246
#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
247
                (x) + 16 : (x))
248

    
249
#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
250
                ? (x) + 16 : (x))
251

    
252
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
253
#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
254
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
255
#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
256

    
257
#define CHECK_NOT_DELAY_SLOT \
258
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
259
  {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
260
   return;}
261

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

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

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

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

    
800
        if (ctx->fpscr & FPSCR_PR) {
801
            gen_op_fmov_DT0_drN(DREG(B11_8));
802
        }
803
        else {
804
            gen_op_fmov_FT0_frN(FREG(B11_8));
805
        }
806
        return;
807
    }
808

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

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

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

    
1208
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1209
            ctx->opcode, ctx->pc);
1210
    gen_op_raise_illegal_instruction();
1211
    ctx->bstate = BS_EXCP;
1212
}
1213

    
1214
void decode_opc(DisasContext * ctx)
1215
{
1216
    uint32_t old_flags = ctx->flags;
1217

    
1218
    _decode_opc(ctx);
1219

    
1220
    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1221
        if (ctx->flags & DELAY_SLOT_CLEARME) {
1222
            gen_op_store_flags(0);
1223
        } else {
1224
            /* go out of the delay slot */
1225
            uint32_t new_flags = ctx->flags;
1226
            new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1227
            gen_op_store_flags(new_flags);
1228
        }
1229
        ctx->flags = 0;
1230
        ctx->bstate = BS_BRANCH;
1231
        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1232
            gen_delayed_conditional_jump(ctx);
1233
        } else if (old_flags & DELAY_SLOT) {
1234
            gen_jump(ctx);
1235
        }
1236

    
1237
    }
1238

    
1239
    /* go into a delay slot */
1240
    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1241
        gen_op_store_flags(ctx->flags);
1242
}
1243

    
1244
static inline void
1245
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1246
                               int search_pc)
1247
{
1248
    DisasContext ctx;
1249
    target_ulong pc_start;
1250
    static uint16_t *gen_opc_end;
1251
    int i, ii;
1252
    int num_insns;
1253
    int max_insns;
1254

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

    
1269
#ifdef DEBUG_DISAS
1270
    if (loglevel & CPU_LOG_TB_CPU) {
1271
        fprintf(logfile,
1272
                "------------------------------------------------\n");
1273
        cpu_dump_state(env, logfile, fprintf, 0);
1274
    }
1275
#endif
1276

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

    
1352
    gen_icount_end(tb, num_insns);
1353
    *gen_opc_ptr = INDEX_op_end;
1354
    if (search_pc) {
1355
        i = gen_opc_ptr - gen_opc_buf;
1356
        ii++;
1357
        while (ii <= i)
1358
            gen_opc_instr_start[ii++] = 0;
1359
    } else {
1360
        tb->size = ctx.pc - pc_start;
1361
        tb->icount = num_insns;
1362
    }
1363

    
1364
#ifdef DEBUG_DISAS
1365
#ifdef SH4_DEBUG_DISAS
1366
    if (loglevel & CPU_LOG_TB_IN_ASM)
1367
        fprintf(logfile, "\n");
1368
#endif
1369
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1370
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1371
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1372
        fprintf(logfile, "\n");
1373
    }
1374
#endif
1375
}
1376

    
1377
void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1378
{
1379
    gen_intermediate_code_internal(env, tb, 0);
1380
}
1381

    
1382
void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1383
{
1384
    gen_intermediate_code_internal(env, tb, 1);
1385
}
1386

    
1387
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1388
                unsigned long searched_pc, int pc_pos, void *puc)
1389
{
1390
    env->pc = gen_opc_pc[pc_pos];
1391
    env->flags = gen_opc_hflags[pc_pos];
1392
}