xref: /openbmc/qemu/target/sh4/translate.c (revision 70f168f8)
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/cpu_ldst.h"
26 #include "exec/helper-proto.h"
27 #include "exec/helper-gen.h"
28 #include "exec/translator.h"
29 #include "exec/log.h"
30 #include "qemu/qemu-print.h"
31 
32 
33 typedef struct DisasContext {
34     DisasContextBase base;
35 
36     uint32_t tbflags;  /* should stay unmodified during the TB translation */
37     uint32_t envflags; /* should stay in sync with env->flags using TCG ops */
38     int memidx;
39     int gbank;
40     int fbank;
41     uint32_t delayed_pc;
42     uint32_t features;
43 
44     uint16_t opcode;
45 
46     bool has_movcal;
47 } DisasContext;
48 
49 #if defined(CONFIG_USER_ONLY)
50 #define IS_USER(ctx) 1
51 #define UNALIGN(C)   (ctx->tbflags & TB_FLAG_UNALIGN ? MO_UNALN : MO_ALIGN)
52 #else
53 #define IS_USER(ctx) (!(ctx->tbflags & (1u << SR_MD)))
54 #define UNALIGN(C)   0
55 #endif
56 
57 /* Target-specific values for ctx->base.is_jmp.  */
58 /* We want to exit back to the cpu loop for some reason.
59    Usually this is to recognize interrupts immediately.  */
60 #define DISAS_STOP    DISAS_TARGET_0
61 
62 /* global register indexes */
63 static TCGv cpu_gregs[32];
64 static TCGv cpu_sr, cpu_sr_m, cpu_sr_q, cpu_sr_t;
65 static TCGv cpu_pc, cpu_ssr, cpu_spc, cpu_gbr;
66 static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
67 static TCGv cpu_pr, cpu_fpscr, cpu_fpul;
68 static TCGv cpu_lock_addr, cpu_lock_value;
69 static TCGv cpu_fregs[32];
70 
71 /* internal register indexes */
72 static TCGv cpu_flags, cpu_delayed_pc, cpu_delayed_cond;
73 
74 #include "exec/gen-icount.h"
75 
76 void sh4_translate_init(void)
77 {
78     int i;
79     static const char * const gregnames[24] = {
80         "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
81         "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
82         "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
83         "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
84         "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
85     };
86     static const char * const fregnames[32] = {
87          "FPR0_BANK0",  "FPR1_BANK0",  "FPR2_BANK0",  "FPR3_BANK0",
88          "FPR4_BANK0",  "FPR5_BANK0",  "FPR6_BANK0",  "FPR7_BANK0",
89          "FPR8_BANK0",  "FPR9_BANK0", "FPR10_BANK0", "FPR11_BANK0",
90         "FPR12_BANK0", "FPR13_BANK0", "FPR14_BANK0", "FPR15_BANK0",
91          "FPR0_BANK1",  "FPR1_BANK1",  "FPR2_BANK1",  "FPR3_BANK1",
92          "FPR4_BANK1",  "FPR5_BANK1",  "FPR6_BANK1",  "FPR7_BANK1",
93          "FPR8_BANK1",  "FPR9_BANK1", "FPR10_BANK1", "FPR11_BANK1",
94         "FPR12_BANK1", "FPR13_BANK1", "FPR14_BANK1", "FPR15_BANK1",
95     };
96 
97     for (i = 0; i < 24; i++) {
98         cpu_gregs[i] = tcg_global_mem_new_i32(cpu_env,
99                                               offsetof(CPUSH4State, gregs[i]),
100                                               gregnames[i]);
101     }
102     memcpy(cpu_gregs + 24, cpu_gregs + 8, 8 * sizeof(TCGv));
103 
104     cpu_pc = tcg_global_mem_new_i32(cpu_env,
105                                     offsetof(CPUSH4State, pc), "PC");
106     cpu_sr = tcg_global_mem_new_i32(cpu_env,
107                                     offsetof(CPUSH4State, sr), "SR");
108     cpu_sr_m = tcg_global_mem_new_i32(cpu_env,
109                                       offsetof(CPUSH4State, sr_m), "SR_M");
110     cpu_sr_q = tcg_global_mem_new_i32(cpu_env,
111                                       offsetof(CPUSH4State, sr_q), "SR_Q");
112     cpu_sr_t = tcg_global_mem_new_i32(cpu_env,
113                                       offsetof(CPUSH4State, sr_t), "SR_T");
114     cpu_ssr = tcg_global_mem_new_i32(cpu_env,
115                                      offsetof(CPUSH4State, ssr), "SSR");
116     cpu_spc = tcg_global_mem_new_i32(cpu_env,
117                                      offsetof(CPUSH4State, spc), "SPC");
118     cpu_gbr = tcg_global_mem_new_i32(cpu_env,
119                                      offsetof(CPUSH4State, gbr), "GBR");
120     cpu_vbr = tcg_global_mem_new_i32(cpu_env,
121                                      offsetof(CPUSH4State, vbr), "VBR");
122     cpu_sgr = tcg_global_mem_new_i32(cpu_env,
123                                      offsetof(CPUSH4State, sgr), "SGR");
124     cpu_dbr = tcg_global_mem_new_i32(cpu_env,
125                                      offsetof(CPUSH4State, dbr), "DBR");
126     cpu_mach = tcg_global_mem_new_i32(cpu_env,
127                                       offsetof(CPUSH4State, mach), "MACH");
128     cpu_macl = tcg_global_mem_new_i32(cpu_env,
129                                       offsetof(CPUSH4State, macl), "MACL");
130     cpu_pr = tcg_global_mem_new_i32(cpu_env,
131                                     offsetof(CPUSH4State, pr), "PR");
132     cpu_fpscr = tcg_global_mem_new_i32(cpu_env,
133                                        offsetof(CPUSH4State, fpscr), "FPSCR");
134     cpu_fpul = tcg_global_mem_new_i32(cpu_env,
135                                       offsetof(CPUSH4State, fpul), "FPUL");
136 
137     cpu_flags = tcg_global_mem_new_i32(cpu_env,
138 				       offsetof(CPUSH4State, flags), "_flags_");
139     cpu_delayed_pc = tcg_global_mem_new_i32(cpu_env,
140 					    offsetof(CPUSH4State, delayed_pc),
141 					    "_delayed_pc_");
142     cpu_delayed_cond = tcg_global_mem_new_i32(cpu_env,
143                                               offsetof(CPUSH4State,
144                                                        delayed_cond),
145                                               "_delayed_cond_");
146     cpu_lock_addr = tcg_global_mem_new_i32(cpu_env,
147                                            offsetof(CPUSH4State, lock_addr),
148                                            "_lock_addr_");
149     cpu_lock_value = tcg_global_mem_new_i32(cpu_env,
150                                             offsetof(CPUSH4State, lock_value),
151                                             "_lock_value_");
152 
153     for (i = 0; i < 32; i++)
154         cpu_fregs[i] = tcg_global_mem_new_i32(cpu_env,
155                                               offsetof(CPUSH4State, fregs[i]),
156                                               fregnames[i]);
157 }
158 
159 void superh_cpu_dump_state(CPUState *cs, FILE *f, int flags)
160 {
161     SuperHCPU *cpu = SUPERH_CPU(cs);
162     CPUSH4State *env = &cpu->env;
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(cpu_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(cpu_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(cpu_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(cpu_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(cpu_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, cpu_env, fp0, fp1);
1072                     break;
1073                 case 0xf001:		/* fsub Rm,Rn */
1074                     gen_helper_fsub_DT(fp0, cpu_env, fp0, fp1);
1075                     break;
1076                 case 0xf002:		/* fmul Rm,Rn */
1077                     gen_helper_fmul_DT(fp0, cpu_env, fp0, fp1);
1078                     break;
1079                 case 0xf003:		/* fdiv Rm,Rn */
1080                     gen_helper_fdiv_DT(fp0, cpu_env, fp0, fp1);
1081                     break;
1082                 case 0xf004:		/* fcmp/eq Rm,Rn */
1083                     gen_helper_fcmp_eq_DT(cpu_sr_t, cpu_env, fp0, fp1);
1084                     return;
1085                 case 0xf005:		/* fcmp/gt Rm,Rn */
1086                     gen_helper_fcmp_gt_DT(cpu_sr_t, cpu_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), cpu_env,
1094                                        FREG(B11_8), FREG(B7_4));
1095                     break;
1096                 case 0xf001:		/* fsub Rm,Rn */
1097                     gen_helper_fsub_FT(FREG(B11_8), cpu_env,
1098                                        FREG(B11_8), FREG(B7_4));
1099                     break;
1100                 case 0xf002:		/* fmul Rm,Rn */
1101                     gen_helper_fmul_FT(FREG(B11_8), cpu_env,
1102                                        FREG(B11_8), FREG(B7_4));
1103                     break;
1104                 case 0xf003:		/* fdiv Rm,Rn */
1105                     gen_helper_fdiv_FT(FREG(B11_8), cpu_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, cpu_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, cpu_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), cpu_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(cpu_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(cpu_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(cpu_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(cpu_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(cpu_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, cpu_env, cpu_fpul);
1662             gen_store_fpr64(ctx, fp, B11_8);
1663 	}
1664 	else {
1665             gen_helper_float_FT(FREG(B11_8), cpu_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, cpu_env, fp);
1678 	}
1679 	else {
1680             gen_helper_ftrc_FT(cpu_fpul, cpu_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, cpu_env, fp);
1700             gen_store_fpr64(ctx, fp, B11_8);
1701 	} else {
1702             gen_helper_fsqrt_FT(FREG(B11_8), cpu_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), cpu_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, cpu_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, cpu_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(cpu_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(cpu_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(cpu_env);
1769     } else {
1770         gen_save_cpu_state(ctx, true);
1771         gen_helper_raise_illegal_instruction(cpu_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(cpu_env);
1780     } else {
1781         gen_helper_raise_fpu_disable(cpu_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 /* For uniprocessors, SH4 uses optimistic restartable atomic sequences.
1819    Upon an interrupt, a real kernel would simply notice magic values in
1820    the registers and reset the PC to the start of the sequence.
1821 
1822    For QEMU, we cannot do this in quite the same way.  Instead, we notice
1823    the normal start of such a sequence (mov #-x,r15).  While we can handle
1824    any sequence via cpu_exec_step_atomic, we can recognize the "normal"
1825    sequences and transform them into atomic operations as seen by the host.
1826 */
1827 static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
1828 {
1829     uint16_t insns[5];
1830     int ld_adr, ld_dst, ld_mop;
1831     int op_dst, op_src, op_opc;
1832     int mv_src, mt_dst, st_src, st_mop;
1833     TCGv op_arg;
1834     uint32_t pc = ctx->base.pc_next;
1835     uint32_t pc_end = ctx->base.tb->cs_base;
1836     int max_insns = (pc_end - pc) / 2;
1837     int i;
1838 
1839     /* The state machine below will consume only a few insns.
1840        If there are more than that in a region, fail now.  */
1841     if (max_insns > ARRAY_SIZE(insns)) {
1842         goto fail;
1843     }
1844 
1845     /* Read all of the insns for the region.  */
1846     for (i = 0; i < max_insns; ++i) {
1847         insns[i] = translator_lduw(env, &ctx->base, pc + i * 2);
1848     }
1849 
1850     ld_adr = ld_dst = ld_mop = -1;
1851     mv_src = -1;
1852     op_dst = op_src = op_opc = -1;
1853     mt_dst = -1;
1854     st_src = st_mop = -1;
1855     op_arg = NULL;
1856     i = 0;
1857 
1858 #define NEXT_INSN \
1859     do { if (i >= max_insns) goto fail; ctx->opcode = insns[i++]; } while (0)
1860 
1861     /*
1862      * Expect a load to begin the region.
1863      */
1864     NEXT_INSN;
1865     switch (ctx->opcode & 0xf00f) {
1866     case 0x6000: /* mov.b @Rm,Rn */
1867         ld_mop = MO_SB;
1868         break;
1869     case 0x6001: /* mov.w @Rm,Rn */
1870         ld_mop = MO_TESW;
1871         break;
1872     case 0x6002: /* mov.l @Rm,Rn */
1873         ld_mop = MO_TESL;
1874         break;
1875     default:
1876         goto fail;
1877     }
1878     ld_adr = B7_4;
1879     ld_dst = B11_8;
1880     if (ld_adr == ld_dst) {
1881         goto fail;
1882     }
1883     /* Unless we see a mov, any two-operand operation must use ld_dst.  */
1884     op_dst = ld_dst;
1885 
1886     /*
1887      * Expect an optional register move.
1888      */
1889     NEXT_INSN;
1890     switch (ctx->opcode & 0xf00f) {
1891     case 0x6003: /* mov Rm,Rn */
1892         /*
1893          * Here we want to recognize ld_dst being saved for later consumption,
1894          * or for another input register being copied so that ld_dst need not
1895          * be clobbered during the operation.
1896          */
1897         op_dst = B11_8;
1898         mv_src = B7_4;
1899         if (op_dst == ld_dst) {
1900             /* Overwriting the load output.  */
1901             goto fail;
1902         }
1903         if (mv_src != ld_dst) {
1904             /* Copying a new input; constrain op_src to match the load.  */
1905             op_src = ld_dst;
1906         }
1907         break;
1908 
1909     default:
1910         /* Put back and re-examine as operation.  */
1911         --i;
1912     }
1913 
1914     /*
1915      * Expect the operation.
1916      */
1917     NEXT_INSN;
1918     switch (ctx->opcode & 0xf00f) {
1919     case 0x300c: /* add Rm,Rn */
1920         op_opc = INDEX_op_add_i32;
1921         goto do_reg_op;
1922     case 0x2009: /* and Rm,Rn */
1923         op_opc = INDEX_op_and_i32;
1924         goto do_reg_op;
1925     case 0x200a: /* xor Rm,Rn */
1926         op_opc = INDEX_op_xor_i32;
1927         goto do_reg_op;
1928     case 0x200b: /* or Rm,Rn */
1929         op_opc = INDEX_op_or_i32;
1930     do_reg_op:
1931         /* The operation register should be as expected, and the
1932            other input cannot depend on the load.  */
1933         if (op_dst != B11_8) {
1934             goto fail;
1935         }
1936         if (op_src < 0) {
1937             /* Unconstrainted input.  */
1938             op_src = B7_4;
1939         } else if (op_src == B7_4) {
1940             /* Constrained input matched load.  All operations are
1941                commutative; "swap" them by "moving" the load output
1942                to the (implicit) first argument and the move source
1943                to the (explicit) second argument.  */
1944             op_src = mv_src;
1945         } else {
1946             goto fail;
1947         }
1948         op_arg = REG(op_src);
1949         break;
1950 
1951     case 0x6007: /* not Rm,Rn */
1952         if (ld_dst != B7_4 || mv_src >= 0) {
1953             goto fail;
1954         }
1955         op_dst = B11_8;
1956         op_opc = INDEX_op_xor_i32;
1957         op_arg = tcg_constant_i32(-1);
1958         break;
1959 
1960     case 0x7000 ... 0x700f: /* add #imm,Rn */
1961         if (op_dst != B11_8 || mv_src >= 0) {
1962             goto fail;
1963         }
1964         op_opc = INDEX_op_add_i32;
1965         op_arg = tcg_constant_i32(B7_0s);
1966         break;
1967 
1968     case 0x3000: /* cmp/eq Rm,Rn */
1969         /* Looking for the middle of a compare-and-swap sequence,
1970            beginning with the compare.  Operands can be either order,
1971            but with only one overlapping the load.  */
1972         if ((ld_dst == B11_8) + (ld_dst == B7_4) != 1 || mv_src >= 0) {
1973             goto fail;
1974         }
1975         op_opc = INDEX_op_setcond_i32;  /* placeholder */
1976         op_src = (ld_dst == B11_8 ? B7_4 : B11_8);
1977         op_arg = REG(op_src);
1978 
1979         NEXT_INSN;
1980         switch (ctx->opcode & 0xff00) {
1981         case 0x8b00: /* bf label */
1982         case 0x8f00: /* bf/s label */
1983             if (pc + (i + 1 + B7_0s) * 2 != pc_end) {
1984                 goto fail;
1985             }
1986             if ((ctx->opcode & 0xff00) == 0x8b00) { /* bf label */
1987                 break;
1988             }
1989             /* We're looking to unconditionally modify Rn with the
1990                result of the comparison, within the delay slot of
1991                the branch.  This is used by older gcc.  */
1992             NEXT_INSN;
1993             if ((ctx->opcode & 0xf0ff) == 0x0029) { /* movt Rn */
1994                 mt_dst = B11_8;
1995             } else {
1996                 goto fail;
1997             }
1998             break;
1999 
2000         default:
2001             goto fail;
2002         }
2003         break;
2004 
2005     case 0x2008: /* tst Rm,Rn */
2006         /* Looking for a compare-and-swap against zero.  */
2007         if (ld_dst != B11_8 || ld_dst != B7_4 || mv_src >= 0) {
2008             goto fail;
2009         }
2010         op_opc = INDEX_op_setcond_i32;
2011         op_arg = tcg_constant_i32(0);
2012 
2013         NEXT_INSN;
2014         if ((ctx->opcode & 0xff00) != 0x8900 /* bt label */
2015             || pc + (i + 1 + B7_0s) * 2 != pc_end) {
2016             goto fail;
2017         }
2018         break;
2019 
2020     default:
2021         /* Put back and re-examine as store.  */
2022         --i;
2023     }
2024 
2025     /*
2026      * Expect the store.
2027      */
2028     /* The store must be the last insn.  */
2029     if (i != max_insns - 1) {
2030         goto fail;
2031     }
2032     NEXT_INSN;
2033     switch (ctx->opcode & 0xf00f) {
2034     case 0x2000: /* mov.b Rm,@Rn */
2035         st_mop = MO_UB;
2036         break;
2037     case 0x2001: /* mov.w Rm,@Rn */
2038         st_mop = MO_UW;
2039         break;
2040     case 0x2002: /* mov.l Rm,@Rn */
2041         st_mop = MO_UL;
2042         break;
2043     default:
2044         goto fail;
2045     }
2046     /* The store must match the load.  */
2047     if (ld_adr != B11_8 || st_mop != (ld_mop & MO_SIZE)) {
2048         goto fail;
2049     }
2050     st_src = B7_4;
2051 
2052 #undef NEXT_INSN
2053 
2054     /*
2055      * Emit the operation.
2056      */
2057     switch (op_opc) {
2058     case -1:
2059         /* No operation found.  Look for exchange pattern.  */
2060         if (st_src == ld_dst || mv_src >= 0) {
2061             goto fail;
2062         }
2063         tcg_gen_atomic_xchg_i32(REG(ld_dst), REG(ld_adr), REG(st_src),
2064                                 ctx->memidx, ld_mop);
2065         break;
2066 
2067     case INDEX_op_add_i32:
2068         if (op_dst != st_src) {
2069             goto fail;
2070         }
2071         if (op_dst == ld_dst && st_mop == MO_UL) {
2072             tcg_gen_atomic_add_fetch_i32(REG(ld_dst), REG(ld_adr),
2073                                          op_arg, ctx->memidx, ld_mop);
2074         } else {
2075             tcg_gen_atomic_fetch_add_i32(REG(ld_dst), REG(ld_adr),
2076                                          op_arg, ctx->memidx, ld_mop);
2077             if (op_dst != ld_dst) {
2078                 /* Note that mop sizes < 4 cannot use add_fetch
2079                    because it won't carry into the higher bits.  */
2080                 tcg_gen_add_i32(REG(op_dst), REG(ld_dst), op_arg);
2081             }
2082         }
2083         break;
2084 
2085     case INDEX_op_and_i32:
2086         if (op_dst != st_src) {
2087             goto fail;
2088         }
2089         if (op_dst == ld_dst) {
2090             tcg_gen_atomic_and_fetch_i32(REG(ld_dst), REG(ld_adr),
2091                                          op_arg, ctx->memidx, ld_mop);
2092         } else {
2093             tcg_gen_atomic_fetch_and_i32(REG(ld_dst), REG(ld_adr),
2094                                          op_arg, ctx->memidx, ld_mop);
2095             tcg_gen_and_i32(REG(op_dst), REG(ld_dst), op_arg);
2096         }
2097         break;
2098 
2099     case INDEX_op_or_i32:
2100         if (op_dst != st_src) {
2101             goto fail;
2102         }
2103         if (op_dst == ld_dst) {
2104             tcg_gen_atomic_or_fetch_i32(REG(ld_dst), REG(ld_adr),
2105                                         op_arg, ctx->memidx, ld_mop);
2106         } else {
2107             tcg_gen_atomic_fetch_or_i32(REG(ld_dst), REG(ld_adr),
2108                                         op_arg, ctx->memidx, ld_mop);
2109             tcg_gen_or_i32(REG(op_dst), REG(ld_dst), op_arg);
2110         }
2111         break;
2112 
2113     case INDEX_op_xor_i32:
2114         if (op_dst != st_src) {
2115             goto fail;
2116         }
2117         if (op_dst == ld_dst) {
2118             tcg_gen_atomic_xor_fetch_i32(REG(ld_dst), REG(ld_adr),
2119                                          op_arg, ctx->memidx, ld_mop);
2120         } else {
2121             tcg_gen_atomic_fetch_xor_i32(REG(ld_dst), REG(ld_adr),
2122                                          op_arg, ctx->memidx, ld_mop);
2123             tcg_gen_xor_i32(REG(op_dst), REG(ld_dst), op_arg);
2124         }
2125         break;
2126 
2127     case INDEX_op_setcond_i32:
2128         if (st_src == ld_dst) {
2129             goto fail;
2130         }
2131         tcg_gen_atomic_cmpxchg_i32(REG(ld_dst), REG(ld_adr), op_arg,
2132                                    REG(st_src), ctx->memidx, ld_mop);
2133         tcg_gen_setcond_i32(TCG_COND_EQ, cpu_sr_t, REG(ld_dst), op_arg);
2134         if (mt_dst >= 0) {
2135             tcg_gen_mov_i32(REG(mt_dst), cpu_sr_t);
2136         }
2137         break;
2138 
2139     default:
2140         g_assert_not_reached();
2141     }
2142 
2143     /* The entire region has been translated.  */
2144     ctx->envflags &= ~TB_FLAG_GUSA_MASK;
2145     ctx->base.pc_next = pc_end;
2146     ctx->base.num_insns += max_insns - 1;
2147     return;
2148 
2149  fail:
2150     qemu_log_mask(LOG_UNIMP, "Unrecognized gUSA sequence %08x-%08x\n",
2151                   pc, pc_end);
2152 
2153     /* Restart with the EXCLUSIVE bit set, within a TB run via
2154        cpu_exec_step_atomic holding the exclusive lock.  */
2155     ctx->envflags |= TB_FLAG_GUSA_EXCLUSIVE;
2156     gen_save_cpu_state(ctx, false);
2157     gen_helper_exclusive(cpu_env);
2158     ctx->base.is_jmp = DISAS_NORETURN;
2159 
2160     /* We're not executing an instruction, but we must report one for the
2161        purposes of accounting within the TB.  We might as well report the
2162        entire region consumed via ctx->base.pc_next so that it's immediately
2163        available in the disassembly dump.  */
2164     ctx->base.pc_next = pc_end;
2165     ctx->base.num_insns += max_insns - 1;
2166 }
2167 #endif
2168 
2169 static void sh4_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
2170 {
2171     DisasContext *ctx = container_of(dcbase, DisasContext, base);
2172     CPUSH4State *env = cs->env_ptr;
2173     uint32_t tbflags;
2174     int bound;
2175 
2176     ctx->tbflags = tbflags = ctx->base.tb->flags;
2177     ctx->envflags = tbflags & TB_FLAG_ENVFLAGS_MASK;
2178     ctx->memidx = (tbflags & (1u << SR_MD)) == 0 ? 1 : 0;
2179     /* We don't know if the delayed pc came from a dynamic or static branch,
2180        so assume it is a dynamic branch.  */
2181     ctx->delayed_pc = -1; /* use delayed pc from env pointer */
2182     ctx->features = env->features;
2183     ctx->has_movcal = (tbflags & TB_FLAG_PENDING_MOVCA);
2184     ctx->gbank = ((tbflags & (1 << SR_MD)) &&
2185                   (tbflags & (1 << SR_RB))) * 0x10;
2186     ctx->fbank = tbflags & FPSCR_FR ? 0x10 : 0;
2187 
2188 #ifdef CONFIG_USER_ONLY
2189     if (tbflags & TB_FLAG_GUSA_MASK) {
2190         /* In gUSA exclusive region. */
2191         uint32_t pc = ctx->base.pc_next;
2192         uint32_t pc_end = ctx->base.tb->cs_base;
2193         int backup = sextract32(ctx->tbflags, TB_FLAG_GUSA_SHIFT, 8);
2194         int max_insns = (pc_end - pc) / 2;
2195 
2196         if (pc != pc_end + backup || max_insns < 2) {
2197             /* This is a malformed gUSA region.  Don't do anything special,
2198                since the interpreter is likely to get confused.  */
2199             ctx->envflags &= ~TB_FLAG_GUSA_MASK;
2200         } else if (tbflags & TB_FLAG_GUSA_EXCLUSIVE) {
2201             /* Regardless of single-stepping or the end of the page,
2202                we must complete execution of the gUSA region while
2203                holding the exclusive lock.  */
2204             ctx->base.max_insns = max_insns;
2205             return;
2206         }
2207     }
2208 #endif
2209 
2210     /* Since the ISA is fixed-width, we can bound by the number
2211        of instructions remaining on the page.  */
2212     bound = -(ctx->base.pc_next | TARGET_PAGE_MASK) / 2;
2213     ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
2214 }
2215 
2216 static void sh4_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
2217 {
2218 }
2219 
2220 static void sh4_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
2221 {
2222     DisasContext *ctx = container_of(dcbase, DisasContext, base);
2223 
2224     tcg_gen_insn_start(ctx->base.pc_next, ctx->envflags);
2225 }
2226 
2227 static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
2228 {
2229     CPUSH4State *env = cs->env_ptr;
2230     DisasContext *ctx = container_of(dcbase, DisasContext, base);
2231 
2232 #ifdef CONFIG_USER_ONLY
2233     if (unlikely(ctx->envflags & TB_FLAG_GUSA_MASK)
2234         && !(ctx->envflags & TB_FLAG_GUSA_EXCLUSIVE)) {
2235         /* We're in an gUSA region, and we have not already fallen
2236            back on using an exclusive region.  Attempt to parse the
2237            region into a single supported atomic operation.  Failure
2238            is handled within the parser by raising an exception to
2239            retry using an exclusive region.  */
2240         decode_gusa(ctx, env);
2241         return;
2242     }
2243 #endif
2244 
2245     ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
2246     decode_opc(ctx);
2247     ctx->base.pc_next += 2;
2248 }
2249 
2250 static void sh4_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
2251 {
2252     DisasContext *ctx = container_of(dcbase, DisasContext, base);
2253 
2254     if (ctx->tbflags & TB_FLAG_GUSA_EXCLUSIVE) {
2255         /* Ending the region of exclusivity.  Clear the bits.  */
2256         ctx->envflags &= ~TB_FLAG_GUSA_MASK;
2257     }
2258 
2259     switch (ctx->base.is_jmp) {
2260     case DISAS_STOP:
2261         gen_save_cpu_state(ctx, true);
2262         tcg_gen_exit_tb(NULL, 0);
2263         break;
2264     case DISAS_NEXT:
2265     case DISAS_TOO_MANY:
2266         gen_save_cpu_state(ctx, false);
2267         gen_goto_tb(ctx, 0, ctx->base.pc_next);
2268         break;
2269     case DISAS_NORETURN:
2270         break;
2271     default:
2272         g_assert_not_reached();
2273     }
2274 }
2275 
2276 static void sh4_tr_disas_log(const DisasContextBase *dcbase,
2277                              CPUState *cs, FILE *logfile)
2278 {
2279     fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first));
2280     target_disas(logfile, cs, dcbase->pc_first, dcbase->tb->size);
2281 }
2282 
2283 static const TranslatorOps sh4_tr_ops = {
2284     .init_disas_context = sh4_tr_init_disas_context,
2285     .tb_start           = sh4_tr_tb_start,
2286     .insn_start         = sh4_tr_insn_start,
2287     .translate_insn     = sh4_tr_translate_insn,
2288     .tb_stop            = sh4_tr_tb_stop,
2289     .disas_log          = sh4_tr_disas_log,
2290 };
2291 
2292 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
2293                            target_ulong pc, void *host_pc)
2294 {
2295     DisasContext ctx;
2296 
2297     translator_loop(cs, tb, max_insns, pc, host_pc, &sh4_tr_ops, &ctx.base);
2298 }
2299