Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (47.2 kB)

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

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

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

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

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

    
60
/* global register indexes */
61
static TCGv cpu_env;
62
static TCGv cpu_gregs[24];
63
static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
64
static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
65
static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_flags;
66

    
67
/* internal register indexes */
68
static TCGv cpu_flags, cpu_delayed_pc;
69

    
70
/* 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
    int label = gen_new_label();
265
    tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
266
    tcg_gen_andi_i32(cpu_T[0], cpu_sr, SR_T);
267
    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], t ? SR_T : 0, label);
268
    tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
269
    gen_set_label(label);
270
}
271

    
272
/* Immediate conditional jump (bt or bf) */
273
static void gen_conditional_jump(DisasContext * ctx,
274
                                 target_ulong ift, target_ulong ifnott)
275
{
276
    int l1;
277

    
278
    l1 = gen_new_label();
279
    tcg_gen_andi_i32(cpu_T[0], cpu_sr, SR_T);
280
    tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], SR_T, l1);
281
    gen_goto_tb(ctx, 0, ifnott);
282
    gen_set_label(l1);
283
    gen_goto_tb(ctx, 1, ift);
284
}
285

    
286
/* Delayed conditional jump (bt or bf) */
287
static void gen_delayed_conditional_jump(DisasContext * ctx)
288
{
289
    int l1;
290

    
291
    l1 = gen_new_label();
292
    tcg_gen_andi_i32(cpu_T[0], cpu_flags, DELAY_SLOT_TRUE);
293
    tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], DELAY_SLOT_TRUE, l1);
294
    gen_goto_tb(ctx, 1, ctx->pc + 2);
295
    gen_set_label(l1);
296
    tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
297
    gen_jump(ctx);
298
}
299

    
300
static inline void gen_set_t(void)
301
{
302
    tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
303
}
304

    
305
static inline void gen_clr_t(void)
306
{
307
    tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
308
}
309

    
310
static inline void gen_cmp(int cond, TCGv t0, TCGv t1)
311
{
312
    int label1 = gen_new_label();
313
    int label2 = gen_new_label();
314
    tcg_gen_brcond_i32(cond, t1, t0, label1);
315
    gen_clr_t();
316
    tcg_gen_br(label2);
317
    gen_set_label(label1);
318
    gen_set_t();
319
    gen_set_label(label2);
320
}
321

    
322
static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
323
{
324
    int label1 = gen_new_label();
325
    int label2 = gen_new_label();
326
    tcg_gen_brcondi_i32(cond, t0, imm, label1);
327
    gen_clr_t();
328
    tcg_gen_br(label2);
329
    gen_set_label(label1);
330
    gen_set_t();
331
    gen_set_label(label2);
332
}
333

    
334
static inline void gen_store_flags(uint32_t flags)
335
{
336
    tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
337
    tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
338
}
339

    
340
static inline void gen_copy_bit_i32(TCGv t0, int p0, TCGv t1, int p1)
341
{
342
    TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
343

    
344
    p0 &= 0x1f;
345
    p1 &= 0x1f;
346

    
347
    tcg_gen_andi_i32(tmp, t1, (1 << p1));
348
    tcg_gen_andi_i32(t0, t0, ~(1 << p0));
349
    if (p0 < p1)
350
        tcg_gen_shri_i32(tmp, tmp, p1 - p0);
351
    else if (p0 > p1)
352
        tcg_gen_shli_i32(tmp, tmp, p0 - p1);
353
    tcg_gen_or_i32(t0, t0, tmp);
354

    
355
    tcg_temp_free(tmp);
356
}
357

    
358
#define B3_0 (ctx->opcode & 0xf)
359
#define B6_4 ((ctx->opcode >> 4) & 0x7)
360
#define B7_4 ((ctx->opcode >> 4) & 0xf)
361
#define B7_0 (ctx->opcode & 0xff)
362
#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
363
#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
364
  (ctx->opcode & 0xfff))
365
#define B11_8 ((ctx->opcode >> 8) & 0xf)
366
#define B15_12 ((ctx->opcode >> 12) & 0xf)
367

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

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

    
374
#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
375
#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
376
#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
377
#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
378

    
379
#define CHECK_NOT_DELAY_SLOT \
380
  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
381
  {tcg_gen_helper_0_0(helper_raise_slot_illegal_instruction); ctx->bstate = BS_EXCP; \
382
   return;}
383

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

    
449
    switch (ctx->opcode & 0xf000) {
450
    case 0x1000:                /* mov.l Rm,@(disp,Rn) */
451
        tcg_gen_addi_i32(cpu_T[0], REG(B11_8), B3_0 * 4);
452
        tcg_gen_qemu_st32(REG(B7_4), cpu_T[0], ctx->memidx);
453
        return;
454
    case 0x5000:                /* mov.l @(disp,Rm),Rn */
455
        tcg_gen_addi_i32(cpu_T[0], REG(B7_4), B3_0 * 4);
456
        tcg_gen_qemu_ld32s(REG(B11_8), cpu_T[0], ctx->memidx);
457
        return;
458
    case 0xe000:                /* mov #imm,Rn */
459
        tcg_gen_movi_i32(REG(B11_8), B7_0s);
460
        return;
461
    case 0x9000:                /* mov.w @(disp,PC),Rn */
462
        tcg_gen_movi_i32(cpu_T[0], ctx->pc + 4 + B7_0 * 2);
463
        tcg_gen_qemu_ld16s(REG(B11_8), cpu_T[0], ctx->memidx);
464
        return;
465
    case 0xd000:                /* mov.l @(disp,PC),Rn */
466
        tcg_gen_movi_i32(cpu_T[0], (ctx->pc + 4 + B7_0 * 4) & ~3);
467
        tcg_gen_qemu_ld32s(REG(B11_8), cpu_T[0], ctx->memidx);
468
        return;
469
    case 0x7000:                /* add #imm,Rn */
470
        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);
471
        return;
472
    case 0xa000:                /* bra disp */
473
        CHECK_NOT_DELAY_SLOT
474
        ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
475
        tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
476
        ctx->flags |= DELAY_SLOT;
477
        return;
478
    case 0xb000:                /* bsr disp */
479
        CHECK_NOT_DELAY_SLOT
480
        tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
481
        ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
482
        tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
483
        ctx->flags |= DELAY_SLOT;
484
        return;
485
    }
486

    
487
    switch (ctx->opcode & 0xf00f) {
488
    case 0x6003:                /* mov Rm,Rn */
489
        tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
490
        return;
491
    case 0x2000:                /* mov.b Rm,@Rn */
492
        tcg_gen_qemu_st8(REG(B7_4), REG(B11_8), ctx->memidx);
493
        return;
494
    case 0x2001:                /* mov.w Rm,@Rn */
495
        tcg_gen_qemu_st16(REG(B7_4), REG(B11_8), ctx->memidx);
496
        return;
497
    case 0x2002:                /* mov.l Rm,@Rn */
498
        tcg_gen_qemu_st32(REG(B7_4), REG(B11_8), ctx->memidx);
499
        return;
500
    case 0x6000:                /* mov.b @Rm,Rn */
501
        tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);
502
        return;
503
    case 0x6001:                /* mov.w @Rm,Rn */
504
        tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);
505
        return;
506
    case 0x6002:                /* mov.l @Rm,Rn */
507
        tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);
508
        return;
509
    case 0x2004:                /* mov.b Rm,@-Rn */
510
        tcg_gen_subi_i32(cpu_T[0], REG(B11_8), 1);
511
        tcg_gen_qemu_st8(REG(B7_4), cpu_T[0], ctx->memidx);        /* might cause re-execution */
512
        tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);                /* modify register status */
513
        return;
514
    case 0x2005:                /* mov.w Rm,@-Rn */
515
        tcg_gen_subi_i32(cpu_T[0], REG(B11_8), 2);
516
        tcg_gen_qemu_st16(REG(B7_4), cpu_T[0], ctx->memidx);
517
        tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 2);
518
        return;
519
    case 0x2006:                /* mov.l Rm,@-Rn */
520
        tcg_gen_subi_i32(cpu_T[0], REG(B11_8), 4);
521
        tcg_gen_qemu_st32(REG(B7_4), cpu_T[0], ctx->memidx);
522
        tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
523
        return;
524
    case 0x6004:                /* mov.b @Rm+,Rn */
525
        tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);
526
        if ( B11_8 != B7_4 )
527
                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 1);
528
        return;
529
    case 0x6005:                /* mov.w @Rm+,Rn */
530
        tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);
531
        if ( B11_8 != B7_4 )
532
                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
533
        return;
534
    case 0x6006:                /* mov.l @Rm+,Rn */
535
        tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);
536
        if ( B11_8 != B7_4 )
537
                tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
538
        return;
539
    case 0x0004:                /* mov.b Rm,@(R0,Rn) */
540
        tcg_gen_add_i32(cpu_T[0], REG(B11_8), REG(0));
541
        tcg_gen_qemu_st8(REG(B7_4), cpu_T[0], ctx->memidx);
542
        return;
543
    case 0x0005:                /* mov.w Rm,@(R0,Rn) */
544
        tcg_gen_add_i32(cpu_T[0], REG(B11_8), REG(0));
545
        tcg_gen_qemu_st16(REG(B7_4), cpu_T[0], ctx->memidx);
546
        return;
547
    case 0x0006:                /* mov.l Rm,@(R0,Rn) */
548
        tcg_gen_add_i32(cpu_T[0], REG(B11_8), REG(0));
549
        tcg_gen_qemu_st32(REG(B7_4), cpu_T[0], ctx->memidx);
550
        return;
551
    case 0x000c:                /* mov.b @(R0,Rm),Rn */
552
        tcg_gen_add_i32(cpu_T[0], REG(B7_4), REG(0));
553
        tcg_gen_qemu_ld8s(REG(B11_8), cpu_T[0], ctx->memidx);
554
        return;
555
    case 0x000d:                /* mov.w @(R0,Rm),Rn */
556
        tcg_gen_add_i32(cpu_T[0], REG(B7_4), REG(0));
557
        tcg_gen_qemu_ld16s(REG(B11_8), cpu_T[0], ctx->memidx);
558
        return;
559
    case 0x000e:                /* mov.l @(R0,Rm),Rn */
560
        tcg_gen_add_i32(cpu_T[0], REG(B7_4), REG(0));
561
        tcg_gen_qemu_ld32s(REG(B11_8), cpu_T[0], ctx->memidx);
562
        return;
563
    case 0x6008:                /* swap.b Rm,Rn */
564
        tcg_gen_ext8u_i32(cpu_T[0], REG(B7_4));
565
        tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 8);
566
        tcg_gen_shri_i32(cpu_T[1], REG(B7_4), 8);
567
        tcg_gen_ext8u_i32(cpu_T[1], cpu_T[1]);
568
        tcg_gen_or_i32(REG(B11_8), cpu_T[0], cpu_T[1]);
569
        return;
570
    case 0x6009:                /* swap.w Rm,Rn */
571
        tcg_gen_ext16u_i32(cpu_T[0], REG(B7_4));
572
        tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
573
        tcg_gen_shri_i32(cpu_T[1], REG(B7_4), 16);
574
        tcg_gen_ext16u_i32(cpu_T[1], cpu_T[1]);
575
        tcg_gen_or_i32(REG(B11_8), cpu_T[0], cpu_T[1]);
576
        return;
577
    case 0x200d:                /* xtrct Rm,Rn */
578
        tcg_gen_ext16u_i32(cpu_T[0], REG(B7_4));
579
        tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
580
        tcg_gen_shri_i32(cpu_T[1], REG(B11_8), 16);
581
        tcg_gen_ext16u_i32(cpu_T[1], cpu_T[1]);
582
        tcg_gen_or_i32(REG(B11_8), cpu_T[0], cpu_T[1]);
583
        return;
584
    case 0x300c:                /* add Rm,Rn */
585
        tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));
586
        return;
587
    case 0x300e:                /* addc Rm,Rn */
588
        tcg_gen_helper_1_2(helper_addc, REG(B11_8), REG(B7_4), REG(B11_8));
589
        return;
590
    case 0x300f:                /* addv Rm,Rn */
591
        tcg_gen_helper_1_2(helper_addv, REG(B11_8), REG(B7_4), REG(B11_8));
592
        return;
593
    case 0x2009:                /* and Rm,Rn */
594
        tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
595
        return;
596
    case 0x3000:                /* cmp/eq Rm,Rn */
597
        gen_cmp(TCG_COND_EQ, REG(B7_4), REG(B11_8));
598
        return;
599
    case 0x3003:                /* cmp/ge Rm,Rn */
600
        gen_cmp(TCG_COND_GE, REG(B7_4), REG(B11_8));
601
        return;
602
    case 0x3007:                /* cmp/gt Rm,Rn */
603
        gen_cmp(TCG_COND_GT, REG(B7_4), REG(B11_8));
604
        return;
605
    case 0x3006:                /* cmp/hi Rm,Rn */
606
        gen_cmp(TCG_COND_GTU, REG(B7_4), REG(B11_8));
607
        return;
608
    case 0x3002:                /* cmp/hs Rm,Rn */
609
        gen_cmp(TCG_COND_GEU, REG(B7_4), REG(B11_8));
610
        return;
611
    case 0x200c:                /* cmp/str Rm,Rn */
612
        {
613
            int label1 = gen_new_label();
614
            int label2 = gen_new_label();
615
            tcg_gen_xor_i32(cpu_T[0], REG(B7_4), REG(B11_8));
616
            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff000000);
617
            tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1);
618
            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x00ff0000);
619
            tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1);
620
            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x0000ff00);
621
            tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1);
622
            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x000000ff);
623
            tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1);
624
            tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
625
            tcg_gen_br(label2);
626
            gen_set_label(label1);
627
            tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
628
            gen_set_label(label2);
629
        }
630
        return;
631
    case 0x2007:                /* div0s Rm,Rn */
632
        gen_copy_bit_i32(cpu_sr, 8, REG(B11_8), 31);        /* SR_Q */
633
        gen_copy_bit_i32(cpu_sr, 9, REG(B7_4), 31);        /* SR_M */
634
        tcg_gen_xor_i32(cpu_T[0], REG(B7_4), REG(B11_8));
635
        gen_copy_bit_i32(cpu_sr, 0, cpu_T[0], 31);        /* SR_T */
636
        return;
637
    case 0x3004:                /* div1 Rm,Rn */
638
        tcg_gen_helper_1_2(helper_div1, REG(B11_8), REG(B7_4), REG(B11_8));
639
        return;
640
    case 0x300d:                /* dmuls.l Rm,Rn */
641
        {
642
            TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
643
            TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
644

    
645
            tcg_gen_ext_i32_i64(tmp1, REG(B7_4));
646
            tcg_gen_ext_i32_i64(tmp2, REG(B11_8));
647
            tcg_gen_mul_i64(tmp1, tmp1, tmp2);
648
            tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
649
            tcg_gen_shri_i64(tmp1, tmp1, 32);
650
            tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
651

    
652
            tcg_temp_free(tmp1);
653
            tcg_temp_free(tmp2);
654
        }
655
        return;
656
    case 0x3005:                /* dmulu.l Rm,Rn */
657
        {
658
            TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
659
            TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
660

    
661
            tcg_gen_extu_i32_i64(tmp1, REG(B7_4));
662
            tcg_gen_extu_i32_i64(tmp2, REG(B11_8));
663
            tcg_gen_mul_i64(tmp1, tmp1, tmp2);
664
            tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
665
            tcg_gen_shri_i64(tmp1, tmp1, 32);
666
            tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
667

    
668
            tcg_temp_free(tmp1);
669
            tcg_temp_free(tmp2);
670
        }
671
        return;
672
    case 0x600e:                /* exts.b Rm,Rn */
673
        tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));
674
        return;
675
    case 0x600f:                /* exts.w Rm,Rn */
676
        tcg_gen_ext16s_i32(REG(B11_8), REG(B7_4));
677
        return;
678
    case 0x600c:                /* extu.b Rm,Rn */
679
        tcg_gen_ext8u_i32(REG(B11_8), REG(B7_4));
680
        return;
681
    case 0x600d:                /* extu.w Rm,Rn */
682
        tcg_gen_ext16u_i32(REG(B11_8), REG(B7_4));
683
        return;
684
    case 0x000f:                /* mac.l @Rm+,@Rn+ */
685
        tcg_gen_qemu_ld32s(cpu_T[0], REG(B7_4), ctx->memidx);
686
        tcg_gen_qemu_ld32s(cpu_T[1], REG(B11_8), ctx->memidx);
687
        tcg_gen_helper_0_2(helper_macl, cpu_T[0], cpu_T[1]);
688
        tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
689
        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
690
        return;
691
    case 0x400f:                /* mac.w @Rm+,@Rn+ */
692
        tcg_gen_qemu_ld32s(cpu_T[0], REG(B7_4), ctx->memidx);
693
        tcg_gen_qemu_ld32s(cpu_T[1], REG(B11_8), ctx->memidx);
694
        tcg_gen_helper_0_2(helper_macw, cpu_T[0], cpu_T[1]);
695
        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);
696
        tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
697
        return;
698
    case 0x0007:                /* mul.l Rm,Rn */
699
        tcg_gen_mul_i32(cpu_macl, REG(B7_4), REG(B11_8));
700
        return;
701
    case 0x200f:                /* muls.w Rm,Rn */
702
        tcg_gen_ext16s_i32(cpu_T[0], REG(B7_4));
703
        tcg_gen_ext16s_i32(cpu_T[1], REG(B11_8));
704
        tcg_gen_mul_i32(cpu_macl, cpu_T[0], cpu_T[1]);
705
        return;
706
    case 0x200e:                /* mulu.w Rm,Rn */
707
        tcg_gen_ext16u_i32(cpu_T[0], REG(B7_4));
708
        tcg_gen_ext16u_i32(cpu_T[1], REG(B11_8));
709
        tcg_gen_mul_i32(cpu_macl, cpu_T[0], cpu_T[1]);
710
        return;
711
    case 0x600b:                /* neg Rm,Rn */
712
        tcg_gen_neg_i32(REG(B11_8), REG(B7_4));
713
        return;
714
    case 0x600a:                /* negc Rm,Rn */
715
        tcg_gen_helper_1_1(helper_negc, REG(B11_8), REG(B7_4));
716
        return;
717
    case 0x6007:                /* not Rm,Rn */
718
        tcg_gen_not_i32(REG(B11_8), REG(B7_4));
719
        return;
720
    case 0x200b:                /* or Rm,Rn */
721
        tcg_gen_or_i32(REG(B11_8), REG(B11_8), REG(B7_4));
722
        return;
723
    case 0x400c:                /* shad Rm,Rn */
724
        {
725
            int label1 = gen_new_label();
726
            int label2 = gen_new_label();
727
            int label3 = gen_new_label();
728
            int label4 = gen_new_label();
729
            tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
730
            /* Rm positive, shift to the left */
731
            tcg_gen_andi_i32(cpu_T[0], REG(B7_4), 0x1f);
732
            tcg_gen_shl_i32(REG(B11_8), REG(B11_8), cpu_T[0]);
733
            tcg_gen_br(label4);
734
            /* Rm negative, shift to the right */
735
            gen_set_label(label1);
736
            tcg_gen_andi_i32(cpu_T[0], REG(B7_4), 0x1f);
737
            tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label2);
738
            tcg_gen_not_i32(cpu_T[0], REG(B7_4));
739
            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x1f);
740
            tcg_gen_addi_i32(cpu_T[0], cpu_T[0], 1);
741
            tcg_gen_sar_i32(REG(B11_8), REG(B11_8), cpu_T[0]);
742
            tcg_gen_br(label4);
743
            /* Rm = -32 */
744
            gen_set_label(label2);
745
            tcg_gen_brcondi_i32(TCG_COND_LT, REG(B11_8), 0, label3);
746
            tcg_gen_movi_i32(REG(B11_8), 0);
747
            tcg_gen_br(label4);
748
            gen_set_label(label3);
749
            tcg_gen_movi_i32(REG(B11_8), 0xffffffff);
750
            gen_set_label(label4);
751
        }
752
        return;
753
    case 0x400d:                /* shld Rm,Rn */
754
        {
755
            int label1 = gen_new_label();
756
            int label2 = gen_new_label();
757
            int label3 = gen_new_label();
758
            tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
759
            /* Rm positive, shift to the left */
760
            tcg_gen_andi_i32(cpu_T[0], REG(B7_4), 0x1f);
761
            tcg_gen_shl_i32(REG(B11_8), REG(B11_8), cpu_T[0]);
762
            tcg_gen_br(label3);
763
            /* Rm negative, shift to the right */
764
            gen_set_label(label1);
765
            tcg_gen_andi_i32(cpu_T[0], REG(B7_4), 0x1f);
766
            tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label2);
767
            tcg_gen_not_i32(cpu_T[0], REG(B7_4));
768
            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x1f);
769
            tcg_gen_addi_i32(cpu_T[0], cpu_T[0], 1);
770
            tcg_gen_shr_i32(REG(B11_8), REG(B11_8), cpu_T[0]);
771
            tcg_gen_br(label3);
772
            /* Rm = -32 */
773
            gen_set_label(label2);
774
            tcg_gen_movi_i32(REG(B11_8), 0);
775
            gen_set_label(label3);
776
        }
777
        return;
778
    case 0x3008:                /* sub Rm,Rn */
779
        tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));
780
        return;
781
    case 0x300a:                /* subc Rm,Rn */
782
        tcg_gen_helper_1_2(helper_subc, REG(B11_8), REG(B7_4), REG(B11_8));
783
        return;
784
    case 0x300b:                /* subv Rm,Rn */
785
        tcg_gen_helper_1_2(helper_subv, REG(B11_8), REG(B7_4), REG(B11_8));
786
        return;
787
    case 0x2008:                /* tst Rm,Rn */
788
        tcg_gen_and_i32(cpu_T[0], REG(B7_4), REG(B11_8));
789
        gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
790
        return;
791
    case 0x200a:                /* xor Rm,Rn */
792
        tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));
793
        return;
794
    case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
795
        if (ctx->fpscr & FPSCR_SZ) {
796
            gen_op_fmov_drN_DT0(XREG(B7_4));
797
            gen_op_fmov_DT0_drN(XREG(B11_8));
798
        } else {
799
            gen_op_fmov_frN_FT0(FREG(B7_4));
800
            gen_op_fmov_FT0_frN(FREG(B11_8));
801
        }
802
        return;
803
    case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
804
        if (ctx->fpscr & FPSCR_SZ) {
805
            gen_op_fmov_drN_DT0(XREG(B7_4));
806
            tcg_gen_mov_i32(cpu_T[1], REG(B11_8));
807
            gen_op_stfq_DT0_T1(ctx);
808
        } else {
809
            gen_op_fmov_frN_FT0(FREG(B7_4));
810
            tcg_gen_mov_i32(cpu_T[1], REG(B11_8));
811
            gen_op_stfl_FT0_T1(ctx);
812
        }
813
        return;
814
    case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
815
        if (ctx->fpscr & FPSCR_SZ) {
816
            tcg_gen_mov_i32(cpu_T[0], REG(B7_4));
817
            gen_op_ldfq_T0_DT0(ctx);
818
            gen_op_fmov_DT0_drN(XREG(B11_8));
819
        } else {
820
            tcg_gen_mov_i32(cpu_T[0], REG(B7_4));
821
            gen_op_ldfl_T0_FT0(ctx);
822
            gen_op_fmov_FT0_frN(FREG(B11_8));
823
        }
824
        return;
825
    case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
826
        if (ctx->fpscr & FPSCR_SZ) {
827
            tcg_gen_mov_i32(cpu_T[0], REG(B7_4));
828
            gen_op_ldfq_T0_DT0(ctx);
829
            gen_op_fmov_DT0_drN(XREG(B11_8));
830
            tcg_gen_addi_i32(REG(B7_4),
831
                             REG(B7_4), 8);
832
        } else {
833
            tcg_gen_mov_i32(cpu_T[0], REG(B7_4));
834
            gen_op_ldfl_T0_FT0(ctx);
835
            gen_op_fmov_FT0_frN(FREG(B11_8));
836
            tcg_gen_addi_i32(REG(B7_4),
837
                             REG(B7_4), 4);
838
        }
839
        return;
840
    case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
841
        if (ctx->fpscr & FPSCR_SZ) {
842
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 8);
843
            gen_op_fmov_drN_DT0(XREG(B7_4));
844
            tcg_gen_mov_i32(cpu_T[1], REG(B11_8));
845
            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 8);
846
            gen_op_stfq_DT0_T1(ctx);
847
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 8);
848
        } else {
849
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
850
            gen_op_fmov_frN_FT0(FREG(B7_4));
851
            tcg_gen_mov_i32(cpu_T[1], REG(B11_8));
852
            tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
853
            gen_op_stfl_FT0_T1(ctx);
854
            tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
855
        }
856
        return;
857
    case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
858
        tcg_gen_add_i32(cpu_T[0], REG(B7_4), REG(0));
859
        if (ctx->fpscr & FPSCR_SZ) {
860
            gen_op_ldfq_T0_DT0(ctx);
861
            gen_op_fmov_DT0_drN(XREG(B11_8));
862
        } else {
863
            gen_op_ldfl_T0_FT0(ctx);
864
            gen_op_fmov_FT0_frN(FREG(B11_8));
865
        }
866
        return;
867
    case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
868
        if (ctx->fpscr & FPSCR_SZ) {
869
            gen_op_fmov_drN_DT0(XREG(B7_4));
870
            tcg_gen_mov_i32(cpu_T[1], REG(B11_8));
871
            tcg_gen_add_i32(cpu_T[1], cpu_T[1], REG(0));
872
            gen_op_stfq_DT0_T1(ctx);
873
        } else {
874
            gen_op_fmov_frN_FT0(FREG(B7_4));
875
            tcg_gen_mov_i32(cpu_T[1], REG(B11_8));
876
            tcg_gen_add_i32(cpu_T[1], cpu_T[1], REG(0));
877
            gen_op_stfl_FT0_T1(ctx);
878
        }
879
        return;
880
    case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
881
    case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
882
    case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
883
    case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
884
    case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
885
    case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
886
        if (ctx->fpscr & FPSCR_PR) {
887
            if (ctx->opcode & 0x0110)
888
                break; /* illegal instruction */
889
            gen_op_fmov_drN_DT1(DREG(B7_4));
890
            gen_op_fmov_drN_DT0(DREG(B11_8));
891
        }
892
        else {
893
            gen_op_fmov_frN_FT1(FREG(B7_4));
894
            gen_op_fmov_frN_FT0(FREG(B11_8));
895
        }
896

    
897
        switch (ctx->opcode & 0xf00f) {
898
        case 0xf000:                /* fadd Rm,Rn */
899
            ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
900
            break;
901
        case 0xf001:                /* fsub Rm,Rn */
902
            ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
903
            break;
904
        case 0xf002:                /* fmul Rm,Rn */
905
            ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
906
            break;
907
        case 0xf003:                /* fdiv Rm,Rn */
908
            ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
909
            break;
910
        case 0xf004:                /* fcmp/eq Rm,Rn */
911
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
912
            return;
913
        case 0xf005:                /* fcmp/gt Rm,Rn */
914
            ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
915
            return;
916
        }
917

    
918
        if (ctx->fpscr & FPSCR_PR) {
919
            gen_op_fmov_DT0_drN(DREG(B11_8));
920
        }
921
        else {
922
            gen_op_fmov_FT0_frN(FREG(B11_8));
923
        }
924
        return;
925
    }
926

    
927
    switch (ctx->opcode & 0xff00) {
928
    case 0xc900:                /* and #imm,R0 */
929
        tcg_gen_andi_i32(REG(0), REG(0), B7_0);
930
        return;
931
    case 0xcd00:                /* and.b #imm,@(R0,GBR) */
932
        tcg_gen_add_i32(cpu_T[1], REG(0), cpu_gbr);
933
        tcg_gen_qemu_ld8u(cpu_T[0], cpu_T[1], ctx->memidx);
934
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0);
935
        tcg_gen_qemu_st8(cpu_T[0], cpu_T[1], ctx->memidx);
936
        return;
937
    case 0x8b00:                /* bf label */
938
        CHECK_NOT_DELAY_SLOT
939
            gen_conditional_jump(ctx, ctx->pc + 2,
940
                                 ctx->pc + 4 + B7_0s * 2);
941
        ctx->bstate = BS_BRANCH;
942
        return;
943
    case 0x8f00:                /* bf/s label */
944
        CHECK_NOT_DELAY_SLOT
945
        gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);
946
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
947
        return;
948
    case 0x8900:                /* bt label */
949
        CHECK_NOT_DELAY_SLOT
950
            gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
951
                                 ctx->pc + 2);
952
        ctx->bstate = BS_BRANCH;
953
        return;
954
    case 0x8d00:                /* bt/s label */
955
        CHECK_NOT_DELAY_SLOT
956
        gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);
957
        ctx->flags |= DELAY_SLOT_CONDITIONAL;
958
        return;
959
    case 0x8800:                /* cmp/eq #imm,R0 */
960
        gen_cmp_imm(TCG_COND_EQ, REG(0), B7_0s);
961
        return;
962
    case 0xc400:                /* mov.b @(disp,GBR),R0 */
963
        tcg_gen_addi_i32(cpu_T[0], cpu_gbr, B7_0);
964
        tcg_gen_qemu_ld8s(REG(0), cpu_T[0], ctx->memidx);
965
        return;
966
    case 0xc500:                /* mov.w @(disp,GBR),R0 */
967
        tcg_gen_addi_i32(cpu_T[0], cpu_gbr, B7_0 * 2);
968
        tcg_gen_qemu_ld16s(REG(0), cpu_T[0], ctx->memidx);
969
        return;
970
    case 0xc600:                /* mov.l @(disp,GBR),R0 */
971
        tcg_gen_addi_i32(cpu_T[0], cpu_gbr, B7_0 * 4);
972
        tcg_gen_qemu_ld32s(REG(0), cpu_T[0], ctx->memidx);
973
        return;
974
    case 0xc000:                /* mov.b R0,@(disp,GBR) */
975
        tcg_gen_addi_i32(cpu_T[0], cpu_gbr, B7_0);
976
        tcg_gen_qemu_st8(REG(0), cpu_T[0], ctx->memidx);
977
        return;
978
    case 0xc100:                /* mov.w R0,@(disp,GBR) */
979
        tcg_gen_addi_i32(cpu_T[0], cpu_gbr, B7_0 * 2);
980
        tcg_gen_qemu_st16(REG(0), cpu_T[0], ctx->memidx);
981
        return;
982
    case 0xc200:                /* mov.l R0,@(disp,GBR) */
983
        tcg_gen_addi_i32(cpu_T[0], cpu_gbr, B7_0 * 4);
984
        tcg_gen_qemu_st32(REG(0), cpu_T[0], ctx->memidx);
985
        return;
986
    case 0x8000:                /* mov.b R0,@(disp,Rn) */
987
        tcg_gen_addi_i32(cpu_T[0], REG(B7_4), B3_0);
988
        tcg_gen_qemu_st8(REG(0), cpu_T[0], ctx->memidx);
989
        return;
990
    case 0x8100:                /* mov.w R0,@(disp,Rn) */
991
        tcg_gen_addi_i32(cpu_T[0], REG(B7_4), B3_0 * 2);
992
        tcg_gen_qemu_st16(REG(0), cpu_T[0], ctx->memidx);
993
        return;
994
    case 0x8400:                /* mov.b @(disp,Rn),R0 */
995
        tcg_gen_addi_i32(cpu_T[0], REG(B7_4), B3_0);
996
        tcg_gen_qemu_ld8s(REG(0), cpu_T[0], ctx->memidx);
997
        return;
998
    case 0x8500:                /* mov.w @(disp,Rn),R0 */
999
        tcg_gen_addi_i32(cpu_T[0], REG(B7_4), B3_0 * 2);
1000
        tcg_gen_qemu_ld16s(REG(0), cpu_T[0], ctx->memidx);
1001
        return;
1002
    case 0xc700:                /* mova @(disp,PC),R0 */
1003
        tcg_gen_movi_i32(REG(0), ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
1004
        return;
1005
    case 0xcb00:                /* or #imm,R0 */
1006
        tcg_gen_ori_i32(REG(0), REG(0), B7_0);
1007
        return;
1008
    case 0xcf00:                /* or.b #imm,@(R0,GBR) */
1009
        tcg_gen_add_i32(cpu_T[1], REG(0), cpu_gbr);
1010
        tcg_gen_qemu_ld8u(cpu_T[0], cpu_T[1], ctx->memidx);
1011
        tcg_gen_ori_i32(cpu_T[0], cpu_T[0], B7_0);
1012
        tcg_gen_qemu_st8(cpu_T[0], cpu_T[1], ctx->memidx);
1013
        return;
1014
    case 0xc300:                /* trapa #imm */
1015
        CHECK_NOT_DELAY_SLOT
1016
        tcg_gen_movi_i32(cpu_pc, ctx->pc);
1017
        tcg_gen_movi_i32(cpu_T[0], B7_0);
1018
        tcg_gen_helper_0_1(helper_trapa, cpu_T[0]);
1019
        ctx->bstate = BS_BRANCH;
1020
        return;
1021
    case 0xc800:                /* tst #imm,R0 */
1022
        tcg_gen_andi_i32(cpu_T[0], REG(0), B7_0);
1023
        gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
1024
        return;
1025
    case 0xcc00:                /* tst.b #imm,@(R0,GBR) */
1026
        tcg_gen_add_i32(cpu_T[0], REG(0), cpu_gbr);
1027
        tcg_gen_qemu_ld8u(cpu_T[0], cpu_T[0], ctx->memidx);
1028
        tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0);
1029
        gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
1030
        return;
1031
    case 0xca00:                /* xor #imm,R0 */
1032
        tcg_gen_xori_i32(REG(0), REG(0), B7_0);
1033
        return;
1034
    case 0xce00:                /* xor.b #imm,@(R0,GBR) */
1035
        tcg_gen_add_i32(cpu_T[1], REG(0), cpu_gbr);
1036
        tcg_gen_qemu_ld8u(cpu_T[0], cpu_T[1], ctx->memidx);
1037
        tcg_gen_xori_i32(cpu_T[0], cpu_T[0], B7_0);
1038
        tcg_gen_qemu_st8(cpu_T[0], cpu_T[1], ctx->memidx);
1039
        return;
1040
    }
1041

    
1042
    switch (ctx->opcode & 0xf08f) {
1043
    case 0x408e:                /* ldc Rm,Rn_BANK */
1044
        tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
1045
        return;
1046
    case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
1047
        tcg_gen_qemu_ld32s(ALTREG(B6_4), REG(B11_8), ctx->memidx);
1048
        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1049
        return;
1050
    case 0x0082:                /* stc Rm_BANK,Rn */
1051
        tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
1052
        return;
1053
    case 0x4083:                /* stc.l Rm_BANK,@-Rn */
1054
        tcg_gen_subi_i32(cpu_T[0], REG(B11_8), 4);
1055
        tcg_gen_qemu_st32(ALTREG(B6_4), cpu_T[0], ctx->memidx);
1056
        tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1057
        return;
1058
    }
1059

    
1060
    switch (ctx->opcode & 0xf0ff) {
1061
    case 0x0023:                /* braf Rn */
1062
        CHECK_NOT_DELAY_SLOT
1063
        tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->pc + 4);
1064
        ctx->flags |= DELAY_SLOT;
1065
        ctx->delayed_pc = (uint32_t) - 1;
1066
        return;
1067
    case 0x0003:                /* bsrf Rn */
1068
        CHECK_NOT_DELAY_SLOT
1069
        tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1070
        tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);
1071
        ctx->flags |= DELAY_SLOT;
1072
        ctx->delayed_pc = (uint32_t) - 1;
1073
        return;
1074
    case 0x4015:                /* cmp/pl Rn */
1075
        gen_cmp_imm(TCG_COND_GT, REG(B11_8), 0);
1076
        return;
1077
    case 0x4011:                /* cmp/pz Rn */
1078
        gen_cmp_imm(TCG_COND_GE, REG(B11_8), 0);
1079
        return;
1080
    case 0x4010:                /* dt Rn */
1081
        tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);
1082
        gen_cmp_imm(TCG_COND_EQ, REG(B11_8), 0);
1083
        return;
1084
    case 0x402b:                /* jmp @Rn */
1085
        CHECK_NOT_DELAY_SLOT
1086
        tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1087
        ctx->flags |= DELAY_SLOT;
1088
        ctx->delayed_pc = (uint32_t) - 1;
1089
        return;
1090
    case 0x400b:                /* jsr @Rn */
1091
        CHECK_NOT_DELAY_SLOT
1092
        tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1093
        tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1094
        ctx->flags |= DELAY_SLOT;
1095
        ctx->delayed_pc = (uint32_t) - 1;
1096
        return;
1097
    case 0x400e:                /* lds Rm,SR */
1098
        tcg_gen_andi_i32(cpu_sr, REG(B11_8), 0x700083f3);
1099
        ctx->bstate = BS_STOP;
1100
        return;
1101
    case 0x4007:                /* lds.l @Rm+,SR */
1102
        tcg_gen_qemu_ld32s(cpu_T[0], REG(B11_8), ctx->memidx);
1103
        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1104
        tcg_gen_andi_i32(cpu_sr, cpu_T[0], 0x700083f3);
1105
        ctx->bstate = BS_STOP;
1106
        return;
1107
    case 0x0002:                /* sts SR,Rn */
1108
        tcg_gen_mov_i32(REG(B11_8), cpu_sr);
1109
        return;
1110
    case 0x4003:                /* sts SR,@-Rn */
1111
        tcg_gen_subi_i32(cpu_T[0], REG(B11_8), 4);
1112
        tcg_gen_qemu_st32(cpu_sr, cpu_T[0], ctx->memidx);
1113
        tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1114
        return;
1115
#define LDST(reg,ldnum,ldpnum,stnum,stpnum)                        \
1116
  case ldnum:                                                        \
1117
    tcg_gen_mov_i32 (cpu_##reg, REG(B11_8));                        \
1118
    return;                                                        \
1119
  case ldpnum:                                                        \
1120
    tcg_gen_qemu_ld32s (cpu_##reg, REG(B11_8), ctx->memidx);        \
1121
    tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);                \
1122
    return;                                                        \
1123
  case stnum:                                                        \
1124
    tcg_gen_mov_i32 (REG(B11_8), cpu_##reg);                        \
1125
    return;                                                        \
1126
  case stpnum:                                                        \
1127
    tcg_gen_subi_i32(cpu_T[0], REG(B11_8), 4);                        \
1128
    tcg_gen_qemu_st32 (cpu_##reg, cpu_T[0], ctx->memidx);        \
1129
    tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);                \
1130
    return;
1131
        LDST(gbr,  0x401e, 0x4017, 0x0012, 0x4013)
1132
        LDST(vbr,  0x402e, 0x4027, 0x0022, 0x4023)
1133
        LDST(ssr,  0x403e, 0x4037, 0x0032, 0x4033)
1134
        LDST(spc,  0x404e, 0x4047, 0x0042, 0x4043)
1135
        LDST(dbr,  0x40fa, 0x40f6, 0x00fa, 0x40f2)
1136
        LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002)
1137
        LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012)
1138
        LDST(pr,   0x402a, 0x4026, 0x002a, 0x4022)
1139
        LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052)
1140
    case 0x406a:                /* lds Rm,FPSCR */
1141
        tcg_gen_helper_0_1(helper_ld_fpscr, REG(B11_8));
1142
        ctx->bstate = BS_STOP;
1143
        return;
1144
    case 0x4066:                /* lds.l @Rm+,FPSCR */
1145
        tcg_gen_qemu_ld32s(cpu_T[0], REG(B11_8), ctx->memidx);
1146
        tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1147
        tcg_gen_helper_0_1(helper_ld_fpscr, cpu_T[0]);
1148
        ctx->bstate = BS_STOP;
1149
        return;
1150
    case 0x006a:                /* sts FPSCR,Rn */
1151
        tcg_gen_andi_i32(cpu_T[0], cpu_fpscr, 0x003fffff);
1152
        tcg_gen_mov_i32(REG(B11_8), cpu_T[0]);
1153
        return;
1154
    case 0x4062:                /* sts FPSCR,@-Rn */
1155
        tcg_gen_andi_i32(cpu_T[0], cpu_fpscr, 0x003fffff);
1156
        tcg_gen_subi_i32(cpu_T[1], REG(B11_8), 4);
1157
        tcg_gen_qemu_st32(cpu_T[0], cpu_T[1], ctx->memidx);
1158
        tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1159
        return;
1160
    case 0x00c3:                /* movca.l R0,@Rm */
1161
        tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx);
1162
        return;
1163
    case 0x0029:                /* movt Rn */
1164
        tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T);
1165
        return;
1166
    case 0x0093:                /* ocbi @Rn */
1167
        tcg_gen_qemu_ld32s(cpu_T[0], REG(B11_8), ctx->memidx);
1168
        return;
1169
    case 0x00a3:                /* ocbp @Rn */
1170
        tcg_gen_qemu_ld32s(cpu_T[0], REG(B11_8), ctx->memidx);
1171
        return;
1172
    case 0x00b3:                /* ocbwb @Rn */
1173
        tcg_gen_qemu_ld32s(cpu_T[0], REG(B11_8), ctx->memidx);
1174
        return;
1175
    case 0x0083:                /* pref @Rn */
1176
        return;
1177
    case 0x4024:                /* rotcl Rn */
1178
        tcg_gen_mov_i32(cpu_T[0], cpu_sr);
1179
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1180
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1181
        gen_copy_bit_i32(REG(B11_8), 0, cpu_T[0], 0);
1182
        return;
1183
    case 0x4025:                /* rotcr Rn */
1184
        tcg_gen_mov_i32(cpu_T[0], cpu_sr);
1185
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1186
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1187
        gen_copy_bit_i32(REG(B11_8), 31, cpu_T[0], 0);
1188
        return;
1189
    case 0x4004:                /* rotl Rn */
1190
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1191
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1192
        gen_copy_bit_i32(REG(B11_8), 0, cpu_sr, 0);
1193
        return;
1194
    case 0x4005:                /* rotr Rn */
1195
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1196
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1197
        gen_copy_bit_i32(REG(B11_8), 31, cpu_sr, 0);
1198
        return;
1199
    case 0x4000:                /* shll Rn */
1200
    case 0x4020:                /* shal Rn */
1201
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1202
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1203
        return;
1204
    case 0x4021:                /* shar Rn */
1205
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1206
        tcg_gen_sari_i32(REG(B11_8), REG(B11_8), 1);
1207
        return;
1208
    case 0x4001:                /* shlr Rn */
1209
        gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1210
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1211
        return;
1212
    case 0x4008:                /* shll2 Rn */
1213
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 2);
1214
        return;
1215
    case 0x4018:                /* shll8 Rn */
1216
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 8);
1217
        return;
1218
    case 0x4028:                /* shll16 Rn */
1219
        tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 16);
1220
        return;
1221
    case 0x4009:                /* shlr2 Rn */
1222
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 2);
1223
        return;
1224
    case 0x4019:                /* shlr8 Rn */
1225
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 8);
1226
        return;
1227
    case 0x4029:                /* shlr16 Rn */
1228
        tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16);
1229
        return;
1230
    case 0x401b:                /* tas.b @Rn */
1231
        tcg_gen_mov_i32(cpu_T[1], REG(B11_8));
1232
        tcg_gen_qemu_ld8u(cpu_T[0], cpu_T[1], ctx->memidx);
1233
        gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
1234
        tcg_gen_ori_i32(cpu_T[0], cpu_T[0], 0x80);
1235
        tcg_gen_qemu_st8(cpu_T[0], cpu_T[1], ctx->memidx);
1236
        return;
1237
    case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1238
        gen_op_movl_fpul_FT0();
1239
        gen_op_fmov_FT0_frN(FREG(B11_8));
1240
        return;
1241
    case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1242
        gen_op_fmov_frN_FT0(FREG(B11_8));
1243
        gen_op_movl_FT0_fpul();
1244
        return;
1245
    case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1246
        if (ctx->fpscr & FPSCR_PR) {
1247
            if (ctx->opcode & 0x0100)
1248
                break; /* illegal instruction */
1249
            gen_op_float_DT();
1250
            gen_op_fmov_DT0_drN(DREG(B11_8));
1251
        }
1252
        else {
1253
            gen_op_float_FT();
1254
            gen_op_fmov_FT0_frN(FREG(B11_8));
1255
        }
1256
        return;
1257
    case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1258
        if (ctx->fpscr & FPSCR_PR) {
1259
            if (ctx->opcode & 0x0100)
1260
                break; /* illegal instruction */
1261
            gen_op_fmov_drN_DT0(DREG(B11_8));
1262
            gen_op_ftrc_DT();
1263
        }
1264
        else {
1265
            gen_op_fmov_frN_FT0(FREG(B11_8));
1266
            gen_op_ftrc_FT();
1267
        }
1268
        return;
1269
    case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1270
        gen_op_fneg_frN(FREG(B11_8));
1271
        return;
1272
    case 0xf05d: /* fabs FRn/DRn */
1273
        if (ctx->fpscr & FPSCR_PR) {
1274
            if (ctx->opcode & 0x0100)
1275
                break; /* illegal instruction */
1276
            gen_op_fmov_drN_DT0(DREG(B11_8));
1277
            gen_op_fabs_DT();
1278
            gen_op_fmov_DT0_drN(DREG(B11_8));
1279
        } else {
1280
            gen_op_fmov_frN_FT0(FREG(B11_8));
1281
            gen_op_fabs_FT();
1282
            gen_op_fmov_FT0_frN(FREG(B11_8));
1283
        }
1284
        return;
1285
    case 0xf06d: /* fsqrt FRn */
1286
        if (ctx->fpscr & FPSCR_PR) {
1287
            if (ctx->opcode & 0x0100)
1288
                break; /* illegal instruction */
1289
            gen_op_fmov_drN_DT0(FREG(B11_8));
1290
            gen_op_fsqrt_DT();
1291
            gen_op_fmov_DT0_drN(FREG(B11_8));
1292
        } else {
1293
            gen_op_fmov_frN_FT0(FREG(B11_8));
1294
            gen_op_fsqrt_FT();
1295
            gen_op_fmov_FT0_frN(FREG(B11_8));
1296
        }
1297
        return;
1298
    case 0xf07d: /* fsrra FRn */
1299
        break;
1300
    case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1301
        if (!(ctx->fpscr & FPSCR_PR)) {
1302
            tcg_gen_movi_i32(cpu_T[0], 0);
1303
            gen_op_fmov_T0_frN(FREG(B11_8));
1304
            return;
1305
        }
1306
        break;
1307
    case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1308
        if (!(ctx->fpscr & FPSCR_PR)) {
1309
            tcg_gen_movi_i32(cpu_T[0], 0x3f800000);
1310
            gen_op_fmov_T0_frN(FREG(B11_8));
1311
            return;
1312
        }
1313
        break;
1314
    case 0xf0ad: /* fcnvsd FPUL,DRn */
1315
        gen_op_movl_fpul_FT0();
1316
        gen_op_fcnvsd_FT_DT();
1317
        gen_op_fmov_DT0_drN(DREG(B11_8));
1318
        return;
1319
    case 0xf0bd: /* fcnvds DRn,FPUL */
1320
        gen_op_fmov_drN_DT0(DREG(B11_8));
1321
        gen_op_fcnvds_DT_FT();
1322
        gen_op_movl_FT0_fpul();
1323
        return;
1324
    }
1325

    
1326
    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1327
            ctx->opcode, ctx->pc);
1328
    tcg_gen_helper_0_0(helper_raise_illegal_instruction);
1329
    ctx->bstate = BS_EXCP;
1330
}
1331

    
1332
void decode_opc(DisasContext * ctx)
1333
{
1334
    uint32_t old_flags = ctx->flags;
1335

    
1336
    _decode_opc(ctx);
1337

    
1338
    if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1339
        if (ctx->flags & DELAY_SLOT_CLEARME) {
1340
            gen_store_flags(0);
1341
        } else {
1342
            /* go out of the delay slot */
1343
            uint32_t new_flags = ctx->flags;
1344
            new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1345
            gen_store_flags(new_flags);
1346
        }
1347
        ctx->flags = 0;
1348
        ctx->bstate = BS_BRANCH;
1349
        if (old_flags & DELAY_SLOT_CONDITIONAL) {
1350
            gen_delayed_conditional_jump(ctx);
1351
        } else if (old_flags & DELAY_SLOT) {
1352
            gen_jump(ctx);
1353
        }
1354

    
1355
    }
1356

    
1357
    /* go into a delay slot */
1358
    if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1359
        gen_store_flags(ctx->flags);
1360
}
1361

    
1362
static inline void
1363
gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1364
                               int search_pc)
1365
{
1366
    DisasContext ctx;
1367
    target_ulong pc_start;
1368
    static uint16_t *gen_opc_end;
1369
    int i, ii;
1370
    int num_insns;
1371
    int max_insns;
1372

    
1373
    pc_start = tb->pc;
1374
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1375
    ctx.pc = pc_start;
1376
    ctx.flags = (uint32_t)tb->flags;
1377
    ctx.bstate = BS_NONE;
1378
    ctx.sr = env->sr;
1379
    ctx.fpscr = env->fpscr;
1380
    ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1381
    /* We don't know if the delayed pc came from a dynamic or static branch,
1382
       so assume it is a dynamic branch.  */
1383
    ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1384
    ctx.tb = tb;
1385
    ctx.singlestep_enabled = env->singlestep_enabled;
1386

    
1387
#ifdef DEBUG_DISAS
1388
    if (loglevel & CPU_LOG_TB_CPU) {
1389
        fprintf(logfile,
1390
                "------------------------------------------------\n");
1391
        cpu_dump_state(env, logfile, fprintf, 0);
1392
    }
1393
#endif
1394

    
1395
    ii = -1;
1396
    num_insns = 0;
1397
    max_insns = tb->cflags & CF_COUNT_MASK;
1398
    if (max_insns == 0)
1399
        max_insns = CF_COUNT_MASK;
1400
    gen_icount_start();
1401
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1402
        if (env->nb_breakpoints > 0) {
1403
            for (i = 0; i < env->nb_breakpoints; i++) {
1404
                if (ctx.pc == env->breakpoints[i]) {
1405
                    /* We have hit a breakpoint - make sure PC is up-to-date */
1406
                    tcg_gen_movi_i32(cpu_pc, ctx.pc);
1407
                    tcg_gen_helper_0_0(helper_debug);
1408
                    ctx.bstate = BS_EXCP;
1409
                    break;
1410
                }
1411
            }
1412
        }
1413
        if (search_pc) {
1414
            i = gen_opc_ptr - gen_opc_buf;
1415
            if (ii < i) {
1416
                ii++;
1417
                while (ii < i)
1418
                    gen_opc_instr_start[ii++] = 0;
1419
            }
1420
            gen_opc_pc[ii] = ctx.pc;
1421
            gen_opc_hflags[ii] = ctx.flags;
1422
            gen_opc_instr_start[ii] = 1;
1423
            gen_opc_icount[ii] = num_insns;
1424
        }
1425
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1426
            gen_io_start();
1427
#if 0
1428
        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1429
        fflush(stderr);
1430
#endif
1431
        ctx.opcode = lduw_code(ctx.pc);
1432
        decode_opc(&ctx);
1433
        num_insns++;
1434
        ctx.pc += 2;
1435
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1436
            break;
1437
        if (env->singlestep_enabled)
1438
            break;
1439
        if (num_insns >= max_insns)
1440
            break;
1441
#ifdef SH4_SINGLE_STEP
1442
        break;
1443
#endif
1444
    }
1445
    if (tb->cflags & CF_LAST_IO)
1446
        gen_io_end();
1447
    if (env->singlestep_enabled) {
1448
        tcg_gen_helper_0_0(helper_debug);
1449
    } else {
1450
        switch (ctx.bstate) {
1451
        case BS_STOP:
1452
            /* gen_op_interrupt_restart(); */
1453
            /* fall through */
1454
        case BS_NONE:
1455
            if (ctx.flags) {
1456
                gen_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1457
            }
1458
            gen_goto_tb(&ctx, 0, ctx.pc);
1459
            break;
1460
        case BS_EXCP:
1461
            /* gen_op_interrupt_restart(); */
1462
            tcg_gen_exit_tb(0);
1463
            break;
1464
        case BS_BRANCH:
1465
        default:
1466
            break;
1467
        }
1468
    }
1469

    
1470
    gen_icount_end(tb, num_insns);
1471
    *gen_opc_ptr = INDEX_op_end;
1472
    if (search_pc) {
1473
        i = gen_opc_ptr - gen_opc_buf;
1474
        ii++;
1475
        while (ii <= i)
1476
            gen_opc_instr_start[ii++] = 0;
1477
    } else {
1478
        tb->size = ctx.pc - pc_start;
1479
        tb->icount = num_insns;
1480
    }
1481

    
1482
#ifdef DEBUG_DISAS
1483
#ifdef SH4_DEBUG_DISAS
1484
    if (loglevel & CPU_LOG_TB_IN_ASM)
1485
        fprintf(logfile, "\n");
1486
#endif
1487
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1488
        fprintf(logfile, "IN:\n");        /* , lookup_symbol(pc_start)); */
1489
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1490
        fprintf(logfile, "\n");
1491
    }
1492
#endif
1493
}
1494

    
1495
void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1496
{
1497
    gen_intermediate_code_internal(env, tb, 0);
1498
}
1499

    
1500
void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1501
{
1502
    gen_intermediate_code_internal(env, tb, 1);
1503
}
1504

    
1505
void gen_pc_load(CPUState *env, TranslationBlock *tb,
1506
                unsigned long searched_pc, int pc_pos, void *puc)
1507
{
1508
    env->pc = gen_opc_pc[pc_pos];
1509
    env->flags = gen_opc_hflags[pc_pos];
1510
}