]> git.proxmox.com Git - qemu.git/blame - target-sh4/translate.c
SH4: fix a regression introduced in r5122
[qemu.git] / target-sh4 / translate.c
CommitLineData
fdf9b3e8
FB
1/*
2 * SH4 translation
5fafdf24 3 *
fdf9b3e8
FB
4 * Copyright (c) 2005 Samuel Tardieu
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include <stdarg.h>
21#include <stdlib.h>
22#include <stdio.h>
23#include <string.h>
24#include <inttypes.h>
25#include <assert.h>
26
27#define DEBUG_DISAS
28#define SH4_DEBUG_DISAS
29//#define SH4_SINGLE_STEP
30
31#include "cpu.h"
32#include "exec-all.h"
33#include "disas.h"
988d7eaa 34#include "helper.h"
57fec1fe 35#include "tcg-op.h"
ca10f867 36#include "qemu-common.h"
fdf9b3e8
FB
37
38typedef struct DisasContext {
39 struct TranslationBlock *tb;
40 target_ulong pc;
41 uint32_t sr;
eda9b09b 42 uint32_t fpscr;
fdf9b3e8
FB
43 uint16_t opcode;
44 uint32_t flags;
823029f9 45 int bstate;
fdf9b3e8
FB
46 int memidx;
47 uint32_t delayed_pc;
48 int singlestep_enabled;
49} DisasContext;
50
823029f9
TS
51enum {
52 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
53 * exception condition
54 */
55 BS_STOP = 1, /* We want to stop translation for any reason */
56 BS_BRANCH = 2, /* We reached a branch condition */
57 BS_EXCP = 3, /* We reached an exception condition */
58};
59
1e8864f7
AJ
60/* global register indexes */
61static TCGv cpu_env;
62static TCGv cpu_gregs[24];
3a8a44c4
AJ
63static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
64static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
1000822b
AJ
65static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_flags;
66
67/* internal register indexes */
68static TCGv cpu_flags, cpu_delayed_pc;
1e8864f7 69
2e70f6ef
PB
70#include "gen-icount.h"
71
a5f1b965 72static void sh4_translate_init(void)
2e70f6ef 73{
1e8864f7 74 int i;
2e70f6ef 75 static int done_init = 0;
559dd74d 76 static const char * const gregnames[24] = {
1e8864f7
AJ
77 "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
78 "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
79 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
80 "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
81 "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
82 };
83
2e70f6ef
PB
84 if (done_init)
85 return;
1e8864f7 86
2e70f6ef 87 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
1e8864f7
AJ
88
89 for (i = 0; i < 24; i++)
90 cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
91 offsetof(CPUState, gregs[i]),
92 gregnames[i]);
988d7eaa 93
3a8a44c4
AJ
94 cpu_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
95 offsetof(CPUState, pc), "PC");
96 cpu_sr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
97 offsetof(CPUState, sr), "SR");
98 cpu_ssr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
99 offsetof(CPUState, ssr), "SSR");
100 cpu_spc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
101 offsetof(CPUState, spc), "SPC");
102 cpu_gbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
103 offsetof(CPUState, gbr), "GBR");
104 cpu_vbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
105 offsetof(CPUState, vbr), "VBR");
106 cpu_sgr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
107 offsetof(CPUState, sgr), "SGR");
108 cpu_dbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
109 offsetof(CPUState, dbr), "DBR");
110 cpu_mach = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
111 offsetof(CPUState, mach), "MACH");
112 cpu_macl = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
113 offsetof(CPUState, macl), "MACL");
114 cpu_pr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
115 offsetof(CPUState, pr), "PR");
116 cpu_fpscr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
117 offsetof(CPUState, fpscr), "FPSCR");
118 cpu_fpul = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
119 offsetof(CPUState, fpul), "FPUL");
120
1000822b
AJ
121 cpu_flags = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
122 offsetof(CPUState, flags), "_flags_");
123 cpu_delayed_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
124 offsetof(CPUState, delayed_pc),
125 "_delayed_pc_");
126
988d7eaa
AJ
127 /* register helpers */
128#undef DEF_HELPER
129#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
130#include "helper.h"
131
2e70f6ef
PB
132 done_init = 1;
133}
134
fdf9b3e8
FB
135void cpu_dump_state(CPUState * env, FILE * f,
136 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
137 int flags)
138{
139 int i;
eda9b09b
FB
140 cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
141 env->pc, env->sr, env->pr, env->fpscr);
274a9e70
AJ
142 cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
143 env->spc, env->ssr, env->gbr, env->vbr);
144 cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
145 env->sgr, env->dbr, env->delayed_pc, env->fpul);
fdf9b3e8
FB
146 for (i = 0; i < 24; i += 4) {
147 cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
148 i, env->gregs[i], i + 1, env->gregs[i + 1],
149 i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
150 }
151 if (env->flags & DELAY_SLOT) {
152 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
153 env->delayed_pc);
154 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
155 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
156 env->delayed_pc);
157 }
158}
159
160void cpu_sh4_reset(CPUSH4State * env)
161{
9c2a9ea1 162#if defined(CONFIG_USER_ONLY)
4c909d14 163 env->sr = SR_FD; /* FD - kernel does lazy fpu context switch */
9c2a9ea1 164#else
fdf9b3e8 165 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
9c2a9ea1 166#endif
fdf9b3e8
FB
167 env->vbr = 0;
168 env->pc = 0xA0000000;
ea6cf6be
TS
169#if defined(CONFIG_USER_ONLY)
170 env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
b0b3de89 171 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
ea6cf6be
TS
172#else
173 env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
b0b3de89 174 set_float_rounding_mode(float_round_to_zero, &env->fp_status);
ea6cf6be 175#endif
fdf9b3e8
FB
176 env->mmucr = 0;
177}
178
aaed909a 179CPUSH4State *cpu_sh4_init(const char *cpu_model)
fdf9b3e8
FB
180{
181 CPUSH4State *env;
182
183 env = qemu_mallocz(sizeof(CPUSH4State));
184 if (!env)
185 return NULL;
186 cpu_exec_init(env);
2e70f6ef 187 sh4_translate_init();
fdf9b3e8
FB
188 cpu_sh4_reset(env);
189 tlb_flush(env, 1);
190 return env;
191}
192
fdf9b3e8
FB
193static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
194{
195 TranslationBlock *tb;
196 tb = ctx->tb;
197
198 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
199 !ctx->singlestep_enabled) {
200 /* Use a direct jump if in same page and singlestep not enabled */
57fec1fe 201 tcg_gen_goto_tb(n);
3a8a44c4 202 tcg_gen_movi_i32(cpu_pc, dest);
57fec1fe 203 tcg_gen_exit_tb((long) tb + n);
fdf9b3e8 204 } else {
3a8a44c4 205 tcg_gen_movi_i32(cpu_pc, dest);
57fec1fe 206 if (ctx->singlestep_enabled)
e6afc2f4 207 tcg_gen_helper_0_0(helper_debug);
57fec1fe 208 tcg_gen_exit_tb(0);
fdf9b3e8 209 }
fdf9b3e8
FB
210}
211
fdf9b3e8
FB
212static void gen_jump(DisasContext * ctx)
213{
214 if (ctx->delayed_pc == (uint32_t) - 1) {
215 /* Target is not statically known, it comes necessarily from a
216 delayed jump as immediate jump are conditinal jumps */
1000822b 217 tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
fdf9b3e8 218 if (ctx->singlestep_enabled)
e6afc2f4 219 tcg_gen_helper_0_0(helper_debug);
57fec1fe 220 tcg_gen_exit_tb(0);
fdf9b3e8
FB
221 } else {
222 gen_goto_tb(ctx, 0, ctx->delayed_pc);
223 }
224}
225
1000822b
AJ
226static inline void gen_branch_slot(uint32_t delayed_pc, int t)
227{
c55497ec 228 TCGv sr;
1000822b
AJ
229 int label = gen_new_label();
230 tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
c55497ec
AJ
231 sr = tcg_temp_new(TCG_TYPE_I32);
232 tcg_gen_andi_i32(sr, cpu_sr, SR_T);
233 tcg_gen_brcondi_i32(TCG_COND_NE, sr, t ? SR_T : 0, label);
1000822b
AJ
234 tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
235 gen_set_label(label);
236}
237
fdf9b3e8
FB
238/* Immediate conditional jump (bt or bf) */
239static void gen_conditional_jump(DisasContext * ctx,
240 target_ulong ift, target_ulong ifnott)
241{
242 int l1;
c55497ec 243 TCGv sr;
fdf9b3e8
FB
244
245 l1 = gen_new_label();
c55497ec
AJ
246 sr = tcg_temp_new(TCG_TYPE_I32);
247 tcg_gen_andi_i32(sr, cpu_sr, SR_T);
248 tcg_gen_brcondi_i32(TCG_COND_EQ, sr, SR_T, l1);
fdf9b3e8
FB
249 gen_goto_tb(ctx, 0, ifnott);
250 gen_set_label(l1);
251 gen_goto_tb(ctx, 1, ift);
252}
253
254/* Delayed conditional jump (bt or bf) */
255static void gen_delayed_conditional_jump(DisasContext * ctx)
256{
257 int l1;
c55497ec 258 TCGv ds;
fdf9b3e8
FB
259
260 l1 = gen_new_label();
c55497ec
AJ
261 ds = tcg_temp_new(TCG_TYPE_I32);
262 tcg_gen_andi_i32(ds, cpu_flags, DELAY_SLOT_TRUE);
263 tcg_gen_brcondi_i32(TCG_COND_EQ, ds, DELAY_SLOT_TRUE, l1);
823029f9 264 gen_goto_tb(ctx, 1, ctx->pc + 2);
fdf9b3e8 265 gen_set_label(l1);
1000822b 266 tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
9c2a9ea1 267 gen_jump(ctx);
fdf9b3e8
FB
268}
269
a4625612
AJ
270static inline void gen_set_t(void)
271{
272 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
273}
274
275static inline void gen_clr_t(void)
276{
277 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
278}
279
280static inline void gen_cmp(int cond, TCGv t0, TCGv t1)
281{
282 int label1 = gen_new_label();
283 int label2 = gen_new_label();
284 tcg_gen_brcond_i32(cond, t1, t0, label1);
285 gen_clr_t();
286 tcg_gen_br(label2);
287 gen_set_label(label1);
288 gen_set_t();
289 gen_set_label(label2);
290}
291
292static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
293{
294 int label1 = gen_new_label();
295 int label2 = gen_new_label();
296 tcg_gen_brcondi_i32(cond, t0, imm, label1);
297 gen_clr_t();
298 tcg_gen_br(label2);
299 gen_set_label(label1);
300 gen_set_t();
301 gen_set_label(label2);
302}
303
1000822b
AJ
304static inline void gen_store_flags(uint32_t flags)
305{
306 tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
307 tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
308}
309
69d6275b
AJ
310static inline void gen_copy_bit_i32(TCGv t0, int p0, TCGv t1, int p1)
311{
312 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
313
314 p0 &= 0x1f;
315 p1 &= 0x1f;
316
317 tcg_gen_andi_i32(tmp, t1, (1 << p1));
318 tcg_gen_andi_i32(t0, t0, ~(1 << p0));
319 if (p0 < p1)
320 tcg_gen_shri_i32(tmp, tmp, p1 - p0);
321 else if (p0 > p1)
322 tcg_gen_shli_i32(tmp, tmp, p0 - p1);
323 tcg_gen_or_i32(t0, t0, tmp);
324
325 tcg_temp_free(tmp);
326}
327
cc4ba6a9
AJ
328
329static inline void gen_load_fpr32(TCGv t, int reg)
330{
331 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
332}
333
334static inline void gen_load_fpr64(TCGv t, int reg)
335{
336 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I32);
337 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
338
339 tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg]));
340 tcg_gen_extu_i32_i64(t, tmp1);
341 tcg_gen_shli_i64(t, t, 32);
342 tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg + 1]));
343 tcg_gen_extu_i32_i64(tmp2, tmp1);
344 tcg_temp_free(tmp1);
345 tcg_gen_or_i64(t, t, tmp2);
346 tcg_temp_free(tmp2);
347}
348
349static inline void gen_store_fpr32(TCGv t, int reg)
350{
351 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
352}
353
354static inline void gen_store_fpr64 (TCGv t, int reg)
355{
356 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
357
358 tcg_gen_trunc_i64_i32(tmp, t);
359 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg + 1]));
360 tcg_gen_shri_i64(t, t, 32);
361 tcg_gen_trunc_i64_i32(tmp, t);
362 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg]));
363 tcg_temp_free(tmp);
364}
365
fdf9b3e8
FB
366#define B3_0 (ctx->opcode & 0xf)
367#define B6_4 ((ctx->opcode >> 4) & 0x7)
368#define B7_4 ((ctx->opcode >> 4) & 0xf)
369#define B7_0 (ctx->opcode & 0xff)
370#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
371#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
372 (ctx->opcode & 0xfff))
373#define B11_8 ((ctx->opcode >> 8) & 0xf)
374#define B15_12 ((ctx->opcode >> 12) & 0xf)
375
376#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
7efbe241 377 (cpu_gregs[x + 16]) : (cpu_gregs[x]))
fdf9b3e8
FB
378
379#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
7efbe241 380 ? (cpu_gregs[x + 16]) : (cpu_gregs[x]))
fdf9b3e8 381
eda9b09b 382#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
f09111e0 383#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
eda9b09b 384#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
ea6cf6be 385#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
eda9b09b 386
fdf9b3e8
FB
387#define CHECK_NOT_DELAY_SLOT \
388 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
e6afc2f4 389 {tcg_gen_helper_0_0(helper_raise_slot_illegal_instruction); ctx->bstate = BS_EXCP; \
fdf9b3e8
FB
390 return;}
391
823029f9 392void _decode_opc(DisasContext * ctx)
fdf9b3e8
FB
393{
394#if 0
395 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
396#endif
397 switch (ctx->opcode) {
398 case 0x0019: /* div0u */
3a8a44c4 399 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
fdf9b3e8
FB
400 return;
401 case 0x000b: /* rts */
1000822b
AJ
402 CHECK_NOT_DELAY_SLOT
403 tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
fdf9b3e8
FB
404 ctx->flags |= DELAY_SLOT;
405 ctx->delayed_pc = (uint32_t) - 1;
406 return;
407 case 0x0028: /* clrmac */
3a8a44c4
AJ
408 tcg_gen_movi_i32(cpu_mach, 0);
409 tcg_gen_movi_i32(cpu_macl, 0);
fdf9b3e8
FB
410 return;
411 case 0x0048: /* clrs */
3a8a44c4 412 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S);
fdf9b3e8
FB
413 return;
414 case 0x0008: /* clrt */
a4625612 415 gen_clr_t();
fdf9b3e8
FB
416 return;
417 case 0x0038: /* ldtlb */
ea2b542a 418#if defined(CONFIG_USER_ONLY)
fdf9b3e8 419 assert(0); /* XXXXX */
ea2b542a 420#else
e6afc2f4 421 tcg_gen_helper_0_0(helper_ldtlb);
ea2b542a 422#endif
fdf9b3e8 423 return;
c5e814b2 424 case 0x002b: /* rte */
1000822b
AJ
425 CHECK_NOT_DELAY_SLOT
426 tcg_gen_mov_i32(cpu_sr, cpu_ssr);
427 tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
fdf9b3e8
FB
428 ctx->flags |= DELAY_SLOT;
429 ctx->delayed_pc = (uint32_t) - 1;
430 return;
431 case 0x0058: /* sets */
3a8a44c4 432 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S);
fdf9b3e8
FB
433 return;
434 case 0x0018: /* sett */
a4625612 435 gen_set_t();
fdf9b3e8 436 return;
24988dc2 437 case 0xfbfd: /* frchg */
6f06939b 438 tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
823029f9 439 ctx->bstate = BS_STOP;
fdf9b3e8 440 return;
24988dc2 441 case 0xf3fd: /* fschg */
6f06939b 442 tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
823029f9 443 ctx->bstate = BS_STOP;
fdf9b3e8
FB
444 return;
445 case 0x0009: /* nop */
446 return;
447 case 0x001b: /* sleep */
833ed386 448 if (ctx->memidx) {
e6afc2f4 449 tcg_gen_helper_0_0(helper_sleep);
833ed386 450 } else {
e6afc2f4 451 tcg_gen_helper_0_0(helper_raise_illegal_instruction);
833ed386
AJ
452 ctx->bstate = BS_EXCP;
453 }
fdf9b3e8
FB
454 return;
455 }
456
457 switch (ctx->opcode & 0xf000) {
458 case 0x1000: /* mov.l Rm,@(disp,Rn) */
c55497ec
AJ
459 {
460 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
461 tcg_gen_addi_i32(addr, REG(B11_8), B3_0 * 4);
462 tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
463 tcg_temp_free(addr);
464 }
fdf9b3e8
FB
465 return;
466 case 0x5000: /* mov.l @(disp,Rm),Rn */
c55497ec
AJ
467 {
468 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
469 tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 4);
470 tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
471 tcg_temp_free(addr);
472 }
fdf9b3e8 473 return;
24988dc2 474 case 0xe000: /* mov #imm,Rn */
7efbe241 475 tcg_gen_movi_i32(REG(B11_8), B7_0s);
fdf9b3e8
FB
476 return;
477 case 0x9000: /* mov.w @(disp,PC),Rn */
c55497ec
AJ
478 {
479 TCGv addr = tcg_const_i32(ctx->pc + 4 + B7_0 * 2);
480 tcg_gen_qemu_ld16s(REG(B11_8), addr, ctx->memidx);
481 tcg_temp_free(addr);
482 }
fdf9b3e8
FB
483 return;
484 case 0xd000: /* mov.l @(disp,PC),Rn */
c55497ec
AJ
485 {
486 TCGv addr = tcg_const_i32((ctx->pc + 4 + B7_0 * 4) & ~3);
487 tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
488 tcg_temp_free(addr);
489 }
fdf9b3e8 490 return;
24988dc2 491 case 0x7000: /* add #imm,Rn */
7efbe241 492 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);
fdf9b3e8
FB
493 return;
494 case 0xa000: /* bra disp */
495 CHECK_NOT_DELAY_SLOT
1000822b
AJ
496 ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
497 tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
fdf9b3e8
FB
498 ctx->flags |= DELAY_SLOT;
499 return;
500 case 0xb000: /* bsr disp */
501 CHECK_NOT_DELAY_SLOT
1000822b
AJ
502 tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
503 ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
504 tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
fdf9b3e8
FB
505 ctx->flags |= DELAY_SLOT;
506 return;
507 }
508
509 switch (ctx->opcode & 0xf00f) {
510 case 0x6003: /* mov Rm,Rn */
7efbe241 511 tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
fdf9b3e8
FB
512 return;
513 case 0x2000: /* mov.b Rm,@Rn */
7efbe241 514 tcg_gen_qemu_st8(REG(B7_4), REG(B11_8), ctx->memidx);
fdf9b3e8
FB
515 return;
516 case 0x2001: /* mov.w Rm,@Rn */
7efbe241 517 tcg_gen_qemu_st16(REG(B7_4), REG(B11_8), ctx->memidx);
fdf9b3e8
FB
518 return;
519 case 0x2002: /* mov.l Rm,@Rn */
7efbe241 520 tcg_gen_qemu_st32(REG(B7_4), REG(B11_8), ctx->memidx);
fdf9b3e8
FB
521 return;
522 case 0x6000: /* mov.b @Rm,Rn */
7efbe241 523 tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);
fdf9b3e8
FB
524 return;
525 case 0x6001: /* mov.w @Rm,Rn */
7efbe241 526 tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);
fdf9b3e8
FB
527 return;
528 case 0x6002: /* mov.l @Rm,Rn */
7efbe241 529 tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);
fdf9b3e8
FB
530 return;
531 case 0x2004: /* mov.b Rm,@-Rn */
c55497ec
AJ
532 {
533 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
534 tcg_gen_subi_i32(addr, REG(B11_8), 1);
535 tcg_gen_qemu_st8(REG(B7_4), addr, ctx->memidx); /* might cause re-execution */
536 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1); /* modify register status */
537 tcg_temp_free(addr);
538 }
fdf9b3e8
FB
539 return;
540 case 0x2005: /* mov.w Rm,@-Rn */
c55497ec
AJ
541 {
542 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
543 tcg_gen_subi_i32(addr, REG(B11_8), 2);
544 tcg_gen_qemu_st16(REG(B7_4), addr, ctx->memidx);
545 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 2);
546 tcg_temp_free(addr);
547 }
fdf9b3e8
FB
548 return;
549 case 0x2006: /* mov.l Rm,@-Rn */
c55497ec
AJ
550 {
551 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
552 tcg_gen_subi_i32(addr, REG(B11_8), 4);
553 tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
554 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
555 }
fdf9b3e8 556 return;
eda9b09b 557 case 0x6004: /* mov.b @Rm+,Rn */
7efbe241 558 tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);
24988dc2 559 if ( B11_8 != B7_4 )
7efbe241 560 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 1);
fdf9b3e8
FB
561 return;
562 case 0x6005: /* mov.w @Rm+,Rn */
7efbe241 563 tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);
24988dc2 564 if ( B11_8 != B7_4 )
7efbe241 565 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
fdf9b3e8
FB
566 return;
567 case 0x6006: /* mov.l @Rm+,Rn */
7efbe241 568 tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);
24988dc2 569 if ( B11_8 != B7_4 )
7efbe241 570 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
fdf9b3e8
FB
571 return;
572 case 0x0004: /* mov.b Rm,@(R0,Rn) */
c55497ec
AJ
573 {
574 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
575 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
576 tcg_gen_qemu_st8(REG(B7_4), addr, ctx->memidx);
577 tcg_temp_free(addr);
578 }
fdf9b3e8
FB
579 return;
580 case 0x0005: /* mov.w Rm,@(R0,Rn) */
c55497ec
AJ
581 {
582 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
583 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
584 tcg_gen_qemu_st16(REG(B7_4), addr, ctx->memidx);
585 tcg_temp_free(addr);
586 }
fdf9b3e8
FB
587 return;
588 case 0x0006: /* mov.l Rm,@(R0,Rn) */
c55497ec
AJ
589 {
590 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
591 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
592 tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
593 tcg_temp_free(addr);
594 }
fdf9b3e8
FB
595 return;
596 case 0x000c: /* mov.b @(R0,Rm),Rn */
c55497ec
AJ
597 {
598 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
599 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
600 tcg_gen_qemu_ld8s(REG(B11_8), addr, ctx->memidx);
601 tcg_temp_free(addr);
602 }
fdf9b3e8
FB
603 return;
604 case 0x000d: /* mov.w @(R0,Rm),Rn */
c55497ec
AJ
605 {
606 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
607 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
608 tcg_gen_qemu_ld16s(REG(B11_8), addr, ctx->memidx);
609 tcg_temp_free(addr);
610 }
fdf9b3e8
FB
611 return;
612 case 0x000e: /* mov.l @(R0,Rm),Rn */
c55497ec
AJ
613 {
614 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
615 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
616 tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
617 tcg_temp_free(addr);
618 }
fdf9b3e8
FB
619 return;
620 case 0x6008: /* swap.b Rm,Rn */
c55497ec
AJ
621 {
622 TCGv high, low;
623 high = tcg_temp_new(TCG_TYPE_I32);
624 tcg_gen_ext8u_i32(high, REG(B7_4));
625 tcg_gen_shli_i32(high, high, 8);
626 low = tcg_temp_new(TCG_TYPE_I32);
627 tcg_gen_shri_i32(low, REG(B7_4), 8);
628 tcg_gen_ext8u_i32(low, low);
629 tcg_gen_or_i32(REG(B11_8), high, low);
630 tcg_temp_free(low);
631 tcg_temp_free(high);
632 }
fdf9b3e8
FB
633 return;
634 case 0x6009: /* swap.w Rm,Rn */
c55497ec
AJ
635 {
636 TCGv high, low;
637 high = tcg_temp_new(TCG_TYPE_I32);
638 tcg_gen_ext16u_i32(high, REG(B7_4));
639 tcg_gen_shli_i32(high, high, 16);
640 low = tcg_temp_new(TCG_TYPE_I32);
641 tcg_gen_shri_i32(low, REG(B7_4), 16);
642 tcg_gen_ext16u_i32(low, low);
643 tcg_gen_or_i32(REG(B11_8), high, low);
644 tcg_temp_free(low);
645 tcg_temp_free(high);
646 }
fdf9b3e8
FB
647 return;
648 case 0x200d: /* xtrct Rm,Rn */
c55497ec
AJ
649 {
650 TCGv high, low;
651 high = tcg_temp_new(TCG_TYPE_I32);
652 tcg_gen_ext16u_i32(high, REG(B7_4));
653 tcg_gen_shli_i32(high, high, 16);
654 low = tcg_temp_new(TCG_TYPE_I32);
655 tcg_gen_shri_i32(low, REG(B11_8), 16);
656 tcg_gen_ext16u_i32(low, low);
657 tcg_gen_or_i32(REG(B11_8), high, low);
658 tcg_temp_free(low);
659 tcg_temp_free(high);
660 }
fdf9b3e8
FB
661 return;
662 case 0x300c: /* add Rm,Rn */
7efbe241 663 tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));
fdf9b3e8
FB
664 return;
665 case 0x300e: /* addc Rm,Rn */
7efbe241 666 tcg_gen_helper_1_2(helper_addc, REG(B11_8), REG(B7_4), REG(B11_8));
fdf9b3e8
FB
667 return;
668 case 0x300f: /* addv Rm,Rn */
7efbe241 669 tcg_gen_helper_1_2(helper_addv, REG(B11_8), REG(B7_4), REG(B11_8));
fdf9b3e8
FB
670 return;
671 case 0x2009: /* and Rm,Rn */
7efbe241 672 tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
fdf9b3e8
FB
673 return;
674 case 0x3000: /* cmp/eq Rm,Rn */
7efbe241 675 gen_cmp(TCG_COND_EQ, REG(B7_4), REG(B11_8));
fdf9b3e8
FB
676 return;
677 case 0x3003: /* cmp/ge Rm,Rn */
7efbe241 678 gen_cmp(TCG_COND_GE, REG(B7_4), REG(B11_8));
fdf9b3e8
FB
679 return;
680 case 0x3007: /* cmp/gt Rm,Rn */
7efbe241 681 gen_cmp(TCG_COND_GT, REG(B7_4), REG(B11_8));
fdf9b3e8
FB
682 return;
683 case 0x3006: /* cmp/hi Rm,Rn */
7efbe241 684 gen_cmp(TCG_COND_GTU, REG(B7_4), REG(B11_8));
fdf9b3e8
FB
685 return;
686 case 0x3002: /* cmp/hs Rm,Rn */
7efbe241 687 gen_cmp(TCG_COND_GEU, REG(B7_4), REG(B11_8));
fdf9b3e8
FB
688 return;
689 case 0x200c: /* cmp/str Rm,Rn */
69d6275b
AJ
690 {
691 int label1 = gen_new_label();
692 int label2 = gen_new_label();
c55497ec
AJ
693 TCGv cmp1 = tcg_temp_local_new(TCG_TYPE_I32);
694 TCGv cmp2 = tcg_temp_local_new(TCG_TYPE_I32);
695 tcg_gen_xor_i32(cmp1, REG(B7_4), REG(B11_8));
696 tcg_gen_andi_i32(cmp2, cmp1, 0xff000000);
697 tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
698 tcg_gen_andi_i32(cmp2, cmp1, 0x00ff0000);
699 tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
700 tcg_gen_andi_i32(cmp2, cmp1, 0x0000ff00);
701 tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
702 tcg_gen_andi_i32(cmp2, cmp1, 0x000000ff);
703 tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
69d6275b
AJ
704 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
705 tcg_gen_br(label2);
706 gen_set_label(label1);
707 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
708 gen_set_label(label2);
c55497ec
AJ
709 tcg_temp_free(cmp2);
710 tcg_temp_free(cmp1);
69d6275b 711 }
fdf9b3e8
FB
712 return;
713 case 0x2007: /* div0s Rm,Rn */
c55497ec
AJ
714 {
715 gen_copy_bit_i32(cpu_sr, 8, REG(B11_8), 31); /* SR_Q */
716 gen_copy_bit_i32(cpu_sr, 9, REG(B7_4), 31); /* SR_M */
717 TCGv val = tcg_temp_new(TCG_TYPE_I32);
718 tcg_gen_xor_i32(val, REG(B7_4), REG(B11_8));
719 gen_copy_bit_i32(cpu_sr, 0, val, 31); /* SR_T */
720 tcg_temp_free(val);
721 }
fdf9b3e8
FB
722 return;
723 case 0x3004: /* div1 Rm,Rn */
7efbe241 724 tcg_gen_helper_1_2(helper_div1, REG(B11_8), REG(B7_4), REG(B11_8));
fdf9b3e8
FB
725 return;
726 case 0x300d: /* dmuls.l Rm,Rn */
6f06939b
AJ
727 {
728 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
729 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
730
7efbe241
AJ
731 tcg_gen_ext_i32_i64(tmp1, REG(B7_4));
732 tcg_gen_ext_i32_i64(tmp2, REG(B11_8));
6f06939b
AJ
733 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
734 tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
735 tcg_gen_shri_i64(tmp1, tmp1, 32);
736 tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
737
6f06939b 738 tcg_temp_free(tmp2);
c55497ec 739 tcg_temp_free(tmp1);
6f06939b 740 }
fdf9b3e8
FB
741 return;
742 case 0x3005: /* dmulu.l Rm,Rn */
6f06939b
AJ
743 {
744 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
745 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
746
7efbe241
AJ
747 tcg_gen_extu_i32_i64(tmp1, REG(B7_4));
748 tcg_gen_extu_i32_i64(tmp2, REG(B11_8));
6f06939b
AJ
749 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
750 tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
751 tcg_gen_shri_i64(tmp1, tmp1, 32);
752 tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
753
6f06939b 754 tcg_temp_free(tmp2);
c55497ec 755 tcg_temp_free(tmp1);
6f06939b 756 }
fdf9b3e8
FB
757 return;
758 case 0x600e: /* exts.b Rm,Rn */
7efbe241 759 tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));
fdf9b3e8
FB
760 return;
761 case 0x600f: /* exts.w Rm,Rn */
7efbe241 762 tcg_gen_ext16s_i32(REG(B11_8), REG(B7_4));
fdf9b3e8
FB
763 return;
764 case 0x600c: /* extu.b Rm,Rn */
7efbe241 765 tcg_gen_ext8u_i32(REG(B11_8), REG(B7_4));
fdf9b3e8
FB
766 return;
767 case 0x600d: /* extu.w Rm,Rn */
7efbe241 768 tcg_gen_ext16u_i32(REG(B11_8), REG(B7_4));
fdf9b3e8 769 return;
24988dc2 770 case 0x000f: /* mac.l @Rm+,@Rn+ */
c55497ec
AJ
771 {
772 TCGv arg0, arg1;
773 arg0 = tcg_temp_new(TCG_TYPE_I32);
774 tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);
775 arg1 = tcg_temp_new(TCG_TYPE_I32);
776 tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);
777 tcg_gen_helper_0_2(helper_macl, arg0, arg1);
778 tcg_temp_free(arg1);
779 tcg_temp_free(arg0);
780 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
781 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
782 }
fdf9b3e8
FB
783 return;
784 case 0x400f: /* mac.w @Rm+,@Rn+ */
c55497ec
AJ
785 {
786 TCGv arg0, arg1;
787 arg0 = tcg_temp_new(TCG_TYPE_I32);
788 tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);
789 arg1 = tcg_temp_new(TCG_TYPE_I32);
790 tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);
791 tcg_gen_helper_0_2(helper_macw, arg0, arg1);
792 tcg_temp_free(arg1);
793 tcg_temp_free(arg0);
794 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);
795 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
796 }
fdf9b3e8
FB
797 return;
798 case 0x0007: /* mul.l Rm,Rn */
7efbe241 799 tcg_gen_mul_i32(cpu_macl, REG(B7_4), REG(B11_8));
fdf9b3e8
FB
800 return;
801 case 0x200f: /* muls.w Rm,Rn */
c55497ec
AJ
802 {
803 TCGv arg0, arg1;
804 arg0 = tcg_temp_new(TCG_TYPE_I32);
805 tcg_gen_ext16s_i32(arg0, REG(B7_4));
806 arg1 = tcg_temp_new(TCG_TYPE_I32);
807 tcg_gen_ext16s_i32(arg1, REG(B11_8));
808 tcg_gen_mul_i32(cpu_macl, arg0, arg1);
809 tcg_temp_free(arg1);
810 tcg_temp_free(arg0);
811 }
fdf9b3e8
FB
812 return;
813 case 0x200e: /* mulu.w Rm,Rn */
c55497ec
AJ
814 {
815 TCGv arg0, arg1;
816 arg0 = tcg_temp_new(TCG_TYPE_I32);
817 tcg_gen_ext16u_i32(arg0, REG(B7_4));
818 arg1 = tcg_temp_new(TCG_TYPE_I32);
819 tcg_gen_ext16u_i32(arg1, REG(B11_8));
820 tcg_gen_mul_i32(cpu_macl, arg0, arg1);
821 tcg_temp_free(arg1);
822 tcg_temp_free(arg0);
823 }
fdf9b3e8
FB
824 return;
825 case 0x600b: /* neg Rm,Rn */
7efbe241 826 tcg_gen_neg_i32(REG(B11_8), REG(B7_4));
fdf9b3e8
FB
827 return;
828 case 0x600a: /* negc Rm,Rn */
7efbe241 829 tcg_gen_helper_1_1(helper_negc, REG(B11_8), REG(B7_4));
fdf9b3e8
FB
830 return;
831 case 0x6007: /* not Rm,Rn */
7efbe241 832 tcg_gen_not_i32(REG(B11_8), REG(B7_4));
fdf9b3e8
FB
833 return;
834 case 0x200b: /* or Rm,Rn */
7efbe241 835 tcg_gen_or_i32(REG(B11_8), REG(B11_8), REG(B7_4));
fdf9b3e8
FB
836 return;
837 case 0x400c: /* shad Rm,Rn */
69d6275b
AJ
838 {
839 int label1 = gen_new_label();
840 int label2 = gen_new_label();
841 int label3 = gen_new_label();
842 int label4 = gen_new_label();
c55497ec 843 TCGv shift = tcg_temp_local_new(TCG_TYPE_I32);
7efbe241 844 tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
69d6275b 845 /* Rm positive, shift to the left */
c55497ec
AJ
846 tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
847 tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);
69d6275b
AJ
848 tcg_gen_br(label4);
849 /* Rm negative, shift to the right */
850 gen_set_label(label1);
c55497ec
AJ
851 tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
852 tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);
853 tcg_gen_not_i32(shift, REG(B7_4));
854 tcg_gen_andi_i32(shift, shift, 0x1f);
855 tcg_gen_addi_i32(shift, shift, 1);
856 tcg_gen_sar_i32(REG(B11_8), REG(B11_8), shift);
69d6275b
AJ
857 tcg_gen_br(label4);
858 /* Rm = -32 */
859 gen_set_label(label2);
7efbe241
AJ
860 tcg_gen_brcondi_i32(TCG_COND_LT, REG(B11_8), 0, label3);
861 tcg_gen_movi_i32(REG(B11_8), 0);
69d6275b
AJ
862 tcg_gen_br(label4);
863 gen_set_label(label3);
7efbe241 864 tcg_gen_movi_i32(REG(B11_8), 0xffffffff);
69d6275b 865 gen_set_label(label4);
c55497ec 866 tcg_temp_free(shift);
69d6275b 867 }
fdf9b3e8
FB
868 return;
869 case 0x400d: /* shld Rm,Rn */
69d6275b
AJ
870 {
871 int label1 = gen_new_label();
872 int label2 = gen_new_label();
873 int label3 = gen_new_label();
c55497ec 874 TCGv shift = tcg_temp_local_new(TCG_TYPE_I32);
7efbe241 875 tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
69d6275b 876 /* Rm positive, shift to the left */
c55497ec
AJ
877 tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
878 tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);
69d6275b
AJ
879 tcg_gen_br(label3);
880 /* Rm negative, shift to the right */
881 gen_set_label(label1);
c55497ec
AJ
882 tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
883 tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);
884 tcg_gen_not_i32(shift, REG(B7_4));
885 tcg_gen_andi_i32(shift, shift, 0x1f);
886 tcg_gen_addi_i32(shift, shift, 1);
887 tcg_gen_shr_i32(REG(B11_8), REG(B11_8), shift);
69d6275b
AJ
888 tcg_gen_br(label3);
889 /* Rm = -32 */
890 gen_set_label(label2);
7efbe241 891 tcg_gen_movi_i32(REG(B11_8), 0);
69d6275b 892 gen_set_label(label3);
c55497ec 893 tcg_temp_free(shift);
69d6275b 894 }
fdf9b3e8
FB
895 return;
896 case 0x3008: /* sub Rm,Rn */
7efbe241 897 tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));
fdf9b3e8
FB
898 return;
899 case 0x300a: /* subc Rm,Rn */
7efbe241 900 tcg_gen_helper_1_2(helper_subc, REG(B11_8), REG(B7_4), REG(B11_8));
fdf9b3e8
FB
901 return;
902 case 0x300b: /* subv Rm,Rn */
7efbe241 903 tcg_gen_helper_1_2(helper_subv, REG(B11_8), REG(B7_4), REG(B11_8));
fdf9b3e8
FB
904 return;
905 case 0x2008: /* tst Rm,Rn */
c55497ec
AJ
906 {
907 TCGv val = tcg_temp_new(TCG_TYPE_I32);
908 tcg_gen_and_i32(val, REG(B7_4), REG(B11_8));
909 gen_cmp_imm(TCG_COND_EQ, val, 0);
910 tcg_temp_free(val);
911 }
fdf9b3e8
FB
912 return;
913 case 0x200a: /* xor Rm,Rn */
7efbe241 914 tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));
fdf9b3e8 915 return;
e67888a7 916 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
022a22c7 917 if (ctx->fpscr & FPSCR_SZ) {
cc4ba6a9
AJ
918 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
919 gen_load_fpr64(fp, XREG(B7_4));
920 gen_store_fpr64(fp, XREG(B11_8));
921 tcg_temp_free(fp);
eda9b09b 922 } else {
cc4ba6a9
AJ
923 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
924 gen_load_fpr32(fp, FREG(B7_4));
925 gen_store_fpr32(fp, FREG(B11_8));
926 tcg_temp_free(fp);
eda9b09b
FB
927 }
928 return;
e67888a7 929 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
022a22c7 930 if (ctx->fpscr & FPSCR_SZ) {
cc4ba6a9
AJ
931 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
932 gen_load_fpr64(fp, XREG(B7_4));
933 tcg_gen_qemu_st64(fp, REG(B11_8), ctx->memidx);
934 tcg_temp_free(fp);
eda9b09b 935 } else {
cc4ba6a9
AJ
936 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
937 gen_load_fpr32(fp, FREG(B7_4));
938 tcg_gen_qemu_st32(fp, REG(B11_8), ctx->memidx);
939 tcg_temp_free(fp);
eda9b09b
FB
940 }
941 return;
e67888a7 942 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
022a22c7 943 if (ctx->fpscr & FPSCR_SZ) {
cc4ba6a9
AJ
944 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
945 tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx);
946 gen_store_fpr64(fp, XREG(B11_8));
947 tcg_temp_free(fp);
eda9b09b 948 } else {
cc4ba6a9
AJ
949 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
950 tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);
951 gen_store_fpr32(fp, FREG(B11_8));
952 tcg_temp_free(fp);
eda9b09b
FB
953 }
954 return;
e67888a7 955 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
022a22c7 956 if (ctx->fpscr & FPSCR_SZ) {
cc4ba6a9
AJ
957 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
958 tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx);
959 gen_store_fpr64(fp, XREG(B11_8));
960 tcg_temp_free(fp);
961 tcg_gen_addi_i32(REG(B7_4),REG(B7_4), 8);
eda9b09b 962 } else {
cc4ba6a9
AJ
963 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
964 tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);
965 gen_store_fpr32(fp, FREG(B11_8));
966 tcg_temp_free(fp);
967 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
eda9b09b
FB
968 }
969 return;
e67888a7 970 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
022a22c7 971 if (ctx->fpscr & FPSCR_SZ) {
cc4ba6a9
AJ
972 TCGv addr, fp;
973 addr = tcg_temp_new(TCG_TYPE_I32);
974 tcg_gen_subi_i32(addr, REG(B11_8), 8);
975 fp = tcg_temp_new(TCG_TYPE_I64);
976 gen_load_fpr64(fp, XREG(B7_4));
977 tcg_gen_qemu_st64(fp, addr, ctx->memidx);
978 tcg_temp_free(fp);
979 tcg_temp_free(addr);
7efbe241 980 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 8);
eda9b09b 981 } else {
cc4ba6a9
AJ
982 TCGv addr, fp;
983 addr = tcg_temp_new(TCG_TYPE_I32);
984 tcg_gen_subi_i32(addr, REG(B11_8), 4);
985 fp = tcg_temp_new(TCG_TYPE_I32);
986 gen_load_fpr32(fp, FREG(B7_4));
987 tcg_gen_qemu_st32(fp, addr, ctx->memidx);
988 tcg_temp_free(fp);
989 tcg_temp_free(addr);
7efbe241 990 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
eda9b09b
FB
991 }
992 return;
e67888a7 993 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
cc4ba6a9
AJ
994 {
995 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
996 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
997 if (ctx->fpscr & FPSCR_SZ) {
998 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
999 tcg_gen_qemu_ld64(fp, addr, ctx->memidx);
1000 gen_store_fpr64(fp, XREG(B11_8));
1001 tcg_temp_free(fp);
1002 } else {
1003 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1004 tcg_gen_qemu_ld32u(fp, addr, ctx->memidx);
1005 gen_store_fpr32(fp, FREG(B11_8));
1006 tcg_temp_free(fp);
1007 }
1008 tcg_temp_free(addr);
eda9b09b
FB
1009 }
1010 return;
e67888a7 1011 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
cc4ba6a9
AJ
1012 {
1013 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1014 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
1015 if (ctx->fpscr & FPSCR_SZ) {
1016 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1017 gen_load_fpr64(fp, XREG(B7_4));
1018 tcg_gen_qemu_st64(fp, addr, ctx->memidx);
1019 tcg_temp_free(fp);
1020 } else {
1021 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1022 gen_load_fpr32(fp, FREG(B7_4));
1023 tcg_gen_qemu_st32(fp, addr, ctx->memidx);
1024 tcg_temp_free(fp);
1025 }
1026 tcg_temp_free(addr);
eda9b09b
FB
1027 }
1028 return;
e67888a7
TS
1029 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1030 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1031 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1032 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1033 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1034 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
cc4ba6a9
AJ
1035 {
1036 TCGv fp0, fp1;
1037
1038 if (ctx->fpscr & FPSCR_PR) {
1039 if (ctx->opcode & 0x0110)
1040 break; /* illegal instruction */
1041 fp0 = tcg_temp_new(TCG_TYPE_I64);
1042 fp1 = tcg_temp_new(TCG_TYPE_I64);
1043 gen_load_fpr64(fp0, DREG(B11_8));
1044 gen_load_fpr64(fp1, DREG(B7_4));
1045 }
1046 else {
1047 fp0 = tcg_temp_new(TCG_TYPE_I32);
1048 fp1 = tcg_temp_new(TCG_TYPE_I32);
1049 gen_load_fpr32(fp0, FREG(B11_8));
1050 gen_load_fpr32(fp1, FREG(B7_4));
1051 }
1052
1053 switch (ctx->opcode & 0xf00f) {
1054 case 0xf000: /* fadd Rm,Rn */
1055 if (ctx->fpscr & FPSCR_PR)
1056 tcg_gen_helper_1_2(helper_fadd_DT, fp0, fp0, fp1);
1057 else
1058 tcg_gen_helper_1_2(helper_fadd_FT, fp0, fp0, fp1);
1059 break;
1060 case 0xf001: /* fsub Rm,Rn */
1061 if (ctx->fpscr & FPSCR_PR)
1062 tcg_gen_helper_1_2(helper_fsub_DT, fp0, fp0, fp1);
1063 else
1064 tcg_gen_helper_1_2(helper_fsub_FT, fp0, fp0, fp1);
1065 break;
1066 case 0xf002: /* fmul Rm,Rn */
1067 if (ctx->fpscr & FPSCR_PR)
1068 tcg_gen_helper_1_2(helper_fmul_DT, fp0, fp0, fp1);
1069 else
1070 tcg_gen_helper_1_2(helper_fmul_FT, fp0, fp0, fp1);
1071 break;
1072 case 0xf003: /* fdiv Rm,Rn */
1073 if (ctx->fpscr & FPSCR_PR)
1074 tcg_gen_helper_1_2(helper_fdiv_DT, fp0, fp0, fp1);
1075 else
1076 tcg_gen_helper_1_2(helper_fdiv_FT, fp0, fp0, fp1);
1077 break;
1078 case 0xf004: /* fcmp/eq Rm,Rn */
1079 if (ctx->fpscr & FPSCR_PR)
1080 tcg_gen_helper_0_2(helper_fcmp_eq_DT, fp0, fp1);
1081 else
1082 tcg_gen_helper_0_2(helper_fcmp_eq_FT, fp0, fp1);
1083 return;
1084 case 0xf005: /* fcmp/gt Rm,Rn */
1085 if (ctx->fpscr & FPSCR_PR)
1086 tcg_gen_helper_0_2(helper_fcmp_gt_DT, fp0, fp1);
1087 else
1088 tcg_gen_helper_0_2(helper_fcmp_gt_FT, fp0, fp1);
1089 return;
1090 }
1091
1092 if (ctx->fpscr & FPSCR_PR) {
1093 gen_store_fpr64(fp0, DREG(B11_8));
1094 }
1095 else {
1096 gen_store_fpr32(fp0, FREG(B11_8));
1097 }
1098 tcg_temp_free(fp1);
1099 tcg_temp_free(fp0);
ea6cf6be
TS
1100 }
1101 return;
fdf9b3e8
FB
1102 }
1103
1104 switch (ctx->opcode & 0xff00) {
1105 case 0xc900: /* and #imm,R0 */
7efbe241 1106 tcg_gen_andi_i32(REG(0), REG(0), B7_0);
fdf9b3e8 1107 return;
24988dc2 1108 case 0xcd00: /* and.b #imm,@(R0,GBR) */
c55497ec
AJ
1109 {
1110 TCGv addr, val;
1111 addr = tcg_temp_new(TCG_TYPE_I32);
1112 tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1113 val = tcg_temp_new(TCG_TYPE_I32);
1114 tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1115 tcg_gen_andi_i32(val, val, B7_0);
1116 tcg_gen_qemu_st8(val, addr, ctx->memidx);
1117 tcg_temp_free(val);
1118 tcg_temp_free(addr);
1119 }
fdf9b3e8
FB
1120 return;
1121 case 0x8b00: /* bf label */
1122 CHECK_NOT_DELAY_SLOT
1123 gen_conditional_jump(ctx, ctx->pc + 2,
1124 ctx->pc + 4 + B7_0s * 2);
823029f9 1125 ctx->bstate = BS_BRANCH;
fdf9b3e8
FB
1126 return;
1127 case 0x8f00: /* bf/s label */
1128 CHECK_NOT_DELAY_SLOT
1000822b 1129 gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);
fdf9b3e8
FB
1130 ctx->flags |= DELAY_SLOT_CONDITIONAL;
1131 return;
1132 case 0x8900: /* bt label */
1133 CHECK_NOT_DELAY_SLOT
1134 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
1135 ctx->pc + 2);
823029f9 1136 ctx->bstate = BS_BRANCH;
fdf9b3e8
FB
1137 return;
1138 case 0x8d00: /* bt/s label */
1139 CHECK_NOT_DELAY_SLOT
1000822b 1140 gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);
fdf9b3e8
FB
1141 ctx->flags |= DELAY_SLOT_CONDITIONAL;
1142 return;
1143 case 0x8800: /* cmp/eq #imm,R0 */
7efbe241 1144 gen_cmp_imm(TCG_COND_EQ, REG(0), B7_0s);
fdf9b3e8
FB
1145 return;
1146 case 0xc400: /* mov.b @(disp,GBR),R0 */
c55497ec
AJ
1147 {
1148 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1149 tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1150 tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);
1151 tcg_temp_free(addr);
1152 }
fdf9b3e8
FB
1153 return;
1154 case 0xc500: /* mov.w @(disp,GBR),R0 */
c55497ec
AJ
1155 {
1156 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1157 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1158 tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);
1159 tcg_temp_free(addr);
1160 }
fdf9b3e8
FB
1161 return;
1162 case 0xc600: /* mov.l @(disp,GBR),R0 */
c55497ec
AJ
1163 {
1164 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1165 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1166 tcg_gen_qemu_ld32s(REG(0), addr, ctx->memidx);
1167 tcg_temp_free(addr);
1168 }
fdf9b3e8
FB
1169 return;
1170 case 0xc000: /* mov.b R0,@(disp,GBR) */
c55497ec
AJ
1171 {
1172 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1173 tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1174 tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);
1175 tcg_temp_free(addr);
1176 }
fdf9b3e8
FB
1177 return;
1178 case 0xc100: /* mov.w R0,@(disp,GBR) */
c55497ec
AJ
1179 {
1180 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1181 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1182 tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);
1183 tcg_temp_free(addr);
1184 }
fdf9b3e8
FB
1185 return;
1186 case 0xc200: /* mov.l R0,@(disp,GBR) */
c55497ec
AJ
1187 {
1188 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1189 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1190 tcg_gen_qemu_st32(REG(0), addr, ctx->memidx);
1191 tcg_temp_free(addr);
1192 }
fdf9b3e8
FB
1193 return;
1194 case 0x8000: /* mov.b R0,@(disp,Rn) */
c55497ec
AJ
1195 {
1196 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1197 tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1198 tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);
1199 tcg_temp_free(addr);
1200 }
fdf9b3e8
FB
1201 return;
1202 case 0x8100: /* mov.w R0,@(disp,Rn) */
c55497ec
AJ
1203 {
1204 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1205 tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1206 tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);
1207 tcg_temp_free(addr);
1208 }
fdf9b3e8
FB
1209 return;
1210 case 0x8400: /* mov.b @(disp,Rn),R0 */
c55497ec
AJ
1211 {
1212 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1213 tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1214 tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);
1215 tcg_temp_free(addr);
1216 }
fdf9b3e8
FB
1217 return;
1218 case 0x8500: /* mov.w @(disp,Rn),R0 */
c55497ec
AJ
1219 {
1220 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1221 tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1222 tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);
1223 tcg_temp_free(addr);
1224 }
fdf9b3e8
FB
1225 return;
1226 case 0xc700: /* mova @(disp,PC),R0 */
7efbe241 1227 tcg_gen_movi_i32(REG(0), ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
fdf9b3e8
FB
1228 return;
1229 case 0xcb00: /* or #imm,R0 */
7efbe241 1230 tcg_gen_ori_i32(REG(0), REG(0), B7_0);
fdf9b3e8 1231 return;
24988dc2 1232 case 0xcf00: /* or.b #imm,@(R0,GBR) */
c55497ec
AJ
1233 {
1234 TCGv addr, val;
1235 addr = tcg_temp_new(TCG_TYPE_I32);
1236 tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1237 val = tcg_temp_new(TCG_TYPE_I32);
1238 tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1239 tcg_gen_ori_i32(val, val, B7_0);
1240 tcg_gen_qemu_st8(val, addr, ctx->memidx);
1241 tcg_temp_free(val);
1242 tcg_temp_free(addr);
1243 }
fdf9b3e8
FB
1244 return;
1245 case 0xc300: /* trapa #imm */
c55497ec
AJ
1246 {
1247 TCGv imm;
1248 CHECK_NOT_DELAY_SLOT
1249 tcg_gen_movi_i32(cpu_pc, ctx->pc);
1250 imm = tcg_const_i32(B7_0);
1251 tcg_gen_helper_0_1(helper_trapa, imm);
1252 tcg_temp_free(imm);
1253 ctx->bstate = BS_BRANCH;
1254 }
fdf9b3e8
FB
1255 return;
1256 case 0xc800: /* tst #imm,R0 */
c55497ec
AJ
1257 {
1258 TCGv val = tcg_temp_new(TCG_TYPE_I32);
1259 tcg_gen_andi_i32(val, REG(0), B7_0);
1260 gen_cmp_imm(TCG_COND_EQ, val, 0);
1261 tcg_temp_free(val);
1262 }
fdf9b3e8 1263 return;
24988dc2 1264 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
c55497ec
AJ
1265 {
1266 TCGv val = tcg_temp_new(TCG_TYPE_I32);
1267 tcg_gen_add_i32(val, REG(0), cpu_gbr);
1268 tcg_gen_qemu_ld8u(val, val, ctx->memidx);
1269 tcg_gen_andi_i32(val, val, B7_0);
1270 gen_cmp_imm(TCG_COND_EQ, val, 0);
1271 tcg_temp_free(val);
1272 }
fdf9b3e8
FB
1273 return;
1274 case 0xca00: /* xor #imm,R0 */
7efbe241 1275 tcg_gen_xori_i32(REG(0), REG(0), B7_0);
fdf9b3e8 1276 return;
24988dc2 1277 case 0xce00: /* xor.b #imm,@(R0,GBR) */
c55497ec
AJ
1278 {
1279 TCGv addr, val;
1280 addr = tcg_temp_new(TCG_TYPE_I32);
1281 tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1282 val = tcg_temp_new(TCG_TYPE_I32);
1283 tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1284 tcg_gen_xori_i32(val, val, B7_0);
1285 tcg_gen_qemu_st8(val, addr, ctx->memidx);
1286 tcg_temp_free(val);
1287 tcg_temp_free(addr);
1288 }
fdf9b3e8
FB
1289 return;
1290 }
1291
1292 switch (ctx->opcode & 0xf08f) {
1293 case 0x408e: /* ldc Rm,Rn_BANK */
7efbe241 1294 tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
fdf9b3e8
FB
1295 return;
1296 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
7efbe241
AJ
1297 tcg_gen_qemu_ld32s(ALTREG(B6_4), REG(B11_8), ctx->memidx);
1298 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
fdf9b3e8
FB
1299 return;
1300 case 0x0082: /* stc Rm_BANK,Rn */
7efbe241 1301 tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
fdf9b3e8
FB
1302 return;
1303 case 0x4083: /* stc.l Rm_BANK,@-Rn */
c55497ec
AJ
1304 {
1305 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1306 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1307 tcg_gen_qemu_st32(ALTREG(B6_4), addr, ctx->memidx);
1308 tcg_temp_free(addr);
1309 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1310 }
fdf9b3e8
FB
1311 return;
1312 }
1313
1314 switch (ctx->opcode & 0xf0ff) {
1315 case 0x0023: /* braf Rn */
7efbe241
AJ
1316 CHECK_NOT_DELAY_SLOT
1317 tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->pc + 4);
fdf9b3e8
FB
1318 ctx->flags |= DELAY_SLOT;
1319 ctx->delayed_pc = (uint32_t) - 1;
1320 return;
1321 case 0x0003: /* bsrf Rn */
7efbe241 1322 CHECK_NOT_DELAY_SLOT
1000822b 1323 tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
7efbe241 1324 tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);
fdf9b3e8
FB
1325 ctx->flags |= DELAY_SLOT;
1326 ctx->delayed_pc = (uint32_t) - 1;
1327 return;
1328 case 0x4015: /* cmp/pl Rn */
7efbe241 1329 gen_cmp_imm(TCG_COND_GT, REG(B11_8), 0);
fdf9b3e8
FB
1330 return;
1331 case 0x4011: /* cmp/pz Rn */
7efbe241 1332 gen_cmp_imm(TCG_COND_GE, REG(B11_8), 0);
fdf9b3e8
FB
1333 return;
1334 case 0x4010: /* dt Rn */
7efbe241
AJ
1335 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);
1336 gen_cmp_imm(TCG_COND_EQ, REG(B11_8), 0);
fdf9b3e8
FB
1337 return;
1338 case 0x402b: /* jmp @Rn */
7efbe241
AJ
1339 CHECK_NOT_DELAY_SLOT
1340 tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
fdf9b3e8
FB
1341 ctx->flags |= DELAY_SLOT;
1342 ctx->delayed_pc = (uint32_t) - 1;
1343 return;
1344 case 0x400b: /* jsr @Rn */
7efbe241 1345 CHECK_NOT_DELAY_SLOT
1000822b 1346 tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
7efbe241 1347 tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
fdf9b3e8
FB
1348 ctx->flags |= DELAY_SLOT;
1349 ctx->delayed_pc = (uint32_t) - 1;
1350 return;
390af821 1351 case 0x400e: /* lds Rm,SR */
7efbe241 1352 tcg_gen_andi_i32(cpu_sr, REG(B11_8), 0x700083f3);
390af821
AJ
1353 ctx->bstate = BS_STOP;
1354 return;
1355 case 0x4007: /* lds.l @Rm+,SR */
c55497ec
AJ
1356 {
1357 TCGv val = tcg_temp_new(TCG_TYPE_I32);
1358 tcg_gen_qemu_ld32s(val, REG(B11_8), ctx->memidx);
1359 tcg_gen_andi_i32(cpu_sr, val, 0x700083f3);
1360 tcg_temp_free(val);
1361 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1362 ctx->bstate = BS_STOP;
1363 }
390af821
AJ
1364 return;
1365 case 0x0002: /* sts SR,Rn */
7efbe241 1366 tcg_gen_mov_i32(REG(B11_8), cpu_sr);
390af821
AJ
1367 return;
1368 case 0x4003: /* sts SR,@-Rn */
c55497ec
AJ
1369 {
1370 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1371 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1372 tcg_gen_qemu_st32(cpu_sr, addr, ctx->memidx);
1373 tcg_temp_free(addr);
1374 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1375 }
390af821
AJ
1376 return;
1377#define LDST(reg,ldnum,ldpnum,stnum,stpnum) \
fdf9b3e8 1378 case ldnum: \
7efbe241 1379 tcg_gen_mov_i32 (cpu_##reg, REG(B11_8)); \
fdf9b3e8
FB
1380 return; \
1381 case ldpnum: \
7efbe241
AJ
1382 tcg_gen_qemu_ld32s (cpu_##reg, REG(B11_8), ctx->memidx); \
1383 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4); \
fdf9b3e8
FB
1384 return; \
1385 case stnum: \
7efbe241 1386 tcg_gen_mov_i32 (REG(B11_8), cpu_##reg); \
fdf9b3e8
FB
1387 return; \
1388 case stpnum: \
c55497ec
AJ
1389 { \
1390 TCGv addr = tcg_temp_new(TCG_TYPE_I32); \
1391 tcg_gen_subi_i32(addr, REG(B11_8), 4); \
1392 tcg_gen_qemu_st32 (cpu_##reg, addr, ctx->memidx); \
1393 tcg_temp_free(addr); \
1394 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4); \
86e0abc7 1395 } \
fdf9b3e8 1396 return;
390af821
AJ
1397 LDST(gbr, 0x401e, 0x4017, 0x0012, 0x4013)
1398 LDST(vbr, 0x402e, 0x4027, 0x0022, 0x4023)
1399 LDST(ssr, 0x403e, 0x4037, 0x0032, 0x4033)
1400 LDST(spc, 0x404e, 0x4047, 0x0042, 0x4043)
1401 LDST(dbr, 0x40fa, 0x40f6, 0x00fa, 0x40f2)
1402 LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002)
1403 LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012)
1404 LDST(pr, 0x402a, 0x4026, 0x002a, 0x4022)
1405 LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052)
1406 case 0x406a: /* lds Rm,FPSCR */
7efbe241 1407 tcg_gen_helper_0_1(helper_ld_fpscr, REG(B11_8));
390af821
AJ
1408 ctx->bstate = BS_STOP;
1409 return;
1410 case 0x4066: /* lds.l @Rm+,FPSCR */
c55497ec
AJ
1411 {
1412 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1413 tcg_gen_qemu_ld32s(addr, REG(B11_8), ctx->memidx);
1414 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1415 tcg_gen_helper_0_1(helper_ld_fpscr, addr);
1416 tcg_temp_free(addr);
1417 ctx->bstate = BS_STOP;
1418 }
390af821
AJ
1419 return;
1420 case 0x006a: /* sts FPSCR,Rn */
c55497ec 1421 tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);
390af821
AJ
1422 return;
1423 case 0x4062: /* sts FPSCR,@-Rn */
c55497ec
AJ
1424 {
1425 TCGv addr, val;
1426 val = tcg_temp_new(TCG_TYPE_I32);
1427 tcg_gen_andi_i32(val, cpu_fpscr, 0x003fffff);
1428 addr = tcg_temp_new(TCG_TYPE_I32);
1429 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1430 tcg_gen_qemu_st32(val, addr, ctx->memidx);
1431 tcg_temp_free(addr);
1432 tcg_temp_free(val);
1433 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1434 }
390af821 1435 return;
fdf9b3e8 1436 case 0x00c3: /* movca.l R0,@Rm */
7efbe241 1437 tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx);
fdf9b3e8
FB
1438 return;
1439 case 0x0029: /* movt Rn */
7efbe241 1440 tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T);
fdf9b3e8
FB
1441 return;
1442 case 0x0093: /* ocbi @Rn */
c55497ec
AJ
1443 {
1444 TCGv dummy = tcg_temp_new(TCG_TYPE_I32);
1445 tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1446 tcg_temp_free(dummy);
1447 }
fdf9b3e8 1448 return;
24988dc2 1449 case 0x00a3: /* ocbp @Rn */
c55497ec
AJ
1450 {
1451 TCGv dummy = tcg_temp_new(TCG_TYPE_I32);
1452 tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1453 tcg_temp_free(dummy);
1454 }
fdf9b3e8
FB
1455 return;
1456 case 0x00b3: /* ocbwb @Rn */
c55497ec
AJ
1457 {
1458 TCGv dummy = tcg_temp_new(TCG_TYPE_I32);
1459 tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1460 tcg_temp_free(dummy);
1461 }
fdf9b3e8
FB
1462 return;
1463 case 0x0083: /* pref @Rn */
1464 return;
1465 case 0x4024: /* rotcl Rn */
c55497ec
AJ
1466 {
1467 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
1468 tcg_gen_mov_i32(tmp, cpu_sr);
1469 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1470 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1471 gen_copy_bit_i32(REG(B11_8), 0, tmp, 0);
1472 tcg_temp_free(tmp);
1473 }
fdf9b3e8
FB
1474 return;
1475 case 0x4025: /* rotcr Rn */
c55497ec
AJ
1476 {
1477 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
1478 tcg_gen_mov_i32(tmp, cpu_sr);
1479 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1480 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1481 gen_copy_bit_i32(REG(B11_8), 31, tmp, 0);
1482 tcg_temp_free(tmp);
1483 }
fdf9b3e8
FB
1484 return;
1485 case 0x4004: /* rotl Rn */
7efbe241
AJ
1486 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1487 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1488 gen_copy_bit_i32(REG(B11_8), 0, cpu_sr, 0);
fdf9b3e8
FB
1489 return;
1490 case 0x4005: /* rotr Rn */
7efbe241
AJ
1491 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1492 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1493 gen_copy_bit_i32(REG(B11_8), 31, cpu_sr, 0);
fdf9b3e8
FB
1494 return;
1495 case 0x4000: /* shll Rn */
1496 case 0x4020: /* shal Rn */
7efbe241
AJ
1497 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1498 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
fdf9b3e8
FB
1499 return;
1500 case 0x4021: /* shar Rn */
7efbe241
AJ
1501 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1502 tcg_gen_sari_i32(REG(B11_8), REG(B11_8), 1);
fdf9b3e8
FB
1503 return;
1504 case 0x4001: /* shlr Rn */
7efbe241
AJ
1505 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1506 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
fdf9b3e8
FB
1507 return;
1508 case 0x4008: /* shll2 Rn */
7efbe241 1509 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 2);
fdf9b3e8
FB
1510 return;
1511 case 0x4018: /* shll8 Rn */
7efbe241 1512 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 8);
fdf9b3e8
FB
1513 return;
1514 case 0x4028: /* shll16 Rn */
7efbe241 1515 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 16);
fdf9b3e8
FB
1516 return;
1517 case 0x4009: /* shlr2 Rn */
7efbe241 1518 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 2);
fdf9b3e8
FB
1519 return;
1520 case 0x4019: /* shlr8 Rn */
7efbe241 1521 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 8);
fdf9b3e8
FB
1522 return;
1523 case 0x4029: /* shlr16 Rn */
7efbe241 1524 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16);
fdf9b3e8
FB
1525 return;
1526 case 0x401b: /* tas.b @Rn */
c55497ec
AJ
1527 {
1528 TCGv addr, val;
1529 addr = tcg_temp_local_new(TCG_TYPE_I32);
1530 tcg_gen_mov_i32(addr, REG(B11_8));
1531 val = tcg_temp_local_new(TCG_TYPE_I32);
1532 tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1533 gen_cmp_imm(TCG_COND_EQ, val, 0);
1534 tcg_gen_ori_i32(val, val, 0x80);
1535 tcg_gen_qemu_st8(val, addr, ctx->memidx);
1536 tcg_temp_free(val);
1537 tcg_temp_free(addr);
1538 }
fdf9b3e8 1539 return;
e67888a7 1540 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
cc4ba6a9
AJ
1541 {
1542 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1543 tcg_gen_mov_i32(fp, cpu_fpul);
1544 gen_store_fpr32(fp, FREG(B11_8));
1545 tcg_temp_free(fp);
1546 }
eda9b09b 1547 return;
e67888a7 1548 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
cc4ba6a9
AJ
1549 {
1550 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1551 gen_load_fpr32(fp, FREG(B11_8));
1552 tcg_gen_mov_i32(cpu_fpul, fp);
1553 tcg_temp_free(fp);
1554 }
eda9b09b 1555 return;
e67888a7 1556 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
ea6cf6be 1557 if (ctx->fpscr & FPSCR_PR) {
cc4ba6a9 1558 TCGv fp;
ea6cf6be
TS
1559 if (ctx->opcode & 0x0100)
1560 break; /* illegal instruction */
cc4ba6a9
AJ
1561 fp = tcg_temp_new(TCG_TYPE_I64);
1562 tcg_gen_helper_1_1(helper_float_DT, fp, cpu_fpul);
1563 gen_store_fpr64(fp, DREG(B11_8));
1564 tcg_temp_free(fp);
ea6cf6be
TS
1565 }
1566 else {
cc4ba6a9
AJ
1567 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1568 tcg_gen_helper_1_1(helper_float_FT, fp, cpu_fpul);
1569 gen_store_fpr32(fp, FREG(B11_8));
1570 tcg_temp_free(fp);
ea6cf6be
TS
1571 }
1572 return;
e67888a7 1573 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
ea6cf6be 1574 if (ctx->fpscr & FPSCR_PR) {
cc4ba6a9 1575 TCGv fp;
ea6cf6be
TS
1576 if (ctx->opcode & 0x0100)
1577 break; /* illegal instruction */
cc4ba6a9
AJ
1578 fp = tcg_temp_new(TCG_TYPE_I64);
1579 gen_load_fpr64(fp, DREG(B11_8));
1580 tcg_gen_helper_1_1(helper_ftrc_DT, cpu_fpul, fp);
1581 tcg_temp_free(fp);
ea6cf6be
TS
1582 }
1583 else {
cc4ba6a9
AJ
1584 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1585 gen_load_fpr32(fp, FREG(B11_8));
1586 tcg_gen_helper_1_1(helper_ftrc_FT, cpu_fpul, fp);
1587 tcg_temp_free(fp);
ea6cf6be
TS
1588 }
1589 return;
24988dc2 1590 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
7fdf924f
AJ
1591 {
1592 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1593 gen_load_fpr32(fp, FREG(B11_8));
1594 tcg_gen_helper_1_1(helper_fneg_T, fp, fp);
1595 gen_store_fpr32(fp, FREG(B11_8));
1596 tcg_temp_free(fp);
1597 }
24988dc2
AJ
1598 return;
1599 case 0xf05d: /* fabs FRn/DRn */
1600 if (ctx->fpscr & FPSCR_PR) {
1601 if (ctx->opcode & 0x0100)
1602 break; /* illegal instruction */
cc4ba6a9
AJ
1603 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1604 gen_load_fpr64(fp, DREG(B11_8));
1605 tcg_gen_helper_1_1(helper_fabs_DT, fp, fp);
1606 gen_store_fpr64(fp, DREG(B11_8));
1607 tcg_temp_free(fp);
24988dc2 1608 } else {
cc4ba6a9
AJ
1609 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1610 gen_load_fpr32(fp, FREG(B11_8));
1611 tcg_gen_helper_1_1(helper_fabs_FT, fp, fp);
1612 gen_store_fpr32(fp, FREG(B11_8));
1613 tcg_temp_free(fp);
24988dc2
AJ
1614 }
1615 return;
1616 case 0xf06d: /* fsqrt FRn */
1617 if (ctx->fpscr & FPSCR_PR) {
1618 if (ctx->opcode & 0x0100)
1619 break; /* illegal instruction */
cc4ba6a9
AJ
1620 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1621 gen_load_fpr64(fp, DREG(B11_8));
1622 tcg_gen_helper_1_1(helper_fsqrt_DT, fp, fp);
1623 gen_store_fpr64(fp, DREG(B11_8));
1624 tcg_temp_free(fp);
24988dc2 1625 } else {
cc4ba6a9
AJ
1626 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1627 gen_load_fpr32(fp, FREG(B11_8));
1628 tcg_gen_helper_1_1(helper_fsqrt_FT, fp, fp);
1629 gen_store_fpr32(fp, FREG(B11_8));
1630 tcg_temp_free(fp);
24988dc2
AJ
1631 }
1632 return;
1633 case 0xf07d: /* fsrra FRn */
1634 break;
e67888a7 1635 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
ea6cf6be 1636 if (!(ctx->fpscr & FPSCR_PR)) {
cc4ba6a9
AJ
1637 TCGv val = tcg_const_i32(0);
1638 gen_load_fpr32(val, FREG(B11_8));
1639 tcg_temp_free(val);
ea6cf6be
TS
1640 return;
1641 }
1642 break;
e67888a7 1643 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
ea6cf6be 1644 if (!(ctx->fpscr & FPSCR_PR)) {
cc4ba6a9
AJ
1645 TCGv val = tcg_const_i32(0x3f800000);
1646 gen_load_fpr32(val, FREG(B11_8));
1647 tcg_temp_free(val);
ea6cf6be
TS
1648 return;
1649 }
1650 break;
24988dc2 1651 case 0xf0ad: /* fcnvsd FPUL,DRn */
cc4ba6a9
AJ
1652 {
1653 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1654 tcg_gen_helper_1_1(helper_fcnvsd_FT_DT, fp, cpu_fpul);
1655 gen_store_fpr64(fp, DREG(B11_8));
1656 tcg_temp_free(fp);
1657 }
24988dc2
AJ
1658 return;
1659 case 0xf0bd: /* fcnvds DRn,FPUL */
cc4ba6a9
AJ
1660 {
1661 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1662 gen_load_fpr64(fp, DREG(B11_8));
1663 tcg_gen_helper_1_1(helper_fcnvds_DT_FT, cpu_fpul, fp);
1664 tcg_temp_free(fp);
1665 }
24988dc2 1666 return;
fdf9b3e8
FB
1667 }
1668
1669 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1670 ctx->opcode, ctx->pc);
e6afc2f4 1671 tcg_gen_helper_0_0(helper_raise_illegal_instruction);
823029f9
TS
1672 ctx->bstate = BS_EXCP;
1673}
1674
1675void decode_opc(DisasContext * ctx)
1676{
1677 uint32_t old_flags = ctx->flags;
1678
1679 _decode_opc(ctx);
1680
1681 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1682 if (ctx->flags & DELAY_SLOT_CLEARME) {
1000822b 1683 gen_store_flags(0);
274a9e70
AJ
1684 } else {
1685 /* go out of the delay slot */
1686 uint32_t new_flags = ctx->flags;
1687 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1000822b 1688 gen_store_flags(new_flags);
823029f9
TS
1689 }
1690 ctx->flags = 0;
1691 ctx->bstate = BS_BRANCH;
1692 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1693 gen_delayed_conditional_jump(ctx);
1694 } else if (old_flags & DELAY_SLOT) {
1695 gen_jump(ctx);
1696 }
1697
1698 }
274a9e70
AJ
1699
1700 /* go into a delay slot */
1701 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1000822b 1702 gen_store_flags(ctx->flags);
fdf9b3e8
FB
1703}
1704
2cfc5f17 1705static inline void
820e00f2
TS
1706gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1707 int search_pc)
fdf9b3e8
FB
1708{
1709 DisasContext ctx;
1710 target_ulong pc_start;
1711 static uint16_t *gen_opc_end;
355fb23d 1712 int i, ii;
2e70f6ef
PB
1713 int num_insns;
1714 int max_insns;
fdf9b3e8
FB
1715
1716 pc_start = tb->pc;
fdf9b3e8 1717 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
fdf9b3e8 1718 ctx.pc = pc_start;
823029f9
TS
1719 ctx.flags = (uint32_t)tb->flags;
1720 ctx.bstate = BS_NONE;
fdf9b3e8 1721 ctx.sr = env->sr;
eda9b09b 1722 ctx.fpscr = env->fpscr;
fdf9b3e8 1723 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
9854bc46
PB
1724 /* We don't know if the delayed pc came from a dynamic or static branch,
1725 so assume it is a dynamic branch. */
823029f9 1726 ctx.delayed_pc = -1; /* use delayed pc from env pointer */
fdf9b3e8
FB
1727 ctx.tb = tb;
1728 ctx.singlestep_enabled = env->singlestep_enabled;
fdf9b3e8
FB
1729
1730#ifdef DEBUG_DISAS
1731 if (loglevel & CPU_LOG_TB_CPU) {
1732 fprintf(logfile,
1733 "------------------------------------------------\n");
1734 cpu_dump_state(env, logfile, fprintf, 0);
1735 }
1736#endif
1737
355fb23d 1738 ii = -1;
2e70f6ef
PB
1739 num_insns = 0;
1740 max_insns = tb->cflags & CF_COUNT_MASK;
1741 if (max_insns == 0)
1742 max_insns = CF_COUNT_MASK;
1743 gen_icount_start();
823029f9 1744 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
fdf9b3e8
FB
1745 if (env->nb_breakpoints > 0) {
1746 for (i = 0; i < env->nb_breakpoints; i++) {
1747 if (ctx.pc == env->breakpoints[i]) {
1748 /* We have hit a breakpoint - make sure PC is up-to-date */
3a8a44c4 1749 tcg_gen_movi_i32(cpu_pc, ctx.pc);
e6afc2f4 1750 tcg_gen_helper_0_0(helper_debug);
823029f9 1751 ctx.bstate = BS_EXCP;
fdf9b3e8
FB
1752 break;
1753 }
1754 }
1755 }
355fb23d
PB
1756 if (search_pc) {
1757 i = gen_opc_ptr - gen_opc_buf;
1758 if (ii < i) {
1759 ii++;
1760 while (ii < i)
1761 gen_opc_instr_start[ii++] = 0;
1762 }
1763 gen_opc_pc[ii] = ctx.pc;
823029f9 1764 gen_opc_hflags[ii] = ctx.flags;
355fb23d 1765 gen_opc_instr_start[ii] = 1;
2e70f6ef 1766 gen_opc_icount[ii] = num_insns;
355fb23d 1767 }
2e70f6ef
PB
1768 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1769 gen_io_start();
fdf9b3e8
FB
1770#if 0
1771 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1772 fflush(stderr);
1773#endif
1774 ctx.opcode = lduw_code(ctx.pc);
1775 decode_opc(&ctx);
2e70f6ef 1776 num_insns++;
fdf9b3e8
FB
1777 ctx.pc += 2;
1778 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1779 break;
1780 if (env->singlestep_enabled)
1781 break;
2e70f6ef
PB
1782 if (num_insns >= max_insns)
1783 break;
fdf9b3e8
FB
1784#ifdef SH4_SINGLE_STEP
1785 break;
1786#endif
1787 }
2e70f6ef
PB
1788 if (tb->cflags & CF_LAST_IO)
1789 gen_io_end();
fdf9b3e8 1790 if (env->singlestep_enabled) {
e6afc2f4 1791 tcg_gen_helper_0_0(helper_debug);
823029f9
TS
1792 } else {
1793 switch (ctx.bstate) {
1794 case BS_STOP:
1795 /* gen_op_interrupt_restart(); */
1796 /* fall through */
1797 case BS_NONE:
1798 if (ctx.flags) {
1000822b 1799 gen_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
823029f9
TS
1800 }
1801 gen_goto_tb(&ctx, 0, ctx.pc);
1802 break;
1803 case BS_EXCP:
1804 /* gen_op_interrupt_restart(); */
57fec1fe 1805 tcg_gen_exit_tb(0);
823029f9
TS
1806 break;
1807 case BS_BRANCH:
1808 default:
1809 break;
1810 }
fdf9b3e8 1811 }
823029f9 1812
2e70f6ef 1813 gen_icount_end(tb, num_insns);
fdf9b3e8 1814 *gen_opc_ptr = INDEX_op_end;
355fb23d
PB
1815 if (search_pc) {
1816 i = gen_opc_ptr - gen_opc_buf;
1817 ii++;
1818 while (ii <= i)
1819 gen_opc_instr_start[ii++] = 0;
355fb23d
PB
1820 } else {
1821 tb->size = ctx.pc - pc_start;
2e70f6ef 1822 tb->icount = num_insns;
355fb23d 1823 }
fdf9b3e8
FB
1824
1825#ifdef DEBUG_DISAS
1826#ifdef SH4_DEBUG_DISAS
1827 if (loglevel & CPU_LOG_TB_IN_ASM)
1828 fprintf(logfile, "\n");
1829#endif
1830 if (loglevel & CPU_LOG_TB_IN_ASM) {
1831 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1832 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1833 fprintf(logfile, "\n");
1834 }
fdf9b3e8 1835#endif
fdf9b3e8
FB
1836}
1837
2cfc5f17 1838void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
fdf9b3e8 1839{
2cfc5f17 1840 gen_intermediate_code_internal(env, tb, 0);
fdf9b3e8
FB
1841}
1842
2cfc5f17 1843void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
fdf9b3e8 1844{
2cfc5f17 1845 gen_intermediate_code_internal(env, tb, 1);
fdf9b3e8 1846}
d2856f1a
AJ
1847
1848void gen_pc_load(CPUState *env, TranslationBlock *tb,
1849 unsigned long searched_pc, int pc_pos, void *puc)
1850{
1851 env->pc = gen_opc_pc[pc_pos];
1852 env->flags = gen_opc_hflags[pc_pos];
1853}