Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ f8ed7070

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
#if defined(CONFIG_USER_ONLY)
260
        assert(0);                /* XXXXX */
261
#else
262
        gen_op_ldtlb();
263
#endif
264
        return;
265
    case 0x002b:                /* rte */
266
        CHECK_NOT_DELAY_SLOT gen_op_rte();
267
        ctx->flags |= DELAY_SLOT;
268
        ctx->delayed_pc = (uint32_t) - 1;
269
        return;
270
    case 0x0058:                /* sets */
271
        gen_op_sets();
272
        return;
273
    case 0x0018:                /* sett */
274
        gen_op_sett();
275
        return;
276
    case 0xfbfd:                /* frchg */
277
        gen_op_frchg();
278
        ctx->bstate = BS_STOP;
279
        return;
280
    case 0xf3fd:                /* fschg */
281
        gen_op_fschg();
282
        ctx->bstate = BS_STOP;
283
        return;
284
    case 0x0009:                /* nop */
285
        return;
286
    case 0x001b:                /* sleep */
287
        assert(0);                /* XXXXX */
288
        return;
289
    }
290

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

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

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

    
758
        if (ctx->fpscr & FPSCR_PR) {
759
            gen_op_fmov_DT0_drN(DREG(B11_8));
760
        }
761
        else {
762
            gen_op_fmov_FT0_frN(FREG(B11_8));
763
        }
764
        return;
765
    }
766

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

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

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

    
1157
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1158
            ctx->opcode, ctx->pc);
1159
    gen_op_raise_illegal_instruction();
1160
    ctx->bstate = BS_EXCP;
1161
}
1162

    
1163
void decode_opc(DisasContext * ctx)
1164
{
1165
    uint32_t old_flags = ctx->flags;
1166

    
1167
    _decode_opc(ctx);
1168

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

    
1181
    }
1182
}
1183

    
1184
static inline int
1185
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1186
                               int search_pc)
1187
{
1188
    DisasContext ctx;
1189
    target_ulong pc_start;
1190
    static uint16_t *gen_opc_end;
1191
    int i, ii;
1192

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

    
1207
#ifdef DEBUG_DISAS
1208
    if (loglevel & CPU_LOG_TB_CPU) {
1209
        fprintf(logfile,
1210
                "------------------------------------------------\n");
1211
        cpu_dump_state(env, logfile, fprintf, 0);
1212
    }
1213
#endif
1214

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

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

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

    
1301
int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1302
{
1303
    return gen_intermediate_code_internal(env, tb, 0);
1304
}
1305

    
1306
int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1307
{
1308
    return gen_intermediate_code_internal(env, tb, 1);
1309
}
1310

    
1311
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1312
                unsigned long searched_pc, int pc_pos, void *puc)
1313
{
1314
    env->pc = gen_opc_pc[pc_pos];
1315
    env->flags = gen_opc_hflags[pc_pos];
1316
}