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