]> Git Repo - qemu.git/blob - target/sh4/translate.c
target/sh4: Fix LGPL information in the file headers
[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.1 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 "qemu/osdep.h"
23 #include "cpu.h"
24 #include "disas/disas.h"
25 #include "exec/exec-all.h"
26 #include "tcg-op.h"
27 #include "exec/cpu_ldst.h"
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
30 #include "exec/translator.h"
31 #include "trace-tcg.h"
32 #include "exec/log.h"
33 #include "qemu/qemu-print.h"
34
35
36 typedef struct DisasContext {
37     DisasContextBase base;
38
39     uint32_t tbflags;  /* should stay unmodified during the TB translation */
40     uint32_t envflags; /* should stay in sync with env->flags using TCG ops */
41     int memidx;
42     int gbank;
43     int fbank;
44     uint32_t delayed_pc;
45     uint32_t features;
46
47     uint16_t opcode;
48
49     bool has_movcal;
50 } DisasContext;
51
52 #if defined(CONFIG_USER_ONLY)
53 #define IS_USER(ctx) 1
54 #else
55 #define IS_USER(ctx) (!(ctx->tbflags & (1u << SR_MD)))
56 #endif
57
58 /* Target-specific values for ctx->base.is_jmp.  */
59 /* We want to exit back to the cpu loop for some reason.
60    Usually this is to recognize interrupts immediately.  */
61 #define DISAS_STOP    DISAS_TARGET_0
62
63 /* global register indexes */
64 static TCGv cpu_gregs[32];
65 static TCGv cpu_sr, cpu_sr_m, cpu_sr_q, cpu_sr_t;
66 static TCGv cpu_pc, cpu_ssr, cpu_spc, cpu_gbr;
67 static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
68 static TCGv cpu_pr, cpu_fpscr, cpu_fpul;
69 static TCGv cpu_lock_addr, cpu_lock_value;
70 static TCGv cpu_fregs[32];
71
72 /* internal register indexes */
73 static TCGv cpu_flags, cpu_delayed_pc, cpu_delayed_cond;
74
75 #include "exec/gen-icount.h"
76
77 void sh4_translate_init(void)
78 {
79     int i;
80     static const char * const gregnames[24] = {
81         "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
82         "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
83         "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
84         "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
85         "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
86     };
87     static const char * const fregnames[32] = {
88          "FPR0_BANK0",  "FPR1_BANK0",  "FPR2_BANK0",  "FPR3_BANK0",
89          "FPR4_BANK0",  "FPR5_BANK0",  "FPR6_BANK0",  "FPR7_BANK0",
90          "FPR8_BANK0",  "FPR9_BANK0", "FPR10_BANK0", "FPR11_BANK0",
91         "FPR12_BANK0", "FPR13_BANK0", "FPR14_BANK0", "FPR15_BANK0",
92          "FPR0_BANK1",  "FPR1_BANK1",  "FPR2_BANK1",  "FPR3_BANK1",
93          "FPR4_BANK1",  "FPR5_BANK1",  "FPR6_BANK1",  "FPR7_BANK1",
94          "FPR8_BANK1",  "FPR9_BANK1", "FPR10_BANK1", "FPR11_BANK1",
95         "FPR12_BANK1", "FPR13_BANK1", "FPR14_BANK1", "FPR15_BANK1",
96     };
97
98     for (i = 0; i < 24; i++) {
99         cpu_gregs[i] = tcg_global_mem_new_i32(cpu_env,
100                                               offsetof(CPUSH4State, gregs[i]),
101                                               gregnames[i]);
102     }
103     memcpy(cpu_gregs + 24, cpu_gregs + 8, 8 * sizeof(TCGv));
104
105     cpu_pc = tcg_global_mem_new_i32(cpu_env,
106                                     offsetof(CPUSH4State, pc), "PC");
107     cpu_sr = tcg_global_mem_new_i32(cpu_env,
108                                     offsetof(CPUSH4State, sr), "SR");
109     cpu_sr_m = tcg_global_mem_new_i32(cpu_env,
110                                       offsetof(CPUSH4State, sr_m), "SR_M");
111     cpu_sr_q = tcg_global_mem_new_i32(cpu_env,
112                                       offsetof(CPUSH4State, sr_q), "SR_Q");
113     cpu_sr_t = tcg_global_mem_new_i32(cpu_env,
114                                       offsetof(CPUSH4State, sr_t), "SR_T");
115     cpu_ssr = tcg_global_mem_new_i32(cpu_env,
116                                      offsetof(CPUSH4State, ssr), "SSR");
117     cpu_spc = tcg_global_mem_new_i32(cpu_env,
118                                      offsetof(CPUSH4State, spc), "SPC");
119     cpu_gbr = tcg_global_mem_new_i32(cpu_env,
120                                      offsetof(CPUSH4State, gbr), "GBR");
121     cpu_vbr = tcg_global_mem_new_i32(cpu_env,
122                                      offsetof(CPUSH4State, vbr), "VBR");
123     cpu_sgr = tcg_global_mem_new_i32(cpu_env,
124                                      offsetof(CPUSH4State, sgr), "SGR");
125     cpu_dbr = tcg_global_mem_new_i32(cpu_env,
126                                      offsetof(CPUSH4State, dbr), "DBR");
127     cpu_mach = tcg_global_mem_new_i32(cpu_env,
128                                       offsetof(CPUSH4State, mach), "MACH");
129     cpu_macl = tcg_global_mem_new_i32(cpu_env,
130                                       offsetof(CPUSH4State, macl), "MACL");
131     cpu_pr = tcg_global_mem_new_i32(cpu_env,
132                                     offsetof(CPUSH4State, pr), "PR");
133     cpu_fpscr = tcg_global_mem_new_i32(cpu_env,
134                                        offsetof(CPUSH4State, fpscr), "FPSCR");
135     cpu_fpul = tcg_global_mem_new_i32(cpu_env,
136                                       offsetof(CPUSH4State, fpul), "FPUL");
137
138     cpu_flags = tcg_global_mem_new_i32(cpu_env,
139                                        offsetof(CPUSH4State, flags), "_flags_");
140     cpu_delayed_pc = tcg_global_mem_new_i32(cpu_env,
141                                             offsetof(CPUSH4State, delayed_pc),
142                                             "_delayed_pc_");
143     cpu_delayed_cond = tcg_global_mem_new_i32(cpu_env,
144                                               offsetof(CPUSH4State,
145                                                        delayed_cond),
146                                               "_delayed_cond_");
147     cpu_lock_addr = tcg_global_mem_new_i32(cpu_env,
148                                            offsetof(CPUSH4State, lock_addr),
149                                            "_lock_addr_");
150     cpu_lock_value = tcg_global_mem_new_i32(cpu_env,
151                                             offsetof(CPUSH4State, lock_value),
152                                             "_lock_value_");
153
154     for (i = 0; i < 32; i++)
155         cpu_fregs[i] = tcg_global_mem_new_i32(cpu_env,
156                                               offsetof(CPUSH4State, fregs[i]),
157                                               fregnames[i]);
158 }
159
160 void superh_cpu_dump_state(CPUState *cs, FILE *f, int flags)
161 {
162     SuperHCPU *cpu = SUPERH_CPU(cs);
163     CPUSH4State *env = &cpu->env;
164     int i;
165
166     qemu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
167                  env->pc, cpu_read_sr(env), env->pr, env->fpscr);
168     qemu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
169                  env->spc, env->ssr, env->gbr, env->vbr);
170     qemu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
171                  env->sgr, env->dbr, env->delayed_pc, env->fpul);
172     for (i = 0; i < 24; i += 4) {
173         qemu_printf("r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
174                     i, env->gregs[i], i + 1, env->gregs[i + 1],
175                     i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
176     }
177     if (env->flags & DELAY_SLOT) {
178         qemu_printf("in delay slot (delayed_pc=0x%08x)\n",
179                     env->delayed_pc);
180     } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
181         qemu_printf("in conditional delay slot (delayed_pc=0x%08x)\n",
182                     env->delayed_pc);
183     } else if (env->flags & DELAY_SLOT_RTE) {
184         qemu_fprintf(f, "in rte delay slot (delayed_pc=0x%08x)\n",
185                      env->delayed_pc);
186     }
187 }
188
189 static void gen_read_sr(TCGv dst)
190 {
191     TCGv t0 = tcg_temp_new();
192     tcg_gen_shli_i32(t0, cpu_sr_q, SR_Q);
193     tcg_gen_or_i32(dst, dst, t0);
194     tcg_gen_shli_i32(t0, cpu_sr_m, SR_M);
195     tcg_gen_or_i32(dst, dst, t0);
196     tcg_gen_shli_i32(t0, cpu_sr_t, SR_T);
197     tcg_gen_or_i32(dst, cpu_sr, t0);
198     tcg_temp_free_i32(t0);
199 }
200
201 static void gen_write_sr(TCGv src)
202 {
203     tcg_gen_andi_i32(cpu_sr, src,
204                      ~((1u << SR_Q) | (1u << SR_M) | (1u << SR_T)));
205     tcg_gen_extract_i32(cpu_sr_q, src, SR_Q, 1);
206     tcg_gen_extract_i32(cpu_sr_m, src, SR_M, 1);
207     tcg_gen_extract_i32(cpu_sr_t, src, SR_T, 1);
208 }
209
210 static inline void gen_save_cpu_state(DisasContext *ctx, bool save_pc)
211 {
212     if (save_pc) {
213         tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next);
214     }
215     if (ctx->delayed_pc != (uint32_t) -1) {
216         tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
217     }
218     if ((ctx->tbflags & TB_FLAG_ENVFLAGS_MASK) != ctx->envflags) {
219         tcg_gen_movi_i32(cpu_flags, ctx->envflags);
220     }
221 }
222
223 static inline bool use_exit_tb(DisasContext *ctx)
224 {
225     return (ctx->tbflags & GUSA_EXCLUSIVE) != 0;
226 }
227
228 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
229 {
230     /* Use a direct jump if in same page and singlestep not enabled */
231     if (unlikely(ctx->base.singlestep_enabled || use_exit_tb(ctx))) {
232         return false;
233     }
234 #ifndef CONFIG_USER_ONLY
235     return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
236 #else
237     return true;
238 #endif
239 }
240
241 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
242 {
243     if (use_goto_tb(ctx, dest)) {
244         tcg_gen_goto_tb(n);
245         tcg_gen_movi_i32(cpu_pc, dest);
246         tcg_gen_exit_tb(ctx->base.tb, n);
247     } else {
248         tcg_gen_movi_i32(cpu_pc, dest);
249         if (ctx->base.singlestep_enabled) {
250             gen_helper_debug(cpu_env);
251         } else if (use_exit_tb(ctx)) {
252             tcg_gen_exit_tb(NULL, 0);
253         } else {
254             tcg_gen_lookup_and_goto_ptr();
255         }
256     }
257     ctx->base.is_jmp = DISAS_NORETURN;
258 }
259
260 static void gen_jump(DisasContext * ctx)
261 {
262     if (ctx->delayed_pc == -1) {
263         /* Target is not statically known, it comes necessarily from a
264            delayed jump as immediate jump are conditinal jumps */
265         tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
266         tcg_gen_discard_i32(cpu_delayed_pc);
267         if (ctx->base.singlestep_enabled) {
268             gen_helper_debug(cpu_env);
269         } else if (use_exit_tb(ctx)) {
270             tcg_gen_exit_tb(NULL, 0);
271         } else {
272             tcg_gen_lookup_and_goto_ptr();
273         }
274         ctx->base.is_jmp = DISAS_NORETURN;
275     } else {
276         gen_goto_tb(ctx, 0, ctx->delayed_pc);
277     }
278 }
279
280 /* Immediate conditional jump (bt or bf) */
281 static void gen_conditional_jump(DisasContext *ctx, target_ulong dest,
282                                  bool jump_if_true)
283 {
284     TCGLabel *l1 = gen_new_label();
285     TCGCond cond_not_taken = jump_if_true ? TCG_COND_EQ : TCG_COND_NE;
286
287     if (ctx->tbflags & GUSA_EXCLUSIVE) {
288         /* When in an exclusive region, we must continue to the end.
289            Therefore, exit the region on a taken branch, but otherwise
290            fall through to the next instruction.  */
291         tcg_gen_brcondi_i32(cond_not_taken, cpu_sr_t, 0, l1);
292         tcg_gen_movi_i32(cpu_flags, ctx->envflags & ~GUSA_MASK);
293         /* Note that this won't actually use a goto_tb opcode because we
294            disallow it in use_goto_tb, but it handles exit + singlestep.  */
295         gen_goto_tb(ctx, 0, dest);
296         gen_set_label(l1);
297         ctx->base.is_jmp = DISAS_NEXT;
298         return;
299     }
300
301     gen_save_cpu_state(ctx, false);
302     tcg_gen_brcondi_i32(cond_not_taken, cpu_sr_t, 0, l1);
303     gen_goto_tb(ctx, 0, dest);
304     gen_set_label(l1);
305     gen_goto_tb(ctx, 1, ctx->base.pc_next + 2);
306     ctx->base.is_jmp = DISAS_NORETURN;
307 }
308
309 /* Delayed conditional jump (bt or bf) */
310 static void gen_delayed_conditional_jump(DisasContext * ctx)
311 {
312     TCGLabel *l1 = gen_new_label();
313     TCGv ds = tcg_temp_new();
314
315     tcg_gen_mov_i32(ds, cpu_delayed_cond);
316     tcg_gen_discard_i32(cpu_delayed_cond);
317
318     if (ctx->tbflags & GUSA_EXCLUSIVE) {
319         /* When in an exclusive region, we must continue to the end.
320            Therefore, exit the region on a taken branch, but otherwise
321            fall through to the next instruction.  */
322         tcg_gen_brcondi_i32(TCG_COND_EQ, ds, 0, l1);
323
324         /* Leave the gUSA region.  */
325         tcg_gen_movi_i32(cpu_flags, ctx->envflags & ~GUSA_MASK);
326         gen_jump(ctx);
327
328         gen_set_label(l1);
329         ctx->base.is_jmp = DISAS_NEXT;
330         return;
331     }
332
333     tcg_gen_brcondi_i32(TCG_COND_NE, ds, 0, l1);
334     gen_goto_tb(ctx, 1, ctx->base.pc_next + 2);
335     gen_set_label(l1);
336     gen_jump(ctx);
337 }
338
339 static inline void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
340 {
341     /* We have already signaled illegal instruction for odd Dr.  */
342     tcg_debug_assert((reg & 1) == 0);
343     reg ^= ctx->fbank;
344     tcg_gen_concat_i32_i64(t, cpu_fregs[reg + 1], cpu_fregs[reg]);
345 }
346
347 static inline void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
348 {
349     /* We have already signaled illegal instruction for odd Dr.  */
350     tcg_debug_assert((reg & 1) == 0);
351     reg ^= ctx->fbank;
352     tcg_gen_extr_i64_i32(cpu_fregs[reg + 1], cpu_fregs[reg], t);
353 }
354
355 #define B3_0 (ctx->opcode & 0xf)
356 #define B6_4 ((ctx->opcode >> 4) & 0x7)
357 #define B7_4 ((ctx->opcode >> 4) & 0xf)
358 #define B7_0 (ctx->opcode & 0xff)
359 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
360 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
361   (ctx->opcode & 0xfff))
362 #define B11_8 ((ctx->opcode >> 8) & 0xf)
363 #define B15_12 ((ctx->opcode >> 12) & 0xf)
364
365 #define REG(x)     cpu_gregs[(x) ^ ctx->gbank]
366 #define ALTREG(x)  cpu_gregs[(x) ^ ctx->gbank ^ 0x10]
367 #define FREG(x)    cpu_fregs[(x) ^ ctx->fbank]
368
369 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
370
371 #define CHECK_NOT_DELAY_SLOT \
372     if (ctx->envflags & DELAY_SLOT_MASK) {  \
373         goto do_illegal_slot;               \
374     }
375
376 #define CHECK_PRIVILEGED \
377     if (IS_USER(ctx)) {                     \
378         goto do_illegal;                    \
379     }
380
381 #define CHECK_FPU_ENABLED \
382     if (ctx->tbflags & (1u << SR_FD)) {     \
383         goto do_fpu_disabled;               \
384     }
385
386 #define CHECK_FPSCR_PR_0 \
387     if (ctx->tbflags & FPSCR_PR) {          \
388         goto do_illegal;                    \
389     }
390
391 #define CHECK_FPSCR_PR_1 \
392     if (!(ctx->tbflags & FPSCR_PR)) {       \
393         goto do_illegal;                    \
394     }
395
396 #define CHECK_SH4A \
397     if (!(ctx->features & SH_FEATURE_SH4A)) { \
398         goto do_illegal;                      \
399     }
400
401 static void _decode_opc(DisasContext * ctx)
402 {
403     /* This code tries to make movcal emulation sufficiently
404        accurate for Linux purposes.  This instruction writes
405        memory, and prior to that, always allocates a cache line.
406        It is used in two contexts:
407        - in memcpy, where data is copied in blocks, the first write
408        of to a block uses movca.l for performance.
409        - in arch/sh/mm/cache-sh4.c, movcal.l + ocbi combination is used
410        to flush the cache. Here, the data written by movcal.l is never
411        written to memory, and the data written is just bogus.
412
413        To simulate this, we simulate movcal.l, we store the value to memory,
414        but we also remember the previous content. If we see ocbi, we check
415        if movcal.l for that address was done previously. If so, the write should
416        not have hit the memory, so we restore the previous content.
417        When we see an instruction that is neither movca.l
418        nor ocbi, the previous content is discarded.
419
420        To optimize, we only try to flush stores when we're at the start of
421        TB, or if we already saw movca.l in this TB and did not flush stores
422        yet.  */
423     if (ctx->has_movcal)
424         {
425           int opcode = ctx->opcode & 0xf0ff;
426           if (opcode != 0x0093 /* ocbi */
427               && opcode != 0x00c3 /* movca.l */)
428               {
429                   gen_helper_discard_movcal_backup(cpu_env);
430                   ctx->has_movcal = 0;
431               }
432         }
433
434 #if 0
435     fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
436 #endif
437
438     switch (ctx->opcode) {
439     case 0x0019:                /* div0u */
440         tcg_gen_movi_i32(cpu_sr_m, 0);
441         tcg_gen_movi_i32(cpu_sr_q, 0);
442         tcg_gen_movi_i32(cpu_sr_t, 0);
443         return;
444     case 0x000b:                /* rts */
445         CHECK_NOT_DELAY_SLOT
446         tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
447         ctx->envflags |= DELAY_SLOT;
448         ctx->delayed_pc = (uint32_t) - 1;
449         return;
450     case 0x0028:                /* clrmac */
451         tcg_gen_movi_i32(cpu_mach, 0);
452         tcg_gen_movi_i32(cpu_macl, 0);
453         return;
454     case 0x0048:                /* clrs */
455         tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(1u << SR_S));
456         return;
457     case 0x0008:                /* clrt */
458         tcg_gen_movi_i32(cpu_sr_t, 0);
459         return;
460     case 0x0038:                /* ldtlb */
461         CHECK_PRIVILEGED
462         gen_helper_ldtlb(cpu_env);
463         return;
464     case 0x002b:                /* rte */
465         CHECK_PRIVILEGED
466         CHECK_NOT_DELAY_SLOT
467         gen_write_sr(cpu_ssr);
468         tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
469         ctx->envflags |= DELAY_SLOT_RTE;
470         ctx->delayed_pc = (uint32_t) - 1;
471         ctx->base.is_jmp = DISAS_STOP;
472         return;
473     case 0x0058:                /* sets */
474         tcg_gen_ori_i32(cpu_sr, cpu_sr, (1u << SR_S));
475         return;
476     case 0x0018:                /* sett */
477         tcg_gen_movi_i32(cpu_sr_t, 1);
478         return;
479     case 0xfbfd:                /* frchg */
480         CHECK_FPSCR_PR_0
481         tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
482         ctx->base.is_jmp = DISAS_STOP;
483         return;
484     case 0xf3fd:                /* fschg */
485         CHECK_FPSCR_PR_0
486         tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
487         ctx->base.is_jmp = DISAS_STOP;
488         return;
489     case 0xf7fd:                /* fpchg */
490         CHECK_SH4A
491         tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_PR);
492         ctx->base.is_jmp = DISAS_STOP;
493         return;
494     case 0x0009:                /* nop */
495         return;
496     case 0x001b:                /* sleep */
497         CHECK_PRIVILEGED
498         tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next + 2);
499         gen_helper_sleep(cpu_env);
500         return;
501     }
502
503     switch (ctx->opcode & 0xf000) {
504     case 0x1000:                /* mov.l Rm,@(disp,Rn) */
505         {
506             TCGv addr = tcg_temp_new();
507             tcg_gen_addi_i32(addr, REG(B11_8), B3_0 * 4);
508             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
509             tcg_temp_free(addr);
510         }
511         return;
512     case 0x5000:                /* mov.l @(disp,Rm),Rn */
513         {
514             TCGv addr = tcg_temp_new();
515             tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 4);
516             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
517             tcg_temp_free(addr);
518         }
519         return;
520     case 0xe000:                /* mov #imm,Rn */
521 #ifdef CONFIG_USER_ONLY
522         /* Detect the start of a gUSA region.  If so, update envflags
523            and end the TB.  This will allow us to see the end of the
524            region (stored in R0) in the next TB.  */
525         if (B11_8 == 15 && B7_0s < 0 &&
526             (tb_cflags(ctx->base.tb) & CF_PARALLEL)) {
527             ctx->envflags = deposit32(ctx->envflags, GUSA_SHIFT, 8, B7_0s);
528             ctx->base.is_jmp = DISAS_STOP;
529         }
530 #endif
531         tcg_gen_movi_i32(REG(B11_8), B7_0s);
532         return;
533     case 0x9000:                /* mov.w @(disp,PC),Rn */
534         {
535             TCGv addr = tcg_const_i32(ctx->base.pc_next + 4 + B7_0 * 2);
536             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESW);
537             tcg_temp_free(addr);
538         }
539         return;
540     case 0xd000:                /* mov.l @(disp,PC),Rn */
541         {
542             TCGv addr = tcg_const_i32((ctx->base.pc_next + 4 + B7_0 * 4) & ~3);
543             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
544             tcg_temp_free(addr);
545         }
546         return;
547     case 0x7000:                /* add #imm,Rn */
548         tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);
549         return;
550     case 0xa000:                /* bra disp */
551         CHECK_NOT_DELAY_SLOT
552         ctx->delayed_pc = ctx->base.pc_next + 4 + B11_0s * 2;
553         ctx->envflags |= DELAY_SLOT;
554         return;
555     case 0xb000:                /* bsr disp */
556         CHECK_NOT_DELAY_SLOT
557         tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 4);
558         ctx->delayed_pc = ctx->base.pc_next + 4 + B11_0s * 2;
559         ctx->envflags |= DELAY_SLOT;
560         return;
561     }
562
563     switch (ctx->opcode & 0xf00f) {
564     case 0x6003:                /* mov Rm,Rn */
565         tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
566         return;
567     case 0x2000:                /* mov.b Rm,@Rn */
568         tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_UB);
569         return;
570     case 0x2001:                /* mov.w Rm,@Rn */
571         tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_TEUW);
572         return;
573     case 0x2002:                /* mov.l Rm,@Rn */
574         tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_TEUL);
575         return;
576     case 0x6000:                /* mov.b @Rm,Rn */
577         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_SB);
578         return;
579     case 0x6001:                /* mov.w @Rm,Rn */
580         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESW);
581         return;
582     case 0x6002:                /* mov.l @Rm,Rn */
583         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESL);
584         return;
585     case 0x2004:                /* mov.b Rm,@-Rn */
586         {
587             TCGv addr = tcg_temp_new();
588             tcg_gen_subi_i32(addr, REG(B11_8), 1);
589             /* might cause re-execution */
590             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_UB);
591             tcg_gen_mov_i32(REG(B11_8), addr);                  /* modify register status */
592             tcg_temp_free(addr);
593         }
594         return;
595     case 0x2005:                /* mov.w Rm,@-Rn */
596         {
597             TCGv addr = tcg_temp_new();
598             tcg_gen_subi_i32(addr, REG(B11_8), 2);
599             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUW);
600             tcg_gen_mov_i32(REG(B11_8), addr);
601             tcg_temp_free(addr);
602         }
603         return;
604     case 0x2006:                /* mov.l Rm,@-Rn */
605         {
606             TCGv addr = tcg_temp_new();
607             tcg_gen_subi_i32(addr, REG(B11_8), 4);
608             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
609             tcg_gen_mov_i32(REG(B11_8), addr);
610         tcg_temp_free(addr);
611         }
612         return;
613     case 0x6004:                /* mov.b @Rm+,Rn */
614         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_SB);
615         if ( B11_8 != B7_4 )
616                 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 1);
617         return;
618     case 0x6005:                /* mov.w @Rm+,Rn */
619         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESW);
620         if ( B11_8 != B7_4 )
621                 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
622         return;
623     case 0x6006:                /* mov.l @Rm+,Rn */
624         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESL);
625         if ( B11_8 != B7_4 )
626                 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
627         return;
628     case 0x0004:                /* mov.b Rm,@(R0,Rn) */
629         {
630             TCGv addr = tcg_temp_new();
631             tcg_gen_add_i32(addr, REG(B11_8), REG(0));
632             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_UB);
633             tcg_temp_free(addr);
634         }
635         return;
636     case 0x0005:                /* mov.w Rm,@(R0,Rn) */
637         {
638             TCGv addr = tcg_temp_new();
639             tcg_gen_add_i32(addr, REG(B11_8), REG(0));
640             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUW);
641             tcg_temp_free(addr);
642         }
643         return;
644     case 0x0006:                /* mov.l Rm,@(R0,Rn) */
645         {
646             TCGv addr = tcg_temp_new();
647             tcg_gen_add_i32(addr, REG(B11_8), REG(0));
648             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
649             tcg_temp_free(addr);
650         }
651         return;
652     case 0x000c:                /* mov.b @(R0,Rm),Rn */
653         {
654             TCGv addr = tcg_temp_new();
655             tcg_gen_add_i32(addr, REG(B7_4), REG(0));
656             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_SB);
657             tcg_temp_free(addr);
658         }
659         return;
660     case 0x000d:                /* mov.w @(R0,Rm),Rn */
661         {
662             TCGv addr = tcg_temp_new();
663             tcg_gen_add_i32(addr, REG(B7_4), REG(0));
664             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESW);
665             tcg_temp_free(addr);
666         }
667         return;
668     case 0x000e:                /* mov.l @(R0,Rm),Rn */
669         {
670             TCGv addr = tcg_temp_new();
671             tcg_gen_add_i32(addr, REG(B7_4), REG(0));
672             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
673             tcg_temp_free(addr);
674         }
675         return;
676     case 0x6008:                /* swap.b Rm,Rn */
677         {
678             TCGv low = tcg_temp_new();
679             tcg_gen_ext16u_i32(low, REG(B7_4));
680             tcg_gen_bswap16_i32(low, low);
681             tcg_gen_deposit_i32(REG(B11_8), REG(B7_4), low, 0, 16);
682             tcg_temp_free(low);
683         }
684         return;
685     case 0x6009:                /* swap.w Rm,Rn */
686         tcg_gen_rotli_i32(REG(B11_8), REG(B7_4), 16);
687         return;
688     case 0x200d:                /* xtrct Rm,Rn */
689         {
690             TCGv high, low;
691             high = tcg_temp_new();
692             tcg_gen_shli_i32(high, REG(B7_4), 16);
693             low = tcg_temp_new();
694             tcg_gen_shri_i32(low, REG(B11_8), 16);
695             tcg_gen_or_i32(REG(B11_8), high, low);
696             tcg_temp_free(low);
697             tcg_temp_free(high);
698         }
699         return;
700     case 0x300c:                /* add Rm,Rn */
701         tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));
702         return;
703     case 0x300e:                /* addc Rm,Rn */
704         {
705             TCGv t0, t1;
706             t0 = tcg_const_tl(0);
707             t1 = tcg_temp_new();
708             tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0);
709             tcg_gen_add2_i32(REG(B11_8), cpu_sr_t,
710                              REG(B11_8), t0, t1, cpu_sr_t);
711             tcg_temp_free(t0);
712             tcg_temp_free(t1);
713         }
714         return;
715     case 0x300f:                /* addv Rm,Rn */
716         {
717             TCGv t0, t1, t2;
718             t0 = tcg_temp_new();
719             tcg_gen_add_i32(t0, REG(B7_4), REG(B11_8));
720             t1 = tcg_temp_new();
721             tcg_gen_xor_i32(t1, t0, REG(B11_8));
722             t2 = tcg_temp_new();
723             tcg_gen_xor_i32(t2, REG(B7_4), REG(B11_8));
724             tcg_gen_andc_i32(cpu_sr_t, t1, t2);
725             tcg_temp_free(t2);
726             tcg_gen_shri_i32(cpu_sr_t, cpu_sr_t, 31);
727             tcg_temp_free(t1);
728             tcg_gen_mov_i32(REG(B7_4), t0);
729             tcg_temp_free(t0);
730         }
731         return;
732     case 0x2009:                /* and Rm,Rn */
733         tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
734         return;
735     case 0x3000:                /* cmp/eq Rm,Rn */
736         tcg_gen_setcond_i32(TCG_COND_EQ, cpu_sr_t, REG(B11_8), REG(B7_4));
737         return;
738     case 0x3003:                /* cmp/ge Rm,Rn */
739         tcg_gen_setcond_i32(TCG_COND_GE, cpu_sr_t, REG(B11_8), REG(B7_4));
740         return;
741     case 0x3007:                /* cmp/gt Rm,Rn */
742         tcg_gen_setcond_i32(TCG_COND_GT, cpu_sr_t, REG(B11_8), REG(B7_4));
743         return;
744     case 0x3006:                /* cmp/hi Rm,Rn */
745         tcg_gen_setcond_i32(TCG_COND_GTU, cpu_sr_t, REG(B11_8), REG(B7_4));
746         return;
747     case 0x3002:                /* cmp/hs Rm,Rn */
748         tcg_gen_setcond_i32(TCG_COND_GEU, cpu_sr_t, REG(B11_8), REG(B7_4));
749         return;
750     case 0x200c:                /* cmp/str Rm,Rn */
751         {
752             TCGv cmp1 = tcg_temp_new();
753             TCGv cmp2 = tcg_temp_new();
754             tcg_gen_xor_i32(cmp2, REG(B7_4), REG(B11_8));
755             tcg_gen_subi_i32(cmp1, cmp2, 0x01010101);
756             tcg_gen_andc_i32(cmp1, cmp1, cmp2);
757             tcg_gen_andi_i32(cmp1, cmp1, 0x80808080);
758             tcg_gen_setcondi_i32(TCG_COND_NE, cpu_sr_t, cmp1, 0);
759             tcg_temp_free(cmp2);
760             tcg_temp_free(cmp1);
761         }
762         return;
763     case 0x2007:                /* div0s Rm,Rn */
764         tcg_gen_shri_i32(cpu_sr_q, REG(B11_8), 31);         /* SR_Q */
765         tcg_gen_shri_i32(cpu_sr_m, REG(B7_4), 31);          /* SR_M */
766         tcg_gen_xor_i32(cpu_sr_t, cpu_sr_q, cpu_sr_m);      /* SR_T */
767         return;
768     case 0x3004:                /* div1 Rm,Rn */
769         {
770             TCGv t0 = tcg_temp_new();
771             TCGv t1 = tcg_temp_new();
772             TCGv t2 = tcg_temp_new();
773             TCGv zero = tcg_const_i32(0);
774
775             /* shift left arg1, saving the bit being pushed out and inserting
776                T on the right */
777             tcg_gen_shri_i32(t0, REG(B11_8), 31);
778             tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
779             tcg_gen_or_i32(REG(B11_8), REG(B11_8), cpu_sr_t);
780
781             /* Add or subtract arg0 from arg1 depending if Q == M. To avoid
782                using 64-bit temps, we compute arg0's high part from q ^ m, so
783                that it is 0x00000000 when adding the value or 0xffffffff when
784                subtracting it. */
785             tcg_gen_xor_i32(t1, cpu_sr_q, cpu_sr_m);
786             tcg_gen_subi_i32(t1, t1, 1);
787             tcg_gen_neg_i32(t2, REG(B7_4));
788             tcg_gen_movcond_i32(TCG_COND_EQ, t2, t1, zero, REG(B7_4), t2);
789             tcg_gen_add2_i32(REG(B11_8), t1, REG(B11_8), zero, t2, t1);
790
791             /* compute T and Q depending on carry */
792             tcg_gen_andi_i32(t1, t1, 1);
793             tcg_gen_xor_i32(t1, t1, t0);
794             tcg_gen_xori_i32(cpu_sr_t, t1, 1);
795             tcg_gen_xor_i32(cpu_sr_q, cpu_sr_m, t1);
796
797             tcg_temp_free(zero);
798             tcg_temp_free(t2);
799             tcg_temp_free(t1);
800             tcg_temp_free(t0);
801         }
802         return;
803     case 0x300d:                /* dmuls.l Rm,Rn */
804         tcg_gen_muls2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
805         return;
806     case 0x3005:                /* dmulu.l Rm,Rn */
807         tcg_gen_mulu2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
808         return;
809     case 0x600e:                /* exts.b Rm,Rn */
810         tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));
811         return;
812     case 0x600f:                /* exts.w Rm,Rn */
813         tcg_gen_ext16s_i32(REG(B11_8), REG(B7_4));
814         return;
815     case 0x600c:                /* extu.b Rm,Rn */
816         tcg_gen_ext8u_i32(REG(B11_8), REG(B7_4));
817         return;
818     case 0x600d:                /* extu.w Rm,Rn */
819         tcg_gen_ext16u_i32(REG(B11_8), REG(B7_4));
820         return;
821     case 0x000f:                /* mac.l @Rm+,@Rn+ */
822         {
823             TCGv arg0, arg1;
824             arg0 = tcg_temp_new();
825             tcg_gen_qemu_ld_i32(arg0, REG(B7_4), ctx->memidx, MO_TESL);
826             arg1 = tcg_temp_new();
827             tcg_gen_qemu_ld_i32(arg1, REG(B11_8), ctx->memidx, MO_TESL);
828             gen_helper_macl(cpu_env, arg0, arg1);
829             tcg_temp_free(arg1);
830             tcg_temp_free(arg0);
831             tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
832             tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
833         }
834         return;
835     case 0x400f:                /* mac.w @Rm+,@Rn+ */
836         {
837             TCGv arg0, arg1;
838             arg0 = tcg_temp_new();
839             tcg_gen_qemu_ld_i32(arg0, REG(B7_4), ctx->memidx, MO_TESL);
840             arg1 = tcg_temp_new();
841             tcg_gen_qemu_ld_i32(arg1, REG(B11_8), ctx->memidx, MO_TESL);
842             gen_helper_macw(cpu_env, arg0, arg1);
843             tcg_temp_free(arg1);
844             tcg_temp_free(arg0);
845             tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);
846             tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
847         }
848         return;
849     case 0x0007:                /* mul.l Rm,Rn */
850         tcg_gen_mul_i32(cpu_macl, REG(B7_4), REG(B11_8));
851         return;
852     case 0x200f:                /* muls.w Rm,Rn */
853         {
854             TCGv arg0, arg1;
855             arg0 = tcg_temp_new();
856             tcg_gen_ext16s_i32(arg0, REG(B7_4));
857             arg1 = tcg_temp_new();
858             tcg_gen_ext16s_i32(arg1, REG(B11_8));
859             tcg_gen_mul_i32(cpu_macl, arg0, arg1);
860             tcg_temp_free(arg1);
861             tcg_temp_free(arg0);
862         }
863         return;
864     case 0x200e:                /* mulu.w Rm,Rn */
865         {
866             TCGv arg0, arg1;
867             arg0 = tcg_temp_new();
868             tcg_gen_ext16u_i32(arg0, REG(B7_4));
869             arg1 = tcg_temp_new();
870             tcg_gen_ext16u_i32(arg1, REG(B11_8));
871             tcg_gen_mul_i32(cpu_macl, arg0, arg1);
872             tcg_temp_free(arg1);
873             tcg_temp_free(arg0);
874         }
875         return;
876     case 0x600b:                /* neg Rm,Rn */
877         tcg_gen_neg_i32(REG(B11_8), REG(B7_4));
878         return;
879     case 0x600a:                /* negc Rm,Rn */
880         {
881             TCGv t0 = tcg_const_i32(0);
882             tcg_gen_add2_i32(REG(B11_8), cpu_sr_t,
883                              REG(B7_4), t0, cpu_sr_t, t0);
884             tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t,
885                              t0, t0, REG(B11_8), cpu_sr_t);
886             tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
887             tcg_temp_free(t0);
888         }
889         return;
890     case 0x6007:                /* not Rm,Rn */
891         tcg_gen_not_i32(REG(B11_8), REG(B7_4));
892         return;
893     case 0x200b:                /* or Rm,Rn */
894         tcg_gen_or_i32(REG(B11_8), REG(B11_8), REG(B7_4));
895         return;
896     case 0x400c:                /* shad Rm,Rn */
897         {
898             TCGv t0 = tcg_temp_new();
899             TCGv t1 = tcg_temp_new();
900             TCGv t2 = tcg_temp_new();
901
902             tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
903
904             /* positive case: shift to the left */
905             tcg_gen_shl_i32(t1, REG(B11_8), t0);
906
907             /* negative case: shift to the right in two steps to
908                correctly handle the -32 case */
909             tcg_gen_xori_i32(t0, t0, 0x1f);
910             tcg_gen_sar_i32(t2, REG(B11_8), t0);
911             tcg_gen_sari_i32(t2, t2, 1);
912
913             /* select between the two cases */
914             tcg_gen_movi_i32(t0, 0);
915             tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
916
917             tcg_temp_free(t0);
918             tcg_temp_free(t1);
919             tcg_temp_free(t2);
920         }
921         return;
922     case 0x400d:                /* shld Rm,Rn */
923         {
924             TCGv t0 = tcg_temp_new();
925             TCGv t1 = tcg_temp_new();
926             TCGv t2 = tcg_temp_new();
927
928             tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
929
930             /* positive case: shift to the left */
931             tcg_gen_shl_i32(t1, REG(B11_8), t0);
932
933             /* negative case: shift to the right in two steps to
934                correctly handle the -32 case */
935             tcg_gen_xori_i32(t0, t0, 0x1f);
936             tcg_gen_shr_i32(t2, REG(B11_8), t0);
937             tcg_gen_shri_i32(t2, t2, 1);
938
939             /* select between the two cases */
940             tcg_gen_movi_i32(t0, 0);
941             tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
942
943             tcg_temp_free(t0);
944             tcg_temp_free(t1);
945             tcg_temp_free(t2);
946         }
947         return;
948     case 0x3008:                /* sub Rm,Rn */
949         tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));
950         return;
951     case 0x300a:                /* subc Rm,Rn */
952         {
953             TCGv t0, t1;
954             t0 = tcg_const_tl(0);
955             t1 = tcg_temp_new();
956             tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0);
957             tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t,
958                              REG(B11_8), t0, t1, cpu_sr_t);
959             tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
960             tcg_temp_free(t0);
961             tcg_temp_free(t1);
962         }
963         return;
964     case 0x300b:                /* subv Rm,Rn */
965         {
966             TCGv t0, t1, t2;
967             t0 = tcg_temp_new();
968             tcg_gen_sub_i32(t0, REG(B11_8), REG(B7_4));
969             t1 = tcg_temp_new();
970             tcg_gen_xor_i32(t1, t0, REG(B7_4));
971             t2 = tcg_temp_new();
972             tcg_gen_xor_i32(t2, REG(B11_8), REG(B7_4));
973             tcg_gen_and_i32(t1, t1, t2);
974             tcg_temp_free(t2);
975             tcg_gen_shri_i32(cpu_sr_t, t1, 31);
976             tcg_temp_free(t1);
977             tcg_gen_mov_i32(REG(B11_8), t0);
978             tcg_temp_free(t0);
979         }
980         return;
981     case 0x2008:                /* tst Rm,Rn */
982         {
983             TCGv val = tcg_temp_new();
984             tcg_gen_and_i32(val, REG(B7_4), REG(B11_8));
985             tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
986             tcg_temp_free(val);
987         }
988         return;
989     case 0x200a:                /* xor Rm,Rn */
990         tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));
991         return;
992     case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
993         CHECK_FPU_ENABLED
994         if (ctx->tbflags & FPSCR_SZ) {
995             int xsrc = XHACK(B7_4);
996             int xdst = XHACK(B11_8);
997             tcg_gen_mov_i32(FREG(xdst), FREG(xsrc));
998             tcg_gen_mov_i32(FREG(xdst + 1), FREG(xsrc + 1));
999         } else {
1000             tcg_gen_mov_i32(FREG(B11_8), FREG(B7_4));
1001         }
1002         return;
1003     case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
1004         CHECK_FPU_ENABLED
1005         if (ctx->tbflags & FPSCR_SZ) {
1006             TCGv_i64 fp = tcg_temp_new_i64();
1007             gen_load_fpr64(ctx, fp, XHACK(B7_4));
1008             tcg_gen_qemu_st_i64(fp, REG(B11_8), ctx->memidx, MO_TEQ);
1009             tcg_temp_free_i64(fp);
1010         } else {
1011             tcg_gen_qemu_st_i32(FREG(B7_4), REG(B11_8), ctx->memidx, MO_TEUL);
1012         }
1013         return;
1014     case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
1015         CHECK_FPU_ENABLED
1016         if (ctx->tbflags & FPSCR_SZ) {
1017             TCGv_i64 fp = tcg_temp_new_i64();
1018             tcg_gen_qemu_ld_i64(fp, REG(B7_4), ctx->memidx, MO_TEQ);
1019             gen_store_fpr64(ctx, fp, XHACK(B11_8));
1020             tcg_temp_free_i64(fp);
1021         } else {
1022             tcg_gen_qemu_ld_i32(FREG(B11_8), REG(B7_4), ctx->memidx, MO_TEUL);
1023         }
1024         return;
1025     case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
1026         CHECK_FPU_ENABLED
1027         if (ctx->tbflags & FPSCR_SZ) {
1028             TCGv_i64 fp = tcg_temp_new_i64();
1029             tcg_gen_qemu_ld_i64(fp, REG(B7_4), ctx->memidx, MO_TEQ);
1030             gen_store_fpr64(ctx, fp, XHACK(B11_8));
1031             tcg_temp_free_i64(fp);
1032             tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 8);
1033         } else {
1034             tcg_gen_qemu_ld_i32(FREG(B11_8), REG(B7_4), ctx->memidx, MO_TEUL);
1035             tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
1036         }
1037         return;
1038     case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
1039         CHECK_FPU_ENABLED
1040         {
1041             TCGv addr = tcg_temp_new_i32();
1042             if (ctx->tbflags & FPSCR_SZ) {
1043                 TCGv_i64 fp = tcg_temp_new_i64();
1044                 gen_load_fpr64(ctx, fp, XHACK(B7_4));
1045                 tcg_gen_subi_i32(addr, REG(B11_8), 8);
1046                 tcg_gen_qemu_st_i64(fp, addr, ctx->memidx, MO_TEQ);
1047                 tcg_temp_free_i64(fp);
1048             } else {
1049                 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1050                 tcg_gen_qemu_st_i32(FREG(B7_4), addr, ctx->memidx, MO_TEUL);
1051             }
1052             tcg_gen_mov_i32(REG(B11_8), addr);
1053             tcg_temp_free(addr);
1054         }
1055         return;
1056     case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
1057         CHECK_FPU_ENABLED
1058         {
1059             TCGv addr = tcg_temp_new_i32();
1060             tcg_gen_add_i32(addr, REG(B7_4), REG(0));
1061             if (ctx->tbflags & FPSCR_SZ) {
1062                 TCGv_i64 fp = tcg_temp_new_i64();
1063                 tcg_gen_qemu_ld_i64(fp, addr, ctx->memidx, MO_TEQ);
1064                 gen_store_fpr64(ctx, fp, XHACK(B11_8));
1065                 tcg_temp_free_i64(fp);
1066             } else {
1067                 tcg_gen_qemu_ld_i32(FREG(B11_8), addr, ctx->memidx, MO_TEUL);
1068             }
1069             tcg_temp_free(addr);
1070         }
1071         return;
1072     case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
1073         CHECK_FPU_ENABLED
1074         {
1075             TCGv addr = tcg_temp_new();
1076             tcg_gen_add_i32(addr, REG(B11_8), REG(0));
1077             if (ctx->tbflags & FPSCR_SZ) {
1078                 TCGv_i64 fp = tcg_temp_new_i64();
1079                 gen_load_fpr64(ctx, fp, XHACK(B7_4));
1080                 tcg_gen_qemu_st_i64(fp, addr, ctx->memidx, MO_TEQ);
1081                 tcg_temp_free_i64(fp);
1082             } else {
1083                 tcg_gen_qemu_st_i32(FREG(B7_4), addr, ctx->memidx, MO_TEUL);
1084             }
1085             tcg_temp_free(addr);
1086         }
1087         return;
1088     case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1089     case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1090     case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1091     case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1092     case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1093     case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1094         {
1095             CHECK_FPU_ENABLED
1096             if (ctx->tbflags & FPSCR_PR) {
1097                 TCGv_i64 fp0, fp1;
1098
1099                 if (ctx->opcode & 0x0110) {
1100                     goto do_illegal;
1101                 }
1102                 fp0 = tcg_temp_new_i64();
1103                 fp1 = tcg_temp_new_i64();
1104                 gen_load_fpr64(ctx, fp0, B11_8);
1105                 gen_load_fpr64(ctx, fp1, B7_4);
1106                 switch (ctx->opcode & 0xf00f) {
1107                 case 0xf000:            /* fadd Rm,Rn */
1108                     gen_helper_fadd_DT(fp0, cpu_env, fp0, fp1);
1109                     break;
1110                 case 0xf001:            /* fsub Rm,Rn */
1111                     gen_helper_fsub_DT(fp0, cpu_env, fp0, fp1);
1112                     break;
1113                 case 0xf002:            /* fmul Rm,Rn */
1114                     gen_helper_fmul_DT(fp0, cpu_env, fp0, fp1);
1115                     break;
1116                 case 0xf003:            /* fdiv Rm,Rn */
1117                     gen_helper_fdiv_DT(fp0, cpu_env, fp0, fp1);
1118                     break;
1119                 case 0xf004:            /* fcmp/eq Rm,Rn */
1120                     gen_helper_fcmp_eq_DT(cpu_sr_t, cpu_env, fp0, fp1);
1121                     return;
1122                 case 0xf005:            /* fcmp/gt Rm,Rn */
1123                     gen_helper_fcmp_gt_DT(cpu_sr_t, cpu_env, fp0, fp1);
1124                     return;
1125                 }
1126                 gen_store_fpr64(ctx, fp0, B11_8);
1127                 tcg_temp_free_i64(fp0);
1128                 tcg_temp_free_i64(fp1);
1129             } else {
1130                 switch (ctx->opcode & 0xf00f) {
1131                 case 0xf000:            /* fadd Rm,Rn */
1132                     gen_helper_fadd_FT(FREG(B11_8), cpu_env,
1133                                        FREG(B11_8), FREG(B7_4));
1134                     break;
1135                 case 0xf001:            /* fsub Rm,Rn */
1136                     gen_helper_fsub_FT(FREG(B11_8), cpu_env,
1137                                        FREG(B11_8), FREG(B7_4));
1138                     break;
1139                 case 0xf002:            /* fmul Rm,Rn */
1140                     gen_helper_fmul_FT(FREG(B11_8), cpu_env,
1141                                        FREG(B11_8), FREG(B7_4));
1142                     break;
1143                 case 0xf003:            /* fdiv Rm,Rn */
1144                     gen_helper_fdiv_FT(FREG(B11_8), cpu_env,
1145                                        FREG(B11_8), FREG(B7_4));
1146                     break;
1147                 case 0xf004:            /* fcmp/eq Rm,Rn */
1148                     gen_helper_fcmp_eq_FT(cpu_sr_t, cpu_env,
1149                                           FREG(B11_8), FREG(B7_4));
1150                     return;
1151                 case 0xf005:            /* fcmp/gt Rm,Rn */
1152                     gen_helper_fcmp_gt_FT(cpu_sr_t, cpu_env,
1153                                           FREG(B11_8), FREG(B7_4));
1154                     return;
1155                 }
1156             }
1157         }
1158         return;
1159     case 0xf00e: /* fmac FR0,RM,Rn */
1160         CHECK_FPU_ENABLED
1161         CHECK_FPSCR_PR_0
1162         gen_helper_fmac_FT(FREG(B11_8), cpu_env,
1163                            FREG(0), FREG(B7_4), FREG(B11_8));
1164         return;
1165     }
1166
1167     switch (ctx->opcode & 0xff00) {
1168     case 0xc900:                /* and #imm,R0 */
1169         tcg_gen_andi_i32(REG(0), REG(0), B7_0);
1170         return;
1171     case 0xcd00:                /* and.b #imm,@(R0,GBR) */
1172         {
1173             TCGv addr, val;
1174             addr = tcg_temp_new();
1175             tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1176             val = tcg_temp_new();
1177             tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1178             tcg_gen_andi_i32(val, val, B7_0);
1179             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1180             tcg_temp_free(val);
1181             tcg_temp_free(addr);
1182         }
1183         return;
1184     case 0x8b00:                /* bf label */
1185         CHECK_NOT_DELAY_SLOT
1186         gen_conditional_jump(ctx, ctx->base.pc_next + 4 + B7_0s * 2, false);
1187         return;
1188     case 0x8f00:                /* bf/s label */
1189         CHECK_NOT_DELAY_SLOT
1190         tcg_gen_xori_i32(cpu_delayed_cond, cpu_sr_t, 1);
1191         ctx->delayed_pc = ctx->base.pc_next + 4 + B7_0s * 2;
1192         ctx->envflags |= DELAY_SLOT_CONDITIONAL;
1193         return;
1194     case 0x8900:                /* bt label */
1195         CHECK_NOT_DELAY_SLOT
1196         gen_conditional_jump(ctx, ctx->base.pc_next + 4 + B7_0s * 2, true);
1197         return;
1198     case 0x8d00:                /* bt/s label */
1199         CHECK_NOT_DELAY_SLOT
1200         tcg_gen_mov_i32(cpu_delayed_cond, cpu_sr_t);
1201         ctx->delayed_pc = ctx->base.pc_next + 4 + B7_0s * 2;
1202         ctx->envflags |= DELAY_SLOT_CONDITIONAL;
1203         return;
1204     case 0x8800:                /* cmp/eq #imm,R0 */
1205         tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, REG(0), B7_0s);
1206         return;
1207     case 0xc400:                /* mov.b @(disp,GBR),R0 */
1208         {
1209             TCGv addr = tcg_temp_new();
1210             tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1211             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_SB);
1212             tcg_temp_free(addr);
1213         }
1214         return;
1215     case 0xc500:                /* mov.w @(disp,GBR),R0 */
1216         {
1217             TCGv addr = tcg_temp_new();
1218             tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1219             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESW);
1220             tcg_temp_free(addr);
1221         }
1222         return;
1223     case 0xc600:                /* mov.l @(disp,GBR),R0 */
1224         {
1225             TCGv addr = tcg_temp_new();
1226             tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1227             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESL);
1228             tcg_temp_free(addr);
1229         }
1230         return;
1231     case 0xc000:                /* mov.b R0,@(disp,GBR) */
1232         {
1233             TCGv addr = tcg_temp_new();
1234             tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1235             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_UB);
1236             tcg_temp_free(addr);
1237         }
1238         return;
1239     case 0xc100:                /* mov.w R0,@(disp,GBR) */
1240         {
1241             TCGv addr = tcg_temp_new();
1242             tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1243             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUW);
1244             tcg_temp_free(addr);
1245         }
1246         return;
1247     case 0xc200:                /* mov.l R0,@(disp,GBR) */
1248         {
1249             TCGv addr = tcg_temp_new();
1250             tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1251             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUL);
1252             tcg_temp_free(addr);
1253         }
1254         return;
1255     case 0x8000:                /* mov.b R0,@(disp,Rn) */
1256         {
1257             TCGv addr = tcg_temp_new();
1258             tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1259             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_UB);
1260             tcg_temp_free(addr);
1261         }
1262         return;
1263     case 0x8100:                /* mov.w R0,@(disp,Rn) */
1264         {
1265             TCGv addr = tcg_temp_new();
1266             tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1267             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUW);
1268             tcg_temp_free(addr);
1269         }
1270         return;
1271     case 0x8400:                /* mov.b @(disp,Rn),R0 */
1272         {
1273             TCGv addr = tcg_temp_new();
1274             tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1275             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_SB);
1276             tcg_temp_free(addr);
1277         }
1278         return;
1279     case 0x8500:                /* mov.w @(disp,Rn),R0 */
1280         {
1281             TCGv addr = tcg_temp_new();
1282             tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1283             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESW);
1284             tcg_temp_free(addr);
1285         }
1286         return;
1287     case 0xc700:                /* mova @(disp,PC),R0 */
1288         tcg_gen_movi_i32(REG(0), ((ctx->base.pc_next & 0xfffffffc) +
1289                                   4 + B7_0 * 4) & ~3);
1290         return;
1291     case 0xcb00:                /* or #imm,R0 */
1292         tcg_gen_ori_i32(REG(0), REG(0), B7_0);
1293         return;
1294     case 0xcf00:                /* or.b #imm,@(R0,GBR) */
1295         {
1296             TCGv addr, val;
1297             addr = tcg_temp_new();
1298             tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1299             val = tcg_temp_new();
1300             tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1301             tcg_gen_ori_i32(val, val, B7_0);
1302             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1303             tcg_temp_free(val);
1304             tcg_temp_free(addr);
1305         }
1306         return;
1307     case 0xc300:                /* trapa #imm */
1308         {
1309             TCGv imm;
1310             CHECK_NOT_DELAY_SLOT
1311             gen_save_cpu_state(ctx, true);
1312             imm = tcg_const_i32(B7_0);
1313             gen_helper_trapa(cpu_env, imm);
1314             tcg_temp_free(imm);
1315             ctx->base.is_jmp = DISAS_NORETURN;
1316         }
1317         return;
1318     case 0xc800:                /* tst #imm,R0 */
1319         {
1320             TCGv val = tcg_temp_new();
1321             tcg_gen_andi_i32(val, REG(0), B7_0);
1322             tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1323             tcg_temp_free(val);
1324         }
1325         return;
1326     case 0xcc00:                /* tst.b #imm,@(R0,GBR) */
1327         {
1328             TCGv val = tcg_temp_new();
1329             tcg_gen_add_i32(val, REG(0), cpu_gbr);
1330             tcg_gen_qemu_ld_i32(val, val, ctx->memidx, MO_UB);
1331             tcg_gen_andi_i32(val, val, B7_0);
1332             tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1333             tcg_temp_free(val);
1334         }
1335         return;
1336     case 0xca00:                /* xor #imm,R0 */
1337         tcg_gen_xori_i32(REG(0), REG(0), B7_0);
1338         return;
1339     case 0xce00:                /* xor.b #imm,@(R0,GBR) */
1340         {
1341             TCGv addr, val;
1342             addr = tcg_temp_new();
1343             tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1344             val = tcg_temp_new();
1345             tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1346             tcg_gen_xori_i32(val, val, B7_0);
1347             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1348             tcg_temp_free(val);
1349             tcg_temp_free(addr);
1350         }
1351         return;
1352     }
1353
1354     switch (ctx->opcode & 0xf08f) {
1355     case 0x408e:                /* ldc Rm,Rn_BANK */
1356         CHECK_PRIVILEGED
1357         tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
1358         return;
1359     case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
1360         CHECK_PRIVILEGED
1361         tcg_gen_qemu_ld_i32(ALTREG(B6_4), REG(B11_8), ctx->memidx, MO_TESL);
1362         tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1363         return;
1364     case 0x0082:                /* stc Rm_BANK,Rn */
1365         CHECK_PRIVILEGED
1366         tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
1367         return;
1368     case 0x4083:                /* stc.l Rm_BANK,@-Rn */
1369         CHECK_PRIVILEGED
1370         {
1371             TCGv addr = tcg_temp_new();
1372             tcg_gen_subi_i32(addr, REG(B11_8), 4);
1373             tcg_gen_qemu_st_i32(ALTREG(B6_4), addr, ctx->memidx, MO_TEUL);
1374             tcg_gen_mov_i32(REG(B11_8), addr);
1375             tcg_temp_free(addr);
1376         }
1377         return;
1378     }
1379
1380     switch (ctx->opcode & 0xf0ff) {
1381     case 0x0023:                /* braf Rn */
1382         CHECK_NOT_DELAY_SLOT
1383         tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->base.pc_next + 4);
1384         ctx->envflags |= DELAY_SLOT;
1385         ctx->delayed_pc = (uint32_t) - 1;
1386         return;
1387     case 0x0003:                /* bsrf Rn */
1388         CHECK_NOT_DELAY_SLOT
1389         tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 4);
1390         tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);
1391         ctx->envflags |= DELAY_SLOT;
1392         ctx->delayed_pc = (uint32_t) - 1;
1393         return;
1394     case 0x4015:                /* cmp/pl Rn */
1395         tcg_gen_setcondi_i32(TCG_COND_GT, cpu_sr_t, REG(B11_8), 0);
1396         return;
1397     case 0x4011:                /* cmp/pz Rn */
1398         tcg_gen_setcondi_i32(TCG_COND_GE, cpu_sr_t, REG(B11_8), 0);
1399         return;
1400     case 0x4010:                /* dt Rn */
1401         tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);
1402         tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, REG(B11_8), 0);
1403         return;
1404     case 0x402b:                /* jmp @Rn */
1405         CHECK_NOT_DELAY_SLOT
1406         tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1407         ctx->envflags |= DELAY_SLOT;
1408         ctx->delayed_pc = (uint32_t) - 1;
1409         return;
1410     case 0x400b:                /* jsr @Rn */
1411         CHECK_NOT_DELAY_SLOT
1412         tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 4);
1413         tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1414         ctx->envflags |= DELAY_SLOT;
1415         ctx->delayed_pc = (uint32_t) - 1;
1416         return;
1417     case 0x400e:                /* ldc Rm,SR */
1418         CHECK_PRIVILEGED
1419         {
1420             TCGv val = tcg_temp_new();
1421             tcg_gen_andi_i32(val, REG(B11_8), 0x700083f3);
1422             gen_write_sr(val);
1423             tcg_temp_free(val);
1424             ctx->base.is_jmp = DISAS_STOP;
1425         }
1426         return;
1427     case 0x4007:                /* ldc.l @Rm+,SR */
1428         CHECK_PRIVILEGED
1429         {
1430             TCGv val = tcg_temp_new();
1431             tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_TESL);
1432             tcg_gen_andi_i32(val, val, 0x700083f3);
1433             gen_write_sr(val);
1434             tcg_temp_free(val);
1435             tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1436             ctx->base.is_jmp = DISAS_STOP;
1437         }
1438         return;
1439     case 0x0002:                /* stc SR,Rn */
1440         CHECK_PRIVILEGED
1441         gen_read_sr(REG(B11_8));
1442         return;
1443     case 0x4003:                /* stc SR,@-Rn */
1444         CHECK_PRIVILEGED
1445         {
1446             TCGv addr = tcg_temp_new();
1447             TCGv val = tcg_temp_new();
1448             tcg_gen_subi_i32(addr, REG(B11_8), 4);
1449             gen_read_sr(val);
1450             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_TEUL);
1451             tcg_gen_mov_i32(REG(B11_8), addr);
1452             tcg_temp_free(val);
1453             tcg_temp_free(addr);
1454         }
1455         return;
1456 #define LD(reg,ldnum,ldpnum,prechk)             \
1457   case ldnum:                                                   \
1458     prechk                                                      \
1459     tcg_gen_mov_i32 (cpu_##reg, REG(B11_8));                    \
1460     return;                                                     \
1461   case ldpnum:                                                  \
1462     prechk                                                      \
1463     tcg_gen_qemu_ld_i32(cpu_##reg, REG(B11_8), ctx->memidx, MO_TESL); \
1464     tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);                \
1465     return;
1466 #define ST(reg,stnum,stpnum,prechk)             \
1467   case stnum:                                                   \
1468     prechk                                                      \
1469     tcg_gen_mov_i32 (REG(B11_8), cpu_##reg);                    \
1470     return;                                                     \
1471   case stpnum:                                                  \
1472     prechk                                                      \
1473     {                                                           \
1474         TCGv addr = tcg_temp_new();                             \
1475         tcg_gen_subi_i32(addr, REG(B11_8), 4);                  \
1476         tcg_gen_qemu_st_i32(cpu_##reg, addr, ctx->memidx, MO_TEUL); \
1477         tcg_gen_mov_i32(REG(B11_8), addr);                      \
1478         tcg_temp_free(addr);                                    \
1479     }                                                           \
1480     return;
1481 #define LDST(reg,ldnum,ldpnum,stnum,stpnum,prechk)              \
1482         LD(reg,ldnum,ldpnum,prechk)                             \
1483         ST(reg,stnum,stpnum,prechk)
1484         LDST(gbr,  0x401e, 0x4017, 0x0012, 0x4013, {})
1485         LDST(vbr,  0x402e, 0x4027, 0x0022, 0x4023, CHECK_PRIVILEGED)
1486         LDST(ssr,  0x403e, 0x4037, 0x0032, 0x4033, CHECK_PRIVILEGED)
1487         LDST(spc,  0x404e, 0x4047, 0x0042, 0x4043, CHECK_PRIVILEGED)
1488         ST(sgr,  0x003a, 0x4032, CHECK_PRIVILEGED)
1489         LD(sgr,  0x403a, 0x4036, CHECK_PRIVILEGED CHECK_SH4A)
1490         LDST(dbr,  0x40fa, 0x40f6, 0x00fa, 0x40f2, CHECK_PRIVILEGED)
1491         LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002, {})
1492         LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012, {})
1493         LDST(pr,   0x402a, 0x4026, 0x002a, 0x4022, {})
1494         LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052, {CHECK_FPU_ENABLED})
1495     case 0x406a:                /* lds Rm,FPSCR */
1496         CHECK_FPU_ENABLED
1497         gen_helper_ld_fpscr(cpu_env, REG(B11_8));
1498         ctx->base.is_jmp = DISAS_STOP;
1499         return;
1500     case 0x4066:                /* lds.l @Rm+,FPSCR */
1501         CHECK_FPU_ENABLED
1502         {
1503             TCGv addr = tcg_temp_new();
1504             tcg_gen_qemu_ld_i32(addr, REG(B11_8), ctx->memidx, MO_TESL);
1505             tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1506             gen_helper_ld_fpscr(cpu_env, addr);
1507             tcg_temp_free(addr);
1508             ctx->base.is_jmp = DISAS_STOP;
1509         }
1510         return;
1511     case 0x006a:                /* sts FPSCR,Rn */
1512         CHECK_FPU_ENABLED
1513         tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);
1514         return;
1515     case 0x4062:                /* sts FPSCR,@-Rn */
1516         CHECK_FPU_ENABLED
1517         {
1518             TCGv addr, val;
1519             val = tcg_temp_new();
1520             tcg_gen_andi_i32(val, cpu_fpscr, 0x003fffff);
1521             addr = tcg_temp_new();
1522             tcg_gen_subi_i32(addr, REG(B11_8), 4);
1523             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_TEUL);
1524             tcg_gen_mov_i32(REG(B11_8), addr);
1525             tcg_temp_free(addr);
1526             tcg_temp_free(val);
1527         }
1528         return;
1529     case 0x00c3:                /* movca.l R0,@Rm */
1530         {
1531             TCGv val = tcg_temp_new();
1532             tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_TEUL);
1533             gen_helper_movcal(cpu_env, REG(B11_8), val);
1534             tcg_gen_qemu_st_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1535             tcg_temp_free(val);
1536         }
1537         ctx->has_movcal = 1;
1538         return;
1539     case 0x40a9:                /* movua.l @Rm,R0 */
1540         CHECK_SH4A
1541         /* Load non-boundary-aligned data */
1542         tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx,
1543                             MO_TEUL | MO_UNALN);
1544         return;
1545         break;
1546     case 0x40e9:                /* movua.l @Rm+,R0 */
1547         CHECK_SH4A
1548         /* Load non-boundary-aligned data */
1549         tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx,
1550                             MO_TEUL | MO_UNALN);
1551         tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1552         return;
1553         break;
1554     case 0x0029:                /* movt Rn */
1555         tcg_gen_mov_i32(REG(B11_8), cpu_sr_t);
1556         return;
1557     case 0x0073:
1558         /* MOVCO.L
1559          *     LDST -> T
1560          *     If (T == 1) R0 -> (Rn)
1561          *     0 -> LDST
1562          *
1563          * The above description doesn't work in a parallel context.
1564          * Since we currently support no smp boards, this implies user-mode.
1565          * But we can still support the official mechanism while user-mode
1566          * is single-threaded.  */
1567         CHECK_SH4A
1568         {
1569             TCGLabel *fail = gen_new_label();
1570             TCGLabel *done = gen_new_label();
1571
1572             if ((tb_cflags(ctx->base.tb) & CF_PARALLEL)) {
1573                 TCGv tmp;
1574
1575                 tcg_gen_brcond_i32(TCG_COND_NE, REG(B11_8),
1576                                    cpu_lock_addr, fail);
1577                 tmp = tcg_temp_new();
1578                 tcg_gen_atomic_cmpxchg_i32(tmp, REG(B11_8), cpu_lock_value,
1579                                            REG(0), ctx->memidx, MO_TEUL);
1580                 tcg_gen_setcond_i32(TCG_COND_EQ, cpu_sr_t, tmp, cpu_lock_value);
1581                 tcg_temp_free(tmp);
1582             } else {
1583                 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_lock_addr, -1, fail);
1584                 tcg_gen_qemu_st_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1585                 tcg_gen_movi_i32(cpu_sr_t, 1);
1586             }
1587             tcg_gen_br(done);
1588
1589             gen_set_label(fail);
1590             tcg_gen_movi_i32(cpu_sr_t, 0);
1591
1592             gen_set_label(done);
1593             tcg_gen_movi_i32(cpu_lock_addr, -1);
1594         }
1595         return;
1596     case 0x0063:
1597         /* MOVLI.L @Rm,R0
1598          *     1 -> LDST
1599          *     (Rm) -> R0
1600          *     When interrupt/exception
1601          *     occurred 0 -> LDST
1602          *
1603          * In a parallel context, we must also save the loaded value
1604          * for use with the cmpxchg that we'll use with movco.l.  */
1605         CHECK_SH4A
1606         if ((tb_cflags(ctx->base.tb) & CF_PARALLEL)) {
1607             TCGv tmp = tcg_temp_new();
1608             tcg_gen_mov_i32(tmp, REG(B11_8));
1609             tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TESL);
1610             tcg_gen_mov_i32(cpu_lock_value, REG(0));
1611             tcg_gen_mov_i32(cpu_lock_addr, tmp);
1612             tcg_temp_free(tmp);
1613         } else {
1614             tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TESL);
1615             tcg_gen_movi_i32(cpu_lock_addr, 0);
1616         }
1617         return;
1618     case 0x0093:                /* ocbi @Rn */
1619         {
1620             gen_helper_ocbi(cpu_env, REG(B11_8));
1621         }
1622         return;
1623     case 0x00a3:                /* ocbp @Rn */
1624     case 0x00b3:                /* ocbwb @Rn */
1625         /* These instructions are supposed to do nothing in case of
1626            a cache miss. Given that we only partially emulate caches
1627            it is safe to simply ignore them. */
1628         return;
1629     case 0x0083:                /* pref @Rn */
1630         return;
1631     case 0x00d3:                /* prefi @Rn */
1632         CHECK_SH4A
1633         return;
1634     case 0x00e3:                /* icbi @Rn */
1635         CHECK_SH4A
1636         return;
1637     case 0x00ab:                /* synco */
1638         CHECK_SH4A
1639         tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
1640         return;
1641         break;
1642     case 0x4024:                /* rotcl Rn */
1643         {
1644             TCGv tmp = tcg_temp_new();
1645             tcg_gen_mov_i32(tmp, cpu_sr_t);
1646             tcg_gen_shri_i32(cpu_sr_t, REG(B11_8), 31);
1647             tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1648             tcg_gen_or_i32(REG(B11_8), REG(B11_8), tmp);
1649             tcg_temp_free(tmp);
1650         }
1651         return;
1652     case 0x4025:                /* rotcr Rn */
1653         {
1654             TCGv tmp = tcg_temp_new();
1655             tcg_gen_shli_i32(tmp, cpu_sr_t, 31);
1656             tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1657             tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1658             tcg_gen_or_i32(REG(B11_8), REG(B11_8), tmp);
1659             tcg_temp_free(tmp);
1660         }
1661         return;
1662     case 0x4004:                /* rotl Rn */
1663         tcg_gen_rotli_i32(REG(B11_8), REG(B11_8), 1);
1664         tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 0);
1665         return;
1666     case 0x4005:                /* rotr Rn */
1667         tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 0);
1668         tcg_gen_rotri_i32(REG(B11_8), REG(B11_8), 1);
1669         return;
1670     case 0x4000:                /* shll Rn */
1671     case 0x4020:                /* shal Rn */
1672         tcg_gen_shri_i32(cpu_sr_t, REG(B11_8), 31);
1673         tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1674         return;
1675     case 0x4021:                /* shar Rn */
1676         tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1677         tcg_gen_sari_i32(REG(B11_8), REG(B11_8), 1);
1678         return;
1679     case 0x4001:                /* shlr Rn */
1680         tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1681         tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1682         return;
1683     case 0x4008:                /* shll2 Rn */
1684         tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 2);
1685         return;
1686     case 0x4018:                /* shll8 Rn */
1687         tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 8);
1688         return;
1689     case 0x4028:                /* shll16 Rn */
1690         tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 16);
1691         return;
1692     case 0x4009:                /* shlr2 Rn */
1693         tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 2);
1694         return;
1695     case 0x4019:                /* shlr8 Rn */
1696         tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 8);
1697         return;
1698     case 0x4029:                /* shlr16 Rn */
1699         tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16);
1700         return;
1701     case 0x401b:                /* tas.b @Rn */
1702         {
1703             TCGv val = tcg_const_i32(0x80);
1704             tcg_gen_atomic_fetch_or_i32(val, REG(B11_8), val,
1705                                         ctx->memidx, MO_UB);
1706             tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1707             tcg_temp_free(val);
1708         }
1709         return;
1710     case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1711         CHECK_FPU_ENABLED
1712         tcg_gen_mov_i32(FREG(B11_8), cpu_fpul);
1713         return;
1714     case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1715         CHECK_FPU_ENABLED
1716         tcg_gen_mov_i32(cpu_fpul, FREG(B11_8));
1717         return;
1718     case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1719         CHECK_FPU_ENABLED
1720         if (ctx->tbflags & FPSCR_PR) {
1721             TCGv_i64 fp;
1722             if (ctx->opcode & 0x0100) {
1723                 goto do_illegal;
1724             }
1725             fp = tcg_temp_new_i64();
1726             gen_helper_float_DT(fp, cpu_env, cpu_fpul);
1727             gen_store_fpr64(ctx, fp, B11_8);
1728             tcg_temp_free_i64(fp);
1729         }
1730         else {
1731             gen_helper_float_FT(FREG(B11_8), cpu_env, cpu_fpul);
1732         }
1733         return;
1734     case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1735         CHECK_FPU_ENABLED
1736         if (ctx->tbflags & FPSCR_PR) {
1737             TCGv_i64 fp;
1738             if (ctx->opcode & 0x0100) {
1739                 goto do_illegal;
1740             }
1741             fp = tcg_temp_new_i64();
1742             gen_load_fpr64(ctx, fp, B11_8);
1743             gen_helper_ftrc_DT(cpu_fpul, cpu_env, fp);
1744             tcg_temp_free_i64(fp);
1745         }
1746         else {
1747             gen_helper_ftrc_FT(cpu_fpul, cpu_env, FREG(B11_8));
1748         }
1749         return;
1750     case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1751         CHECK_FPU_ENABLED
1752         tcg_gen_xori_i32(FREG(B11_8), FREG(B11_8), 0x80000000);
1753         return;
1754     case 0xf05d: /* fabs FRn/DRn - FPCSR: Nothing */
1755         CHECK_FPU_ENABLED
1756         tcg_gen_andi_i32(FREG(B11_8), FREG(B11_8), 0x7fffffff);
1757         return;
1758     case 0xf06d: /* fsqrt FRn */
1759         CHECK_FPU_ENABLED
1760         if (ctx->tbflags & FPSCR_PR) {
1761             if (ctx->opcode & 0x0100) {
1762                 goto do_illegal;
1763             }
1764             TCGv_i64 fp = tcg_temp_new_i64();
1765             gen_load_fpr64(ctx, fp, B11_8);
1766             gen_helper_fsqrt_DT(fp, cpu_env, fp);
1767             gen_store_fpr64(ctx, fp, B11_8);
1768             tcg_temp_free_i64(fp);
1769         } else {
1770             gen_helper_fsqrt_FT(FREG(B11_8), cpu_env, FREG(B11_8));
1771         }
1772         return;
1773     case 0xf07d: /* fsrra FRn */
1774         CHECK_FPU_ENABLED
1775         CHECK_FPSCR_PR_0
1776         gen_helper_fsrra_FT(FREG(B11_8), cpu_env, FREG(B11_8));
1777         break;
1778     case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1779         CHECK_FPU_ENABLED
1780         CHECK_FPSCR_PR_0
1781         tcg_gen_movi_i32(FREG(B11_8), 0);
1782         return;
1783     case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1784         CHECK_FPU_ENABLED
1785         CHECK_FPSCR_PR_0
1786         tcg_gen_movi_i32(FREG(B11_8), 0x3f800000);
1787         return;
1788     case 0xf0ad: /* fcnvsd FPUL,DRn */
1789         CHECK_FPU_ENABLED
1790         {
1791             TCGv_i64 fp = tcg_temp_new_i64();
1792             gen_helper_fcnvsd_FT_DT(fp, cpu_env, cpu_fpul);
1793             gen_store_fpr64(ctx, fp, B11_8);
1794             tcg_temp_free_i64(fp);
1795         }
1796         return;
1797     case 0xf0bd: /* fcnvds DRn,FPUL */
1798         CHECK_FPU_ENABLED
1799         {
1800             TCGv_i64 fp = tcg_temp_new_i64();
1801             gen_load_fpr64(ctx, fp, B11_8);
1802             gen_helper_fcnvds_DT_FT(cpu_fpul, cpu_env, fp);
1803             tcg_temp_free_i64(fp);
1804         }
1805         return;
1806     case 0xf0ed: /* fipr FVm,FVn */
1807         CHECK_FPU_ENABLED
1808         CHECK_FPSCR_PR_1
1809         {
1810             TCGv m = tcg_const_i32((ctx->opcode >> 8) & 3);
1811             TCGv n = tcg_const_i32((ctx->opcode >> 10) & 3);
1812             gen_helper_fipr(cpu_env, m, n);
1813             tcg_temp_free(m);
1814             tcg_temp_free(n);
1815             return;
1816         }
1817         break;
1818     case 0xf0fd: /* ftrv XMTRX,FVn */
1819         CHECK_FPU_ENABLED
1820         CHECK_FPSCR_PR_1
1821         {
1822             if ((ctx->opcode & 0x0300) != 0x0100) {
1823                 goto do_illegal;
1824             }
1825             TCGv n = tcg_const_i32((ctx->opcode >> 10) & 3);
1826             gen_helper_ftrv(cpu_env, n);
1827             tcg_temp_free(n);
1828             return;
1829         }
1830         break;
1831     }
1832 #if 0
1833     fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1834             ctx->opcode, ctx->base.pc_next);
1835     fflush(stderr);
1836 #endif
1837  do_illegal:
1838     if (ctx->envflags & DELAY_SLOT_MASK) {
1839  do_illegal_slot:
1840         gen_save_cpu_state(ctx, true);
1841         gen_helper_raise_slot_illegal_instruction(cpu_env);
1842     } else {
1843         gen_save_cpu_state(ctx, true);
1844         gen_helper_raise_illegal_instruction(cpu_env);
1845     }
1846     ctx->base.is_jmp = DISAS_NORETURN;
1847     return;
1848
1849  do_fpu_disabled:
1850     gen_save_cpu_state(ctx, true);
1851     if (ctx->envflags & DELAY_SLOT_MASK) {
1852         gen_helper_raise_slot_fpu_disable(cpu_env);
1853     } else {
1854         gen_helper_raise_fpu_disable(cpu_env);
1855     }
1856     ctx->base.is_jmp = DISAS_NORETURN;
1857     return;
1858 }
1859
1860 static void decode_opc(DisasContext * ctx)
1861 {
1862     uint32_t old_flags = ctx->envflags;
1863
1864     _decode_opc(ctx);
1865
1866     if (old_flags & DELAY_SLOT_MASK) {
1867         /* go out of the delay slot */
1868         ctx->envflags &= ~DELAY_SLOT_MASK;
1869
1870         /* When in an exclusive region, we must continue to the end
1871            for conditional branches.  */
1872         if (ctx->tbflags & GUSA_EXCLUSIVE
1873             && old_flags & DELAY_SLOT_CONDITIONAL) {
1874             gen_delayed_conditional_jump(ctx);
1875             return;
1876         }
1877         /* Otherwise this is probably an invalid gUSA region.
1878            Drop the GUSA bits so the next TB doesn't see them.  */
1879         ctx->envflags &= ~GUSA_MASK;
1880
1881         tcg_gen_movi_i32(cpu_flags, ctx->envflags);
1882         if (old_flags & DELAY_SLOT_CONDITIONAL) {
1883             gen_delayed_conditional_jump(ctx);
1884         } else {
1885             gen_jump(ctx);
1886         }
1887     }
1888 }
1889
1890 #ifdef CONFIG_USER_ONLY
1891 /* For uniprocessors, SH4 uses optimistic restartable atomic sequences.
1892    Upon an interrupt, a real kernel would simply notice magic values in
1893    the registers and reset the PC to the start of the sequence.
1894
1895    For QEMU, we cannot do this in quite the same way.  Instead, we notice
1896    the normal start of such a sequence (mov #-x,r15).  While we can handle
1897    any sequence via cpu_exec_step_atomic, we can recognize the "normal"
1898    sequences and transform them into atomic operations as seen by the host.
1899 */
1900 static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
1901 {
1902     uint16_t insns[5];
1903     int ld_adr, ld_dst, ld_mop;
1904     int op_dst, op_src, op_opc;
1905     int mv_src, mt_dst, st_src, st_mop;
1906     TCGv op_arg;
1907     uint32_t pc = ctx->base.pc_next;
1908     uint32_t pc_end = ctx->base.tb->cs_base;
1909     int max_insns = (pc_end - pc) / 2;
1910     int i;
1911
1912     /* The state machine below will consume only a few insns.
1913        If there are more than that in a region, fail now.  */
1914     if (max_insns > ARRAY_SIZE(insns)) {
1915         goto fail;
1916     }
1917
1918     /* Read all of the insns for the region.  */
1919     for (i = 0; i < max_insns; ++i) {
1920         insns[i] = cpu_lduw_code(env, pc + i * 2);
1921     }
1922
1923     ld_adr = ld_dst = ld_mop = -1;
1924     mv_src = -1;
1925     op_dst = op_src = op_opc = -1;
1926     mt_dst = -1;
1927     st_src = st_mop = -1;
1928     op_arg = NULL;
1929     i = 0;
1930
1931 #define NEXT_INSN \
1932     do { if (i >= max_insns) goto fail; ctx->opcode = insns[i++]; } while (0)
1933
1934     /*
1935      * Expect a load to begin the region.
1936      */
1937     NEXT_INSN;
1938     switch (ctx->opcode & 0xf00f) {
1939     case 0x6000: /* mov.b @Rm,Rn */
1940         ld_mop = MO_SB;
1941         break;
1942     case 0x6001: /* mov.w @Rm,Rn */
1943         ld_mop = MO_TESW;
1944         break;
1945     case 0x6002: /* mov.l @Rm,Rn */
1946         ld_mop = MO_TESL;
1947         break;
1948     default:
1949         goto fail;
1950     }
1951     ld_adr = B7_4;
1952     ld_dst = B11_8;
1953     if (ld_adr == ld_dst) {
1954         goto fail;
1955     }
1956     /* Unless we see a mov, any two-operand operation must use ld_dst.  */
1957     op_dst = ld_dst;
1958
1959     /*
1960      * Expect an optional register move.
1961      */
1962     NEXT_INSN;
1963     switch (ctx->opcode & 0xf00f) {
1964     case 0x6003: /* mov Rm,Rn */
1965         /* Here we want to recognize ld_dst being saved for later consumtion,
1966            or for another input register being copied so that ld_dst need not
1967            be clobbered during the operation.  */
1968         op_dst = B11_8;
1969         mv_src = B7_4;
1970         if (op_dst == ld_dst) {
1971             /* Overwriting the load output.  */
1972             goto fail;
1973         }
1974         if (mv_src != ld_dst) {
1975             /* Copying a new input; constrain op_src to match the load.  */
1976             op_src = ld_dst;
1977         }
1978         break;
1979
1980     default:
1981         /* Put back and re-examine as operation.  */
1982         --i;
1983     }
1984
1985     /*
1986      * Expect the operation.
1987      */
1988     NEXT_INSN;
1989     switch (ctx->opcode & 0xf00f) {
1990     case 0x300c: /* add Rm,Rn */
1991         op_opc = INDEX_op_add_i32;
1992         goto do_reg_op;
1993     case 0x2009: /* and Rm,Rn */
1994         op_opc = INDEX_op_and_i32;
1995         goto do_reg_op;
1996     case 0x200a: /* xor Rm,Rn */
1997         op_opc = INDEX_op_xor_i32;
1998         goto do_reg_op;
1999     case 0x200b: /* or Rm,Rn */
2000         op_opc = INDEX_op_or_i32;
2001     do_reg_op:
2002         /* The operation register should be as expected, and the
2003            other input cannot depend on the load.  */
2004         if (op_dst != B11_8) {
2005             goto fail;
2006         }
2007         if (op_src < 0) {
2008             /* Unconstrainted input.  */
2009             op_src = B7_4;
2010         } else if (op_src == B7_4) {
2011             /* Constrained input matched load.  All operations are
2012                commutative; "swap" them by "moving" the load output
2013                to the (implicit) first argument and the move source
2014                to the (explicit) second argument.  */
2015             op_src = mv_src;
2016         } else {
2017             goto fail;
2018         }
2019         op_arg = REG(op_src);
2020         break;
2021
2022     case 0x6007: /* not Rm,Rn */
2023         if (ld_dst != B7_4 || mv_src >= 0) {
2024             goto fail;
2025         }
2026         op_dst = B11_8;
2027         op_opc = INDEX_op_xor_i32;
2028         op_arg = tcg_const_i32(-1);
2029         break;
2030
2031     case 0x7000 ... 0x700f: /* add #imm,Rn */
2032         if (op_dst != B11_8 || mv_src >= 0) {
2033             goto fail;
2034         }
2035         op_opc = INDEX_op_add_i32;
2036         op_arg = tcg_const_i32(B7_0s);
2037         break;
2038
2039     case 0x3000: /* cmp/eq Rm,Rn */
2040         /* Looking for the middle of a compare-and-swap sequence,
2041            beginning with the compare.  Operands can be either order,
2042            but with only one overlapping the load.  */
2043         if ((ld_dst == B11_8) + (ld_dst == B7_4) != 1 || mv_src >= 0) {
2044             goto fail;
2045         }
2046         op_opc = INDEX_op_setcond_i32;  /* placeholder */
2047         op_src = (ld_dst == B11_8 ? B7_4 : B11_8);
2048         op_arg = REG(op_src);
2049
2050         NEXT_INSN;
2051         switch (ctx->opcode & 0xff00) {
2052         case 0x8b00: /* bf label */
2053         case 0x8f00: /* bf/s label */
2054             if (pc + (i + 1 + B7_0s) * 2 != pc_end) {
2055                 goto fail;
2056             }
2057             if ((ctx->opcode & 0xff00) == 0x8b00) { /* bf label */
2058                 break;
2059             }
2060             /* We're looking to unconditionally modify Rn with the
2061                result of the comparison, within the delay slot of
2062                the branch.  This is used by older gcc.  */
2063             NEXT_INSN;
2064             if ((ctx->opcode & 0xf0ff) == 0x0029) { /* movt Rn */
2065                 mt_dst = B11_8;
2066             } else {
2067                 goto fail;
2068             }
2069             break;
2070
2071         default:
2072             goto fail;
2073         }
2074         break;
2075
2076     case 0x2008: /* tst Rm,Rn */
2077         /* Looking for a compare-and-swap against zero.  */
2078         if (ld_dst != B11_8 || ld_dst != B7_4 || mv_src >= 0) {
2079             goto fail;
2080         }
2081         op_opc = INDEX_op_setcond_i32;
2082         op_arg = tcg_const_i32(0);
2083
2084         NEXT_INSN;
2085         if ((ctx->opcode & 0xff00) != 0x8900 /* bt label */
2086             || pc + (i + 1 + B7_0s) * 2 != pc_end) {
2087             goto fail;
2088         }
2089         break;
2090
2091     default:
2092         /* Put back and re-examine as store.  */
2093         --i;
2094     }
2095
2096     /*
2097      * Expect the store.
2098      */
2099     /* The store must be the last insn.  */
2100     if (i != max_insns - 1) {
2101         goto fail;
2102     }
2103     NEXT_INSN;
2104     switch (ctx->opcode & 0xf00f) {
2105     case 0x2000: /* mov.b Rm,@Rn */
2106         st_mop = MO_UB;
2107         break;
2108     case 0x2001: /* mov.w Rm,@Rn */
2109         st_mop = MO_UW;
2110         break;
2111     case 0x2002: /* mov.l Rm,@Rn */
2112         st_mop = MO_UL;
2113         break;
2114     default:
2115         goto fail;
2116     }
2117     /* The store must match the load.  */
2118     if (ld_adr != B11_8 || st_mop != (ld_mop & MO_SIZE)) {
2119         goto fail;
2120     }
2121     st_src = B7_4;
2122
2123 #undef NEXT_INSN
2124
2125     /*
2126      * Emit the operation.
2127      */
2128     switch (op_opc) {
2129     case -1:
2130         /* No operation found.  Look for exchange pattern.  */
2131         if (st_src == ld_dst || mv_src >= 0) {
2132             goto fail;
2133         }
2134         tcg_gen_atomic_xchg_i32(REG(ld_dst), REG(ld_adr), REG(st_src),
2135                                 ctx->memidx, ld_mop);
2136         break;
2137
2138     case INDEX_op_add_i32:
2139         if (op_dst != st_src) {
2140             goto fail;
2141         }
2142         if (op_dst == ld_dst && st_mop == MO_UL) {
2143             tcg_gen_atomic_add_fetch_i32(REG(ld_dst), REG(ld_adr),
2144                                          op_arg, ctx->memidx, ld_mop);
2145         } else {
2146             tcg_gen_atomic_fetch_add_i32(REG(ld_dst), REG(ld_adr),
2147                                          op_arg, ctx->memidx, ld_mop);
2148             if (op_dst != ld_dst) {
2149                 /* Note that mop sizes < 4 cannot use add_fetch
2150                    because it won't carry into the higher bits.  */
2151                 tcg_gen_add_i32(REG(op_dst), REG(ld_dst), op_arg);
2152             }
2153         }
2154         break;
2155
2156     case INDEX_op_and_i32:
2157         if (op_dst != st_src) {
2158             goto fail;
2159         }
2160         if (op_dst == ld_dst) {
2161             tcg_gen_atomic_and_fetch_i32(REG(ld_dst), REG(ld_adr),
2162                                          op_arg, ctx->memidx, ld_mop);
2163         } else {
2164             tcg_gen_atomic_fetch_and_i32(REG(ld_dst), REG(ld_adr),
2165                                          op_arg, ctx->memidx, ld_mop);
2166             tcg_gen_and_i32(REG(op_dst), REG(ld_dst), op_arg);
2167         }
2168         break;
2169
2170     case INDEX_op_or_i32:
2171         if (op_dst != st_src) {
2172             goto fail;
2173         }
2174         if (op_dst == ld_dst) {
2175             tcg_gen_atomic_or_fetch_i32(REG(ld_dst), REG(ld_adr),
2176                                         op_arg, ctx->memidx, ld_mop);
2177         } else {
2178             tcg_gen_atomic_fetch_or_i32(REG(ld_dst), REG(ld_adr),
2179                                         op_arg, ctx->memidx, ld_mop);
2180             tcg_gen_or_i32(REG(op_dst), REG(ld_dst), op_arg);
2181         }
2182         break;
2183
2184     case INDEX_op_xor_i32:
2185         if (op_dst != st_src) {
2186             goto fail;
2187         }
2188         if (op_dst == ld_dst) {
2189             tcg_gen_atomic_xor_fetch_i32(REG(ld_dst), REG(ld_adr),
2190                                          op_arg, ctx->memidx, ld_mop);
2191         } else {
2192             tcg_gen_atomic_fetch_xor_i32(REG(ld_dst), REG(ld_adr),
2193                                          op_arg, ctx->memidx, ld_mop);
2194             tcg_gen_xor_i32(REG(op_dst), REG(ld_dst), op_arg);
2195         }
2196         break;
2197
2198     case INDEX_op_setcond_i32:
2199         if (st_src == ld_dst) {
2200             goto fail;
2201         }
2202         tcg_gen_atomic_cmpxchg_i32(REG(ld_dst), REG(ld_adr), op_arg,
2203                                    REG(st_src), ctx->memidx, ld_mop);
2204         tcg_gen_setcond_i32(TCG_COND_EQ, cpu_sr_t, REG(ld_dst), op_arg);
2205         if (mt_dst >= 0) {
2206             tcg_gen_mov_i32(REG(mt_dst), cpu_sr_t);
2207         }
2208         break;
2209
2210     default:
2211         g_assert_not_reached();
2212     }
2213
2214     /* If op_src is not a valid register, then op_arg was a constant.  */
2215     if (op_src < 0 && op_arg) {
2216         tcg_temp_free_i32(op_arg);
2217     }
2218
2219     /* The entire region has been translated.  */
2220     ctx->envflags &= ~GUSA_MASK;
2221     ctx->base.pc_next = pc_end;
2222     ctx->base.num_insns += max_insns - 1;
2223     return;
2224
2225  fail:
2226     qemu_log_mask(LOG_UNIMP, "Unrecognized gUSA sequence %08x-%08x\n",
2227                   pc, pc_end);
2228
2229     /* Restart with the EXCLUSIVE bit set, within a TB run via
2230        cpu_exec_step_atomic holding the exclusive lock.  */
2231     ctx->envflags |= GUSA_EXCLUSIVE;
2232     gen_save_cpu_state(ctx, false);
2233     gen_helper_exclusive(cpu_env);
2234     ctx->base.is_jmp = DISAS_NORETURN;
2235
2236     /* We're not executing an instruction, but we must report one for the
2237        purposes of accounting within the TB.  We might as well report the
2238        entire region consumed via ctx->base.pc_next so that it's immediately
2239        available in the disassembly dump.  */
2240     ctx->base.pc_next = pc_end;
2241     ctx->base.num_insns += max_insns - 1;
2242 }
2243 #endif
2244
2245 static void sh4_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
2246 {
2247     DisasContext *ctx = container_of(dcbase, DisasContext, base);
2248     CPUSH4State *env = cs->env_ptr;
2249     uint32_t tbflags;
2250     int bound;
2251
2252     ctx->tbflags = tbflags = ctx->base.tb->flags;
2253     ctx->envflags = tbflags & TB_FLAG_ENVFLAGS_MASK;
2254     ctx->memidx = (tbflags & (1u << SR_MD)) == 0 ? 1 : 0;
2255     /* We don't know if the delayed pc came from a dynamic or static branch,
2256        so assume it is a dynamic branch.  */
2257     ctx->delayed_pc = -1; /* use delayed pc from env pointer */
2258     ctx->features = env->features;
2259     ctx->has_movcal = (tbflags & TB_FLAG_PENDING_MOVCA);
2260     ctx->gbank = ((tbflags & (1 << SR_MD)) &&
2261                   (tbflags & (1 << SR_RB))) * 0x10;
2262     ctx->fbank = tbflags & FPSCR_FR ? 0x10 : 0;
2263
2264     if (tbflags & GUSA_MASK) {
2265         uint32_t pc = ctx->base.pc_next;
2266         uint32_t pc_end = ctx->base.tb->cs_base;
2267         int backup = sextract32(ctx->tbflags, GUSA_SHIFT, 8);
2268         int max_insns = (pc_end - pc) / 2;
2269
2270         if (pc != pc_end + backup || max_insns < 2) {
2271             /* This is a malformed gUSA region.  Don't do anything special,
2272                since the interpreter is likely to get confused.  */
2273             ctx->envflags &= ~GUSA_MASK;
2274         } else if (tbflags & GUSA_EXCLUSIVE) {
2275             /* Regardless of single-stepping or the end of the page,
2276                we must complete execution of the gUSA region while
2277                holding the exclusive lock.  */
2278             ctx->base.max_insns = max_insns;
2279             return;
2280         }
2281     }
2282
2283     /* Since the ISA is fixed-width, we can bound by the number
2284        of instructions remaining on the page.  */
2285     bound = -(ctx->base.pc_next | TARGET_PAGE_MASK) / 2;
2286     ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
2287 }
2288
2289 static void sh4_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
2290 {
2291 }
2292
2293 static void sh4_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
2294 {
2295     DisasContext *ctx = container_of(dcbase, DisasContext, base);
2296
2297     tcg_gen_insn_start(ctx->base.pc_next, ctx->envflags);
2298 }
2299
2300 static bool sh4_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
2301                                     const CPUBreakpoint *bp)
2302 {
2303     DisasContext *ctx = container_of(dcbase, DisasContext, base);
2304
2305     /* We have hit a breakpoint - make sure PC is up-to-date */
2306     gen_save_cpu_state(ctx, true);
2307     gen_helper_debug(cpu_env);
2308     ctx->base.is_jmp = DISAS_NORETURN;
2309     /* The address covered by the breakpoint must be included in
2310        [tb->pc, tb->pc + tb->size) in order to for it to be
2311        properly cleared -- thus we increment the PC here so that
2312        the logic setting tb->size below does the right thing.  */
2313     ctx->base.pc_next += 2;
2314     return true;
2315 }
2316
2317 static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
2318 {
2319     CPUSH4State *env = cs->env_ptr;
2320     DisasContext *ctx = container_of(dcbase, DisasContext, base);
2321
2322 #ifdef CONFIG_USER_ONLY
2323     if (unlikely(ctx->envflags & GUSA_MASK)
2324         && !(ctx->envflags & GUSA_EXCLUSIVE)) {
2325         /* We're in an gUSA region, and we have not already fallen
2326            back on using an exclusive region.  Attempt to parse the
2327            region into a single supported atomic operation.  Failure
2328            is handled within the parser by raising an exception to
2329            retry using an exclusive region.  */
2330         decode_gusa(ctx, env);
2331         return;
2332     }
2333 #endif
2334
2335     ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
2336     decode_opc(ctx);
2337     ctx->base.pc_next += 2;
2338 }
2339
2340 static void sh4_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
2341 {
2342     DisasContext *ctx = container_of(dcbase, DisasContext, base);
2343
2344     if (ctx->tbflags & GUSA_EXCLUSIVE) {
2345         /* Ending the region of exclusivity.  Clear the bits.  */
2346         ctx->envflags &= ~GUSA_MASK;
2347     }
2348
2349     switch (ctx->base.is_jmp) {
2350     case DISAS_STOP:
2351         gen_save_cpu_state(ctx, true);
2352         if (ctx->base.singlestep_enabled) {
2353             gen_helper_debug(cpu_env);
2354         } else {
2355             tcg_gen_exit_tb(NULL, 0);
2356         }
2357         break;
2358     case DISAS_NEXT:
2359     case DISAS_TOO_MANY:
2360         gen_save_cpu_state(ctx, false);
2361         gen_goto_tb(ctx, 0, ctx->base.pc_next);
2362         break;
2363     case DISAS_NORETURN:
2364         break;
2365     default:
2366         g_assert_not_reached();
2367     }
2368 }
2369
2370 static void sh4_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
2371 {
2372     qemu_log("IN:\n");  /* , lookup_symbol(dcbase->pc_first)); */
2373     log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
2374 }
2375
2376 static const TranslatorOps sh4_tr_ops = {
2377     .init_disas_context = sh4_tr_init_disas_context,
2378     .tb_start           = sh4_tr_tb_start,
2379     .insn_start         = sh4_tr_insn_start,
2380     .breakpoint_check   = sh4_tr_breakpoint_check,
2381     .translate_insn     = sh4_tr_translate_insn,
2382     .tb_stop            = sh4_tr_tb_stop,
2383     .disas_log          = sh4_tr_disas_log,
2384 };
2385
2386 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
2387 {
2388     DisasContext ctx;
2389
2390     translator_loop(&sh4_tr_ops, &ctx.base, cs, tb, max_insns);
2391 }
2392
2393 void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb,
2394                           target_ulong *data)
2395 {
2396     env->pc = data[0];
2397     env->flags = data[1];
2398     /* Theoretically delayed_pc should also be restored. In practice the
2399        branch instruction is re-executed after exception, so the delayed
2400        branch target will be recomputed. */
2401 }
This page took 0.163907 seconds and 4 git commands to generate.