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