These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / 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 "tcg-op.h"
26 #include "exec/cpu_ldst.h"
27
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
30
31 #include "trace-tcg.h"
32 #include "exec/log.h"
33
34
35 typedef struct DisasContext {
36     struct TranslationBlock *tb;
37     target_ulong pc;
38     uint16_t opcode;
39     uint32_t flags;
40     int bstate;
41     int memidx;
42     uint32_t delayed_pc;
43     int singlestep_enabled;
44     uint32_t features;
45     int has_movcal;
46 } DisasContext;
47
48 #if defined(CONFIG_USER_ONLY)
49 #define IS_USER(ctx) 1
50 #else
51 #define IS_USER(ctx) (!(ctx->flags & (1u << SR_MD)))
52 #endif
53
54 enum {
55     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
56                       * exception condition
57                       */
58     BS_STOP     = 1, /* We want to stop translation for any reason */
59     BS_BRANCH   = 2, /* We reached a branch condition     */
60     BS_EXCP     = 3, /* We reached an exception condition */
61 };
62
63 /* global register indexes */
64 static TCGv_env cpu_env;
65 static TCGv cpu_gregs[24];
66 static TCGv cpu_sr, cpu_sr_m, cpu_sr_q, cpu_sr_t;
67 static TCGv cpu_pc, cpu_ssr, cpu_spc, cpu_gbr;
68 static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
69 static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_ldst;
70 static TCGv cpu_fregs[32];
71
72 /* internal register indexes */
73 static TCGv cpu_flags, cpu_delayed_pc;
74
75 #include "exec/gen-icount.h"
76
77 void sh4_translate_init(void)
78 {
79     int i;
80     static int done_init = 0;
81     static const char * const gregnames[24] = {
82         "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
83         "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
84         "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
85         "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
86         "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
87     };
88     static const char * const fregnames[32] = {
89          "FPR0_BANK0",  "FPR1_BANK0",  "FPR2_BANK0",  "FPR3_BANK0",
90          "FPR4_BANK0",  "FPR5_BANK0",  "FPR6_BANK0",  "FPR7_BANK0",
91          "FPR8_BANK0",  "FPR9_BANK0", "FPR10_BANK0", "FPR11_BANK0",
92         "FPR12_BANK0", "FPR13_BANK0", "FPR14_BANK0", "FPR15_BANK0",
93          "FPR0_BANK1",  "FPR1_BANK1",  "FPR2_BANK1",  "FPR3_BANK1",
94          "FPR4_BANK1",  "FPR5_BANK1",  "FPR6_BANK1",  "FPR7_BANK1",
95          "FPR8_BANK1",  "FPR9_BANK1", "FPR10_BANK1", "FPR11_BANK1",
96         "FPR12_BANK1", "FPR13_BANK1", "FPR14_BANK1", "FPR15_BANK1",
97     };
98
99     if (done_init)
100         return;
101
102     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
103
104     for (i = 0; i < 24; i++)
105         cpu_gregs[i] = tcg_global_mem_new_i32(cpu_env,
106                                               offsetof(CPUSH4State, gregs[i]),
107                                               gregnames[i]);
108
109     cpu_pc = tcg_global_mem_new_i32(cpu_env,
110                                     offsetof(CPUSH4State, pc), "PC");
111     cpu_sr = tcg_global_mem_new_i32(cpu_env,
112                                     offsetof(CPUSH4State, sr), "SR");
113     cpu_sr_m = tcg_global_mem_new_i32(cpu_env,
114                                       offsetof(CPUSH4State, sr_m), "SR_M");
115     cpu_sr_q = tcg_global_mem_new_i32(cpu_env,
116                                       offsetof(CPUSH4State, sr_q), "SR_Q");
117     cpu_sr_t = tcg_global_mem_new_i32(cpu_env,
118                                       offsetof(CPUSH4State, sr_t), "SR_T");
119     cpu_ssr = tcg_global_mem_new_i32(cpu_env,
120                                      offsetof(CPUSH4State, ssr), "SSR");
121     cpu_spc = tcg_global_mem_new_i32(cpu_env,
122                                      offsetof(CPUSH4State, spc), "SPC");
123     cpu_gbr = tcg_global_mem_new_i32(cpu_env,
124                                      offsetof(CPUSH4State, gbr), "GBR");
125     cpu_vbr = tcg_global_mem_new_i32(cpu_env,
126                                      offsetof(CPUSH4State, vbr), "VBR");
127     cpu_sgr = tcg_global_mem_new_i32(cpu_env,
128                                      offsetof(CPUSH4State, sgr), "SGR");
129     cpu_dbr = tcg_global_mem_new_i32(cpu_env,
130                                      offsetof(CPUSH4State, dbr), "DBR");
131     cpu_mach = tcg_global_mem_new_i32(cpu_env,
132                                       offsetof(CPUSH4State, mach), "MACH");
133     cpu_macl = tcg_global_mem_new_i32(cpu_env,
134                                       offsetof(CPUSH4State, macl), "MACL");
135     cpu_pr = tcg_global_mem_new_i32(cpu_env,
136                                     offsetof(CPUSH4State, pr), "PR");
137     cpu_fpscr = tcg_global_mem_new_i32(cpu_env,
138                                        offsetof(CPUSH4State, fpscr), "FPSCR");
139     cpu_fpul = tcg_global_mem_new_i32(cpu_env,
140                                       offsetof(CPUSH4State, fpul), "FPUL");
141
142     cpu_flags = tcg_global_mem_new_i32(cpu_env,
143                                        offsetof(CPUSH4State, flags), "_flags_");
144     cpu_delayed_pc = tcg_global_mem_new_i32(cpu_env,
145                                             offsetof(CPUSH4State, delayed_pc),
146                                             "_delayed_pc_");
147     cpu_ldst = tcg_global_mem_new_i32(cpu_env,
148                                       offsetof(CPUSH4State, ldst), "_ldst_");
149
150     for (i = 0; i < 32; i++)
151         cpu_fregs[i] = tcg_global_mem_new_i32(cpu_env,
152                                               offsetof(CPUSH4State, fregs[i]),
153                                               fregnames[i]);
154
155     done_init = 1;
156 }
157
158 void superh_cpu_dump_state(CPUState *cs, FILE *f,
159                            fprintf_function cpu_fprintf, int flags)
160 {
161     SuperHCPU *cpu = SUPERH_CPU(cs);
162     CPUSH4State *env = &cpu->env;
163     int i;
164     cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
165                 env->pc, cpu_read_sr(env), env->pr, env->fpscr);
166     cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
167                 env->spc, env->ssr, env->gbr, env->vbr);
168     cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
169                 env->sgr, env->dbr, env->delayed_pc, env->fpul);
170     for (i = 0; i < 24; i += 4) {
171         cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
172                     i, env->gregs[i], i + 1, env->gregs[i + 1],
173                     i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
174     }
175     if (env->flags & DELAY_SLOT) {
176         cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
177                     env->delayed_pc);
178     } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
179         cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
180                     env->delayed_pc);
181     }
182 }
183
184 static void gen_read_sr(TCGv dst)
185 {
186     TCGv t0 = tcg_temp_new();
187     tcg_gen_shli_i32(t0, cpu_sr_q, SR_Q);
188     tcg_gen_or_i32(dst, dst, t0);
189     tcg_gen_shli_i32(t0, cpu_sr_m, SR_M);
190     tcg_gen_or_i32(dst, dst, t0);
191     tcg_gen_shli_i32(t0, cpu_sr_t, SR_T);
192     tcg_gen_or_i32(dst, cpu_sr, t0);
193     tcg_temp_free_i32(t0);
194 }
195
196 static void gen_write_sr(TCGv src)
197 {
198     tcg_gen_andi_i32(cpu_sr, src,
199                      ~((1u << SR_Q) | (1u << SR_M) | (1u << SR_T)));
200     tcg_gen_shri_i32(cpu_sr_q, src, SR_Q);
201     tcg_gen_andi_i32(cpu_sr_q, cpu_sr_q, 1);
202     tcg_gen_shri_i32(cpu_sr_m, src, SR_M);
203     tcg_gen_andi_i32(cpu_sr_m, cpu_sr_m, 1);
204     tcg_gen_shri_i32(cpu_sr_t, src, SR_T);
205     tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
206 }
207
208 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
209 {
210     TranslationBlock *tb;
211     tb = ctx->tb;
212
213     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
214         !ctx->singlestep_enabled) {
215         /* Use a direct jump if in same page and singlestep not enabled */
216         tcg_gen_goto_tb(n);
217         tcg_gen_movi_i32(cpu_pc, dest);
218         tcg_gen_exit_tb((uintptr_t)tb + n);
219     } else {
220         tcg_gen_movi_i32(cpu_pc, dest);
221         if (ctx->singlestep_enabled)
222             gen_helper_debug(cpu_env);
223         tcg_gen_exit_tb(0);
224     }
225 }
226
227 static void gen_jump(DisasContext * ctx)
228 {
229     if (ctx->delayed_pc == (uint32_t) - 1) {
230         /* Target is not statically known, it comes necessarily from a
231            delayed jump as immediate jump are conditinal jumps */
232         tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
233         if (ctx->singlestep_enabled)
234             gen_helper_debug(cpu_env);
235         tcg_gen_exit_tb(0);
236     } else {
237         gen_goto_tb(ctx, 0, ctx->delayed_pc);
238     }
239 }
240
241 static inline void gen_branch_slot(uint32_t delayed_pc, int t)
242 {
243     TCGLabel *label = gen_new_label();
244     tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
245     tcg_gen_brcondi_i32(t ? TCG_COND_EQ : TCG_COND_NE, cpu_sr_t, 0, label);
246     tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
247     gen_set_label(label);
248 }
249
250 /* Immediate conditional jump (bt or bf) */
251 static void gen_conditional_jump(DisasContext * ctx,
252                                  target_ulong ift, target_ulong ifnott)
253 {
254     TCGLabel *l1 = gen_new_label();
255     tcg_gen_brcondi_i32(TCG_COND_NE, cpu_sr_t, 0, l1);
256     gen_goto_tb(ctx, 0, ifnott);
257     gen_set_label(l1);
258     gen_goto_tb(ctx, 1, ift);
259 }
260
261 /* Delayed conditional jump (bt or bf) */
262 static void gen_delayed_conditional_jump(DisasContext * ctx)
263 {
264     TCGLabel *l1;
265     TCGv ds;
266
267     l1 = gen_new_label();
268     ds = tcg_temp_new();
269     tcg_gen_andi_i32(ds, cpu_flags, DELAY_SLOT_TRUE);
270     tcg_gen_brcondi_i32(TCG_COND_NE, ds, 0, l1);
271     gen_goto_tb(ctx, 1, ctx->pc + 2);
272     gen_set_label(l1);
273     tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
274     gen_jump(ctx);
275 }
276
277 static inline void gen_store_flags(uint32_t flags)
278 {
279     tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
280     tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
281 }
282
283 static inline void gen_load_fpr64(TCGv_i64 t, int reg)
284 {
285     tcg_gen_concat_i32_i64(t, cpu_fregs[reg + 1], cpu_fregs[reg]);
286 }
287
288 static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
289 {
290     TCGv_i32 tmp = tcg_temp_new_i32();
291     tcg_gen_extrl_i64_i32(tmp, t);
292     tcg_gen_mov_i32(cpu_fregs[reg + 1], tmp);
293     tcg_gen_shri_i64(t, t, 32);
294     tcg_gen_extrl_i64_i32(tmp, t);
295     tcg_gen_mov_i32(cpu_fregs[reg], tmp);
296     tcg_temp_free_i32(tmp);
297 }
298
299 #define B3_0 (ctx->opcode & 0xf)
300 #define B6_4 ((ctx->opcode >> 4) & 0x7)
301 #define B7_4 ((ctx->opcode >> 4) & 0xf)
302 #define B7_0 (ctx->opcode & 0xff)
303 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
304 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
305   (ctx->opcode & 0xfff))
306 #define B11_8 ((ctx->opcode >> 8) & 0xf)
307 #define B15_12 ((ctx->opcode >> 12) & 0xf)
308
309 #define REG(x) ((x) < 8 && (ctx->flags & (1u << SR_MD))\
310                         && (ctx->flags & (1u << SR_RB))\
311                 ? (cpu_gregs[x + 16]) : (cpu_gregs[x]))
312
313 #define ALTREG(x) ((x) < 8 && (!(ctx->flags & (1u << SR_MD))\
314                                || !(ctx->flags & (1u << SR_RB)))\
315                 ? (cpu_gregs[x + 16]) : (cpu_gregs[x]))
316
317 #define FREG(x) (ctx->flags & FPSCR_FR ? (x) ^ 0x10 : (x))
318 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
319 #define XREG(x) (ctx->flags & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
320 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
321
322 #define CHECK_NOT_DELAY_SLOT \
323   if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))     \
324   {                                                           \
325       tcg_gen_movi_i32(cpu_pc, ctx->pc);                      \
326       gen_helper_raise_slot_illegal_instruction(cpu_env);     \
327       ctx->bstate = BS_BRANCH;                                \
328       return;                                                 \
329   }
330
331 #define CHECK_PRIVILEGED                                        \
332   if (IS_USER(ctx)) {                                           \
333       tcg_gen_movi_i32(cpu_pc, ctx->pc);                        \
334       if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
335           gen_helper_raise_slot_illegal_instruction(cpu_env);   \
336       } else {                                                  \
337           gen_helper_raise_illegal_instruction(cpu_env);        \
338       }                                                         \
339       ctx->bstate = BS_BRANCH;                                  \
340       return;                                                   \
341   }
342
343 #define CHECK_FPU_ENABLED                                       \
344   if (ctx->flags & (1u << SR_FD)) {                             \
345       tcg_gen_movi_i32(cpu_pc, ctx->pc);                        \
346       if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
347           gen_helper_raise_slot_fpu_disable(cpu_env);           \
348       } else {                                                  \
349           gen_helper_raise_fpu_disable(cpu_env);                \
350       }                                                         \
351       ctx->bstate = BS_BRANCH;                                  \
352       return;                                                   \
353   }
354
355 static void _decode_opc(DisasContext * ctx)
356 {
357     /* This code tries to make movcal emulation sufficiently
358        accurate for Linux purposes.  This instruction writes
359        memory, and prior to that, always allocates a cache line.
360        It is used in two contexts:
361        - in memcpy, where data is copied in blocks, the first write
362        of to a block uses movca.l for performance.
363        - in arch/sh/mm/cache-sh4.c, movcal.l + ocbi combination is used
364        to flush the cache. Here, the data written by movcal.l is never
365        written to memory, and the data written is just bogus.
366
367        To simulate this, we simulate movcal.l, we store the value to memory,
368        but we also remember the previous content. If we see ocbi, we check
369        if movcal.l for that address was done previously. If so, the write should
370        not have hit the memory, so we restore the previous content.
371        When we see an instruction that is neither movca.l
372        nor ocbi, the previous content is discarded.
373
374        To optimize, we only try to flush stores when we're at the start of
375        TB, or if we already saw movca.l in this TB and did not flush stores
376        yet.  */
377     if (ctx->has_movcal)
378         {
379           int opcode = ctx->opcode & 0xf0ff;
380           if (opcode != 0x0093 /* ocbi */
381               && opcode != 0x00c3 /* movca.l */)
382               {
383                   gen_helper_discard_movcal_backup(cpu_env);
384                   ctx->has_movcal = 0;
385               }
386         }
387
388 #if 0
389     fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
390 #endif
391
392     switch (ctx->opcode) {
393     case 0x0019:                /* div0u */
394         tcg_gen_movi_i32(cpu_sr_m, 0);
395         tcg_gen_movi_i32(cpu_sr_q, 0);
396         tcg_gen_movi_i32(cpu_sr_t, 0);
397         return;
398     case 0x000b:                /* rts */
399         CHECK_NOT_DELAY_SLOT
400         tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
401         ctx->flags |= DELAY_SLOT;
402         ctx->delayed_pc = (uint32_t) - 1;
403         return;
404     case 0x0028:                /* clrmac */
405         tcg_gen_movi_i32(cpu_mach, 0);
406         tcg_gen_movi_i32(cpu_macl, 0);
407         return;
408     case 0x0048:                /* clrs */
409         tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(1u << SR_S));
410         return;
411     case 0x0008:                /* clrt */
412         tcg_gen_movi_i32(cpu_sr_t, 0);
413         return;
414     case 0x0038:                /* ldtlb */
415         CHECK_PRIVILEGED
416         gen_helper_ldtlb(cpu_env);
417         return;
418     case 0x002b:                /* rte */
419         CHECK_PRIVILEGED
420         CHECK_NOT_DELAY_SLOT
421         gen_write_sr(cpu_ssr);
422         tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
423         ctx->flags |= DELAY_SLOT;
424         ctx->delayed_pc = (uint32_t) - 1;
425         return;
426     case 0x0058:                /* sets */
427         tcg_gen_ori_i32(cpu_sr, cpu_sr, (1u << SR_S));
428         return;
429     case 0x0018:                /* sett */
430         tcg_gen_movi_i32(cpu_sr_t, 1);
431         return;
432     case 0xfbfd:                /* frchg */
433         tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
434         ctx->bstate = BS_STOP;
435         return;
436     case 0xf3fd:                /* fschg */
437         tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
438         ctx->bstate = BS_STOP;
439         return;
440     case 0x0009:                /* nop */
441         return;
442     case 0x001b:                /* sleep */
443         CHECK_PRIVILEGED
444         tcg_gen_movi_i32(cpu_pc, ctx->pc + 2);
445         gen_helper_sleep(cpu_env);
446         return;
447     }
448
449     switch (ctx->opcode & 0xf000) {
450     case 0x1000:                /* mov.l Rm,@(disp,Rn) */
451         {
452             TCGv addr = tcg_temp_new();
453             tcg_gen_addi_i32(addr, REG(B11_8), B3_0 * 4);
454             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
455             tcg_temp_free(addr);
456         }
457         return;
458     case 0x5000:                /* mov.l @(disp,Rm),Rn */
459         {
460             TCGv addr = tcg_temp_new();
461             tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 4);
462             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
463             tcg_temp_free(addr);
464         }
465         return;
466     case 0xe000:                /* mov #imm,Rn */
467         tcg_gen_movi_i32(REG(B11_8), B7_0s);
468         return;
469     case 0x9000:                /* mov.w @(disp,PC),Rn */
470         {
471             TCGv addr = tcg_const_i32(ctx->pc + 4 + B7_0 * 2);
472             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESW);
473             tcg_temp_free(addr);
474         }
475         return;
476     case 0xd000:                /* mov.l @(disp,PC),Rn */
477         {
478             TCGv addr = tcg_const_i32((ctx->pc + 4 + B7_0 * 4) & ~3);
479             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
480             tcg_temp_free(addr);
481         }
482         return;
483     case 0x7000:                /* add #imm,Rn */
484         tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);
485         return;
486     case 0xa000:                /* bra disp */
487         CHECK_NOT_DELAY_SLOT
488         ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
489         tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
490         ctx->flags |= DELAY_SLOT;
491         return;
492     case 0xb000:                /* bsr disp */
493         CHECK_NOT_DELAY_SLOT
494         tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
495         ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
496         tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
497         ctx->flags |= DELAY_SLOT;
498         return;
499     }
500
501     switch (ctx->opcode & 0xf00f) {
502     case 0x6003:                /* mov Rm,Rn */
503         tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
504         return;
505     case 0x2000:                /* mov.b Rm,@Rn */
506         tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_UB);
507         return;
508     case 0x2001:                /* mov.w Rm,@Rn */
509         tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_TEUW);
510         return;
511     case 0x2002:                /* mov.l Rm,@Rn */
512         tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_TEUL);
513         return;
514     case 0x6000:                /* mov.b @Rm,Rn */
515         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_SB);
516         return;
517     case 0x6001:                /* mov.w @Rm,Rn */
518         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESW);
519         return;
520     case 0x6002:                /* mov.l @Rm,Rn */
521         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESL);
522         return;
523     case 0x2004:                /* mov.b Rm,@-Rn */
524         {
525             TCGv addr = tcg_temp_new();
526             tcg_gen_subi_i32(addr, REG(B11_8), 1);
527             /* might cause re-execution */
528             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_UB);
529             tcg_gen_mov_i32(REG(B11_8), addr);                  /* modify register status */
530             tcg_temp_free(addr);
531         }
532         return;
533     case 0x2005:                /* mov.w Rm,@-Rn */
534         {
535             TCGv addr = tcg_temp_new();
536             tcg_gen_subi_i32(addr, REG(B11_8), 2);
537             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUW);
538             tcg_gen_mov_i32(REG(B11_8), addr);
539             tcg_temp_free(addr);
540         }
541         return;
542     case 0x2006:                /* mov.l Rm,@-Rn */
543         {
544             TCGv addr = tcg_temp_new();
545             tcg_gen_subi_i32(addr, REG(B11_8), 4);
546             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
547             tcg_gen_mov_i32(REG(B11_8), addr);
548         }
549         return;
550     case 0x6004:                /* mov.b @Rm+,Rn */
551         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_SB);
552         if ( B11_8 != B7_4 )
553                 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 1);
554         return;
555     case 0x6005:                /* mov.w @Rm+,Rn */
556         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESW);
557         if ( B11_8 != B7_4 )
558                 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
559         return;
560     case 0x6006:                /* mov.l @Rm+,Rn */
561         tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESL);
562         if ( B11_8 != B7_4 )
563                 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
564         return;
565     case 0x0004:                /* mov.b Rm,@(R0,Rn) */
566         {
567             TCGv addr = tcg_temp_new();
568             tcg_gen_add_i32(addr, REG(B11_8), REG(0));
569             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_UB);
570             tcg_temp_free(addr);
571         }
572         return;
573     case 0x0005:                /* mov.w Rm,@(R0,Rn) */
574         {
575             TCGv addr = tcg_temp_new();
576             tcg_gen_add_i32(addr, REG(B11_8), REG(0));
577             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUW);
578             tcg_temp_free(addr);
579         }
580         return;
581     case 0x0006:                /* mov.l Rm,@(R0,Rn) */
582         {
583             TCGv addr = tcg_temp_new();
584             tcg_gen_add_i32(addr, REG(B11_8), REG(0));
585             tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
586             tcg_temp_free(addr);
587         }
588         return;
589     case 0x000c:                /* mov.b @(R0,Rm),Rn */
590         {
591             TCGv addr = tcg_temp_new();
592             tcg_gen_add_i32(addr, REG(B7_4), REG(0));
593             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_SB);
594             tcg_temp_free(addr);
595         }
596         return;
597     case 0x000d:                /* mov.w @(R0,Rm),Rn */
598         {
599             TCGv addr = tcg_temp_new();
600             tcg_gen_add_i32(addr, REG(B7_4), REG(0));
601             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESW);
602             tcg_temp_free(addr);
603         }
604         return;
605     case 0x000e:                /* mov.l @(R0,Rm),Rn */
606         {
607             TCGv addr = tcg_temp_new();
608             tcg_gen_add_i32(addr, REG(B7_4), REG(0));
609             tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
610             tcg_temp_free(addr);
611         }
612         return;
613     case 0x6008:                /* swap.b Rm,Rn */
614         {
615             TCGv low = tcg_temp_new();;
616             tcg_gen_ext16u_i32(low, REG(B7_4));
617             tcg_gen_bswap16_i32(low, low);
618             tcg_gen_deposit_i32(REG(B11_8), REG(B7_4), low, 0, 16);
619             tcg_temp_free(low);
620         }
621         return;
622     case 0x6009:                /* swap.w Rm,Rn */
623         tcg_gen_rotli_i32(REG(B11_8), REG(B7_4), 16);
624         return;
625     case 0x200d:                /* xtrct Rm,Rn */
626         {
627             TCGv high, low;
628             high = tcg_temp_new();
629             tcg_gen_shli_i32(high, REG(B7_4), 16);
630             low = tcg_temp_new();
631             tcg_gen_shri_i32(low, REG(B11_8), 16);
632             tcg_gen_or_i32(REG(B11_8), high, low);
633             tcg_temp_free(low);
634             tcg_temp_free(high);
635         }
636         return;
637     case 0x300c:                /* add Rm,Rn */
638         tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));
639         return;
640     case 0x300e:                /* addc Rm,Rn */
641         {
642             TCGv t0, t1;
643             t0 = tcg_const_tl(0);
644             t1 = tcg_temp_new();
645             tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0);
646             tcg_gen_add2_i32(REG(B11_8), cpu_sr_t,
647                              REG(B11_8), t0, t1, cpu_sr_t);
648             tcg_temp_free(t0);
649             tcg_temp_free(t1);
650         }
651         return;
652     case 0x300f:                /* addv Rm,Rn */
653         {
654             TCGv t0, t1, t2;
655             t0 = tcg_temp_new();
656             tcg_gen_add_i32(t0, REG(B7_4), REG(B11_8));
657             t1 = tcg_temp_new();
658             tcg_gen_xor_i32(t1, t0, REG(B11_8));
659             t2 = tcg_temp_new();
660             tcg_gen_xor_i32(t2, REG(B7_4), REG(B11_8));
661             tcg_gen_andc_i32(cpu_sr_t, t1, t2);
662             tcg_temp_free(t2);
663             tcg_gen_shri_i32(cpu_sr_t, cpu_sr_t, 31);
664             tcg_temp_free(t1);
665             tcg_gen_mov_i32(REG(B7_4), t0);
666             tcg_temp_free(t0);
667         }
668         return;
669     case 0x2009:                /* and Rm,Rn */
670         tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
671         return;
672     case 0x3000:                /* cmp/eq Rm,Rn */
673         tcg_gen_setcond_i32(TCG_COND_EQ, cpu_sr_t, REG(B11_8), REG(B7_4));
674         return;
675     case 0x3003:                /* cmp/ge Rm,Rn */
676         tcg_gen_setcond_i32(TCG_COND_GE, cpu_sr_t, REG(B11_8), REG(B7_4));
677         return;
678     case 0x3007:                /* cmp/gt Rm,Rn */
679         tcg_gen_setcond_i32(TCG_COND_GT, cpu_sr_t, REG(B11_8), REG(B7_4));
680         return;
681     case 0x3006:                /* cmp/hi Rm,Rn */
682         tcg_gen_setcond_i32(TCG_COND_GTU, cpu_sr_t, REG(B11_8), REG(B7_4));
683         return;
684     case 0x3002:                /* cmp/hs Rm,Rn */
685         tcg_gen_setcond_i32(TCG_COND_GEU, cpu_sr_t, REG(B11_8), REG(B7_4));
686         return;
687     case 0x200c:                /* cmp/str Rm,Rn */
688         {
689             TCGv cmp1 = tcg_temp_new();
690             TCGv cmp2 = tcg_temp_new();
691             tcg_gen_xor_i32(cmp2, REG(B7_4), REG(B11_8));
692             tcg_gen_subi_i32(cmp1, cmp2, 0x01010101);
693             tcg_gen_andc_i32(cmp1, cmp1, cmp2);
694             tcg_gen_andi_i32(cmp1, cmp1, 0x80808080);
695             tcg_gen_setcondi_i32(TCG_COND_NE, cpu_sr_t, cmp1, 0);
696             tcg_temp_free(cmp2);
697             tcg_temp_free(cmp1);
698         }
699         return;
700     case 0x2007:                /* div0s Rm,Rn */
701         tcg_gen_shri_i32(cpu_sr_q, REG(B11_8), 31);         /* SR_Q */
702         tcg_gen_shri_i32(cpu_sr_m, REG(B7_4), 31);          /* SR_M */
703         tcg_gen_xor_i32(cpu_sr_t, cpu_sr_q, cpu_sr_m);      /* SR_T */
704         return;
705     case 0x3004:                /* div1 Rm,Rn */
706         {
707             TCGv t0 = tcg_temp_new();
708             TCGv t1 = tcg_temp_new();
709             TCGv t2 = tcg_temp_new();
710             TCGv zero = tcg_const_i32(0);
711
712             /* shift left arg1, saving the bit being pushed out and inserting
713                T on the right */
714             tcg_gen_shri_i32(t0, REG(B11_8), 31);
715             tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
716             tcg_gen_or_i32(REG(B11_8), REG(B11_8), cpu_sr_t);
717
718             /* Add or subtract arg0 from arg1 depending if Q == M. To avoid
719                using 64-bit temps, we compute arg0's high part from q ^ m, so
720                that it is 0x00000000 when adding the value or 0xffffffff when
721                subtracting it. */
722             tcg_gen_xor_i32(t1, cpu_sr_q, cpu_sr_m);
723             tcg_gen_subi_i32(t1, t1, 1);
724             tcg_gen_neg_i32(t2, REG(B7_4));
725             tcg_gen_movcond_i32(TCG_COND_EQ, t2, t1, zero, REG(B7_4), t2);
726             tcg_gen_add2_i32(REG(B11_8), t1, REG(B11_8), zero, t2, t1);
727
728             /* compute T and Q depending on carry */
729             tcg_gen_andi_i32(t1, t1, 1);
730             tcg_gen_xor_i32(t1, t1, t0);
731             tcg_gen_xori_i32(cpu_sr_t, t1, 1);
732             tcg_gen_xor_i32(cpu_sr_q, cpu_sr_m, t1);
733
734             tcg_temp_free(zero);
735             tcg_temp_free(t2);
736             tcg_temp_free(t1);
737             tcg_temp_free(t0);
738         }
739         return;
740     case 0x300d:                /* dmuls.l Rm,Rn */
741         tcg_gen_muls2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
742         return;
743     case 0x3005:                /* dmulu.l Rm,Rn */
744         tcg_gen_mulu2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
745         return;
746     case 0x600e:                /* exts.b Rm,Rn */
747         tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));
748         return;
749     case 0x600f:                /* exts.w Rm,Rn */
750         tcg_gen_ext16s_i32(REG(B11_8), REG(B7_4));
751         return;
752     case 0x600c:                /* extu.b Rm,Rn */
753         tcg_gen_ext8u_i32(REG(B11_8), REG(B7_4));
754         return;
755     case 0x600d:                /* extu.w Rm,Rn */
756         tcg_gen_ext16u_i32(REG(B11_8), REG(B7_4));
757         return;
758     case 0x000f:                /* mac.l @Rm+,@Rn+ */
759         {
760             TCGv arg0, arg1;
761             arg0 = tcg_temp_new();
762             tcg_gen_qemu_ld_i32(arg0, REG(B7_4), ctx->memidx, MO_TESL);
763             arg1 = tcg_temp_new();
764             tcg_gen_qemu_ld_i32(arg1, REG(B11_8), ctx->memidx, MO_TESL);
765             gen_helper_macl(cpu_env, arg0, arg1);
766             tcg_temp_free(arg1);
767             tcg_temp_free(arg0);
768             tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
769             tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
770         }
771         return;
772     case 0x400f:                /* mac.w @Rm+,@Rn+ */
773         {
774             TCGv arg0, arg1;
775             arg0 = tcg_temp_new();
776             tcg_gen_qemu_ld_i32(arg0, REG(B7_4), ctx->memidx, MO_TESL);
777             arg1 = tcg_temp_new();
778             tcg_gen_qemu_ld_i32(arg1, REG(B11_8), ctx->memidx, MO_TESL);
779             gen_helper_macw(cpu_env, arg0, arg1);
780             tcg_temp_free(arg1);
781             tcg_temp_free(arg0);
782             tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);
783             tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
784         }
785         return;
786     case 0x0007:                /* mul.l Rm,Rn */
787         tcg_gen_mul_i32(cpu_macl, REG(B7_4), REG(B11_8));
788         return;
789     case 0x200f:                /* muls.w Rm,Rn */
790         {
791             TCGv arg0, arg1;
792             arg0 = tcg_temp_new();
793             tcg_gen_ext16s_i32(arg0, REG(B7_4));
794             arg1 = tcg_temp_new();
795             tcg_gen_ext16s_i32(arg1, REG(B11_8));
796             tcg_gen_mul_i32(cpu_macl, arg0, arg1);
797             tcg_temp_free(arg1);
798             tcg_temp_free(arg0);
799         }
800         return;
801     case 0x200e:                /* mulu.w Rm,Rn */
802         {
803             TCGv arg0, arg1;
804             arg0 = tcg_temp_new();
805             tcg_gen_ext16u_i32(arg0, REG(B7_4));
806             arg1 = tcg_temp_new();
807             tcg_gen_ext16u_i32(arg1, REG(B11_8));
808             tcg_gen_mul_i32(cpu_macl, arg0, arg1);
809             tcg_temp_free(arg1);
810             tcg_temp_free(arg0);
811         }
812         return;
813     case 0x600b:                /* neg Rm,Rn */
814         tcg_gen_neg_i32(REG(B11_8), REG(B7_4));
815         return;
816     case 0x600a:                /* negc Rm,Rn */
817         {
818             TCGv t0 = tcg_const_i32(0);
819             tcg_gen_add2_i32(REG(B11_8), cpu_sr_t,
820                              REG(B7_4), t0, cpu_sr_t, t0);
821             tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t,
822                              t0, t0, REG(B11_8), cpu_sr_t);
823             tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
824             tcg_temp_free(t0);
825         }
826         return;
827     case 0x6007:                /* not Rm,Rn */
828         tcg_gen_not_i32(REG(B11_8), REG(B7_4));
829         return;
830     case 0x200b:                /* or Rm,Rn */
831         tcg_gen_or_i32(REG(B11_8), REG(B11_8), REG(B7_4));
832         return;
833     case 0x400c:                /* shad Rm,Rn */
834         {
835             TCGv t0 = tcg_temp_new();
836             TCGv t1 = tcg_temp_new();
837             TCGv t2 = tcg_temp_new();
838
839             tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
840
841             /* positive case: shift to the left */
842             tcg_gen_shl_i32(t1, REG(B11_8), t0);
843
844             /* negative case: shift to the right in two steps to
845                correctly handle the -32 case */
846             tcg_gen_xori_i32(t0, t0, 0x1f);
847             tcg_gen_sar_i32(t2, REG(B11_8), t0);
848             tcg_gen_sari_i32(t2, t2, 1);
849
850             /* select between the two cases */
851             tcg_gen_movi_i32(t0, 0);
852             tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
853
854             tcg_temp_free(t0);
855             tcg_temp_free(t1);
856             tcg_temp_free(t2);
857         }
858         return;
859     case 0x400d:                /* shld Rm,Rn */
860         {
861             TCGv t0 = tcg_temp_new();
862             TCGv t1 = tcg_temp_new();
863             TCGv t2 = tcg_temp_new();
864
865             tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
866
867             /* positive case: shift to the left */
868             tcg_gen_shl_i32(t1, REG(B11_8), t0);
869
870             /* negative case: shift to the right in two steps to
871                correctly handle the -32 case */
872             tcg_gen_xori_i32(t0, t0, 0x1f);
873             tcg_gen_shr_i32(t2, REG(B11_8), t0);
874             tcg_gen_shri_i32(t2, t2, 1);
875
876             /* select between the two cases */
877             tcg_gen_movi_i32(t0, 0);
878             tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
879
880             tcg_temp_free(t0);
881             tcg_temp_free(t1);
882             tcg_temp_free(t2);
883         }
884         return;
885     case 0x3008:                /* sub Rm,Rn */
886         tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));
887         return;
888     case 0x300a:                /* subc Rm,Rn */
889         {
890             TCGv t0, t1;
891             t0 = tcg_const_tl(0);
892             t1 = tcg_temp_new();
893             tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0);
894             tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t,
895                              REG(B11_8), t0, t1, cpu_sr_t);
896             tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
897             tcg_temp_free(t0);
898             tcg_temp_free(t1);
899         }
900         return;
901     case 0x300b:                /* subv Rm,Rn */
902         {
903             TCGv t0, t1, t2;
904             t0 = tcg_temp_new();
905             tcg_gen_sub_i32(t0, REG(B11_8), REG(B7_4));
906             t1 = tcg_temp_new();
907             tcg_gen_xor_i32(t1, t0, REG(B7_4));
908             t2 = tcg_temp_new();
909             tcg_gen_xor_i32(t2, REG(B11_8), REG(B7_4));
910             tcg_gen_and_i32(t1, t1, t2);
911             tcg_temp_free(t2);
912             tcg_gen_shri_i32(cpu_sr_t, t1, 31);
913             tcg_temp_free(t1);
914             tcg_gen_mov_i32(REG(B11_8), t0);
915             tcg_temp_free(t0);
916         }
917         return;
918     case 0x2008:                /* tst Rm,Rn */
919         {
920             TCGv val = tcg_temp_new();
921             tcg_gen_and_i32(val, REG(B7_4), REG(B11_8));
922             tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
923             tcg_temp_free(val);
924         }
925         return;
926     case 0x200a:                /* xor Rm,Rn */
927         tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));
928         return;
929     case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
930         CHECK_FPU_ENABLED
931         if (ctx->flags & FPSCR_SZ) {
932             TCGv_i64 fp = tcg_temp_new_i64();
933             gen_load_fpr64(fp, XREG(B7_4));
934             gen_store_fpr64(fp, XREG(B11_8));
935             tcg_temp_free_i64(fp);
936         } else {
937             tcg_gen_mov_i32(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
938         }
939         return;
940     case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
941         CHECK_FPU_ENABLED
942         if (ctx->flags & FPSCR_SZ) {
943             TCGv addr_hi = tcg_temp_new();
944             int fr = XREG(B7_4);
945             tcg_gen_addi_i32(addr_hi, REG(B11_8), 4);
946             tcg_gen_qemu_st_i32(cpu_fregs[fr], REG(B11_8),
947                                 ctx->memidx, MO_TEUL);
948             tcg_gen_qemu_st_i32(cpu_fregs[fr+1], addr_hi,
949                                 ctx->memidx, MO_TEUL);
950             tcg_temp_free(addr_hi);
951         } else {
952             tcg_gen_qemu_st_i32(cpu_fregs[FREG(B7_4)], REG(B11_8),
953                                 ctx->memidx, MO_TEUL);
954         }
955         return;
956     case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
957         CHECK_FPU_ENABLED
958         if (ctx->flags & FPSCR_SZ) {
959             TCGv addr_hi = tcg_temp_new();
960             int fr = XREG(B11_8);
961             tcg_gen_addi_i32(addr_hi, REG(B7_4), 4);
962             tcg_gen_qemu_ld_i32(cpu_fregs[fr], REG(B7_4), ctx->memidx, MO_TEUL);
963             tcg_gen_qemu_ld_i32(cpu_fregs[fr+1], addr_hi, ctx->memidx, MO_TEUL);
964             tcg_temp_free(addr_hi);
965         } else {
966             tcg_gen_qemu_ld_i32(cpu_fregs[FREG(B11_8)], REG(B7_4),
967                                 ctx->memidx, MO_TEUL);
968         }
969         return;
970     case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
971         CHECK_FPU_ENABLED
972         if (ctx->flags & FPSCR_SZ) {
973             TCGv addr_hi = tcg_temp_new();
974             int fr = XREG(B11_8);
975             tcg_gen_addi_i32(addr_hi, REG(B7_4), 4);
976             tcg_gen_qemu_ld_i32(cpu_fregs[fr], REG(B7_4), ctx->memidx, MO_TEUL);
977             tcg_gen_qemu_ld_i32(cpu_fregs[fr+1], addr_hi, ctx->memidx, MO_TEUL);
978             tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 8);
979             tcg_temp_free(addr_hi);
980         } else {
981             tcg_gen_qemu_ld_i32(cpu_fregs[FREG(B11_8)], REG(B7_4),
982                                 ctx->memidx, MO_TEUL);
983             tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
984         }
985         return;
986     case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
987         CHECK_FPU_ENABLED
988         TCGv addr = tcg_temp_new_i32();
989         tcg_gen_subi_i32(addr, REG(B11_8), 4);
990         if (ctx->flags & FPSCR_SZ) {
991             int fr = XREG(B7_4);
992             tcg_gen_qemu_st_i32(cpu_fregs[fr+1], addr, ctx->memidx, MO_TEUL);
993             tcg_gen_subi_i32(addr, addr, 4);
994             tcg_gen_qemu_st_i32(cpu_fregs[fr], addr, ctx->memidx, MO_TEUL);
995         } else {
996             tcg_gen_qemu_st_i32(cpu_fregs[FREG(B7_4)], addr,
997                                 ctx->memidx, MO_TEUL);
998         }
999         tcg_gen_mov_i32(REG(B11_8), addr);
1000         tcg_temp_free(addr);
1001         return;
1002     case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
1003         CHECK_FPU_ENABLED
1004         {
1005             TCGv addr = tcg_temp_new_i32();
1006             tcg_gen_add_i32(addr, REG(B7_4), REG(0));
1007             if (ctx->flags & FPSCR_SZ) {
1008                 int fr = XREG(B11_8);
1009                 tcg_gen_qemu_ld_i32(cpu_fregs[fr], addr,
1010                                     ctx->memidx, MO_TEUL);
1011                 tcg_gen_addi_i32(addr, addr, 4);
1012                 tcg_gen_qemu_ld_i32(cpu_fregs[fr+1], addr,
1013                                     ctx->memidx, MO_TEUL);
1014             } else {
1015                 tcg_gen_qemu_ld_i32(cpu_fregs[FREG(B11_8)], addr,
1016                                     ctx->memidx, MO_TEUL);
1017             }
1018             tcg_temp_free(addr);
1019         }
1020         return;
1021     case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
1022         CHECK_FPU_ENABLED
1023         {
1024             TCGv addr = tcg_temp_new();
1025             tcg_gen_add_i32(addr, REG(B11_8), REG(0));
1026             if (ctx->flags & FPSCR_SZ) {
1027                 int fr = XREG(B7_4);
1028                 tcg_gen_qemu_ld_i32(cpu_fregs[fr], addr,
1029                                     ctx->memidx, MO_TEUL);
1030                 tcg_gen_addi_i32(addr, addr, 4);
1031                 tcg_gen_qemu_ld_i32(cpu_fregs[fr+1], addr,
1032                                     ctx->memidx, MO_TEUL);
1033             } else {
1034                 tcg_gen_qemu_st_i32(cpu_fregs[FREG(B7_4)], addr,
1035                                     ctx->memidx, MO_TEUL);
1036             }
1037             tcg_temp_free(addr);
1038         }
1039         return;
1040     case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1041     case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1042     case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1043     case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1044     case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1045     case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1046         {
1047             CHECK_FPU_ENABLED
1048             if (ctx->flags & FPSCR_PR) {
1049                 TCGv_i64 fp0, fp1;
1050
1051                 if (ctx->opcode & 0x0110)
1052                     break; /* illegal instruction */
1053                 fp0 = tcg_temp_new_i64();
1054                 fp1 = tcg_temp_new_i64();
1055                 gen_load_fpr64(fp0, DREG(B11_8));
1056                 gen_load_fpr64(fp1, DREG(B7_4));
1057                 switch (ctx->opcode & 0xf00f) {
1058                 case 0xf000:            /* fadd Rm,Rn */
1059                     gen_helper_fadd_DT(fp0, cpu_env, fp0, fp1);
1060                     break;
1061                 case 0xf001:            /* fsub Rm,Rn */
1062                     gen_helper_fsub_DT(fp0, cpu_env, fp0, fp1);
1063                     break;
1064                 case 0xf002:            /* fmul Rm,Rn */
1065                     gen_helper_fmul_DT(fp0, cpu_env, fp0, fp1);
1066                     break;
1067                 case 0xf003:            /* fdiv Rm,Rn */
1068                     gen_helper_fdiv_DT(fp0, cpu_env, fp0, fp1);
1069                     break;
1070                 case 0xf004:            /* fcmp/eq Rm,Rn */
1071                     gen_helper_fcmp_eq_DT(cpu_env, fp0, fp1);
1072                     return;
1073                 case 0xf005:            /* fcmp/gt Rm,Rn */
1074                     gen_helper_fcmp_gt_DT(cpu_env, fp0, fp1);
1075                     return;
1076                 }
1077                 gen_store_fpr64(fp0, DREG(B11_8));
1078                 tcg_temp_free_i64(fp0);
1079                 tcg_temp_free_i64(fp1);
1080             } else {
1081                 switch (ctx->opcode & 0xf00f) {
1082                 case 0xf000:            /* fadd Rm,Rn */
1083                     gen_helper_fadd_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1084                                        cpu_fregs[FREG(B11_8)],
1085                                        cpu_fregs[FREG(B7_4)]);
1086                     break;
1087                 case 0xf001:            /* fsub Rm,Rn */
1088                     gen_helper_fsub_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1089                                        cpu_fregs[FREG(B11_8)],
1090                                        cpu_fregs[FREG(B7_4)]);
1091                     break;
1092                 case 0xf002:            /* fmul Rm,Rn */
1093                     gen_helper_fmul_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1094                                        cpu_fregs[FREG(B11_8)],
1095                                        cpu_fregs[FREG(B7_4)]);
1096                     break;
1097                 case 0xf003:            /* fdiv Rm,Rn */
1098                     gen_helper_fdiv_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1099                                        cpu_fregs[FREG(B11_8)],
1100                                        cpu_fregs[FREG(B7_4)]);
1101                     break;
1102                 case 0xf004:            /* fcmp/eq Rm,Rn */
1103                     gen_helper_fcmp_eq_FT(cpu_env, cpu_fregs[FREG(B11_8)],
1104                                           cpu_fregs[FREG(B7_4)]);
1105                     return;
1106                 case 0xf005:            /* fcmp/gt Rm,Rn */
1107                     gen_helper_fcmp_gt_FT(cpu_env, cpu_fregs[FREG(B11_8)],
1108                                           cpu_fregs[FREG(B7_4)]);
1109                     return;
1110                 }
1111             }
1112         }
1113         return;
1114     case 0xf00e: /* fmac FR0,RM,Rn */
1115         {
1116             CHECK_FPU_ENABLED
1117             if (ctx->flags & FPSCR_PR) {
1118                 break; /* illegal instruction */
1119             } else {
1120                 gen_helper_fmac_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1121                                    cpu_fregs[FREG(0)], cpu_fregs[FREG(B7_4)],
1122                                    cpu_fregs[FREG(B11_8)]);
1123                 return;
1124             }
1125         }
1126     }
1127
1128     switch (ctx->opcode & 0xff00) {
1129     case 0xc900:                /* and #imm,R0 */
1130         tcg_gen_andi_i32(REG(0), REG(0), B7_0);
1131         return;
1132     case 0xcd00:                /* and.b #imm,@(R0,GBR) */
1133         {
1134             TCGv addr, val;
1135             addr = tcg_temp_new();
1136             tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1137             val = tcg_temp_new();
1138             tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1139             tcg_gen_andi_i32(val, val, B7_0);
1140             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1141             tcg_temp_free(val);
1142             tcg_temp_free(addr);
1143         }
1144         return;
1145     case 0x8b00:                /* bf label */
1146         CHECK_NOT_DELAY_SLOT
1147             gen_conditional_jump(ctx, ctx->pc + 2,
1148                                  ctx->pc + 4 + B7_0s * 2);
1149         ctx->bstate = BS_BRANCH;
1150         return;
1151     case 0x8f00:                /* bf/s label */
1152         CHECK_NOT_DELAY_SLOT
1153         gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);
1154         ctx->flags |= DELAY_SLOT_CONDITIONAL;
1155         return;
1156     case 0x8900:                /* bt label */
1157         CHECK_NOT_DELAY_SLOT
1158             gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
1159                                  ctx->pc + 2);
1160         ctx->bstate = BS_BRANCH;
1161         return;
1162     case 0x8d00:                /* bt/s label */
1163         CHECK_NOT_DELAY_SLOT
1164         gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);
1165         ctx->flags |= DELAY_SLOT_CONDITIONAL;
1166         return;
1167     case 0x8800:                /* cmp/eq #imm,R0 */
1168         tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, REG(0), B7_0s);
1169         return;
1170     case 0xc400:                /* mov.b @(disp,GBR),R0 */
1171         {
1172             TCGv addr = tcg_temp_new();
1173             tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1174             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_SB);
1175             tcg_temp_free(addr);
1176         }
1177         return;
1178     case 0xc500:                /* mov.w @(disp,GBR),R0 */
1179         {
1180             TCGv addr = tcg_temp_new();
1181             tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1182             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESW);
1183             tcg_temp_free(addr);
1184         }
1185         return;
1186     case 0xc600:                /* mov.l @(disp,GBR),R0 */
1187         {
1188             TCGv addr = tcg_temp_new();
1189             tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1190             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESL);
1191             tcg_temp_free(addr);
1192         }
1193         return;
1194     case 0xc000:                /* mov.b R0,@(disp,GBR) */
1195         {
1196             TCGv addr = tcg_temp_new();
1197             tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1198             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_UB);
1199             tcg_temp_free(addr);
1200         }
1201         return;
1202     case 0xc100:                /* mov.w R0,@(disp,GBR) */
1203         {
1204             TCGv addr = tcg_temp_new();
1205             tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1206             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUW);
1207             tcg_temp_free(addr);
1208         }
1209         return;
1210     case 0xc200:                /* mov.l R0,@(disp,GBR) */
1211         {
1212             TCGv addr = tcg_temp_new();
1213             tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1214             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUL);
1215             tcg_temp_free(addr);
1216         }
1217         return;
1218     case 0x8000:                /* mov.b R0,@(disp,Rn) */
1219         {
1220             TCGv addr = tcg_temp_new();
1221             tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1222             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_UB);
1223             tcg_temp_free(addr);
1224         }
1225         return;
1226     case 0x8100:                /* mov.w R0,@(disp,Rn) */
1227         {
1228             TCGv addr = tcg_temp_new();
1229             tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1230             tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUW);
1231             tcg_temp_free(addr);
1232         }
1233         return;
1234     case 0x8400:                /* mov.b @(disp,Rn),R0 */
1235         {
1236             TCGv addr = tcg_temp_new();
1237             tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1238             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_SB);
1239             tcg_temp_free(addr);
1240         }
1241         return;
1242     case 0x8500:                /* mov.w @(disp,Rn),R0 */
1243         {
1244             TCGv addr = tcg_temp_new();
1245             tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1246             tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESW);
1247             tcg_temp_free(addr);
1248         }
1249         return;
1250     case 0xc700:                /* mova @(disp,PC),R0 */
1251         tcg_gen_movi_i32(REG(0), ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
1252         return;
1253     case 0xcb00:                /* or #imm,R0 */
1254         tcg_gen_ori_i32(REG(0), REG(0), B7_0);
1255         return;
1256     case 0xcf00:                /* or.b #imm,@(R0,GBR) */
1257         {
1258             TCGv addr, val;
1259             addr = tcg_temp_new();
1260             tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1261             val = tcg_temp_new();
1262             tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1263             tcg_gen_ori_i32(val, val, B7_0);
1264             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1265             tcg_temp_free(val);
1266             tcg_temp_free(addr);
1267         }
1268         return;
1269     case 0xc300:                /* trapa #imm */
1270         {
1271             TCGv imm;
1272             CHECK_NOT_DELAY_SLOT
1273             tcg_gen_movi_i32(cpu_pc, ctx->pc);
1274             imm = tcg_const_i32(B7_0);
1275             gen_helper_trapa(cpu_env, imm);
1276             tcg_temp_free(imm);
1277             ctx->bstate = BS_BRANCH;
1278         }
1279         return;
1280     case 0xc800:                /* tst #imm,R0 */
1281         {
1282             TCGv val = tcg_temp_new();
1283             tcg_gen_andi_i32(val, REG(0), B7_0);
1284             tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1285             tcg_temp_free(val);
1286         }
1287         return;
1288     case 0xcc00:                /* tst.b #imm,@(R0,GBR) */
1289         {
1290             TCGv val = tcg_temp_new();
1291             tcg_gen_add_i32(val, REG(0), cpu_gbr);
1292             tcg_gen_qemu_ld_i32(val, val, ctx->memidx, MO_UB);
1293             tcg_gen_andi_i32(val, val, B7_0);
1294             tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1295             tcg_temp_free(val);
1296         }
1297         return;
1298     case 0xca00:                /* xor #imm,R0 */
1299         tcg_gen_xori_i32(REG(0), REG(0), B7_0);
1300         return;
1301     case 0xce00:                /* xor.b #imm,@(R0,GBR) */
1302         {
1303             TCGv addr, val;
1304             addr = tcg_temp_new();
1305             tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1306             val = tcg_temp_new();
1307             tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1308             tcg_gen_xori_i32(val, val, B7_0);
1309             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1310             tcg_temp_free(val);
1311             tcg_temp_free(addr);
1312         }
1313         return;
1314     }
1315
1316     switch (ctx->opcode & 0xf08f) {
1317     case 0x408e:                /* ldc Rm,Rn_BANK */
1318         CHECK_PRIVILEGED
1319         tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
1320         return;
1321     case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
1322         CHECK_PRIVILEGED
1323         tcg_gen_qemu_ld_i32(ALTREG(B6_4), REG(B11_8), ctx->memidx, MO_TESL);
1324         tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1325         return;
1326     case 0x0082:                /* stc Rm_BANK,Rn */
1327         CHECK_PRIVILEGED
1328         tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
1329         return;
1330     case 0x4083:                /* stc.l Rm_BANK,@-Rn */
1331         CHECK_PRIVILEGED
1332         {
1333             TCGv addr = tcg_temp_new();
1334             tcg_gen_subi_i32(addr, REG(B11_8), 4);
1335             tcg_gen_qemu_st_i32(ALTREG(B6_4), addr, ctx->memidx, MO_TEUL);
1336             tcg_gen_mov_i32(REG(B11_8), addr);
1337             tcg_temp_free(addr);
1338         }
1339         return;
1340     }
1341
1342     switch (ctx->opcode & 0xf0ff) {
1343     case 0x0023:                /* braf Rn */
1344         CHECK_NOT_DELAY_SLOT
1345         tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->pc + 4);
1346         ctx->flags |= DELAY_SLOT;
1347         ctx->delayed_pc = (uint32_t) - 1;
1348         return;
1349     case 0x0003:                /* bsrf Rn */
1350         CHECK_NOT_DELAY_SLOT
1351         tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1352         tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);
1353         ctx->flags |= DELAY_SLOT;
1354         ctx->delayed_pc = (uint32_t) - 1;
1355         return;
1356     case 0x4015:                /* cmp/pl Rn */
1357         tcg_gen_setcondi_i32(TCG_COND_GT, cpu_sr_t, REG(B11_8), 0);
1358         return;
1359     case 0x4011:                /* cmp/pz Rn */
1360         tcg_gen_setcondi_i32(TCG_COND_GE, cpu_sr_t, REG(B11_8), 0);
1361         return;
1362     case 0x4010:                /* dt Rn */
1363         tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);
1364         tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, REG(B11_8), 0);
1365         return;
1366     case 0x402b:                /* jmp @Rn */
1367         CHECK_NOT_DELAY_SLOT
1368         tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1369         ctx->flags |= DELAY_SLOT;
1370         ctx->delayed_pc = (uint32_t) - 1;
1371         return;
1372     case 0x400b:                /* jsr @Rn */
1373         CHECK_NOT_DELAY_SLOT
1374         tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1375         tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1376         ctx->flags |= DELAY_SLOT;
1377         ctx->delayed_pc = (uint32_t) - 1;
1378         return;
1379     case 0x400e:                /* ldc Rm,SR */
1380         CHECK_PRIVILEGED
1381         {
1382             TCGv val = tcg_temp_new();
1383             tcg_gen_andi_i32(val, REG(B11_8), 0x700083f3);
1384             gen_write_sr(val);
1385             tcg_temp_free(val);
1386             ctx->bstate = BS_STOP;
1387         }
1388         return;
1389     case 0x4007:                /* ldc.l @Rm+,SR */
1390         CHECK_PRIVILEGED
1391         {
1392             TCGv val = tcg_temp_new();
1393             tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_TESL);
1394             tcg_gen_andi_i32(val, val, 0x700083f3);
1395             gen_write_sr(val);
1396             tcg_temp_free(val);
1397             tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1398             ctx->bstate = BS_STOP;
1399         }
1400         return;
1401     case 0x0002:                /* stc SR,Rn */
1402         CHECK_PRIVILEGED
1403         gen_read_sr(REG(B11_8));
1404         return;
1405     case 0x4003:                /* stc SR,@-Rn */
1406         CHECK_PRIVILEGED
1407         {
1408             TCGv addr = tcg_temp_new();
1409             TCGv val = tcg_temp_new();
1410             tcg_gen_subi_i32(addr, REG(B11_8), 4);
1411             gen_read_sr(val);
1412             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_TEUL);
1413             tcg_gen_mov_i32(REG(B11_8), addr);
1414             tcg_temp_free(val);
1415             tcg_temp_free(addr);
1416         }
1417         return;
1418 #define LD(reg,ldnum,ldpnum,prechk)             \
1419   case ldnum:                                                   \
1420     prechk                                                      \
1421     tcg_gen_mov_i32 (cpu_##reg, REG(B11_8));                    \
1422     return;                                                     \
1423   case ldpnum:                                                  \
1424     prechk                                                      \
1425     tcg_gen_qemu_ld_i32(cpu_##reg, REG(B11_8), ctx->memidx, MO_TESL); \
1426     tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);                \
1427     return;
1428 #define ST(reg,stnum,stpnum,prechk)             \
1429   case stnum:                                                   \
1430     prechk                                                      \
1431     tcg_gen_mov_i32 (REG(B11_8), cpu_##reg);                    \
1432     return;                                                     \
1433   case stpnum:                                                  \
1434     prechk                                                      \
1435     {                                                           \
1436         TCGv addr = tcg_temp_new();                             \
1437         tcg_gen_subi_i32(addr, REG(B11_8), 4);                  \
1438         tcg_gen_qemu_st_i32(cpu_##reg, addr, ctx->memidx, MO_TEUL); \
1439         tcg_gen_mov_i32(REG(B11_8), addr);                      \
1440         tcg_temp_free(addr);                                    \
1441     }                                                           \
1442     return;
1443 #define LDST(reg,ldnum,ldpnum,stnum,stpnum,prechk)              \
1444         LD(reg,ldnum,ldpnum,prechk)                             \
1445         ST(reg,stnum,stpnum,prechk)
1446         LDST(gbr,  0x401e, 0x4017, 0x0012, 0x4013, {})
1447         LDST(vbr,  0x402e, 0x4027, 0x0022, 0x4023, CHECK_PRIVILEGED)
1448         LDST(ssr,  0x403e, 0x4037, 0x0032, 0x4033, CHECK_PRIVILEGED)
1449         LDST(spc,  0x404e, 0x4047, 0x0042, 0x4043, CHECK_PRIVILEGED)
1450         ST(sgr,  0x003a, 0x4032, CHECK_PRIVILEGED)
1451         LD(sgr,  0x403a, 0x4036, CHECK_PRIVILEGED if (!(ctx->features & SH_FEATURE_SH4A)) break;)
1452         LDST(dbr,  0x40fa, 0x40f6, 0x00fa, 0x40f2, CHECK_PRIVILEGED)
1453         LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002, {})
1454         LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012, {})
1455         LDST(pr,   0x402a, 0x4026, 0x002a, 0x4022, {})
1456         LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052, {CHECK_FPU_ENABLED})
1457     case 0x406a:                /* lds Rm,FPSCR */
1458         CHECK_FPU_ENABLED
1459         gen_helper_ld_fpscr(cpu_env, REG(B11_8));
1460         ctx->bstate = BS_STOP;
1461         return;
1462     case 0x4066:                /* lds.l @Rm+,FPSCR */
1463         CHECK_FPU_ENABLED
1464         {
1465             TCGv addr = tcg_temp_new();
1466             tcg_gen_qemu_ld_i32(addr, REG(B11_8), ctx->memidx, MO_TESL);
1467             tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1468             gen_helper_ld_fpscr(cpu_env, addr);
1469             tcg_temp_free(addr);
1470             ctx->bstate = BS_STOP;
1471         }
1472         return;
1473     case 0x006a:                /* sts FPSCR,Rn */
1474         CHECK_FPU_ENABLED
1475         tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);
1476         return;
1477     case 0x4062:                /* sts FPSCR,@-Rn */
1478         CHECK_FPU_ENABLED
1479         {
1480             TCGv addr, val;
1481             val = tcg_temp_new();
1482             tcg_gen_andi_i32(val, cpu_fpscr, 0x003fffff);
1483             addr = tcg_temp_new();
1484             tcg_gen_subi_i32(addr, REG(B11_8), 4);
1485             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_TEUL);
1486             tcg_gen_mov_i32(REG(B11_8), addr);
1487             tcg_temp_free(addr);
1488             tcg_temp_free(val);
1489         }
1490         return;
1491     case 0x00c3:                /* movca.l R0,@Rm */
1492         {
1493             TCGv val = tcg_temp_new();
1494             tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_TEUL);
1495             gen_helper_movcal(cpu_env, REG(B11_8), val);
1496             tcg_gen_qemu_st_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1497         }
1498         ctx->has_movcal = 1;
1499         return;
1500     case 0x40a9:
1501         /* MOVUA.L @Rm,R0 (Rm) -> R0
1502            Load non-boundary-aligned data */
1503         tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1504         return;
1505     case 0x40e9:
1506         /* MOVUA.L @Rm+,R0   (Rm) -> R0, Rm + 4 -> Rm
1507            Load non-boundary-aligned data */
1508         tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1509         tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1510         return;
1511     case 0x0029:                /* movt Rn */
1512         tcg_gen_mov_i32(REG(B11_8), cpu_sr_t);
1513         return;
1514     case 0x0073:
1515         /* MOVCO.L
1516                LDST -> T
1517                If (T == 1) R0 -> (Rn)
1518                0 -> LDST
1519         */
1520         if (ctx->features & SH_FEATURE_SH4A) {
1521             TCGLabel *label = gen_new_label();
1522             tcg_gen_mov_i32(cpu_sr_t, cpu_ldst);
1523             tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ldst, 0, label);
1524             tcg_gen_qemu_st_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1525             gen_set_label(label);
1526             tcg_gen_movi_i32(cpu_ldst, 0);
1527             return;
1528         } else
1529             break;
1530     case 0x0063:
1531         /* MOVLI.L @Rm,R0
1532                1 -> LDST
1533                (Rm) -> R0
1534                When interrupt/exception
1535                occurred 0 -> LDST
1536         */
1537         if (ctx->features & SH_FEATURE_SH4A) {
1538             tcg_gen_movi_i32(cpu_ldst, 0);
1539             tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TESL);
1540             tcg_gen_movi_i32(cpu_ldst, 1);
1541             return;
1542         } else
1543             break;
1544     case 0x0093:                /* ocbi @Rn */
1545         {
1546             gen_helper_ocbi(cpu_env, REG(B11_8));
1547         }
1548         return;
1549     case 0x00a3:                /* ocbp @Rn */
1550     case 0x00b3:                /* ocbwb @Rn */
1551         /* These instructions are supposed to do nothing in case of
1552            a cache miss. Given that we only partially emulate caches
1553            it is safe to simply ignore them. */
1554         return;
1555     case 0x0083:                /* pref @Rn */
1556         return;
1557     case 0x00d3:                /* prefi @Rn */
1558         if (ctx->features & SH_FEATURE_SH4A)
1559             return;
1560         else
1561             break;
1562     case 0x00e3:                /* icbi @Rn */
1563         if (ctx->features & SH_FEATURE_SH4A)
1564             return;
1565         else
1566             break;
1567     case 0x00ab:                /* synco */
1568         if (ctx->features & SH_FEATURE_SH4A)
1569             return;
1570         else
1571             break;
1572     case 0x4024:                /* rotcl Rn */
1573         {
1574             TCGv tmp = tcg_temp_new();
1575             tcg_gen_mov_i32(tmp, cpu_sr_t);
1576             tcg_gen_shri_i32(cpu_sr_t, REG(B11_8), 31);
1577             tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1578             tcg_gen_or_i32(REG(B11_8), REG(B11_8), tmp);
1579             tcg_temp_free(tmp);
1580         }
1581         return;
1582     case 0x4025:                /* rotcr Rn */
1583         {
1584             TCGv tmp = tcg_temp_new();
1585             tcg_gen_shli_i32(tmp, cpu_sr_t, 31);
1586             tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1587             tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1588             tcg_gen_or_i32(REG(B11_8), REG(B11_8), tmp);
1589             tcg_temp_free(tmp);
1590         }
1591         return;
1592     case 0x4004:                /* rotl Rn */
1593         tcg_gen_rotli_i32(REG(B11_8), REG(B11_8), 1);
1594         tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 0);
1595         return;
1596     case 0x4005:                /* rotr Rn */
1597         tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 0);
1598         tcg_gen_rotri_i32(REG(B11_8), REG(B11_8), 1);
1599         return;
1600     case 0x4000:                /* shll Rn */
1601     case 0x4020:                /* shal Rn */
1602         tcg_gen_shri_i32(cpu_sr_t, REG(B11_8), 31);
1603         tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1604         return;
1605     case 0x4021:                /* shar Rn */
1606         tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1607         tcg_gen_sari_i32(REG(B11_8), REG(B11_8), 1);
1608         return;
1609     case 0x4001:                /* shlr Rn */
1610         tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1611         tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1612         return;
1613     case 0x4008:                /* shll2 Rn */
1614         tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 2);
1615         return;
1616     case 0x4018:                /* shll8 Rn */
1617         tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 8);
1618         return;
1619     case 0x4028:                /* shll16 Rn */
1620         tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 16);
1621         return;
1622     case 0x4009:                /* shlr2 Rn */
1623         tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 2);
1624         return;
1625     case 0x4019:                /* shlr8 Rn */
1626         tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 8);
1627         return;
1628     case 0x4029:                /* shlr16 Rn */
1629         tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16);
1630         return;
1631     case 0x401b:                /* tas.b @Rn */
1632         {
1633             TCGv addr, val;
1634             addr = tcg_temp_local_new();
1635             tcg_gen_mov_i32(addr, REG(B11_8));
1636             val = tcg_temp_local_new();
1637             tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1638             tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1639             tcg_gen_ori_i32(val, val, 0x80);
1640             tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1641             tcg_temp_free(val);
1642             tcg_temp_free(addr);
1643         }
1644         return;
1645     case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1646         CHECK_FPU_ENABLED
1647         tcg_gen_mov_i32(cpu_fregs[FREG(B11_8)], cpu_fpul);
1648         return;
1649     case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1650         CHECK_FPU_ENABLED
1651         tcg_gen_mov_i32(cpu_fpul, cpu_fregs[FREG(B11_8)]);
1652         return;
1653     case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1654         CHECK_FPU_ENABLED
1655         if (ctx->flags & FPSCR_PR) {
1656             TCGv_i64 fp;
1657             if (ctx->opcode & 0x0100)
1658                 break; /* illegal instruction */
1659             fp = tcg_temp_new_i64();
1660             gen_helper_float_DT(fp, cpu_env, cpu_fpul);
1661             gen_store_fpr64(fp, DREG(B11_8));
1662             tcg_temp_free_i64(fp);
1663         }
1664         else {
1665             gen_helper_float_FT(cpu_fregs[FREG(B11_8)], cpu_env, cpu_fpul);
1666         }
1667         return;
1668     case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1669         CHECK_FPU_ENABLED
1670         if (ctx->flags & FPSCR_PR) {
1671             TCGv_i64 fp;
1672             if (ctx->opcode & 0x0100)
1673                 break; /* illegal instruction */
1674             fp = tcg_temp_new_i64();
1675             gen_load_fpr64(fp, DREG(B11_8));
1676             gen_helper_ftrc_DT(cpu_fpul, cpu_env, fp);
1677             tcg_temp_free_i64(fp);
1678         }
1679         else {
1680             gen_helper_ftrc_FT(cpu_fpul, cpu_env, cpu_fregs[FREG(B11_8)]);
1681         }
1682         return;
1683     case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1684         CHECK_FPU_ENABLED
1685         {
1686             gen_helper_fneg_T(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
1687         }
1688         return;
1689     case 0xf05d: /* fabs FRn/DRn */
1690         CHECK_FPU_ENABLED
1691         if (ctx->flags & FPSCR_PR) {
1692             if (ctx->opcode & 0x0100)
1693                 break; /* illegal instruction */
1694             TCGv_i64 fp = tcg_temp_new_i64();
1695             gen_load_fpr64(fp, DREG(B11_8));
1696             gen_helper_fabs_DT(fp, fp);
1697             gen_store_fpr64(fp, DREG(B11_8));
1698             tcg_temp_free_i64(fp);
1699         } else {
1700             gen_helper_fabs_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
1701         }
1702         return;
1703     case 0xf06d: /* fsqrt FRn */
1704         CHECK_FPU_ENABLED
1705         if (ctx->flags & FPSCR_PR) {
1706             if (ctx->opcode & 0x0100)
1707                 break; /* illegal instruction */
1708             TCGv_i64 fp = tcg_temp_new_i64();
1709             gen_load_fpr64(fp, DREG(B11_8));
1710             gen_helper_fsqrt_DT(fp, cpu_env, fp);
1711             gen_store_fpr64(fp, DREG(B11_8));
1712             tcg_temp_free_i64(fp);
1713         } else {
1714             gen_helper_fsqrt_FT(cpu_fregs[FREG(B11_8)], cpu_env,
1715                                 cpu_fregs[FREG(B11_8)]);
1716         }
1717         return;
1718     case 0xf07d: /* fsrra FRn */
1719         CHECK_FPU_ENABLED
1720         break;
1721     case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1722         CHECK_FPU_ENABLED
1723         if (!(ctx->flags & FPSCR_PR)) {
1724             tcg_gen_movi_i32(cpu_fregs[FREG(B11_8)], 0);
1725         }
1726         return;
1727     case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1728         CHECK_FPU_ENABLED
1729         if (!(ctx->flags & FPSCR_PR)) {
1730             tcg_gen_movi_i32(cpu_fregs[FREG(B11_8)], 0x3f800000);
1731         }
1732         return;
1733     case 0xf0ad: /* fcnvsd FPUL,DRn */
1734         CHECK_FPU_ENABLED
1735         {
1736             TCGv_i64 fp = tcg_temp_new_i64();
1737             gen_helper_fcnvsd_FT_DT(fp, cpu_env, cpu_fpul);
1738             gen_store_fpr64(fp, DREG(B11_8));
1739             tcg_temp_free_i64(fp);
1740         }
1741         return;
1742     case 0xf0bd: /* fcnvds DRn,FPUL */
1743         CHECK_FPU_ENABLED
1744         {
1745             TCGv_i64 fp = tcg_temp_new_i64();
1746             gen_load_fpr64(fp, DREG(B11_8));
1747             gen_helper_fcnvds_DT_FT(cpu_fpul, cpu_env, fp);
1748             tcg_temp_free_i64(fp);
1749         }
1750         return;
1751     case 0xf0ed: /* fipr FVm,FVn */
1752         CHECK_FPU_ENABLED
1753         if ((ctx->flags & FPSCR_PR) == 0) {
1754             TCGv m, n;
1755             m = tcg_const_i32((ctx->opcode >> 8) & 3);
1756             n = tcg_const_i32((ctx->opcode >> 10) & 3);
1757             gen_helper_fipr(cpu_env, m, n);
1758             tcg_temp_free(m);
1759             tcg_temp_free(n);
1760             return;
1761         }
1762         break;
1763     case 0xf0fd: /* ftrv XMTRX,FVn */
1764         CHECK_FPU_ENABLED
1765         if ((ctx->opcode & 0x0300) == 0x0100 &&
1766             (ctx->flags & FPSCR_PR) == 0) {
1767             TCGv n;
1768             n = tcg_const_i32((ctx->opcode >> 10) & 3);
1769             gen_helper_ftrv(cpu_env, n);
1770             tcg_temp_free(n);
1771             return;
1772         }
1773         break;
1774     }
1775 #if 0
1776     fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1777             ctx->opcode, ctx->pc);
1778     fflush(stderr);
1779 #endif
1780     tcg_gen_movi_i32(cpu_pc, ctx->pc);
1781     if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1782         gen_helper_raise_slot_illegal_instruction(cpu_env);
1783     } else {
1784         gen_helper_raise_illegal_instruction(cpu_env);
1785     }
1786     ctx->bstate = BS_BRANCH;
1787 }
1788
1789 static void decode_opc(DisasContext * ctx)
1790 {
1791     uint32_t old_flags = ctx->flags;
1792
1793     _decode_opc(ctx);
1794
1795     if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1796         if (ctx->flags & DELAY_SLOT_CLEARME) {
1797             gen_store_flags(0);
1798         } else {
1799             /* go out of the delay slot */
1800             uint32_t new_flags = ctx->flags;
1801             new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1802             gen_store_flags(new_flags);
1803         }
1804         ctx->flags = 0;
1805         ctx->bstate = BS_BRANCH;
1806         if (old_flags & DELAY_SLOT_CONDITIONAL) {
1807             gen_delayed_conditional_jump(ctx);
1808         } else if (old_flags & DELAY_SLOT) {
1809             gen_jump(ctx);
1810         }
1811
1812     }
1813
1814     /* go into a delay slot */
1815     if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1816         gen_store_flags(ctx->flags);
1817 }
1818
1819 void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
1820 {
1821     SuperHCPU *cpu = sh_env_get_cpu(env);
1822     CPUState *cs = CPU(cpu);
1823     DisasContext ctx;
1824     target_ulong pc_start;
1825     int num_insns;
1826     int max_insns;
1827
1828     pc_start = tb->pc;
1829     ctx.pc = pc_start;
1830     ctx.flags = (uint32_t)tb->flags;
1831     ctx.bstate = BS_NONE;
1832     ctx.memidx = (ctx.flags & (1u << SR_MD)) == 0 ? 1 : 0;
1833     /* We don't know if the delayed pc came from a dynamic or static branch,
1834        so assume it is a dynamic branch.  */
1835     ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1836     ctx.tb = tb;
1837     ctx.singlestep_enabled = cs->singlestep_enabled;
1838     ctx.features = env->features;
1839     ctx.has_movcal = (ctx.flags & TB_FLAG_PENDING_MOVCA);
1840
1841     num_insns = 0;
1842     max_insns = tb->cflags & CF_COUNT_MASK;
1843     if (max_insns == 0) {
1844         max_insns = CF_COUNT_MASK;
1845     }
1846     if (max_insns > TCG_MAX_INSNS) {
1847         max_insns = TCG_MAX_INSNS;
1848     }
1849
1850     gen_tb_start(tb);
1851     while (ctx.bstate == BS_NONE && !tcg_op_buf_full()) {
1852         tcg_gen_insn_start(ctx.pc, ctx.flags);
1853         num_insns++;
1854
1855         if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
1856             /* We have hit a breakpoint - make sure PC is up-to-date */
1857             tcg_gen_movi_i32(cpu_pc, ctx.pc);
1858             gen_helper_debug(cpu_env);
1859             ctx.bstate = BS_BRANCH;
1860             /* The address covered by the breakpoint must be included in
1861                [tb->pc, tb->pc + tb->size) in order to for it to be
1862                properly cleared -- thus we increment the PC here so that
1863                the logic setting tb->size below does the right thing.  */
1864             ctx.pc += 2;
1865             break;
1866         }
1867
1868         if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
1869             gen_io_start();
1870         }
1871
1872         ctx.opcode = cpu_lduw_code(env, ctx.pc);
1873         decode_opc(&ctx);
1874         ctx.pc += 2;
1875         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1876             break;
1877         if (cs->singlestep_enabled) {
1878             break;
1879         }
1880         if (num_insns >= max_insns)
1881             break;
1882         if (singlestep)
1883             break;
1884     }
1885     if (tb->cflags & CF_LAST_IO)
1886         gen_io_end();
1887     if (cs->singlestep_enabled) {
1888         tcg_gen_movi_i32(cpu_pc, ctx.pc);
1889         gen_helper_debug(cpu_env);
1890     } else {
1891         switch (ctx.bstate) {
1892         case BS_STOP:
1893             /* gen_op_interrupt_restart(); */
1894             /* fall through */
1895         case BS_NONE:
1896             if (ctx.flags) {
1897                 gen_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1898             }
1899             gen_goto_tb(&ctx, 0, ctx.pc);
1900             break;
1901         case BS_EXCP:
1902             /* gen_op_interrupt_restart(); */
1903             tcg_gen_exit_tb(0);
1904             break;
1905         case BS_BRANCH:
1906         default:
1907             break;
1908         }
1909     }
1910
1911     gen_tb_end(tb, num_insns);
1912
1913     tb->size = ctx.pc - pc_start;
1914     tb->icount = num_insns;
1915
1916 #ifdef DEBUG_DISAS
1917     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1918         qemu_log("IN:\n");      /* , lookup_symbol(pc_start)); */
1919         log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
1920         qemu_log("\n");
1921     }
1922 #endif
1923 }
1924
1925 void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb,
1926                           target_ulong *data)
1927 {
1928     env->pc = data[0];
1929     env->flags = data[1];
1930 }