Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ a4625612

History | View | Annotate | Download (48.1 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
/* global register indexes */
61
static TCGv cpu_env;
62
static TCGv cpu_gregs[24];
63
static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
64
static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
65
static TCGv cpu_pr, cpu_fpscr, cpu_fpul;
66

    
67
/* dyngen register indexes */
68
static TCGv cpu_T[2];
69

    
70
#include "gen-icount.h"
71

    
72
static void sh4_translate_init(void)
73
{
74
    int i;
75
    static int done_init = 0;
76
    static const char * const gregnames[24] = {
77
        "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
78
        "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
79
        "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
80
        "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
81
        "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
82
    };
83

    
84
    if (done_init)
85
        return;
86

    
87
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
88
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
89
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
90

    
91
    for (i = 0; i < 24; i++)
92
        cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
93
                                          offsetof(CPUState, gregs[i]),
94
                                          gregnames[i]);
95

    
96
    cpu_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
97
                                offsetof(CPUState, pc), "PC");
98
    cpu_sr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
99
                                offsetof(CPUState, sr), "SR");
100
    cpu_ssr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
101
                                 offsetof(CPUState, ssr), "SSR");
102
    cpu_spc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
103
                                 offsetof(CPUState, spc), "SPC");
104
    cpu_gbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
105
                                 offsetof(CPUState, gbr), "GBR");
106
    cpu_vbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
107
                                 offsetof(CPUState, vbr), "VBR");
108
    cpu_sgr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
109
                                 offsetof(CPUState, sgr), "SGR");
110
    cpu_dbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
111
                                 offsetof(CPUState, dbr), "DBR");
112
    cpu_mach = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
113
                                  offsetof(CPUState, mach), "MACH");
114
    cpu_macl = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
115
                                  offsetof(CPUState, macl), "MACL");
116
    cpu_pr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
117
                                offsetof(CPUState, pr), "PR");
118
    cpu_fpscr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
119
                                   offsetof(CPUState, fpscr), "FPSCR");
120
    cpu_fpul = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
121
                                  offsetof(CPUState, fpul), "FPUL");
122

    
123
    /* register helpers */
124
#undef DEF_HELPER
125
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
126
#include "helper.h"
127

    
128
    done_init = 1;
129
}
130

    
131
#ifdef CONFIG_USER_ONLY
132

    
133
#define GEN_OP_LD(width, reg) \
134
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
135
    gen_op_ld##width##_T0_##reg##_raw(); \
136
  }
137
#define GEN_OP_ST(width, reg) \
138
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
139
    gen_op_st##width##_##reg##_T1_raw(); \
140
  }
141

    
142
#else
143

    
144
#define GEN_OP_LD(width, reg) \
145
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
146
    if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
147
    else gen_op_ld##width##_T0_##reg##_user();\
148
  }
149
#define GEN_OP_ST(width, reg) \
150
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
151
    if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
152
    else gen_op_st##width##_##reg##_T1_user();\
153
  }
154

    
155
#endif
156

    
157
GEN_OP_LD(ub, T0)
158
GEN_OP_LD(b, T0)
159
GEN_OP_ST(b, T0)
160
GEN_OP_LD(uw, T0)
161
GEN_OP_LD(w, T0)
162
GEN_OP_ST(w, T0)
163
GEN_OP_LD(l, T0)
164
GEN_OP_ST(l, T0)
165
GEN_OP_LD(fl, FT0)
166
GEN_OP_ST(fl, FT0)
167
GEN_OP_LD(fq, DT0)
168
GEN_OP_ST(fq, DT0)
169

    
170
void cpu_dump_state(CPUState * env, FILE * f,
171
                    int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
172
                    int flags)
173
{
174
    int i;
175
    cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
176
                env->pc, env->sr, env->pr, env->fpscr);
177
    cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
178
                env->spc, env->ssr, env->gbr, env->vbr);
179
    cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
180
                env->sgr, env->dbr, env->delayed_pc, env->fpul);
181
    for (i = 0; i < 24; i += 4) {
182
        cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
183
                    i, env->gregs[i], i + 1, env->gregs[i + 1],
184
                    i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
185
    }
186
    if (env->flags & DELAY_SLOT) {
187
        cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
188
                    env->delayed_pc);
189
    } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
190
        cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
191
                    env->delayed_pc);
192
    }
193
}
194

    
195
void cpu_sh4_reset(CPUSH4State * env)
196
{
197
#if defined(CONFIG_USER_ONLY)
198
    env->sr = SR_FD;            /* FD - kernel does lazy fpu context switch */
199
#else
200
    env->sr = 0x700000F0;        /* MD, RB, BL, I3-I0 */
201
#endif
202
    env->vbr = 0;
203
    env->pc = 0xA0000000;
204
#if defined(CONFIG_USER_ONLY)
205
    env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
206
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
207
#else
208
    env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
209
    set_float_rounding_mode(float_round_to_zero, &env->fp_status);
210
#endif
211
    env->mmucr = 0;
212
}
213

    
214
CPUSH4State *cpu_sh4_init(const char *cpu_model)
215
{
216
    CPUSH4State *env;
217

    
218
    env = qemu_mallocz(sizeof(CPUSH4State));
219
    if (!env)
220
        return NULL;
221
    cpu_exec_init(env);
222
    sh4_translate_init();
223
    cpu_sh4_reset(env);
224
    tlb_flush(env, 1);
225
    return env;
226
}
227

    
228
static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
229
{
230
    TranslationBlock *tb;
231
    tb = ctx->tb;
232

    
233
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
234
        !ctx->singlestep_enabled) {
235
        /* Use a direct jump if in same page and singlestep not enabled */
236
        tcg_gen_goto_tb(n);
237
        tcg_gen_movi_i32(cpu_pc, dest);
238
        tcg_gen_exit_tb((long) tb + n);
239
    } else {
240
        tcg_gen_movi_i32(cpu_pc, dest);
241
        if (ctx->singlestep_enabled)
242
            gen_op_debug();
243
        tcg_gen_exit_tb(0);
244
    }
245
}
246

    
247
static void gen_jump(DisasContext * ctx)
248
{
249
    if (ctx->delayed_pc == (uint32_t) - 1) {
250
        /* Target is not statically known, it comes necessarily from a
251
           delayed jump as immediate jump are conditinal jumps */
252
        gen_op_movl_delayed_pc_PC();
253
        if (ctx->singlestep_enabled)
254
            gen_op_debug();
255
        tcg_gen_exit_tb(0);
256
    } else {
257
        gen_goto_tb(ctx, 0, ctx->delayed_pc);
258
    }
259
}
260

    
261
/* Immediate conditional jump (bt or bf) */
262
static void gen_conditional_jump(DisasContext * ctx,
263
                                 target_ulong ift, target_ulong ifnott)
264
{
265
    int l1;
266

    
267
    l1 = gen_new_label();
268
    gen_op_jT(l1);
269
    gen_goto_tb(ctx, 0, ifnott);
270
    gen_set_label(l1);
271
    gen_goto_tb(ctx, 1, ift);
272
}
273

    
274
/* Delayed conditional jump (bt or bf) */
275
static void gen_delayed_conditional_jump(DisasContext * ctx)
276
{
277
    int l1;
278

    
279
    l1 = gen_new_label();
280
    gen_op_jdelayed(l1);
281
    gen_goto_tb(ctx, 1, ctx->pc + 2);
282
    gen_set_label(l1);
283
    gen_jump(ctx);
284
}
285

    
286
static inline void gen_set_t(void)
287
{
288
    tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
289
}
290

    
291
static inline void gen_clr_t(void)
292
{
293
    tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
294
}
295

    
296
static inline void gen_cmp(int cond, TCGv t0, TCGv t1)
297
{
298
    int label1 = gen_new_label();
299
    int label2 = gen_new_label();
300
    tcg_gen_brcond_i32(cond, t1, t0, label1);
301
    gen_clr_t();
302
    tcg_gen_br(label2);
303
    gen_set_label(label1);
304
    gen_set_t();
305
    gen_set_label(label2);
306
}
307

    
308
static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
309
{
310
    int label1 = gen_new_label();
311
    int label2 = gen_new_label();
312
    tcg_gen_brcondi_i32(cond, t0, imm, label1);
313
    gen_clr_t();
314
    tcg_gen_br(label2);
315
    gen_set_label(label1);
316
    gen_set_t();
317
    gen_set_label(label2);
318
}
319

    
320
#define B3_0 (ctx->opcode & 0xf)
321
#define B6_4 ((ctx->opcode >> 4) & 0x7)
322
#define B7_4 ((ctx->opcode >> 4) & 0xf)
323
#define B7_0 (ctx->opcode & 0xff)
324
#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
325
#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
326
  (ctx->opcode & 0xfff))
327
#define B11_8 ((ctx->opcode >> 8) & 0xf)
328
#define B15_12 ((ctx->opcode >> 12) & 0xf)
329

    
330
#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
331
                (x) + 16 : (x))
332

    
333
#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
334
                ? (x) + 16 : (x))
335

    
336
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
337
#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
338
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
339
#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
340

    
341
#define CHECK_NOT_DELAY_SLOT \
342
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
343
  {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
344
   return;}
345

    
346
void _decode_opc(DisasContext * ctx)
347
{
348
#if 0
349
    fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
350
#endif
351
    switch (ctx->opcode) {
352
    case 0x0019:                /* div0u */
353
        tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
354
        return;
355
    case 0x000b:                /* rts */
356
        CHECK_NOT_DELAY_SLOT gen_op_rts();
357
        ctx->flags |= DELAY_SLOT;
358
        ctx->delayed_pc = (uint32_t) - 1;
359
        return;
360
    case 0x0028:                /* clrmac */
361
        tcg_gen_movi_i32(cpu_mach, 0);
362
        tcg_gen_movi_i32(cpu_macl, 0);
363
        return;
364
    case 0x0048:                /* clrs */
365
        tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S);
366
        return;
367
    case 0x0008:                /* clrt */
368
        gen_clr_t();
369
        return;
370
    case 0x0038:                /* ldtlb */
371
#if defined(CONFIG_USER_ONLY)
372
        assert(0);                /* XXXXX */
373
#else
374
        gen_op_ldtlb();
375
#endif
376
        return;
377
    case 0x002b:                /* rte */
378
        CHECK_NOT_DELAY_SLOT gen_op_rte();
379
        ctx->flags |= DELAY_SLOT;
380
        ctx->delayed_pc = (uint32_t) - 1;
381
        return;
382
    case 0x0058:                /* sets */
383
        tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S);
384
        return;
385
    case 0x0018:                /* sett */
386
        gen_set_t();
387
        return;
388
    case 0xfbfd:                /* frchg */
389
        gen_op_frchg();
390
        ctx->bstate = BS_STOP;
391
        return;
392
    case 0xf3fd:                /* fschg */
393
        gen_op_fschg();
394
        ctx->bstate = BS_STOP;
395
        return;
396
    case 0x0009:                /* nop */
397
        return;
398
    case 0x001b:                /* sleep */
399
        if (ctx->memidx) {
400
                gen_op_sleep();
401
        } else {
402
                gen_op_raise_illegal_instruction();
403
                ctx->bstate = BS_EXCP;
404
        }
405
        return;
406
    }
407

    
408
    switch (ctx->opcode & 0xf000) {
409
    case 0x1000:                /* mov.l Rm,@(disp,Rn) */
410
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
411
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
412
        tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 4);
413
        gen_op_stl_T0_T1(ctx);
414
        return;
415
    case 0x5000:                /* mov.l @(disp,Rm),Rn */
416
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
417
        tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 4);
418
        gen_op_ldl_T0_T0(ctx);
419
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
420
        return;
421
    case 0xe000:                /* mov #imm,Rn */
422
        tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], B7_0s);
423
        return;
424
    case 0x9000:                /* mov.w @(disp,PC),Rn */
425
        tcg_gen_movi_i32(cpu_T[0], ctx->pc + 4 + B7_0 * 2);
426
        gen_op_ldw_T0_T0(ctx);
427
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
428
        return;
429
    case 0xd000:                /* mov.l @(disp,PC),Rn */
430
        tcg_gen_movi_i32(cpu_T[0], (ctx->pc + 4 + B7_0 * 4) & ~3);
431
        gen_op_ldl_T0_T0(ctx);
432
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
433
        return;
434
    case 0x7000:                /* add #imm,Rn */
435
        tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], B7_0s);
436
        return;
437
    case 0xa000:                /* bra disp */
438
        CHECK_NOT_DELAY_SLOT
439
            gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
440
        ctx->flags |= DELAY_SLOT;
441
        return;
442
    case 0xb000:                /* bsr disp */
443
        CHECK_NOT_DELAY_SLOT
444
            gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
445
                       ctx->pc + 4 + B11_0s * 2);
446
        ctx->flags |= DELAY_SLOT;
447
        return;
448
    }
449

    
450
    switch (ctx->opcode & 0xf00f) {
451
    case 0x6003:                /* mov Rm,Rn */
452
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
453
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
454
        return;
455
    case 0x2000:                /* mov.b Rm,@Rn */
456
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
457
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
458
        gen_op_stb_T0_T1(ctx);
459
        return;
460
    case 0x2001:                /* mov.w Rm,@Rn */
461
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
462
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
463
        gen_op_stw_T0_T1(ctx);
464
        return;
465
    case 0x2002:                /* mov.l Rm,@Rn */
466
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
467
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
468
        gen_op_stl_T0_T1(ctx);
469
        return;
470
    case 0x6000:                /* mov.b @Rm,Rn */
471
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
472
        gen_op_ldb_T0_T0(ctx);
473
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
474
        return;
475
    case 0x6001:                /* mov.w @Rm,Rn */
476
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
477
        gen_op_ldw_T0_T0(ctx);
478
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
479
        return;
480
    case 0x6002:                /* mov.l @Rm,Rn */
481
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
482
        gen_op_ldl_T0_T0(ctx);
483
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
484
        return;
485
    case 0x2004:                /* mov.b Rm,@-Rn */
486
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
487
        tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
488
                         cpu_gregs[REG(B11_8)], 1);        /* modify register status */
489
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
490
        tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
491
                         cpu_gregs[REG(B11_8)],        1);        /* recover register status */
492
        gen_op_stb_T0_T1(ctx);                                /* might cause re-execution */
493
        tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
494
                         cpu_gregs[REG(B11_8)], 1);        /* modify register status */
495
        return;
496
    case 0x2005:                /* mov.w Rm,@-Rn */
497
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
498
        tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
499
                         cpu_gregs[REG(B11_8)], 2);
500
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
501
        tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
502
                         cpu_gregs[REG(B11_8)], 2);
503
        gen_op_stw_T0_T1(ctx);
504
        tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
505
                         cpu_gregs[REG(B11_8)], 2);
506
        return;
507
    case 0x2006:                /* mov.l Rm,@-Rn */
508
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
509
        tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
510
                         cpu_gregs[REG(B11_8)], 4);
511
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
512
        tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
513
                         cpu_gregs[REG(B11_8)], 4);
514
        gen_op_stl_T0_T1(ctx);
515
        tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
516
                         cpu_gregs[REG(B11_8)], 4);
517
        return;
518
    case 0x6004:                /* mov.b @Rm+,Rn */
519
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
520
        gen_op_ldb_T0_T0(ctx);
521
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
522
        if ( B11_8 != B7_4 )
523
                tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
524
                                 cpu_gregs[REG(B7_4)], 1);
525
        return;
526
    case 0x6005:                /* mov.w @Rm+,Rn */
527
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
528
        gen_op_ldw_T0_T0(ctx);
529
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
530
        if ( B11_8 != B7_4 )
531
                tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
532
                                 cpu_gregs[REG(B7_4)], 2);
533
        return;
534
    case 0x6006:                /* mov.l @Rm+,Rn */
535
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
536
        gen_op_ldl_T0_T0(ctx);
537
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
538
        if ( B11_8 != B7_4 )
539
                tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
540
                                 cpu_gregs[REG(B7_4)], 4);
541
        return;
542
    case 0x0004:                /* mov.b Rm,@(R0,Rn) */
543
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
544
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
545
        tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
546
        gen_op_stb_T0_T1(ctx);
547
        return;
548
    case 0x0005:                /* mov.w Rm,@(R0,Rn) */
549
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
550
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
551
        tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
552
        gen_op_stw_T0_T1(ctx);
553
        return;
554
    case 0x0006:                /* mov.l Rm,@(R0,Rn) */
555
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
556
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
557
        tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
558
        gen_op_stl_T0_T1(ctx);
559
        return;
560
    case 0x000c:                /* mov.b @(R0,Rm),Rn */
561
        tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
562
        gen_op_ldb_T0_T0(ctx);
563
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
564
        return;
565
    case 0x000d:                /* mov.w @(R0,Rm),Rn */
566
        tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
567
        gen_op_ldw_T0_T0(ctx);
568
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
569
        return;
570
    case 0x000e:                /* mov.l @(R0,Rm),Rn */
571
        tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
572
        gen_op_ldl_T0_T0(ctx);
573
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
574
        return;
575
    case 0x6008:                /* swap.b Rm,Rn */
576
        tcg_gen_andi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], 0xffff0000);
577
        tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xff);
578
        tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 8);
579
        tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
580
        tcg_gen_shri_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 8);
581
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
582
        tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
583
        return;
584
    case 0x6009:                /* swap.w Rm,Rn */
585
        tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
586
        tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
587
        tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B7_4)], 16);
588
        tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
589
        tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
590
        return;
591
    case 0x200d:                /* xtrct Rm,Rn */
592
        tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
593
        tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
594
        tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B11_8)], 16);
595
        tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
596
        tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
597
        return;
598
    case 0x300c:                /* add Rm,Rn */
599
        tcg_gen_add_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
600
        return;
601
    case 0x300e:                /* addc Rm,Rn */
602
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
603
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
604
        gen_op_addc_T0_T1();
605
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
606
        return;
607
    case 0x300f:                /* addv Rm,Rn */
608
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
609
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
610
        gen_op_addv_T0_T1();
611
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
612
        return;
613
    case 0x2009:                /* and Rm,Rn */
614
        tcg_gen_and_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
615
        return;
616
    case 0x3000:                /* cmp/eq Rm,Rn */
617
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
618
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
619
        gen_cmp(TCG_COND_EQ, cpu_T[0], cpu_T[1]);
620
        return;
621
    case 0x3003:                /* cmp/ge Rm,Rn */
622
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
623
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
624
        gen_cmp(TCG_COND_GE, cpu_T[0], cpu_T[1]);
625
        return;
626
    case 0x3007:                /* cmp/gt Rm,Rn */
627
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
628
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
629
        gen_cmp(TCG_COND_GT, cpu_T[0], cpu_T[1]);
630
        return;
631
    case 0x3006:                /* cmp/hi Rm,Rn */
632
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
633
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
634
        gen_cmp(TCG_COND_GTU, cpu_T[0], cpu_T[1]);
635
        return;
636
    case 0x3002:                /* cmp/hs Rm,Rn */
637
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
638
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
639
        gen_cmp(TCG_COND_GEU, cpu_T[0], cpu_T[1]);
640
        return;
641
    case 0x200c:                /* cmp/str Rm,Rn */
642
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
643
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
644
        gen_op_cmp_str_T0_T1();
645
        return;
646
    case 0x2007:                /* div0s Rm,Rn */
647
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
648
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
649
        gen_op_div0s_T0_T1();
650
        return;
651
    case 0x3004:                /* div1 Rm,Rn */
652
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
653
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
654
        gen_op_div1_T0_T1();
655
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
656
        return;
657
    case 0x300d:                /* dmuls.l Rm,Rn */
658
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
659
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
660
        gen_op_dmulsl_T0_T1();
661
        return;
662
    case 0x3005:                /* dmulu.l Rm,Rn */
663
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
664
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
665
        gen_op_dmulul_T0_T1();
666
        return;
667
    case 0x600e:                /* exts.b Rm,Rn */
668
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
669
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
670
        tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
671
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
672
        return;
673
    case 0x600f:                /* exts.w Rm,Rn */
674
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
675
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
676
        tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
677
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
678
        return;
679
    case 0x600c:                /* extu.b Rm,Rn */
680
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
681
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
682
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
683
        return;
684
    case 0x600d:                /* extu.w Rm,Rn */
685
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
686
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
687
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
688
        return;
689
    case 0x000f:                /* mac.l @Rm+,@Rn+ */
690
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
691
        gen_op_ldl_T0_T0(ctx);
692
        tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
693
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
694
        gen_op_ldl_T0_T0(ctx);
695
        gen_op_macl_T0_T1();
696
        tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 4);
697
        tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
698
        return;
699
    case 0x400f:                /* mac.w @Rm+,@Rn+ */
700
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
701
        gen_op_ldl_T0_T0(ctx);
702
        tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
703
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
704
        gen_op_ldl_T0_T0(ctx);
705
        gen_op_macw_T0_T1();
706
        tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
707
        tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 2);
708
        return;
709
    case 0x0007:                /* mul.l Rm,Rn */
710
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
711
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
712
        gen_op_mull_T0_T1();
713
        return;
714
    case 0x200f:                /* muls.w Rm,Rn */
715
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
716
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
717
        tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
718
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
719
        tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
720
        tcg_gen_ext16s_i32(cpu_T[1], cpu_T[1]);
721
        gen_op_mulsw_T0_T1();
722
        return;
723
    case 0x200e:                /* mulu.w Rm,Rn */
724
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
725
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
726
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
727
        tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
728
        gen_op_muluw_T0_T1();
729
        return;
730
    case 0x600b:                /* neg Rm,Rn */
731
        tcg_gen_neg_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
732
        return;
733
    case 0x600a:                /* negc Rm,Rn */
734
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
735
        gen_op_negc_T0();
736
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
737
        return;
738
    case 0x6007:                /* not Rm,Rn */
739
        tcg_gen_not_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
740
        return;
741
    case 0x200b:                /* or Rm,Rn */
742
        tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
743
        return;
744
    case 0x400c:                /* shad Rm,Rn */
745
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
746
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
747
        gen_op_shad_T0_T1();
748
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
749
        return;
750
    case 0x400d:                /* shld Rm,Rn */
751
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
752
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
753
        gen_op_shld_T0_T1();
754
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
755
        return;
756
    case 0x3008:                /* sub Rm,Rn */
757
        tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
758
        return;
759
    case 0x300a:                /* subc Rm,Rn */
760
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
761
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
762
        gen_op_subc_T0_T1();
763
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
764
        return;
765
    case 0x300b:                /* subv Rm,Rn */
766
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
767
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
768
        gen_op_subv_T0_T1();
769
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
770
        return;
771
    case 0x2008:                /* tst Rm,Rn */
772
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
773
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
774
        tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
775
        gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
776
        return;
777
    case 0x200a:                /* xor Rm,Rn */
778
        tcg_gen_xor_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
779
        return;
780
    case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
781
        if (ctx->fpscr & FPSCR_SZ) {
782
            gen_op_fmov_drN_DT0(XREG(B7_4));
783
            gen_op_fmov_DT0_drN(XREG(B11_8));
784
        } else {
785
            gen_op_fmov_frN_FT0(FREG(B7_4));
786
            gen_op_fmov_FT0_frN(FREG(B11_8));
787
        }
788
        return;
789
    case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
790
        if (ctx->fpscr & FPSCR_SZ) {
791
            gen_op_fmov_drN_DT0(XREG(B7_4));
792
            tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
793
            gen_op_stfq_DT0_T1(ctx);
794
        } else {
795
            gen_op_fmov_frN_FT0(FREG(B7_4));
796
            tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
797
            gen_op_stfl_FT0_T1(ctx);
798
        }
799
        return;
800
    case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
801
        if (ctx->fpscr & FPSCR_SZ) {
802
            tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
803
            gen_op_ldfq_T0_DT0(ctx);
804
            gen_op_fmov_DT0_drN(XREG(B11_8));
805
        } else {
806
            tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
807
            gen_op_ldfl_T0_FT0(ctx);
808
            gen_op_fmov_FT0_frN(FREG(B11_8));
809
        }
810
        return;
811
    case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
812
        if (ctx->fpscr & FPSCR_SZ) {
813
            tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
814
            gen_op_ldfq_T0_DT0(ctx);
815
            gen_op_fmov_DT0_drN(XREG(B11_8));
816
            tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
817
                             cpu_gregs[REG(B7_4)], 8);
818
        } else {
819
            tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
820
            gen_op_ldfl_T0_FT0(ctx);
821
            gen_op_fmov_FT0_frN(FREG(B11_8));
822
            tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
823
                             cpu_gregs[REG(B7_4)], 4);
824
        }
825
        return;
826
    case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
827
        if (ctx->fpscr & FPSCR_SZ) {
828
            tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
829
            gen_op_fmov_drN_DT0(XREG(B7_4));
830
            tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
831
            tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
832
            gen_op_stfq_DT0_T1(ctx);
833
            tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
834
        } else {
835
            tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
836
            gen_op_fmov_frN_FT0(FREG(B7_4));
837
            tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
838
            tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
839
            gen_op_stfl_FT0_T1(ctx);
840
            tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
841
        }
842
        return;
843
    case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
844
        tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
845
        if (ctx->fpscr & FPSCR_SZ) {
846
            gen_op_ldfq_T0_DT0(ctx);
847
            gen_op_fmov_DT0_drN(XREG(B11_8));
848
        } else {
849
            gen_op_ldfl_T0_FT0(ctx);
850
            gen_op_fmov_FT0_frN(FREG(B11_8));
851
        }
852
        return;
853
    case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
854
        if (ctx->fpscr & FPSCR_SZ) {
855
            gen_op_fmov_drN_DT0(XREG(B7_4));
856
            tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
857
            tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
858
            gen_op_stfq_DT0_T1(ctx);
859
        } else {
860
            gen_op_fmov_frN_FT0(FREG(B7_4));
861
            tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
862
            tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
863
            gen_op_stfl_FT0_T1(ctx);
864
        }
865
        return;
866
    case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
867
    case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
868
    case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
869
    case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
870
    case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
871
    case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
872
        if (ctx->fpscr & FPSCR_PR) {
873
            if (ctx->opcode & 0x0110)
874
                break; /* illegal instruction */
875
            gen_op_fmov_drN_DT1(DREG(B7_4));
876
            gen_op_fmov_drN_DT0(DREG(B11_8));
877
        }
878
        else {
879
            gen_op_fmov_frN_FT1(FREG(B7_4));
880
            gen_op_fmov_frN_FT0(FREG(B11_8));
881
        }
882

    
883
        switch (ctx->opcode & 0xf00f) {
884
        case 0xf000:                /* fadd Rm,Rn */
885
            ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
886
            break;
887
        case 0xf001:                /* fsub Rm,Rn */
888
            ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
889
            break;
890
        case 0xf002:                /* fmul Rm,Rn */
891
            ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
892
            break;
893
        case 0xf003:                /* fdiv Rm,Rn */
894
            ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
895
            break;
896
        case 0xf004:                /* fcmp/eq Rm,Rn */
897
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
898
            return;
899
        case 0xf005:                /* fcmp/gt Rm,Rn */
900
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
901
            return;
902
        }
903

    
904
        if (ctx->fpscr & FPSCR_PR) {
905
            gen_op_fmov_DT0_drN(DREG(B11_8));
906
        }
907
        else {
908
            gen_op_fmov_FT0_frN(FREG(B11_8));
909
        }
910
        return;
911
    }
912

    
913
    switch (ctx->opcode & 0xff00) {
914
    case 0xc900:                /* and #imm,R0 */
915
        tcg_gen_andi_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
916
        return;
917
    case 0xcd00:                /* and.b #imm,@(R0,GBR) */
918
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
919
        tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
920
        tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
921
        gen_op_ldub_T0_T0(ctx);
922
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0);
923
        gen_op_stb_T0_T1(ctx);
924
        return;
925
    case 0x8b00:                /* bf label */
926
        CHECK_NOT_DELAY_SLOT
927
            gen_conditional_jump(ctx, ctx->pc + 2,
928
                                 ctx->pc + 4 + B7_0s * 2);
929
        ctx->bstate = BS_BRANCH;
930
        return;
931
    case 0x8f00:                /* bf/s label */
932
        CHECK_NOT_DELAY_SLOT
933
            gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
934
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
935
        return;
936
    case 0x8900:                /* bt label */
937
        CHECK_NOT_DELAY_SLOT
938
            gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
939
                                 ctx->pc + 2);
940
        ctx->bstate = BS_BRANCH;
941
        return;
942
    case 0x8d00:                /* bt/s label */
943
        CHECK_NOT_DELAY_SLOT
944
            gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
945
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
946
        return;
947
    case 0x8800:                /* cmp/eq #imm,R0 */
948
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
949
        gen_cmp_imm(TCG_COND_EQ, cpu_T[0], B7_0s);
950
        return;
951
    case 0xc400:                /* mov.b @(disp,GBR),R0 */
952
        gen_op_stc_gbr_T0();
953
        tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0);
954
        gen_op_ldb_T0_T0(ctx);
955
        tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
956
        return;
957
    case 0xc500:                /* mov.w @(disp,GBR),R0 */
958
        gen_op_stc_gbr_T0();
959
        tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 2);
960
        gen_op_ldw_T0_T0(ctx);
961
        tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
962
        return;
963
    case 0xc600:                /* mov.l @(disp,GBR),R0 */
964
        gen_op_stc_gbr_T0();
965
        tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 4);
966
        gen_op_ldl_T0_T0(ctx);
967
        tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
968
        return;
969
    case 0xc000:                /* mov.b R0,@(disp,GBR) */
970
        gen_op_stc_gbr_T0();
971
        tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0);
972
        tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
973
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
974
        gen_op_stb_T0_T1(ctx);
975
        return;
976
    case 0xc100:                /* mov.w R0,@(disp,GBR) */
977
        gen_op_stc_gbr_T0();
978
        tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 2);
979
        tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
980
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
981
        gen_op_stw_T0_T1(ctx);
982
        return;
983
    case 0xc200:                /* mov.l R0,@(disp,GBR) */
984
        gen_op_stc_gbr_T0();
985
        tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 4);
986
        tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
987
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
988
        gen_op_stl_T0_T1(ctx);
989
        return;
990
    case 0x8000:                /* mov.b R0,@(disp,Rn) */
991
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
992
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
993
        tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0);
994
        gen_op_stb_T0_T1(ctx);
995
        return;
996
    case 0x8100:                /* mov.w R0,@(disp,Rn) */
997
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
998
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
999
        tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 2);
1000
        gen_op_stw_T0_T1(ctx);
1001
        return;
1002
    case 0x8400:                /* mov.b @(disp,Rn),R0 */
1003
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
1004
        tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0);
1005
        gen_op_ldb_T0_T0(ctx);
1006
        tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
1007
        return;
1008
    case 0x8500:                /* mov.w @(disp,Rn),R0 */
1009
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
1010
        tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 2);
1011
        gen_op_ldw_T0_T0(ctx);
1012
        tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
1013
        return;
1014
    case 0xc700:                /* mova @(disp,PC),R0 */
1015
        tcg_gen_movi_i32(cpu_gregs[REG(0)],
1016
                         ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
1017
        return;
1018
    case 0xcb00:                /* or #imm,R0 */
1019
        tcg_gen_ori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
1020
        return;
1021
    case 0xcf00:                /* or.b #imm,@(R0,GBR) */
1022
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1023
        tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
1024
        tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
1025
        gen_op_ldub_T0_T0(ctx);
1026
        tcg_gen_ori_i32(cpu_T[0], cpu_T[0], B7_0);
1027
        gen_op_stb_T0_T1(ctx);
1028
        return;
1029
    case 0xc300:                /* trapa #imm */
1030
        CHECK_NOT_DELAY_SLOT tcg_gen_movi_i32(cpu_pc, ctx->pc);
1031
        gen_op_trapa(B7_0);
1032
        ctx->bstate = BS_BRANCH;
1033
        return;
1034
    case 0xc800:                /* tst #imm,R0 */
1035
        tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(0)], B7_0);
1036
        gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
1037
        return;
1038
    case 0xcc00:                /* tst.b #imm,@(R0,GBR) */
1039
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1040
        tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
1041
        gen_op_ldub_T0_T0(ctx);
1042
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0);
1043
        gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
1044
        return;
1045
    case 0xca00:                /* xor #imm,R0 */
1046
        tcg_gen_xori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
1047
        return;
1048
    case 0xce00:                /* xor.b #imm,@(R0,GBR) */
1049
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1050
        tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
1051
        tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1052
        gen_op_ldub_T0_T0(ctx);
1053
        tcg_gen_xori_i32(cpu_T[0], cpu_T[0], B7_0);
1054
        gen_op_stb_T0_T1(ctx);
1055
        return;
1056
    }
1057

    
1058
    switch (ctx->opcode & 0xf08f) {
1059
    case 0x408e:                /* ldc Rm,Rn_BANK */
1060
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1061
        tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
1062
        return;
1063
    case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
1064
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1065
        gen_op_ldl_T0_T0(ctx);
1066
        tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
1067
        tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1068
        return;
1069
    case 0x0082:                /* stc Rm_BANK,Rn */
1070
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
1071
        tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
1072
        return;
1073
    case 0x4083:                /* stc.l Rm_BANK,@-Rn */
1074
        tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1075
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1076
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
1077
        tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1078
        gen_op_stl_T0_T1(ctx);
1079
        tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1080
        return;
1081
    }
1082

    
1083
    switch (ctx->opcode & 0xf0ff) {
1084
    case 0x0023:                /* braf Rn */
1085
        CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1086
        gen_op_braf_T0(ctx->pc + 4);
1087
        ctx->flags |= DELAY_SLOT;
1088
        ctx->delayed_pc = (uint32_t) - 1;
1089
        return;
1090
    case 0x0003:                /* bsrf Rn */
1091
        CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1092
        gen_op_bsrf_T0(ctx->pc + 4);
1093
        ctx->flags |= DELAY_SLOT;
1094
        ctx->delayed_pc = (uint32_t) - 1;
1095
        return;
1096
    case 0x4015:                /* cmp/pl Rn */
1097
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1098
        gen_cmp_imm(TCG_COND_GT, cpu_T[0], 0);
1099
        return;
1100
    case 0x4011:                /* cmp/pz Rn */
1101
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1102
        gen_cmp_imm(TCG_COND_GE, cpu_T[0], 0);
1103
        return;
1104
    case 0x4010:                /* dt Rn */
1105
        tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
1106
        gen_cmp_imm(TCG_COND_EQ, cpu_gregs[REG(B11_8)], 0);
1107
        return;
1108
    case 0x402b:                /* jmp @Rn */
1109
        CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1110
        gen_op_jmp_T0();
1111
        ctx->flags |= DELAY_SLOT;
1112
        ctx->delayed_pc = (uint32_t) - 1;
1113
        return;
1114
    case 0x400b:                /* jsr @Rn */
1115
        CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1116
        gen_op_jsr_T0(ctx->pc + 4);
1117
        ctx->flags |= DELAY_SLOT;
1118
        ctx->delayed_pc = (uint32_t) - 1;
1119
        return;
1120
#define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald)        \
1121
  case ldnum:                                                        \
1122
    tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]);                \
1123
    gen_op_##ldop##_T0_##reg ();                                \
1124
    extrald                                                        \
1125
    return;                                                        \
1126
  case ldpnum:                                                        \
1127
    tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]);                \
1128
    gen_op_ldl_T0_T0 (ctx);                                        \
1129
    tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],                         \
1130
                     cpu_gregs[REG(B11_8)], 4);                        \
1131
    gen_op_##ldop##_T0_##reg ();                                \
1132
    extrald                                                        \
1133
    return;                                                        \
1134
  case stnum:                                                        \
1135
    gen_op_##stop##_##reg##_T0 ();                                \
1136
    tcg_gen_mov_i32 (cpu_gregs[REG(B11_8)], cpu_T[0]);                \
1137
    return;                                                        \
1138
  case stpnum:                                                        \
1139
    gen_op_##stop##_##reg##_T0 ();                                \
1140
    tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],                         \
1141
                     cpu_gregs[REG(B11_8)], 4);                        \
1142
    tcg_gen_mov_i32 (cpu_T[1], cpu_gregs[REG(B11_8)]);                \
1143
    tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],                         \
1144
                     cpu_gregs[REG(B11_8)], 4);                        \
1145
    gen_op_stl_T0_T1 (ctx);                                        \
1146
    tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],                         \
1147
                     cpu_gregs[REG(B11_8)], 4);                        \
1148
    return;
1149
        LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate =
1150
             BS_STOP;)
1151
        LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1152
        LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1153
        LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1154
        LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1155
        LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1156
        LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1157
        LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1158
        LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1159
        LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
1160
        LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->bstate =
1161
             BS_STOP;)
1162
    case 0x00c3:                /* movca.l R0,@Rm */
1163
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1164
        tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1165
        gen_op_stl_T0_T1(ctx);
1166
        return;
1167
    case 0x0029:                /* movt Rn */
1168
        tcg_gen_andi_i32(cpu_gregs[REG(B11_8)], cpu_sr, SR_T);
1169
        return;
1170
    case 0x0093:                /* ocbi @Rn */
1171
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1172
        gen_op_ldl_T0_T0(ctx);
1173
        return;
1174
    case 0x00a3:                /* ocbp @Rn */
1175
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1176
        gen_op_ldl_T0_T0(ctx);
1177
        return;
1178
    case 0x00b3:                /* ocbwb @Rn */
1179
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1180
        gen_op_ldl_T0_T0(ctx);
1181
        return;
1182
    case 0x0083:                /* pref @Rn */
1183
        return;
1184
    case 0x4024:                /* rotcl Rn */
1185
        gen_op_rotcl_Rn(REG(B11_8));
1186
        return;
1187
    case 0x4025:                /* rotcr Rn */
1188
        gen_op_rotcr_Rn(REG(B11_8));
1189
        return;
1190
    case 0x4004:                /* rotl Rn */
1191
        gen_op_rotl_Rn(REG(B11_8));
1192
        return;
1193
    case 0x4005:                /* rotr Rn */
1194
        gen_op_rotr_Rn(REG(B11_8));
1195
        return;
1196
    case 0x4000:                /* shll Rn */
1197
    case 0x4020:                /* shal Rn */
1198
        gen_op_shal_Rn(REG(B11_8));
1199
        return;
1200
    case 0x4021:                /* shar Rn */
1201
        gen_op_shar_Rn(REG(B11_8));
1202
        return;
1203
    case 0x4001:                /* shlr Rn */
1204
        gen_op_shlr_Rn(REG(B11_8));
1205
        return;
1206
    case 0x4008:                /* shll2 Rn */
1207
        tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
1208
        return;
1209
    case 0x4018:                /* shll8 Rn */
1210
        tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
1211
        return;
1212
    case 0x4028:                /* shll16 Rn */
1213
        tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
1214
        return;
1215
    case 0x4009:                /* shlr2 Rn */
1216
        tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
1217
        return;
1218
    case 0x4019:                /* shlr8 Rn */
1219
        tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
1220
        return;
1221
    case 0x4029:                /* shlr16 Rn */
1222
        tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
1223
        return;
1224
    case 0x401b:                /* tas.b @Rn */
1225
        tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1226
        tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1227
        gen_op_ldub_T0_T0(ctx);
1228
        gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
1229
        tcg_gen_ori_i32(cpu_T[0], cpu_T[0], 0x80);
1230
        gen_op_stb_T0_T1(ctx);
1231
        return;
1232
    case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1233
        gen_op_movl_fpul_FT0();
1234
        gen_op_fmov_FT0_frN(FREG(B11_8));
1235
        return;
1236
    case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1237
        gen_op_fmov_frN_FT0(FREG(B11_8));
1238
        gen_op_movl_FT0_fpul();
1239
        return;
1240
    case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1241
        if (ctx->fpscr & FPSCR_PR) {
1242
            if (ctx->opcode & 0x0100)
1243
                break; /* illegal instruction */
1244
            gen_op_float_DT();
1245
            gen_op_fmov_DT0_drN(DREG(B11_8));
1246
        }
1247
        else {
1248
            gen_op_float_FT();
1249
            gen_op_fmov_FT0_frN(FREG(B11_8));
1250
        }
1251
        return;
1252
    case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1253
        if (ctx->fpscr & FPSCR_PR) {
1254
            if (ctx->opcode & 0x0100)
1255
                break; /* illegal instruction */
1256
            gen_op_fmov_drN_DT0(DREG(B11_8));
1257
            gen_op_ftrc_DT();
1258
        }
1259
        else {
1260
            gen_op_fmov_frN_FT0(FREG(B11_8));
1261
            gen_op_ftrc_FT();
1262
        }
1263
        return;
1264
    case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1265
        gen_op_fneg_frN(FREG(B11_8));
1266
        return;
1267
    case 0xf05d: /* fabs FRn/DRn */
1268
        if (ctx->fpscr & FPSCR_PR) {
1269
            if (ctx->opcode & 0x0100)
1270
                break; /* illegal instruction */
1271
            gen_op_fmov_drN_DT0(DREG(B11_8));
1272
            gen_op_fabs_DT();
1273
            gen_op_fmov_DT0_drN(DREG(B11_8));
1274
        } else {
1275
            gen_op_fmov_frN_FT0(FREG(B11_8));
1276
            gen_op_fabs_FT();
1277
            gen_op_fmov_FT0_frN(FREG(B11_8));
1278
        }
1279
        return;
1280
    case 0xf06d: /* fsqrt FRn */
1281
        if (ctx->fpscr & FPSCR_PR) {
1282
            if (ctx->opcode & 0x0100)
1283
                break; /* illegal instruction */
1284
            gen_op_fmov_drN_DT0(FREG(B11_8));
1285
            gen_op_fsqrt_DT();
1286
            gen_op_fmov_DT0_drN(FREG(B11_8));
1287
        } else {
1288
            gen_op_fmov_frN_FT0(FREG(B11_8));
1289
            gen_op_fsqrt_FT();
1290
            gen_op_fmov_FT0_frN(FREG(B11_8));
1291
        }
1292
        return;
1293
    case 0xf07d: /* fsrra FRn */
1294
        break;
1295
    case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1296
        if (!(ctx->fpscr & FPSCR_PR)) {
1297
            tcg_gen_movi_i32(cpu_T[0], 0);
1298
            gen_op_fmov_T0_frN(FREG(B11_8));
1299
            return;
1300
        }
1301
        break;
1302
    case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1303
        if (!(ctx->fpscr & FPSCR_PR)) {
1304
            tcg_gen_movi_i32(cpu_T[0], 0x3f800000);
1305
            gen_op_fmov_T0_frN(FREG(B11_8));
1306
            return;
1307
        }
1308
        break;
1309
    case 0xf0ad: /* fcnvsd FPUL,DRn */
1310
        gen_op_movl_fpul_FT0();
1311
        gen_op_fcnvsd_FT_DT();
1312
        gen_op_fmov_DT0_drN(DREG(B11_8));
1313
        return;
1314
    case 0xf0bd: /* fcnvds DRn,FPUL */
1315
        gen_op_fmov_drN_DT0(DREG(B11_8));
1316
        gen_op_fcnvds_DT_FT();
1317
        gen_op_movl_FT0_fpul();
1318
        return;
1319
    }
1320

    
1321
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1322
            ctx->opcode, ctx->pc);
1323
    gen_op_raise_illegal_instruction();
1324
    ctx->bstate = BS_EXCP;
1325
}
1326

    
1327
void decode_opc(DisasContext * ctx)
1328
{
1329
    uint32_t old_flags = ctx->flags;
1330

    
1331
    _decode_opc(ctx);
1332

    
1333
    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1334
        if (ctx->flags & DELAY_SLOT_CLEARME) {
1335
            gen_op_store_flags(0);
1336
        } else {
1337
            /* go out of the delay slot */
1338
            uint32_t new_flags = ctx->flags;
1339
            new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1340
            gen_op_store_flags(new_flags);
1341
        }
1342
        ctx->flags = 0;
1343
        ctx->bstate = BS_BRANCH;
1344
        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1345
            gen_delayed_conditional_jump(ctx);
1346
        } else if (old_flags & DELAY_SLOT) {
1347
            gen_jump(ctx);
1348
        }
1349

    
1350
    }
1351

    
1352
    /* go into a delay slot */
1353
    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1354
        gen_op_store_flags(ctx->flags);
1355
}
1356

    
1357
static inline void
1358
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1359
                               int search_pc)
1360
{
1361
    DisasContext ctx;
1362
    target_ulong pc_start;
1363
    static uint16_t *gen_opc_end;
1364
    int i, ii;
1365
    int num_insns;
1366
    int max_insns;
1367

    
1368
    pc_start = tb->pc;
1369
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1370
    ctx.pc = pc_start;
1371
    ctx.flags = (uint32_t)tb->flags;
1372
    ctx.bstate = BS_NONE;
1373
    ctx.sr = env->sr;
1374
    ctx.fpscr = env->fpscr;
1375
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1376
    /* We don't know if the delayed pc came from a dynamic or static branch,
1377
       so assume it is a dynamic branch.  */
1378
    ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1379
    ctx.tb = tb;
1380
    ctx.singlestep_enabled = env->singlestep_enabled;
1381

    
1382
#ifdef DEBUG_DISAS
1383
    if (loglevel & CPU_LOG_TB_CPU) {
1384
        fprintf(logfile,
1385
                "------------------------------------------------\n");
1386
        cpu_dump_state(env, logfile, fprintf, 0);
1387
    }
1388
#endif
1389

    
1390
    ii = -1;
1391
    num_insns = 0;
1392
    max_insns = tb->cflags & CF_COUNT_MASK;
1393
    if (max_insns == 0)
1394
        max_insns = CF_COUNT_MASK;
1395
    gen_icount_start();
1396
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1397
        if (env->nb_breakpoints > 0) {
1398
            for (i = 0; i < env->nb_breakpoints; i++) {
1399
                if (ctx.pc == env->breakpoints[i]) {
1400
                    /* We have hit a breakpoint - make sure PC is up-to-date */
1401
                    tcg_gen_movi_i32(cpu_pc, ctx.pc);
1402
                    gen_op_debug();
1403
                    ctx.bstate = BS_EXCP;
1404
                    break;
1405
                }
1406
            }
1407
        }
1408
        if (search_pc) {
1409
            i = gen_opc_ptr - gen_opc_buf;
1410
            if (ii < i) {
1411
                ii++;
1412
                while (ii < i)
1413
                    gen_opc_instr_start[ii++] = 0;
1414
            }
1415
            gen_opc_pc[ii] = ctx.pc;
1416
            gen_opc_hflags[ii] = ctx.flags;
1417
            gen_opc_instr_start[ii] = 1;
1418
            gen_opc_icount[ii] = num_insns;
1419
        }
1420
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1421
            gen_io_start();
1422
#if 0
1423
        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1424
        fflush(stderr);
1425
#endif
1426
        ctx.opcode = lduw_code(ctx.pc);
1427
        decode_opc(&ctx);
1428
        num_insns++;
1429
        ctx.pc += 2;
1430
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1431
            break;
1432
        if (env->singlestep_enabled)
1433
            break;
1434
        if (num_insns >= max_insns)
1435
            break;
1436
#ifdef SH4_SINGLE_STEP
1437
        break;
1438
#endif
1439
    }
1440
    if (tb->cflags & CF_LAST_IO)
1441
        gen_io_end();
1442
    if (env->singlestep_enabled) {
1443
        gen_op_debug();
1444
    } else {
1445
        switch (ctx.bstate) {
1446
        case BS_STOP:
1447
            /* gen_op_interrupt_restart(); */
1448
            /* fall through */
1449
        case BS_NONE:
1450
            if (ctx.flags) {
1451
                gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1452
            }
1453
            gen_goto_tb(&ctx, 0, ctx.pc);
1454
            break;
1455
        case BS_EXCP:
1456
            /* gen_op_interrupt_restart(); */
1457
            tcg_gen_exit_tb(0);
1458
            break;
1459
        case BS_BRANCH:
1460
        default:
1461
            break;
1462
        }
1463
    }
1464

    
1465
    gen_icount_end(tb, num_insns);
1466
    *gen_opc_ptr = INDEX_op_end;
1467
    if (search_pc) {
1468
        i = gen_opc_ptr - gen_opc_buf;
1469
        ii++;
1470
        while (ii <= i)
1471
            gen_opc_instr_start[ii++] = 0;
1472
    } else {
1473
        tb->size = ctx.pc - pc_start;
1474
        tb->icount = num_insns;
1475
    }
1476

    
1477
#ifdef DEBUG_DISAS
1478
#ifdef SH4_DEBUG_DISAS
1479
    if (loglevel & CPU_LOG_TB_IN_ASM)
1480
        fprintf(logfile, "\n");
1481
#endif
1482
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1483
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1484
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1485
        fprintf(logfile, "\n");
1486
    }
1487
#endif
1488
}
1489

    
1490
void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1491
{
1492
    gen_intermediate_code_internal(env, tb, 0);
1493
}
1494

    
1495
void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1496
{
1497
    gen_intermediate_code_internal(env, tb, 1);
1498
}
1499

    
1500
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1501
                unsigned long searched_pc, int pc_pos, void *puc)
1502
{
1503
    env->pc = gen_opc_pc[pc_pos];
1504
    env->flags = gen_opc_hflags[pc_pos];
1505
}