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