]> Git Repo - qemu.git/blob - target-sh4/translate.c
Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging
[qemu.git] / target-sh4 / translate.c
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, see <http://www.gnu.org/licenses/>.
18  */
19
20 #define DEBUG_DISAS
21
22 #include "cpu.h"
23 #include "disas/disas.h"
24 #include "tcg-op.h"
25 #include "exec/cpu_ldst.h"
26
27 #include "exec/helper-proto.h"
28 #include "exec/helper-gen.h"
29
30 #include "trace-tcg.h"
31
32
33 typedef struct DisasContext {
34     struct TranslationBlock *tb;
35     target_ulong pc;
36     uint16_t opcode;
37     uint32_t flags;
38     int bstate;
39     int memidx;
40     uint32_t delayed_pc;
41     int singlestep_enabled;
42     uint32_t features;
43     int has_movcal;
44 } DisasContext;
45
46 #if defined(CONFIG_USER_ONLY)
47 #define IS_USER(ctx) 1
48 #else
49 #define IS_USER(ctx) (!(ctx->flags & (1u << SR_MD)))
50 #endif
51
52 enum {
53     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
54                       * exception condition
55                       */
56     BS_STOP     = 1, /* We want to stop translation for any reason */
57     BS_BRANCH   = 2, /* We reached a branch condition     */
58     BS_EXCP     = 3, /* We reached an exception condition */
59 };
60
61 /* global register indexes */
62 static TCGv_ptr cpu_env;
63 static TCGv cpu_gregs[24];
64 static TCGv cpu_sr, cpu_sr_m, cpu_sr_q, cpu_sr_t;
65 static TCGv cpu_pc, cpu_ssr, cpu_spc, cpu_gbr;
66 static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
67 static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_ldst;
68 static TCGv cpu_fregs[32];
69
70 /* internal register indexes */
71 static TCGv cpu_flags, cpu_delayed_pc;
72
73 #include "exec/gen-icount.h"
74
75 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     static const char * const fregnames[32] = {
87          "FPR0_BANK0",  "FPR1_BANK0",  "FPR2_BANK0",  "FPR3_BANK0",
88          "FPR4_BANK0",  "FPR5_BANK0",  "FPR6_BANK0",  "FPR7_BANK0",
89          "FPR8_BANK0",  "FPR9_BANK0", "FPR10_BANK0", "FPR11_BANK0",
90         "FPR12_BANK0", "FPR13_BANK0", "FPR14_BANK0", "FPR15_BANK0",
91          "FPR0_BANK1",  "FPR1_BANK1",  "FPR2_BANK1",  "FPR3_BANK1",
92          "FPR4_BANK1",  "FPR5_BANK1",  "FPR6_BANK1",  "FPR7_BANK1",
93          "FPR8_BANK1",  "FPR9_BANK1", "FPR10_BANK1", "FPR11_BANK1",
94         "FPR12_BANK1", "FPR13_BANK1", "FPR14_BANK1", "FPR15_BANK1",
95     };
96
97     if (done_init)
98         return;
99
100     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
101
102     for (i = 0; i < 24; i++)
103         cpu_gregs[i] = tcg_global_mem_new_i32(TCG_AREG0,
104                                               offsetof(CPUSH4State, gregs[i]),
105                                               gregnames[i]);
106
107     cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
108                                     offsetof(CPUSH4State, pc), "PC");
109     cpu_sr = tcg_global_mem_new_i32(TCG_AREG0,
110                                     offsetof(CPUSH4State, sr), "SR");
111     cpu_sr_m = tcg_global_mem_new_i32(TCG_AREG0,
112                                     offsetof(CPUSH4State, sr_m), "SR_M");
113     cpu_sr_q = tcg_global_mem_new_i32(TCG_AREG0,
114                                     offsetof(CPUSH4State, sr_q), "SR_Q");
115     cpu_sr_t = tcg_global_mem_new_i32(TCG_AREG0,
116                                     offsetof(CPUSH4State, sr_t), "SR_T");
117     cpu_ssr = tcg_global_mem_new_i32(TCG_AREG0,
118                                      offsetof(CPUSH4State, ssr), "SSR");
119     cpu_spc = tcg_global_mem_new_i32(TCG_AREG0,
120                                      offsetof(CPUSH4State, spc), "SPC");
121     cpu_gbr = tcg_global_mem_new_i32(TCG_AREG0,
122                                      offsetof(CPUSH4State, gbr), "GBR");
123     cpu_vbr = tcg_global_mem_new_i32(TCG_AREG0,
124                                      offsetof(CPUSH4State, vbr), "VBR");
125     cpu_sgr = tcg_global_mem_new_i32(TCG_AREG0,
126                                      offsetof(CPUSH4State, sgr), "SGR");
127     cpu_dbr = tcg_global_mem_new_i32(TCG_AREG0,
128                                      offsetof(CPUSH4State, dbr), "DBR");
129     cpu_mach = tcg_global_mem_new_i32(TCG_AREG0,
130                                       offsetof(CPUSH4State, mach), "MACH");
131     cpu_macl = tcg_global_mem_new_i32(TCG_AREG0,
132                                       offsetof(CPUSH4State, macl), "MACL");
133     cpu_pr = tcg_global_mem_new_i32(TCG_AREG0,
134                                     offsetof(CPUSH4State, pr), "PR");
135     cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
136                                        offsetof(CPUSH4State, fpscr), "FPSCR");
137     cpu_fpul = tcg_global_mem_new_i32(TCG_AREG0,
138                                       offsetof(CPUSH4State, fpul), "FPUL");
139
140     cpu_flags = tcg_global_mem_new_i32(TCG_AREG0,
141                                        offsetof(CPUSH4State, flags), "_flags_");
142     cpu_delayed_pc = tcg_global_mem_new_i32(TCG_AREG0,
143                                             offsetof(CPUSH4State, delayed_pc),
144                                             "_delayed_pc_");
145     cpu_ldst = tcg_global_mem_new_i32(TCG_AREG0,
146                                       offsetof(CPUSH4State, ldst), "_ldst_");
147
148     for (i = 0; i < 32; i++)
149         cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0,
150                                               offsetof(CPUSH4State, fregs[i]),
151                                               fregnames[i]);
152
153     done_init = 1;
154 }
155
156 void superh_cpu_dump_state(CPUState *cs, FILE *f,
157                            fprintf_function cpu_fprintf, int flags)
158 {
159     SuperHCPU *cpu = SUPERH_CPU(cs);
160     CPUSH4State *env = &cpu->env;
161     int i;
162     cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
163                 env->pc, cpu_read_sr(env), env->pr, env->fpscr);
164     cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
165                 env->spc, env->ssr, env->gbr, env->vbr);
166     cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
167                 env->sgr, env->dbr, env->delayed_pc, env->fpul);
168     for (i = 0; i < 24; i += 4) {
169         cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
170                     i, env->gregs[i], i + 1, env->gregs[i + 1],
171                     i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
172     }
173     if (env->flags & DELAY_SLOT) {
174         cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
175                     env->delayed_pc);
176     } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
177         cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
178                     env->delayed_pc);
179     }
180 }
181
182 static void gen_read_sr(TCGv dst)
183 {
184     TCGv t0 = tcg_temp_new();
185     tcg_gen_shli_i32(t0, cpu_sr_q, SR_Q);
186     tcg_gen_or_i32(dst, dst, t0);
187     tcg_gen_shli_i32(t0, cpu_sr_m, SR_M);
188     tcg_gen_or_i32(dst, dst, t0);
189     tcg_gen_shli_i32(t0, cpu_sr_t, SR_T);
190     tcg_gen_or_i32(dst, cpu_sr, t0);
191     tcg_temp_free_i32(t0);
192 }
193
194 static void gen_write_sr(TCGv src)
195 {
196     tcg_gen_andi_i32(cpu_sr, src,
197                      ~((1u << SR_Q) | (1u << SR_M) | (1u << SR_T)));
198     tcg_gen_shri_i32(cpu_sr_q, src, SR_Q);
199     tcg_gen_andi_i32(cpu_sr_q, cpu_sr_q, 1);
200     tcg_gen_shri_i32(cpu_sr_m, src, SR_M);
201     tcg_gen_andi_i32(cpu_sr_m, cpu_sr_m, 1);
202     tcg_gen_shri_i32(cpu_sr_t, src, SR_T);
203     tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
204 }
205
206 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
207 {
208     TranslationBlock *tb;
209     tb = ctx->tb;
210
211     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
212         !ctx->singlestep_enabled) {
213         /* Use a direct jump if in same page and singlestep not enabled */
214         tcg_gen_goto_tb(n);
215         tcg_gen_movi_i32(cpu_pc, dest);
216         tcg_gen_exit_tb((uintptr_t)tb + n);
217     } else {
218         tcg_gen_movi_i32(cpu_pc, dest);
219         if (ctx->singlestep_enabled)
220             gen_helper_debug(cpu_env);
221         tcg_gen_exit_tb(0);
222     }
223 }
224
225 static void gen_jump(DisasContext * ctx)
226 {
227     if (ctx->delayed_pc == (uint32_t) - 1) {
228         /* Target is not statically known, it comes necessarily from a
229            delayed jump as immediate jump are conditinal jumps */
230         tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
231         if (ctx->singlestep_enabled)
232             gen_helper_debug(cpu_env);
233         tcg_gen_exit_tb(0);
234     } else {
235         gen_goto_tb(ctx, 0, ctx->delayed_pc);
236     }
237 }
238
239 static inline void gen_branch_slot(uint32_t delayed_pc, int t)
240 {
241     TCGLabel *label = gen_new_label();
242     tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
243     tcg_gen_brcondi_i32(t ? TCG_COND_EQ : TCG_COND_NE, cpu_sr_t, 0, label);
244     tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
245     gen_set_label(label);
246 }
247
248 /* Immediate conditional jump (bt or bf) */
249 static void gen_conditional_jump(DisasContext * ctx,
250                                  target_ulong ift, target_ulong ifnott)
251 {
252     TCGLabel *l1 = gen_new_label();
253     tcg_gen_brcondi_i32(TCG_COND_NE, cpu_sr_t, 0, l1);
254     gen_goto_tb(ctx, 0, ifnott);
255     gen_set_label(l1);
256     gen_goto_tb(ctx, 1, ift);
257 }
258
259 /* Delayed conditional jump (bt or bf) */
260 static void gen_delayed_conditional_jump(DisasContext * ctx)
261 {
262     TCGLabel *l1;
263     TCGv ds;
264
265     l1 = gen_new_label();
266     ds = tcg_temp_new();
267     tcg_gen_andi_i32(ds, cpu_flags, DELAY_SLOT_TRUE);
268     tcg_gen_brcondi_i32(TCG_COND_NE, ds, 0, l1);
269     gen_goto_tb(ctx, 1, ctx->pc + 2);
270     gen_set_label(l1);
271     tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
272     gen_jump(ctx);
273 }
274
275 static inline void gen_store_flags(uint32_t flags)
276 {
277     tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
278     tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
279 }
280
281 static inline void gen_load_fpr64(TCGv_i64 t, int reg)
282 {
283     tcg_gen_concat_i32_i64(t, cpu_fregs[reg + 1], cpu_fregs[reg]);
284 }
285
286 static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
287 {
288     TCGv_i32 tmp = tcg_temp_new_i32();
289     tcg_gen_extrl_i64_i32(tmp, t);
290     tcg_gen_mov_i32(cpu_fregs[reg + 1], tmp);
291     tcg_gen_shri_i64(t, t, 32);
292     tcg_gen_extrl_i64_i32(tmp, t);
293     tcg_gen_mov_i32(cpu_fregs[reg], tmp);
294     tcg_temp_free_i32(tmp);
295 }
296
297 #define B3_0 (ctx->opcode & 0xf)
298 #define B6_4 ((ctx->opcode >> 4) & 0x7)
299 #define B7_4 ((ctx->opcode >> 4) & 0xf)
300 #define B7_0 (ctx->opcode & 0xff)
301 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
302 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
303   (ctx->opcode & 0xfff))
304 #define B11_8 ((ctx->opcode >> 8) & 0xf)
305 #define B15_12 ((ctx->opcode >> 12) & 0xf)
306
307 #define REG(x) ((x) < 8 && (ctx->flags & (1u << SR_MD))\
308                         && (ctx->flags & (1u << SR_RB))\
309                 ? (cpu_gregs[x + 16]) : (cpu_gregs[x]))
310
311 #define ALTREG(x) ((x) < 8 && (!(ctx->flags & (1u << SR_MD))\
312                                || !(ctx->flags & (1u << SR_RB)))\
313                 ? (cpu_gregs[x + 16]) : (cpu_gregs[x]))
314
315 #define FREG(x) (ctx->flags & FPSCR_FR ? (x) ^ 0x10 : (x))
316 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
317 #define XREG(x) (ctx->flags & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
318 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
319
320 #define CHECK_NOT_DELAY_SLOT \
321   if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))     \
322   {                                                           \
323       tcg_gen_movi_i32(cpu_pc, ctx->pc);                      \
324       gen_helper_raise_slot_illegal_instruction(cpu_env);     \
325       ctx->bstate = BS_BRANCH;                                \
326       return;                                                 \
327   }
328
329 #define CHECK_PRIVILEGED                                        \
330   if (IS_USER(ctx)) {                                           \
331       tcg_gen_movi_i32(cpu_pc, ctx->pc);                        \
332       if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
333           gen_helper_raise_slot_illegal_instruction(cpu_env);   \
334       } else {                                                  \
335           gen_helper_raise_illegal_instruction(cpu_env);        \
336       }                                                         \
337       ctx->bstate = BS_BRANCH;                                  \
338       return;                                                   \
339   }
340
341 #define CHECK_FPU_ENABLED                                       \
342   if (ctx->flags & (1u << SR_FD)) {                             \
343       tcg_gen_movi_i32(cpu_pc, ctx->pc);                        \
344       if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
345           gen_helper_raise_slot_fpu_disable(cpu_env);           \
346       } else {                                                  \
347           gen_helper_raise_fpu_disable(cpu_env);                \
348       }                                                         \
349       ctx->bstate = BS_BRANCH;                                  \
350       return;                                                   \
351   }
352
353 static void _decode_opc(DisasContext * ctx)
354 {
355     /* This code tries to make movcal emulation sufficiently
356        accurate for Linux purposes.  This instruction writes
357        memory, and prior to that, always allocates a cache line.
358        It is used in two contexts:
359        - in memcpy, where data is copied in blocks, the first write
360        of to a block uses movca.l for performance.
361        - in arch/sh/mm/cache-sh4.c, movcal.l + ocbi combination is used
362        to flush the cache. Here, the data written by movcal.l is never
363        written to memory, and the data written is just bogus.
364
365        To simulate this, we simulate movcal.l, we store the value to memory,
366        but we also remember the previous content. If we see ocbi, we check
367        if movcal.l for that address was done previously. If so, the write should
368        not have hit the memory, so we restore the previous content.
369        When we see an instruction that is neither movca.l
370        nor ocbi, the previous content is discarded.
371
372        To optimize, we only try to flush stores when we're at the start of
373        TB, or if we already saw movca.l in this TB and did not flush stores
374        yet.  */
375     if (ctx->has_movcal)
376         {
377           int opcode = ctx->opcode & 0xf0ff;
378           if (opcode != 0x0093 /* ocbi */
379               && opcode != 0x00c3 /* movca.l */)
380               {
381                   gen_helper_discard_movcal_backup(cpu_env);
382                   ctx->has_movcal = 0;
383               }
384         }
385
386 #if 0
387     fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
388 #endif
389
390     switch (ctx->opcode) {
391     case 0x0019:                /* div0u */
392         tcg_gen_movi_i32(cpu_sr_m, 0);
393         tcg_gen_movi_i32(cpu_sr_q, 0);
394         tcg_gen_movi_i32(cpu_sr_t, 0);
395         return;
396     case 0x000b:                /* rts */
397         CHECK_NOT_DELAY_SLOT
398         tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
399         ctx->flags |= DELAY_SLOT;
400         ctx->delayed_pc = (uint32_t) - 1;
401         return;
402     case 0x0028:                /* clrmac */
403         tcg_gen_movi_i32(cpu_mach, 0);
404         tcg_gen_movi_i32(cpu_macl, 0);
405         return;
406     case 0x0048:                /* clrs */
407         tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(1u << SR_S));
408         return;
409     case 0x0008:                /* clrt */
410         tcg_gen_movi_i32(cpu_sr_t, 0);
411         return;
412     case 0x0038:                /* ldtlb */
413         CHECK_PRIVILEGED
414         gen_helper_ldtlb(cpu_env);
415         return;
416     case 0x002b:                /* rte */
417         CHECK_PRIVILEGED
418         CHECK_NOT_DELAY_SLOT
419         gen_write_sr(cpu_ssr);
420         tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
421         ctx->flags |= DELAY_SLOT;
422         ctx->delayed_pc = (uint32_t) - 1;
423         return;
424     case 0x0058:                /* sets */
425         tcg_gen_ori_i32(cpu_sr, cpu_sr, (1u << SR_S));
426         return;
427     case 0x0018:                /* sett */
428         tcg_gen_movi_i32(cpu_sr_t, 1);
429         return;
430     case 0xfbfd:                /* frchg */
431         tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
432         ctx->bstate = BS_STOP;
433         return;
434     case 0xf3fd:                /* fschg */
435         tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
436         ctx->bstate = BS_STOP;
437         return;
438     case 0x0009:                /* nop */
439         return;
440     case 0x001b:                /* sleep */
441         CHECK_PRIVILEGED
442         tcg_gen_movi_i32(cpu_pc, ctx->pc + 2);
443         gen_helper_sleep(cpu_env);
444         return;
445     }
446
447     switch (ctx->opcode & 0xf000) {
448     case 0x1000:                /* mov.l Rm,@(disp,Rn) */
449         {
450             TCGv addr = tcg_temp_new();
451             tcg_gen_addi_i32(addr, REG(B11_8), B3_0 * 4);
452             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
453             tcg_temp_free(addr);
454         }
455         return;
456     case 0x5000:                /* mov.l @(disp,Rm),Rn */
457         {
458             TCGv addr = tcg_temp_new();
459             tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 4);
460             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
461             tcg_temp_free(addr);
462         }
463         return;
464     case 0xe000:                /* mov #imm,Rn */
465         tcg_gen_movi_i32(REG(B11_8), B7_0s);
466         return;
467     case 0x9000:                /* mov.w @(disp,PC),Rn */
468         {
469             TCGv addr = tcg_const_i32(ctx->pc + 4 + B7_0 * 2);
470             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESW);
471             tcg_temp_free(addr);
472         }
473         return;
474     case 0xd000:                /* mov.l @(disp,PC),Rn */
475         {
476             TCGv addr = tcg_const_i32((ctx->pc + 4 + B7_0 * 4) & ~3);
477             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
478             tcg_temp_free(addr);
479         }
480         return;
481     case 0x7000:                /* add #imm,Rn */
482         tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);
483         return;
484     case 0xa000:                /* bra disp */
485         CHECK_NOT_DELAY_SLOT
486         ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
487         tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
488         ctx->flags |= DELAY_SLOT;
489         return;
490     case 0xb000:                /* bsr disp */
491         CHECK_NOT_DELAY_SLOT
492         tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
493         ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
494         tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
495         ctx->flags |= DELAY_SLOT;
496         return;
497     }
498
499     switch (ctx->opcode & 0xf00f) {
500     case 0x6003:                /* mov Rm,Rn */
501         tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
502         return;
503     case 0x2000:                /* mov.b Rm,@Rn */
504         tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_UB);
505         return;
506     case 0x2001:                /* mov.w Rm,@Rn */
507         tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_TEUW);
508         return;
509     case 0x2002:                /* mov.l Rm,@Rn */
510         tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_TEUL);
511         return;
512     case 0x6000:                /* mov.b @Rm,Rn */
513         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_SB);
514         return;
515     case 0x6001:                /* mov.w @Rm,Rn */
516         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESW);
517         return;
518     case 0x6002:                /* mov.l @Rm,Rn */
519         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESL);
520         return;
521     case 0x2004:                /* mov.b Rm,@-Rn */
522         {
523             TCGv addr = tcg_temp_new();
524             tcg_gen_subi_i32(addr, REG(B11_8), 1);
525             /* might cause re-execution */
526             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_UB);
527             tcg_gen_mov_i32(REG(B11_8), addr);                  /* modify register status */
528             tcg_temp_free(addr);
529         }
530         return;
531     case 0x2005:                /* mov.w Rm,@-Rn */
532         {
533             TCGv addr = tcg_temp_new();
534             tcg_gen_subi_i32(addr, REG(B11_8), 2);
535             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUW);
536             tcg_gen_mov_i32(REG(B11_8), addr);
537             tcg_temp_free(addr);
538         }
539         return;
540     case 0x2006:                /* mov.l Rm,@-Rn */
541         {
542             TCGv addr = tcg_temp_new();
543             tcg_gen_subi_i32(addr, REG(B11_8), 4);
544             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
545             tcg_gen_mov_i32(REG(B11_8), addr);
546         }
547         return;
548     case 0x6004:                /* mov.b @Rm+,Rn */
549         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_SB);
550         if ( B11_8 != B7_4 )
551                 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 1);
552         return;
553     case 0x6005:                /* mov.w @Rm+,Rn */
554         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESW);
555         if ( B11_8 != B7_4 )
556                 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
557         return;
558     case 0x6006:                /* mov.l @Rm+,Rn */
559         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESL);
560         if ( B11_8 != B7_4 )
561                 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
562         return;
563     case 0x0004:                /* mov.b Rm,@(R0,Rn) */
564         {
565             TCGv addr = tcg_temp_new();
566             tcg_gen_add_i32(addr, REG(B11_8), REG(0));
567             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_UB);
568             tcg_temp_free(addr);
569         }
570         return;
571     case 0x0005:                /* mov.w Rm,@(R0,Rn) */
572         {
573             TCGv addr = tcg_temp_new();
574             tcg_gen_add_i32(addr, REG(B11_8), REG(0));
575             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUW);
576             tcg_temp_free(addr);
577         }
578         return;
579     case 0x0006:                /* mov.l Rm,@(R0,Rn) */
580         {
581             TCGv addr = tcg_temp_new();
582             tcg_gen_add_i32(addr, REG(B11_8), REG(0));
583             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
584             tcg_temp_free(addr);
585         }
586         return;
587     case 0x000c:                /* mov.b @(R0,Rm),Rn */
588         {
589             TCGv addr = tcg_temp_new();
590             tcg_gen_add_i32(addr, REG(B7_4), REG(0));
591             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_SB);
592             tcg_temp_free(addr);
593         }
594         return;
595     case 0x000d:                /* mov.w @(R0,Rm),Rn */
596         {
597             TCGv addr = tcg_temp_new();
598             tcg_gen_add_i32(addr, REG(B7_4), REG(0));
599             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESW);
600             tcg_temp_free(addr);
601         }
602         return;
603     case 0x000e:                /* mov.l @(R0,Rm),Rn */
604         {
605             TCGv addr = tcg_temp_new();
606             tcg_gen_add_i32(addr, REG(B7_4), REG(0));
607             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
608             tcg_temp_free(addr);
609         }
610         return;
611     case 0x6008:                /* swap.b Rm,Rn */
612         {
613             TCGv low = tcg_temp_new();;
614             tcg_gen_ext16u_i32(low, REG(B7_4));
615             tcg_gen_bswap16_i32(low, low);
616             tcg_gen_deposit_i32(REG(B11_8), REG(B7_4), low, 0, 16);
617             tcg_temp_free(low);
618         }
619         return;
620     case 0x6009:                /* swap.w Rm,Rn */
621         tcg_gen_rotli_i32(REG(B11_8), REG(B7_4), 16);
622         return;
623     case 0x200d:                /* xtrct Rm,Rn */
624         {
625             TCGv high, low;
626             high = tcg_temp_new();
627             tcg_gen_shli_i32(high, REG(B7_4), 16);
628             low = tcg_temp_new();
629             tcg_gen_shri_i32(low, REG(B11_8), 16);
630             tcg_gen_or_i32(REG(B11_8), high, low);
631             tcg_temp_free(low);
632             tcg_temp_free(high);
633         }
634         return;
635     case 0x300c:                /* add Rm,Rn */
636         tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));
637         return;
638     case 0x300e:                /* addc Rm,Rn */
639         {
640             TCGv t0, t1;
641             t0 = tcg_const_tl(0);
642             t1 = tcg_temp_new();
643             tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0);
644             tcg_gen_add2_i32(REG(B11_8), cpu_sr_t,
645                              REG(B11_8), t0, t1, cpu_sr_t);
646             tcg_temp_free(t0);
647             tcg_temp_free(t1);
648         }
649         return;
650     case 0x300f:                /* addv Rm,Rn */
651         {
652             TCGv t0, t1, t2;
653             t0 = tcg_temp_new();
654             tcg_gen_add_i32(t0, REG(B7_4), REG(B11_8));
655             t1 = tcg_temp_new();
656             tcg_gen_xor_i32(t1, t0, REG(B11_8));
657             t2 = tcg_temp_new();
658             tcg_gen_xor_i32(t2, REG(B7_4), REG(B11_8));
659             tcg_gen_andc_i32(cpu_sr_t, t1, t2);
660             tcg_temp_free(t2);
661             tcg_gen_shri_i32(cpu_sr_t, cpu_sr_t, 31);
662             tcg_temp_free(t1);
663             tcg_gen_mov_i32(REG(B7_4), t0);
664             tcg_temp_free(t0);
665         }
666         return;
667     case 0x2009:                /* and Rm,Rn */
668         tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
669         return;
670     case 0x3000:                /* cmp/eq Rm,Rn */
671         tcg_gen_setcond_i32(TCG_COND_EQ, cpu_sr_t, REG(B11_8), REG(B7_4));
672         return;
673     case 0x3003:                /* cmp/ge Rm,Rn */
674         tcg_gen_setcond_i32(TCG_COND_GE, cpu_sr_t, REG(B11_8), REG(B7_4));
675         return;
676     case 0x3007:                /* cmp/gt Rm,Rn */
677         tcg_gen_setcond_i32(TCG_COND_GT, cpu_sr_t, REG(B11_8), REG(B7_4));
678         return;
679     case 0x3006:                /* cmp/hi Rm,Rn */
680         tcg_gen_setcond_i32(TCG_COND_GTU, cpu_sr_t, REG(B11_8), REG(B7_4));
681         return;
682     case 0x3002:                /* cmp/hs Rm,Rn */
683         tcg_gen_setcond_i32(TCG_COND_GEU, cpu_sr_t, REG(B11_8), REG(B7_4));
684         return;
685     case 0x200c:                /* cmp/str Rm,Rn */
686         {
687             TCGv cmp1 = tcg_temp_new();
688             TCGv cmp2 = tcg_temp_new();
689             tcg_gen_xor_i32(cmp2, REG(B7_4), REG(B11_8));
690             tcg_gen_subi_i32(cmp1, cmp2, 0x01010101);
691             tcg_gen_andc_i32(cmp1, cmp1, cmp2);
692             tcg_gen_andi_i32(cmp1, cmp1, 0x80808080);
693             tcg_gen_setcondi_i32(TCG_COND_NE, cpu_sr_t, cmp1, 0);
694             tcg_temp_free(cmp2);
695             tcg_temp_free(cmp1);
696         }
697         return;
698     case 0x2007:                /* div0s Rm,Rn */
699         tcg_gen_shri_i32(cpu_sr_q, REG(B11_8), 31);         /* SR_Q */
700         tcg_gen_shri_i32(cpu_sr_m, REG(B7_4), 31);          /* SR_M */
701         tcg_gen_xor_i32(cpu_sr_t, cpu_sr_q, cpu_sr_m);      /* SR_T */
702         return;
703     case 0x3004:                /* div1 Rm,Rn */
704         {
705             TCGv t0 = tcg_temp_new();
706             TCGv t1 = tcg_temp_new();
707             TCGv t2 = tcg_temp_new();
708             TCGv zero = tcg_const_i32(0);
709
710             /* shift left arg1, saving the bit being pushed out and inserting
711                T on the right */
712             tcg_gen_shri_i32(t0, REG(B11_8), 31);
713             tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
714             tcg_gen_or_i32(REG(B11_8), REG(B11_8), cpu_sr_t);
715
716             /* Add or subtract arg0 from arg1 depending if Q == M. To avoid
717                using 64-bit temps, we compute arg0's high part from q ^ m, so
718                that it is 0x00000000 when adding the value or 0xffffffff when
719                subtracting it. */
720             tcg_gen_xor_i32(t1, cpu_sr_q, cpu_sr_m);
721             tcg_gen_subi_i32(t1, t1, 1);
722             tcg_gen_neg_i32(t2, REG(B7_4));
723             tcg_gen_movcond_i32(TCG_COND_EQ, t2, t1, zero, REG(B7_4), t2);
724             tcg_gen_add2_i32(REG(B11_8), t1, REG(B11_8), zero, t2, t1);
725
726             /* compute T and Q depending on carry */
727             tcg_gen_andi_i32(t1, t1, 1);
728             tcg_gen_xor_i32(t1, t1, t0);
729             tcg_gen_xori_i32(cpu_sr_t, t1, 1);
730             tcg_gen_xor_i32(cpu_sr_q, cpu_sr_m, t1);
731
732             tcg_temp_free(zero);
733             tcg_temp_free(t2);
734             tcg_temp_free(t1);
735             tcg_temp_free(t0);
736         }
737         return;
738     case 0x300d:                /* dmuls.l Rm,Rn */
739         tcg_gen_muls2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
740         return;
741     case 0x3005:                /* dmulu.l Rm,Rn */
742         tcg_gen_mulu2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
743         return;
744     case 0x600e:                /* exts.b Rm,Rn */
745         tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));
746         return;
747     case 0x600f:                /* exts.w Rm,Rn */
748         tcg_gen_ext16s_i32(REG(B11_8), REG(B7_4));
749         return;
750     case 0x600c:                /* extu.b Rm,Rn */
751         tcg_gen_ext8u_i32(REG(B11_8), REG(B7_4));
752         return;
753     case 0x600d:                /* extu.w Rm,Rn */
754         tcg_gen_ext16u_i32(REG(B11_8), REG(B7_4));
755         return;
756     case 0x000f:                /* mac.l @Rm+,@Rn+ */
757         {
758             TCGv arg0, arg1;
759             arg0 = tcg_temp_new();
760             tcg_gen_qemu_ld_i32(arg0, REG(B7_4), ctx->memidx, MO_TESL);
761             arg1 = tcg_temp_new();
762             tcg_gen_qemu_ld_i32(arg1, REG(B11_8), ctx->memidx, MO_TESL);
763             gen_helper_macl(cpu_env, arg0, arg1);
764             tcg_temp_free(arg1);
765             tcg_temp_free(arg0);
766             tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
767             tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
768         }
769         return;
770     case 0x400f:                /* mac.w @Rm+,@Rn+ */
771         {
772             TCGv arg0, arg1;
773             arg0 = tcg_temp_new();
774             tcg_gen_qemu_ld_i32(arg0, REG(B7_4), ctx->memidx, MO_TESL);
775             arg1 = tcg_temp_new();
776             tcg_gen_qemu_ld_i32(arg1, REG(B11_8), ctx->memidx, MO_TESL);
777             gen_helper_macw(cpu_env, arg0, arg1);
778             tcg_temp_free(arg1);
779             tcg_temp_free(arg0);
780             tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);
781             tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
782         }
783         return;
784     case 0x0007:                /* mul.l Rm,Rn */
785         tcg_gen_mul_i32(cpu_macl, REG(B7_4), REG(B11_8));
786         return;
787     case 0x200f:                /* muls.w Rm,Rn */
788         {
789             TCGv arg0, arg1;
790             arg0 = tcg_temp_new();
791             tcg_gen_ext16s_i32(arg0, REG(B7_4));
792             arg1 = tcg_temp_new();
793             tcg_gen_ext16s_i32(arg1, REG(B11_8));
794             tcg_gen_mul_i32(cpu_macl, arg0, arg1);
795             tcg_temp_free(arg1);
796             tcg_temp_free(arg0);
797         }
798         return;
799     case 0x200e:                /* mulu.w Rm,Rn */
800         {
801             TCGv arg0, arg1;
802             arg0 = tcg_temp_new();
803             tcg_gen_ext16u_i32(arg0, REG(B7_4));
804             arg1 = tcg_temp_new();
805             tcg_gen_ext16u_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 0x600b:                /* neg Rm,Rn */
812         tcg_gen_neg_i32(REG(B11_8), REG(B7_4));
813         return;
814     case 0x600a:                /* negc Rm,Rn */
815         {
816             TCGv t0 = tcg_const_i32(0);
817             tcg_gen_add2_i32(REG(B11_8), cpu_sr_t,
818                              REG(B7_4), t0, cpu_sr_t, t0);
819             tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t,
820                              t0, t0, REG(B11_8), cpu_sr_t);
821             tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
822             tcg_temp_free(t0);
823         }
824         return;
825     case 0x6007:                /* not Rm,Rn */
826         tcg_gen_not_i32(REG(B11_8), REG(B7_4));
827         return;
828     case 0x200b:                /* or Rm,Rn */
829         tcg_gen_or_i32(REG(B11_8), REG(B11_8), REG(B7_4));
830         return;
831     case 0x400c:                /* shad Rm,Rn */
832         {
833             TCGv t0 = tcg_temp_new();
834             TCGv t1 = tcg_temp_new();
835             TCGv t2 = tcg_temp_new();
836
837             tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
838
839             /* positive case: shift to the left */
840             tcg_gen_shl_i32(t1, REG(B11_8), t0);
841
842             /* negative case: shift to the right in two steps to
843                correctly handle the -32 case */
844             tcg_gen_xori_i32(t0, t0, 0x1f);
845             tcg_gen_sar_i32(t2, REG(B11_8), t0);
846             tcg_gen_sari_i32(t2, t2, 1);
847
848             /* select between the two cases */
849             tcg_gen_movi_i32(t0, 0);
850             tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
851
852             tcg_temp_free(t0);
853             tcg_temp_free(t1);
854             tcg_temp_free(t2);
855         }
856         return;
857     case 0x400d:                /* shld Rm,Rn */
858         {
859             TCGv t0 = tcg_temp_new();
860             TCGv t1 = tcg_temp_new();
861             TCGv t2 = tcg_temp_new();
862
863             tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
864
865             /* positive case: shift to the left */
866             tcg_gen_shl_i32(t1, REG(B11_8), t0);
867
868             /* negative case: shift to the right in two steps to
869                correctly handle the -32 case */
870             tcg_gen_xori_i32(t0, t0, 0x1f);
871             tcg_gen_shr_i32(t2, REG(B11_8), t0);
872             tcg_gen_shri_i32(t2, t2, 1);
873
874             /* select between the two cases */
875             tcg_gen_movi_i32(t0, 0);
876             tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
877
878             tcg_temp_free(t0);
879             tcg_temp_free(t1);
880             tcg_temp_free(t2);
881         }
882         return;
883     case 0x3008:                /* sub Rm,Rn */
884         tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));
885         return;
886     case 0x300a:                /* subc Rm,Rn */
887         {
888             TCGv t0, t1;
889             t0 = tcg_const_tl(0);
890             t1 = tcg_temp_new();
891             tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0);
892             tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t,
893                              REG(B11_8), t0, t1, cpu_sr_t);
894             tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
895             tcg_temp_free(t0);
896             tcg_temp_free(t1);
897         }
898         return;
899     case 0x300b:                /* subv Rm,Rn */
900         {
901             TCGv t0, t1, t2;
902             t0 = tcg_temp_new();
903             tcg_gen_sub_i32(t0, REG(B11_8), REG(B7_4));
904             t1 = tcg_temp_new();
905             tcg_gen_xor_i32(t1, t0, REG(B7_4));
906             t2 = tcg_temp_new();
907             tcg_gen_xor_i32(t2, REG(B11_8), REG(B7_4));
908             tcg_gen_and_i32(t1, t1, t2);
909             tcg_temp_free(t2);
910             tcg_gen_shri_i32(cpu_sr_t, t1, 31);
911             tcg_temp_free(t1);
912             tcg_gen_mov_i32(REG(B11_8), t0);
913             tcg_temp_free(t0);
914         }
915         return;
916     case 0x2008:                /* tst Rm,Rn */
917         {
918             TCGv val = tcg_temp_new();
919             tcg_gen_and_i32(val, REG(B7_4), REG(B11_8));
920             tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
921             tcg_temp_free(val);
922         }
923         return;
924     case 0x200a:                /* xor Rm,Rn */
925         tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));
926         return;
927     case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
928         CHECK_FPU_ENABLED
929         if (ctx->flags & FPSCR_SZ) {
930             TCGv_i64 fp = tcg_temp_new_i64();
931             gen_load_fpr64(fp, XREG(B7_4));
932             gen_store_fpr64(fp, XREG(B11_8));
933             tcg_temp_free_i64(fp);
934         } else {
935             tcg_gen_mov_i32(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
936         }
937         return;
938     case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
939         CHECK_FPU_ENABLED
940         if (ctx->flags & FPSCR_SZ) {
941             TCGv addr_hi = tcg_temp_new();
942             int fr = XREG(B7_4);
943             tcg_gen_addi_i32(addr_hi, REG(B11_8), 4);
944             tcg_gen_qemu_st_i32(cpu_fregs[fr], REG(B11_8),
945                                 ctx->memidx, MO_TEUL);
946             tcg_gen_qemu_st_i32(cpu_fregs[fr+1], addr_hi,
947                                 ctx->memidx, MO_TEUL);
948             tcg_temp_free(addr_hi);
949         } else {
950             tcg_gen_qemu_st_i32(cpu_fregs[FREG(B7_4)], REG(B11_8),
951                                 ctx->memidx, MO_TEUL);
952         }
953         return;
954     case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
955         CHECK_FPU_ENABLED
956         if (ctx->flags & FPSCR_SZ) {
957             TCGv addr_hi = tcg_temp_new();
958             int fr = XREG(B11_8);
959             tcg_gen_addi_i32(addr_hi, REG(B7_4), 4);
960             tcg_gen_qemu_ld_i32(cpu_fregs[fr], REG(B7_4), ctx->memidx, MO_TEUL);
961             tcg_gen_qemu_ld_i32(cpu_fregs[fr+1], addr_hi, ctx->memidx, MO_TEUL);
962             tcg_temp_free(addr_hi);
963         } else {
964             tcg_gen_qemu_ld_i32(cpu_fregs[FREG(B11_8)], REG(B7_4),
965                                 ctx->memidx, MO_TEUL);
966         }
967         return;
968     case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
969         CHECK_FPU_ENABLED
970         if (ctx->flags & FPSCR_SZ) {
971             TCGv addr_hi = tcg_temp_new();
972             int fr = XREG(B11_8);
973             tcg_gen_addi_i32(addr_hi, REG(B7_4), 4);
974             tcg_gen_qemu_ld_i32(cpu_fregs[fr], REG(B7_4), ctx->memidx, MO_TEUL);
975             tcg_gen_qemu_ld_i32(cpu_fregs[fr+1], addr_hi, ctx->memidx, MO_TEUL);
976             tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 8);
977             tcg_temp_free(addr_hi);
978         } else {
979             tcg_gen_qemu_ld_i32(cpu_fregs[FREG(B11_8)], REG(B7_4),
980                                 ctx->memidx, MO_TEUL);
981             tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
982         }
983         return;
984     case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
985         CHECK_FPU_ENABLED
986         TCGv addr = tcg_temp_new_i32();
987         tcg_gen_subi_i32(addr, REG(B11_8), 4);
988         if (ctx->flags & FPSCR_SZ) {
989             int fr = XREG(B7_4);
990             tcg_gen_qemu_st_i32(cpu_fregs[fr+1], addr, ctx->memidx, MO_TEUL);
991             tcg_gen_subi_i32(addr, addr, 4);
992             tcg_gen_qemu_st_i32(cpu_fregs[fr], addr, ctx->memidx, MO_TEUL);
993         } else {
994             tcg_gen_qemu_st_i32(cpu_fregs[FREG(B7_4)], addr,
995                                 ctx->memidx, MO_TEUL);
996         }
997         tcg_gen_mov_i32(REG(B11_8), addr);
998         tcg_temp_free(addr);
999         return;
1000     case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
1001         CHECK_FPU_ENABLED
1002         {
1003             TCGv addr = tcg_temp_new_i32();
1004             tcg_gen_add_i32(addr, REG(B7_4), REG(0));
1005             if (ctx->flags & FPSCR_SZ) {
1006                 int fr = XREG(B11_8);
1007                 tcg_gen_qemu_ld_i32(cpu_fregs[fr], addr,
1008                                     ctx->memidx, MO_TEUL);
1009                 tcg_gen_addi_i32(addr, addr, 4);
1010                 tcg_gen_qemu_ld_i32(cpu_fregs[fr+1], addr,
1011                                     ctx->memidx, MO_TEUL);
1012             } else {
1013                 tcg_gen_qemu_ld_i32(cpu_fregs[FREG(B11_8)], addr,
1014                                     ctx->memidx, MO_TEUL);
1015             }
1016             tcg_temp_free(addr);
1017         }
1018         return;
1019     case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
1020         CHECK_FPU_ENABLED
1021         {
1022             TCGv addr = tcg_temp_new();
1023             tcg_gen_add_i32(addr, REG(B11_8), REG(0));
1024             if (ctx->flags & FPSCR_SZ) {
1025                 int fr = XREG(B7_4);
1026                 tcg_gen_qemu_ld_i32(cpu_fregs[fr], addr,
1027                                     ctx->memidx, MO_TEUL);
1028                 tcg_gen_addi_i32(addr, addr, 4);
1029                 tcg_gen_qemu_ld_i32(cpu_fregs[fr+1], addr,
1030                                     ctx->memidx, MO_TEUL);
1031             } else {
1032                 tcg_gen_qemu_st_i32(cpu_fregs[FREG(B7_4)], addr,
1033                                     ctx->memidx, MO_TEUL);
1034             }
1035             tcg_temp_free(addr);
1036         }
1037         return;
1038     case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1039     case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1040     case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1041     case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1042     case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1043     case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1044         {
1045             CHECK_FPU_ENABLED
1046             if (ctx->flags & FPSCR_PR) {
1047                 TCGv_i64 fp0, fp1;
1048
1049                 if (ctx->opcode & 0x0110)
1050                     break; /* illegal instruction */
1051                 fp0 = tcg_temp_new_i64();
1052                 fp1 = tcg_temp_new_i64();
1053                 gen_load_fpr64(fp0, DREG(B11_8));
1054                 gen_load_fpr64(fp1, DREG(B7_4));
1055                 switch (ctx->opcode & 0xf00f) {
1056                 case 0xf000:            /* fadd Rm,Rn */
1057                     gen_helper_fadd_DT(fp0, cpu_env, fp0, fp1);
1058                     break;
1059                 case 0xf001:            /* fsub Rm,Rn */
1060                     gen_helper_fsub_DT(fp0, cpu_env, fp0, fp1);
1061                     break;
1062                 case 0xf002:            /* fmul Rm,Rn */
1063                     gen_helper_fmul_DT(fp0, cpu_env, fp0, fp1);
1064                     break;
1065                 case 0xf003:            /* fdiv Rm,Rn */
1066                     gen_helper_fdiv_DT(fp0, cpu_env, fp0, fp1);
1067                     break;
1068                 case 0xf004:            /* fcmp/eq Rm,Rn */
1069                     gen_helper_fcmp_eq_DT(cpu_env, fp0, fp1);
1070                     return;
1071                 case 0xf005:            /* fcmp/gt Rm,Rn */
1072                     gen_helper_fcmp_gt_DT(cpu_env, fp0, fp1);
1073                     return;
1074                 }
1075                 gen_store_fpr64(fp0, DREG(B11_8));
1076                 tcg_temp_free_i64(fp0);
1077                 tcg_temp_free_i64(fp1);
1078             } else {
1079                 switch (ctx->opcode & 0xf00f) {
1080                 case 0xf000:            /* fadd Rm,Rn */
1081                     gen_helper_fadd_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1082                                        cpu_fregs[FREG(B11_8)],
1083                                        cpu_fregs[FREG(B7_4)]);
1084                     break;
1085                 case 0xf001:            /* fsub Rm,Rn */
1086                     gen_helper_fsub_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1087                                        cpu_fregs[FREG(B11_8)],
1088                                        cpu_fregs[FREG(B7_4)]);
1089                     break;
1090                 case 0xf002:            /* fmul Rm,Rn */
1091                     gen_helper_fmul_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1092                                        cpu_fregs[FREG(B11_8)],
1093                                        cpu_fregs[FREG(B7_4)]);
1094                     break;
1095                 case 0xf003:            /* fdiv Rm,Rn */
1096                     gen_helper_fdiv_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1097                                        cpu_fregs[FREG(B11_8)],
1098                                        cpu_fregs[FREG(B7_4)]);
1099                     break;
1100                 case 0xf004:            /* fcmp/eq Rm,Rn */
1101                     gen_helper_fcmp_eq_FT(cpu_env, cpu_fregs[FREG(B11_8)],
1102                                           cpu_fregs[FREG(B7_4)]);
1103                     return;
1104                 case 0xf005:            /* fcmp/gt Rm,Rn */
1105                     gen_helper_fcmp_gt_FT(cpu_env, cpu_fregs[FREG(B11_8)],
1106                                           cpu_fregs[FREG(B7_4)]);
1107                     return;
1108                 }
1109             }
1110         }
1111         return;
1112     case 0xf00e: /* fmac FR0,RM,Rn */
1113         {
1114             CHECK_FPU_ENABLED
1115             if (ctx->flags & FPSCR_PR) {
1116                 break; /* illegal instruction */
1117             } else {
1118                 gen_helper_fmac_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1119                                    cpu_fregs[FREG(0)], cpu_fregs[FREG(B7_4)],
1120                                    cpu_fregs[FREG(B11_8)]);
1121                 return;
1122             }
1123         }
1124     }
1125
1126     switch (ctx->opcode & 0xff00) {
1127     case 0xc900:                /* and #imm,R0 */
1128         tcg_gen_andi_i32(REG(0), REG(0), B7_0);
1129         return;
1130     case 0xcd00:                /* and.b #imm,@(R0,GBR) */
1131         {
1132             TCGv addr, val;
1133             addr = tcg_temp_new();
1134             tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1135             val = tcg_temp_new();
1136             tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1137             tcg_gen_andi_i32(val, val, B7_0);
1138             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1139             tcg_temp_free(val);
1140             tcg_temp_free(addr);
1141         }
1142         return;
1143     case 0x8b00:                /* bf label */
1144         CHECK_NOT_DELAY_SLOT
1145             gen_conditional_jump(ctx, ctx->pc + 2,
1146                                  ctx->pc + 4 + B7_0s * 2);
1147         ctx->bstate = BS_BRANCH;
1148         return;
1149     case 0x8f00:                /* bf/s label */
1150         CHECK_NOT_DELAY_SLOT
1151         gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);
1152         ctx->flags |= DELAY_SLOT_CONDITIONAL;
1153         return;
1154     case 0x8900:                /* bt label */
1155         CHECK_NOT_DELAY_SLOT
1156             gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
1157                                  ctx->pc + 2);
1158         ctx->bstate = BS_BRANCH;
1159         return;
1160     case 0x8d00:                /* bt/s label */
1161         CHECK_NOT_DELAY_SLOT
1162         gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);
1163         ctx->flags |= DELAY_SLOT_CONDITIONAL;
1164         return;
1165     case 0x8800:                /* cmp/eq #imm,R0 */
1166         tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, REG(0), B7_0s);
1167         return;
1168     case 0xc400:                /* mov.b @(disp,GBR),R0 */
1169         {
1170             TCGv addr = tcg_temp_new();
1171             tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1172             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_SB);
1173             tcg_temp_free(addr);
1174         }
1175         return;
1176     case 0xc500:                /* mov.w @(disp,GBR),R0 */
1177         {
1178             TCGv addr = tcg_temp_new();
1179             tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1180             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESW);
1181             tcg_temp_free(addr);
1182         }
1183         return;
1184     case 0xc600:                /* mov.l @(disp,GBR),R0 */
1185         {
1186             TCGv addr = tcg_temp_new();
1187             tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1188             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESL);
1189             tcg_temp_free(addr);
1190         }
1191         return;
1192     case 0xc000:                /* mov.b R0,@(disp,GBR) */
1193         {
1194             TCGv addr = tcg_temp_new();
1195             tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1196             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_UB);
1197             tcg_temp_free(addr);
1198         }
1199         return;
1200     case 0xc100:                /* mov.w R0,@(disp,GBR) */
1201         {
1202             TCGv addr = tcg_temp_new();
1203             tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1204             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUW);
1205             tcg_temp_free(addr);
1206         }
1207         return;
1208     case 0xc200:                /* mov.l R0,@(disp,GBR) */
1209         {
1210             TCGv addr = tcg_temp_new();
1211             tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1212             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUL);
1213             tcg_temp_free(addr);
1214         }
1215         return;
1216     case 0x8000:                /* mov.b R0,@(disp,Rn) */
1217         {
1218             TCGv addr = tcg_temp_new();
1219             tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1220             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_UB);
1221             tcg_temp_free(addr);
1222         }
1223         return;
1224     case 0x8100:                /* mov.w R0,@(disp,Rn) */
1225         {
1226             TCGv addr = tcg_temp_new();
1227             tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1228             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUW);
1229             tcg_temp_free(addr);
1230         }
1231         return;
1232     case 0x8400:                /* mov.b @(disp,Rn),R0 */
1233         {
1234             TCGv addr = tcg_temp_new();
1235             tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1236             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_SB);
1237             tcg_temp_free(addr);
1238         }
1239         return;
1240     case 0x8500:                /* mov.w @(disp,Rn),R0 */
1241         {
1242             TCGv addr = tcg_temp_new();
1243             tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1244             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESW);
1245             tcg_temp_free(addr);
1246         }
1247         return;
1248     case 0xc700:                /* mova @(disp,PC),R0 */
1249         tcg_gen_movi_i32(REG(0), ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
1250         return;
1251     case 0xcb00:                /* or #imm,R0 */
1252         tcg_gen_ori_i32(REG(0), REG(0), B7_0);
1253         return;
1254     case 0xcf00:                /* or.b #imm,@(R0,GBR) */
1255         {
1256             TCGv addr, val;
1257             addr = tcg_temp_new();
1258             tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1259             val = tcg_temp_new();
1260             tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1261             tcg_gen_ori_i32(val, val, B7_0);
1262             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1263             tcg_temp_free(val);
1264             tcg_temp_free(addr);
1265         }
1266         return;
1267     case 0xc300:                /* trapa #imm */
1268         {
1269             TCGv imm;
1270             CHECK_NOT_DELAY_SLOT
1271             tcg_gen_movi_i32(cpu_pc, ctx->pc);
1272             imm = tcg_const_i32(B7_0);
1273             gen_helper_trapa(cpu_env, imm);
1274             tcg_temp_free(imm);
1275             ctx->bstate = BS_BRANCH;
1276         }
1277         return;
1278     case 0xc800:                /* tst #imm,R0 */
1279         {
1280             TCGv val = tcg_temp_new();
1281             tcg_gen_andi_i32(val, REG(0), B7_0);
1282             tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1283             tcg_temp_free(val);
1284         }
1285         return;
1286     case 0xcc00:                /* tst.b #imm,@(R0,GBR) */
1287         {
1288             TCGv val = tcg_temp_new();
1289             tcg_gen_add_i32(val, REG(0), cpu_gbr);
1290             tcg_gen_qemu_ld_i32(val, val, ctx->memidx, MO_UB);
1291             tcg_gen_andi_i32(val, val, B7_0);
1292             tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1293             tcg_temp_free(val);
1294         }
1295         return;
1296     case 0xca00:                /* xor #imm,R0 */
1297         tcg_gen_xori_i32(REG(0), REG(0), B7_0);
1298         return;
1299     case 0xce00:                /* xor.b #imm,@(R0,GBR) */
1300         {
1301             TCGv addr, val;
1302             addr = tcg_temp_new();
1303             tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1304             val = tcg_temp_new();
1305             tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1306             tcg_gen_xori_i32(val, val, B7_0);
1307             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1308             tcg_temp_free(val);
1309             tcg_temp_free(addr);
1310         }
1311         return;
1312     }
1313
1314     switch (ctx->opcode & 0xf08f) {
1315     case 0x408e:                /* ldc Rm,Rn_BANK */
1316         CHECK_PRIVILEGED
1317         tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
1318         return;
1319     case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
1320         CHECK_PRIVILEGED
1321         tcg_gen_qemu_ld_i32(ALTREG(B6_4), REG(B11_8), ctx->memidx, MO_TESL);
1322         tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1323         return;
1324     case 0x0082:                /* stc Rm_BANK,Rn */
1325         CHECK_PRIVILEGED
1326         tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
1327         return;
1328     case 0x4083:                /* stc.l Rm_BANK,@-Rn */
1329         CHECK_PRIVILEGED
1330         {
1331             TCGv addr = tcg_temp_new();
1332             tcg_gen_subi_i32(addr, REG(B11_8), 4);
1333             tcg_gen_qemu_st_i32(ALTREG(B6_4), addr, ctx->memidx, MO_TEUL);
1334             tcg_gen_mov_i32(REG(B11_8), addr);
1335             tcg_temp_free(addr);
1336         }
1337         return;
1338     }
1339
1340     switch (ctx->opcode & 0xf0ff) {
1341     case 0x0023:                /* braf Rn */
1342         CHECK_NOT_DELAY_SLOT
1343         tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->pc + 4);
1344         ctx->flags |= DELAY_SLOT;
1345         ctx->delayed_pc = (uint32_t) - 1;
1346         return;
1347     case 0x0003:                /* bsrf Rn */
1348         CHECK_NOT_DELAY_SLOT
1349         tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1350         tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);
1351         ctx->flags |= DELAY_SLOT;
1352         ctx->delayed_pc = (uint32_t) - 1;
1353         return;
1354     case 0x4015:                /* cmp/pl Rn */
1355         tcg_gen_setcondi_i32(TCG_COND_GT, cpu_sr_t, REG(B11_8), 0);
1356         return;
1357     case 0x4011:                /* cmp/pz Rn */
1358         tcg_gen_setcondi_i32(TCG_COND_GE, cpu_sr_t, REG(B11_8), 0);
1359         return;
1360     case 0x4010:                /* dt Rn */
1361         tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);
1362         tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, REG(B11_8), 0);
1363         return;
1364     case 0x402b:                /* jmp @Rn */
1365         CHECK_NOT_DELAY_SLOT
1366         tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1367         ctx->flags |= DELAY_SLOT;
1368         ctx->delayed_pc = (uint32_t) - 1;
1369         return;
1370     case 0x400b:                /* jsr @Rn */
1371         CHECK_NOT_DELAY_SLOT
1372         tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1373         tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1374         ctx->flags |= DELAY_SLOT;
1375         ctx->delayed_pc = (uint32_t) - 1;
1376         return;
1377     case 0x400e:                /* ldc Rm,SR */
1378         CHECK_PRIVILEGED
1379         {
1380             TCGv val = tcg_temp_new();
1381             tcg_gen_andi_i32(val, REG(B11_8), 0x700083f3);
1382             gen_write_sr(val);
1383             tcg_temp_free(val);
1384             ctx->bstate = BS_STOP;
1385         }
1386         return;
1387     case 0x4007:                /* ldc.l @Rm+,SR */
1388         CHECK_PRIVILEGED
1389         {
1390             TCGv val = tcg_temp_new();
1391             tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_TESL);
1392             tcg_gen_andi_i32(val, val, 0x700083f3);
1393             gen_write_sr(val);
1394             tcg_temp_free(val);
1395             tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1396             ctx->bstate = BS_STOP;
1397         }
1398         return;
1399     case 0x0002:                /* stc SR,Rn */
1400         CHECK_PRIVILEGED
1401         gen_read_sr(REG(B11_8));
1402         return;
1403     case 0x4003:                /* stc SR,@-Rn */
1404         CHECK_PRIVILEGED
1405         {
1406             TCGv addr = tcg_temp_new();
1407             TCGv val = tcg_temp_new();
1408             tcg_gen_subi_i32(addr, REG(B11_8), 4);
1409             gen_read_sr(val);
1410             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_TEUL);
1411             tcg_gen_mov_i32(REG(B11_8), addr);
1412             tcg_temp_free(val);
1413             tcg_temp_free(addr);
1414         }
1415         return;
1416 #define LD(reg,ldnum,ldpnum,prechk)             \
1417   case ldnum:                                                   \
1418     prechk                                                      \
1419     tcg_gen_mov_i32 (cpu_##reg, REG(B11_8));                    \
1420     return;                                                     \
1421   case ldpnum:                                                  \
1422     prechk                                                      \
1423     tcg_gen_qemu_ld_i32(cpu_##reg, REG(B11_8), ctx->memidx, MO_TESL); \
1424     tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);                \
1425     return;
1426 #define ST(reg,stnum,stpnum,prechk)             \
1427   case stnum:                                                   \
1428     prechk                                                      \
1429     tcg_gen_mov_i32 (REG(B11_8), cpu_##reg);                    \
1430     return;                                                     \
1431   case stpnum:                                                  \
1432     prechk                                                      \
1433     {                                                           \
1434         TCGv addr = tcg_temp_new();                             \
1435         tcg_gen_subi_i32(addr, REG(B11_8), 4);                  \
1436         tcg_gen_qemu_st_i32(cpu_##reg, addr, ctx->memidx, MO_TEUL); \
1437         tcg_gen_mov_i32(REG(B11_8), addr);                      \
1438         tcg_temp_free(addr);                                    \
1439     }                                                           \
1440     return;
1441 #define LDST(reg,ldnum,ldpnum,stnum,stpnum,prechk)              \
1442         LD(reg,ldnum,ldpnum,prechk)                             \
1443         ST(reg,stnum,stpnum,prechk)
1444         LDST(gbr,  0x401e, 0x4017, 0x0012, 0x4013, {})
1445         LDST(vbr,  0x402e, 0x4027, 0x0022, 0x4023, CHECK_PRIVILEGED)
1446         LDST(ssr,  0x403e, 0x4037, 0x0032, 0x4033, CHECK_PRIVILEGED)
1447         LDST(spc,  0x404e, 0x4047, 0x0042, 0x4043, CHECK_PRIVILEGED)
1448         ST(sgr,  0x003a, 0x4032, CHECK_PRIVILEGED)
1449         LD(sgr,  0x403a, 0x4036, CHECK_PRIVILEGED if (!(ctx->features & SH_FEATURE_SH4A)) break;)
1450         LDST(dbr,  0x40fa, 0x40f6, 0x00fa, 0x40f2, CHECK_PRIVILEGED)
1451         LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002, {})
1452         LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012, {})
1453         LDST(pr,   0x402a, 0x4026, 0x002a, 0x4022, {})
1454         LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052, {CHECK_FPU_ENABLED})
1455     case 0x406a:                /* lds Rm,FPSCR */
1456         CHECK_FPU_ENABLED
1457         gen_helper_ld_fpscr(cpu_env, REG(B11_8));
1458         ctx->bstate = BS_STOP;
1459         return;
1460     case 0x4066:                /* lds.l @Rm+,FPSCR */
1461         CHECK_FPU_ENABLED
1462         {
1463             TCGv addr = tcg_temp_new();
1464             tcg_gen_qemu_ld_i32(addr, REG(B11_8), ctx->memidx, MO_TESL);
1465             tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1466             gen_helper_ld_fpscr(cpu_env, addr);
1467             tcg_temp_free(addr);
1468             ctx->bstate = BS_STOP;
1469         }
1470         return;
1471     case 0x006a:                /* sts FPSCR,Rn */
1472         CHECK_FPU_ENABLED
1473         tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);
1474         return;
1475     case 0x4062:                /* sts FPSCR,@-Rn */
1476         CHECK_FPU_ENABLED
1477         {
1478             TCGv addr, val;
1479             val = tcg_temp_new();
1480             tcg_gen_andi_i32(val, cpu_fpscr, 0x003fffff);
1481             addr = tcg_temp_new();
1482             tcg_gen_subi_i32(addr, REG(B11_8), 4);
1483             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_TEUL);
1484             tcg_gen_mov_i32(REG(B11_8), addr);
1485             tcg_temp_free(addr);
1486             tcg_temp_free(val);
1487         }
1488         return;
1489     case 0x00c3:                /* movca.l R0,@Rm */
1490         {
1491             TCGv val = tcg_temp_new();
1492             tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_TEUL);
1493             gen_helper_movcal(cpu_env, REG(B11_8), val);
1494             tcg_gen_qemu_st_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1495         }
1496         ctx->has_movcal = 1;
1497         return;
1498     case 0x40a9:
1499         /* MOVUA.L @Rm,R0 (Rm) -> R0
1500            Load non-boundary-aligned data */
1501         tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1502         return;
1503     case 0x40e9:
1504         /* MOVUA.L @Rm+,R0   (Rm) -> R0, Rm + 4 -> Rm
1505            Load non-boundary-aligned data */
1506         tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1507         tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1508         return;
1509     case 0x0029:                /* movt Rn */
1510         tcg_gen_mov_i32(REG(B11_8), cpu_sr_t);
1511         return;
1512     case 0x0073:
1513         /* MOVCO.L
1514                LDST -> T
1515                If (T == 1) R0 -> (Rn)
1516                0 -> LDST
1517         */
1518         if (ctx->features & SH_FEATURE_SH4A) {
1519             TCGLabel *label = gen_new_label();
1520             tcg_gen_mov_i32(cpu_sr_t, cpu_ldst);
1521             tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ldst, 0, label);
1522             tcg_gen_qemu_st_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1523             gen_set_label(label);
1524             tcg_gen_movi_i32(cpu_ldst, 0);
1525             return;
1526         } else
1527             break;
1528     case 0x0063:
1529         /* MOVLI.L @Rm,R0
1530                1 -> LDST
1531                (Rm) -> R0
1532                When interrupt/exception
1533                occurred 0 -> LDST
1534         */
1535         if (ctx->features & SH_FEATURE_SH4A) {
1536             tcg_gen_movi_i32(cpu_ldst, 0);
1537             tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TESL);
1538             tcg_gen_movi_i32(cpu_ldst, 1);
1539             return;
1540         } else
1541             break;
1542     case 0x0093:                /* ocbi @Rn */
1543         {
1544             gen_helper_ocbi(cpu_env, REG(B11_8));
1545         }
1546         return;
1547     case 0x00a3:                /* ocbp @Rn */
1548     case 0x00b3:                /* ocbwb @Rn */
1549         /* These instructions are supposed to do nothing in case of
1550            a cache miss. Given that we only partially emulate caches
1551            it is safe to simply ignore them. */
1552         return;
1553     case 0x0083:                /* pref @Rn */
1554         return;
1555     case 0x00d3:                /* prefi @Rn */
1556         if (ctx->features & SH_FEATURE_SH4A)
1557             return;
1558         else
1559             break;
1560     case 0x00e3:                /* icbi @Rn */
1561         if (ctx->features & SH_FEATURE_SH4A)
1562             return;
1563         else
1564             break;
1565     case 0x00ab:                /* synco */
1566         if (ctx->features & SH_FEATURE_SH4A)
1567             return;
1568         else
1569             break;
1570     case 0x4024:                /* rotcl Rn */
1571         {
1572             TCGv tmp = tcg_temp_new();
1573             tcg_gen_mov_i32(tmp, cpu_sr_t);
1574             tcg_gen_shri_i32(cpu_sr_t, REG(B11_8), 31);
1575             tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1576             tcg_gen_or_i32(REG(B11_8), REG(B11_8), tmp);
1577             tcg_temp_free(tmp);
1578         }
1579         return;
1580     case 0x4025:                /* rotcr Rn */
1581         {
1582             TCGv tmp = tcg_temp_new();
1583             tcg_gen_shli_i32(tmp, cpu_sr_t, 31);
1584             tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1585             tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1586             tcg_gen_or_i32(REG(B11_8), REG(B11_8), tmp);
1587             tcg_temp_free(tmp);
1588         }
1589         return;
1590     case 0x4004:                /* rotl Rn */
1591         tcg_gen_rotli_i32(REG(B11_8), REG(B11_8), 1);
1592         tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 0);
1593         return;
1594     case 0x4005:                /* rotr Rn */
1595         tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 0);
1596         tcg_gen_rotri_i32(REG(B11_8), REG(B11_8), 1);
1597         return;
1598     case 0x4000:                /* shll Rn */
1599     case 0x4020:                /* shal Rn */
1600         tcg_gen_shri_i32(cpu_sr_t, REG(B11_8), 31);
1601         tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1602         return;
1603     case 0x4021:                /* shar Rn */
1604         tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1605         tcg_gen_sari_i32(REG(B11_8), REG(B11_8), 1);
1606         return;
1607     case 0x4001:                /* shlr Rn */
1608         tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1609         tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1610         return;
1611     case 0x4008:                /* shll2 Rn */
1612         tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 2);
1613         return;
1614     case 0x4018:                /* shll8 Rn */
1615         tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 8);
1616         return;
1617     case 0x4028:                /* shll16 Rn */
1618         tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 16);
1619         return;
1620     case 0x4009:                /* shlr2 Rn */
1621         tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 2);
1622         return;
1623     case 0x4019:                /* shlr8 Rn */
1624         tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 8);
1625         return;
1626     case 0x4029:                /* shlr16 Rn */
1627         tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16);
1628         return;
1629     case 0x401b:                /* tas.b @Rn */
1630         {
1631             TCGv addr, val;
1632             addr = tcg_temp_local_new();
1633             tcg_gen_mov_i32(addr, REG(B11_8));
1634             val = tcg_temp_local_new();
1635             tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1636             tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1637             tcg_gen_ori_i32(val, val, 0x80);
1638             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1639             tcg_temp_free(val);
1640             tcg_temp_free(addr);
1641         }
1642         return;
1643     case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1644         CHECK_FPU_ENABLED
1645         tcg_gen_mov_i32(cpu_fregs[FREG(B11_8)], cpu_fpul);
1646         return;
1647     case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1648         CHECK_FPU_ENABLED
1649         tcg_gen_mov_i32(cpu_fpul, cpu_fregs[FREG(B11_8)]);
1650         return;
1651     case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1652         CHECK_FPU_ENABLED
1653         if (ctx->flags & FPSCR_PR) {
1654             TCGv_i64 fp;
1655             if (ctx->opcode & 0x0100)
1656                 break; /* illegal instruction */
1657             fp = tcg_temp_new_i64();
1658             gen_helper_float_DT(fp, cpu_env, cpu_fpul);
1659             gen_store_fpr64(fp, DREG(B11_8));
1660             tcg_temp_free_i64(fp);
1661         }
1662         else {
1663             gen_helper_float_FT(cpu_fregs[FREG(B11_8)], cpu_env, cpu_fpul);
1664         }
1665         return;
1666     case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1667         CHECK_FPU_ENABLED
1668         if (ctx->flags & FPSCR_PR) {
1669             TCGv_i64 fp;
1670             if (ctx->opcode & 0x0100)
1671                 break; /* illegal instruction */
1672             fp = tcg_temp_new_i64();
1673             gen_load_fpr64(fp, DREG(B11_8));
1674             gen_helper_ftrc_DT(cpu_fpul, cpu_env, fp);
1675             tcg_temp_free_i64(fp);
1676         }
1677         else {
1678             gen_helper_ftrc_FT(cpu_fpul, cpu_env, cpu_fregs[FREG(B11_8)]);
1679         }
1680         return;
1681     case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1682         CHECK_FPU_ENABLED
1683         {
1684             gen_helper_fneg_T(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
1685         }
1686         return;
1687     case 0xf05d: /* fabs FRn/DRn */
1688         CHECK_FPU_ENABLED
1689         if (ctx->flags & FPSCR_PR) {
1690             if (ctx->opcode & 0x0100)
1691                 break; /* illegal instruction */
1692             TCGv_i64 fp = tcg_temp_new_i64();
1693             gen_load_fpr64(fp, DREG(B11_8));
1694             gen_helper_fabs_DT(fp, fp);
1695             gen_store_fpr64(fp, DREG(B11_8));
1696             tcg_temp_free_i64(fp);
1697         } else {
1698             gen_helper_fabs_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
1699         }
1700         return;
1701     case 0xf06d: /* fsqrt FRn */
1702         CHECK_FPU_ENABLED
1703         if (ctx->flags & FPSCR_PR) {
1704             if (ctx->opcode & 0x0100)
1705                 break; /* illegal instruction */
1706             TCGv_i64 fp = tcg_temp_new_i64();
1707             gen_load_fpr64(fp, DREG(B11_8));
1708             gen_helper_fsqrt_DT(fp, cpu_env, fp);
1709             gen_store_fpr64(fp, DREG(B11_8));
1710             tcg_temp_free_i64(fp);
1711         } else {
1712             gen_helper_fsqrt_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1713                                 cpu_fregs[FREG(B11_8)]);
1714         }
1715         return;
1716     case 0xf07d: /* fsrra FRn */
1717         CHECK_FPU_ENABLED
1718         break;
1719     case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1720         CHECK_FPU_ENABLED
1721         if (!(ctx->flags & FPSCR_PR)) {
1722             tcg_gen_movi_i32(cpu_fregs[FREG(B11_8)], 0);
1723         }
1724         return;
1725     case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1726         CHECK_FPU_ENABLED
1727         if (!(ctx->flags & FPSCR_PR)) {
1728             tcg_gen_movi_i32(cpu_fregs[FREG(B11_8)], 0x3f800000);
1729         }
1730         return;
1731     case 0xf0ad: /* fcnvsd FPUL,DRn */
1732         CHECK_FPU_ENABLED
1733         {
1734             TCGv_i64 fp = tcg_temp_new_i64();
1735             gen_helper_fcnvsd_FT_DT(fp, cpu_env, cpu_fpul);
1736             gen_store_fpr64(fp, DREG(B11_8));
1737             tcg_temp_free_i64(fp);
1738         }
1739         return;
1740     case 0xf0bd: /* fcnvds DRn,FPUL */
1741         CHECK_FPU_ENABLED
1742         {
1743             TCGv_i64 fp = tcg_temp_new_i64();
1744             gen_load_fpr64(fp, DREG(B11_8));
1745             gen_helper_fcnvds_DT_FT(cpu_fpul, cpu_env, fp);
1746             tcg_temp_free_i64(fp);
1747         }
1748         return;
1749     case 0xf0ed: /* fipr FVm,FVn */
1750         CHECK_FPU_ENABLED
1751         if ((ctx->flags & FPSCR_PR) == 0) {
1752             TCGv m, n;
1753             m = tcg_const_i32((ctx->opcode >> 8) & 3);
1754             n = tcg_const_i32((ctx->opcode >> 10) & 3);
1755             gen_helper_fipr(cpu_env, m, n);
1756             tcg_temp_free(m);
1757             tcg_temp_free(n);
1758             return;
1759         }
1760         break;
1761     case 0xf0fd: /* ftrv XMTRX,FVn */
1762         CHECK_FPU_ENABLED
1763         if ((ctx->opcode & 0x0300) == 0x0100 &&
1764             (ctx->flags & FPSCR_PR) == 0) {
1765             TCGv n;
1766             n = tcg_const_i32((ctx->opcode >> 10) & 3);
1767             gen_helper_ftrv(cpu_env, n);
1768             tcg_temp_free(n);
1769             return;
1770         }
1771         break;
1772     }
1773 #if 0
1774     fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1775             ctx->opcode, ctx->pc);
1776     fflush(stderr);
1777 #endif
1778     tcg_gen_movi_i32(cpu_pc, ctx->pc);
1779     if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1780         gen_helper_raise_slot_illegal_instruction(cpu_env);
1781     } else {
1782         gen_helper_raise_illegal_instruction(cpu_env);
1783     }
1784     ctx->bstate = BS_BRANCH;
1785 }
1786
1787 static void decode_opc(DisasContext * ctx)
1788 {
1789     uint32_t old_flags = ctx->flags;
1790
1791     _decode_opc(ctx);
1792
1793     if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1794         if (ctx->flags & DELAY_SLOT_CLEARME) {
1795             gen_store_flags(0);
1796         } else {
1797             /* go out of the delay slot */
1798             uint32_t new_flags = ctx->flags;
1799             new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1800             gen_store_flags(new_flags);
1801         }
1802         ctx->flags = 0;
1803         ctx->bstate = BS_BRANCH;
1804         if (old_flags & DELAY_SLOT_CONDITIONAL) {
1805             gen_delayed_conditional_jump(ctx);
1806         } else if (old_flags & DELAY_SLOT) {
1807             gen_jump(ctx);
1808         }
1809
1810     }
1811
1812     /* go into a delay slot */
1813     if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1814         gen_store_flags(ctx->flags);
1815 }
1816
1817 void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
1818 {
1819     SuperHCPU *cpu = sh_env_get_cpu(env);
1820     CPUState *cs = CPU(cpu);
1821     DisasContext ctx;
1822     target_ulong pc_start;
1823     int num_insns;
1824     int max_insns;
1825
1826     pc_start = tb->pc;
1827     ctx.pc = pc_start;
1828     ctx.flags = (uint32_t)tb->flags;
1829     ctx.bstate = BS_NONE;
1830     ctx.memidx = (ctx.flags & (1u << SR_MD)) == 0 ? 1 : 0;
1831     /* We don't know if the delayed pc came from a dynamic or static branch,
1832        so assume it is a dynamic branch.  */
1833     ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1834     ctx.tb = tb;
1835     ctx.singlestep_enabled = cs->singlestep_enabled;
1836     ctx.features = env->features;
1837     ctx.has_movcal = (ctx.flags & TB_FLAG_PENDING_MOVCA);
1838
1839     num_insns = 0;
1840     max_insns = tb->cflags & CF_COUNT_MASK;
1841     if (max_insns == 0) {
1842         max_insns = CF_COUNT_MASK;
1843     }
1844     if (max_insns > TCG_MAX_INSNS) {
1845         max_insns = TCG_MAX_INSNS;
1846     }
1847
1848     gen_tb_start(tb);
1849     while (ctx.bstate == BS_NONE && !tcg_op_buf_full()) {
1850         tcg_gen_insn_start(ctx.pc, ctx.flags);
1851         num_insns++;
1852
1853         if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
1854             /* We have hit a breakpoint - make sure PC is up-to-date */
1855             tcg_gen_movi_i32(cpu_pc, ctx.pc);
1856             gen_helper_debug(cpu_env);
1857             ctx.bstate = BS_BRANCH;
1858             break;
1859         }
1860
1861         if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
1862             gen_io_start();
1863         }
1864
1865         ctx.opcode = cpu_lduw_code(env, ctx.pc);
1866         decode_opc(&ctx);
1867         ctx.pc += 2;
1868         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1869             break;
1870         if (cs->singlestep_enabled) {
1871             break;
1872         }
1873         if (num_insns >= max_insns)
1874             break;
1875         if (singlestep)
1876             break;
1877     }
1878     if (tb->cflags & CF_LAST_IO)
1879         gen_io_end();
1880     if (cs->singlestep_enabled) {
1881         tcg_gen_movi_i32(cpu_pc, ctx.pc);
1882         gen_helper_debug(cpu_env);
1883     } else {
1884         switch (ctx.bstate) {
1885         case BS_STOP:
1886             /* gen_op_interrupt_restart(); */
1887             /* fall through */
1888         case BS_NONE:
1889             if (ctx.flags) {
1890                 gen_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1891             }
1892             gen_goto_tb(&ctx, 0, ctx.pc);
1893             break;
1894         case BS_EXCP:
1895             /* gen_op_interrupt_restart(); */
1896             tcg_gen_exit_tb(0);
1897             break;
1898         case BS_BRANCH:
1899         default:
1900             break;
1901         }
1902     }
1903
1904     gen_tb_end(tb, num_insns);
1905
1906     tb->size = ctx.pc - pc_start;
1907     tb->icount = num_insns;
1908
1909 #ifdef DEBUG_DISAS
1910     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1911         qemu_log("IN:\n");      /* , lookup_symbol(pc_start)); */
1912         log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
1913         qemu_log("\n");
1914     }
1915 #endif
1916 }
1917
1918 void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb,
1919                           target_ulong *data)
1920 {
1921     env->pc = data[0];
1922     env->flags = data[1];
1923 }
This page took 0.138653 seconds and 4 git commands to generate.