Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ 7fdf924f

History | View | Annotate | Download (55.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
/* dyngen register indexes */
71
static TCGv cpu_T[2];
72

    
73
#include "gen-icount.h"
74

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

    
87
    if (done_init)
88
        return;
89

    
90
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
91
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
92
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
93

    
94
    for (i = 0; i < 24; i++)
95
        cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
96
                                          offsetof(CPUState, gregs[i]),
97
                                          gregnames[i]);
98

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

    
126
    cpu_flags = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
127
                                   offsetof(CPUState, flags), "_flags_");
128
    cpu_delayed_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
129
                                        offsetof(CPUState, delayed_pc),
130
                                        "_delayed_pc_");
131

    
132
    /* register helpers */
133
#undef DEF_HELPER
134
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
135
#include "helper.h"
136

    
137
    done_init = 1;
138
}
139

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

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

    
184
CPUSH4State *cpu_sh4_init(const char *cpu_model)
185
{
186
    CPUSH4State *env;
187

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

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

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

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

    
231
static inline void gen_branch_slot(uint32_t delayed_pc, int t)
232
{
233
    TCGv sr;
234
    int label = gen_new_label();
235
    tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
236
    sr = tcg_temp_new(TCG_TYPE_I32);
237
    tcg_gen_andi_i32(sr, cpu_sr, SR_T);
238
    tcg_gen_brcondi_i32(TCG_COND_NE, sr, t ? SR_T : 0, label);
239
    tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
240
    gen_set_label(label);
241
}
242

    
243
/* Immediate conditional jump (bt or bf) */
244
static void gen_conditional_jump(DisasContext * ctx,
245
                                 target_ulong ift, target_ulong ifnott)
246
{
247
    int l1;
248
    TCGv sr;
249

    
250
    l1 = gen_new_label();
251
    sr = tcg_temp_new(TCG_TYPE_I32);
252
    tcg_gen_andi_i32(sr, cpu_sr, SR_T);
253
    tcg_gen_brcondi_i32(TCG_COND_EQ, sr, SR_T, l1);
254
    gen_goto_tb(ctx, 0, ifnott);
255
    gen_set_label(l1);
256
    gen_goto_tb(ctx, 1, ift);
257
}
258

    
259
/* Delayed conditional jump (bt or bf) */
260
static void gen_delayed_conditional_jump(DisasContext * ctx)
261
{
262
    int l1;
263
    TCGv ds;
264

    
265
    l1 = gen_new_label();
266
    ds = tcg_temp_new(TCG_TYPE_I32);
267
    tcg_gen_andi_i32(ds, cpu_flags, DELAY_SLOT_TRUE);
268
    tcg_gen_brcondi_i32(TCG_COND_EQ, ds, DELAY_SLOT_TRUE, l1);
269
    gen_goto_tb(ctx, 1, ctx->pc + 2);
270
    gen_set_label(l1);
271
    tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
272
    gen_jump(ctx);
273
}
274

    
275
static inline void gen_set_t(void)
276
{
277
    tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
278
}
279

    
280
static inline void gen_clr_t(void)
281
{
282
    tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
283
}
284

    
285
static inline void gen_cmp(int cond, TCGv t0, TCGv t1)
286
{
287
    int label1 = gen_new_label();
288
    int label2 = gen_new_label();
289
    tcg_gen_brcond_i32(cond, t1, t0, label1);
290
    gen_clr_t();
291
    tcg_gen_br(label2);
292
    gen_set_label(label1);
293
    gen_set_t();
294
    gen_set_label(label2);
295
}
296

    
297
static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
298
{
299
    int label1 = gen_new_label();
300
    int label2 = gen_new_label();
301
    tcg_gen_brcondi_i32(cond, t0, imm, label1);
302
    gen_clr_t();
303
    tcg_gen_br(label2);
304
    gen_set_label(label1);
305
    gen_set_t();
306
    gen_set_label(label2);
307
}
308

    
309
static inline void gen_store_flags(uint32_t flags)
310
{
311
    tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
312
    tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
313
}
314

    
315
static inline void gen_copy_bit_i32(TCGv t0, int p0, TCGv t1, int p1)
316
{
317
    TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
318

    
319
    p0 &= 0x1f;
320
    p1 &= 0x1f;
321

    
322
    tcg_gen_andi_i32(tmp, t1, (1 << p1));
323
    tcg_gen_andi_i32(t0, t0, ~(1 << p0));
324
    if (p0 < p1)
325
        tcg_gen_shri_i32(tmp, tmp, p1 - p0);
326
    else if (p0 > p1)
327
        tcg_gen_shli_i32(tmp, tmp, p0 - p1);
328
    tcg_gen_or_i32(t0, t0, tmp);
329

    
330
    tcg_temp_free(tmp);
331
}
332

    
333

    
334
static inline void gen_load_fpr32(TCGv t, int reg)
335
{
336
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
337
}
338

    
339
static inline void gen_load_fpr64(TCGv t, int reg)
340
{
341
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I32);
342
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
343

    
344
    tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg]));
345
    tcg_gen_extu_i32_i64(t, tmp1);
346
    tcg_gen_shli_i64(t, t, 32);
347
    tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg + 1]));
348
    tcg_gen_extu_i32_i64(tmp2, tmp1);
349
    tcg_temp_free(tmp1);
350
    tcg_gen_or_i64(t, t, tmp2);
351
    tcg_temp_free(tmp2);
352
}
353

    
354
static inline void gen_store_fpr32(TCGv t, int reg)
355
{
356
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
357
}
358

    
359
static inline void gen_store_fpr64 (TCGv t, int reg)
360
{
361
    TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
362

    
363
    tcg_gen_trunc_i64_i32(tmp, t);
364
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg + 1]));
365
    tcg_gen_shri_i64(t, t, 32);
366
    tcg_gen_trunc_i64_i32(tmp, t);
367
    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg]));
368
    tcg_temp_free(tmp);
369
}
370

    
371
#define B3_0 (ctx->opcode & 0xf)
372
#define B6_4 ((ctx->opcode >> 4) & 0x7)
373
#define B7_4 ((ctx->opcode >> 4) & 0xf)
374
#define B7_0 (ctx->opcode & 0xff)
375
#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
376
#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
377
  (ctx->opcode & 0xfff))
378
#define B11_8 ((ctx->opcode >> 8) & 0xf)
379
#define B15_12 ((ctx->opcode >> 12) & 0xf)
380

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

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

    
387
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
388
#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
389
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
390
#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
391

    
392
#define CHECK_NOT_DELAY_SLOT \
393
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
394
  {tcg_gen_helper_0_0(helper_raise_slot_illegal_instruction); ctx->bstate = BS_EXCP; \
395
   return;}
396

    
397
void _decode_opc(DisasContext * ctx)
398
{
399
#if 0
400
    fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
401
#endif
402
    switch (ctx->opcode) {
403
    case 0x0019:                /* div0u */
404
        tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
405
        return;
406
    case 0x000b:                /* rts */
407
        CHECK_NOT_DELAY_SLOT
408
        tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
409
        ctx->flags |= DELAY_SLOT;
410
        ctx->delayed_pc = (uint32_t) - 1;
411
        return;
412
    case 0x0028:                /* clrmac */
413
        tcg_gen_movi_i32(cpu_mach, 0);
414
        tcg_gen_movi_i32(cpu_macl, 0);
415
        return;
416
    case 0x0048:                /* clrs */
417
        tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S);
418
        return;
419
    case 0x0008:                /* clrt */
420
        gen_clr_t();
421
        return;
422
    case 0x0038:                /* ldtlb */
423
#if defined(CONFIG_USER_ONLY)
424
        assert(0);                /* XXXXX */
425
#else
426
        tcg_gen_helper_0_0(helper_ldtlb);
427
#endif
428
        return;
429
    case 0x002b:                /* rte */
430
        CHECK_NOT_DELAY_SLOT
431
        tcg_gen_mov_i32(cpu_sr, cpu_ssr);
432
        tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
433
        ctx->flags |= DELAY_SLOT;
434
        ctx->delayed_pc = (uint32_t) - 1;
435
        return;
436
    case 0x0058:                /* sets */
437
        tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S);
438
        return;
439
    case 0x0018:                /* sett */
440
        gen_set_t();
441
        return;
442
    case 0xfbfd:                /* frchg */
443
        tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
444
        ctx->bstate = BS_STOP;
445
        return;
446
    case 0xf3fd:                /* fschg */
447
        tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
448
        ctx->bstate = BS_STOP;
449
        return;
450
    case 0x0009:                /* nop */
451
        return;
452
    case 0x001b:                /* sleep */
453
        if (ctx->memidx) {
454
                tcg_gen_helper_0_0(helper_sleep);
455
        } else {
456
                tcg_gen_helper_0_0(helper_raise_illegal_instruction);
457
                ctx->bstate = BS_EXCP;
458
        }
459
        return;
460
    }
461

    
462
    switch (ctx->opcode & 0xf000) {
463
    case 0x1000:                /* mov.l Rm,@(disp,Rn) */
464
        {
465
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
466
            tcg_gen_addi_i32(addr, REG(B11_8), B3_0 * 4);
467
            tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
468
            tcg_temp_free(addr);
469
        }
470
        return;
471
    case 0x5000:                /* mov.l @(disp,Rm),Rn */
472
        {
473
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
474
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 4);
475
            tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
476
            tcg_temp_free(addr);
477
        }
478
        return;
479
    case 0xe000:                /* mov #imm,Rn */
480
        tcg_gen_movi_i32(REG(B11_8), B7_0s);
481
        return;
482
    case 0x9000:                /* mov.w @(disp,PC),Rn */
483
        {
484
            TCGv addr = tcg_const_i32(ctx->pc + 4 + B7_0 * 2);
485
            tcg_gen_qemu_ld16s(REG(B11_8), addr, ctx->memidx);
486
            tcg_temp_free(addr);
487
        }
488
        return;
489
    case 0xd000:                /* mov.l @(disp,PC),Rn */
490
        {
491
            TCGv addr = tcg_const_i32((ctx->pc + 4 + B7_0 * 4) & ~3);
492
            tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
493
            tcg_temp_free(addr);
494
        }
495
        return;
496
    case 0x7000:                /* add #imm,Rn */
497
        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);
498
        return;
499
    case 0xa000:                /* bra disp */
500
        CHECK_NOT_DELAY_SLOT
501
        ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
502
        tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
503
        ctx->flags |= DELAY_SLOT;
504
        return;
505
    case 0xb000:                /* bsr disp */
506
        CHECK_NOT_DELAY_SLOT
507
        tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
508
        ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
509
        tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
510
        ctx->flags |= DELAY_SLOT;
511
        return;
512
    }
513

    
514
    switch (ctx->opcode & 0xf00f) {
515
    case 0x6003:                /* mov Rm,Rn */
516
        tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
517
        return;
518
    case 0x2000:                /* mov.b Rm,@Rn */
519
        tcg_gen_qemu_st8(REG(B7_4), REG(B11_8), ctx->memidx);
520
        return;
521
    case 0x2001:                /* mov.w Rm,@Rn */
522
        tcg_gen_qemu_st16(REG(B7_4), REG(B11_8), ctx->memidx);
523
        return;
524
    case 0x2002:                /* mov.l Rm,@Rn */
525
        tcg_gen_qemu_st32(REG(B7_4), REG(B11_8), ctx->memidx);
526
        return;
527
    case 0x6000:                /* mov.b @Rm,Rn */
528
        tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);
529
        return;
530
    case 0x6001:                /* mov.w @Rm,Rn */
531
        tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);
532
        return;
533
    case 0x6002:                /* mov.l @Rm,Rn */
534
        tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);
535
        return;
536
    case 0x2004:                /* mov.b Rm,@-Rn */
537
        {
538
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
539
            tcg_gen_subi_i32(addr, REG(B11_8), 1);
540
            tcg_gen_qemu_st8(REG(B7_4), addr, ctx->memidx);        /* might cause re-execution */
541
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);        /* modify register status */
542
            tcg_temp_free(addr);
543
        }
544
        return;
545
    case 0x2005:                /* mov.w Rm,@-Rn */
546
        {
547
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
548
            tcg_gen_subi_i32(addr, REG(B11_8), 2);
549
            tcg_gen_qemu_st16(REG(B7_4), addr, ctx->memidx);
550
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 2);
551
            tcg_temp_free(addr);
552
        }
553
        return;
554
    case 0x2006:                /* mov.l Rm,@-Rn */
555
        {
556
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
557
            tcg_gen_subi_i32(addr, REG(B11_8), 4);
558
            tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
559
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
560
        }
561
        return;
562
    case 0x6004:                /* mov.b @Rm+,Rn */
563
        tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);
564
        if ( B11_8 != B7_4 )
565
                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 1);
566
        return;
567
    case 0x6005:                /* mov.w @Rm+,Rn */
568
        tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);
569
        if ( B11_8 != B7_4 )
570
                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
571
        return;
572
    case 0x6006:                /* mov.l @Rm+,Rn */
573
        tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);
574
        if ( B11_8 != B7_4 )
575
                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
576
        return;
577
    case 0x0004:                /* mov.b Rm,@(R0,Rn) */
578
        {
579
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
580
            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
581
            tcg_gen_qemu_st8(REG(B7_4), addr, ctx->memidx);
582
            tcg_temp_free(addr);
583
        }
584
        return;
585
    case 0x0005:                /* mov.w Rm,@(R0,Rn) */
586
        {
587
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
588
            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
589
            tcg_gen_qemu_st16(REG(B7_4), addr, ctx->memidx);
590
            tcg_temp_free(addr);
591
        }
592
        return;
593
    case 0x0006:                /* mov.l Rm,@(R0,Rn) */
594
        {
595
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
596
            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
597
            tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
598
            tcg_temp_free(addr);
599
        }
600
        return;
601
    case 0x000c:                /* mov.b @(R0,Rm),Rn */
602
        {
603
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
604
            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
605
            tcg_gen_qemu_ld8s(REG(B11_8), addr, ctx->memidx);
606
            tcg_temp_free(addr);
607
        }
608
        return;
609
    case 0x000d:                /* mov.w @(R0,Rm),Rn */
610
        {
611
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
612
            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
613
            tcg_gen_qemu_ld16s(REG(B11_8), addr, ctx->memidx);
614
            tcg_temp_free(addr);
615
        }
616
        return;
617
    case 0x000e:                /* mov.l @(R0,Rm),Rn */
618
        {
619
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
620
            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
621
            tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
622
            tcg_temp_free(addr);
623
        }
624
        return;
625
    case 0x6008:                /* swap.b Rm,Rn */
626
        {
627
            TCGv high, low;
628
            high = tcg_temp_new(TCG_TYPE_I32);
629
            tcg_gen_ext8u_i32(high, REG(B7_4));
630
            tcg_gen_shli_i32(high, high, 8);
631
            low = tcg_temp_new(TCG_TYPE_I32);
632
            tcg_gen_shri_i32(low, REG(B7_4), 8);
633
            tcg_gen_ext8u_i32(low, low);
634
            tcg_gen_or_i32(REG(B11_8), high, low);
635
            tcg_temp_free(low);
636
            tcg_temp_free(high);
637
        }
638
        return;
639
    case 0x6009:                /* swap.w Rm,Rn */
640
        {
641
            TCGv high, low;
642
            high = tcg_temp_new(TCG_TYPE_I32);
643
            tcg_gen_ext16u_i32(high, REG(B7_4));
644
            tcg_gen_shli_i32(high, high, 16);
645
            low = tcg_temp_new(TCG_TYPE_I32);
646
            tcg_gen_shri_i32(low, REG(B7_4), 16);
647
            tcg_gen_ext16u_i32(low, low);
648
            tcg_gen_or_i32(REG(B11_8), high, low);
649
            tcg_temp_free(low);
650
            tcg_temp_free(high);
651
        }
652
        return;
653
    case 0x200d:                /* xtrct Rm,Rn */
654
        {
655
            TCGv high, low;
656
            high = tcg_temp_new(TCG_TYPE_I32);
657
            tcg_gen_ext16u_i32(high, REG(B7_4));
658
            tcg_gen_shli_i32(high, high, 16);
659
            low = tcg_temp_new(TCG_TYPE_I32);
660
            tcg_gen_shri_i32(low, REG(B11_8), 16);
661
            tcg_gen_ext16u_i32(low, low);
662
            tcg_gen_or_i32(REG(B11_8), high, low);
663
            tcg_temp_free(low);
664
            tcg_temp_free(high);
665
        }
666
        return;
667
    case 0x300c:                /* add Rm,Rn */
668
        tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));
669
        return;
670
    case 0x300e:                /* addc Rm,Rn */
671
        tcg_gen_helper_1_2(helper_addc, REG(B11_8), REG(B7_4), REG(B11_8));
672
        return;
673
    case 0x300f:                /* addv Rm,Rn */
674
        tcg_gen_helper_1_2(helper_addv, REG(B11_8), REG(B7_4), REG(B11_8));
675
        return;
676
    case 0x2009:                /* and Rm,Rn */
677
        tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
678
        return;
679
    case 0x3000:                /* cmp/eq Rm,Rn */
680
        gen_cmp(TCG_COND_EQ, REG(B7_4), REG(B11_8));
681
        return;
682
    case 0x3003:                /* cmp/ge Rm,Rn */
683
        gen_cmp(TCG_COND_GE, REG(B7_4), REG(B11_8));
684
        return;
685
    case 0x3007:                /* cmp/gt Rm,Rn */
686
        gen_cmp(TCG_COND_GT, REG(B7_4), REG(B11_8));
687
        return;
688
    case 0x3006:                /* cmp/hi Rm,Rn */
689
        gen_cmp(TCG_COND_GTU, REG(B7_4), REG(B11_8));
690
        return;
691
    case 0x3002:                /* cmp/hs Rm,Rn */
692
        gen_cmp(TCG_COND_GEU, REG(B7_4), REG(B11_8));
693
        return;
694
    case 0x200c:                /* cmp/str Rm,Rn */
695
        {
696
            int label1 = gen_new_label();
697
            int label2 = gen_new_label();
698
            TCGv cmp1 = tcg_temp_local_new(TCG_TYPE_I32);
699
            TCGv cmp2 = tcg_temp_local_new(TCG_TYPE_I32);
700
            tcg_gen_xor_i32(cmp1, REG(B7_4), REG(B11_8));
701
            tcg_gen_andi_i32(cmp2, cmp1, 0xff000000);
702
            tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
703
            tcg_gen_andi_i32(cmp2, cmp1, 0x00ff0000);
704
            tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
705
            tcg_gen_andi_i32(cmp2, cmp1, 0x0000ff00);
706
            tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
707
            tcg_gen_andi_i32(cmp2, cmp1, 0x000000ff);
708
            tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
709
            tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
710
            tcg_gen_br(label2);
711
            gen_set_label(label1);
712
            tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
713
            gen_set_label(label2);
714
            tcg_temp_free(cmp2);
715
            tcg_temp_free(cmp1);
716
        }
717
        return;
718
    case 0x2007:                /* div0s Rm,Rn */
719
        {
720
            gen_copy_bit_i32(cpu_sr, 8, REG(B11_8), 31);        /* SR_Q */
721
            gen_copy_bit_i32(cpu_sr, 9, REG(B7_4), 31);                /* SR_M */
722
            TCGv val = tcg_temp_new(TCG_TYPE_I32);
723
            tcg_gen_xor_i32(val, REG(B7_4), REG(B11_8));
724
            gen_copy_bit_i32(cpu_sr, 0, val, 31);                /* SR_T */
725
            tcg_temp_free(val);
726
        }
727
        return;
728
    case 0x3004:                /* div1 Rm,Rn */
729
        tcg_gen_helper_1_2(helper_div1, REG(B11_8), REG(B7_4), REG(B11_8));
730
        return;
731
    case 0x300d:                /* dmuls.l Rm,Rn */
732
        {
733
            TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
734
            TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
735

    
736
            tcg_gen_ext_i32_i64(tmp1, REG(B7_4));
737
            tcg_gen_ext_i32_i64(tmp2, REG(B11_8));
738
            tcg_gen_mul_i64(tmp1, tmp1, tmp2);
739
            tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
740
            tcg_gen_shri_i64(tmp1, tmp1, 32);
741
            tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
742

    
743
            tcg_temp_free(tmp2);
744
            tcg_temp_free(tmp1);
745
        }
746
        return;
747
    case 0x3005:                /* dmulu.l Rm,Rn */
748
        {
749
            TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
750
            TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
751

    
752
            tcg_gen_extu_i32_i64(tmp1, REG(B7_4));
753
            tcg_gen_extu_i32_i64(tmp2, REG(B11_8));
754
            tcg_gen_mul_i64(tmp1, tmp1, tmp2);
755
            tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
756
            tcg_gen_shri_i64(tmp1, tmp1, 32);
757
            tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
758

    
759
            tcg_temp_free(tmp2);
760
            tcg_temp_free(tmp1);
761
        }
762
        return;
763
    case 0x600e:                /* exts.b Rm,Rn */
764
        tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));
765
        return;
766
    case 0x600f:                /* exts.w Rm,Rn */
767
        tcg_gen_ext16s_i32(REG(B11_8), REG(B7_4));
768
        return;
769
    case 0x600c:                /* extu.b Rm,Rn */
770
        tcg_gen_ext8u_i32(REG(B11_8), REG(B7_4));
771
        return;
772
    case 0x600d:                /* extu.w Rm,Rn */
773
        tcg_gen_ext16u_i32(REG(B11_8), REG(B7_4));
774
        return;
775
    case 0x000f:                /* mac.l @Rm+,@Rn+ */
776
        {
777
            TCGv arg0, arg1;
778
            arg0 = tcg_temp_new(TCG_TYPE_I32);
779
            tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);
780
            arg1 = tcg_temp_new(TCG_TYPE_I32);
781
            tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);
782
            tcg_gen_helper_0_2(helper_macl, arg0, arg1);
783
            tcg_temp_free(arg1);
784
            tcg_temp_free(arg0);
785
            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
786
            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
787
        }
788
        return;
789
    case 0x400f:                /* mac.w @Rm+,@Rn+ */
790
        {
791
            TCGv arg0, arg1;
792
            arg0 = tcg_temp_new(TCG_TYPE_I32);
793
            tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);
794
            arg1 = tcg_temp_new(TCG_TYPE_I32);
795
            tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);
796
            tcg_gen_helper_0_2(helper_macw, arg0, arg1);
797
            tcg_temp_free(arg1);
798
            tcg_temp_free(arg0);
799
            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);
800
            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
801
        }
802
        return;
803
    case 0x0007:                /* mul.l Rm,Rn */
804
        tcg_gen_mul_i32(cpu_macl, REG(B7_4), REG(B11_8));
805
        return;
806
    case 0x200f:                /* muls.w Rm,Rn */
807
        {
808
            TCGv arg0, arg1;
809
            arg0 = tcg_temp_new(TCG_TYPE_I32);
810
            tcg_gen_ext16s_i32(arg0, REG(B7_4));
811
            arg1 = tcg_temp_new(TCG_TYPE_I32);
812
            tcg_gen_ext16s_i32(arg1, REG(B11_8));
813
            tcg_gen_mul_i32(cpu_macl, arg0, arg1);
814
            tcg_temp_free(arg1);
815
            tcg_temp_free(arg0);
816
        }
817
        return;
818
    case 0x200e:                /* mulu.w Rm,Rn */
819
        {
820
            TCGv arg0, arg1;
821
            arg0 = tcg_temp_new(TCG_TYPE_I32);
822
            tcg_gen_ext16u_i32(arg0, REG(B7_4));
823
            arg1 = tcg_temp_new(TCG_TYPE_I32);
824
            tcg_gen_ext16u_i32(arg1, REG(B11_8));
825
            tcg_gen_mul_i32(cpu_macl, arg0, arg1);
826
            tcg_temp_free(arg1);
827
            tcg_temp_free(arg0);
828
        }
829
        return;
830
    case 0x600b:                /* neg Rm,Rn */
831
        tcg_gen_neg_i32(REG(B11_8), REG(B7_4));
832
        return;
833
    case 0x600a:                /* negc Rm,Rn */
834
        tcg_gen_helper_1_1(helper_negc, REG(B11_8), REG(B7_4));
835
        return;
836
    case 0x6007:                /* not Rm,Rn */
837
        tcg_gen_not_i32(REG(B11_8), REG(B7_4));
838
        return;
839
    case 0x200b:                /* or Rm,Rn */
840
        tcg_gen_or_i32(REG(B11_8), REG(B11_8), REG(B7_4));
841
        return;
842
    case 0x400c:                /* shad Rm,Rn */
843
        {
844
            int label1 = gen_new_label();
845
            int label2 = gen_new_label();
846
            int label3 = gen_new_label();
847
            int label4 = gen_new_label();
848
            TCGv shift = tcg_temp_local_new(TCG_TYPE_I32);
849
            tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
850
            /* Rm positive, shift to the left */
851
            tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
852
            tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);
853
            tcg_gen_br(label4);
854
            /* Rm negative, shift to the right */
855
            gen_set_label(label1);
856
            tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
857
            tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);
858
            tcg_gen_not_i32(shift, REG(B7_4));
859
            tcg_gen_andi_i32(shift, shift, 0x1f);
860
            tcg_gen_addi_i32(shift, shift, 1);
861
            tcg_gen_sar_i32(REG(B11_8), REG(B11_8), shift);
862
            tcg_gen_br(label4);
863
            /* Rm = -32 */
864
            gen_set_label(label2);
865
            tcg_gen_brcondi_i32(TCG_COND_LT, REG(B11_8), 0, label3);
866
            tcg_gen_movi_i32(REG(B11_8), 0);
867
            tcg_gen_br(label4);
868
            gen_set_label(label3);
869
            tcg_gen_movi_i32(REG(B11_8), 0xffffffff);
870
            gen_set_label(label4);
871
            tcg_temp_free(shift);
872
        }
873
        return;
874
    case 0x400d:                /* shld Rm,Rn */
875
        {
876
            int label1 = gen_new_label();
877
            int label2 = gen_new_label();
878
            int label3 = gen_new_label();
879
            TCGv shift = tcg_temp_local_new(TCG_TYPE_I32);
880
            tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
881
            /* Rm positive, shift to the left */
882
            tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
883
            tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);
884
            tcg_gen_br(label3);
885
            /* Rm negative, shift to the right */
886
            gen_set_label(label1);
887
            tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
888
            tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);
889
            tcg_gen_not_i32(shift, REG(B7_4));
890
            tcg_gen_andi_i32(shift, shift, 0x1f);
891
            tcg_gen_addi_i32(shift, shift, 1);
892
            tcg_gen_shr_i32(REG(B11_8), REG(B11_8), shift);
893
            tcg_gen_br(label3);
894
            /* Rm = -32 */
895
            gen_set_label(label2);
896
            tcg_gen_movi_i32(REG(B11_8), 0);
897
            gen_set_label(label3);
898
            tcg_temp_free(shift);
899
        }
900
        return;
901
    case 0x3008:                /* sub Rm,Rn */
902
        tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));
903
        return;
904
    case 0x300a:                /* subc Rm,Rn */
905
        tcg_gen_helper_1_2(helper_subc, REG(B11_8), REG(B7_4), REG(B11_8));
906
        return;
907
    case 0x300b:                /* subv Rm,Rn */
908
        tcg_gen_helper_1_2(helper_subv, REG(B11_8), REG(B7_4), REG(B11_8));
909
        return;
910
    case 0x2008:                /* tst Rm,Rn */
911
        {
912
            TCGv val = tcg_temp_new(TCG_TYPE_I32);
913
            tcg_gen_and_i32(val, REG(B7_4), REG(B11_8));
914
            gen_cmp_imm(TCG_COND_EQ, val, 0);
915
            tcg_temp_free(val);
916
        }
917
        return;
918
    case 0x200a:                /* xor Rm,Rn */
919
        tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));
920
        return;
921
    case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
922
        if (ctx->fpscr & FPSCR_SZ) {
923
            TCGv fp = tcg_temp_new(TCG_TYPE_I64);
924
            gen_load_fpr64(fp, XREG(B7_4));
925
            gen_store_fpr64(fp, XREG(B11_8));
926
            tcg_temp_free(fp);
927
        } else {
928
            TCGv fp = tcg_temp_new(TCG_TYPE_I32);
929
            gen_load_fpr32(fp, FREG(B7_4));
930
            gen_store_fpr32(fp, FREG(B11_8));
931
            tcg_temp_free(fp);
932
        }
933
        return;
934
    case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
935
        if (ctx->fpscr & FPSCR_SZ) {
936
            TCGv fp = tcg_temp_new(TCG_TYPE_I64);
937
            gen_load_fpr64(fp, XREG(B7_4));
938
            tcg_gen_qemu_st64(fp, REG(B11_8), ctx->memidx);
939
            tcg_temp_free(fp);
940
        } else {
941
            TCGv fp = tcg_temp_new(TCG_TYPE_I32);
942
            gen_load_fpr32(fp, FREG(B7_4));
943
            tcg_gen_qemu_st32(fp, REG(B11_8), ctx->memidx);
944
            tcg_temp_free(fp);
945
        }
946
        return;
947
    case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
948
        if (ctx->fpscr & FPSCR_SZ) {
949
            TCGv fp = tcg_temp_new(TCG_TYPE_I64);
950
            tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx);
951
            gen_store_fpr64(fp, XREG(B11_8));
952
            tcg_temp_free(fp);
953
        } else {
954
            TCGv fp = tcg_temp_new(TCG_TYPE_I32);
955
            tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);
956
            gen_store_fpr32(fp, FREG(B11_8));
957
            tcg_temp_free(fp);
958
        }
959
        return;
960
    case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
961
        if (ctx->fpscr & FPSCR_SZ) {
962
            TCGv fp = tcg_temp_new(TCG_TYPE_I64);
963
            tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx);
964
            gen_store_fpr64(fp, XREG(B11_8));
965
            tcg_temp_free(fp);
966
            tcg_gen_addi_i32(REG(B7_4),REG(B7_4), 8);
967
        } else {
968
            TCGv fp = tcg_temp_new(TCG_TYPE_I32);
969
            tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);
970
            gen_store_fpr32(fp, FREG(B11_8));
971
            tcg_temp_free(fp);
972
            tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
973
        }
974
        return;
975
    case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
976
        if (ctx->fpscr & FPSCR_SZ) {
977
            TCGv addr, fp;
978
            addr = tcg_temp_new(TCG_TYPE_I32);
979
            tcg_gen_subi_i32(addr, REG(B11_8), 8);
980
            fp = tcg_temp_new(TCG_TYPE_I64);
981
            gen_load_fpr64(fp, XREG(B7_4));
982
            tcg_gen_qemu_st64(fp, addr, ctx->memidx);
983
            tcg_temp_free(fp);
984
            tcg_temp_free(addr);
985
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 8);
986
        } else {
987
            TCGv addr, fp;
988
            addr = tcg_temp_new(TCG_TYPE_I32);
989
            tcg_gen_subi_i32(addr, REG(B11_8), 4);
990
            fp = tcg_temp_new(TCG_TYPE_I32);
991
            gen_load_fpr32(fp, FREG(B7_4));
992
            tcg_gen_qemu_st32(fp, addr, ctx->memidx);
993
            tcg_temp_free(fp);
994
            tcg_temp_free(addr);
995
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
996
        }
997
        return;
998
    case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
999
        {
1000
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1001
            tcg_gen_add_i32(addr, REG(B7_4), REG(0));
1002
            if (ctx->fpscr & FPSCR_SZ) {
1003
                TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1004
                tcg_gen_qemu_ld64(fp, addr, 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, addr, ctx->memidx);
1010
                gen_store_fpr32(fp, FREG(B11_8));
1011
                tcg_temp_free(fp);
1012
            }
1013
            tcg_temp_free(addr);
1014
        }
1015
        return;
1016
    case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
1017
        {
1018
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1019
            tcg_gen_add_i32(addr, REG(B11_8), REG(0));
1020
            if (ctx->fpscr & FPSCR_SZ) {
1021
                TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1022
                gen_load_fpr64(fp, XREG(B7_4));
1023
                tcg_gen_qemu_st64(fp, addr, ctx->memidx);
1024
                tcg_temp_free(fp);
1025
            } else {
1026
                TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1027
                gen_load_fpr32(fp, FREG(B7_4));
1028
                tcg_gen_qemu_st32(fp, addr, ctx->memidx);
1029
                tcg_temp_free(fp);
1030
            }
1031
            tcg_temp_free(addr);
1032
        }
1033
        return;
1034
    case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1035
    case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1036
    case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1037
    case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1038
    case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1039
    case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1040
        {
1041
            TCGv fp0, fp1;
1042

    
1043
            if (ctx->fpscr & FPSCR_PR) {
1044
                if (ctx->opcode & 0x0110)
1045
                    break; /* illegal instruction */
1046
                fp0 = tcg_temp_new(TCG_TYPE_I64);
1047
                fp1 = tcg_temp_new(TCG_TYPE_I64);
1048
                gen_load_fpr64(fp0, DREG(B11_8));
1049
                gen_load_fpr64(fp1, DREG(B7_4));
1050
            }
1051
            else {
1052
                fp0 = tcg_temp_new(TCG_TYPE_I32);
1053
                fp1 = tcg_temp_new(TCG_TYPE_I32);
1054
                gen_load_fpr32(fp0, FREG(B11_8));
1055
                gen_load_fpr32(fp1, FREG(B7_4));
1056
            }
1057

    
1058
            switch (ctx->opcode & 0xf00f) {
1059
            case 0xf000:                /* fadd Rm,Rn */
1060
                if (ctx->fpscr & FPSCR_PR)
1061
                    tcg_gen_helper_1_2(helper_fadd_DT, fp0, fp0, fp1);
1062
                else
1063
                    tcg_gen_helper_1_2(helper_fadd_FT, fp0, fp0, fp1);
1064
                break;
1065
            case 0xf001:                /* fsub Rm,Rn */
1066
                if (ctx->fpscr & FPSCR_PR)
1067
                    tcg_gen_helper_1_2(helper_fsub_DT, fp0, fp0, fp1);
1068
                else
1069
                    tcg_gen_helper_1_2(helper_fsub_FT, fp0, fp0, fp1);
1070
                break;
1071
            case 0xf002:                /* fmul Rm,Rn */
1072
                if (ctx->fpscr & FPSCR_PR)
1073
                    tcg_gen_helper_1_2(helper_fmul_DT, fp0, fp0, fp1);
1074
                else
1075
                    tcg_gen_helper_1_2(helper_fmul_FT, fp0, fp0, fp1);
1076
                break;
1077
            case 0xf003:                /* fdiv Rm,Rn */
1078
                if (ctx->fpscr & FPSCR_PR)
1079
                    tcg_gen_helper_1_2(helper_fdiv_DT, fp0, fp0, fp1);
1080
                else
1081
                    tcg_gen_helper_1_2(helper_fdiv_FT, fp0, fp0, fp1);
1082
                break;
1083
            case 0xf004:                /* fcmp/eq Rm,Rn */
1084
                if (ctx->fpscr & FPSCR_PR)
1085
                    tcg_gen_helper_0_2(helper_fcmp_eq_DT, fp0, fp1);
1086
                else
1087
                    tcg_gen_helper_0_2(helper_fcmp_eq_FT, fp0, fp1);
1088
                return;
1089
            case 0xf005:                /* fcmp/gt Rm,Rn */
1090
                if (ctx->fpscr & FPSCR_PR)
1091
                    tcg_gen_helper_0_2(helper_fcmp_gt_DT, fp0, fp1);
1092
                else
1093
                    tcg_gen_helper_0_2(helper_fcmp_gt_FT, fp0, fp1);
1094
                return;
1095
            }
1096

    
1097
            if (ctx->fpscr & FPSCR_PR) {
1098
                gen_store_fpr64(fp0, DREG(B11_8));
1099
            }
1100
            else {
1101
                gen_store_fpr32(fp0, FREG(B11_8));
1102
            }
1103
            tcg_temp_free(fp1);
1104
            tcg_temp_free(fp0);
1105
        }
1106
        return;
1107
    }
1108

    
1109
    switch (ctx->opcode & 0xff00) {
1110
    case 0xc900:                /* and #imm,R0 */
1111
        tcg_gen_andi_i32(REG(0), REG(0), B7_0);
1112
        return;
1113
    case 0xcd00:                /* and.b #imm,@(R0,GBR) */
1114
        {
1115
            TCGv addr, val;
1116
            addr = tcg_temp_new(TCG_TYPE_I32);
1117
            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1118
            val = tcg_temp_new(TCG_TYPE_I32);
1119
            tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1120
            tcg_gen_andi_i32(val, val, B7_0);
1121
            tcg_gen_qemu_st8(val, addr, ctx->memidx);
1122
            tcg_temp_free(val);
1123
            tcg_temp_free(addr);
1124
        }
1125
        return;
1126
    case 0x8b00:                /* bf label */
1127
        CHECK_NOT_DELAY_SLOT
1128
            gen_conditional_jump(ctx, ctx->pc + 2,
1129
                                 ctx->pc + 4 + B7_0s * 2);
1130
        ctx->bstate = BS_BRANCH;
1131
        return;
1132
    case 0x8f00:                /* bf/s label */
1133
        CHECK_NOT_DELAY_SLOT
1134
        gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);
1135
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
1136
        return;
1137
    case 0x8900:                /* bt label */
1138
        CHECK_NOT_DELAY_SLOT
1139
            gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
1140
                                 ctx->pc + 2);
1141
        ctx->bstate = BS_BRANCH;
1142
        return;
1143
    case 0x8d00:                /* bt/s label */
1144
        CHECK_NOT_DELAY_SLOT
1145
        gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);
1146
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
1147
        return;
1148
    case 0x8800:                /* cmp/eq #imm,R0 */
1149
        gen_cmp_imm(TCG_COND_EQ, REG(0), B7_0s);
1150
        return;
1151
    case 0xc400:                /* mov.b @(disp,GBR),R0 */
1152
        {
1153
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1154
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1155
            tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);
1156
            tcg_temp_free(addr);
1157
        }
1158
        return;
1159
    case 0xc500:                /* mov.w @(disp,GBR),R0 */
1160
        {
1161
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1162
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1163
            tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);
1164
            tcg_temp_free(addr);
1165
        }
1166
        return;
1167
    case 0xc600:                /* mov.l @(disp,GBR),R0 */
1168
        {
1169
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1170
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1171
            tcg_gen_qemu_ld32s(REG(0), addr, ctx->memidx);
1172
            tcg_temp_free(addr);
1173
        }
1174
        return;
1175
    case 0xc000:                /* mov.b R0,@(disp,GBR) */
1176
        {
1177
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1178
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1179
            tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);
1180
            tcg_temp_free(addr);
1181
        }
1182
        return;
1183
    case 0xc100:                /* mov.w R0,@(disp,GBR) */
1184
        {
1185
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1186
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1187
            tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);
1188
            tcg_temp_free(addr);
1189
        }
1190
        return;
1191
    case 0xc200:                /* mov.l R0,@(disp,GBR) */
1192
        {
1193
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1194
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1195
            tcg_gen_qemu_st32(REG(0), addr, ctx->memidx);
1196
            tcg_temp_free(addr);
1197
        }
1198
        return;
1199
    case 0x8000:                /* mov.b R0,@(disp,Rn) */
1200
        {
1201
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1202
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1203
            tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);
1204
            tcg_temp_free(addr);
1205
        }
1206
        return;
1207
    case 0x8100:                /* mov.w R0,@(disp,Rn) */
1208
        {
1209
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1210
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1211
            tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);
1212
            tcg_temp_free(addr);
1213
        }
1214
        return;
1215
    case 0x8400:                /* mov.b @(disp,Rn),R0 */
1216
        {
1217
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1218
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1219
            tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);
1220
            tcg_temp_free(addr);
1221
        }
1222
        return;
1223
    case 0x8500:                /* mov.w @(disp,Rn),R0 */
1224
        {
1225
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1226
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1227
            tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);
1228
            tcg_temp_free(addr);
1229
        }
1230
        return;
1231
    case 0xc700:                /* mova @(disp,PC),R0 */
1232
        tcg_gen_movi_i32(REG(0), ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
1233
        return;
1234
    case 0xcb00:                /* or #imm,R0 */
1235
        tcg_gen_ori_i32(REG(0), REG(0), B7_0);
1236
        return;
1237
    case 0xcf00:                /* or.b #imm,@(R0,GBR) */
1238
        {
1239
            TCGv addr, val;
1240
            addr = tcg_temp_new(TCG_TYPE_I32);
1241
            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1242
            val = tcg_temp_new(TCG_TYPE_I32);
1243
            tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1244
            tcg_gen_ori_i32(val, val, B7_0);
1245
            tcg_gen_qemu_st8(val, addr, ctx->memidx);
1246
            tcg_temp_free(val);
1247
            tcg_temp_free(addr);
1248
        }
1249
        return;
1250
    case 0xc300:                /* trapa #imm */
1251
        {
1252
            TCGv imm;
1253
            CHECK_NOT_DELAY_SLOT
1254
            tcg_gen_movi_i32(cpu_pc, ctx->pc);
1255
            imm = tcg_const_i32(B7_0);
1256
            tcg_gen_helper_0_1(helper_trapa, imm);
1257
            tcg_temp_free(imm);
1258
            ctx->bstate = BS_BRANCH;
1259
        }
1260
        return;
1261
    case 0xc800:                /* tst #imm,R0 */
1262
        {
1263
            TCGv val = tcg_temp_new(TCG_TYPE_I32);
1264
            tcg_gen_andi_i32(val, REG(0), B7_0);
1265
            gen_cmp_imm(TCG_COND_EQ, val, 0);
1266
            tcg_temp_free(val);
1267
        }
1268
        return;
1269
    case 0xcc00:                /* tst.b #imm,@(R0,GBR) */
1270
        {
1271
            TCGv val = tcg_temp_new(TCG_TYPE_I32);
1272
            tcg_gen_add_i32(val, REG(0), cpu_gbr);
1273
            tcg_gen_qemu_ld8u(val, val, ctx->memidx);
1274
            tcg_gen_andi_i32(val, val, B7_0);
1275
            gen_cmp_imm(TCG_COND_EQ, val, 0);
1276
            tcg_temp_free(val);
1277
        }
1278
        return;
1279
    case 0xca00:                /* xor #imm,R0 */
1280
        tcg_gen_xori_i32(REG(0), REG(0), B7_0);
1281
        return;
1282
    case 0xce00:                /* xor.b #imm,@(R0,GBR) */
1283
        {
1284
            TCGv addr, val;
1285
            addr = tcg_temp_new(TCG_TYPE_I32);
1286
            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1287
            val = tcg_temp_new(TCG_TYPE_I32);
1288
            tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1289
            tcg_gen_xori_i32(val, val, B7_0);
1290
            tcg_gen_qemu_st8(val, addr, ctx->memidx);
1291
            tcg_temp_free(val);
1292
            tcg_temp_free(addr);
1293
        }
1294
        return;
1295
    }
1296

    
1297
    switch (ctx->opcode & 0xf08f) {
1298
    case 0x408e:                /* ldc Rm,Rn_BANK */
1299
        tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
1300
        return;
1301
    case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
1302
        tcg_gen_qemu_ld32s(ALTREG(B6_4), REG(B11_8), ctx->memidx);
1303
        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1304
        return;
1305
    case 0x0082:                /* stc Rm_BANK,Rn */
1306
        tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
1307
        return;
1308
    case 0x4083:                /* stc.l Rm_BANK,@-Rn */
1309
        {
1310
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1311
            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1312
            tcg_gen_qemu_st32(ALTREG(B6_4), addr, ctx->memidx);
1313
            tcg_temp_free(addr);
1314
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1315
        }
1316
        return;
1317
    }
1318

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

    
1674
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1675
            ctx->opcode, ctx->pc);
1676
    tcg_gen_helper_0_0(helper_raise_illegal_instruction);
1677
    ctx->bstate = BS_EXCP;
1678
}
1679

    
1680
void decode_opc(DisasContext * ctx)
1681
{
1682
    uint32_t old_flags = ctx->flags;
1683

    
1684
    _decode_opc(ctx);
1685

    
1686
    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1687
        if (ctx->flags & DELAY_SLOT_CLEARME) {
1688
            gen_store_flags(0);
1689
        } else {
1690
            /* go out of the delay slot */
1691
            uint32_t new_flags = ctx->flags;
1692
            new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1693
            gen_store_flags(new_flags);
1694
        }
1695
        ctx->flags = 0;
1696
        ctx->bstate = BS_BRANCH;
1697
        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1698
            gen_delayed_conditional_jump(ctx);
1699
        } else if (old_flags & DELAY_SLOT) {
1700
            gen_jump(ctx);
1701
        }
1702

    
1703
    }
1704

    
1705
    /* go into a delay slot */
1706
    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1707
        gen_store_flags(ctx->flags);
1708
}
1709

    
1710
static inline void
1711
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1712
                               int search_pc)
1713
{
1714
    DisasContext ctx;
1715
    target_ulong pc_start;
1716
    static uint16_t *gen_opc_end;
1717
    int i, ii;
1718
    int num_insns;
1719
    int max_insns;
1720

    
1721
    pc_start = tb->pc;
1722
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1723
    ctx.pc = pc_start;
1724
    ctx.flags = (uint32_t)tb->flags;
1725
    ctx.bstate = BS_NONE;
1726
    ctx.sr = env->sr;
1727
    ctx.fpscr = env->fpscr;
1728
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1729
    /* We don't know if the delayed pc came from a dynamic or static branch,
1730
       so assume it is a dynamic branch.  */
1731
    ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1732
    ctx.tb = tb;
1733
    ctx.singlestep_enabled = env->singlestep_enabled;
1734

    
1735
#ifdef DEBUG_DISAS
1736
    if (loglevel & CPU_LOG_TB_CPU) {
1737
        fprintf(logfile,
1738
                "------------------------------------------------\n");
1739
        cpu_dump_state(env, logfile, fprintf, 0);
1740
    }
1741
#endif
1742

    
1743
    ii = -1;
1744
    num_insns = 0;
1745
    max_insns = tb->cflags & CF_COUNT_MASK;
1746
    if (max_insns == 0)
1747
        max_insns = CF_COUNT_MASK;
1748
    gen_icount_start();
1749
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1750
        if (env->nb_breakpoints > 0) {
1751
            for (i = 0; i < env->nb_breakpoints; i++) {
1752
                if (ctx.pc == env->breakpoints[i]) {
1753
                    /* We have hit a breakpoint - make sure PC is up-to-date */
1754
                    tcg_gen_movi_i32(cpu_pc, ctx.pc);
1755
                    tcg_gen_helper_0_0(helper_debug);
1756
                    ctx.bstate = BS_EXCP;
1757
                    break;
1758
                }
1759
            }
1760
        }
1761
        if (search_pc) {
1762
            i = gen_opc_ptr - gen_opc_buf;
1763
            if (ii < i) {
1764
                ii++;
1765
                while (ii < i)
1766
                    gen_opc_instr_start[ii++] = 0;
1767
            }
1768
            gen_opc_pc[ii] = ctx.pc;
1769
            gen_opc_hflags[ii] = ctx.flags;
1770
            gen_opc_instr_start[ii] = 1;
1771
            gen_opc_icount[ii] = num_insns;
1772
        }
1773
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1774
            gen_io_start();
1775
#if 0
1776
        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1777
        fflush(stderr);
1778
#endif
1779
        ctx.opcode = lduw_code(ctx.pc);
1780
        decode_opc(&ctx);
1781
        num_insns++;
1782
        ctx.pc += 2;
1783
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1784
            break;
1785
        if (env->singlestep_enabled)
1786
            break;
1787
        if (num_insns >= max_insns)
1788
            break;
1789
#ifdef SH4_SINGLE_STEP
1790
        break;
1791
#endif
1792
    }
1793
    if (tb->cflags & CF_LAST_IO)
1794
        gen_io_end();
1795
    if (env->singlestep_enabled) {
1796
        tcg_gen_helper_0_0(helper_debug);
1797
    } else {
1798
        switch (ctx.bstate) {
1799
        case BS_STOP:
1800
            /* gen_op_interrupt_restart(); */
1801
            /* fall through */
1802
        case BS_NONE:
1803
            if (ctx.flags) {
1804
                gen_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1805
            }
1806
            gen_goto_tb(&ctx, 0, ctx.pc);
1807
            break;
1808
        case BS_EXCP:
1809
            /* gen_op_interrupt_restart(); */
1810
            tcg_gen_exit_tb(0);
1811
            break;
1812
        case BS_BRANCH:
1813
        default:
1814
            break;
1815
        }
1816
    }
1817

    
1818
    gen_icount_end(tb, num_insns);
1819
    *gen_opc_ptr = INDEX_op_end;
1820
    if (search_pc) {
1821
        i = gen_opc_ptr - gen_opc_buf;
1822
        ii++;
1823
        while (ii <= i)
1824
            gen_opc_instr_start[ii++] = 0;
1825
    } else {
1826
        tb->size = ctx.pc - pc_start;
1827
        tb->icount = num_insns;
1828
    }
1829

    
1830
#ifdef DEBUG_DISAS
1831
#ifdef SH4_DEBUG_DISAS
1832
    if (loglevel & CPU_LOG_TB_IN_ASM)
1833
        fprintf(logfile, "\n");
1834
#endif
1835
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1836
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1837
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1838
        fprintf(logfile, "\n");
1839
    }
1840
#endif
1841
}
1842

    
1843
void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1844
{
1845
    gen_intermediate_code_internal(env, tb, 0);
1846
}
1847

    
1848
void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1849
{
1850
    gen_intermediate_code_internal(env, tb, 1);
1851
}
1852

    
1853
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1854
                unsigned long searched_pc, int pc_pos, void *puc)
1855
{
1856
    env->pc = gen_opc_pc[pc_pos];
1857
    env->flags = gen_opc_hflags[pc_pos];
1858
}