Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ 7478757e

History | View | Annotate | Download (56.2 kB)

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

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

    
31
#include "cpu.h"
32
#include "exec-all.h"
33
#include "disas.h"
34
#include "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, cpu_flags;
66

    
67
/* internal register indexes */
68
static TCGv cpu_flags, cpu_delayed_pc;
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

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

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

    
121
    cpu_flags = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
122
                                   offsetof(CPUState, flags), "_flags_");
123
    cpu_delayed_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
124
                                        offsetof(CPUState, delayed_pc),
125
                                        "_delayed_pc_");
126

    
127
    /* register helpers */
128
#undef DEF_HELPER
129
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
130
#include "helper.h"
131

    
132
    done_init = 1;
133
}
134

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

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

    
179
typedef struct {
180
    const unsigned char *name;
181
    int id;
182
    uint32_t pvr;
183
    uint32_t prr;
184
    uint32_t cvr;
185
} sh4_def_t;
186

    
187
static sh4_def_t sh4_defs[] = {
188
    {
189
        .name = "SH7750R",
190
        .id = SH_CPU_SH7750R,
191
        .pvr = 0x00050000,
192
        .prr = 0x00000100,
193
        .cvr = 0x00110000,
194
    }, {
195
        .name = "SH7751R",
196
        .id = SH_CPU_SH7751R,
197
        .pvr = 0x04050005,
198
        .prr = 0x00000113,
199
        .cvr = 0x00110000,        /* Neutered caches, should be 0x20480000 */
200
    },
201
};
202

    
203
static const sh4_def_t *cpu_sh4_find_by_name(const unsigned char *name)
204
{
205
    int i;
206

    
207
    if (strcasecmp(name, "any") == 0)
208
        return &sh4_defs[0];
209

    
210
    for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++)
211
        if (strcasecmp(name, sh4_defs[i].name) == 0)
212
            return &sh4_defs[i];
213

    
214
    return NULL;
215
}
216

    
217
void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
218
{
219
    int i;
220

    
221
    for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++)
222
        (*cpu_fprintf)(f, "%s\n", sh4_defs[i].name);
223
}
224

    
225
static int cpu_sh4_register(CPUSH4State *env, const sh4_def_t *def)
226
{
227
    env->pvr = def->pvr;
228
    env->prr = def->prr;
229
    env->cvr = def->cvr;
230
    env->id = def->id;
231
}
232

    
233
CPUSH4State *cpu_sh4_init(const char *cpu_model)
234
{
235
    CPUSH4State *env;
236
    const sh4_def_t *def;
237

    
238
    def = cpu_sh4_find_by_name(cpu_model);
239
    if (!def)
240
        return NULL;
241
    env = qemu_mallocz(sizeof(CPUSH4State));
242
    if (!env)
243
        return NULL;
244
    cpu_exec_init(env);
245
    sh4_translate_init();
246
    env->cpu_model_str = cpu_model;
247
    cpu_sh4_reset(env);
248
    cpu_sh4_register(env, def);
249
    tlb_flush(env, 1);
250
    return env;
251
}
252

    
253
static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
254
{
255
    TranslationBlock *tb;
256
    tb = ctx->tb;
257

    
258
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
259
        !ctx->singlestep_enabled) {
260
        /* Use a direct jump if in same page and singlestep not enabled */
261
        tcg_gen_goto_tb(n);
262
        tcg_gen_movi_i32(cpu_pc, dest);
263
        tcg_gen_exit_tb((long) tb + n);
264
    } else {
265
        tcg_gen_movi_i32(cpu_pc, dest);
266
        if (ctx->singlestep_enabled)
267
            tcg_gen_helper_0_0(helper_debug);
268
        tcg_gen_exit_tb(0);
269
    }
270
}
271

    
272
static void gen_jump(DisasContext * ctx)
273
{
274
    if (ctx->delayed_pc == (uint32_t) - 1) {
275
        /* Target is not statically known, it comes necessarily from a
276
           delayed jump as immediate jump are conditinal jumps */
277
        tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
278
        if (ctx->singlestep_enabled)
279
            tcg_gen_helper_0_0(helper_debug);
280
        tcg_gen_exit_tb(0);
281
    } else {
282
        gen_goto_tb(ctx, 0, ctx->delayed_pc);
283
    }
284
}
285

    
286
static inline void gen_branch_slot(uint32_t delayed_pc, int t)
287
{
288
    TCGv sr;
289
    int label = gen_new_label();
290
    tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
291
    sr = tcg_temp_new(TCG_TYPE_I32);
292
    tcg_gen_andi_i32(sr, cpu_sr, SR_T);
293
    tcg_gen_brcondi_i32(TCG_COND_NE, sr, t ? SR_T : 0, label);
294
    tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
295
    gen_set_label(label);
296
}
297

    
298
/* Immediate conditional jump (bt or bf) */
299
static void gen_conditional_jump(DisasContext * ctx,
300
                                 target_ulong ift, target_ulong ifnott)
301
{
302
    int l1;
303
    TCGv sr;
304

    
305
    l1 = gen_new_label();
306
    sr = tcg_temp_new(TCG_TYPE_I32);
307
    tcg_gen_andi_i32(sr, cpu_sr, SR_T);
308
    tcg_gen_brcondi_i32(TCG_COND_EQ, sr, SR_T, l1);
309
    gen_goto_tb(ctx, 0, ifnott);
310
    gen_set_label(l1);
311
    gen_goto_tb(ctx, 1, ift);
312
}
313

    
314
/* Delayed conditional jump (bt or bf) */
315
static void gen_delayed_conditional_jump(DisasContext * ctx)
316
{
317
    int l1;
318
    TCGv ds;
319

    
320
    l1 = gen_new_label();
321
    ds = tcg_temp_new(TCG_TYPE_I32);
322
    tcg_gen_andi_i32(ds, cpu_flags, DELAY_SLOT_TRUE);
323
    tcg_gen_brcondi_i32(TCG_COND_EQ, ds, DELAY_SLOT_TRUE, l1);
324
    gen_goto_tb(ctx, 1, ctx->pc + 2);
325
    gen_set_label(l1);
326
    tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
327
    gen_jump(ctx);
328
}
329

    
330
static inline void gen_set_t(void)
331
{
332
    tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
333
}
334

    
335
static inline void gen_clr_t(void)
336
{
337
    tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
338
}
339

    
340
static inline void gen_cmp(int cond, TCGv t0, TCGv t1)
341
{
342
    int label1 = gen_new_label();
343
    int label2 = gen_new_label();
344
    tcg_gen_brcond_i32(cond, t1, t0, label1);
345
    gen_clr_t();
346
    tcg_gen_br(label2);
347
    gen_set_label(label1);
348
    gen_set_t();
349
    gen_set_label(label2);
350
}
351

    
352
static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
353
{
354
    int label1 = gen_new_label();
355
    int label2 = gen_new_label();
356
    tcg_gen_brcondi_i32(cond, t0, imm, label1);
357
    gen_clr_t();
358
    tcg_gen_br(label2);
359
    gen_set_label(label1);
360
    gen_set_t();
361
    gen_set_label(label2);
362
}
363

    
364
static inline void gen_store_flags(uint32_t flags)
365
{
366
    tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
367
    tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
368
}
369

    
370
static inline void gen_copy_bit_i32(TCGv t0, int p0, TCGv t1, int p1)
371
{
372
    TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
373

    
374
    p0 &= 0x1f;
375
    p1 &= 0x1f;
376

    
377
    tcg_gen_andi_i32(tmp, t1, (1 << p1));
378
    tcg_gen_andi_i32(t0, t0, ~(1 << p0));
379
    if (p0 < p1)
380
        tcg_gen_shri_i32(tmp, tmp, p1 - p0);
381
    else if (p0 > p1)
382
        tcg_gen_shli_i32(tmp, tmp, p0 - p1);
383
    tcg_gen_or_i32(t0, t0, tmp);
384

    
385
    tcg_temp_free(tmp);
386
}
387

    
388

    
389
static inline void gen_load_fpr32(TCGv t, int reg)
390
{
391
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
392
}
393

    
394
static inline void gen_load_fpr64(TCGv t, int reg)
395
{
396
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I32);
397
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
398

    
399
    tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg]));
400
    tcg_gen_extu_i32_i64(t, tmp1);
401
    tcg_gen_shli_i64(t, t, 32);
402
    tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg + 1]));
403
    tcg_gen_extu_i32_i64(tmp2, tmp1);
404
    tcg_temp_free(tmp1);
405
    tcg_gen_or_i64(t, t, tmp2);
406
    tcg_temp_free(tmp2);
407
}
408

    
409
static inline void gen_store_fpr32(TCGv t, int reg)
410
{
411
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
412
}
413

    
414
static inline void gen_store_fpr64 (TCGv t, int reg)
415
{
416
    TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
417

    
418
    tcg_gen_trunc_i64_i32(tmp, t);
419
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg + 1]));
420
    tcg_gen_shri_i64(t, t, 32);
421
    tcg_gen_trunc_i64_i32(tmp, t);
422
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg]));
423
    tcg_temp_free(tmp);
424
}
425

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

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

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

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

    
447
#define CHECK_NOT_DELAY_SLOT \
448
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
449
  {tcg_gen_helper_0_0(helper_raise_slot_illegal_instruction); ctx->bstate = BS_EXCP; \
450
   return;}
451

    
452
void _decode_opc(DisasContext * ctx)
453
{
454
#if 0
455
    fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
456
#endif
457
    switch (ctx->opcode) {
458
    case 0x0019:                /* div0u */
459
        tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
460
        return;
461
    case 0x000b:                /* rts */
462
        CHECK_NOT_DELAY_SLOT
463
        tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
464
        ctx->flags |= DELAY_SLOT;
465
        ctx->delayed_pc = (uint32_t) - 1;
466
        return;
467
    case 0x0028:                /* clrmac */
468
        tcg_gen_movi_i32(cpu_mach, 0);
469
        tcg_gen_movi_i32(cpu_macl, 0);
470
        return;
471
    case 0x0048:                /* clrs */
472
        tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S);
473
        return;
474
    case 0x0008:                /* clrt */
475
        gen_clr_t();
476
        return;
477
    case 0x0038:                /* ldtlb */
478
#if defined(CONFIG_USER_ONLY)
479
        assert(0);                /* XXXXX */
480
#else
481
        tcg_gen_helper_0_0(helper_ldtlb);
482
#endif
483
        return;
484
    case 0x002b:                /* rte */
485
        CHECK_NOT_DELAY_SLOT
486
        tcg_gen_mov_i32(cpu_sr, cpu_ssr);
487
        tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
488
        ctx->flags |= DELAY_SLOT;
489
        ctx->delayed_pc = (uint32_t) - 1;
490
        return;
491
    case 0x0058:                /* sets */
492
        tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S);
493
        return;
494
    case 0x0018:                /* sett */
495
        gen_set_t();
496
        return;
497
    case 0xfbfd:                /* frchg */
498
        tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
499
        ctx->bstate = BS_STOP;
500
        return;
501
    case 0xf3fd:                /* fschg */
502
        tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
503
        ctx->bstate = BS_STOP;
504
        return;
505
    case 0x0009:                /* nop */
506
        return;
507
    case 0x001b:                /* sleep */
508
        if (ctx->memidx) {
509
                tcg_gen_helper_0_1(helper_sleep, tcg_const_i32(ctx->pc + 2));
510
        } else {
511
                tcg_gen_helper_0_0(helper_raise_illegal_instruction);
512
                ctx->bstate = BS_EXCP;
513
        }
514
        return;
515
    }
516

    
517
    switch (ctx->opcode & 0xf000) {
518
    case 0x1000:                /* mov.l Rm,@(disp,Rn) */
519
        {
520
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
521
            tcg_gen_addi_i32(addr, REG(B11_8), B3_0 * 4);
522
            tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
523
            tcg_temp_free(addr);
524
        }
525
        return;
526
    case 0x5000:                /* mov.l @(disp,Rm),Rn */
527
        {
528
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
529
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 4);
530
            tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
531
            tcg_temp_free(addr);
532
        }
533
        return;
534
    case 0xe000:                /* mov #imm,Rn */
535
        tcg_gen_movi_i32(REG(B11_8), B7_0s);
536
        return;
537
    case 0x9000:                /* mov.w @(disp,PC),Rn */
538
        {
539
            TCGv addr = tcg_const_i32(ctx->pc + 4 + B7_0 * 2);
540
            tcg_gen_qemu_ld16s(REG(B11_8), addr, ctx->memidx);
541
            tcg_temp_free(addr);
542
        }
543
        return;
544
    case 0xd000:                /* mov.l @(disp,PC),Rn */
545
        {
546
            TCGv addr = tcg_const_i32((ctx->pc + 4 + B7_0 * 4) & ~3);
547
            tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
548
            tcg_temp_free(addr);
549
        }
550
        return;
551
    case 0x7000:                /* add #imm,Rn */
552
        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);
553
        return;
554
    case 0xa000:                /* bra disp */
555
        CHECK_NOT_DELAY_SLOT
556
        ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
557
        tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
558
        ctx->flags |= DELAY_SLOT;
559
        return;
560
    case 0xb000:                /* bsr disp */
561
        CHECK_NOT_DELAY_SLOT
562
        tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
563
        ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
564
        tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
565
        ctx->flags |= DELAY_SLOT;
566
        return;
567
    }
568

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

    
791
            tcg_gen_ext_i32_i64(tmp1, REG(B7_4));
792
            tcg_gen_ext_i32_i64(tmp2, REG(B11_8));
793
            tcg_gen_mul_i64(tmp1, tmp1, tmp2);
794
            tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
795
            tcg_gen_shri_i64(tmp1, tmp1, 32);
796
            tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
797

    
798
            tcg_temp_free(tmp2);
799
            tcg_temp_free(tmp1);
800
        }
801
        return;
802
    case 0x3005:                /* dmulu.l Rm,Rn */
803
        {
804
            TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
805
            TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
806

    
807
            tcg_gen_extu_i32_i64(tmp1, REG(B7_4));
808
            tcg_gen_extu_i32_i64(tmp2, REG(B11_8));
809
            tcg_gen_mul_i64(tmp1, tmp1, tmp2);
810
            tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
811
            tcg_gen_shri_i64(tmp1, tmp1, 32);
812
            tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
813

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

    
1098
            if (ctx->fpscr & FPSCR_PR) {
1099
                if (ctx->opcode & 0x0110)
1100
                    break; /* illegal instruction */
1101
                fp0 = tcg_temp_new(TCG_TYPE_I64);
1102
                fp1 = tcg_temp_new(TCG_TYPE_I64);
1103
                gen_load_fpr64(fp0, DREG(B11_8));
1104
                gen_load_fpr64(fp1, DREG(B7_4));
1105
            }
1106
            else {
1107
                fp0 = tcg_temp_new(TCG_TYPE_I32);
1108
                fp1 = tcg_temp_new(TCG_TYPE_I32);
1109
                gen_load_fpr32(fp0, FREG(B11_8));
1110
                gen_load_fpr32(fp1, FREG(B7_4));
1111
            }
1112

    
1113
            switch (ctx->opcode & 0xf00f) {
1114
            case 0xf000:                /* fadd Rm,Rn */
1115
                if (ctx->fpscr & FPSCR_PR)
1116
                    tcg_gen_helper_1_2(helper_fadd_DT, fp0, fp0, fp1);
1117
                else
1118
                    tcg_gen_helper_1_2(helper_fadd_FT, fp0, fp0, fp1);
1119
                break;
1120
            case 0xf001:                /* fsub Rm,Rn */
1121
                if (ctx->fpscr & FPSCR_PR)
1122
                    tcg_gen_helper_1_2(helper_fsub_DT, fp0, fp0, fp1);
1123
                else
1124
                    tcg_gen_helper_1_2(helper_fsub_FT, fp0, fp0, fp1);
1125
                break;
1126
            case 0xf002:                /* fmul Rm,Rn */
1127
                if (ctx->fpscr & FPSCR_PR)
1128
                    tcg_gen_helper_1_2(helper_fmul_DT, fp0, fp0, fp1);
1129
                else
1130
                    tcg_gen_helper_1_2(helper_fmul_FT, fp0, fp0, fp1);
1131
                break;
1132
            case 0xf003:                /* fdiv Rm,Rn */
1133
                if (ctx->fpscr & FPSCR_PR)
1134
                    tcg_gen_helper_1_2(helper_fdiv_DT, fp0, fp0, fp1);
1135
                else
1136
                    tcg_gen_helper_1_2(helper_fdiv_FT, fp0, fp0, fp1);
1137
                break;
1138
            case 0xf004:                /* fcmp/eq Rm,Rn */
1139
                if (ctx->fpscr & FPSCR_PR)
1140
                    tcg_gen_helper_0_2(helper_fcmp_eq_DT, fp0, fp1);
1141
                else
1142
                    tcg_gen_helper_0_2(helper_fcmp_eq_FT, fp0, fp1);
1143
                return;
1144
            case 0xf005:                /* fcmp/gt Rm,Rn */
1145
                if (ctx->fpscr & FPSCR_PR)
1146
                    tcg_gen_helper_0_2(helper_fcmp_gt_DT, fp0, fp1);
1147
                else
1148
                    tcg_gen_helper_0_2(helper_fcmp_gt_FT, fp0, fp1);
1149
                return;
1150
            }
1151

    
1152
            if (ctx->fpscr & FPSCR_PR) {
1153
                gen_store_fpr64(fp0, DREG(B11_8));
1154
            }
1155
            else {
1156
                gen_store_fpr32(fp0, FREG(B11_8));
1157
            }
1158
            tcg_temp_free(fp1);
1159
            tcg_temp_free(fp0);
1160
        }
1161
        return;
1162
    }
1163

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

    
1352
    switch (ctx->opcode & 0xf08f) {
1353
    case 0x408e:                /* ldc Rm,Rn_BANK */
1354
        tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
1355
        return;
1356
    case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
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
        tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
1362
        return;
1363
    case 0x4083:                /* stc.l Rm_BANK,@-Rn */
1364
        {
1365
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1366
            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1367
            tcg_gen_qemu_st32(ALTREG(B6_4), addr, ctx->memidx);
1368
            tcg_temp_free(addr);
1369
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1370
        }
1371
        return;
1372
    }
1373

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

    
1729
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1730
            ctx->opcode, ctx->pc);
1731
    tcg_gen_helper_0_0(helper_raise_illegal_instruction);
1732
    ctx->bstate = BS_EXCP;
1733
}
1734

    
1735
void decode_opc(DisasContext * ctx)
1736
{
1737
    uint32_t old_flags = ctx->flags;
1738

    
1739
    _decode_opc(ctx);
1740

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

    
1758
    }
1759

    
1760
    /* go into a delay slot */
1761
    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1762
        gen_store_flags(ctx->flags);
1763
}
1764

    
1765
static inline void
1766
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1767
                               int search_pc)
1768
{
1769
    DisasContext ctx;
1770
    target_ulong pc_start;
1771
    static uint16_t *gen_opc_end;
1772
    int i, ii;
1773
    int num_insns;
1774
    int max_insns;
1775

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

    
1790
#ifdef DEBUG_DISAS
1791
    if (loglevel & CPU_LOG_TB_CPU) {
1792
        fprintf(logfile,
1793
                "------------------------------------------------\n");
1794
        cpu_dump_state(env, logfile, fprintf, 0);
1795
    }
1796
#endif
1797

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

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

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

    
1898
void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1899
{
1900
    gen_intermediate_code_internal(env, tb, 0);
1901
}
1902

    
1903
void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1904
{
1905
    gen_intermediate_code_internal(env, tb, 1);
1906
}
1907

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