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