Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ 3bf73a49

History | View | Annotate | Download (39.8 kB)

1
/*
2
 *  SH4 translation
3
 *
4
 *  Copyright (c) 2005 Samuel Tardieu
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
#include <stdarg.h>
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <string.h>
24
#include <inttypes.h>
25
#include <assert.h>
26

    
27
#define DEBUG_DISAS
28
#define SH4_DEBUG_DISAS
29
//#define SH4_SINGLE_STEP
30

    
31
#include "cpu.h"
32
#include "exec-all.h"
33
#include "disas.h"
34
#include "helper.h"
35
#include "tcg-op.h"
36
#include "qemu-common.h"
37

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

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

    
60
static TCGv cpu_env, cpu_T[2];
61

    
62
#include "gen-icount.h"
63

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

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

    
78
    done_init = 1;
79
}
80

    
81
/* General purpose registers moves. */
82
static inline void gen_movl_imm_rN(uint32_t arg, int reg)
83
{
84
    TCGv tmp = tcg_const_i32(arg);
85
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, gregs[reg]));
86
    tcg_temp_free(tmp);
87
}
88

    
89
static always_inline void gen_movl_T_rN (TCGv t, int reg)
90
{
91
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, gregs[reg]));
92
}
93

    
94
static always_inline void gen_movl_rN_T (TCGv t, int reg)
95
{
96
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, gregs[reg]));
97
}
98

    
99
#ifdef CONFIG_USER_ONLY
100

    
101
#define GEN_OP_LD(width, reg) \
102
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
103
    gen_op_ld##width##_T0_##reg##_raw(); \
104
  }
105
#define GEN_OP_ST(width, reg) \
106
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
107
    gen_op_st##width##_##reg##_T1_raw(); \
108
  }
109

    
110
#else
111

    
112
#define GEN_OP_LD(width, reg) \
113
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
114
    if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
115
    else gen_op_ld##width##_T0_##reg##_user();\
116
  }
117
#define GEN_OP_ST(width, reg) \
118
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
119
    if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
120
    else gen_op_st##width##_##reg##_T1_user();\
121
  }
122

    
123
#endif
124

    
125
GEN_OP_LD(ub, T0)
126
GEN_OP_LD(b, T0)
127
GEN_OP_ST(b, T0)
128
GEN_OP_LD(uw, T0)
129
GEN_OP_LD(w, T0)
130
GEN_OP_ST(w, T0)
131
GEN_OP_LD(l, T0)
132
GEN_OP_ST(l, T0)
133
GEN_OP_LD(fl, FT0)
134
GEN_OP_ST(fl, FT0)
135
GEN_OP_LD(fq, DT0)
136
GEN_OP_ST(fq, DT0)
137

    
138
void cpu_dump_state(CPUState * env, FILE * f,
139
                    int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
140
                    int flags)
141
{
142
    int i;
143
    cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
144
                env->pc, env->sr, env->pr, env->fpscr);
145
    cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
146
                env->spc, env->ssr, env->gbr, env->vbr);
147
    cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
148
                env->sgr, env->dbr, env->delayed_pc, env->fpul);
149
    for (i = 0; i < 24; i += 4) {
150
        cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
151
                    i, env->gregs[i], i + 1, env->gregs[i + 1],
152
                    i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
153
    }
154
    if (env->flags & DELAY_SLOT) {
155
        cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
156
                    env->delayed_pc);
157
    } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
158
        cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
159
                    env->delayed_pc);
160
    }
161
}
162

    
163
void cpu_sh4_reset(CPUSH4State * env)
164
{
165
#if defined(CONFIG_USER_ONLY)
166
    env->sr = SR_FD;            /* FD - kernel does lazy fpu context switch */
167
#else
168
    env->sr = 0x700000F0;        /* MD, RB, BL, I3-I0 */
169
#endif
170
    env->vbr = 0;
171
    env->pc = 0xA0000000;
172
#if defined(CONFIG_USER_ONLY)
173
    env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
174
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
175
#else
176
    env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
177
    set_float_rounding_mode(float_round_to_zero, &env->fp_status);
178
#endif
179
    env->mmucr = 0;
180
}
181

    
182
CPUSH4State *cpu_sh4_init(const char *cpu_model)
183
{
184
    CPUSH4State *env;
185

    
186
    env = qemu_mallocz(sizeof(CPUSH4State));
187
    if (!env)
188
        return NULL;
189
    cpu_exec_init(env);
190
    sh4_translate_init();
191
    cpu_sh4_reset(env);
192
    tlb_flush(env, 1);
193
    return env;
194
}
195

    
196
static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
197
{
198
    TranslationBlock *tb;
199
    tb = ctx->tb;
200

    
201
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
202
        !ctx->singlestep_enabled) {
203
        /* Use a direct jump if in same page and singlestep not enabled */
204
        tcg_gen_goto_tb(n);
205
        gen_op_movl_imm_PC(dest);
206
        tcg_gen_exit_tb((long) tb + n);
207
    } else {
208
        gen_op_movl_imm_PC(dest);
209
        if (ctx->singlestep_enabled)
210
            gen_op_debug();
211
        tcg_gen_exit_tb(0);
212
    }
213
}
214

    
215
static void gen_jump(DisasContext * ctx)
216
{
217
    if (ctx->delayed_pc == (uint32_t) - 1) {
218
        /* Target is not statically known, it comes necessarily from a
219
           delayed jump as immediate jump are conditinal jumps */
220
        gen_op_movl_delayed_pc_PC();
221
        if (ctx->singlestep_enabled)
222
            gen_op_debug();
223
        tcg_gen_exit_tb(0);
224
    } else {
225
        gen_goto_tb(ctx, 0, ctx->delayed_pc);
226
    }
227
}
228

    
229
/* Immediate conditional jump (bt or bf) */
230
static void gen_conditional_jump(DisasContext * ctx,
231
                                 target_ulong ift, target_ulong ifnott)
232
{
233
    int l1;
234

    
235
    l1 = gen_new_label();
236
    gen_op_jT(l1);
237
    gen_goto_tb(ctx, 0, ifnott);
238
    gen_set_label(l1);
239
    gen_goto_tb(ctx, 1, ift);
240
}
241

    
242
/* Delayed conditional jump (bt or bf) */
243
static void gen_delayed_conditional_jump(DisasContext * ctx)
244
{
245
    int l1;
246

    
247
    l1 = gen_new_label();
248
    gen_op_jdelayed(l1);
249
    gen_goto_tb(ctx, 1, ctx->pc + 2);
250
    gen_set_label(l1);
251
    gen_jump(ctx);
252
}
253

    
254
#define B3_0 (ctx->opcode & 0xf)
255
#define B6_4 ((ctx->opcode >> 4) & 0x7)
256
#define B7_4 ((ctx->opcode >> 4) & 0xf)
257
#define B7_0 (ctx->opcode & 0xff)
258
#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
259
#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
260
  (ctx->opcode & 0xfff))
261
#define B11_8 ((ctx->opcode >> 8) & 0xf)
262
#define B15_12 ((ctx->opcode >> 12) & 0xf)
263

    
264
#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
265
                (x) + 16 : (x))
266

    
267
#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
268
                ? (x) + 16 : (x))
269

    
270
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
271
#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
272
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
273
#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
274

    
275
#define CHECK_NOT_DELAY_SLOT \
276
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
277
  {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
278
   return;}
279

    
280
void _decode_opc(DisasContext * ctx)
281
{
282
#if 0
283
    fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
284
#endif
285
    switch (ctx->opcode) {
286
    case 0x0019:                /* div0u */
287
        gen_op_div0u();
288
        return;
289
    case 0x000b:                /* rts */
290
        CHECK_NOT_DELAY_SLOT gen_op_rts();
291
        ctx->flags |= DELAY_SLOT;
292
        ctx->delayed_pc = (uint32_t) - 1;
293
        return;
294
    case 0x0028:                /* clrmac */
295
        gen_op_clrmac();
296
        return;
297
    case 0x0048:                /* clrs */
298
        gen_op_clrs();
299
        return;
300
    case 0x0008:                /* clrt */
301
        gen_op_clrt();
302
        return;
303
    case 0x0038:                /* ldtlb */
304
#if defined(CONFIG_USER_ONLY)
305
        assert(0);                /* XXXXX */
306
#else
307
        gen_op_ldtlb();
308
#endif
309
        return;
310
    case 0x002b:                /* rte */
311
        CHECK_NOT_DELAY_SLOT gen_op_rte();
312
        ctx->flags |= DELAY_SLOT;
313
        ctx->delayed_pc = (uint32_t) - 1;
314
        return;
315
    case 0x0058:                /* sets */
316
        gen_op_sets();
317
        return;
318
    case 0x0018:                /* sett */
319
        gen_op_sett();
320
        return;
321
    case 0xfbfd:                /* frchg */
322
        gen_op_frchg();
323
        ctx->bstate = BS_STOP;
324
        return;
325
    case 0xf3fd:                /* fschg */
326
        gen_op_fschg();
327
        ctx->bstate = BS_STOP;
328
        return;
329
    case 0x0009:                /* nop */
330
        return;
331
    case 0x001b:                /* sleep */
332
        if (ctx->memidx) {
333
                gen_op_sleep();
334
        } else {
335
                gen_op_raise_illegal_instruction();
336
                ctx->bstate = BS_EXCP;
337
        }
338
        return;
339
    }
340

    
341
    switch (ctx->opcode & 0xf000) {
342
    case 0x1000:                /* mov.l Rm,@(disp,Rn) */
343
        gen_movl_rN_T(cpu_T[0], REG(B7_4));
344
        gen_movl_rN_T(cpu_T[1], REG(B11_8));
345
        gen_op_addl_imm_T1(B3_0 * 4);
346
        gen_op_stl_T0_T1(ctx);
347
        return;
348
    case 0x5000:                /* mov.l @(disp,Rm),Rn */
349
        gen_movl_rN_T(cpu_T[0], REG(B7_4));
350
        gen_op_addl_imm_T0(B3_0 * 4);
351
        gen_op_ldl_T0_T0(ctx);
352
        gen_movl_T_rN(cpu_T[0], REG(B11_8));
353
        return;
354
    case 0xe000:                /* mov #imm,Rn */
355
        gen_movl_imm_rN(B7_0s, REG(B11_8));
356
        return;
357
    case 0x9000:                /* mov.w @(disp,PC),Rn */
358
        tcg_gen_movi_i32(cpu_T[0], ctx->pc + 4 + B7_0 * 2);
359
        gen_op_ldw_T0_T0(ctx);
360
        gen_movl_T_rN(cpu_T[0], REG(B11_8));
361
        return;
362
    case 0xd000:                /* mov.l @(disp,PC),Rn */
363
        tcg_gen_movi_i32(cpu_T[0], (ctx->pc + 4 + B7_0 * 4) & ~3);
364
        gen_op_ldl_T0_T0(ctx);
365
        gen_movl_T_rN(cpu_T[0], REG(B11_8));
366
        return;
367
    case 0x7000:                /* add #imm,Rn */
368
        gen_op_add_imm_rN(B7_0s, REG(B11_8));
369
        return;
370
    case 0xa000:                /* bra disp */
371
        CHECK_NOT_DELAY_SLOT
372
            gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
373
        ctx->flags |= DELAY_SLOT;
374
        return;
375
    case 0xb000:                /* bsr disp */
376
        CHECK_NOT_DELAY_SLOT
377
            gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
378
                       ctx->pc + 4 + B11_0s * 2);
379
        ctx->flags |= DELAY_SLOT;
380
        return;
381
    }
382

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

    
809
        switch (ctx->opcode & 0xf00f) {
810
        case 0xf000:                /* fadd Rm,Rn */
811
            ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
812
            break;
813
        case 0xf001:                /* fsub Rm,Rn */
814
            ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
815
            break;
816
        case 0xf002:                /* fmul Rm,Rn */
817
            ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
818
            break;
819
        case 0xf003:                /* fdiv Rm,Rn */
820
            ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
821
            break;
822
        case 0xf004:                /* fcmp/eq Rm,Rn */
823
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
824
            return;
825
        case 0xf005:                /* fcmp/gt Rm,Rn */
826
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
827
            return;
828
        }
829

    
830
        if (ctx->fpscr & FPSCR_PR) {
831
            gen_op_fmov_DT0_drN(DREG(B11_8));
832
        }
833
        else {
834
            gen_op_fmov_FT0_frN(FREG(B11_8));
835
        }
836
        return;
837
    }
838

    
839
    switch (ctx->opcode & 0xff00) {
840
    case 0xc900:                /* and #imm,R0 */
841
        gen_op_and_imm_rN(B7_0, REG(0));
842
        return;
843
    case 0xcd00:                /* and.b #imm,@(R0,GBR) */
844
        gen_movl_rN_T(cpu_T[0], REG(0));
845
        gen_op_addl_GBR_T0();
846
        tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
847
        gen_op_ldub_T0_T0(ctx);
848
        gen_op_and_imm_T0(B7_0);
849
        gen_op_stb_T0_T1(ctx);
850
        return;
851
    case 0x8b00:                /* bf label */
852
        CHECK_NOT_DELAY_SLOT
853
            gen_conditional_jump(ctx, ctx->pc + 2,
854
                                 ctx->pc + 4 + B7_0s * 2);
855
        ctx->bstate = BS_BRANCH;
856
        return;
857
    case 0x8f00:                /* bf/s label */
858
        CHECK_NOT_DELAY_SLOT
859
            gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
860
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
861
        return;
862
    case 0x8900:                /* bt label */
863
        CHECK_NOT_DELAY_SLOT
864
            gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
865
                                 ctx->pc + 2);
866
        ctx->bstate = BS_BRANCH;
867
        return;
868
    case 0x8d00:                /* bt/s label */
869
        CHECK_NOT_DELAY_SLOT
870
            gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
871
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
872
        return;
873
    case 0x8800:                /* cmp/eq #imm,R0 */
874
        gen_movl_rN_T(cpu_T[0], REG(0));
875
        gen_op_cmp_eq_imm_T0(B7_0s);
876
        return;
877
    case 0xc400:                /* mov.b @(disp,GBR),R0 */
878
        gen_op_stc_gbr_T0();
879
        gen_op_addl_imm_T0(B7_0);
880
        gen_op_ldb_T0_T0(ctx);
881
        gen_movl_T_rN(cpu_T[0], REG(0));
882
        return;
883
    case 0xc500:                /* mov.w @(disp,GBR),R0 */
884
        gen_op_stc_gbr_T0();
885
        gen_op_addl_imm_T0(B7_0 * 2);
886
        gen_op_ldw_T0_T0(ctx);
887
        gen_movl_T_rN(cpu_T[0], REG(0));
888
        return;
889
    case 0xc600:                /* mov.l @(disp,GBR),R0 */
890
        gen_op_stc_gbr_T0();
891
        gen_op_addl_imm_T0(B7_0 * 4);
892
        gen_op_ldl_T0_T0(ctx);
893
        gen_movl_T_rN(cpu_T[0], REG(0));
894
        return;
895
    case 0xc000:                /* mov.b R0,@(disp,GBR) */
896
        gen_op_stc_gbr_T0();
897
        gen_op_addl_imm_T0(B7_0);
898
        tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
899
        gen_movl_rN_T(cpu_T[0], REG(0));
900
        gen_op_stb_T0_T1(ctx);
901
        return;
902
    case 0xc100:                /* mov.w R0,@(disp,GBR) */
903
        gen_op_stc_gbr_T0();
904
        gen_op_addl_imm_T0(B7_0 * 2);
905
        tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
906
        gen_movl_rN_T(cpu_T[0], REG(0));
907
        gen_op_stw_T0_T1(ctx);
908
        return;
909
    case 0xc200:                /* mov.l R0,@(disp,GBR) */
910
        gen_op_stc_gbr_T0();
911
        gen_op_addl_imm_T0(B7_0 * 4);
912
        tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
913
        gen_movl_rN_T(cpu_T[0], REG(0));
914
        gen_op_stl_T0_T1(ctx);
915
        return;
916
    case 0x8000:                /* mov.b R0,@(disp,Rn) */
917
        gen_movl_rN_T(cpu_T[0], REG(0));
918
        gen_movl_rN_T(cpu_T[1], REG(B7_4));
919
        gen_op_addl_imm_T1(B3_0);
920
        gen_op_stb_T0_T1(ctx);
921
        return;
922
    case 0x8100:                /* mov.w R0,@(disp,Rn) */
923
        gen_movl_rN_T(cpu_T[0], REG(0));
924
        gen_movl_rN_T(cpu_T[1], REG(B7_4));
925
        gen_op_addl_imm_T1(B3_0 * 2);
926
        gen_op_stw_T0_T1(ctx);
927
        return;
928
    case 0x8400:                /* mov.b @(disp,Rn),R0 */
929
        gen_movl_rN_T(cpu_T[0], REG(B7_4));
930
        gen_op_addl_imm_T0(B3_0);
931
        gen_op_ldb_T0_T0(ctx);
932
        gen_movl_T_rN(cpu_T[0], REG(0));
933
        return;
934
    case 0x8500:                /* mov.w @(disp,Rn),R0 */
935
        gen_movl_rN_T(cpu_T[0], REG(B7_4));
936
        gen_op_addl_imm_T0(B3_0 * 2);
937
        gen_op_ldw_T0_T0(ctx);
938
        gen_movl_T_rN(cpu_T[0], REG(0));
939
        return;
940
    case 0xc700:                /* mova @(disp,PC),R0 */
941
        gen_movl_imm_rN(((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3,
942
                           REG(0));
943
        return;
944
    case 0xcb00:                /* or #imm,R0 */
945
        gen_op_or_imm_rN(B7_0, REG(0));
946
        return;
947
    case 0xcf00:                /* or.b #imm,@(R0,GBR) */
948
        gen_movl_rN_T(cpu_T[0], REG(0));
949
        gen_op_addl_GBR_T0();
950
        tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
951
        gen_op_ldub_T0_T0(ctx);
952
        gen_op_or_imm_T0(B7_0);
953
        gen_op_stb_T0_T1(ctx);
954
        return;
955
    case 0xc300:                /* trapa #imm */
956
        CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
957
        gen_op_trapa(B7_0);
958
        ctx->bstate = BS_BRANCH;
959
        return;
960
    case 0xc800:                /* tst #imm,R0 */
961
        gen_op_tst_imm_rN(B7_0, REG(0));
962
        return;
963
    case 0xcc00:                /* tst.b #imm,@(R0,GBR) */
964
        gen_movl_rN_T(cpu_T[0], REG(0));
965
        gen_op_addl_GBR_T0();
966
        gen_op_ldub_T0_T0(ctx);
967
        gen_op_tst_imm_T0(B7_0);
968
        return;
969
    case 0xca00:                /* xor #imm,R0 */
970
        gen_op_xor_imm_rN(B7_0, REG(0));
971
        return;
972
    case 0xce00:                /* xor.b #imm,@(R0,GBR) */
973
        gen_movl_rN_T(cpu_T[0], REG(0));
974
        gen_op_addl_GBR_T0();
975
        tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
976
        gen_op_ldub_T0_T0(ctx);
977
        gen_op_xor_imm_T0(B7_0);
978
        gen_op_stb_T0_T1(ctx);
979
        return;
980
    }
981

    
982
    switch (ctx->opcode & 0xf08f) {
983
    case 0x408e:                /* ldc Rm,Rn_BANK */
984
        gen_movl_rN_T(cpu_T[0], REG(B11_8));
985
        gen_movl_T_rN(cpu_T[0], ALTREG(B6_4));
986
        return;
987
    case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
988
        gen_movl_rN_T(cpu_T[0], REG(B11_8));
989
        gen_op_ldl_T0_T0(ctx);
990
        gen_movl_T_rN(cpu_T[0], ALTREG(B6_4));
991
        gen_op_inc4_rN(REG(B11_8));
992
        return;
993
    case 0x0082:                /* stc Rm_BANK,Rn */
994
        gen_movl_rN_T(cpu_T[0], ALTREG(B6_4));
995
        gen_movl_T_rN(cpu_T[0], REG(B11_8));
996
        return;
997
    case 0x4083:                /* stc.l Rm_BANK,@-Rn */
998
        gen_op_dec4_rN(REG(B11_8));
999
        gen_movl_rN_T(cpu_T[1], REG(B11_8));
1000
        gen_movl_rN_T(cpu_T[0], ALTREG(B6_4));
1001
        gen_op_inc4_rN(REG(B11_8));
1002
        gen_op_stl_T0_T1(ctx);
1003
        gen_op_dec4_rN(REG(B11_8));
1004
        return;
1005
    }
1006

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

    
1240
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1241
            ctx->opcode, ctx->pc);
1242
    gen_op_raise_illegal_instruction();
1243
    ctx->bstate = BS_EXCP;
1244
}
1245

    
1246
void decode_opc(DisasContext * ctx)
1247
{
1248
    uint32_t old_flags = ctx->flags;
1249

    
1250
    _decode_opc(ctx);
1251

    
1252
    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1253
        if (ctx->flags & DELAY_SLOT_CLEARME) {
1254
            gen_op_store_flags(0);
1255
        } else {
1256
            /* go out of the delay slot */
1257
            uint32_t new_flags = ctx->flags;
1258
            new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1259
            gen_op_store_flags(new_flags);
1260
        }
1261
        ctx->flags = 0;
1262
        ctx->bstate = BS_BRANCH;
1263
        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1264
            gen_delayed_conditional_jump(ctx);
1265
        } else if (old_flags & DELAY_SLOT) {
1266
            gen_jump(ctx);
1267
        }
1268

    
1269
    }
1270

    
1271
    /* go into a delay slot */
1272
    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1273
        gen_op_store_flags(ctx->flags);
1274
}
1275

    
1276
static inline void
1277
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1278
                               int search_pc)
1279
{
1280
    DisasContext ctx;
1281
    target_ulong pc_start;
1282
    static uint16_t *gen_opc_end;
1283
    int i, ii;
1284
    int num_insns;
1285
    int max_insns;
1286

    
1287
    pc_start = tb->pc;
1288
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1289
    ctx.pc = pc_start;
1290
    ctx.flags = (uint32_t)tb->flags;
1291
    ctx.bstate = BS_NONE;
1292
    ctx.sr = env->sr;
1293
    ctx.fpscr = env->fpscr;
1294
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1295
    /* We don't know if the delayed pc came from a dynamic or static branch,
1296
       so assume it is a dynamic branch.  */
1297
    ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1298
    ctx.tb = tb;
1299
    ctx.singlestep_enabled = env->singlestep_enabled;
1300

    
1301
#ifdef DEBUG_DISAS
1302
    if (loglevel & CPU_LOG_TB_CPU) {
1303
        fprintf(logfile,
1304
                "------------------------------------------------\n");
1305
        cpu_dump_state(env, logfile, fprintf, 0);
1306
    }
1307
#endif
1308

    
1309
    ii = -1;
1310
    num_insns = 0;
1311
    max_insns = tb->cflags & CF_COUNT_MASK;
1312
    if (max_insns == 0)
1313
        max_insns = CF_COUNT_MASK;
1314
    gen_icount_start();
1315
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1316
        if (env->nb_breakpoints > 0) {
1317
            for (i = 0; i < env->nb_breakpoints; i++) {
1318
                if (ctx.pc == env->breakpoints[i]) {
1319
                    /* We have hit a breakpoint - make sure PC is up-to-date */
1320
                    gen_op_movl_imm_PC(ctx.pc);
1321
                    gen_op_debug();
1322
                    ctx.bstate = BS_EXCP;
1323
                    break;
1324
                }
1325
            }
1326
        }
1327
        if (search_pc) {
1328
            i = gen_opc_ptr - gen_opc_buf;
1329
            if (ii < i) {
1330
                ii++;
1331
                while (ii < i)
1332
                    gen_opc_instr_start[ii++] = 0;
1333
            }
1334
            gen_opc_pc[ii] = ctx.pc;
1335
            gen_opc_hflags[ii] = ctx.flags;
1336
            gen_opc_instr_start[ii] = 1;
1337
            gen_opc_icount[ii] = num_insns;
1338
        }
1339
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1340
            gen_io_start();
1341
#if 0
1342
        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1343
        fflush(stderr);
1344
#endif
1345
        ctx.opcode = lduw_code(ctx.pc);
1346
        decode_opc(&ctx);
1347
        num_insns++;
1348
        ctx.pc += 2;
1349
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1350
            break;
1351
        if (env->singlestep_enabled)
1352
            break;
1353
        if (num_insns >= max_insns)
1354
            break;
1355
#ifdef SH4_SINGLE_STEP
1356
        break;
1357
#endif
1358
    }
1359
    if (tb->cflags & CF_LAST_IO)
1360
        gen_io_end();
1361
    if (env->singlestep_enabled) {
1362
        gen_op_debug();
1363
    } else {
1364
        switch (ctx.bstate) {
1365
        case BS_STOP:
1366
            /* gen_op_interrupt_restart(); */
1367
            /* fall through */
1368
        case BS_NONE:
1369
            if (ctx.flags) {
1370
                gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1371
            }
1372
            gen_goto_tb(&ctx, 0, ctx.pc);
1373
            break;
1374
        case BS_EXCP:
1375
            /* gen_op_interrupt_restart(); */
1376
            tcg_gen_exit_tb(0);
1377
            break;
1378
        case BS_BRANCH:
1379
        default:
1380
            break;
1381
        }
1382
    }
1383

    
1384
    gen_icount_end(tb, num_insns);
1385
    *gen_opc_ptr = INDEX_op_end;
1386
    if (search_pc) {
1387
        i = gen_opc_ptr - gen_opc_buf;
1388
        ii++;
1389
        while (ii <= i)
1390
            gen_opc_instr_start[ii++] = 0;
1391
    } else {
1392
        tb->size = ctx.pc - pc_start;
1393
        tb->icount = num_insns;
1394
    }
1395

    
1396
#ifdef DEBUG_DISAS
1397
#ifdef SH4_DEBUG_DISAS
1398
    if (loglevel & CPU_LOG_TB_IN_ASM)
1399
        fprintf(logfile, "\n");
1400
#endif
1401
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1402
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1403
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1404
        fprintf(logfile, "\n");
1405
    }
1406
#endif
1407
}
1408

    
1409
void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1410
{
1411
    gen_intermediate_code_internal(env, tb, 0);
1412
}
1413

    
1414
void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1415
{
1416
    gen_intermediate_code_internal(env, tb, 1);
1417
}
1418

    
1419
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1420
                unsigned long searched_pc, int pc_pos, void *puc)
1421
{
1422
    env->pc = gen_opc_pc[pc_pos];
1423
    env->flags = gen_opc_hflags[pc_pos];
1424
}