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