Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ 0fd3ca30

History | View | Annotate | Download (56.1 kB)

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

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

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

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

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

    
60
/* global register indexes */
61
static TCGv cpu_env;
62
static TCGv cpu_gregs[24];
63
static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
64
static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
65
static TCGv cpu_pr, cpu_fpscr, cpu_fpul, 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
    cpu_sh4_reset(env);
247
    cpu_sh4_register(env, def);
248
    tlb_flush(env, 1);
249
    return env;
250
}
251

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
384
    tcg_temp_free(tmp);
385
}
386

    
387

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1738
    _decode_opc(ctx);
1739

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

    
1757
    }
1758

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

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

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

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

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

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

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

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

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

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