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