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