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