Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ b79e1752

History | View | Annotate | Download (57 kB)

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

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

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

    
37
#include "helper.h"
38
#define GEN_HELPER 1
39
#include "helper.h"
40

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

    
54
#if defined(CONFIG_USER_ONLY)
55
#define IS_USER(ctx) 1
56
#else
57
#define IS_USER(ctx) (!(ctx->sr & SR_MD))
58
#endif
59

    
60
enum {
61
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
62
                      * exception condition
63
                      */
64
    BS_STOP     = 1, /* We want to stop translation for any reason */
65
    BS_BRANCH   = 2, /* We reached a branch condition     */
66
    BS_EXCP     = 3, /* We reached an exception condition */
67
};
68

    
69
/* global register indexes */
70
static TCGv_ptr cpu_env;
71
static TCGv cpu_gregs[24];
72
static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
73
static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
74
static TCGv cpu_pr, cpu_fpscr, cpu_fpul;
75
static TCGv cpu_fregs[32];
76

    
77
/* internal register indexes */
78
static TCGv cpu_flags, cpu_delayed_pc;
79

    
80
#include "gen-icount.h"
81

    
82
static void sh4_translate_init(void)
83
{
84
    int i;
85
    static int done_init = 0;
86
    static const char * const gregnames[24] = {
87
        "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
88
        "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
89
        "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
90
        "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
91
        "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
92
    };
93
    static const char * const fregnames[32] = {
94
         "FPR0_BANK0",  "FPR1_BANK0",  "FPR2_BANK0",  "FPR3_BANK0",
95
         "FPR4_BANK0",  "FPR5_BANK0",  "FPR6_BANK0",  "FPR7_BANK0",
96
         "FPR8_BANK0",  "FPR9_BANK0", "FPR10_BANK0", "FPR11_BANK0",
97
        "FPR12_BANK0", "FPR13_BANK0", "FPR14_BANK0", "FPR15_BANK0",
98
         "FPR0_BANK1",  "FPR1_BANK1",  "FPR2_BANK1",  "FPR3_BANK1",
99
         "FPR4_BANK1",  "FPR5_BANK1",  "FPR6_BANK1",  "FPR7_BANK1",
100
         "FPR8_BANK1",  "FPR9_BANK1", "FPR10_BANK1", "FPR11_BANK1",
101
        "FPR12_BANK1", "FPR13_BANK1", "FPR14_BANK1", "FPR15_BANK1",
102
    };
103

    
104
    if (done_init)
105
        return;
106

    
107
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
108

    
109
    for (i = 0; i < 24; i++)
110
        cpu_gregs[i] = tcg_global_mem_new_i32(TCG_AREG0,
111
                                              offsetof(CPUState, gregs[i]),
112
                                              gregnames[i]);
113

    
114
    cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
115
                                    offsetof(CPUState, pc), "PC");
116
    cpu_sr = tcg_global_mem_new_i32(TCG_AREG0,
117
                                    offsetof(CPUState, sr), "SR");
118
    cpu_ssr = tcg_global_mem_new_i32(TCG_AREG0,
119
                                     offsetof(CPUState, ssr), "SSR");
120
    cpu_spc = tcg_global_mem_new_i32(TCG_AREG0,
121
                                     offsetof(CPUState, spc), "SPC");
122
    cpu_gbr = tcg_global_mem_new_i32(TCG_AREG0,
123
                                     offsetof(CPUState, gbr), "GBR");
124
    cpu_vbr = tcg_global_mem_new_i32(TCG_AREG0,
125
                                     offsetof(CPUState, vbr), "VBR");
126
    cpu_sgr = tcg_global_mem_new_i32(TCG_AREG0,
127
                                     offsetof(CPUState, sgr), "SGR");
128
    cpu_dbr = tcg_global_mem_new_i32(TCG_AREG0,
129
                                     offsetof(CPUState, dbr), "DBR");
130
    cpu_mach = tcg_global_mem_new_i32(TCG_AREG0,
131
                                      offsetof(CPUState, mach), "MACH");
132
    cpu_macl = tcg_global_mem_new_i32(TCG_AREG0,
133
                                      offsetof(CPUState, macl), "MACL");
134
    cpu_pr = tcg_global_mem_new_i32(TCG_AREG0,
135
                                    offsetof(CPUState, pr), "PR");
136
    cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
137
                                       offsetof(CPUState, fpscr), "FPSCR");
138
    cpu_fpul = tcg_global_mem_new_i32(TCG_AREG0,
139
                                      offsetof(CPUState, fpul), "FPUL");
140

    
141
    cpu_flags = tcg_global_mem_new_i32(TCG_AREG0,
142
                                       offsetof(CPUState, flags), "_flags_");
143
    cpu_delayed_pc = tcg_global_mem_new_i32(TCG_AREG0,
144
                                            offsetof(CPUState, delayed_pc),
145
                                            "_delayed_pc_");
146

    
147
    for (i = 0; i < 32; i++)
148
        cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0,
149
                                              offsetof(CPUState, fregs[i]),
150
                                              fregnames[i]);
151

    
152
    /* register helpers */
153
#define GEN_HELPER 2
154
#include "helper.h"
155

    
156
    done_init = 1;
157
}
158

    
159
void cpu_dump_state(CPUState * env, FILE * f,
160
                    int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
161
                    int flags)
162
{
163
    int i;
164
    cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
165
                env->pc, env->sr, env->pr, env->fpscr);
166
    cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
167
                env->spc, env->ssr, env->gbr, env->vbr);
168
    cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
169
                env->sgr, env->dbr, env->delayed_pc, env->fpul);
170
    for (i = 0; i < 24; i += 4) {
171
        cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
172
                    i, env->gregs[i], i + 1, env->gregs[i + 1],
173
                    i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
174
    }
175
    if (env->flags & DELAY_SLOT) {
176
        cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
177
                    env->delayed_pc);
178
    } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
179
        cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
180
                    env->delayed_pc);
181
    }
182
}
183

    
184
static void cpu_sh4_reset(CPUSH4State * env)
185
{
186
#if defined(CONFIG_USER_ONLY)
187
    env->sr = SR_FD;            /* FD - kernel does lazy fpu context switch */
188
#else
189
    env->sr = 0x700000F0;        /* MD, RB, BL, I3-I0 */
190
#endif
191
    env->vbr = 0;
192
    env->pc = 0xA0000000;
193
#if defined(CONFIG_USER_ONLY)
194
    env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
195
    set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
196
#else
197
    env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
198
    set_float_rounding_mode(float_round_to_zero, &env->fp_status);
199
#endif
200
    env->mmucr = 0;
201
}
202

    
203
typedef struct {
204
    const char *name;
205
    int id;
206
    uint32_t pvr;
207
    uint32_t prr;
208
    uint32_t cvr;
209
} sh4_def_t;
210

    
211
static sh4_def_t sh4_defs[] = {
212
    {
213
        .name = "SH7750R",
214
        .id = SH_CPU_SH7750R,
215
        .pvr = 0x00050000,
216
        .prr = 0x00000100,
217
        .cvr = 0x00110000,
218
    }, {
219
        .name = "SH7751R",
220
        .id = SH_CPU_SH7751R,
221
        .pvr = 0x04050005,
222
        .prr = 0x00000113,
223
        .cvr = 0x00110000,        /* Neutered caches, should be 0x20480000 */
224
    },
225
};
226

    
227
static const sh4_def_t *cpu_sh4_find_by_name(const char *name)
228
{
229
    int i;
230

    
231
    if (strcasecmp(name, "any") == 0)
232
        return &sh4_defs[0];
233

    
234
    for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++)
235
        if (strcasecmp(name, sh4_defs[i].name) == 0)
236
            return &sh4_defs[i];
237

    
238
    return NULL;
239
}
240

    
241
void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
242
{
243
    int i;
244

    
245
    for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++)
246
        (*cpu_fprintf)(f, "%s\n", sh4_defs[i].name);
247
}
248

    
249
static void cpu_sh4_register(CPUSH4State *env, const sh4_def_t *def)
250
{
251
    env->pvr = def->pvr;
252
    env->prr = def->prr;
253
    env->cvr = def->cvr;
254
    env->id = def->id;
255
}
256

    
257
CPUSH4State *cpu_sh4_init(const char *cpu_model)
258
{
259
    CPUSH4State *env;
260
    const sh4_def_t *def;
261

    
262
    def = cpu_sh4_find_by_name(cpu_model);
263
    if (!def)
264
        return NULL;
265
    env = qemu_mallocz(sizeof(CPUSH4State));
266
    if (!env)
267
        return NULL;
268
    cpu_exec_init(env);
269
    sh4_translate_init();
270
    env->cpu_model_str = cpu_model;
271
    cpu_sh4_reset(env);
272
    cpu_sh4_register(env, def);
273
    tlb_flush(env, 1);
274
    return env;
275
}
276

    
277
static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
278
{
279
    TranslationBlock *tb;
280
    tb = ctx->tb;
281

    
282
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
283
        !ctx->singlestep_enabled) {
284
        /* Use a direct jump if in same page and singlestep not enabled */
285
        tcg_gen_goto_tb(n);
286
        tcg_gen_movi_i32(cpu_pc, dest);
287
        tcg_gen_exit_tb((long) tb + n);
288
    } else {
289
        tcg_gen_movi_i32(cpu_pc, dest);
290
        if (ctx->singlestep_enabled)
291
            gen_helper_debug();
292
        tcg_gen_exit_tb(0);
293
    }
294
}
295

    
296
static void gen_jump(DisasContext * ctx)
297
{
298
    if (ctx->delayed_pc == (uint32_t) - 1) {
299
        /* Target is not statically known, it comes necessarily from a
300
           delayed jump as immediate jump are conditinal jumps */
301
        tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
302
        if (ctx->singlestep_enabled)
303
            gen_helper_debug();
304
        tcg_gen_exit_tb(0);
305
    } else {
306
        gen_goto_tb(ctx, 0, ctx->delayed_pc);
307
    }
308
}
309

    
310
static inline void gen_branch_slot(uint32_t delayed_pc, int t)
311
{
312
    TCGv sr;
313
    int label = gen_new_label();
314
    tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
315
    sr = tcg_temp_new();
316
    tcg_gen_andi_i32(sr, cpu_sr, SR_T);
317
    tcg_gen_brcondi_i32(TCG_COND_NE, sr, t ? SR_T : 0, label);
318
    tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
319
    gen_set_label(label);
320
}
321

    
322
/* Immediate conditional jump (bt or bf) */
323
static void gen_conditional_jump(DisasContext * ctx,
324
                                 target_ulong ift, target_ulong ifnott)
325
{
326
    int l1;
327
    TCGv sr;
328

    
329
    l1 = gen_new_label();
330
    sr = tcg_temp_new();
331
    tcg_gen_andi_i32(sr, cpu_sr, SR_T);
332
    tcg_gen_brcondi_i32(TCG_COND_EQ, sr, SR_T, l1);
333
    gen_goto_tb(ctx, 0, ifnott);
334
    gen_set_label(l1);
335
    gen_goto_tb(ctx, 1, ift);
336
}
337

    
338
/* Delayed conditional jump (bt or bf) */
339
static void gen_delayed_conditional_jump(DisasContext * ctx)
340
{
341
    int l1;
342
    TCGv ds;
343

    
344
    l1 = gen_new_label();
345
    ds = tcg_temp_new();
346
    tcg_gen_andi_i32(ds, cpu_flags, DELAY_SLOT_TRUE);
347
    tcg_gen_brcondi_i32(TCG_COND_EQ, ds, DELAY_SLOT_TRUE, l1);
348
    gen_goto_tb(ctx, 1, ctx->pc + 2);
349
    gen_set_label(l1);
350
    tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
351
    gen_jump(ctx);
352
}
353

    
354
static inline void gen_set_t(void)
355
{
356
    tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
357
}
358

    
359
static inline void gen_clr_t(void)
360
{
361
    tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
362
}
363

    
364
static inline void gen_cmp(int cond, TCGv t0, TCGv t1)
365
{
366
    int label1 = gen_new_label();
367
    int label2 = gen_new_label();
368
    tcg_gen_brcond_i32(cond, t1, t0, label1);
369
    gen_clr_t();
370
    tcg_gen_br(label2);
371
    gen_set_label(label1);
372
    gen_set_t();
373
    gen_set_label(label2);
374
}
375

    
376
static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
377
{
378
    int label1 = gen_new_label();
379
    int label2 = gen_new_label();
380
    tcg_gen_brcondi_i32(cond, t0, imm, label1);
381
    gen_clr_t();
382
    tcg_gen_br(label2);
383
    gen_set_label(label1);
384
    gen_set_t();
385
    gen_set_label(label2);
386
}
387

    
388
static inline void gen_store_flags(uint32_t flags)
389
{
390
    tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
391
    tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
392
}
393

    
394
static inline void gen_copy_bit_i32(TCGv t0, int p0, TCGv t1, int p1)
395
{
396
    TCGv tmp = tcg_temp_new();
397

    
398
    p0 &= 0x1f;
399
    p1 &= 0x1f;
400

    
401
    tcg_gen_andi_i32(tmp, t1, (1 << p1));
402
    tcg_gen_andi_i32(t0, t0, ~(1 << p0));
403
    if (p0 < p1)
404
        tcg_gen_shri_i32(tmp, tmp, p1 - p0);
405
    else if (p0 > p1)
406
        tcg_gen_shli_i32(tmp, tmp, p0 - p1);
407
    tcg_gen_or_i32(t0, t0, tmp);
408

    
409
    tcg_temp_free(tmp);
410
}
411

    
412
static inline void gen_load_fpr64(TCGv_i64 t, int reg)
413
{
414
    tcg_gen_concat_i32_i64(t, cpu_fregs[reg + 1], cpu_fregs[reg]);
415
}
416

    
417
static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
418
{
419
    TCGv_i32 tmp = tcg_temp_new_i32();
420
    tcg_gen_trunc_i64_i32(tmp, t);
421
    tcg_gen_mov_i32(cpu_fregs[reg + 1], tmp);
422
    tcg_gen_shri_i64(t, t, 32);
423
    tcg_gen_trunc_i64_i32(tmp, t);
424
    tcg_gen_mov_i32(cpu_fregs[reg], tmp);
425
    tcg_temp_free_i32(tmp);
426
}
427

    
428
#define B3_0 (ctx->opcode & 0xf)
429
#define B6_4 ((ctx->opcode >> 4) & 0x7)
430
#define B7_4 ((ctx->opcode >> 4) & 0xf)
431
#define B7_0 (ctx->opcode & 0xff)
432
#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
433
#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
434
  (ctx->opcode & 0xfff))
435
#define B11_8 ((ctx->opcode >> 8) & 0xf)
436
#define B15_12 ((ctx->opcode >> 12) & 0xf)
437

    
438
#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
439
                (cpu_gregs[x + 16]) : (cpu_gregs[x]))
440

    
441
#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
442
                ? (cpu_gregs[x + 16]) : (cpu_gregs[x]))
443

    
444
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
445
#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
446
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
447
#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
448

    
449
#define CHECK_NOT_DELAY_SLOT \
450
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))     \
451
  {                                                           \
452
      tcg_gen_movi_i32(cpu_pc, ctx->pc-2);                    \
453
      gen_helper_raise_slot_illegal_instruction();            \
454
      ctx->bstate = BS_EXCP;                                  \
455
      return;                                                 \
456
  }
457

    
458
#define CHECK_PRIVILEGED                                      \
459
  if (IS_USER(ctx)) {                                         \
460
      tcg_gen_movi_i32(cpu_pc, ctx->pc);                      \
461
      gen_helper_raise_illegal_instruction();                 \
462
      ctx->bstate = BS_EXCP;                                  \
463
      return;                                                 \
464
  }
465

    
466
#define CHECK_FPU_ENABLED                                       \
467
  if (ctx->flags & SR_FD) {                                     \
468
      if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
469
          tcg_gen_movi_i32(cpu_pc, ctx->pc-2);                  \
470
          gen_helper_raise_slot_fpu_disable();                  \
471
      } else {                                                  \
472
          tcg_gen_movi_i32(cpu_pc, ctx->pc);                    \
473
          gen_helper_raise_fpu_disable();                       \
474
      }                                                         \
475
      ctx->bstate = BS_EXCP;                                    \
476
      return;                                                   \
477
  }
478

    
479
static void _decode_opc(DisasContext * ctx)
480
{
481
#if 0
482
    fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
483
#endif
484
    switch (ctx->opcode) {
485
    case 0x0019:                /* div0u */
486
        tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
487
        return;
488
    case 0x000b:                /* rts */
489
        CHECK_NOT_DELAY_SLOT
490
        tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
491
        ctx->flags |= DELAY_SLOT;
492
        ctx->delayed_pc = (uint32_t) - 1;
493
        return;
494
    case 0x0028:                /* clrmac */
495
        tcg_gen_movi_i32(cpu_mach, 0);
496
        tcg_gen_movi_i32(cpu_macl, 0);
497
        return;
498
    case 0x0048:                /* clrs */
499
        tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S);
500
        return;
501
    case 0x0008:                /* clrt */
502
        gen_clr_t();
503
        return;
504
    case 0x0038:                /* ldtlb */
505
        CHECK_PRIVILEGED
506
        gen_helper_ldtlb();
507
        return;
508
    case 0x002b:                /* rte */
509
        CHECK_PRIVILEGED
510
        CHECK_NOT_DELAY_SLOT
511
        tcg_gen_mov_i32(cpu_sr, cpu_ssr);
512
        tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
513
        ctx->flags |= DELAY_SLOT;
514
        ctx->delayed_pc = (uint32_t) - 1;
515
        return;
516
    case 0x0058:                /* sets */
517
        tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S);
518
        return;
519
    case 0x0018:                /* sett */
520
        gen_set_t();
521
        return;
522
    case 0xfbfd:                /* frchg */
523
        tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
524
        ctx->bstate = BS_STOP;
525
        return;
526
    case 0xf3fd:                /* fschg */
527
        tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
528
        ctx->bstate = BS_STOP;
529
        return;
530
    case 0x0009:                /* nop */
531
        return;
532
    case 0x001b:                /* sleep */
533
        CHECK_PRIVILEGED
534
        gen_helper_sleep(tcg_const_i32(ctx->pc + 2));
535
        return;
536
    }
537

    
538
    switch (ctx->opcode & 0xf000) {
539
    case 0x1000:                /* mov.l Rm,@(disp,Rn) */
540
        {
541
            TCGv addr = tcg_temp_new();
542
            tcg_gen_addi_i32(addr, REG(B11_8), B3_0 * 4);
543
            tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
544
            tcg_temp_free(addr);
545
        }
546
        return;
547
    case 0x5000:                /* mov.l @(disp,Rm),Rn */
548
        {
549
            TCGv addr = tcg_temp_new();
550
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 4);
551
            tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
552
            tcg_temp_free(addr);
553
        }
554
        return;
555
    case 0xe000:                /* mov #imm,Rn */
556
        tcg_gen_movi_i32(REG(B11_8), B7_0s);
557
        return;
558
    case 0x9000:                /* mov.w @(disp,PC),Rn */
559
        {
560
            TCGv addr = tcg_const_i32(ctx->pc + 4 + B7_0 * 2);
561
            tcg_gen_qemu_ld16s(REG(B11_8), addr, ctx->memidx);
562
            tcg_temp_free(addr);
563
        }
564
        return;
565
    case 0xd000:                /* mov.l @(disp,PC),Rn */
566
        {
567
            TCGv addr = tcg_const_i32((ctx->pc + 4 + B7_0 * 4) & ~3);
568
            tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
569
            tcg_temp_free(addr);
570
        }
571
        return;
572
    case 0x7000:                /* add #imm,Rn */
573
        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);
574
        return;
575
    case 0xa000:                /* bra disp */
576
        CHECK_NOT_DELAY_SLOT
577
        ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
578
        tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
579
        ctx->flags |= DELAY_SLOT;
580
        return;
581
    case 0xb000:                /* bsr disp */
582
        CHECK_NOT_DELAY_SLOT
583
        tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
584
        ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
585
        tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
586
        ctx->flags |= DELAY_SLOT;
587
        return;
588
    }
589

    
590
    switch (ctx->opcode & 0xf00f) {
591
    case 0x6003:                /* mov Rm,Rn */
592
        tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
593
        return;
594
    case 0x2000:                /* mov.b Rm,@Rn */
595
        tcg_gen_qemu_st8(REG(B7_4), REG(B11_8), ctx->memidx);
596
        return;
597
    case 0x2001:                /* mov.w Rm,@Rn */
598
        tcg_gen_qemu_st16(REG(B7_4), REG(B11_8), ctx->memidx);
599
        return;
600
    case 0x2002:                /* mov.l Rm,@Rn */
601
        tcg_gen_qemu_st32(REG(B7_4), REG(B11_8), ctx->memidx);
602
        return;
603
    case 0x6000:                /* mov.b @Rm,Rn */
604
        tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);
605
        return;
606
    case 0x6001:                /* mov.w @Rm,Rn */
607
        tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);
608
        return;
609
    case 0x6002:                /* mov.l @Rm,Rn */
610
        tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);
611
        return;
612
    case 0x2004:                /* mov.b Rm,@-Rn */
613
        {
614
            TCGv addr = tcg_temp_new();
615
            tcg_gen_subi_i32(addr, REG(B11_8), 1);
616
            tcg_gen_qemu_st8(REG(B7_4), addr, ctx->memidx);        /* might cause re-execution */
617
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);        /* modify register status */
618
            tcg_temp_free(addr);
619
        }
620
        return;
621
    case 0x2005:                /* mov.w Rm,@-Rn */
622
        {
623
            TCGv addr = tcg_temp_new();
624
            tcg_gen_subi_i32(addr, REG(B11_8), 2);
625
            tcg_gen_qemu_st16(REG(B7_4), addr, ctx->memidx);
626
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 2);
627
            tcg_temp_free(addr);
628
        }
629
        return;
630
    case 0x2006:                /* mov.l Rm,@-Rn */
631
        {
632
            TCGv addr = tcg_temp_new();
633
            tcg_gen_subi_i32(addr, REG(B11_8), 4);
634
            tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
635
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
636
        }
637
        return;
638
    case 0x6004:                /* mov.b @Rm+,Rn */
639
        tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);
640
        if ( B11_8 != B7_4 )
641
                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 1);
642
        return;
643
    case 0x6005:                /* mov.w @Rm+,Rn */
644
        tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);
645
        if ( B11_8 != B7_4 )
646
                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
647
        return;
648
    case 0x6006:                /* mov.l @Rm+,Rn */
649
        tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);
650
        if ( B11_8 != B7_4 )
651
                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
652
        return;
653
    case 0x0004:                /* mov.b Rm,@(R0,Rn) */
654
        {
655
            TCGv addr = tcg_temp_new();
656
            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
657
            tcg_gen_qemu_st8(REG(B7_4), addr, ctx->memidx);
658
            tcg_temp_free(addr);
659
        }
660
        return;
661
    case 0x0005:                /* mov.w Rm,@(R0,Rn) */
662
        {
663
            TCGv addr = tcg_temp_new();
664
            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
665
            tcg_gen_qemu_st16(REG(B7_4), addr, ctx->memidx);
666
            tcg_temp_free(addr);
667
        }
668
        return;
669
    case 0x0006:                /* mov.l Rm,@(R0,Rn) */
670
        {
671
            TCGv addr = tcg_temp_new();
672
            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
673
            tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
674
            tcg_temp_free(addr);
675
        }
676
        return;
677
    case 0x000c:                /* mov.b @(R0,Rm),Rn */
678
        {
679
            TCGv addr = tcg_temp_new();
680
            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
681
            tcg_gen_qemu_ld8s(REG(B11_8), addr, ctx->memidx);
682
            tcg_temp_free(addr);
683
        }
684
        return;
685
    case 0x000d:                /* mov.w @(R0,Rm),Rn */
686
        {
687
            TCGv addr = tcg_temp_new();
688
            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
689
            tcg_gen_qemu_ld16s(REG(B11_8), addr, ctx->memidx);
690
            tcg_temp_free(addr);
691
        }
692
        return;
693
    case 0x000e:                /* mov.l @(R0,Rm),Rn */
694
        {
695
            TCGv addr = tcg_temp_new();
696
            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
697
            tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
698
            tcg_temp_free(addr);
699
        }
700
        return;
701
    case 0x6008:                /* swap.b Rm,Rn */
702
        {
703
            TCGv highw, high, low;
704
            highw = tcg_temp_new();
705
            tcg_gen_andi_i32(highw, REG(B7_4), 0xffff0000);
706
            high = tcg_temp_new();
707
            tcg_gen_ext8u_i32(high, REG(B7_4));
708
            tcg_gen_shli_i32(high, high, 8);
709
            low = tcg_temp_new();
710
            tcg_gen_shri_i32(low, REG(B7_4), 8);
711
            tcg_gen_ext8u_i32(low, low);
712
            tcg_gen_or_i32(REG(B11_8), high, low);
713
            tcg_gen_or_i32(REG(B11_8), REG(B11_8), highw);
714
            tcg_temp_free(low);
715
            tcg_temp_free(high);
716
        }
717
        return;
718
    case 0x6009:                /* swap.w Rm,Rn */
719
        {
720
            TCGv high, low;
721
            high = tcg_temp_new();
722
            tcg_gen_ext16u_i32(high, REG(B7_4));
723
            tcg_gen_shli_i32(high, high, 16);
724
            low = tcg_temp_new();
725
            tcg_gen_shri_i32(low, REG(B7_4), 16);
726
            tcg_gen_ext16u_i32(low, low);
727
            tcg_gen_or_i32(REG(B11_8), high, low);
728
            tcg_temp_free(low);
729
            tcg_temp_free(high);
730
        }
731
        return;
732
    case 0x200d:                /* xtrct Rm,Rn */
733
        {
734
            TCGv high, low;
735
            high = tcg_temp_new();
736
            tcg_gen_ext16u_i32(high, REG(B7_4));
737
            tcg_gen_shli_i32(high, high, 16);
738
            low = tcg_temp_new();
739
            tcg_gen_shri_i32(low, REG(B11_8), 16);
740
            tcg_gen_ext16u_i32(low, low);
741
            tcg_gen_or_i32(REG(B11_8), high, low);
742
            tcg_temp_free(low);
743
            tcg_temp_free(high);
744
        }
745
        return;
746
    case 0x300c:                /* add Rm,Rn */
747
        tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));
748
        return;
749
    case 0x300e:                /* addc Rm,Rn */
750
        gen_helper_addc(REG(B11_8), REG(B7_4), REG(B11_8));
751
        return;
752
    case 0x300f:                /* addv Rm,Rn */
753
        gen_helper_addv(REG(B11_8), REG(B7_4), REG(B11_8));
754
        return;
755
    case 0x2009:                /* and Rm,Rn */
756
        tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
757
        return;
758
    case 0x3000:                /* cmp/eq Rm,Rn */
759
        gen_cmp(TCG_COND_EQ, REG(B7_4), REG(B11_8));
760
        return;
761
    case 0x3003:                /* cmp/ge Rm,Rn */
762
        gen_cmp(TCG_COND_GE, REG(B7_4), REG(B11_8));
763
        return;
764
    case 0x3007:                /* cmp/gt Rm,Rn */
765
        gen_cmp(TCG_COND_GT, REG(B7_4), REG(B11_8));
766
        return;
767
    case 0x3006:                /* cmp/hi Rm,Rn */
768
        gen_cmp(TCG_COND_GTU, REG(B7_4), REG(B11_8));
769
        return;
770
    case 0x3002:                /* cmp/hs Rm,Rn */
771
        gen_cmp(TCG_COND_GEU, REG(B7_4), REG(B11_8));
772
        return;
773
    case 0x200c:                /* cmp/str Rm,Rn */
774
        {
775
            int label1 = gen_new_label();
776
            int label2 = gen_new_label();
777
            TCGv cmp1 = tcg_temp_local_new(TCG_TYPE_I32);
778
            TCGv cmp2 = tcg_temp_local_new(TCG_TYPE_I32);
779
            tcg_gen_xor_i32(cmp1, REG(B7_4), REG(B11_8));
780
            tcg_gen_andi_i32(cmp2, cmp1, 0xff000000);
781
            tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
782
            tcg_gen_andi_i32(cmp2, cmp1, 0x00ff0000);
783
            tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
784
            tcg_gen_andi_i32(cmp2, cmp1, 0x0000ff00);
785
            tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
786
            tcg_gen_andi_i32(cmp2, cmp1, 0x000000ff);
787
            tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
788
            tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
789
            tcg_gen_br(label2);
790
            gen_set_label(label1);
791
            tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
792
            gen_set_label(label2);
793
            tcg_temp_free(cmp2);
794
            tcg_temp_free(cmp1);
795
        }
796
        return;
797
    case 0x2007:                /* div0s Rm,Rn */
798
        {
799
            gen_copy_bit_i32(cpu_sr, 8, REG(B11_8), 31);        /* SR_Q */
800
            gen_copy_bit_i32(cpu_sr, 9, REG(B7_4), 31);                /* SR_M */
801
            TCGv val = tcg_temp_new();
802
            tcg_gen_xor_i32(val, REG(B7_4), REG(B11_8));
803
            gen_copy_bit_i32(cpu_sr, 0, val, 31);                /* SR_T */
804
            tcg_temp_free(val);
805
        }
806
        return;
807
    case 0x3004:                /* div1 Rm,Rn */
808
        gen_helper_div1(REG(B11_8), REG(B7_4), REG(B11_8));
809
        return;
810
    case 0x300d:                /* dmuls.l Rm,Rn */
811
        {
812
            TCGv_i64 tmp1 = tcg_temp_new_i64();
813
            TCGv_i64 tmp2 = tcg_temp_new_i64();
814

    
815
            tcg_gen_ext_i32_i64(tmp1, REG(B7_4));
816
            tcg_gen_ext_i32_i64(tmp2, REG(B11_8));
817
            tcg_gen_mul_i64(tmp1, tmp1, tmp2);
818
            tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
819
            tcg_gen_shri_i64(tmp1, tmp1, 32);
820
            tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
821

    
822
            tcg_temp_free_i64(tmp2);
823
            tcg_temp_free_i64(tmp1);
824
        }
825
        return;
826
    case 0x3005:                /* dmulu.l Rm,Rn */
827
        {
828
            TCGv_i64 tmp1 = tcg_temp_new_i64();
829
            TCGv_i64 tmp2 = tcg_temp_new_i64();
830

    
831
            tcg_gen_extu_i32_i64(tmp1, REG(B7_4));
832
            tcg_gen_extu_i32_i64(tmp2, REG(B11_8));
833
            tcg_gen_mul_i64(tmp1, tmp1, tmp2);
834
            tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
835
            tcg_gen_shri_i64(tmp1, tmp1, 32);
836
            tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
837

    
838
            tcg_temp_free_i64(tmp2);
839
            tcg_temp_free_i64(tmp1);
840
        }
841
        return;
842
    case 0x600e:                /* exts.b Rm,Rn */
843
        tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));
844
        return;
845
    case 0x600f:                /* exts.w Rm,Rn */
846
        tcg_gen_ext16s_i32(REG(B11_8), REG(B7_4));
847
        return;
848
    case 0x600c:                /* extu.b Rm,Rn */
849
        tcg_gen_ext8u_i32(REG(B11_8), REG(B7_4));
850
        return;
851
    case 0x600d:                /* extu.w Rm,Rn */
852
        tcg_gen_ext16u_i32(REG(B11_8), REG(B7_4));
853
        return;
854
    case 0x000f:                /* mac.l @Rm+,@Rn+ */
855
        {
856
            TCGv arg0, arg1;
857
            arg0 = tcg_temp_new();
858
            tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);
859
            arg1 = tcg_temp_new();
860
            tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);
861
            gen_helper_macl(arg0, arg1);
862
            tcg_temp_free(arg1);
863
            tcg_temp_free(arg0);
864
            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
865
            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
866
        }
867
        return;
868
    case 0x400f:                /* mac.w @Rm+,@Rn+ */
869
        {
870
            TCGv arg0, arg1;
871
            arg0 = tcg_temp_new();
872
            tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);
873
            arg1 = tcg_temp_new();
874
            tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);
875
            gen_helper_macw(arg0, arg1);
876
            tcg_temp_free(arg1);
877
            tcg_temp_free(arg0);
878
            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);
879
            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
880
        }
881
        return;
882
    case 0x0007:                /* mul.l Rm,Rn */
883
        tcg_gen_mul_i32(cpu_macl, REG(B7_4), REG(B11_8));
884
        return;
885
    case 0x200f:                /* muls.w Rm,Rn */
886
        {
887
            TCGv arg0, arg1;
888
            arg0 = tcg_temp_new();
889
            tcg_gen_ext16s_i32(arg0, REG(B7_4));
890
            arg1 = tcg_temp_new();
891
            tcg_gen_ext16s_i32(arg1, REG(B11_8));
892
            tcg_gen_mul_i32(cpu_macl, arg0, arg1);
893
            tcg_temp_free(arg1);
894
            tcg_temp_free(arg0);
895
        }
896
        return;
897
    case 0x200e:                /* mulu.w Rm,Rn */
898
        {
899
            TCGv arg0, arg1;
900
            arg0 = tcg_temp_new();
901
            tcg_gen_ext16u_i32(arg0, REG(B7_4));
902
            arg1 = tcg_temp_new();
903
            tcg_gen_ext16u_i32(arg1, REG(B11_8));
904
            tcg_gen_mul_i32(cpu_macl, arg0, arg1);
905
            tcg_temp_free(arg1);
906
            tcg_temp_free(arg0);
907
        }
908
        return;
909
    case 0x600b:                /* neg Rm,Rn */
910
        tcg_gen_neg_i32(REG(B11_8), REG(B7_4));
911
        return;
912
    case 0x600a:                /* negc Rm,Rn */
913
        gen_helper_negc(REG(B11_8), REG(B7_4));
914
        return;
915
    case 0x6007:                /* not Rm,Rn */
916
        tcg_gen_not_i32(REG(B11_8), REG(B7_4));
917
        return;
918
    case 0x200b:                /* or Rm,Rn */
919
        tcg_gen_or_i32(REG(B11_8), REG(B11_8), REG(B7_4));
920
        return;
921
    case 0x400c:                /* shad Rm,Rn */
922
        {
923
            int label1 = gen_new_label();
924
            int label2 = gen_new_label();
925
            int label3 = gen_new_label();
926
            int label4 = gen_new_label();
927
            TCGv shift = tcg_temp_local_new(TCG_TYPE_I32);
928
            tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
929
            /* Rm positive, shift to the left */
930
            tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
931
            tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);
932
            tcg_gen_br(label4);
933
            /* Rm negative, shift to the right */
934
            gen_set_label(label1);
935
            tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
936
            tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);
937
            tcg_gen_not_i32(shift, REG(B7_4));
938
            tcg_gen_andi_i32(shift, shift, 0x1f);
939
            tcg_gen_addi_i32(shift, shift, 1);
940
            tcg_gen_sar_i32(REG(B11_8), REG(B11_8), shift);
941
            tcg_gen_br(label4);
942
            /* Rm = -32 */
943
            gen_set_label(label2);
944
            tcg_gen_brcondi_i32(TCG_COND_LT, REG(B11_8), 0, label3);
945
            tcg_gen_movi_i32(REG(B11_8), 0);
946
            tcg_gen_br(label4);
947
            gen_set_label(label3);
948
            tcg_gen_movi_i32(REG(B11_8), 0xffffffff);
949
            gen_set_label(label4);
950
            tcg_temp_free(shift);
951
        }
952
        return;
953
    case 0x400d:                /* shld Rm,Rn */
954
        {
955
            int label1 = gen_new_label();
956
            int label2 = gen_new_label();
957
            int label3 = gen_new_label();
958
            TCGv shift = tcg_temp_local_new(TCG_TYPE_I32);
959
            tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
960
            /* Rm positive, shift to the left */
961
            tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
962
            tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);
963
            tcg_gen_br(label3);
964
            /* Rm negative, shift to the right */
965
            gen_set_label(label1);
966
            tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
967
            tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);
968
            tcg_gen_not_i32(shift, REG(B7_4));
969
            tcg_gen_andi_i32(shift, shift, 0x1f);
970
            tcg_gen_addi_i32(shift, shift, 1);
971
            tcg_gen_shr_i32(REG(B11_8), REG(B11_8), shift);
972
            tcg_gen_br(label3);
973
            /* Rm = -32 */
974
            gen_set_label(label2);
975
            tcg_gen_movi_i32(REG(B11_8), 0);
976
            gen_set_label(label3);
977
            tcg_temp_free(shift);
978
        }
979
        return;
980
    case 0x3008:                /* sub Rm,Rn */
981
        tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));
982
        return;
983
    case 0x300a:                /* subc Rm,Rn */
984
        gen_helper_subc(REG(B11_8), REG(B7_4), REG(B11_8));
985
        return;
986
    case 0x300b:                /* subv Rm,Rn */
987
        gen_helper_subv(REG(B11_8), REG(B7_4), REG(B11_8));
988
        return;
989
    case 0x2008:                /* tst Rm,Rn */
990
        {
991
            TCGv val = tcg_temp_new();
992
            tcg_gen_and_i32(val, REG(B7_4), REG(B11_8));
993
            gen_cmp_imm(TCG_COND_EQ, val, 0);
994
            tcg_temp_free(val);
995
        }
996
        return;
997
    case 0x200a:                /* xor Rm,Rn */
998
        tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));
999
        return;
1000
    case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
1001
        if (ctx->fpscr & FPSCR_SZ) {
1002
            TCGv_i64 fp = tcg_temp_new_i64();
1003
            gen_load_fpr64(fp, XREG(B7_4));
1004
            gen_store_fpr64(fp, XREG(B11_8));
1005
            tcg_temp_free_i64(fp);
1006
        } else {
1007
            tcg_gen_mov_i32(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
1008
        }
1009
        return;
1010
    case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
1011
        if (ctx->fpscr & FPSCR_SZ) {
1012
            TCGv addr_hi = tcg_temp_new();
1013
            int fr = XREG(B7_4);
1014
            tcg_gen_addi_i32(addr_hi, REG(B11_8), 4);
1015
            tcg_gen_qemu_st32(cpu_fregs[fr  ], REG(B11_8), ctx->memidx);
1016
            tcg_gen_qemu_st32(cpu_fregs[fr+1], addr_hi,           ctx->memidx);
1017
            tcg_temp_free(addr_hi);
1018
        } else {
1019
            tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], REG(B11_8), ctx->memidx);
1020
        }
1021
        return;
1022
    case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
1023
        if (ctx->fpscr & FPSCR_SZ) {
1024
            TCGv addr_hi = tcg_temp_new();
1025
            int fr = XREG(B11_8);
1026
            tcg_gen_addi_i32(addr_hi, REG(B7_4), 4);
1027
            tcg_gen_qemu_ld32u(cpu_fregs[fr  ], REG(B7_4), ctx->memidx);
1028
            tcg_gen_qemu_ld32u(cpu_fregs[fr+1], addr_hi,   ctx->memidx);
1029
            tcg_temp_free(addr_hi);
1030
        } else {
1031
            tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], REG(B7_4), ctx->memidx);
1032
        }
1033
        return;
1034
    case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
1035
        if (ctx->fpscr & FPSCR_SZ) {
1036
            TCGv addr_hi = tcg_temp_new();
1037
            int fr = XREG(B11_8);
1038
            tcg_gen_addi_i32(addr_hi, REG(B7_4), 4);
1039
            tcg_gen_qemu_ld32u(cpu_fregs[fr  ], REG(B7_4), ctx->memidx);
1040
            tcg_gen_qemu_ld32u(cpu_fregs[fr+1], addr_hi,   ctx->memidx);
1041
            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 8);
1042
            tcg_temp_free(addr_hi);
1043
        } else {
1044
            tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], REG(B7_4), ctx->memidx);
1045
            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
1046
        }
1047
        return;
1048
    case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
1049
        if (ctx->fpscr & FPSCR_SZ) {
1050
            TCGv addr = tcg_temp_new_i32();
1051
            int fr = XREG(B7_4);
1052
            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1053
            tcg_gen_qemu_st32(cpu_fregs[fr+1], addr, ctx->memidx);
1054
            tcg_gen_subi_i32(addr, REG(B11_8), 8);
1055
            tcg_gen_qemu_st32(cpu_fregs[fr  ], addr, ctx->memidx);
1056
            tcg_gen_mov_i32(REG(B11_8), addr);
1057
            tcg_temp_free(addr);
1058
        } else {
1059
            TCGv addr;
1060
            addr = tcg_temp_new_i32();
1061
            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1062
            tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], addr, ctx->memidx);
1063
            tcg_temp_free(addr);
1064
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1065
        }
1066
        return;
1067
    case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
1068
        {
1069
            TCGv addr = tcg_temp_new_i32();
1070
            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
1071
            if (ctx->fpscr & FPSCR_SZ) {
1072
                int fr = XREG(B11_8);
1073
                tcg_gen_qemu_ld32u(cpu_fregs[fr         ], addr, ctx->memidx);
1074
                tcg_gen_addi_i32(addr, addr, 4);
1075
                tcg_gen_qemu_ld32u(cpu_fregs[fr+1], addr, ctx->memidx);
1076
            } else {
1077
                tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], addr, ctx->memidx);
1078
            }
1079
            tcg_temp_free(addr);
1080
        }
1081
        return;
1082
    case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
1083
        {
1084
            TCGv addr = tcg_temp_new();
1085
            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
1086
            if (ctx->fpscr & FPSCR_SZ) {
1087
                int fr = XREG(B7_4);
1088
                tcg_gen_qemu_ld32u(cpu_fregs[fr         ], addr, ctx->memidx);
1089
                tcg_gen_addi_i32(addr, addr, 4);
1090
                tcg_gen_qemu_ld32u(cpu_fregs[fr+1], addr, ctx->memidx);
1091
            } else {
1092
                tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], addr, ctx->memidx);
1093
            }
1094
            tcg_temp_free(addr);
1095
        }
1096
        return;
1097
    case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1098
    case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1099
    case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1100
    case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1101
    case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1102
    case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1103
        {
1104
            if (ctx->fpscr & FPSCR_PR) {
1105
                TCGv_i64 fp0, fp1;
1106

    
1107
                if (ctx->opcode & 0x0110)
1108
                    break; /* illegal instruction */
1109
                fp0 = tcg_temp_new_i64();
1110
                fp1 = tcg_temp_new_i64();
1111
                gen_load_fpr64(fp0, DREG(B11_8));
1112
                gen_load_fpr64(fp1, DREG(B7_4));
1113
                switch (ctx->opcode & 0xf00f) {
1114
                case 0xf000:                /* fadd Rm,Rn */
1115
                    gen_helper_fadd_DT(fp0, fp0, fp1);
1116
                    break;
1117
                case 0xf001:                /* fsub Rm,Rn */
1118
                    gen_helper_fsub_DT(fp0, fp0, fp1);
1119
                    break;
1120
                case 0xf002:                /* fmul Rm,Rn */
1121
                    gen_helper_fmul_DT(fp0, fp0, fp1);
1122
                    break;
1123
                case 0xf003:                /* fdiv Rm,Rn */
1124
                    gen_helper_fdiv_DT(fp0, fp0, fp1);
1125
                    break;
1126
                case 0xf004:                /* fcmp/eq Rm,Rn */
1127
                    gen_helper_fcmp_eq_DT(fp0, fp1);
1128
                    return;
1129
                case 0xf005:                /* fcmp/gt Rm,Rn */
1130
                    gen_helper_fcmp_gt_DT(fp0, fp1);
1131
                    return;
1132
                }
1133
                gen_store_fpr64(fp0, DREG(B11_8));
1134
                tcg_temp_free_i64(fp0);
1135
                tcg_temp_free_i64(fp1);
1136
            } else {
1137
                switch (ctx->opcode & 0xf00f) {
1138
                case 0xf000:                /* fadd Rm,Rn */
1139
                    gen_helper_fadd_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
1140
                    break;
1141
                case 0xf001:                /* fsub Rm,Rn */
1142
                    gen_helper_fsub_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
1143
                    break;
1144
                case 0xf002:                /* fmul Rm,Rn */
1145
                    gen_helper_fmul_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
1146
                    break;
1147
                case 0xf003:                /* fdiv Rm,Rn */
1148
                    gen_helper_fdiv_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
1149
                    break;
1150
                case 0xf004:                /* fcmp/eq Rm,Rn */
1151
                    gen_helper_fcmp_eq_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
1152
                    return;
1153
                case 0xf005:                /* fcmp/gt Rm,Rn */
1154
                    gen_helper_fcmp_gt_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
1155
                    return;
1156
                }
1157
            }
1158
        }
1159
        return;
1160
    }
1161

    
1162
    switch (ctx->opcode & 0xff00) {
1163
    case 0xc900:                /* and #imm,R0 */
1164
        tcg_gen_andi_i32(REG(0), REG(0), B7_0);
1165
        return;
1166
    case 0xcd00:                /* and.b #imm,@(R0,GBR) */
1167
        {
1168
            TCGv addr, val;
1169
            addr = tcg_temp_new();
1170
            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1171
            val = tcg_temp_new();
1172
            tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1173
            tcg_gen_andi_i32(val, val, B7_0);
1174
            tcg_gen_qemu_st8(val, addr, ctx->memidx);
1175
            tcg_temp_free(val);
1176
            tcg_temp_free(addr);
1177
        }
1178
        return;
1179
    case 0x8b00:                /* bf label */
1180
        CHECK_NOT_DELAY_SLOT
1181
            gen_conditional_jump(ctx, ctx->pc + 2,
1182
                                 ctx->pc + 4 + B7_0s * 2);
1183
        ctx->bstate = BS_BRANCH;
1184
        return;
1185
    case 0x8f00:                /* bf/s label */
1186
        CHECK_NOT_DELAY_SLOT
1187
        gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);
1188
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
1189
        return;
1190
    case 0x8900:                /* bt label */
1191
        CHECK_NOT_DELAY_SLOT
1192
            gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
1193
                                 ctx->pc + 2);
1194
        ctx->bstate = BS_BRANCH;
1195
        return;
1196
    case 0x8d00:                /* bt/s label */
1197
        CHECK_NOT_DELAY_SLOT
1198
        gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);
1199
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
1200
        return;
1201
    case 0x8800:                /* cmp/eq #imm,R0 */
1202
        gen_cmp_imm(TCG_COND_EQ, REG(0), B7_0s);
1203
        return;
1204
    case 0xc400:                /* mov.b @(disp,GBR),R0 */
1205
        {
1206
            TCGv addr = tcg_temp_new();
1207
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1208
            tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);
1209
            tcg_temp_free(addr);
1210
        }
1211
        return;
1212
    case 0xc500:                /* mov.w @(disp,GBR),R0 */
1213
        {
1214
            TCGv addr = tcg_temp_new();
1215
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1216
            tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);
1217
            tcg_temp_free(addr);
1218
        }
1219
        return;
1220
    case 0xc600:                /* mov.l @(disp,GBR),R0 */
1221
        {
1222
            TCGv addr = tcg_temp_new();
1223
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1224
            tcg_gen_qemu_ld32s(REG(0), addr, ctx->memidx);
1225
            tcg_temp_free(addr);
1226
        }
1227
        return;
1228
    case 0xc000:                /* mov.b R0,@(disp,GBR) */
1229
        {
1230
            TCGv addr = tcg_temp_new();
1231
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1232
            tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);
1233
            tcg_temp_free(addr);
1234
        }
1235
        return;
1236
    case 0xc100:                /* mov.w R0,@(disp,GBR) */
1237
        {
1238
            TCGv addr = tcg_temp_new();
1239
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1240
            tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);
1241
            tcg_temp_free(addr);
1242
        }
1243
        return;
1244
    case 0xc200:                /* mov.l R0,@(disp,GBR) */
1245
        {
1246
            TCGv addr = tcg_temp_new();
1247
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1248
            tcg_gen_qemu_st32(REG(0), addr, ctx->memidx);
1249
            tcg_temp_free(addr);
1250
        }
1251
        return;
1252
    case 0x8000:                /* mov.b R0,@(disp,Rn) */
1253
        {
1254
            TCGv addr = tcg_temp_new();
1255
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1256
            tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);
1257
            tcg_temp_free(addr);
1258
        }
1259
        return;
1260
    case 0x8100:                /* mov.w R0,@(disp,Rn) */
1261
        {
1262
            TCGv addr = tcg_temp_new();
1263
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1264
            tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);
1265
            tcg_temp_free(addr);
1266
        }
1267
        return;
1268
    case 0x8400:                /* mov.b @(disp,Rn),R0 */
1269
        {
1270
            TCGv addr = tcg_temp_new();
1271
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1272
            tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);
1273
            tcg_temp_free(addr);
1274
        }
1275
        return;
1276
    case 0x8500:                /* mov.w @(disp,Rn),R0 */
1277
        {
1278
            TCGv addr = tcg_temp_new();
1279
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1280
            tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);
1281
            tcg_temp_free(addr);
1282
        }
1283
        return;
1284
    case 0xc700:                /* mova @(disp,PC),R0 */
1285
        tcg_gen_movi_i32(REG(0), ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
1286
        return;
1287
    case 0xcb00:                /* or #imm,R0 */
1288
        tcg_gen_ori_i32(REG(0), REG(0), B7_0);
1289
        return;
1290
    case 0xcf00:                /* or.b #imm,@(R0,GBR) */
1291
        {
1292
            TCGv addr, val;
1293
            addr = tcg_temp_new();
1294
            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1295
            val = tcg_temp_new();
1296
            tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1297
            tcg_gen_ori_i32(val, val, B7_0);
1298
            tcg_gen_qemu_st8(val, addr, ctx->memidx);
1299
            tcg_temp_free(val);
1300
            tcg_temp_free(addr);
1301
        }
1302
        return;
1303
    case 0xc300:                /* trapa #imm */
1304
        {
1305
            TCGv imm;
1306
            CHECK_NOT_DELAY_SLOT
1307
            tcg_gen_movi_i32(cpu_pc, ctx->pc);
1308
            imm = tcg_const_i32(B7_0);
1309
            gen_helper_trapa(imm);
1310
            tcg_temp_free(imm);
1311
            ctx->bstate = BS_BRANCH;
1312
        }
1313
        return;
1314
    case 0xc800:                /* tst #imm,R0 */
1315
        {
1316
            TCGv val = tcg_temp_new();
1317
            tcg_gen_andi_i32(val, REG(0), B7_0);
1318
            gen_cmp_imm(TCG_COND_EQ, val, 0);
1319
            tcg_temp_free(val);
1320
        }
1321
        return;
1322
    case 0xcc00:                /* tst.b #imm,@(R0,GBR) */
1323
        {
1324
            TCGv val = tcg_temp_new();
1325
            tcg_gen_add_i32(val, REG(0), cpu_gbr);
1326
            tcg_gen_qemu_ld8u(val, val, ctx->memidx);
1327
            tcg_gen_andi_i32(val, val, B7_0);
1328
            gen_cmp_imm(TCG_COND_EQ, val, 0);
1329
            tcg_temp_free(val);
1330
        }
1331
        return;
1332
    case 0xca00:                /* xor #imm,R0 */
1333
        tcg_gen_xori_i32(REG(0), REG(0), B7_0);
1334
        return;
1335
    case 0xce00:                /* xor.b #imm,@(R0,GBR) */
1336
        {
1337
            TCGv addr, val;
1338
            addr = tcg_temp_new();
1339
            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1340
            val = tcg_temp_new();
1341
            tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1342
            tcg_gen_xori_i32(val, val, B7_0);
1343
            tcg_gen_qemu_st8(val, addr, ctx->memidx);
1344
            tcg_temp_free(val);
1345
            tcg_temp_free(addr);
1346
        }
1347
        return;
1348
    }
1349

    
1350
    switch (ctx->opcode & 0xf08f) {
1351
    case 0x408e:                /* ldc Rm,Rn_BANK */
1352
        CHECK_PRIVILEGED
1353
        tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
1354
        return;
1355
    case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
1356
        CHECK_PRIVILEGED
1357
        tcg_gen_qemu_ld32s(ALTREG(B6_4), REG(B11_8), ctx->memidx);
1358
        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1359
        return;
1360
    case 0x0082:                /* stc Rm_BANK,Rn */
1361
        CHECK_PRIVILEGED
1362
        tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
1363
        return;
1364
    case 0x4083:                /* stc.l Rm_BANK,@-Rn */
1365
        CHECK_PRIVILEGED
1366
        {
1367
            TCGv addr = tcg_temp_new();
1368
            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1369
            tcg_gen_qemu_st32(ALTREG(B6_4), addr, ctx->memidx);
1370
            tcg_temp_free(addr);
1371
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1372
        }
1373
        return;
1374
    }
1375

    
1376
    switch (ctx->opcode & 0xf0ff) {
1377
    case 0x0023:                /* braf Rn */
1378
        CHECK_NOT_DELAY_SLOT
1379
        tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->pc + 4);
1380
        ctx->flags |= DELAY_SLOT;
1381
        ctx->delayed_pc = (uint32_t) - 1;
1382
        return;
1383
    case 0x0003:                /* bsrf Rn */
1384
        CHECK_NOT_DELAY_SLOT
1385
        tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1386
        tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);
1387
        ctx->flags |= DELAY_SLOT;
1388
        ctx->delayed_pc = (uint32_t) - 1;
1389
        return;
1390
    case 0x4015:                /* cmp/pl Rn */
1391
        gen_cmp_imm(TCG_COND_GT, REG(B11_8), 0);
1392
        return;
1393
    case 0x4011:                /* cmp/pz Rn */
1394
        gen_cmp_imm(TCG_COND_GE, REG(B11_8), 0);
1395
        return;
1396
    case 0x4010:                /* dt Rn */
1397
        tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);
1398
        gen_cmp_imm(TCG_COND_EQ, REG(B11_8), 0);
1399
        return;
1400
    case 0x402b:                /* jmp @Rn */
1401
        CHECK_NOT_DELAY_SLOT
1402
        tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1403
        ctx->flags |= DELAY_SLOT;
1404
        ctx->delayed_pc = (uint32_t) - 1;
1405
        return;
1406
    case 0x400b:                /* jsr @Rn */
1407
        CHECK_NOT_DELAY_SLOT
1408
        tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1409
        tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1410
        ctx->flags |= DELAY_SLOT;
1411
        ctx->delayed_pc = (uint32_t) - 1;
1412
        return;
1413
    case 0x400e:                /* ldc Rm,SR */
1414
        CHECK_PRIVILEGED
1415
        tcg_gen_andi_i32(cpu_sr, REG(B11_8), 0x700083f3);
1416
        ctx->bstate = BS_STOP;
1417
        return;
1418
    case 0x4007:                /* ldc.l @Rm+,SR */
1419
        CHECK_PRIVILEGED
1420
        {
1421
            TCGv val = tcg_temp_new();
1422
            tcg_gen_qemu_ld32s(val, REG(B11_8), ctx->memidx);
1423
            tcg_gen_andi_i32(cpu_sr, val, 0x700083f3);
1424
            tcg_temp_free(val);
1425
            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1426
            ctx->bstate = BS_STOP;
1427
        }
1428
        return;
1429
    case 0x0002:                /* stc SR,Rn */
1430
        CHECK_PRIVILEGED
1431
        tcg_gen_mov_i32(REG(B11_8), cpu_sr);
1432
        return;
1433
    case 0x4003:                /* stc SR,@-Rn */
1434
        CHECK_PRIVILEGED
1435
        {
1436
            TCGv addr = tcg_temp_new();
1437
            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1438
            tcg_gen_qemu_st32(cpu_sr, addr, ctx->memidx);
1439
            tcg_temp_free(addr);
1440
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1441
        }
1442
        return;
1443
#define LDST(reg,ldnum,ldpnum,stnum,stpnum,prechk)                \
1444
  case ldnum:                                                        \
1445
    prechk                                                            \
1446
    tcg_gen_mov_i32 (cpu_##reg, REG(B11_8));                        \
1447
    return;                                                        \
1448
  case ldpnum:                                                        \
1449
    prechk                                                            \
1450
    tcg_gen_qemu_ld32s (cpu_##reg, REG(B11_8), ctx->memidx);        \
1451
    tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);                \
1452
    return;                                                        \
1453
  case stnum:                                                        \
1454
    prechk                                                            \
1455
    tcg_gen_mov_i32 (REG(B11_8), cpu_##reg);                        \
1456
    return;                                                        \
1457
  case stpnum:                                                        \
1458
    prechk                                                            \
1459
    {                                                                \
1460
        TCGv addr = tcg_temp_new();                        \
1461
        tcg_gen_subi_i32(addr, REG(B11_8), 4);                        \
1462
        tcg_gen_qemu_st32 (cpu_##reg, addr, ctx->memidx);        \
1463
        tcg_temp_free(addr);                                        \
1464
        tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);                \
1465
    }                                                                \
1466
    return;
1467
        LDST(gbr,  0x401e, 0x4017, 0x0012, 0x4013, {})
1468
        LDST(vbr,  0x402e, 0x4027, 0x0022, 0x4023, CHECK_PRIVILEGED)
1469
        LDST(ssr,  0x403e, 0x4037, 0x0032, 0x4033, CHECK_PRIVILEGED)
1470
        LDST(spc,  0x404e, 0x4047, 0x0042, 0x4043, CHECK_PRIVILEGED)
1471
        LDST(dbr,  0x40fa, 0x40f6, 0x00fa, 0x40f2, CHECK_PRIVILEGED)
1472
        LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002, {})
1473
        LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012, {})
1474
        LDST(pr,   0x402a, 0x4026, 0x002a, 0x4022, {})
1475
        LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052, {CHECK_FPU_ENABLED})
1476
    case 0x406a:                /* lds Rm,FPSCR */
1477
        CHECK_FPU_ENABLED
1478
        gen_helper_ld_fpscr(REG(B11_8));
1479
        ctx->bstate = BS_STOP;
1480
        return;
1481
    case 0x4066:                /* lds.l @Rm+,FPSCR */
1482
        CHECK_FPU_ENABLED
1483
        {
1484
            TCGv addr = tcg_temp_new();
1485
            tcg_gen_qemu_ld32s(addr, REG(B11_8), ctx->memidx);
1486
            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1487
            gen_helper_ld_fpscr(addr);
1488
            tcg_temp_free(addr);
1489
            ctx->bstate = BS_STOP;
1490
        }
1491
        return;
1492
    case 0x006a:                /* sts FPSCR,Rn */
1493
        CHECK_FPU_ENABLED
1494
        tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);
1495
        return;
1496
    case 0x4062:                /* sts FPSCR,@-Rn */
1497
        CHECK_FPU_ENABLED
1498
        {
1499
            TCGv addr, val;
1500
            val = tcg_temp_new();
1501
            tcg_gen_andi_i32(val, cpu_fpscr, 0x003fffff);
1502
            addr = tcg_temp_new();
1503
            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1504
            tcg_gen_qemu_st32(val, addr, ctx->memidx);
1505
            tcg_temp_free(addr);
1506
            tcg_temp_free(val);
1507
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1508
        }
1509
        return;
1510
    case 0x00c3:                /* movca.l R0,@Rm */
1511
        tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx);
1512
        return;
1513
    case 0x40a9:
1514
        /* MOVUA.L @Rm,R0 (Rm) -> R0
1515
           Load non-boundary-aligned data */
1516
        tcg_gen_qemu_ld32u(REG(0), REG(B11_8), ctx->memidx);
1517
        return;
1518
    case 0x40e9:
1519
        /* MOVUA.L @Rm+,R0   (Rm) -> R0, Rm + 4 -> Rm
1520
           Load non-boundary-aligned data */
1521
        tcg_gen_qemu_ld32u(REG(0), REG(B11_8), ctx->memidx);
1522
        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1523
        return;
1524
    case 0x0029:                /* movt Rn */
1525
        tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T);
1526
        return;
1527
    case 0x0093:                /* ocbi @Rn */
1528
        {
1529
            TCGv dummy = tcg_temp_new();
1530
            tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1531
            tcg_temp_free(dummy);
1532
        }
1533
        return;
1534
    case 0x00a3:                /* ocbp @Rn */
1535
        {
1536
            TCGv dummy = tcg_temp_new();
1537
            tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1538
            tcg_temp_free(dummy);
1539
        }
1540
        return;
1541
    case 0x00b3:                /* ocbwb @Rn */
1542
        {
1543
            TCGv dummy = tcg_temp_new();
1544
            tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1545
            tcg_temp_free(dummy);
1546
        }
1547
        return;
1548
    case 0x0083:                /* pref @Rn */
1549
        return;
1550
    case 0x4024:                /* rotcl Rn */
1551
        {
1552
            TCGv tmp = tcg_temp_new();
1553
            tcg_gen_mov_i32(tmp, cpu_sr);
1554
            gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1555
            tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1556
            gen_copy_bit_i32(REG(B11_8), 0, tmp, 0);
1557
            tcg_temp_free(tmp);
1558
        }
1559
        return;
1560
    case 0x4025:                /* rotcr Rn */
1561
        {
1562
            TCGv tmp = tcg_temp_new();
1563
            tcg_gen_mov_i32(tmp, cpu_sr);
1564
            gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1565
            tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1566
            gen_copy_bit_i32(REG(B11_8), 31, tmp, 0);
1567
            tcg_temp_free(tmp);
1568
        }
1569
        return;
1570
    case 0x4004:                /* rotl Rn */
1571
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1572
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1573
        gen_copy_bit_i32(REG(B11_8), 0, cpu_sr, 0);
1574
        return;
1575
    case 0x4005:                /* rotr Rn */
1576
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1577
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1578
        gen_copy_bit_i32(REG(B11_8), 31, cpu_sr, 0);
1579
        return;
1580
    case 0x4000:                /* shll Rn */
1581
    case 0x4020:                /* shal Rn */
1582
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1583
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1584
        return;
1585
    case 0x4021:                /* shar Rn */
1586
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1587
        tcg_gen_sari_i32(REG(B11_8), REG(B11_8), 1);
1588
        return;
1589
    case 0x4001:                /* shlr Rn */
1590
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1591
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1592
        return;
1593
    case 0x4008:                /* shll2 Rn */
1594
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 2);
1595
        return;
1596
    case 0x4018:                /* shll8 Rn */
1597
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 8);
1598
        return;
1599
    case 0x4028:                /* shll16 Rn */
1600
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 16);
1601
        return;
1602
    case 0x4009:                /* shlr2 Rn */
1603
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 2);
1604
        return;
1605
    case 0x4019:                /* shlr8 Rn */
1606
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 8);
1607
        return;
1608
    case 0x4029:                /* shlr16 Rn */
1609
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16);
1610
        return;
1611
    case 0x401b:                /* tas.b @Rn */
1612
        {
1613
            TCGv addr, val;
1614
            addr = tcg_temp_local_new(TCG_TYPE_I32);
1615
            tcg_gen_mov_i32(addr, REG(B11_8));
1616
            val = tcg_temp_local_new(TCG_TYPE_I32);
1617
            tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1618
            gen_cmp_imm(TCG_COND_EQ, val, 0);
1619
            tcg_gen_ori_i32(val, val, 0x80);
1620
            tcg_gen_qemu_st8(val, addr, ctx->memidx);
1621
            tcg_temp_free(val);
1622
            tcg_temp_free(addr);
1623
        }
1624
        return;
1625
    case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1626
        {
1627
            tcg_gen_mov_i32(cpu_fregs[FREG(B11_8)], cpu_fpul);
1628
        }
1629
        return;
1630
    case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1631
        {
1632
            tcg_gen_mov_i32(cpu_fpul, cpu_fregs[FREG(B11_8)]);
1633
        }
1634
        return;
1635
    case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1636
        if (ctx->fpscr & FPSCR_PR) {
1637
            TCGv_i64 fp;
1638
            if (ctx->opcode & 0x0100)
1639
                break; /* illegal instruction */
1640
            fp = tcg_temp_new_i64();
1641
            gen_helper_float_DT(fp, cpu_fpul);
1642
            gen_store_fpr64(fp, DREG(B11_8));
1643
            tcg_temp_free_i64(fp);
1644
        }
1645
        else {
1646
            gen_helper_float_FT(cpu_fregs[FREG(B11_8)], cpu_fpul);
1647
        }
1648
        return;
1649
    case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1650
        if (ctx->fpscr & FPSCR_PR) {
1651
            TCGv_i64 fp;
1652
            if (ctx->opcode & 0x0100)
1653
                break; /* illegal instruction */
1654
            fp = tcg_temp_new_i64();
1655
            gen_load_fpr64(fp, DREG(B11_8));
1656
            gen_helper_ftrc_DT(cpu_fpul, fp);
1657
            tcg_temp_free_i64(fp);
1658
        }
1659
        else {
1660
            gen_helper_ftrc_FT(cpu_fpul, cpu_fregs[FREG(B11_8)]);
1661
        }
1662
        return;
1663
    case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1664
        {
1665
            gen_helper_fneg_T(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
1666
        }
1667
        return;
1668
    case 0xf05d: /* fabs FRn/DRn */
1669
        if (ctx->fpscr & FPSCR_PR) {
1670
            if (ctx->opcode & 0x0100)
1671
                break; /* illegal instruction */
1672
            TCGv_i64 fp = tcg_temp_new_i64();
1673
            gen_load_fpr64(fp, DREG(B11_8));
1674
            gen_helper_fabs_DT(fp, fp);
1675
            gen_store_fpr64(fp, DREG(B11_8));
1676
            tcg_temp_free_i64(fp);
1677
        } else {
1678
            gen_helper_fabs_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
1679
        }
1680
        return;
1681
    case 0xf06d: /* fsqrt FRn */
1682
        if (ctx->fpscr & FPSCR_PR) {
1683
            if (ctx->opcode & 0x0100)
1684
                break; /* illegal instruction */
1685
            TCGv_i64 fp = tcg_temp_new_i64();
1686
            gen_load_fpr64(fp, DREG(B11_8));
1687
            gen_helper_fsqrt_DT(fp, fp);
1688
            gen_store_fpr64(fp, DREG(B11_8));
1689
            tcg_temp_free_i64(fp);
1690
        } else {
1691
            gen_helper_fsqrt_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
1692
        }
1693
        return;
1694
    case 0xf07d: /* fsrra FRn */
1695
        break;
1696
    case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1697
        if (!(ctx->fpscr & FPSCR_PR)) {
1698
            tcg_gen_movi_i32(cpu_fregs[FREG(B11_8)], 0);
1699
        }
1700
        return;
1701
    case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1702
        if (!(ctx->fpscr & FPSCR_PR)) {
1703
            tcg_gen_movi_i32(cpu_fregs[FREG(B11_8)], 0x3f800000);
1704
        }
1705
        return;
1706
    case 0xf0ad: /* fcnvsd FPUL,DRn */
1707
        {
1708
            TCGv_i64 fp = tcg_temp_new_i64();
1709
            gen_helper_fcnvsd_FT_DT(fp, cpu_fpul);
1710
            gen_store_fpr64(fp, DREG(B11_8));
1711
            tcg_temp_free_i64(fp);
1712
        }
1713
        return;
1714
    case 0xf0bd: /* fcnvds DRn,FPUL */
1715
        {
1716
            TCGv_i64 fp = tcg_temp_new_i64();
1717
            gen_load_fpr64(fp, DREG(B11_8));
1718
            gen_helper_fcnvds_DT_FT(cpu_fpul, fp);
1719
            tcg_temp_free_i64(fp);
1720
        }
1721
        return;
1722
    }
1723

    
1724
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1725
            ctx->opcode, ctx->pc);
1726
    gen_helper_raise_illegal_instruction();
1727
    ctx->bstate = BS_EXCP;
1728
}
1729

    
1730
static void decode_opc(DisasContext * ctx)
1731
{
1732
    uint32_t old_flags = ctx->flags;
1733

    
1734
    _decode_opc(ctx);
1735

    
1736
    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1737
        if (ctx->flags & DELAY_SLOT_CLEARME) {
1738
            gen_store_flags(0);
1739
        } else {
1740
            /* go out of the delay slot */
1741
            uint32_t new_flags = ctx->flags;
1742
            new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1743
            gen_store_flags(new_flags);
1744
        }
1745
        ctx->flags = 0;
1746
        ctx->bstate = BS_BRANCH;
1747
        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1748
            gen_delayed_conditional_jump(ctx);
1749
        } else if (old_flags & DELAY_SLOT) {
1750
            gen_jump(ctx);
1751
        }
1752

    
1753
    }
1754

    
1755
    /* go into a delay slot */
1756
    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1757
        gen_store_flags(ctx->flags);
1758
}
1759

    
1760
static inline void
1761
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1762
                               int search_pc)
1763
{
1764
    DisasContext ctx;
1765
    target_ulong pc_start;
1766
    static uint16_t *gen_opc_end;
1767
    CPUBreakpoint *bp;
1768
    int i, ii;
1769
    int num_insns;
1770
    int max_insns;
1771

    
1772
    pc_start = tb->pc;
1773
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1774
    ctx.pc = pc_start;
1775
    ctx.flags = (uint32_t)tb->flags;
1776
    ctx.bstate = BS_NONE;
1777
    ctx.sr = env->sr;
1778
    ctx.fpscr = env->fpscr;
1779
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1780
    /* We don't know if the delayed pc came from a dynamic or static branch,
1781
       so assume it is a dynamic branch.  */
1782
    ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1783
    ctx.tb = tb;
1784
    ctx.singlestep_enabled = env->singlestep_enabled;
1785

    
1786
#ifdef DEBUG_DISAS
1787
    if (loglevel & CPU_LOG_TB_CPU) {
1788
        fprintf(logfile,
1789
                "------------------------------------------------\n");
1790
        cpu_dump_state(env, logfile, fprintf, 0);
1791
    }
1792
#endif
1793

    
1794
    ii = -1;
1795
    num_insns = 0;
1796
    max_insns = tb->cflags & CF_COUNT_MASK;
1797
    if (max_insns == 0)
1798
        max_insns = CF_COUNT_MASK;
1799
    gen_icount_start();
1800
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1801
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
1802
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
1803
                if (ctx.pc == bp->pc) {
1804
                    /* We have hit a breakpoint - make sure PC is up-to-date */
1805
                    tcg_gen_movi_i32(cpu_pc, ctx.pc);
1806
                    gen_helper_debug();
1807
                    ctx.bstate = BS_EXCP;
1808
                    break;
1809
                }
1810
            }
1811
        }
1812
        if (search_pc) {
1813
            i = gen_opc_ptr - gen_opc_buf;
1814
            if (ii < i) {
1815
                ii++;
1816
                while (ii < i)
1817
                    gen_opc_instr_start[ii++] = 0;
1818
            }
1819
            gen_opc_pc[ii] = ctx.pc;
1820
            gen_opc_hflags[ii] = ctx.flags;
1821
            gen_opc_instr_start[ii] = 1;
1822
            gen_opc_icount[ii] = num_insns;
1823
        }
1824
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1825
            gen_io_start();
1826
#if 0
1827
        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1828
        fflush(stderr);
1829
#endif
1830
        ctx.opcode = lduw_code(ctx.pc);
1831
        decode_opc(&ctx);
1832
        num_insns++;
1833
        ctx.pc += 2;
1834
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1835
            break;
1836
        if (env->singlestep_enabled)
1837
            break;
1838
        if (num_insns >= max_insns)
1839
            break;
1840
#ifdef SH4_SINGLE_STEP
1841
        break;
1842
#endif
1843
    }
1844
    if (tb->cflags & CF_LAST_IO)
1845
        gen_io_end();
1846
    if (env->singlestep_enabled) {
1847
        tcg_gen_movi_i32(cpu_pc, ctx.pc);
1848
        gen_helper_debug();
1849
    } else {
1850
        switch (ctx.bstate) {
1851
        case BS_STOP:
1852
            /* gen_op_interrupt_restart(); */
1853
            /* fall through */
1854
        case BS_NONE:
1855
            if (ctx.flags) {
1856
                gen_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1857
            }
1858
            gen_goto_tb(&ctx, 0, ctx.pc);
1859
            break;
1860
        case BS_EXCP:
1861
            /* gen_op_interrupt_restart(); */
1862
            tcg_gen_exit_tb(0);
1863
            break;
1864
        case BS_BRANCH:
1865
        default:
1866
            break;
1867
        }
1868
    }
1869

    
1870
    gen_icount_end(tb, num_insns);
1871
    *gen_opc_ptr = INDEX_op_end;
1872
    if (search_pc) {
1873
        i = gen_opc_ptr - gen_opc_buf;
1874
        ii++;
1875
        while (ii <= i)
1876
            gen_opc_instr_start[ii++] = 0;
1877
    } else {
1878
        tb->size = ctx.pc - pc_start;
1879
        tb->icount = num_insns;
1880
    }
1881

    
1882
#ifdef DEBUG_DISAS
1883
#ifdef SH4_DEBUG_DISAS
1884
    if (loglevel & CPU_LOG_TB_IN_ASM)
1885
        fprintf(logfile, "\n");
1886
#endif
1887
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1888
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1889
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1890
        fprintf(logfile, "\n");
1891
    }
1892
#endif
1893
}
1894

    
1895
void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1896
{
1897
    gen_intermediate_code_internal(env, tb, 0);
1898
}
1899

    
1900
void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1901
{
1902
    gen_intermediate_code_internal(env, tb, 1);
1903
}
1904

    
1905
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1906
                unsigned long searched_pc, int pc_pos, void *puc)
1907
{
1908
    env->pc = gen_opc_pc[pc_pos];
1909
    env->flags = gen_opc_hflags[pc_pos];
1910
}