Statistics
| Branch: | Revision:

root / target-sh4 / translate.c @ c55497ec

History | View | Annotate | Download (52 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
#ifdef CONFIG_USER_ONLY
141

    
142
#define GEN_OP_LD(width, reg) \
143
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
144
    gen_op_ld##width##_T0_##reg##_raw(); \
145
  }
146
#define GEN_OP_ST(width, reg) \
147
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
148
    gen_op_st##width##_##reg##_T1_raw(); \
149
  }
150

    
151
#else
152

    
153
#define GEN_OP_LD(width, reg) \
154
  void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
155
    if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
156
    else gen_op_ld##width##_T0_##reg##_user();\
157
  }
158
#define GEN_OP_ST(width, reg) \
159
  void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
160
    if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
161
    else gen_op_st##width##_##reg##_T1_user();\
162
  }
163

    
164
#endif
165

    
166
GEN_OP_LD(fl, FT0)
167
GEN_OP_ST(fl, FT0)
168
GEN_OP_LD(fq, DT0)
169
GEN_OP_ST(fq, DT0)
170

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

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

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

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

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

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

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

    
262
static inline void gen_branch_slot(uint32_t delayed_pc, int t)
263
{
264
    TCGv sr;
265
    int label = gen_new_label();
266
    tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
267
    sr = tcg_temp_new(TCG_TYPE_I32);
268
    tcg_gen_andi_i32(sr, cpu_sr, SR_T);
269
    tcg_gen_brcondi_i32(TCG_COND_NE, sr, t ? SR_T : 0, label);
270
    tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
271
    gen_set_label(label);
272
}
273

    
274
/* Immediate conditional jump (bt or bf) */
275
static void gen_conditional_jump(DisasContext * ctx,
276
                                 target_ulong ift, target_ulong ifnott)
277
{
278
    int l1;
279
    TCGv sr;
280

    
281
    l1 = gen_new_label();
282
    sr = tcg_temp_new(TCG_TYPE_I32);
283
    tcg_gen_andi_i32(sr, cpu_sr, SR_T);
284
    tcg_gen_brcondi_i32(TCG_COND_EQ, sr, SR_T, l1);
285
    gen_goto_tb(ctx, 0, ifnott);
286
    gen_set_label(l1);
287
    gen_goto_tb(ctx, 1, ift);
288
}
289

    
290
/* Delayed conditional jump (bt or bf) */
291
static void gen_delayed_conditional_jump(DisasContext * ctx)
292
{
293
    int l1;
294
    TCGv ds;
295

    
296
    l1 = gen_new_label();
297
    ds = tcg_temp_new(TCG_TYPE_I32);
298
    tcg_gen_andi_i32(ds, cpu_flags, DELAY_SLOT_TRUE);
299
    tcg_gen_brcondi_i32(TCG_COND_EQ, ds, DELAY_SLOT_TRUE, l1);
300
    gen_goto_tb(ctx, 1, ctx->pc + 2);
301
    gen_set_label(l1);
302
    tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
303
    gen_jump(ctx);
304
}
305

    
306
static inline void gen_set_t(void)
307
{
308
    tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
309
}
310

    
311
static inline void gen_clr_t(void)
312
{
313
    tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
314
}
315

    
316
static inline void gen_cmp(int cond, TCGv t0, TCGv t1)
317
{
318
    int label1 = gen_new_label();
319
    int label2 = gen_new_label();
320
    tcg_gen_brcond_i32(cond, t1, t0, label1);
321
    gen_clr_t();
322
    tcg_gen_br(label2);
323
    gen_set_label(label1);
324
    gen_set_t();
325
    gen_set_label(label2);
326
}
327

    
328
static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
329
{
330
    int label1 = gen_new_label();
331
    int label2 = gen_new_label();
332
    tcg_gen_brcondi_i32(cond, t0, imm, label1);
333
    gen_clr_t();
334
    tcg_gen_br(label2);
335
    gen_set_label(label1);
336
    gen_set_t();
337
    gen_set_label(label2);
338
}
339

    
340
static inline void gen_store_flags(uint32_t flags)
341
{
342
    tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
343
    tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
344
}
345

    
346
static inline void gen_copy_bit_i32(TCGv t0, int p0, TCGv t1, int p1)
347
{
348
    TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
349

    
350
    p0 &= 0x1f;
351
    p1 &= 0x1f;
352

    
353
    tcg_gen_andi_i32(tmp, t1, (1 << p1));
354
    tcg_gen_andi_i32(t0, t0, ~(1 << p0));
355
    if (p0 < p1)
356
        tcg_gen_shri_i32(tmp, tmp, p1 - p0);
357
    else if (p0 > p1)
358
        tcg_gen_shli_i32(tmp, tmp, p0 - p1);
359
    tcg_gen_or_i32(t0, t0, tmp);
360

    
361
    tcg_temp_free(tmp);
362
}
363

    
364
#define B3_0 (ctx->opcode & 0xf)
365
#define B6_4 ((ctx->opcode >> 4) & 0x7)
366
#define B7_4 ((ctx->opcode >> 4) & 0xf)
367
#define B7_0 (ctx->opcode & 0xff)
368
#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
369
#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
370
  (ctx->opcode & 0xfff))
371
#define B11_8 ((ctx->opcode >> 8) & 0xf)
372
#define B15_12 ((ctx->opcode >> 12) & 0xf)
373

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

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

    
380
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
381
#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
382
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
383
#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
384

    
385
#define CHECK_NOT_DELAY_SLOT \
386
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
387
  {tcg_gen_helper_0_0(helper_raise_slot_illegal_instruction); ctx->bstate = BS_EXCP; \
388
   return;}
389

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

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

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

    
729
            tcg_gen_ext_i32_i64(tmp1, REG(B7_4));
730
            tcg_gen_ext_i32_i64(tmp2, REG(B11_8));
731
            tcg_gen_mul_i64(tmp1, tmp1, tmp2);
732
            tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
733
            tcg_gen_shri_i64(tmp1, tmp1, 32);
734
            tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
735

    
736
            tcg_temp_free(tmp2);
737
            tcg_temp_free(tmp1);
738
        }
739
        return;
740
    case 0x3005:                /* dmulu.l Rm,Rn */
741
        {
742
            TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
743
            TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
744

    
745
            tcg_gen_extu_i32_i64(tmp1, REG(B7_4));
746
            tcg_gen_extu_i32_i64(tmp2, REG(B11_8));
747
            tcg_gen_mul_i64(tmp1, tmp1, tmp2);
748
            tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
749
            tcg_gen_shri_i64(tmp1, tmp1, 32);
750
            tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
751

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

    
1017
        switch (ctx->opcode & 0xf00f) {
1018
        case 0xf000:                /* fadd Rm,Rn */
1019
            ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
1020
            break;
1021
        case 0xf001:                /* fsub Rm,Rn */
1022
            ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
1023
            break;
1024
        case 0xf002:                /* fmul Rm,Rn */
1025
            ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
1026
            break;
1027
        case 0xf003:                /* fdiv Rm,Rn */
1028
            ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
1029
            break;
1030
        case 0xf004:                /* fcmp/eq Rm,Rn */
1031
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
1032
            return;
1033
        case 0xf005:                /* fcmp/gt Rm,Rn */
1034
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
1035
            return;
1036
        }
1037

    
1038
        if (ctx->fpscr & FPSCR_PR) {
1039
            gen_op_fmov_DT0_drN(DREG(B11_8));
1040
        }
1041
        else {
1042
            gen_op_fmov_FT0_frN(FREG(B11_8));
1043
        }
1044
        return;
1045
    }
1046

    
1047
    switch (ctx->opcode & 0xff00) {
1048
    case 0xc900:                /* and #imm,R0 */
1049
        tcg_gen_andi_i32(REG(0), REG(0), B7_0);
1050
        return;
1051
    case 0xcd00:                /* and.b #imm,@(R0,GBR) */
1052
        {
1053
            TCGv addr, val;
1054
            addr = tcg_temp_new(TCG_TYPE_I32);
1055
            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1056
            val = tcg_temp_new(TCG_TYPE_I32);
1057
            tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1058
            tcg_gen_andi_i32(val, val, B7_0);
1059
            tcg_gen_qemu_st8(val, addr, ctx->memidx);
1060
            tcg_temp_free(val);
1061
            tcg_temp_free(addr);
1062
        }
1063
        return;
1064
    case 0x8b00:                /* bf label */
1065
        CHECK_NOT_DELAY_SLOT
1066
            gen_conditional_jump(ctx, ctx->pc + 2,
1067
                                 ctx->pc + 4 + B7_0s * 2);
1068
        ctx->bstate = BS_BRANCH;
1069
        return;
1070
    case 0x8f00:                /* bf/s label */
1071
        CHECK_NOT_DELAY_SLOT
1072
        gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);
1073
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
1074
        return;
1075
    case 0x8900:                /* bt label */
1076
        CHECK_NOT_DELAY_SLOT
1077
            gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
1078
                                 ctx->pc + 2);
1079
        ctx->bstate = BS_BRANCH;
1080
        return;
1081
    case 0x8d00:                /* bt/s label */
1082
        CHECK_NOT_DELAY_SLOT
1083
        gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);
1084
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
1085
        return;
1086
    case 0x8800:                /* cmp/eq #imm,R0 */
1087
        gen_cmp_imm(TCG_COND_EQ, REG(0), B7_0s);
1088
        return;
1089
    case 0xc400:                /* mov.b @(disp,GBR),R0 */
1090
        {
1091
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1092
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1093
            tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);
1094
            tcg_temp_free(addr);
1095
        }
1096
        return;
1097
    case 0xc500:                /* mov.w @(disp,GBR),R0 */
1098
        {
1099
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1100
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1101
            tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);
1102
            tcg_temp_free(addr);
1103
        }
1104
        return;
1105
    case 0xc600:                /* mov.l @(disp,GBR),R0 */
1106
        {
1107
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1108
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1109
            tcg_gen_qemu_ld32s(REG(0), addr, ctx->memidx);
1110
            tcg_temp_free(addr);
1111
        }
1112
        return;
1113
    case 0xc000:                /* mov.b R0,@(disp,GBR) */
1114
        {
1115
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1116
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1117
            tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);
1118
            tcg_temp_free(addr);
1119
        }
1120
        return;
1121
    case 0xc100:                /* mov.w R0,@(disp,GBR) */
1122
        {
1123
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1124
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1125
            tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);
1126
            tcg_temp_free(addr);
1127
        }
1128
        return;
1129
    case 0xc200:                /* mov.l R0,@(disp,GBR) */
1130
        {
1131
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1132
            tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1133
            tcg_gen_qemu_st32(REG(0), addr, ctx->memidx);
1134
            tcg_temp_free(addr);
1135
        }
1136
        return;
1137
    case 0x8000:                /* mov.b R0,@(disp,Rn) */
1138
        {
1139
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1140
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1141
            tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);
1142
            tcg_temp_free(addr);
1143
        }
1144
        return;
1145
    case 0x8100:                /* mov.w R0,@(disp,Rn) */
1146
        {
1147
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1148
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1149
            tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);
1150
            tcg_temp_free(addr);
1151
        }
1152
        return;
1153
    case 0x8400:                /* mov.b @(disp,Rn),R0 */
1154
        {
1155
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1156
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1157
            tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);
1158
            tcg_temp_free(addr);
1159
        }
1160
        return;
1161
    case 0x8500:                /* mov.w @(disp,Rn),R0 */
1162
        {
1163
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1164
            tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1165
            tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);
1166
            tcg_temp_free(addr);
1167
        }
1168
        return;
1169
    case 0xc700:                /* mova @(disp,PC),R0 */
1170
        tcg_gen_movi_i32(REG(0), ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
1171
        return;
1172
    case 0xcb00:                /* or #imm,R0 */
1173
        tcg_gen_ori_i32(REG(0), REG(0), B7_0);
1174
        return;
1175
    case 0xcf00:                /* or.b #imm,@(R0,GBR) */
1176
        {
1177
            TCGv addr, val;
1178
            addr = tcg_temp_new(TCG_TYPE_I32);
1179
            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1180
            val = tcg_temp_new(TCG_TYPE_I32);
1181
            tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1182
            tcg_gen_ori_i32(val, val, B7_0);
1183
            tcg_gen_qemu_st8(val, addr, ctx->memidx);
1184
            tcg_temp_free(val);
1185
            tcg_temp_free(addr);
1186
        }
1187
        return;
1188
    case 0xc300:                /* trapa #imm */
1189
        {
1190
            TCGv imm;
1191
            CHECK_NOT_DELAY_SLOT
1192
            tcg_gen_movi_i32(cpu_pc, ctx->pc);
1193
            imm = tcg_const_i32(B7_0);
1194
            tcg_gen_helper_0_1(helper_trapa, imm);
1195
            tcg_temp_free(imm);
1196
            ctx->bstate = BS_BRANCH;
1197
        }
1198
        return;
1199
    case 0xc800:                /* tst #imm,R0 */
1200
        {
1201
            TCGv val = tcg_temp_new(TCG_TYPE_I32);
1202
            tcg_gen_andi_i32(val, REG(0), B7_0);
1203
            gen_cmp_imm(TCG_COND_EQ, val, 0);
1204
            tcg_temp_free(val);
1205
        }
1206
        return;
1207
    case 0xcc00:                /* tst.b #imm,@(R0,GBR) */
1208
        {
1209
            TCGv val = tcg_temp_new(TCG_TYPE_I32);
1210
            tcg_gen_add_i32(val, REG(0), cpu_gbr);
1211
            tcg_gen_qemu_ld8u(val, val, ctx->memidx);
1212
            tcg_gen_andi_i32(val, val, B7_0);
1213
            gen_cmp_imm(TCG_COND_EQ, val, 0);
1214
            tcg_temp_free(val);
1215
        }
1216
        return;
1217
    case 0xca00:                /* xor #imm,R0 */
1218
        tcg_gen_xori_i32(REG(0), REG(0), B7_0);
1219
        return;
1220
    case 0xce00:                /* xor.b #imm,@(R0,GBR) */
1221
        {
1222
            TCGv addr, val;
1223
            addr = tcg_temp_new(TCG_TYPE_I32);
1224
            tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1225
            val = tcg_temp_new(TCG_TYPE_I32);
1226
            tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1227
            tcg_gen_xori_i32(val, val, B7_0);
1228
            tcg_gen_qemu_st8(val, addr, ctx->memidx);
1229
            tcg_temp_free(val);
1230
            tcg_temp_free(addr);
1231
        }
1232
        return;
1233
    }
1234

    
1235
    switch (ctx->opcode & 0xf08f) {
1236
    case 0x408e:                /* ldc Rm,Rn_BANK */
1237
        tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
1238
        return;
1239
    case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
1240
        tcg_gen_qemu_ld32s(ALTREG(B6_4), REG(B11_8), ctx->memidx);
1241
        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1242
        return;
1243
    case 0x0082:                /* stc Rm_BANK,Rn */
1244
        tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
1245
        return;
1246
    case 0x4083:                /* stc.l Rm_BANK,@-Rn */
1247
        {
1248
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1249
            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1250
            tcg_gen_qemu_st32(ALTREG(B6_4), addr, ctx->memidx);
1251
            tcg_temp_free(addr);
1252
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1253
        }
1254
        return;
1255
    }
1256

    
1257
    switch (ctx->opcode & 0xf0ff) {
1258
    case 0x0023:                /* braf Rn */
1259
        CHECK_NOT_DELAY_SLOT
1260
        tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->pc + 4);
1261
        ctx->flags |= DELAY_SLOT;
1262
        ctx->delayed_pc = (uint32_t) - 1;
1263
        return;
1264
    case 0x0003:                /* bsrf Rn */
1265
        CHECK_NOT_DELAY_SLOT
1266
        tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1267
        tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);
1268
        ctx->flags |= DELAY_SLOT;
1269
        ctx->delayed_pc = (uint32_t) - 1;
1270
        return;
1271
    case 0x4015:                /* cmp/pl Rn */
1272
        gen_cmp_imm(TCG_COND_GT, REG(B11_8), 0);
1273
        return;
1274
    case 0x4011:                /* cmp/pz Rn */
1275
        gen_cmp_imm(TCG_COND_GE, REG(B11_8), 0);
1276
        return;
1277
    case 0x4010:                /* dt Rn */
1278
        tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);
1279
        gen_cmp_imm(TCG_COND_EQ, REG(B11_8), 0);
1280
        return;
1281
    case 0x402b:                /* jmp @Rn */
1282
        CHECK_NOT_DELAY_SLOT
1283
        tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1284
        ctx->flags |= DELAY_SLOT;
1285
        ctx->delayed_pc = (uint32_t) - 1;
1286
        return;
1287
    case 0x400b:                /* jsr @Rn */
1288
        CHECK_NOT_DELAY_SLOT
1289
        tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1290
        tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1291
        ctx->flags |= DELAY_SLOT;
1292
        ctx->delayed_pc = (uint32_t) - 1;
1293
        return;
1294
    case 0x400e:                /* lds Rm,SR */
1295
        tcg_gen_andi_i32(cpu_sr, REG(B11_8), 0x700083f3);
1296
        ctx->bstate = BS_STOP;
1297
        return;
1298
    case 0x4007:                /* lds.l @Rm+,SR */
1299
        {
1300
            TCGv val = tcg_temp_new(TCG_TYPE_I32);
1301
            tcg_gen_qemu_ld32s(val, REG(B11_8), ctx->memidx);
1302
            tcg_gen_andi_i32(cpu_sr, val, 0x700083f3);
1303
            tcg_temp_free(val);
1304
            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1305
            ctx->bstate = BS_STOP;
1306
        }
1307
        return;
1308
    case 0x0002:                /* sts SR,Rn */
1309
        tcg_gen_mov_i32(REG(B11_8), cpu_sr);
1310
        return;
1311
    case 0x4003:                /* sts SR,@-Rn */
1312
        {
1313
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1314
            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1315
            tcg_gen_qemu_st32(cpu_sr, addr, ctx->memidx);
1316
            tcg_temp_free(addr);
1317
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1318
        }
1319
        return;
1320
#define LDST(reg,ldnum,ldpnum,stnum,stpnum)                        \
1321
  case ldnum:                                                        \
1322
    tcg_gen_mov_i32 (cpu_##reg, REG(B11_8));                        \
1323
    return;                                                        \
1324
  case ldpnum:                                                        \
1325
    tcg_gen_qemu_ld32s (cpu_##reg, REG(B11_8), ctx->memidx);        \
1326
    tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);                \
1327
    return;                                                        \
1328
  case stnum:                                                        \
1329
    tcg_gen_mov_i32 (REG(B11_8), cpu_##reg);                        \
1330
    return;                                                        \
1331
  case stpnum:                                                        \
1332
    {                                                                \
1333
        TCGv addr = tcg_temp_new(TCG_TYPE_I32);                        \
1334
        tcg_gen_subi_i32(addr, REG(B11_8), 4);                        \
1335
        tcg_gen_qemu_st32 (cpu_##reg, addr, ctx->memidx);        \
1336
        tcg_temp_free(addr);                                        \
1337
        tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);                \
1338
    }
1339
    return;
1340
        LDST(gbr,  0x401e, 0x4017, 0x0012, 0x4013)
1341
        LDST(vbr,  0x402e, 0x4027, 0x0022, 0x4023)
1342
        LDST(ssr,  0x403e, 0x4037, 0x0032, 0x4033)
1343
        LDST(spc,  0x404e, 0x4047, 0x0042, 0x4043)
1344
        LDST(dbr,  0x40fa, 0x40f6, 0x00fa, 0x40f2)
1345
        LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002)
1346
        LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012)
1347
        LDST(pr,   0x402a, 0x4026, 0x002a, 0x4022)
1348
        LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052)
1349
    case 0x406a:                /* lds Rm,FPSCR */
1350
        tcg_gen_helper_0_1(helper_ld_fpscr, REG(B11_8));
1351
        ctx->bstate = BS_STOP;
1352
        return;
1353
    case 0x4066:                /* lds.l @Rm+,FPSCR */
1354
        {
1355
            TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1356
            tcg_gen_qemu_ld32s(addr, REG(B11_8), ctx->memidx);
1357
            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1358
            tcg_gen_helper_0_1(helper_ld_fpscr, addr);
1359
            tcg_temp_free(addr);
1360
            ctx->bstate = BS_STOP;
1361
        }
1362
        return;
1363
    case 0x006a:                /* sts FPSCR,Rn */
1364
        tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);
1365
        return;
1366
    case 0x4062:                /* sts FPSCR,@-Rn */
1367
        {
1368
            TCGv addr, val;
1369
            val = tcg_temp_new(TCG_TYPE_I32);
1370
            tcg_gen_andi_i32(val, cpu_fpscr, 0x003fffff);
1371
            addr = tcg_temp_new(TCG_TYPE_I32);
1372
            tcg_gen_subi_i32(addr, REG(B11_8), 4);
1373
            tcg_gen_qemu_st32(val, addr, ctx->memidx);
1374
            tcg_temp_free(addr);
1375
            tcg_temp_free(val);
1376
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1377
        }
1378
        return;
1379
    case 0x00c3:                /* movca.l R0,@Rm */
1380
        tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx);
1381
        return;
1382
    case 0x0029:                /* movt Rn */
1383
        tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T);
1384
        return;
1385
    case 0x0093:                /* ocbi @Rn */
1386
        {
1387
            TCGv dummy = tcg_temp_new(TCG_TYPE_I32);
1388
            tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1389
            tcg_temp_free(dummy);
1390
        }
1391
        return;
1392
    case 0x00a3:                /* ocbp @Rn */
1393
        {
1394
            TCGv dummy = tcg_temp_new(TCG_TYPE_I32);
1395
            tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1396
            tcg_temp_free(dummy);
1397
        }
1398
        return;
1399
    case 0x00b3:                /* ocbwb @Rn */
1400
        {
1401
            TCGv dummy = tcg_temp_new(TCG_TYPE_I32);
1402
            tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1403
            tcg_temp_free(dummy);
1404
        }
1405
        return;
1406
    case 0x0083:                /* pref @Rn */
1407
        return;
1408
    case 0x4024:                /* rotcl Rn */
1409
        {
1410
            TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
1411
            tcg_gen_mov_i32(tmp, cpu_sr);
1412
            gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1413
            tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1414
            gen_copy_bit_i32(REG(B11_8), 0, tmp, 0);
1415
            tcg_temp_free(tmp);
1416
        }
1417
        return;
1418
    case 0x4025:                /* rotcr Rn */
1419
        {
1420
            TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
1421
            tcg_gen_mov_i32(tmp, cpu_sr);
1422
            gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1423
            tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1424
            gen_copy_bit_i32(REG(B11_8), 31, tmp, 0);
1425
            tcg_temp_free(tmp);
1426
        }
1427
        return;
1428
    case 0x4004:                /* rotl Rn */
1429
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1430
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1431
        gen_copy_bit_i32(REG(B11_8), 0, cpu_sr, 0);
1432
        return;
1433
    case 0x4005:                /* rotr Rn */
1434
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1435
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1436
        gen_copy_bit_i32(REG(B11_8), 31, cpu_sr, 0);
1437
        return;
1438
    case 0x4000:                /* shll Rn */
1439
    case 0x4020:                /* shal Rn */
1440
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1441
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1442
        return;
1443
    case 0x4021:                /* shar Rn */
1444
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1445
        tcg_gen_sari_i32(REG(B11_8), REG(B11_8), 1);
1446
        return;
1447
    case 0x4001:                /* shlr Rn */
1448
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1449
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1450
        return;
1451
    case 0x4008:                /* shll2 Rn */
1452
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 2);
1453
        return;
1454
    case 0x4018:                /* shll8 Rn */
1455
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 8);
1456
        return;
1457
    case 0x4028:                /* shll16 Rn */
1458
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 16);
1459
        return;
1460
    case 0x4009:                /* shlr2 Rn */
1461
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 2);
1462
        return;
1463
    case 0x4019:                /* shlr8 Rn */
1464
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 8);
1465
        return;
1466
    case 0x4029:                /* shlr16 Rn */
1467
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16);
1468
        return;
1469
    case 0x401b:                /* tas.b @Rn */
1470
        {
1471
            TCGv addr, val;
1472
            addr = tcg_temp_local_new(TCG_TYPE_I32);
1473
            tcg_gen_mov_i32(addr, REG(B11_8));
1474
            val = tcg_temp_local_new(TCG_TYPE_I32);
1475
            tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1476
            gen_cmp_imm(TCG_COND_EQ, val, 0);
1477
            tcg_gen_ori_i32(val, val, 0x80);
1478
            tcg_gen_qemu_st8(val, addr, ctx->memidx);
1479
            tcg_temp_free(val);
1480
            tcg_temp_free(addr);
1481
        }
1482
        return;
1483
    case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1484
        gen_op_movl_fpul_FT0();
1485
        gen_op_fmov_FT0_frN(FREG(B11_8));
1486
        return;
1487
    case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1488
        gen_op_fmov_frN_FT0(FREG(B11_8));
1489
        gen_op_movl_FT0_fpul();
1490
        return;
1491
    case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1492
        if (ctx->fpscr & FPSCR_PR) {
1493
            if (ctx->opcode & 0x0100)
1494
                break; /* illegal instruction */
1495
            gen_op_float_DT();
1496
            gen_op_fmov_DT0_drN(DREG(B11_8));
1497
        }
1498
        else {
1499
            gen_op_float_FT();
1500
            gen_op_fmov_FT0_frN(FREG(B11_8));
1501
        }
1502
        return;
1503
    case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1504
        if (ctx->fpscr & FPSCR_PR) {
1505
            if (ctx->opcode & 0x0100)
1506
                break; /* illegal instruction */
1507
            gen_op_fmov_drN_DT0(DREG(B11_8));
1508
            gen_op_ftrc_DT();
1509
        }
1510
        else {
1511
            gen_op_fmov_frN_FT0(FREG(B11_8));
1512
            gen_op_ftrc_FT();
1513
        }
1514
        return;
1515
    case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1516
        gen_op_fneg_frN(FREG(B11_8));
1517
        return;
1518
    case 0xf05d: /* fabs FRn/DRn */
1519
        if (ctx->fpscr & FPSCR_PR) {
1520
            if (ctx->opcode & 0x0100)
1521
                break; /* illegal instruction */
1522
            gen_op_fmov_drN_DT0(DREG(B11_8));
1523
            gen_op_fabs_DT();
1524
            gen_op_fmov_DT0_drN(DREG(B11_8));
1525
        } else {
1526
            gen_op_fmov_frN_FT0(FREG(B11_8));
1527
            gen_op_fabs_FT();
1528
            gen_op_fmov_FT0_frN(FREG(B11_8));
1529
        }
1530
        return;
1531
    case 0xf06d: /* fsqrt FRn */
1532
        if (ctx->fpscr & FPSCR_PR) {
1533
            if (ctx->opcode & 0x0100)
1534
                break; /* illegal instruction */
1535
            gen_op_fmov_drN_DT0(FREG(B11_8));
1536
            gen_op_fsqrt_DT();
1537
            gen_op_fmov_DT0_drN(FREG(B11_8));
1538
        } else {
1539
            gen_op_fmov_frN_FT0(FREG(B11_8));
1540
            gen_op_fsqrt_FT();
1541
            gen_op_fmov_FT0_frN(FREG(B11_8));
1542
        }
1543
        return;
1544
    case 0xf07d: /* fsrra FRn */
1545
        break;
1546
    case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1547
        if (!(ctx->fpscr & FPSCR_PR)) {
1548
            tcg_gen_movi_i32(cpu_T[0], 0);
1549
            gen_op_fmov_T0_frN(FREG(B11_8));
1550
            return;
1551
        }
1552
        break;
1553
    case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1554
        if (!(ctx->fpscr & FPSCR_PR)) {
1555
            tcg_gen_movi_i32(cpu_T[0], 0x3f800000);
1556
            gen_op_fmov_T0_frN(FREG(B11_8));
1557
            return;
1558
        }
1559
        break;
1560
    case 0xf0ad: /* fcnvsd FPUL,DRn */
1561
        gen_op_movl_fpul_FT0();
1562
        gen_op_fcnvsd_FT_DT();
1563
        gen_op_fmov_DT0_drN(DREG(B11_8));
1564
        return;
1565
    case 0xf0bd: /* fcnvds DRn,FPUL */
1566
        gen_op_fmov_drN_DT0(DREG(B11_8));
1567
        gen_op_fcnvds_DT_FT();
1568
        gen_op_movl_FT0_fpul();
1569
        return;
1570
    }
1571

    
1572
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1573
            ctx->opcode, ctx->pc);
1574
    tcg_gen_helper_0_0(helper_raise_illegal_instruction);
1575
    ctx->bstate = BS_EXCP;
1576
}
1577

    
1578
void decode_opc(DisasContext * ctx)
1579
{
1580
    uint32_t old_flags = ctx->flags;
1581

    
1582
    _decode_opc(ctx);
1583

    
1584
    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1585
        if (ctx->flags & DELAY_SLOT_CLEARME) {
1586
            gen_store_flags(0);
1587
        } else {
1588
            /* go out of the delay slot */
1589
            uint32_t new_flags = ctx->flags;
1590
            new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1591
            gen_store_flags(new_flags);
1592
        }
1593
        ctx->flags = 0;
1594
        ctx->bstate = BS_BRANCH;
1595
        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1596
            gen_delayed_conditional_jump(ctx);
1597
        } else if (old_flags & DELAY_SLOT) {
1598
            gen_jump(ctx);
1599
        }
1600

    
1601
    }
1602

    
1603
    /* go into a delay slot */
1604
    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1605
        gen_store_flags(ctx->flags);
1606
}
1607

    
1608
static inline void
1609
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1610
                               int search_pc)
1611
{
1612
    DisasContext ctx;
1613
    target_ulong pc_start;
1614
    static uint16_t *gen_opc_end;
1615
    int i, ii;
1616
    int num_insns;
1617
    int max_insns;
1618

    
1619
    pc_start = tb->pc;
1620
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1621
    ctx.pc = pc_start;
1622
    ctx.flags = (uint32_t)tb->flags;
1623
    ctx.bstate = BS_NONE;
1624
    ctx.sr = env->sr;
1625
    ctx.fpscr = env->fpscr;
1626
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1627
    /* We don't know if the delayed pc came from a dynamic or static branch,
1628
       so assume it is a dynamic branch.  */
1629
    ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1630
    ctx.tb = tb;
1631
    ctx.singlestep_enabled = env->singlestep_enabled;
1632

    
1633
#ifdef DEBUG_DISAS
1634
    if (loglevel & CPU_LOG_TB_CPU) {
1635
        fprintf(logfile,
1636
                "------------------------------------------------\n");
1637
        cpu_dump_state(env, logfile, fprintf, 0);
1638
    }
1639
#endif
1640

    
1641
    ii = -1;
1642
    num_insns = 0;
1643
    max_insns = tb->cflags & CF_COUNT_MASK;
1644
    if (max_insns == 0)
1645
        max_insns = CF_COUNT_MASK;
1646
    gen_icount_start();
1647
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1648
        if (env->nb_breakpoints > 0) {
1649
            for (i = 0; i < env->nb_breakpoints; i++) {
1650
                if (ctx.pc == env->breakpoints[i]) {
1651
                    /* We have hit a breakpoint - make sure PC is up-to-date */
1652
                    tcg_gen_movi_i32(cpu_pc, ctx.pc);
1653
                    tcg_gen_helper_0_0(helper_debug);
1654
                    ctx.bstate = BS_EXCP;
1655
                    break;
1656
                }
1657
            }
1658
        }
1659
        if (search_pc) {
1660
            i = gen_opc_ptr - gen_opc_buf;
1661
            if (ii < i) {
1662
                ii++;
1663
                while (ii < i)
1664
                    gen_opc_instr_start[ii++] = 0;
1665
            }
1666
            gen_opc_pc[ii] = ctx.pc;
1667
            gen_opc_hflags[ii] = ctx.flags;
1668
            gen_opc_instr_start[ii] = 1;
1669
            gen_opc_icount[ii] = num_insns;
1670
        }
1671
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1672
            gen_io_start();
1673
#if 0
1674
        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1675
        fflush(stderr);
1676
#endif
1677
        ctx.opcode = lduw_code(ctx.pc);
1678
        decode_opc(&ctx);
1679
        num_insns++;
1680
        ctx.pc += 2;
1681
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1682
            break;
1683
        if (env->singlestep_enabled)
1684
            break;
1685
        if (num_insns >= max_insns)
1686
            break;
1687
#ifdef SH4_SINGLE_STEP
1688
        break;
1689
#endif
1690
    }
1691
    if (tb->cflags & CF_LAST_IO)
1692
        gen_io_end();
1693
    if (env->singlestep_enabled) {
1694
        tcg_gen_helper_0_0(helper_debug);
1695
    } else {
1696
        switch (ctx.bstate) {
1697
        case BS_STOP:
1698
            /* gen_op_interrupt_restart(); */
1699
            /* fall through */
1700
        case BS_NONE:
1701
            if (ctx.flags) {
1702
                gen_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1703
            }
1704
            gen_goto_tb(&ctx, 0, ctx.pc);
1705
            break;
1706
        case BS_EXCP:
1707
            /* gen_op_interrupt_restart(); */
1708
            tcg_gen_exit_tb(0);
1709
            break;
1710
        case BS_BRANCH:
1711
        default:
1712
            break;
1713
        }
1714
    }
1715

    
1716
    gen_icount_end(tb, num_insns);
1717
    *gen_opc_ptr = INDEX_op_end;
1718
    if (search_pc) {
1719
        i = gen_opc_ptr - gen_opc_buf;
1720
        ii++;
1721
        while (ii <= i)
1722
            gen_opc_instr_start[ii++] = 0;
1723
    } else {
1724
        tb->size = ctx.pc - pc_start;
1725
        tb->icount = num_insns;
1726
    }
1727

    
1728
#ifdef DEBUG_DISAS
1729
#ifdef SH4_DEBUG_DISAS
1730
    if (loglevel & CPU_LOG_TB_IN_ASM)
1731
        fprintf(logfile, "\n");
1732
#endif
1733
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1734
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1735
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1736
        fprintf(logfile, "\n");
1737
    }
1738
#endif
1739
}
1740

    
1741
void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1742
{
1743
    gen_intermediate_code_internal(env, tb, 0);
1744
}
1745

    
1746
void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1747
{
1748
    gen_intermediate_code_internal(env, tb, 1);
1749
}
1750

    
1751
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1752
                unsigned long searched_pc, int pc_pos, void *puc)
1753
{
1754
    env->pc = gen_opc_pc[pc_pos];
1755
    env->flags = gen_opc_hflags[pc_pos];
1756
}