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