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