Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ 397e923f

History | View | Annotate | Download (32.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

    
35
enum {
36
#define DEF(s, n, copy_size) INDEX_op_ ## s,
37
#include "opc.h"
38
#undef DEF
39
    NB_OPS,
40
};
41

    
42
#ifdef USE_DIRECT_JUMP
43
#define TBPARAM(x)
44
#else
45
#define TBPARAM(x) ((long)(x))
46
#endif
47

    
48
static uint16_t *gen_opc_ptr;
49
static uint32_t *gen_opparam_ptr;
50

    
51
#include "gen-op.h"
52

    
53
typedef struct DisasContext {
54
    struct TranslationBlock *tb;
55
    target_ulong pc;
56
    uint32_t sr;
57
    uint32_t fpscr;
58
    uint16_t opcode;
59
    uint32_t flags;
60
    int memidx;
61
    uint32_t delayed_pc;
62
    int singlestep_enabled;
63
} DisasContext;
64

    
65
#ifdef CONFIG_USER_ONLY
66

    
67
#define GEN_OP_LD(width, reg) \
68
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
69
    gen_op_ld##width##_T0_##reg##_raw(); \
70
  }
71
#define GEN_OP_ST(width, reg) \
72
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
73
    gen_op_st##width##_##reg##_T1_raw(); \
74
  }
75

    
76
#else
77

    
78
#define GEN_OP_LD(width, reg) \
79
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
80
    if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
81
    else gen_op_ld##width##_T0_##reg##_user();\
82
  }
83
#define GEN_OP_ST(width, reg) \
84
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
85
    if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
86
    else gen_op_st##width##_##reg##_T1_user();\
87
  }
88

    
89
#endif
90

    
91
GEN_OP_LD(ub, T0)
92
GEN_OP_LD(b, T0)
93
GEN_OP_ST(b, T0)
94
GEN_OP_LD(uw, T0)
95
GEN_OP_LD(w, T0)
96
GEN_OP_ST(w, T0)
97
GEN_OP_LD(l, T0)
98
GEN_OP_ST(l, T0)
99
GEN_OP_LD(fl, FT0)
100
GEN_OP_ST(fl, FT0)
101
GEN_OP_LD(fq, DT0)
102
GEN_OP_ST(fq, DT0)
103

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

    
125
void cpu_sh4_reset(CPUSH4State * env)
126
{
127
    env->sr = 0x700000F0;        /* MD, RB, BL, I3-I0 */
128
    env->vbr = 0;
129
    env->pc = 0xA0000000;
130
    env->fpscr = 0x00040001;
131
    env->mmucr = 0;
132
}
133

    
134
CPUSH4State *cpu_sh4_init(void)
135
{
136
    CPUSH4State *env;
137

    
138
    env = qemu_mallocz(sizeof(CPUSH4State));
139
    if (!env)
140
        return NULL;
141
    cpu_exec_init(env);
142
    cpu_sh4_reset(env);
143
    tlb_flush(env, 1);
144
    return env;
145
}
146

    
147
static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
148
{
149
    TranslationBlock *tb;
150
    tb = ctx->tb;
151

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

    
169
/* Jump to pc after an exception */
170
static void gen_jump_exception(DisasContext * ctx)
171
{
172
    gen_op_movl_imm_T0(0);
173
    if (ctx->singlestep_enabled)
174
        gen_op_debug();
175
    gen_op_exit_tb();
176
}
177

    
178
static void gen_jump(DisasContext * ctx)
179
{
180
    if (ctx->delayed_pc == (uint32_t) - 1) {
181
        /* Target is not statically known, it comes necessarily from a
182
           delayed jump as immediate jump are conditinal jumps */
183
        gen_op_movl_delayed_pc_PC();
184
        gen_op_movl_imm_T0(0);
185
        if (ctx->singlestep_enabled)
186
            gen_op_debug();
187
        gen_op_exit_tb();
188
    } else {
189
        gen_goto_tb(ctx, 0, ctx->delayed_pc);
190
    }
191
}
192

    
193
/* Immediate conditional jump (bt or bf) */
194
static void gen_conditional_jump(DisasContext * ctx,
195
                                 target_ulong ift, target_ulong ifnott)
196
{
197
    int l1;
198

    
199
    l1 = gen_new_label();
200
    gen_op_jT(l1);
201
    gen_goto_tb(ctx, 0, ifnott);
202
    gen_set_label(l1);
203
    gen_goto_tb(ctx, 1, ift);
204
}
205

    
206
/* Delayed conditional jump (bt or bf) */
207
static void gen_delayed_conditional_jump(DisasContext * ctx)
208
{
209
    int l1;
210

    
211
    l1 = gen_new_label();
212
    gen_op_jTT2(l1);
213
    gen_goto_tb(ctx, 0, ctx->pc);
214
    gen_set_label(l1);
215
    gen_goto_tb(ctx, 1, ctx->delayed_pc);
216
}
217

    
218
#define B3_0 (ctx->opcode & 0xf)
219
#define B6_4 ((ctx->opcode >> 4) & 0x7)
220
#define B7_4 ((ctx->opcode >> 4) & 0xf)
221
#define B7_0 (ctx->opcode & 0xff)
222
#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
223
#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
224
  (ctx->opcode & 0xfff))
225
#define B11_8 ((ctx->opcode >> 8) & 0xf)
226
#define B15_12 ((ctx->opcode >> 12) & 0xf)
227

    
228
#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
229
                (x) + 16 : (x))
230

    
231
#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
232
                ? (x) + 16 : (x))
233

    
234
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
235
#define XHACK(x) (((x) & 1 ) << 4 | ((x) & 0xe ) << 1)
236
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
237

    
238
#define CHECK_NOT_DELAY_SLOT \
239
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
240
  {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \
241
   return;}
242

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

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

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

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

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

    
933
    switch (ctx->opcode & 0xf0ff) {
934
    case 0x0023:                /* braf Rn */
935
        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
936
        gen_op_braf_T0(ctx->pc + 4);
937
        ctx->flags |= DELAY_SLOT;
938
        ctx->delayed_pc = (uint32_t) - 1;
939
        return;
940
    case 0x0003:                /* bsrf Rn */
941
        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
942
        gen_op_bsrf_T0(ctx->pc + 4);
943
        ctx->flags |= DELAY_SLOT;
944
        ctx->delayed_pc = (uint32_t) - 1;
945
        return;
946
    case 0x4015:                /* cmp/pl Rn */
947
        gen_op_movl_rN_T0(REG(B11_8));
948
        gen_op_cmp_pl_T0();
949
        return;
950
    case 0x4011:                /* cmp/pz Rn */
951
        gen_op_movl_rN_T0(REG(B11_8));
952
        gen_op_cmp_pz_T0();
953
        return;
954
    case 0x4010:                /* dt Rn */
955
        gen_op_dt_rN(REG(B11_8));
956
        return;
957
    case 0x402b:                /* jmp @Rn */
958
        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
959
        gen_op_jmp_T0();
960
        ctx->flags |= DELAY_SLOT;
961
        ctx->delayed_pc = (uint32_t) - 1;
962
        return;
963
    case 0x400b:                /* jsr @Rn */
964
        CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
965
        gen_op_jsr_T0(ctx->pc + 4);
966
        ctx->flags |= DELAY_SLOT;
967
        ctx->delayed_pc = (uint32_t) - 1;
968
        return;
969
#define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald)        \
970
  case ldnum:                                                        \
971
    gen_op_movl_rN_T0 (REG(B11_8));                                \
972
    gen_op_##ldop##_T0_##reg ();                                \
973
    extrald                                                        \
974
    return;                                                        \
975
  case ldpnum:                                                        \
976
    gen_op_movl_rN_T0 (REG(B11_8));                                \
977
    gen_op_ldl_T0_T0 (ctx);                                        \
978
    gen_op_inc4_rN (REG(B11_8));                                \
979
    gen_op_##ldop##_T0_##reg ();                                \
980
    extrald                                                        \
981
    return;                                                        \
982
  case stnum:                                                        \
983
    gen_op_##stop##_##reg##_T0 ();                                        \
984
    gen_op_movl_T0_rN (REG(B11_8));                                \
985
    return;                                                        \
986
  case stpnum:                                                        \
987
    gen_op_##stop##_##reg##_T0 ();                                \
988
    gen_op_dec4_rN (REG(B11_8));                                \
989
    gen_op_movl_rN_T1 (REG(B11_8));                                \
990
    gen_op_stl_T0_T1 (ctx);                                        \
991
    return;
992
        LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |=
993
             MODE_CHANGE;)
994
        LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
995
        LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
996
        LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
997
        LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
998
        LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
999
        LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1000
        LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1001
        LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1002
        LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x0052, sts,)
1003
        LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x0062, sts, ctx->flags |=
1004
             MODE_CHANGE;)
1005
    case 0x00c3:                /* movca.l R0,@Rm */
1006
        gen_op_movl_rN_T0(REG(0));
1007
        gen_op_movl_rN_T1(REG(B11_8));
1008
        gen_op_stl_T0_T1(ctx);
1009
        return;
1010
    case 0x0029:                /* movt Rn */
1011
        gen_op_movt_rN(REG(B11_8));
1012
        return;
1013
    case 0x0093:                /* ocbi @Rn */
1014
        gen_op_movl_rN_T0(REG(B11_8));
1015
        gen_op_ldl_T0_T0(ctx);
1016
        return;
1017
    case 0x00a2:                /* ocbp @Rn */
1018
        gen_op_movl_rN_T0(REG(B11_8));
1019
        gen_op_ldl_T0_T0(ctx);
1020
        return;
1021
    case 0x00b3:                /* ocbwb @Rn */
1022
        gen_op_movl_rN_T0(REG(B11_8));
1023
        gen_op_ldl_T0_T0(ctx);
1024
        return;
1025
    case 0x0083:                /* pref @Rn */
1026
        return;
1027
    case 0x4024:                /* rotcl Rn */
1028
        gen_op_rotcl_Rn(REG(B11_8));
1029
        return;
1030
    case 0x4025:                /* rotcr Rn */
1031
        gen_op_rotcr_Rn(REG(B11_8));
1032
        return;
1033
    case 0x4004:                /* rotl Rn */
1034
        gen_op_rotl_Rn(REG(B11_8));
1035
        return;
1036
    case 0x4005:                /* rotr Rn */
1037
        gen_op_rotr_Rn(REG(B11_8));
1038
        return;
1039
    case 0x4000:                /* shll Rn */
1040
    case 0x4020:                /* shal Rn */
1041
        gen_op_shal_Rn(REG(B11_8));
1042
        return;
1043
    case 0x4021:                /* shar Rn */
1044
        gen_op_shar_Rn(REG(B11_8));
1045
        return;
1046
    case 0x4001:                /* shlr Rn */
1047
        gen_op_shlr_Rn(REG(B11_8));
1048
        return;
1049
    case 0x4008:                /* shll2 Rn */
1050
        gen_op_shll2_Rn(REG(B11_8));
1051
        return;
1052
    case 0x4018:                /* shll8 Rn */
1053
        gen_op_shll8_Rn(REG(B11_8));
1054
        return;
1055
    case 0x4028:                /* shll16 Rn */
1056
        gen_op_shll16_Rn(REG(B11_8));
1057
        return;
1058
    case 0x4009:                /* shlr2 Rn */
1059
        gen_op_shlr2_Rn(REG(B11_8));
1060
        return;
1061
    case 0x4019:                /* shlr8 Rn */
1062
        gen_op_shlr8_Rn(REG(B11_8));
1063
        return;
1064
    case 0x4029:                /* shlr16 Rn */
1065
        gen_op_shlr16_Rn(REG(B11_8));
1066
        return;
1067
    case 0x401b:                /* tas.b @Rn */
1068
        gen_op_tasb_rN(REG(B11_8));
1069
        return;
1070
    case 0xf00d:                /* fsts FPUL,FRn */
1071
        gen_op_movl_fpul_FT0();
1072
        gen_op_fmov_FT0_frN(FREG(B11_8));
1073
        return;
1074
    case 0xf01d:                /* flds FRm.FPUL */
1075
        gen_op_fmov_frN_FT0(FREG(B11_8));
1076
        gen_op_movl_FT0_fpul();
1077
        return;
1078
    }
1079

    
1080
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1081
            ctx->opcode, ctx->pc);
1082
    gen_op_raise_illegal_instruction();
1083
    ctx->flags |= BRANCH_EXCEPTION;
1084
}
1085

    
1086
int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1087
                                   int search_pc)
1088
{
1089
    DisasContext ctx;
1090
    target_ulong pc_start;
1091
    static uint16_t *gen_opc_end;
1092
    uint32_t old_flags;
1093
    int i, ii;
1094

    
1095
    pc_start = tb->pc;
1096
    gen_opc_ptr = gen_opc_buf;
1097
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1098
    gen_opparam_ptr = gen_opparam_buf;
1099
    ctx.pc = pc_start;
1100
    ctx.flags = env->flags;
1101
    old_flags = 0;
1102
    ctx.sr = env->sr;
1103
    ctx.fpscr = env->fpscr;
1104
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1105
    /* We don't know if the delayed pc came from a dynamic or static branch,
1106
       so assume it is a dynamic branch.  */
1107
    ctx.delayed_pc = -1;
1108
    ctx.tb = tb;
1109
    ctx.singlestep_enabled = env->singlestep_enabled;
1110
    nb_gen_labels = 0;
1111

    
1112
#ifdef DEBUG_DISAS
1113
    if (loglevel & CPU_LOG_TB_CPU) {
1114
        fprintf(logfile,
1115
                "------------------------------------------------\n");
1116
        cpu_dump_state(env, logfile, fprintf, 0);
1117
    }
1118
#endif
1119

    
1120
    ii = -1;
1121
    while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 &&
1122
           (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE |
1123
                         BRANCH_EXCEPTION)) == 0 &&
1124
           gen_opc_ptr < gen_opc_end && ctx.sr == env->sr) {
1125
        old_flags = ctx.flags;
1126
        if (env->nb_breakpoints > 0) {
1127
            for (i = 0; i < env->nb_breakpoints; i++) {
1128
                if (ctx.pc == env->breakpoints[i]) {
1129
                    /* We have hit a breakpoint - make sure PC is up-to-date */
1130
                    gen_op_movl_imm_PC(ctx.pc);
1131
                    gen_op_debug();
1132
                    ctx.flags |= BRANCH_EXCEPTION;
1133
                    break;
1134
                }
1135
            }
1136
        }
1137
        if (search_pc) {
1138
            i = gen_opc_ptr - gen_opc_buf;
1139
            if (ii < i) {
1140
                ii++;
1141
                while (ii < i)
1142
                    gen_opc_instr_start[ii++] = 0;
1143
            }
1144
            gen_opc_pc[ii] = ctx.pc;
1145
            gen_opc_instr_start[ii] = 1;
1146
        }
1147
#if 0
1148
        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1149
        fflush(stderr);
1150
#endif
1151
        ctx.opcode = lduw_code(ctx.pc);
1152
        decode_opc(&ctx);
1153
        ctx.pc += 2;
1154
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1155
            break;
1156
        if (env->singlestep_enabled)
1157
            break;
1158
#ifdef SH4_SINGLE_STEP
1159
        break;
1160
#endif
1161
    }
1162

    
1163
    switch (old_flags & (DELAY_SLOT_CONDITIONAL | DELAY_SLOT)) {
1164
    case DELAY_SLOT_CONDITIONAL:
1165
        gen_op_clr_delay_slot_conditional();
1166
        gen_delayed_conditional_jump(&ctx);
1167
        break;
1168
    case DELAY_SLOT:
1169
        gen_op_clr_delay_slot();
1170
        gen_jump(&ctx);
1171
        break;
1172
    case 0:
1173
        if (ctx.flags & BRANCH_EXCEPTION) {
1174
            gen_jump_exception(&ctx);
1175
        } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) {
1176
            gen_goto_tb(&ctx, 0, ctx.pc);
1177
        }
1178
        break;
1179
    default:
1180
        /* Both cannot be set at the same time */
1181
        assert(0);
1182
    }
1183

    
1184
    if (env->singlestep_enabled) {
1185
        gen_op_debug();
1186
    }
1187
    *gen_opc_ptr = INDEX_op_end;
1188
    if (search_pc) {
1189
        i = gen_opc_ptr - gen_opc_buf;
1190
        ii++;
1191
        while (ii <= i)
1192
            gen_opc_instr_start[ii++] = 0;
1193
        tb->size = 0;
1194
    } else {
1195
        tb->size = ctx.pc - pc_start;
1196
    }
1197

    
1198
#ifdef DEBUG_DISAS
1199
#ifdef SH4_DEBUG_DISAS
1200
    if (loglevel & CPU_LOG_TB_IN_ASM)
1201
        fprintf(logfile, "\n");
1202
#endif
1203
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1204
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1205
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1206
        fprintf(logfile, "\n");
1207
    }
1208
    if (loglevel & CPU_LOG_TB_OP) {
1209
        fprintf(logfile, "OP:\n");
1210
        dump_ops(gen_opc_buf, gen_opparam_buf);
1211
        fprintf(logfile, "\n");
1212
    }
1213
#endif
1214
    return 0;
1215
}
1216

    
1217
int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1218
{
1219
    return gen_intermediate_code_internal(env, tb, 0);
1220
}
1221

    
1222
int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1223
{
1224
    return gen_intermediate_code_internal(env, tb, 1);
1225
}