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